dtls13_record_decrypt.c
Go to the documentation of this file.
1 /**
2  * @file dtls13_record_decrypt.c
3  * @brief DTLS 1.3 record decryption
4  *
5  * @section License
6  *
7  * SPDX-License-Identifier: GPL-2.0-or-later
8  *
9  * Copyright (C) 2010-2026 Oryx Embedded SARL. All rights reserved.
10  *
11  * This file is part of CycloneSSL Open.
12  *
13  * This program is free software; you can redistribute it and/or
14  * modify it under the terms of the GNU General Public License
15  * as published by the Free Software Foundation; either version 2
16  * of the License, or (at your option) any later version.
17  *
18  * This program is distributed in the hope that it will be useful,
19  * but WITHOUT ANY WARRANTY; without even the implied warranty of
20  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21  * GNU General Public License for more details.
22  *
23  * You should have received a copy of the GNU General Public License
24  * along with this program; if not, write to the Free Software Foundation,
25  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
26  *
27  * @author Oryx Embedded SARL (www.oryx-embedded.com)
28  * @version 2.6.2
29  **/
30 
31 //Switch to the appropriate trace level
32 #define TRACE_LEVEL TLS_TRACE_LEVEL
33 
34 //Dependencies
35 #include "tls/tls.h"
37 #include "dtls13/dtls13_misc.h"
39 #include "debug.h"
40 
41 //Check TLS library configuration
42 #if (TLS_SUPPORT == ENABLED && DTLS_SUPPORT == ENABLED && \
43  TLS_MAX_VERSION >= TLS_VERSION_1_3)
44 
45 
46 /**
47  * @brief Receive a DTLS 1.3 record
48  * @param[in] context Pointer to the TLS context
49  * @return Error code
50  **/
51 
53 {
54  error_t error;
55  uint8_t *record;
56 
57  //Point to the DTLS record
58  record = context->rxBuffer + context->rxDatagramPos;
59 
60  //Implementations can demultiplex DTLS 1.3 records by examining the first
61  //byte (refer to RFC 9147, section 4.1)
62  if(record[0] == TLS_TYPE_ALERT || record[0] == TLS_TYPE_HANDSHAKE ||
63  record[0] == TLS_TYPE_ACK)
64  {
65  //If the first byte is alert(21), handshake(22), or ack(26), the record
66  //must be interpreted as a DTLSPlaintext record
67  error = dtls13ReadPlaintextRecord(context, record);
68  }
69  else if((record[0] & DTLS13_HEADER_MASK) == DTLS13_HEADER_FIXED)
70  {
71  //If the leading bits of the first byte are 001, the implementation
72  //must process the record as DTLSCiphertext
73  error = dtls13ReadCiphertextRecord(context, record);
74  }
75  else
76  {
77  //Otherwise, the record must be rejected as if it had failed deprotection
78  context->rxDatagramLen = 0;
79  //Report an error
80  error = ERROR_BAD_RECORD_MAC;
81  }
82 
83  //Return status code
84  return error;
85 }
86 
87 
88 /**
89  * @brief Receive a DTLSPlaintext record
90  * @param[in] context Pointer to the TLS context
91  * @param[in] record Pointer to the DTLSPlaintext structure
92  * @return Error code
93  **/
94 
95 error_t dtls13ReadPlaintextRecord(TlsContext *context, uint8_t *record)
96 {
97  error_t error;
98  size_t dataLen;
99  DtlsRecord *header;
100  TlsEncryptionEngine *decryptionEngine;
101 
102  //The DTLSPlaintext structure has a fixed-length header
103  header = (DtlsRecord *) record;
104 
105  //Malformed datagram?
106  if(context->rxDatagramLen < sizeof(DtlsRecord))
107  {
108  //Drop the received datagram
109  context->rxDatagramLen = 0;
110  //Report an error
111  return ERROR_INVALID_LENGTH;
112  }
113 
114  //Retrieve the length of the payload
115  dataLen = ntohs(header->length);
116 
117  //Malformed DTLS record?
118  if((dataLen + sizeof(DtlsRecord)) > context->rxDatagramLen)
119  {
120  //Drop the received datagram
121  context->rxDatagramLen = 0;
122  //Report an error
123  return ERROR_BAD_RECORD_MAC;
124  }
125 
126  //Point to the payload data
127  context->rxRecordPos = context->rxDatagramPos + sizeof(DtlsRecord);
128 
129  //Multiple DTLSPlaintext and DTLSCiphertext records can be included in the
130  //same underlying transport datagram (refer to RFC 9147, section 4)
131  context->rxDatagramPos += dataLen + sizeof(DtlsRecord);
132  context->rxDatagramLen -= dataLen + sizeof(DtlsRecord);
133 
134  //Point to the decryption engine
135  decryptionEngine = &context->decryptionEngine[0];
136 
137  //DTLSPlaintext records are used to send unprotected records
138  if(decryptionEngine->cipherMode != CIPHER_MODE_NULL ||
139  decryptionEngine->hashAlgo != NULL)
140  {
141  //Discard the offending record
143  }
144 
145  //Compliant servers must accept any value {254,XX} as the record layer
146  //version number for ClientHello
147  if(MSB(ntohs(header->version)) != MSB(DTLS_VERSION_1_0))
149 
150  //Discard packets from earlier epochs
151  if(ntohs(header->epoch) != decryptionEngine->epoch)
152  return ERROR_INVALID_EPOCH;
153 
154  //Check whether anti-replay mechanism is enabled
155  if(context->replayDetectionEnabled)
156  {
157  //Perform replay detection
158  error = dtlsCheckReplayWindow(decryptionEngine, &header->seqNum);
159  //Any error to report?
160  if(error)
161  return error;
162  }
163 
164  //Update the receive window
165  dtlsUpdateReplayWindow(decryptionEngine, &header->seqNum);
166 
167  //Save record version
168  context->rxRecordVersion = ntohs(header->version);
169  //Save record type
170  context->rxBufferType = (TlsContentType) header->type;
171  //Save record length
172  context->rxRecordLen = dataLen;
173 
174  //Save record number
175  context->rxRecordNum.epoch = ntohs(header->epoch);
176  context->rxRecordNum.seqNum = LOAD48BE(header->seqNum.b);
177 
178  //Successful processing
179  return NO_ERROR;
180 }
181 
182 
183 /**
184  * @brief Receive a DTLSCiphertext record
185  * @param[in] context Pointer to the TLS context
186  * @param[in] record Pointer to the DTLSCiphertext structure
187  * @return Error code
188  **/
189 
191 {
192  error_t error;
193  uint_t i;
194  uint8_t type;
195  uint16_t epoch;
196  size_t headerLen;
197  size_t dataLen;
199  TlsEncryptionEngine *decryptionEngine;
200 
201  //The unified header is a structure of variable length
202  headerLen = sizeof(uint8_t);
203 
204  //Malformed datagram?
205  if(context->rxDatagramLen < headerLen)
206  {
207  //Drop the received datagram
208  context->rxDatagramLen = 0;
209  //Report an error
210  return ERROR_INVALID_LENGTH;
211  }
212 
213  //The C bit is set if the Connection ID is present
214  if((record[0] & DTLS13_HEADER_FLAG_C) != 0)
215  {
216  //Drop the received datagram
217  context->rxDatagramLen = 0;
218  //Report an error
219  return ERROR_INVALID_LENGTH;
220  }
221 
222  //The record sequence number is 16 bits if the S bit is set to 1, and 8 bits
223  //if the S bit is 0
224  if((record[0] & DTLS13_HEADER_FLAG_S) != 0)
225  {
226  headerLen += sizeof(uint16_t);
227  }
228  else
229  {
230  headerLen += sizeof(uint8_t);
231  }
232 
233  //The length field is present if the L bit is set
234  if((record[0] & DTLS13_HEADER_FLAG_L) != 0)
235  {
236  headerLen += sizeof(uint16_t);
237  }
238 
239  //Malformed datagram?
240  if(context->rxDatagramLen < headerLen)
241  {
242  //Drop the received datagram
243  context->rxDatagramLen = 0;
244  //Report an error
245  return ERROR_INVALID_LENGTH;
246  }
247 
248  //The length field may be omitted by clearing the L bit, which means that
249  //the record consumes the entire rest of the datagram in the lower level
250  //transport (refer to RFC 9147, section 4)
251  if((record[0] & DTLS13_HEADER_FLAG_L) != 0)
252  {
253  dataLen = LOAD16BE(record + headerLen - sizeof(uint16_t));
254  }
255  else
256  {
257  dataLen = context->rxDatagramLen - headerLen;
258  }
259 
260  //Malformed DTLS record?
261  if((headerLen + dataLen) > context->rxDatagramLen)
262  {
263  //Drop the received datagram
264  context->rxDatagramLen = 0;
265  //Report an error
266  return ERROR_BAD_RECORD_MAC;
267  }
268 
269  //Point to the payload data
270  context->rxRecordPos = context->rxDatagramPos + headerLen;
271 
272  //Multiple DTLSPlaintext and DTLSCiphertext records can be included in the
273  //same underlying transport datagram (refer to RFC 9147, section 4)
274  context->rxDatagramPos += headerLen + dataLen;
275  context->rxDatagramLen -= headerLen + dataLen;
276 
277  //The two low bits include the low-order two bits of the epoch
278  epoch = record[0] & DTLS13_HEADER_FLAG_E;
279 
280  //If the epoch bits do not match those from the current epoch,
281  //implementations should use the most recent past epoch which has
282  //matching bits (refer to RFC 9147, section 4.2.2)
283  for(decryptionEngine = NULL, i = 0; i < TLS_MAX_DECRYPTION_ENGINES; i++)
284  {
285  //Valid decryption engine?
286  if(context->decryptionEngine[i].active)
287  {
288  //Matching epoch bits?
289  if((context->decryptionEngine[i].epoch & 3) == epoch)
290  {
291  decryptionEngine = &context->decryptionEngine[i];
292  break;
293  }
294  }
295  }
296 
297  //Invalid keying material?
298  if(decryptionEngine == NULL)
299  return ERROR_INVALID_EPOCH;
300 
301  //In DTLS 1.3, when records are encrypted, record sequence numbers are
302  //also encrypted (refer to RFC 9147, section 4.2.3)
303  error = dtls13DecryptSequenceNumber(decryptionEngine, record);
304  //Chek status code
305  if(error)
306  return error;
307 
308  //Reconstruct the sequence number
309  dtls13ReconstructSequenceNumber(decryptionEngine, record, &seqNum);
310 
311  //Check whether anti-replay mechanism is enabled
312  if(context->replayDetectionEnabled)
313  {
314  //Perform replay detection
315  error = dtlsCheckReplayWindow(decryptionEngine, &seqNum);
316  //Any error to report?
317  if(error)
318  return error;
319  }
320 
321  //DTLSCiphertext records are used to send protected records
322  if(decryptionEngine->cipherMode != CIPHER_MODE_NULL ||
323  decryptionEngine->hashAlgo != NULL)
324  {
325  size_t nonceLen;
326  uint8_t nonce[48];
327 
328  //Generate the nonce
329  dtls13FormatNonce(decryptionEngine, &seqNum, nonce, &nonceLen);
330 
331  //Decrypt DTLS 1.3 record
332  error = dtls13DecryptRecord(context, decryptionEngine, nonce, nonceLen,
333  record, headerLen, record + headerLen, &dataLen, &type);
334  //If the MAC validation fails, the receiver must discard the record
335  if(error)
336  return error;
337 
338  //The length of the plaintext record must not exceed 2^14 bytes
340  return ERROR_RECORD_OVERFLOW;
341  }
342  else
343  {
344  //Discard the offending record
346  }
347 
348  //Check current state
349  if(context->state == TLS_STATE_APPLICATION_DATA ||
350  context->state == TLS_STATE_CLIENT_FINISHED_ACK ||
351  context->state == TLS_STATE_NEW_SESSION_TICKET_ACK ||
352  context->state == TLS_STATE_KEY_UPDATE_ACK)
353  {
354  //Due to the possibility of an ACK message for a KeyUpdate being lost and
355  //thereby preventing the sender of the KeyUpdate from updating its keying
356  //material, receivers must retain the pre-update keying material until
357  //receipt and successful decryption of a message using the new keys
358  if(i == 0 && context->decryptionEngine[1].active)
359  {
360  context->decryptionEngine[1].lifetime = 60000;
361  context->decryptionEngine[1].timestamp = osGetSystemTime();
362  }
363  }
364 
365  //The receive window is updated only if the MAC verification succeeds
366  dtlsUpdateReplayWindow(decryptionEngine, &seqNum);
367 
368  //Debug message
369  TRACE_DEBUG("DTLS decrypted record received (%" PRIuSIZE " bytes)...\r\n", headerLen + dataLen);
370  TRACE_DEBUG_ARRAY(" ", record, headerLen + dataLen);
371 
372  //Save record version
373  context->rxRecordVersion = DTLS_VERSION_1_3;
374  //Save record type
375  context->rxBufferType = (TlsContentType) type;
376  //Save record length
377  context->rxRecordLen = dataLen;
378 
379  //Save record number
380  context->rxRecordNum.epoch = decryptionEngine->epoch;
381  context->rxRecordNum.seqNum = LOAD48BE(seqNum.b);
382 
383  //Successful processing
384  return NO_ERROR;
385 }
386 
387 
388 /**
389  * @brief Decrypt an incoming DTLS 1.3 record
390  * @param[in] context Pointer to the TLS context
391  * @param[in] decryptionEngine Pointer to the decryption engine
392  * @param[in] nonce Nonce
393  * @param[in] nonceLen Length of the nonce, in bytes
394  * @param[in] aad Additional authenticated data
395  * @param[in] aadLen Length of the additional data
396  * @param[in,out] data Payload data
397  * @param[in] dataLen Actual length of the payload data
398  * @param[out] type Record type
399  * @return Error code
400  **/
401 
403  TlsEncryptionEngine *decryptionEngine, const uint8_t *nonce,
404  size_t nonceLen, const uint8_t *aad, size_t aadLen, uint8_t *data,
405  size_t *dataLen, uint8_t *type)
406 {
407  error_t error;
408  size_t n;
409  size_t authTagLen;
410 
411  //Get the length of the ciphertext
412  n = *dataLen;
413 
414  //Debug message
415  TRACE_DEBUG("Record to be decrypted (%" PRIuSIZE " bytes):\r\n", n);
416  TRACE_DEBUG_ARRAY(" ", data, n);
417 
418  //Retrieve the length of the authentication tag
419  if(decryptionEngine->hashAlgo != NULL)
420  {
421  authTagLen = decryptionEngine->hashAlgo->digestSize;
422  }
423  else
424  {
425  authTagLen = decryptionEngine->authTagLen;
426  }
427 
428  //Make sure the message length is acceptable
429  if(n < authTagLen)
430  return ERROR_BAD_RECORD_MAC;
431 
432  //Calculate the length of the ciphertext
433  n -= authTagLen;
434 
435  //The length must not exceed 2^14 octets + 1 octet for ContentType + the
436  //maximum AEAD expansion. An endpoint that receives a record that exceeds
437  //this length must terminate the connection with a record_overflow alert
438  if(n > (TLS_MAX_RECORD_LENGTH + 1))
439  return ERROR_RECORD_OVERFLOW;
440 
441 #if (TLS_CCM_CIPHER_SUPPORT == ENABLED || TLS_CCM_8_CIPHER_SUPPORT == ENABLED || \
442  TLS_GCM_CIPHER_SUPPORT == ENABLED || TLS_CHACHA20_POLY1305_SUPPORT == ENABLED)
443  //AEAD cipher?
444  if(decryptionEngine->cipherMode == CIPHER_MODE_CCM ||
445  decryptionEngine->cipherMode == CIPHER_MODE_GCM ||
446  decryptionEngine->cipherMode == CIPHER_MODE_CHACHA20_POLY1305)
447  {
448  //Perform authenticated decryption
449  error = dtls13DecryptAeadRecord(context, decryptionEngine, nonce,
450  nonceLen, aad, aadLen, data, n, data + n);
451  }
452  else
453 #endif
454 #if (TLS_NULL_CIPHER_SUPPORT == ENABLED)
455  //NULL cipher?
456  if(decryptionEngine->cipherMode == CIPHER_MODE_NULL)
457  {
458  //Verify message authentication code
459  error = dtls13VerifyMac(context, decryptionEngine, nonce, nonceLen, aad,
460  aadLen, data, n, data + n);
461  }
462  else
463 #endif
464  //Invalid cipher mode?
465  {
466  //The specified cipher mode is not supported
468  }
469 
470  //Wrong authentication tag?
471  if(error)
472  return ERROR_BAD_RECORD_MAC;
473 
474  //Upon successful decryption of an encrypted record, the receiving
475  //implementation scans the field from the end toward the beginning
476  //until it finds a non-zero octet
477  while(n > 0 && data[n - 1] == 0)
478  {
479  n--;
480  }
481 
482  //If a receiving implementation does not find a non-zero octet in the
483  //cleartext, it must terminate the connection with an unexpected_message
484  //alert
485  if(n == 0)
487 
488  //Retrieve the length of the plaintext
489  n--;
490 
491  //The actual content type of the record is found in the type field
492  *type = data[n];
493 
494  //Debug message
495  TRACE_DEBUG("Decrypted record (%" PRIuSIZE " bytes):\r\n", n);
496  TRACE_DEBUG_ARRAY(" ", data, n);
497 
498  //Return the length of the plaintext
499  *dataLen = n;
500 
501  //Successful processing
502  return NO_ERROR;
503 }
504 
505 
506 /**
507  * @brief Record decryption (AEAD cipher)
508  * @param[in] context Pointer to the TLS context
509  * @param[in] decryptionEngine Pointer to the decryption engine
510  * @param[in] nonce Nonce
511  * @param[in] nonceLen Length of the nonce, in bytes
512  * @param[in] aad Additional authenticated data
513  * @param[in] aadLen Length of the additional data
514  * @param[in,out] data Payload data
515  * @param[in] dataLen Total number of data bytes to be decrypted
516  * @param[out] tag Authentication tag
517  * @return Error code
518  **/
519 
521  TlsEncryptionEngine *decryptionEngine, const uint8_t *nonce,
522  size_t nonceLen, const uint8_t *aad, size_t aadLen, uint8_t *data,
523  size_t dataLen, uint8_t *tag)
524 {
525  error_t error;
526 
527 #if (TLS_CCM_CIPHER_SUPPORT == ENABLED || TLS_CCM_8_CIPHER_SUPPORT == ENABLED)
528  //CCM AEAD cipher?
529  if(decryptionEngine->cipherMode == CIPHER_MODE_CCM)
530  {
531  //Authenticated decryption using CCM
532  error = ccmDecrypt(decryptionEngine->cipherAlgo,
533  decryptionEngine->cipherContext, nonce, nonceLen, aad, aadLen,
534  data, data, dataLen, tag, decryptionEngine->authTagLen);
535  }
536  else
537 #endif
538 #if (TLS_GCM_CIPHER_SUPPORT == ENABLED)
539  //GCM AEAD cipher?
540  if(decryptionEngine->cipherMode == CIPHER_MODE_GCM)
541  {
542  //Authenticated decryption using GCM
543  error = gcmDecrypt(decryptionEngine->gcmContext, nonce, nonceLen,
544  aad, aadLen, data, data, dataLen, tag, decryptionEngine->authTagLen);
545  }
546  else
547 #endif
548 #if (TLS_CHACHA20_POLY1305_SUPPORT == ENABLED)
549  //ChaCha20Poly1305 AEAD cipher?
550  if(decryptionEngine->cipherMode == CIPHER_MODE_CHACHA20_POLY1305)
551  {
552  //Authenticated decryption using ChaCha20Poly1305
553  error = chacha20Poly1305Decrypt(decryptionEngine->encKey,
554  decryptionEngine->encKeyLen, nonce, 12, aad, aadLen, data,
555  data, dataLen, tag, decryptionEngine->authTagLen);
556  }
557  else
558 #endif
559  //Invalid cipher mode?
560  {
561  //The specified cipher mode is not supported
563  }
564 
565  //Return status code
566  return error;
567 }
568 
569 
570 /**
571  * @brief Check message authentication code
572  * @param[in] context Pointer to the TLS context
573  * @param[in] decryptionEngine Pointer to the decryption engine
574  * @param[in] nonce Nonce
575  * @param[in] nonceLen Length of the nonce, in bytes
576  * @param[in] aad Additional authenticated data
577  * @param[in] aadLen Length of the additional data
578  * @param[in] data Payload data
579  * @param[in] dataLen Total number of data bytes to be authenticated
580  * @param[out] mac Message authentication code
581  * @return Error code
582  **/
583 
585  TlsEncryptionEngine *decryptionEngine, const uint8_t *nonce,
586  size_t nonceLen, const uint8_t *aad, size_t aadLen, const uint8_t *data,
587  size_t dataLen, uint8_t *mac)
588 {
589  size_t i;
590  uint8_t mask;
591  HmacContext *hmacContext;
592  uint8_t temp[MAX_HASH_DIGEST_SIZE];
593 
594  //Point to the HMAC context
595  hmacContext = decryptionEngine->hmacContext;
596 
597  //The protect operation provides the integrity protection using HMAC SHA-256
598  //or HMAC SHA-384 (refer to RFC 9150, section 5)
599  hmacInit(hmacContext, decryptionEngine->hashAlgo,
600  decryptionEngine->encKey, decryptionEngine->encKeyLen);
601 
602  //Compute HMAC(write_key, nonce || additional_data || DTLSInnerPlaintext)
603  hmacUpdate(hmacContext, nonce, nonceLen);
604  hmacUpdate(hmacContext, aad, aadLen);
605  hmacUpdate(hmacContext, data, dataLen);
606 
607  //Finalize HMAC computation
608  hmacFinal(hmacContext, temp);
609 
610  //The calculated MAC is bitwise compared to the received message
611  //authentication code
612  for(mask = 0, i = 0; i < decryptionEngine->hashAlgo->digestSize; i++)
613  {
614  mask |= mac[i] ^ temp[i];
615  }
616 
617  //The message is authenticated if and only if the MAC values match
618  return (mask == 0) ? NO_ERROR : ERROR_BAD_RECORD_MAC;
619 }
620 
621 
622 /**
623  * @brief Decrypt sequence number
624  * @param[in] decryptionEngine Pointer to the decryption engine
625  * @param[in,out] record Pointer to the DTLS 1.3 record
626  * @return Error code
627  **/
628 
630  uint8_t *record)
631 {
632  error_t error;
633  size_t n;
634  uint8_t mask[16];
635 
636  //Initialize status code
637  error = NO_ERROR;
638 
639  //The DTLS 1.3 unified header is a structure of variable length
640  n = sizeof(uint8_t);
641 
642  //The record sequence number is 16 bits if the S bit is set to 1, and 8 bits
643  //if the S bit is 0
644  if((record[0] & DTLS13_HEADER_FLAG_S) != 0)
645  {
646  n += sizeof(uint16_t);
647  }
648  else
649  {
650  n += sizeof(uint8_t);
651  }
652 
653  //The length field is present if the L bit is set
654  if((record[0] & DTLS13_HEADER_FLAG_L) != 0)
655  {
656  n += sizeof(uint16_t);
657  }
658 
659 #if (TLS_CCM_CIPHER_SUPPORT == ENABLED || TLS_CCM_8_CIPHER_SUPPORT == ENABLED || \
660  TLS_GCM_CIPHER_SUPPORT == ENABLED)
661  //CCM or GCM AEAD cipher?
662  if(decryptionEngine->cipherMode == CIPHER_MODE_CCM ||
663  decryptionEngine->cipherMode == CIPHER_MODE_GCM)
664  {
665  //When the AEAD is based on AES, then the mask is generated by computing
666  //AES-ECB on the first 16 bytes of the ciphertext (refer to RFC 9147,
667  //section 4.2.3)
668  decryptionEngine->cipherAlgo->encryptBlock(
669  decryptionEngine->snCipherContext, record + n, mask);
670  }
671  else
672 #endif
673 #if (TLS_CHACHA20_POLY1305_SUPPORT == ENABLED)
674  //ChaCha20Poly1305 AEAD cipher?
675  if(decryptionEngine->cipherMode == CIPHER_MODE_CHACHA20_POLY1305)
676  {
677  ChachaContext chachaContext;
678 
679  //When the AEAD is based on ChaCha20, then the mask is generated by
680  //treating the first 4 bytes of the ciphertext as the block counter and
681  //the next 12 bytes as the nonce
682  error = chachaInit(&chachaContext, 20, decryptionEngine->snKey,
683  decryptionEngine->encKeyLen, record + n, 16);
684 
685  //Check status code
686  if(!error)
687  {
688  //Invoke ChaCha20 block function
689  chachaCipher(&chachaContext, NULL, mask, 2);
690  }
691  }
692  else
693 #endif
694 #if (TLS_NULL_CIPHER_SUPPORT == ENABLED)
695  //NULL cipher?
696  if(decryptionEngine->cipherMode == CIPHER_MODE_NULL)
697  {
698  //For integrity-only cipher suites, the record sequence numbers are sent
699  //unencrypted (refer to RFC 9150, section 9)
700  mask[0] = 0;
701  mask[1] = 0;
702  }
703  else
704 #endif
705  //Invalid cipher mode?
706  {
707  //The specified cipher mode is not supported
709  }
710 
711  //Check status code
712  if(!error)
713  {
714  //The encrypted sequence number is computed by XORing the leading bytes
715  //of the mask with the on-the-wire representation of the sequence number
716  if((record[0] & DTLS13_HEADER_FLAG_S) != 0)
717  {
718  record[1] ^= mask[0];
719  record[2] ^= mask[1];
720  }
721  else
722  {
723  record[1] ^= mask[0];
724  }
725  }
726 
727  //Return status code
728  return error;
729 }
730 
731 
732 /**
733  * @brief Sequence number reconstruction
734  * @param[in] decryptionEngine Pointer to the decryption engine
735  * @param[in,out] record Pointer to the DTLS 1.3 record
736  * @param[out] seqNum Reconstructed sequence number
737  **/
738 
740  const uint8_t *record, DtlsSequenceNumber *seqNum)
741 {
742  uint64_t n;
743  uint64_t n1;
744  uint64_t n2;
745  uint64_t n3;
746  uint64_t delta1;
747  uint64_t delta2;
748  uint64_t delta3;
749  uint64_t mask;
750  uint64_t next;
751 
752  //The record sequence number is 16 bits if the S bit is set to 1, and 8 bits
753  //if the S bit is 0
754  if((record[0] & DTLS13_HEADER_FLAG_S) != 0)
755  {
756  //Retrieve the low-order 16 bits of the record sequence number
757  n = LOAD16BE(record + 1);
758  mask = 0xFFFF;
759  }
760  else
761  {
762  //Retrieve the low-order 8 bits of the record sequence number
763  n = record[1];
764  mask = 0xFF;
765  }
766 
767  //Implementations should reconstruct the sequence number by computing the
768  //full sequence number which is numerically closest to one plus the
769  //sequence number of the highest successfully deprotected record in the
770  //current epoch (refer to RFC 9147, section 4.2.2)
771  next = LOAD48BE(decryptionEngine->dtlsSeqNum.b) + 1;
772 
773  //Compute the 3 possible full sequence numbers
774  n1 = ((next & ~mask) - (mask + 1)) | n;
775  n2 = (next & ~mask) | n;
776  n3 = ((next & ~mask) + (mask + 1)) | n;
777 
778  //Enforce the DTLS 1.2 2^48-1 limit
782 
783  //Compute the corresponding deltas
784  delta1 = (n1 > next) ? (n1 - next) : (next - n1);
785  delta2 = (n2 > next) ? (n2 - next) : (next - n2);
786  delta3 = (n3 > next) ? (n3 - next) : (next - n3);
787 
788  //Determine the full sequence number which is numerically closest
789  if(delta3 <= delta1 && delta3 <= delta2)
790  {
791  STORE48BE(n3, seqNum->b);
792  }
793  else if(delta2 <= delta1 && delta2 <= delta3)
794  {
795  STORE48BE(n2, seqNum->b);
796  }
797  else
798  {
799  STORE48BE(n1, seqNum->b);
800  }
801 }
802 
803 #endif
#define TLS_MAX_RECORD_LENGTH
Definition: tls.h:994
__weak_func error_t ccmDecrypt(const CipherAlgo *cipher, void *context, const uint8_t *n, size_t nLen, const uint8_t *a, size_t aLen, const uint8_t *c, uint8_t *p, size_t length, const uint8_t *t, size_t tLen)
Authenticated decryption using CCM.
Definition: ccm.c:208
HMAC algorithm context.
Definition: hmac.h:59
@ ERROR_VERSION_NOT_SUPPORTED
Definition: error.h:67
@ ERROR_UNEXPECTED_MESSAGE
Definition: error.h:195
DtlsRecord
Definition: dtls_misc.h:185
#define STORE48BE(a, p)
Definition: cpu_endian.h:302
@ CIPHER_MODE_GCM
Definition: crypto.h:1068
Collection of AEAD algorithms.
uint8_t data[]
Definition: ethernet.h:224
@ TLS_TYPE_HANDSHAKE
Definition: tls.h:1087
error_t dtls13ReadRecord(TlsContext *context)
Receive a DTLS 1.3 record.
@ TLS_STATE_APPLICATION_DATA
Definition: tls.h:1589
uint8_t type
Definition: coap_common.h:176
@ TLS_TYPE_ACK
Definition: tls.h:1091
@ ERROR_BAD_RECORD_MAC
Definition: error.h:232
void dtlsUpdateReplayWindow(TlsEncryptionEngine *decryptionEngine, const DtlsSequenceNumber *seqNum)
Update sliding window.
Definition: dtls_misc.c:581
#define DTLS13_HEADER_MASK
Definition: dtls13_misc.h:45
void chachaCipher(ChachaContext *context, const uint8_t *input, uint8_t *output, size_t length)
Encrypt/decrypt data with the ChaCha algorithm.
Definition: chacha.c:192
error_t dtlsCheckReplayWindow(TlsEncryptionEngine *decryptionEngine, const DtlsSequenceNumber *seqNum)
Perform replay detection.
Definition: dtls_misc.c:506
error_t dtls13ReadCiphertextRecord(TlsContext *context, uint8_t *record)
Receive a DTLSCiphertext record.
#define MAX_HASH_DIGEST_SIZE
@ ERROR_UNSUPPORTED_CIPHER_MODE
Definition: error.h:128
#define DTLS_VERSION_1_0
Definition: dtls_misc.h:35
error_t chachaInit(ChachaContext *context, uint_t nr, const uint8_t *key, size_t keyLen, const uint8_t *nonce, size_t nonceLen)
Initialize ChaCha context using the supplied key and nonce.
Definition: chacha.c:70
#define TlsContext
Definition: tls.h:36
error_t
Error codes.
Definition: error.h:43
uint32_t seqNum
Definition: tcp.h:348
#define TLS_MAX_DECRYPTION_ENGINES
Definition: tls.h:981
#define DTLS_MAX_SEQUENCE_NUMBER
Definition: dtls_misc.h:112
DTLS 1.3 (Datagram Transport Layer Security)
@ TLS_TYPE_ALERT
Definition: tls.h:1086
@ ERROR_INVALID_LENGTH
Definition: error.h:111
uint16_t epoch
Definition: dtls_misc.h:181
#define DTLS13_HEADER_FLAG_C
Definition: dtls13_misc.h:47
uint8_t mask
Definition: web_socket.h:319
#define MSB(x)
Definition: os_port.h:59
void dtls13ReconstructSequenceNumber(TlsEncryptionEngine *decryptionEngine, const uint8_t *record, DtlsSequenceNumber *seqNum)
Sequence number reconstruction.
#define LOAD48BE(p)
Definition: cpu_endian.h:226
void dtls13FormatNonce(TlsEncryptionEngine *encryptionEngine, const DtlsSequenceNumber *seqNum, uint8_t *nonce, size_t *nonceLen)
Format nonce.
Definition: dtls13_misc.c:381
#define DTLS13_HEADER_FIXED
Definition: dtls13_misc.h:46
uint32_t dataLen
Definition: sftp_common.h:229
ChaCha algorithm context.
Definition: chacha.h:48
@ ERROR_INVALID_EPOCH
Definition: error.h:108
#define ntohs(value)
Definition: cpu_endian.h:421
__weak_func void hmacUpdate(HmacContext *context, const void *data, size_t length)
Update the HMAC context with a portion of the message being hashed.
Definition: hmac.c:201
#define TRACE_DEBUG(...)
Definition: debug.h:119
@ CIPHER_MODE_CCM
Definition: crypto.h:1067
TlsContentType
Content type.
Definition: tls.h:1083
#define TRACE_DEBUG_ARRAY(p, a, n)
Definition: debug.h:120
error_t dtls13VerifyMac(TlsContext *context, TlsEncryptionEngine *decryptionEngine, const uint8_t *nonce, size_t nonceLen, const uint8_t *aad, size_t aadLen, const uint8_t *data, size_t dataLen, uint8_t *mac)
Check message authentication code.
uint8_t n
#define DTLS_VERSION_1_3
Definition: dtls_misc.h:37
__weak_func void hmacFinal(HmacContext *context, uint8_t *digest)
Finish the HMAC calculation.
Definition: hmac.c:218
error_t dtls13DecryptRecord(TlsContext *context, TlsEncryptionEngine *decryptionEngine, const uint8_t *nonce, size_t nonceLen, const uint8_t *aad, size_t aadLen, uint8_t *data, size_t *dataLen, uint8_t *type)
Decrypt an incoming DTLS 1.3 record.
@ TLS_STATE_CLIENT_FINISHED_ACK
Definition: tls.h:1590
error_t dtls13ReadPlaintextRecord(TlsContext *context, uint8_t *record)
Receive a DTLSPlaintext record.
DtlsSequenceNumber
Definition: dtls_misc.h:148
#define DTLS13_HEADER_FLAG_E
Definition: dtls13_misc.h:50
TLS (Transport Layer Security)
@ CIPHER_MODE_NULL
Definition: crypto.h:1060
@ CIPHER_MODE_CHACHA20_POLY1305
Definition: crypto.h:1070
@ ERROR_RECORD_OVERFLOW
Definition: error.h:233
#define PRIuSIZE
error_t chacha20Poly1305Decrypt(const uint8_t *k, size_t kLen, const uint8_t *n, size_t nLen, const uint8_t *a, size_t aLen, const uint8_t *c, uint8_t *p, size_t length, const uint8_t *t, size_t tLen)
Authenticated decryption using ChaCha20Poly1305.
unsigned int uint_t
Definition: compiler_port.h:57
#define LOAD16BE(p)
Definition: cpu_endian.h:186
#define DTLS13_HEADER_FLAG_L
Definition: dtls13_misc.h:49
__weak_func error_t hmacInit(HmacContext *context, const HashAlgo *hash, const void *key, size_t keyLen)
Initialize HMAC calculation.
Definition: hmac.c:140
#define DTLS13_HEADER_FLAG_S
Definition: dtls13_misc.h:48
@ TLS_STATE_KEY_UPDATE_ACK
Definition: tls.h:1593
__weak_func error_t gcmDecrypt(GcmContext *context, const uint8_t *iv, size_t ivLen, const uint8_t *a, size_t aLen, const uint8_t *c, uint8_t *p, size_t length, const uint8_t *t, size_t tLen)
Authenticated decryption using GCM.
Definition: gcm.c:356
error_t dtls13DecryptAeadRecord(TlsContext *context, TlsEncryptionEngine *decryptionEngine, const uint8_t *nonce, size_t nonceLen, const uint8_t *aad, size_t aadLen, uint8_t *data, size_t dataLen, uint8_t *tag)
Record decryption (AEAD cipher)
error_t dtls13DecryptSequenceNumber(TlsEncryptionEngine *decryptionEngine, uint8_t *record)
Decrypt sequence number.
uint16_t next
Definition: ipv4_frag.h:106
#define TlsEncryptionEngine
Definition: tls.h:40
uint8_t nonce[]
Definition: ntp_common.h:239
@ NO_ERROR
Success.
Definition: error.h:44
Debugging facilities.
@ TLS_STATE_NEW_SESSION_TICKET_ACK
Definition: tls.h:1591
DTLS 1.3 record decryption.
systime_t osGetSystemTime(void)
Retrieve system time.