dtls_record.c
Go to the documentation of this file.
1 /**
2  * @file dtls_record.c
3  * @brief DTLS record layer
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"
36 #include "tls/tls_common.h"
37 #include "tls/tls_record.h"
38 #include "tls/tls_record_encrypt.h"
39 #include "tls/tls_record_decrypt.h"
40 #include "tls/tls_misc.h"
42 #include "dtls/dtls_misc.h"
43 #include "dtls/dtls_record.h"
46 #include "dtls13/dtls13_misc.h"
47 #include "debug.h"
48 
49 //Check TLS library configuration
50 #if (TLS_SUPPORT == ENABLED && DTLS_SUPPORT == ENABLED)
51 
52 
53 /**
54  * @brief Write protocol data
55  * @param[in] context Pointer to the TLS context
56  * @param[in] data Pointer to the data buffer
57  * @param[in] length Number of data bytes to be written
58  * @param[in] contentType Higher level protocol
59  * @return Error code
60  **/
61 
63  const uint8_t *data, size_t length, TlsContentType contentType)
64 {
65  error_t error;
66  DtlsRetransmitState state;
67 
68  //Prepare DTLS record
69  error = dtlsWriteRecord(context, data, length, contentType);
70 
71  //Check status code
72  if(!error)
73  {
74  //DTLS operates as a client or a server?
75  if(context->entity == TLS_CONNECTION_END_CLIENT)
76  {
77  //Client messages are grouped into a series of message flights
78  if(context->state == TLS_STATE_CLIENT_HELLO ||
79  context->state == TLS_STATE_CLIENT_HELLO_2 ||
80  context->state == TLS_STATE_CLIENT_FINISHED ||
81  context->state == TLS_STATE_KEY_UPDATE)
82  {
84  }
85  else
86  {
88  }
89  }
90  else
91  {
92  //Server messages are grouped into a series of message flights
93  if(context->state == TLS_STATE_HELLO_VERIFY_REQUEST ||
94  context->state == TLS_STATE_HELLO_RETRY_REQUEST ||
95  context->state == TLS_STATE_SERVER_HELLO_DONE ||
96  context->state == TLS_STATE_SERVER_FINISHED ||
97  context->state == TLS_STATE_KEY_UPDATE)
98  {
100  }
101  else if(context->state == TLS_STATE_NEW_SESSION_TICKET_2)
102  {
103 #if (TLS_MAX_VERSION >= TLS_VERSION_1_3 && TLS_MIN_VERSION <= TLS_VERSION_1_3)
104  //A server may send multiple NewSessionTicket messages at once
105  //without awaiting ACKs for earlier NewSessionTicket messages
106  //first (refer to RFC 9147, section 5.8.4)
107  if(context->newSessionTicketCount >= TLS13_NEW_SESSION_TICKET_COUNT)
108  {
110  }
111  else
112 #endif
113  {
115  }
116  }
117  else
118  {
120  }
121  }
122 
123  //Check retransmission state
124  if(state == DTLS_RETRANSMIT_STATE_SENDING)
125  {
126  //Reset retransmission counter
127  context->retransmitCount = 0;
128  //Implementations should use an initial timer value of 1 second
129  context->retransmitTimeout = DTLS_INIT_TIMEOUT;
130 
131  //In the SENDING state, the implementation transmits the buffered
132  //flight of messages (refer to RFC 6347, section 4.2.4)
133  error = dtlsSendFlight(context);
134 
135  //Timeout and retransmission do not apply to HelloVerifyRequest and
136  //HelloRetryRequest messages, because this would require creating
137  //state on the server
138  if(context->state == TLS_STATE_HELLO_VERIFY_REQUEST ||
139  context->state == TLS_STATE_HELLO_RETRY_REQUEST)
140  {
141  context->txBufferLen = 0;
142  }
143 
144 #if (TLS_MAX_VERSION >= TLS_VERSION_1_3 && TLS_MIN_VERSION <= TLS_VERSION_1_3)
145  //Implementations must clear their ACK list upon receiving the start
146  //of the next flight (refer to RFC 9147, section 7)
147  context->numAckRecords = 0;
148  context->ackTimerRunning = FALSE;
149 #endif
150  }
151  }
152 
153  //Return status code
154  return error;
155 }
156 
157 
158 /**
159  * @brief Read protocol data
160  * @param[in] context Pointer to the TLS context
161  * @param[out] data Pointer to the received data
162  * @param[out] length Number of data bytes that were received
163  * @param[out] contentType Higher level protocol
164  * @return Error code
165  **/
166 
168  uint8_t **data, size_t *length, TlsContentType *contentType)
169 {
170  error_t error;
171 
172  //Initialize status code
173  error = NO_ERROR;
174 
175  //Receive process
176  while(error == NO_ERROR)
177  {
178  if(context->rxBufferLen > 0)
179  {
180  //Pass the received data to the higher layer
181  break;
182  }
183  else if(context->rxRecordLen > 0)
184  {
185  //Process the incoming DTLS record
186  error = dtlsProcessRecord(context);
187 
188  //Invalid record?
189  if(error)
190  {
191  //Debug message
192  TRACE_WARNING("Discarding DTLS record!\r\n");
193 
194  //DTLS implementations should silently discard records with bad MACs
195  //and continue with the connection
196  error = NO_ERROR;
197  }
198  }
199  else if(context->rxDatagramLen > 0)
200  {
201 #if (TLS_MAX_VERSION >= TLS_VERSION_1_3 && TLS_MIN_VERSION <= TLS_VERSION_1_3)
202  //DTLS 1.3 protocol?
203  if(context->version == TLS_VERSION_1_3)
204  {
205  //Read a new DTLS 1.3 record from the datagram
206  error = dtls13ReadRecord(context);
207  }
208  else
209 #endif
210  {
211  //Read a new DTLS record from the datagram
212  error = dtlsReadRecord(context);
213  }
214 
215  //Malformed record?
216  if(error != NO_ERROR && error != ERROR_RECORD_OVERFLOW)
217  {
218  //Debug message
219  TRACE_WARNING("Discarding DTLS record!\r\n");
220 
221  //The receiving implementation should discard the offending record
222  error = NO_ERROR;
223  }
224  }
225  else
226  {
227  //Read a new datagram
228  error = dtlsReadDatagram(context, context->rxBuffer + context->rxFragQueueLen,
229  context->rxBufferSize - context->rxFragQueueLen, &context->rxDatagramLen);
230 
231  //Check whether a valid datagram has been received
232  if(!error)
233  {
234  //Make room for the fragment reassembly process
235  context->rxDatagramPos = context->rxBufferSize - context->rxDatagramLen;
236 
237  //Copy the received datagram
238  osMemmove(context->rxBuffer + context->rxDatagramPos,
239  context->rxBuffer + context->rxFragQueueLen, context->rxDatagramLen);
240  }
241  }
242  }
243 
244  //Successful processing?
245  if(!error)
246  {
247 #if (TLS_MAX_WARNING_ALERTS > 0)
248  //Reset the count of consecutive warning alerts
249  if(context->rxBufferType != TLS_TYPE_ALERT)
250  {
251  context->alertCount = 0;
252  }
253 #endif
254 #if (TLS_MAX_KEY_UPDATE_MESSAGES > 0)
255  //Reset the count of consecutive KeyUpdate messages
256  if(context->rxBufferType != TLS_TYPE_HANDSHAKE)
257  {
258  context->keyUpdateCount = 0;
259  }
260 #endif
261 
262  //Pointer to the received data
263  *data = context->rxBuffer + context->rxBufferPos;
264  //Length, in byte, of the data
265  *length = context->rxBufferLen;
266  //Protocol type
267  *contentType = context->rxBufferType;
268  }
269 
270  //Return status code
271  return error;
272 }
273 
274 
275 /**
276  * @brief Send a DTLS record
277  * @param[in] context Pointer to the TLS context
278  * @param[in] data Pointer to the record data
279  * @param[in] length Length of the record data
280  * @param[in] contentType Record type
281  * @return Error code
282  **/
283 
284 error_t dtlsWriteRecord(TlsContext *context, const uint8_t *data,
285  size_t length, TlsContentType contentType)
286 {
287  error_t error;
288  size_t n;
289  uint16_t legacyVersion;
290  DtlsRecord *record;
291  TlsEncryptionEngine *encryptionEngine;
292 
293  //Calculate the length of the DTLSPlaintext record
294  n = length + sizeof(DtlsRecord);
295 
296  //Make sure the buffer is large enough to hold the DTLSPlaintext record
297  if((context->txBufferLen + n) > context->txBufferSize)
298  return ERROR_BUFFER_OVERFLOW;
299 
300 #if (TLS_MAX_VERSION >= TLS_VERSION_1_3 && TLS_MIN_VERSION <= TLS_VERSION_1_3)
301  //Implementations must not send records with the new keys until the previous
302  //KeyUpdate has been acknowledged (refer to RFC 9147, section 8)
303  if(context->version == TLS_VERSION_1_3 &&
304  context->state == TLS_STATE_KEY_UPDATE_ACK)
305  {
306  encryptionEngine = &context->encryptionEngine[1];
307  }
308  else
309 #endif
310  {
311  encryptionEngine = &context->encryptionEngine[0];
312  }
313 
314  //Point to the DTLS record header
315  record = (DtlsRecord *) (context->txBuffer + context->txBufferLen);
316 
317  //Copy record data
318  osMemmove(record->data, data, length);
319 
320  //The record version must be set to {254, 253} for all records generated
321  //by a DTLS 1.3 implementation other than an initial ClientHello
322  legacyVersion = MIN(encryptionEngine->version, TLS_VERSION_1_2);
323  legacyVersion = dtlsTranslateVersion(legacyVersion);
324 
325  //Format DTLSPlaintext structure
326  record->type = contentType;
327  record->version = htons(legacyVersion);
328  record->epoch = htons(encryptionEngine->epoch);
329  record->length = htons(length);
330 
331  //Check record type
332  if(contentType == TLS_TYPE_HANDSHAKE ||
333  contentType == TLS_TYPE_CHANGE_CIPHER_SPEC)
334  {
335  //Sequence numbers are handled at record layer
336  osMemset(&record->seqNum, 0, sizeof(DtlsSequenceNumber));
337 
338  //Adjust the length of the buffered flight of messages
339  context->txBufferLen += n;
340  }
341  else
342  {
343  //This record will have a new sequence number
344  record->seqNum = encryptionEngine->dtlsSeqNum;
345 
346  //Protect record payload?
347  if(encryptionEngine->cipherMode != CIPHER_MODE_NULL ||
348  encryptionEngine->hashAlgo != NULL)
349  {
350 #if (TLS_MAX_VERSION >= TLS_VERSION_1_3 && TLS_MIN_VERSION <= TLS_VERSION_1_3)
351  //DTLS 1.3 protocol?
352  if(context->version == TLS_VERSION_1_3)
353  {
354  //Overhead caused by record encryption must be considered
355  n = length + dtls13ComputeEncryptionOverhead(encryptionEngine);
356 
357  //Make sure the buffer is large enough to hold the DTLSCiphertext
358  //record
359  if((context->txBufferLen + n) > context->txBufferSize)
360  return ERROR_BUFFER_OVERFLOW;
361 
362  //Encrypt DTLS 1.3 record
363  error = dtls13EncryptRecord(context, encryptionEngine, record->type,
364  record->data, ntohs(record->length), (uint8_t *) record, &n);
365  //Any error to report?
366  if(error)
367  return error;
368  }
369  else
370 #endif
371  {
372  //Overhead caused by record encryption must be considered
373  n += tlsComputeEncryptionOverhead(encryptionEngine, n);
374 
375  //Make sure the buffer is large enough to hold the DTLSCiphertext
376  //record
377  if((context->txBufferLen + n) > context->txBufferSize)
378  return ERROR_BUFFER_OVERFLOW;
379 
380  //Encrypt DTLS record
381  error = tlsEncryptRecord(context, encryptionEngine, record);
382  //Any error to report?
383  if(error)
384  return error;
385 
386  //Length of the resulting datagram, in bytes
387  n = ntohs(record->length) + sizeof(DtlsRecord);
388  }
389  }
390  else
391  {
392  //Length of the datagram, in bytes
393  n = ntohs(record->length) + sizeof(DtlsRecord);
394  }
395 
396  //Debug message
397  TRACE_DEBUG("Encrypted DTLS record (%" PRIuSIZE " bytes)...\r\n", n);
398  TRACE_DEBUG_ARRAY(" ", record, n);
399 
400  //Increment sequence number
401  dtlsIncSequenceNumber(&encryptionEngine->dtlsSeqNum);
402 
403  //Debug message
404  TRACE_INFO("Sending UDP datagram (%" PRIuSIZE " bytes)...\r\n", n);
405 
406  //Send datagram
407  error = context->socketSendCallback(context->socketHandle, record, n, &n, 0);
408  //Any error to report?
409  if(error)
410  return error;
411  }
412 
413  //Successful processing
414  return NO_ERROR;
415 }
416 
417 
418 /**
419  * @brief Receive a DTLS record
420  * @param[in] context Pointer to the TLS context
421  * @return Error code
422  **/
423 
425 {
426  error_t error;
427  DtlsRecord *record;
428  size_t recordLen;
429  TlsEncryptionEngine *decryptionEngine;
430 
431  //Point to the decryption engine
432  decryptionEngine = &context->decryptionEngine[0];
433 
434  //Malformed datagram?
435  if(context->rxDatagramLen < sizeof(DtlsRecord))
436  {
437  //Drop the received datagram
438  context->rxDatagramLen = 0;
439  //Report an error
440  return ERROR_INVALID_LENGTH;
441  }
442 
443  //Point to the DTLS record
444  record = (DtlsRecord *) (context->rxBuffer + context->rxDatagramPos);
445  //Retrieve the length of the record
446  recordLen = ntohs(record->length);
447 
448  //Malformed DTLS record?
449  if((recordLen + sizeof(DtlsRecord)) > context->rxDatagramLen)
450  {
451  //Drop the received datagram
452  context->rxDatagramLen = 0;
453  //Report an error
454  return ERROR_INVALID_LENGTH;
455  }
456 
457  //Debug message
458  TRACE_DEBUG("DTLS encrypted record received (%" PRIuSIZE " bytes)...\r\n", recordLen);
459  TRACE_DEBUG_ARRAY(" ", record, recordLen + sizeof(DtlsRecord));
460 
461  //Point to the payload data
462  context->rxRecordPos = context->rxDatagramPos + sizeof(DtlsRecord);
463 
464  //It is acceptable to pack multiple DTLS records in the same datagram
465  context->rxDatagramPos += recordLen + sizeof(DtlsRecord);
466  context->rxDatagramLen -= recordLen + sizeof(DtlsRecord);
467 
468  //Compliant servers must accept any value {254,XX} as the record layer
469  //version number for ClientHello
470  if(MSB(ntohs(record->version)) != MSB(DTLS_VERSION_1_0))
472 
473  //Discard packets from earlier epochs
474  if(ntohs(record->epoch) != decryptionEngine->epoch)
475  return ERROR_INVALID_EPOCH;
476 
477  //Check whether anti-replay mechanism is enabled
478  if(context->replayDetectionEnabled)
479  {
480  //Perform replay detection
481  error = dtlsCheckReplayWindow(decryptionEngine, &record->seqNum);
482  //Any error to report?
483  if(error)
484  return error;
485  }
486 
487  //Check whether the record payload is protected
488  if(decryptionEngine->cipherMode != CIPHER_MODE_NULL ||
489  decryptionEngine->hashAlgo != NULL)
490  {
491  //Decrypt DTLS record
492  error = tlsDecryptRecord(context, decryptionEngine, record);
493  //If the MAC validation fails, the receiver must discard the record
494  if(error)
495  return error;
496 
497  //The length of the plaintext record must not exceed 2^14 bytes
498  if(ntohs(record->length) > TLS_MAX_RECORD_LENGTH)
499  return ERROR_RECORD_OVERFLOW;
500  }
501 
502  //The receive window is updated only if the MAC verification succeeds
503  dtlsUpdateReplayWindow(decryptionEngine, &record->seqNum);
504 
505  //Retrieve the length of the record
506  recordLen = ntohs(record->length);
507 
508  //Debug message
509  TRACE_DEBUG("DTLS decrypted record received (%" PRIuSIZE " bytes)...\r\n", recordLen);
510  TRACE_DEBUG_ARRAY(" ", record, recordLen + sizeof(DtlsRecord));
511 
512  //Save record version
513  context->rxRecordVersion = ntohs(record->version);
514  //Save record type
515  context->rxBufferType = (TlsContentType) record->type;
516  //Save record length
517  context->rxRecordLen = recordLen;
518 
520  //Save record number
521  context->rxRecordNum.epoch = ntohs(record->epoch);
522  context->rxRecordNum.seqNum = LOAD48BE(record->seqNum.b);
523 #endif
524 
525  //Successful processing
526  return NO_ERROR;
527 }
528 
529 
530 /**
531  * @brief Process incoming DTLS record
532  * @param[in] context Pointer to the TLS context
533  * @return Error code
534  **/
535 
537 {
538  error_t error;
539  systime_t time;
540 
541  //Handshake message received?
542  if(context->rxBufferType == TLS_TYPE_HANDSHAKE)
543  {
544  size_t length;
545  size_t fragLen;
547 
548  //Make sure the DTLS record is large enough to hold a handshake message
549  if(context->rxRecordLen < sizeof(DtlsHandshake))
550  {
551  //Drop the received DTLS record
552  context->rxRecordLen = 0;
553  //Report an error
554  return ERROR_INVALID_LENGTH;
555  }
556 
557  //Point to the handshake message
558  message = (DtlsHandshake *) (context->rxBuffer + context->rxRecordPos);
559 
560  //Debug message
561  TRACE_DEBUG("Handshake message fragment received (%" PRIuSIZE " bytes)...\r\n",
562  LOAD24BE(message->fragLength));
563  TRACE_DEBUG(" msgType = %u\r\n", message->msgType);
564  TRACE_DEBUG(" msgSeq = %u\r\n", ntohs(message->msgSeq));
565  TRACE_DEBUG(" fragOffset = %u\r\n", LOAD24BE(message->fragOffset));
566  TRACE_DEBUG(" fragLength = %u\r\n", LOAD24BE(message->fragLength));
567  TRACE_DEBUG(" length = %u\r\n", LOAD24BE(message->length));
568 
569  //Retrieve fragment length
570  fragLen = LOAD24BE(message->fragLength) + sizeof(DtlsHandshake);
571 
572  //Sanity check
573  if(fragLen > context->rxRecordLen)
574  {
575  //Drop the received DTLS record
576  context->rxRecordLen = 0;
577  //Report an error
578  return ERROR_INVALID_LENGTH;
579  }
580 
581  //It is acceptable to pack multiple handshake messages in the same record
582  context->rxRecordPos += fragLen;
583  context->rxRecordLen -= fragLen;
584 
585  //Invalid fragment length?
586  if(LOAD24BE(message->fragLength) > LOAD24BE(message->length))
587  return ERROR_INVALID_LENGTH;
588 
589  //Empty fragment?
590  if(LOAD24BE(message->fragLength) == 0 && LOAD24BE(message->length) != 0)
591  return ERROR_INVALID_LENGTH;
592 
593  //Check whether TLS operates as a client or a server
594  if(context->entity == TLS_CONNECTION_END_CLIENT)
595  {
596  //HelloRequest message received?
597  if(message->msgType == TLS_TYPE_HELLO_REQUEST &&
598  context->state == TLS_STATE_APPLICATION_DATA)
599  {
600  //Re-initialize message sequence numbers
601  context->rxMsgSeq = ntohs(message->msgSeq);
602  context->txMsgSeq = 0;
603  }
604  }
605  else
606  {
607  //ClientHello message received?
608  if(message->msgType == TLS_TYPE_CLIENT_HELLO &&
609  context->state == TLS_STATE_CLIENT_HELLO)
610  {
611  //Initial handshake?
612  if(context->decryptionEngine[0].epoch == 0)
613  {
614  //DTLS 1.2 adds a record sequence number mirroring technique
615  //for handling repeated ClientHello messages (refer to RFC 6347,
616  //section 8)
617  context->encryptionEngine[0].dtlsSeqNum =
618  context->decryptionEngine[0].dtlsSeqNum;
619 
620  //Re-initialize message sequence numbers
621  context->rxMsgSeq = ntohs(message->msgSeq);
622  context->txMsgSeq = ntohs(message->msgSeq);
623  }
624  }
625  }
626 
627 #if (TLS_MAX_VERSION >= TLS_VERSION_1_3 && TLS_MIN_VERSION <= TLS_VERSION_1_3)
628  //DTLS 1.3 protocol?
629  if(context->version == TLS_VERSION_1_3)
630  {
631  //DTLS 1.3 assigns dedicated epoch values to messages in the protocol
632  //exchange to allow identification of the correct cipher state (refer
633  //to RFC 9147, section 6.1)
634  if(message->msgType == TLS_TYPE_CLIENT_HELLO ||
635  message->msgType == TLS_TYPE_SERVER_HELLO ||
637  {
638  //Epoch value 0 is used with unencrypted messages
639  if(context->rxRecordNum.epoch != 0)
640  return ERROR_INVALID_EPOCH;
641  }
642  else if(message->msgType == TLS_TYPE_NEW_SESSION_TICKET ||
644  message->msgType == TLS_TYPE_NEW_CONNECTION_ID ||
645  message->msgType == TLS_TYPE_KEY_UPDATE)
646  {
647  //Epoch values 3 to 2^64-1 are used for post-handshake messages
648  if(context->rxRecordNum.epoch < 3)
649  return ERROR_INVALID_EPOCH;
650  }
651  else
652  {
653  //Epoch value 2 is used for messages transmitted during the initial
654  //handshake
655  if(context->rxRecordNum.epoch != 2)
656  return ERROR_INVALID_EPOCH;
657  }
658 
659  //Check current state
660  if(context->state != TLS_STATE_SERVER_HELLO &&
661  context->state != TLS_STATE_SERVER_HELLO_2 &&
662  context->state != TLS_STATE_CLIENT_FINISHED_ACK)
663  {
664  //Check whether the sequence number of the received message matches
665  //the expected value
666  if(ntohs(message->msgSeq) == context->rxMsgSeq)
667  {
668  //Receiving a message from a handshake flight implicitly
669  //acknowledges all messages from the previous flight (refer to
670  //RFC 9147, section 7)
671  context->txBufferLen = 0;
672  }
673  }
674  }
675 
676  //Check whether DTLS 1.3 is supported
677  if(context->versionMax >= TLS_VERSION_1_3 &&
678  context->versionMin <= TLS_VERSION_1_3)
679  {
680  //Implementations must not send ACKs for handshake messages which they
681  //discard because they are not the next expected message (refer to
682  //RFC 9147, section 7)
683  if(ntohs(message->msgSeq) <= context->rxMsgSeq)
684  {
685  dtls13SaveRecordNumber(context, context->rxRecordNum.epoch,
686  context->rxRecordNum.seqNum);
687  }
688  }
689 #endif
690 
691  //When a peer receives a handshake message, it can quickly determine
692  //whether that message is the next message it expects
693  if(ntohs(message->msgSeq) < context->rxMsgSeq)
694  {
695  //Retransmitted flight from the peer?
696  if(message->msgType == TLS_TYPE_CLIENT_HELLO ||
697  message->msgType == TLS_TYPE_SERVER_HELLO_DONE ||
698  message->msgType == TLS_TYPE_FINISHED)
699  {
700  //First fragment of the handshake message?
701  if(LOAD24BE(message->fragOffset) == 0)
702  {
703  //Check whether a flight of messages is buffered
704  if(context->txBufferLen > 0)
705  {
706  //Get current time
707  time = osGetSystemTime();
708 
709  //Send only one response in the case multiple retransmitted
710  //flights are received from the peer
711  if((time - context->retransmitTimestamp) >= DTLS_MIN_TIMEOUT)
712  {
713  //The implementation transitions to the SENDING state,
714  //where it retransmits the flight, resets the retransmit
715  //timer, and returns to the WAITING state
716  if(context->retransmitCount < DTLS_MAX_RETRIES)
717  {
718  dtlsSendFlight(context);
719  }
720  }
721  }
722  }
723  }
724 
725  //If the sequence number of the received message is less than the
726  //expected value, the message must be discarded
728  }
729  else if(ntohs(message->msgSeq) > context->rxMsgSeq)
730  {
731  //If the sequence number of the received message is greater than the
732  //expected value, the implementation may discard it
734  }
735  else
736  {
737  //If the sequence number of the received message matches the expected
738  //value, the message is processed
739  }
740 
741  //Check current state
742  if(context->state > TLS_STATE_SERVER_HELLO_2)
743  {
744  //Once the server has sent the ServerHello message, enforce the version
745  //of incoming records
746  if(context->rxRecordVersion != dtlsTranslateVersion(context->version))
748  }
749 
750  //When a DTLS implementation receives a handshake message fragment, it
751  //must buffer it until it has the entire handshake message. DTLS
752  //implementations must be able to handle overlapping fragment ranges
753  error = dtlsReassembleHandshakeMessage(context, message);
754  //Unacceptable message received?
755  if(error)
756  {
757  //Flush the reassembly queue
758  context->rxFragQueueLen = 0;
759  //Report an error
760  return error;
761  }
762 
763  //Point to the first fragment of the reassembly queue
764  message = (DtlsHandshake *) context->rxBuffer;
765  //Retrive the length of the handshake message
766  length = LOAD24BE(message->length);
767 
768  //An unfragmented message is a degenerate case with fragment_offset = 0
769  //and fragment_length = length
770  if(LOAD24BE(message->fragOffset) == 0 &&
771  LOAD24BE(message->fragLength) == length)
772  {
773  //The reassembly process is now complete
774  context->rxFragQueueLen = 0;
775 
776  //Number of bytes available for reading
777  context->rxBufferLen = length + sizeof(DtlsHandshake);
778  //Rewind to the beginning of the buffer
779  context->rxBufferPos = 0;
780 
781  //The message sequence number is incremented by one
782  context->rxMsgSeq++;
783 
784  //Version of TLS prior to TLS 1.3?
785  if(context->version <= TLS_VERSION_1_2)
786  {
787  //Check whether a complete flight of messages has been received
788  if(message->msgType == TLS_TYPE_CLIENT_HELLO ||
790  message->msgType == TLS_TYPE_SERVER_HELLO_DONE ||
791  message->msgType == TLS_TYPE_FINISHED)
792  {
793  //Exit from the WAITING state
794  context->txBufferLen = 0;
795  }
796  }
797  }
798  }
799  else
800  {
801  //ChangeCipherSpec message received?
802  if(context->rxBufferType == TLS_TYPE_CHANGE_CIPHER_SPEC)
803  {
804  //Malformed ChangeCipherSpec message?
805  if(context->rxRecordLen < sizeof(TlsChangeCipherSpec))
806  {
807  //Drop the received DTLS record
808  context->rxRecordLen = 0;
809  //Report an error
810  return ERROR_INVALID_LENGTH;
811  }
812 
813  //DTLS operates as a client or a server?
814  if(context->entity == TLS_CONNECTION_END_CLIENT)
815  {
816  //Check current state
817  if(context->state != TLS_STATE_SERVER_CHANGE_CIPHER_SPEC)
818  {
819  //Drop the received DTLS record
820  context->rxRecordLen = 0;
821  //Report an error
823  }
824  }
825  else
826  {
827  //Check current state
828  if(context->state != TLS_STATE_CLIENT_CHANGE_CIPHER_SPEC)
829  {
830  //Drop the received DTLS record
831  context->rxRecordLen = 0;
832  //Report an error
834  }
835  }
836 
837  //Enforce the version the received DTLS record
838  if(context->rxRecordVersion != dtlsTranslateVersion(context->version))
839  {
840  //Drop the received DTLS record
841  context->rxRecordLen = 0;
842  //Report an error
844  }
845  }
846  //Alert message received?
847  else if(context->rxBufferType == TLS_TYPE_ALERT)
848  {
849  //Malformed Alert message?
850  if(context->rxRecordLen < sizeof(TlsAlert))
851  {
852  //Drop the received DTLS record
853  context->rxRecordLen = 0;
854  //Report an error
855  return ERROR_INVALID_LENGTH;
856  }
857  }
858  //Application data received?
859  else if(context->rxBufferType == TLS_TYPE_APPLICATION_DATA)
860  {
861  //Check current state
862  if(context->state == TLS_STATE_APPLICATION_DATA ||
863  context->state == TLS_STATE_CLIENT_FINISHED_ACK ||
864  context->state == TLS_STATE_NEW_SESSION_TICKET_ACK ||
865  context->state == TLS_STATE_KEY_UPDATE_ACK)
866  {
867  //Version of TLS prior to TLS 1.3?
868  if(context->version <= TLS_VERSION_1_2)
869  {
870  //The last flight of messages has been received by the peer
871  context->txBufferLen = 0;
872  }
873  }
874  else
875  {
876  //Drop the received DTLS record
877  context->rxRecordLen = 0;
878  //Report an error
880  }
881 
882  //Enforce the version the received DTLS record
883  if(context->rxRecordVersion != dtlsTranslateVersion(context->version))
884  {
885  //Drop the received DTLS record
886  context->rxRecordLen = 0;
887  //Report an error
889  }
890 
891 #if (TLS_MAX_VERSION >= TLS_VERSION_1_3 && TLS_MIN_VERSION <= TLS_VERSION_1_3)
892  //DTLS 1.3 assigns dedicated epoch values to messages in the protocol
893  //exchange to allow identification of the correct cipher state (refer
894  //to RFC 9147, section 6.1)
895  if(context->version == TLS_VERSION_1_3)
896  {
897  //Epoch values 3 to 2^64-1 are used for application data messages
898  if(context->rxRecordNum.epoch < 3)
899  {
900  //Drop the received DTLS record
901  context->rxRecordLen = 0;
902  //Report an error
903  return ERROR_INVALID_EPOCH;
904  }
905  }
906 #endif
907  }
908  //ACK message received?
909  else if(context->rxBufferType == TLS_TYPE_ACK)
910  {
911  //Malformed ACK message?
912  if(context->rxRecordLen < sizeof(Dtls13Ack))
913  {
914  //Drop the received DTLS record
915  context->rxRecordLen = 0;
916  //Report an error
917  return ERROR_INVALID_LENGTH;
918  }
919  }
920  //Unknown content type?
921  else
922  {
923  //Drop the received DTLS record
924  context->rxRecordLen = 0;
925  //Report an error
927  }
928 
929  //Number of bytes available for reading
930  context->rxBufferLen = context->rxRecordLen;
931  //Rewind to the beginning of the buffer
932  context->rxBufferPos = 0;
933 
934  //Copy application data
935  osMemcpy(context->rxBuffer, context->rxBuffer + context->rxRecordPos,
936  context->rxRecordLen);
937 
938  //The DTLS record has been entirely processed
939  context->rxRecordLen = 0;
940  //Flush the reassembly queue
941  context->rxFragQueueLen = 0;
942  }
943 
944  //Successful processing
945  return NO_ERROR;
946 }
947 
948 
949 /**
950  * @brief Send the buffered flight of messages
951  * @param[in] context Pointer to the TLS context
952  * @return Error code
953  **/
954 
956 {
957  error_t error;
958  uint_t i;
959  size_t n;
960  size_t pmtu;
961  uint8_t *datagram;
962  DtlsRecord *record;
964  TlsEncryptionEngine *encryptionEngine;
965 
966  //Determine the value of the PMTU
967  pmtu = MIN(context->pmtu, context->txBufferSize - context->txBufferLen);
968 
969  //Make sure the PMTU value is acceptable
970  if(pmtu < DTLS_MIN_PMTU)
971  return ERROR_BUFFER_OVERFLOW;
972 
973  //Point to the buffer where to format the datagram
974  datagram = context->txBuffer + context->txBufferLen;
975  //Length of the datagram, in bytes
976  context->txDatagramLen = 0;
977  //Point to the first message of the flight
978  context->txBufferPos = 0;
979 
980 #if (TLS_MAX_VERSION >= TLS_VERSION_1_3 && TLS_MIN_VERSION <= TLS_VERSION_1_3)
981  //Initial transmission?
982  if(context->retransmitCount == 0)
983  {
984  //Initialize retransmission state
985  osMemset(&context->encryptionEngine[0].retransmitState, 0,
986  sizeof(Dtls13RetransmitState));
987 
988  osMemset(&context->encryptionEngine[1].retransmitState, 0,
989  sizeof(Dtls13RetransmitState));
990 
991  osMemset(&context->encryptionEngine[2].retransmitState, 0,
992  sizeof(Dtls13RetransmitState));
993  }
994 
995  //Prepare to send the first packet of the flight
996  context->encryptionEngine[0].retransmitState.index = 0;
997  context->encryptionEngine[1].retransmitState.index = 0;
998  context->encryptionEngine[2].retransmitState.index = 0;
999 #endif
1000 
1001  //In the SENDING state, the implementation transmits the buffered flight of
1002  //messages (refer to RFC 6347, section 4.2.4)
1003  while(context->txBufferPos < context->txBufferLen)
1004  {
1005  //Point to the current DTLS record
1006  record = (DtlsRecord *) (context->txBuffer + context->txBufferPos);
1007 
1008  //Advance data pointer
1009  context->txBufferPos += ntohs(record->length) + sizeof(DtlsRecord);
1010 
1011  //Implementations must send retransmissions of lost messages using the
1012  //same epoch and keying material as the original transmission
1013  for(encryptionEngine = NULL, i = 0; i < TLS_MAX_ENCRYPTION_ENGINES; i++)
1014  {
1015  //Compare epochs
1016  if(context->encryptionEngine[i].epoch == ntohs(record->epoch))
1017  {
1018  encryptionEngine = &context->encryptionEngine[i];
1019  break;
1020  }
1021  }
1022 
1023  //Invalid keying material?
1024  if(encryptionEngine == NULL)
1025  return ERROR_INVALID_EPOCH;
1026 
1027 #if (TLS_MAX_VERSION >= TLS_VERSION_1_3 && TLS_MIN_VERSION <= TLS_VERSION_1_3)
1028  //Save the sequence number of the first packet of the flight
1029  if(context->retransmitCount == 0 ||
1030  context->state == TLS_STATE_APPLICATION_DATA ||
1031  context->state == TLS_STATE_CLIENT_FINISHED_ACK ||
1032  context->state == TLS_STATE_NEW_SESSION_TICKET_ACK ||
1033  context->state == TLS_STATE_KEY_UPDATE_ACK)
1034  {
1035  //First packet of the flight?
1036  if(encryptionEngine->retransmitState.index == 0)
1037  {
1038  encryptionEngine->retransmitState.start =
1039  LOAD48BE(encryptionEngine->dtlsSeqNum.b);
1040  }
1041  }
1042 #endif
1043 
1044  //Handshake message?
1045  if(record->type == TLS_TYPE_HANDSHAKE)
1046  {
1047  //Point to the handshake message header to be fragmented
1048  message = (DtlsHandshake *) record->data;
1049 
1050  //Fragment handshake message into smaller fragments
1051  error = dtlsFragmentHandshakeMessage(context, ntohs(record->version),
1052  encryptionEngine, message);
1053  //Any error to report?
1054  if(error)
1055  return error;
1056  }
1057  else
1058  {
1059  //Any datagram pending to be sent?
1060  if(context->txDatagramLen > 0)
1061  {
1062  //Estimate the length of the DTLS record
1063  n = ntohs(record->length) + sizeof(DtlsRecord);
1064  //Overhead caused by record encryption must be considered
1065  n += tlsComputeEncryptionOverhead(encryptionEngine, n);
1066 
1067  //Records may not span datagrams
1068  if((context->txDatagramLen + n) > pmtu)
1069  {
1070  //Debug message
1071  TRACE_INFO("Sending UDP datagram (%" PRIuSIZE " bytes)...\r\n",
1072  context->txDatagramLen);
1073 
1074  //Send datagram
1075  error = context->socketSendCallback(context->socketHandle,
1076  datagram, context->txDatagramLen, &n, 0);
1077  //Any error to report?
1078  if(error)
1079  return error;
1080 
1081  //The datagram has been successfully transmitted
1082  context->txDatagramLen = 0;
1083  }
1084  }
1085 
1086  //Estimate the length of the DTLS record
1087  n = ntohs(record->length) + sizeof(DtlsRecord);
1088  //Overhead caused by record encryption must be considered
1089  n += tlsComputeEncryptionOverhead(encryptionEngine, n);
1090 
1091  //Make sure the buffer is large enough to hold the DTLSCiphertext
1092  //record
1093  if((context->txBufferLen + context->txDatagramLen + n) > context->txBufferSize)
1094  return ERROR_BUFFER_OVERFLOW;
1095 
1096  //Multiple DTLS records may be placed in a single datagram. They are
1097  //simply encoded consecutively
1098  osMemcpy(datagram + context->txDatagramLen, record,
1099  ntohs(record->length) + sizeof(DtlsRecord));
1100 
1101  //Point to the DTLS record header
1102  record = (DtlsRecord *) (datagram + context->txDatagramLen);
1103 
1104  //From the perspective of the DTLS record layer, the retransmission is
1105  //a new record. This record will have a new sequence number
1106  record->seqNum = encryptionEngine->dtlsSeqNum;
1107 
1108  //Protect record payload?
1109  if(encryptionEngine->cipherMode != CIPHER_MODE_NULL ||
1110  encryptionEngine->hashAlgo != NULL)
1111  {
1112  //Encrypt DTLS record
1113  error = tlsEncryptRecord(context, encryptionEngine, record);
1114  //Any error to report?
1115  if(error)
1116  return error;
1117  }
1118 
1119  //Debug message
1120  TRACE_DEBUG("Encrypted DTLS record (%" PRIuSIZE " bytes)...\r\n", ntohs(record->length));
1121  TRACE_DEBUG_ARRAY(" ", record, ntohs(record->length) + sizeof(DtlsRecord));
1122 
1123  //Increment sequence number
1124  dtlsIncSequenceNumber(&encryptionEngine->dtlsSeqNum);
1125 
1126  //Adjust the length of the datagram
1127  context->txDatagramLen += ntohs(record->length) + sizeof(DtlsRecord);
1128  }
1129  }
1130 
1131  //Any datagram pending to be sent?
1132  if(context->txDatagramLen > 0)
1133  {
1134  //Debug message
1135  TRACE_INFO("Sending UDP datagram (%" PRIuSIZE " bytes)...\r\n",
1136  context->txDatagramLen);
1137 
1138  //Send datagram
1139  error = context->socketSendCallback(context->socketHandle, datagram,
1140  context->txDatagramLen, &n, 0);
1141  //Any error to report?
1142  if(error)
1143  return error;
1144 
1145  //The datagram has been successfully transmitted
1146  context->txDatagramLen = 0;
1147  }
1148 
1149  //Save the time at which the flight of messages was sent
1150  context->retransmitTimestamp = osGetSystemTime();
1151  //Increment retransmission counter
1152  context->retransmitCount++;
1153 
1154  //Successful processing
1155  return NO_ERROR;
1156 }
1157 
1158 
1159 /**
1160  * @brief Handshake message fragmentation
1161  * @param[in] context Pointer to the TLS context
1162  * @param[in] version DTLS version to be used
1163  * @param[in] encryptionEngine Pointer to the encryption engine
1164  * @param[in] message Pointer the handshake message to be fragmented
1165  * @return Error code
1166  **/
1167 
1169  TlsEncryptionEngine *encryptionEngine, const DtlsHandshake *message)
1170 {
1171  error_t error;
1172  size_t n;
1173  size_t pmtu;
1174  size_t totalLength;
1175  size_t fragOffset;
1176  size_t fragLen;
1177  size_t maxFragSize;
1178  uint8_t *datagram;
1179  DtlsRecord *record;
1180  DtlsHandshake *fragment;
1181 
1182  //Determine the value of the PMTU
1183  pmtu = MIN(context->pmtu, context->txBufferSize - context->txBufferLen);
1184 
1185 #if (TLS_MAX_VERSION >= TLS_VERSION_1_3 && TLS_MIN_VERSION <= TLS_VERSION_1_3)
1186  //The DTLS 1.3 record layer is different from the DTLS 1.2 record layer
1187  if(context->version == TLS_VERSION_1_3 &&
1188  (encryptionEngine->cipherMode != CIPHER_MODE_NULL ||
1189  encryptionEngine->hashAlgo != NULL))
1190  {
1191  //DTLS handshake messages have 12 bytes of overhead
1192  n = sizeof(DtlsHandshake);
1193  //Overhead caused by record encryption must be considered
1194  n += dtls13ComputeEncryptionOverhead(encryptionEngine);
1195  }
1196  else
1197 #endif
1198  {
1199  //DTLS records have 25 bytes of overhead
1200  n = sizeof(DtlsRecord) + sizeof(DtlsHandshake);
1201  //Overhead caused by record encryption must be considered
1202  n += tlsComputeEncryptionOverhead(encryptionEngine, 0);
1203  }
1204 
1205  //Make sure the PMTU value is acceptable
1206  if(pmtu <= n || pmtu < DTLS_MIN_PMTU)
1207  return ERROR_BUFFER_OVERFLOW;
1208 
1209  //Determine the maximum payload size for fragmented messages
1210  maxFragSize = pmtu - n;
1211 
1212  //Point to the buffer where to format the datagram
1213  datagram = context->txBuffer + context->txBufferLen;
1214  //Get the length of the handshake message
1215  totalLength = LOAD24BE(message->length);
1216  //Prepare to send the first fragment
1217  fragOffset = 0;
1218 
1219  //Fragmentation process
1220  do
1221  {
1222  //Calculate the length of the current fragment
1223  fragLen = MIN(totalLength - fragOffset, maxFragSize);
1224 
1225  //Any datagram pending to be sent?
1226  if(context->txDatagramLen > 0)
1227  {
1228 #if (TLS_MAX_VERSION >= TLS_VERSION_1_3 && TLS_MIN_VERSION <= TLS_VERSION_1_3)
1229  //The DTLS 1.3 record layer is different from the DTLS 1.2 record layer
1230  if(context->version == TLS_VERSION_1_3 &&
1231  (encryptionEngine->cipherMode != CIPHER_MODE_NULL ||
1232  encryptionEngine->hashAlgo != NULL))
1233  {
1234  //Estimate the length of the DTLS handshake message
1235  n = fragLen + sizeof(DtlsHandshake);
1236  //Overhead caused by record encryption must be considered
1237  n += dtls13ComputeEncryptionOverhead(encryptionEngine);
1238  }
1239  else
1240 #endif
1241  {
1242  //Estimate the length of the DTLS record
1243  n = fragLen + sizeof(DtlsRecord) + sizeof(DtlsHandshake);
1244  //Overhead caused by record encryption must be considered
1245  n += tlsComputeEncryptionOverhead(encryptionEngine, n);
1246  }
1247 
1248  //Records may not span datagrams
1249  if((context->txDatagramLen + n) > pmtu)
1250  {
1251  //Debug message
1252  TRACE_INFO("Sending UDP datagram (%" PRIuSIZE " bytes)...\r\n",
1253  context->txDatagramLen);
1254 
1255  //Send datagram
1256  error = context->socketSendCallback(context->socketHandle,
1257  datagram, context->txDatagramLen, &n, 0);
1258  //Any error to report?
1259  if(error)
1260  return error;
1261 
1262  //The datagram has been successfully transmitted
1263  context->txDatagramLen = 0;
1264  }
1265  }
1266 
1267  //Multiple DTLS records may be placed in a single datagram. They are
1268  //simply encoded consecutively
1269  record = (DtlsRecord *) (datagram + context->txDatagramLen);
1270 
1271  //The DTLS 1.3 record layer is different from the DTLS 1.2 record layer
1272  if(context->version == TLS_VERSION_1_3 &&
1273  (encryptionEngine->cipherMode != CIPHER_MODE_NULL ||
1274  encryptionEngine->hashAlgo != NULL))
1275  {
1276  //Point to the handshake message header
1277  fragment = (DtlsHandshake *) (datagram + context->txDatagramLen);
1278  }
1279  else
1280  {
1281  //Format DTLS record
1282  record->type = TLS_TYPE_HANDSHAKE;
1283  record->version = htons(version);
1284  record->epoch = htons(encryptionEngine->epoch);
1285  record->seqNum = encryptionEngine->dtlsSeqNum;
1286  record->length = htons(fragLen + sizeof(DtlsHandshake));
1287 
1288  //Point to the handshake message header
1289  fragment = (DtlsHandshake *) record->data;
1290  }
1291 
1292  //Handshake message type
1293  fragment->msgType = message->msgType;
1294  //Number of bytes in the message
1295  STORE24BE(totalLength, fragment->length);
1296  //Message sequence number
1297  fragment->msgSeq = message->msgSeq;
1298  //Fragment offset
1299  STORE24BE(fragOffset, fragment->fragOffset);
1300  //Fragment length
1301  STORE24BE(fragLen, fragment->fragLength);
1302 
1303  //Copy data
1304  osMemcpy(fragment->data, message->data + fragOffset, fragLen);
1305 
1306  //Debug message
1307  TRACE_DEBUG("Sending handshake message fragment (%" PRIuSIZE " bytes)...\r\n",
1308  LOAD24BE(fragment->fragLength));
1309  TRACE_DEBUG(" msgType = %u\r\n", fragment->msgType);
1310  TRACE_DEBUG(" msgSeq = %u\r\n", ntohs(fragment->msgSeq));
1311  TRACE_DEBUG(" fragOffset = %u\r\n", LOAD24BE(fragment->fragOffset));
1312  TRACE_DEBUG(" fragLength = %u\r\n", LOAD24BE(fragment->fragLength));
1313  TRACE_DEBUG(" length = %u\r\n", LOAD24BE(fragment->length));
1314 
1315  //Protect record payload?
1316  if(encryptionEngine->cipherMode != CIPHER_MODE_NULL ||
1317  encryptionEngine->hashAlgo != NULL)
1318  {
1319 #if (TLS_MAX_VERSION >= TLS_VERSION_1_3 && TLS_MIN_VERSION <= TLS_VERSION_1_3)
1320  //DTLS 1.3 protocol?
1321  if(context->version == TLS_VERSION_1_3)
1322  {
1323  //Encrypt DTLS 1.3 record
1324  error = dtls13EncryptRecord(context, encryptionEngine,
1325  TLS_TYPE_HANDSHAKE, (uint8_t *) fragment,
1326  fragLen + sizeof(DtlsHandshake), (uint8_t *) record, &n);
1327  //Any error to report?
1328  if(error)
1329  return error;
1330  }
1331  else
1332 #endif
1333  {
1334  //Encrypt DTLS record
1335  error = tlsEncryptRecord(context, encryptionEngine, record);
1336  //Any error to report?
1337  if(error)
1338  return error;
1339 
1340  //Length of the resulting datagram, in bytes
1341  n = ntohs(record->length) + sizeof(DtlsRecord);
1342  }
1343  }
1344  else
1345  {
1346  //Length of the datagram, in bytes
1347  n = ntohs(record->length) + sizeof(DtlsRecord);
1348  }
1349 
1350  //Debug message
1351  TRACE_DEBUG("Encrypted DTLS record (%" PRIuSIZE " bytes)...\r\n", n);
1352  TRACE_DEBUG_ARRAY(" ", record, n);
1353 
1354  //Increment sequence number
1355  dtlsIncSequenceNumber(&encryptionEngine->dtlsSeqNum);
1356 
1357 #if (TLS_MAX_VERSION >= TLS_VERSION_1_3 && TLS_MIN_VERSION <= TLS_VERSION_1_3)
1358  //DTLS 1.3 protocol?
1359  if(context->version == TLS_VERSION_1_3)
1360  {
1361  Dtls13RetransmitState *retransmitState;
1362 
1363  //Point to the retransmission state
1364  retransmitState = &encryptionEngine->retransmitState;
1365 
1366  //Initial transmission?
1367  if(context->retransmitCount == 0)
1368  {
1369  //Each flight may consist of a number of records
1370  retransmitState->count++;
1371  //The record is initially marked as unacknowledged
1372  retransmitState->mask = (retransmitState->mask << 1) | 1;
1373  }
1374  else
1375  {
1376  //An implementation should omit ACKed records from any future
1377  //retransmissions
1378  if(retransmitState->index < 32 &&
1379  (retransmitState->mask & (1 << retransmitState->index)) == 0)
1380  {
1381  n = 0;
1382  }
1383  }
1384 
1385  //Next record of the flight
1386  retransmitState->index++;
1387  }
1388 #endif
1389 
1390  //Adjust the length of the datagram
1391  context->txDatagramLen += n;
1392  //Next fragment
1393  fragOffset += fragLen;
1394 
1395  //Check whether fragmentation process is complete
1396  } while(fragOffset < totalLength);
1397 
1398  //Successful processing
1399  return NO_ERROR;
1400 }
1401 
1402 
1403 /**
1404  * @brief Handshake message reassembly algorithm
1405  * @param[in] context Pointer to the TLS context
1406  * @param[in] message Pointer the newly arrived fragment
1407  * @return Error code
1408  **/
1409 
1411  const DtlsHandshake *message)
1412 {
1413  size_t n;
1414  size_t pos;
1415  size_t fragOffset;
1416  size_t fragLen;
1417  size_t prevFragOffset;
1418  size_t prevFragLen;
1419  DtlsHandshake *fragment;
1420  DtlsHandshake *prevFragment;
1421 
1422  //Retrieve fragment offset
1423  fragOffset = LOAD24BE(message->fragOffset);
1424  //Retrieve fragment length
1425  fragLen = LOAD24BE(message->fragLength) + sizeof(DtlsHandshake);
1426 
1427  //Point to the beginning of the reassembly queue
1428  pos = 0;
1429 
1430  //Loop through the reassembly queue
1431  while(pos < context->rxFragQueueLen)
1432  {
1433  //Point to the current fragment
1434  fragment = (DtlsHandshake *) (context->rxBuffer + pos);
1435 
1436  //Message type mismatch?
1437  if(message->msgType != fragment->msgType)
1438  return ERROR_UNEXPECTED_MESSAGE;
1439 
1440  //Message length mismatch?
1441  if(LOAD24BE(message->length) != LOAD24BE(fragment->length))
1442  return ERROR_UNEXPECTED_MESSAGE;
1443 
1444  //Sort fragments in ascending order
1445  if(fragOffset < LOAD24BE(fragment->fragOffset))
1446  break;
1447 
1448  //Next fragment
1449  pos += LOAD24BE(fragment->fragLength) + sizeof(DtlsHandshake);
1450  }
1451 
1452  //Sanity check
1453  if((context->rxFragQueueLen + fragLen) >
1454  (context->rxBufferSize - context->rxDatagramLen))
1455  {
1456  return ERROR_BUFFER_OVERFLOW;
1457  }
1458 
1459  //Position where to insert the new fragment
1460  fragment = (DtlsHandshake *) (context->rxBuffer + pos);
1461 
1462  //Make room for the new fragment
1463  osMemmove(context->rxBuffer + pos + fragLen, fragment,
1464  context->rxFragQueueLen - pos);
1465 
1466  //Insert the new fragment in the reassembly queue
1467  osMemcpy(fragment, message, fragLen);
1468  //Update the length of the reassembly queue
1469  context->rxFragQueueLen += fragLen;
1470 
1471  //Point to the first fragment of the reassembly queue
1472  prevFragment = (DtlsHandshake *) context->rxBuffer;
1473  //Retrieve fragment offset
1474  prevFragOffset = LOAD24BE(prevFragment->fragOffset);
1475  //Retrieve fragment length
1476  prevFragLen = LOAD24BE(prevFragment->fragLength);
1477 
1478  //Position of the next fragment
1479  pos = prevFragLen + sizeof(DtlsHandshake);
1480 
1481  //Loop through the reassembly queue
1482  while(pos < context->rxFragQueueLen)
1483  {
1484  //Point to the current fragment
1485  fragment = (DtlsHandshake *) (context->rxBuffer + pos);
1486  //Retrieve fragment offset
1487  fragOffset = LOAD24BE(fragment->fragOffset);
1488  //Retrieve fragment length
1489  fragLen = LOAD24BE(fragment->fragLength);
1490 
1491  //Check whether the current fragment interacts in some way with the
1492  //previous fragment
1493  if(fragOffset <= (prevFragOffset + prevFragLen))
1494  {
1495  //DTLS implementations must be able to handle overlapping fragment
1496  //ranges
1497  if((fragOffset + fragLen) > (prevFragOffset + prevFragLen))
1498  {
1499  //Coalesce overlapping fragments
1500  osMemmove(prevFragment->data + fragOffset - prevFragOffset,
1501  fragment->data,
1502  context->rxFragQueueLen - pos - sizeof(DtlsHandshake));
1503 
1504  //Number of bytes that do not overlap with the previous fragment
1505  n = fragOffset + fragLen - prevFragOffset - prevFragLen;
1506 
1507  //Update the length of the reassembly queue
1508  context->rxFragQueueLen -= fragLen - n + sizeof(DtlsHandshake);
1509 
1510  //Adjust the length of the previous fragment
1511  prevFragLen += n;
1512  //Fix fragment length field
1513  STORE24BE(prevFragLen, prevFragment->fragLength);
1514 
1515  //Jump to the next fragment
1516  pos += n;
1517  }
1518  else
1519  {
1520  //Drop current fragment
1521  osMemmove(fragment, fragment->data + fragLen,
1522  context->rxFragQueueLen - fragLen - sizeof(DtlsHandshake));
1523 
1524  //Update the length of the reassembly queue
1525  context->rxFragQueueLen -= fragLen + sizeof(DtlsHandshake);
1526  }
1527  }
1528  else
1529  {
1530  //Jump to the next fragment
1531  pos += fragLen + sizeof(DtlsHandshake);
1532 
1533  //Keep track of the previous fragment
1534  prevFragment = fragment;
1535  prevFragOffset = fragOffset;
1536  prevFragLen = fragLen;
1537  }
1538  }
1539 
1540  //Successful processing
1541  return NO_ERROR;
1542 }
1543 
1544 
1545 /**
1546  * @brief Receive a datagram
1547  * @param[in] context Pointer to the TLS context
1548  * @param[out] data Buffer where to store the incoming datagram
1549  * @param[in] size Maximum number of bytes that can be received
1550  * @param[out] length Number of bytes that have been received
1551  * @return Error code
1552  **/
1553 
1555  size_t size, size_t *length)
1556 {
1557  error_t error;
1558  systime_t time;
1559 
1560  //Initialize status code
1561  error = NO_ERROR;
1562 
1563  //Wait for an incoming datagram
1564  while(!error)
1565  {
1566  //Receive datagram
1567  error = context->socketReceiveCallback(context->socketHandle, data,
1568  size, length, 0);
1569 
1570  //Check status code
1571  if(error == NO_ERROR)
1572  {
1573  //Debug message
1574  TRACE_INFO("UDP datagram received (%" PRIuSIZE " bytes)...\r\n", *length);
1575  TRACE_DEBUG_ARRAY(" ", data, *length);
1576 
1577  //A datagram has been successfully received
1578  break;
1579  }
1580  else if(error == ERROR_WOULD_BLOCK)
1581  {
1582  //Manage retransmission timer
1583  error = dtlsTick(context);
1584 
1585  //Check status code
1586  if(!error)
1587  {
1588  //Exit immediately
1589  error = ERROR_WOULD_BLOCK;
1590  }
1591  }
1592  else if(error == ERROR_TIMEOUT)
1593  {
1594  //Manage retransmission timer
1595  error = dtlsTick(context);
1596 
1597  //Check status code
1598  if(!error)
1599  {
1600  //Check whether a timeout has been specified
1601  if(context->timeout != INFINITE_DELAY)
1602  {
1603  //Get current time
1604  time = osGetSystemTime();
1605 
1606  //Check whether the timeout has elapsed
1607  if((time - context->startTime) >= context->timeout)
1608  {
1609  //Exit immediately
1610  error = ERROR_TIMEOUT;
1611  }
1612  }
1613  }
1614  }
1615  else
1616  {
1617  //The read operation has failed
1618  error = ERROR_READ_FAILED;
1619  }
1620  }
1621 
1622  //Return status code
1623  return error;
1624 }
1625 
1626 
1627 /**
1628  * @brief Manage retransmission timers
1629  * @param[in] context Pointer to the TLS context
1630  * @return Error code
1631  **/
1632 
1634 {
1635  error_t error;
1636  systime_t time;
1637 
1638  //Initialize status code
1639  error = NO_ERROR;
1640 
1641  //Get current time
1642  time = osGetSystemTime();
1643 
1644 #if (TLS_MAX_VERSION >= TLS_VERSION_1_3 && TLS_MIN_VERSION <= TLS_VERSION_1_3)
1645  //DTLS 1.3 currently selected?
1646  if(context->version == TLS_VERSION_1_3)
1647  {
1648  uint_t i;
1649 
1650  //Loop through the decryption engines
1651  for(i = 0; i < TLS_MAX_DECRYPTION_ENGINES; i++)
1652  {
1653  //Valid decryption engine?
1654  if(context->decryptionEngine[i].active)
1655  {
1656  //Any lifetime specified?
1657  if(context->decryptionEngine[i].lifetime > 0)
1658  {
1659  //Check whether the lifetime has expired
1660  if((time - context->decryptionEngine[i].timestamp) >=
1661  context->decryptionEngine[i].lifetime)
1662  {
1663  tlsFreeEncryptionEngine(&context->decryptionEngine[i]);
1664  context->decryptionEngine[i].epoch = 0;
1665  }
1666  }
1667  }
1668  }
1669 
1670  //Check whether the ACK timer is running
1671  if(context->ackTimerRunning)
1672  {
1673  //It is recommended that implementations generate ACKs when they have
1674  //received part of a flight and do not immediately receive the rest of the
1675  //flight. One approach is to set a timer for 1/4 the current retransmit
1676  //timer value when the first record in the flight is received and then
1677  //send an ACK when that timer expires (refer to RFC 9147, section 7.1)
1678  if((time - context->ackTimestamp) >= (context->retransmitTimeout / 4))
1679  {
1680  //Generate ACKs
1681  dtls13SendAck(context);
1682  //Stop the ACK timer
1683  context->ackTimerRunning = FALSE;
1684  }
1685  }
1686  }
1687 #endif
1688 
1689  //Check current state
1690  if(context->state != TLS_STATE_APPLICATION_DATA)
1691  {
1692  //Any flight of messages buffered?
1693  if(context->txBufferLen > 0)
1694  {
1695  //Check whether the retransmission timer has expired
1696  if((time - context->retransmitTimestamp) >= context->retransmitTimeout)
1697  {
1698  //Check retransmission counter
1699  if(context->retransmitCount < DTLS_MAX_RETRIES)
1700  {
1701  //The implementation transitions to the SENDING state, where
1702  //it retransmits the flight, resets the retransmit timer, and
1703  //returns to the WAITING state
1704  error = dtlsSendFlight(context);
1705 
1706  //Double the value at each retransmission, up to no less than
1707  //the RFC 6298 maximum of 60 seconds
1708  context->retransmitTimeout = MIN(context->retransmitTimeout * 2,
1710  }
1711  else
1712  {
1713  //The maximum number of retransmissions has been exceeded
1714  error = ERROR_HANDSHAKE_FAILED;
1715  }
1716  }
1717  }
1718  }
1719 
1720  //Return status code
1721  return error;
1722 }
1723 
1724 
1725 /**
1726  * @brief Increment sequence number
1727  * @param[in,out] seqNum Pointer to the 48-bit sequence number
1728  **/
1729 
1731 {
1732  uint16_t temp;
1733 
1734  //Sequence numbers are stored MSB first
1735  temp = seqNum->b[5] + 1;
1736  seqNum->b[5] = temp & 0xFF;
1737  temp = (temp >> 8) + seqNum->b[4];
1738  seqNum->b[4] = temp & 0xFF;
1739  temp = (temp >> 8) + seqNum->b[3];
1740  seqNum->b[3] = temp & 0xFF;
1741  temp = (temp >> 8) + seqNum->b[2];
1742  seqNum->b[2] = temp & 0xFF;
1743  temp = (temp >> 8) + seqNum->b[1];
1744  seqNum->b[1] = temp & 0xFF;
1745  temp = (temp >> 8) + seqNum->b[0];
1746  seqNum->b[0] = temp & 0xFF;
1747 }
1748 
1749 #endif
Dtls13Ack
Definition: dtls13_misc.h:84
#define TLS_MAX_RECORD_LENGTH
Definition: tls.h:994
#define htons(value)
Definition: cpu_endian.h:413
DTLS (Datagram Transport Layer Security)
TLS helper functions.
@ TLS_STATE_HELLO_RETRY_REQUEST
Definition: tls.h:1563
@ TLS_TYPE_NEW_CONNECTION_ID
Definition: tls.h:1110
@ ERROR_WOULD_BLOCK
Definition: error.h:96
error_t dtlsTick(TlsContext *context)
Manage retransmission timers.
Definition: dtls_record.c:1633
@ TLS_TYPE_SERVER_HELLO_DONE
Definition: tls.h:1114
@ ERROR_BUFFER_OVERFLOW
Definition: error.h:143
@ ERROR_VERSION_NOT_SUPPORTED
Definition: error.h:67
@ ERROR_UNEXPECTED_MESSAGE
Definition: error.h:195
DtlsRecord
Definition: dtls_misc.h:185
uint8_t message[]
Definition: chap.h:154
@ TLS_TYPE_CHANGE_CIPHER_SPEC
Definition: tls.h:1085
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
@ ERROR_HANDSHAKE_FAILED
Definition: error.h:234
TLS record decryption.
@ TLS_TYPE_ACK
Definition: tls.h:1091
error_t dtlsReadDatagram(TlsContext *context, uint8_t *data, size_t size, size_t *length)
Receive a datagram.
Definition: dtls_record.c:1554
TLS record encryption.
#define DTLS_MIN_TIMEOUT
Definition: dtls_misc.h:97
uint16_t totalLength
Definition: ipv4.h:348
uint8_t version
Definition: coap_common.h:177
TlsChangeCipherSpec
Definition: tls.h:2005
void dtlsUpdateReplayWindow(TlsEncryptionEngine *decryptionEngine, const DtlsSequenceNumber *seqNum)
Update sliding window.
Definition: dtls_misc.c:581
#define DTLS_MIN_PMTU
Definition: dtls_misc.h:55
Retransmission state.
Definition: dtls13_misc.h:100
@ TLS_STATE_CLIENT_HELLO
Definition: tls.h:1559
@ TLS_STATE_SERVER_HELLO
Definition: tls.h:1564
@ TLS_STATE_HELLO_VERIFY_REQUEST
Definition: tls.h:1562
error_t dtlsCheckReplayWindow(TlsEncryptionEngine *decryptionEngine, const DtlsSequenceNumber *seqNum)
Perform replay detection.
Definition: dtls_misc.c:506
@ TLS_STATE_KEY_UPDATE
Definition: tls.h:1592
#define DTLS_VERSION_1_0
Definition: dtls_misc.h:35
#define FALSE
Definition: os_port.h:46
#define osMemcpy(dest, src, length)
Definition: os_port.h:144
#define TlsContext
Definition: tls.h:36
error_t
Error codes.
Definition: error.h:43
uint32_t seqNum
Definition: tcp.h:348
DTLS record layer.
error_t tlsDecryptRecord(TlsContext *context, TlsEncryptionEngine *decryptionEngine, void *record)
Decrypt an incoming TLS record.
#define TLS_MAX_DECRYPTION_ENGINES
Definition: tls.h:981
void tlsFreeEncryptionEngine(TlsEncryptionEngine *encryptionEngine)
Release encryption engine.
Definition: tls_misc.c:1150
#define TLS_VERSION_1_2
Definition: tls.h:97
error_t dtlsReadRecord(TlsContext *context)
Receive a DTLS record.
Definition: dtls_record.c:424
#define TLS_MAX_VERSION
Definition: tls.h:137
TlsAlert
Definition: tls.h:2016
#define TLS_MIN_VERSION
Definition: tls.h:130
@ DTLS_RETRANSMIT_STATE_SENDING
Definition: dtls_misc.h:127
error_t dtlsReassembleHandshakeMessage(TlsContext *context, const DtlsHandshake *message)
Handshake message reassembly algorithm.
Definition: dtls_record.c:1410
@ TLS_TYPE_APPLICATION_DATA
Definition: tls.h:1088
@ TLS_TYPE_CLIENT_HELLO
Definition: tls.h:1102
@ TLS_STATE_SERVER_FINISHED
Definition: tls.h:1585
Helper functions for TLS 1.3 client.
DTLS 1.3 (Datagram Transport Layer Security)
@ TLS_TYPE_REQUEST_CONNECTION_ID
Definition: tls.h:1109
error_t dtlsFragmentHandshakeMessage(TlsContext *context, uint16_t version, TlsEncryptionEngine *encryptionEngine, const DtlsHandshake *message)
Handshake message fragmentation.
Definition: dtls_record.c:1168
@ TLS_TYPE_ALERT
Definition: tls.h:1086
#define TLS_VERSION_1_3
Definition: tls.h:98
@ TLS_TYPE_SERVER_HELLO
Definition: tls.h:1103
Handshake message processing (TLS client and server)
@ ERROR_INVALID_LENGTH
Definition: error.h:111
TLS record protocol.
@ TLS_STATE_SERVER_CHANGE_CIPHER_SPEC
Definition: tls.h:1583
#define DTLS_MAX_RETRIES
Definition: dtls_misc.h:83
uint8_t fragOffset[3]
Definition: dtls_misc.h:197
#define MSB(x)
Definition: os_port.h:59
error_t dtlsWriteProtocolData(TlsContext *context, const uint8_t *data, size_t length, TlsContentType contentType)
Write protocol data.
Definition: dtls_record.c:62
size_t tlsComputeEncryptionOverhead(TlsEncryptionEngine *encryptionEngine, size_t payloadLen)
Compute overhead caused by encryption.
Definition: tls_misc.c:1789
#define TRACE_INFO(...)
Definition: debug.h:105
uint8_t length
Definition: tcp.h:375
#define LOAD48BE(p)
Definition: cpu_endian.h:226
@ TLS_TYPE_HELLO_VERIFY_REQUEST
Definition: tls.h:1104
#define MIN(a, b)
Definition: os_port.h:63
error_t dtlsWriteRecord(TlsContext *context, const uint8_t *data, size_t length, TlsContentType contentType)
Send a DTLS record.
Definition: dtls_record.c:284
uint16_t dtlsTranslateVersion(uint16_t version)
Translate TLS version into DTLS version.
Definition: dtls_misc.c:124
@ TLS_STATE_CLIENT_CHANGE_CIPHER_SPEC
Definition: tls.h:1577
@ TLS_STATE_NEW_SESSION_TICKET_2
Definition: tls.h:1582
@ ERROR_INVALID_EPOCH
Definition: error.h:108
uint32_t systime_t
System time.
#define ntohs(value)
Definition: cpu_endian.h:421
#define TRACE_WARNING(...)
Definition: debug.h:93
#define TRACE_DEBUG(...)
Definition: debug.h:119
@ ERROR_TIMEOUT
Definition: error.h:95
#define DTLS_MAX_TIMEOUT
Definition: dtls_misc.h:104
@ TLS_STATE_CLIENT_HELLO_2
Definition: tls.h:1560
uint32_t time
TlsContentType
Content type.
Definition: tls.h:1083
#define TRACE_DEBUG_ARRAY(p, a, n)
Definition: debug.h:120
error_t dtlsReadProtocolData(TlsContext *context, uint8_t **data, size_t *length, TlsContentType *contentType)
Read protocol data.
Definition: dtls_record.c:167
#define DTLS_INIT_TIMEOUT
Definition: dtls_misc.h:90
uint8_t n
DtlsHandshake
Definition: dtls_misc.h:200
@ ERROR_READ_FAILED
Definition: error.h:224
@ TLS_TYPE_FINISHED
Definition: tls.h:1117
#define LOAD24BE(p)
Definition: cpu_endian.h:197
@ TLS_STATE_CLIENT_FINISHED_ACK
Definition: tls.h:1590
@ TLS_CONNECTION_END_CLIENT
Definition: tls.h:1029
error_t dtlsSendFlight(TlsContext *context)
Send the buffered flight of messages.
Definition: dtls_record.c:955
error_t tlsEncryptRecord(TlsContext *context, TlsEncryptionEngine *encryptionEngine, void *record)
Encrypt an outgoing TLS record.
DtlsSequenceNumber
Definition: dtls_misc.h:148
TLS (Transport Layer Security)
size_t dtls13ComputeEncryptionOverhead(TlsEncryptionEngine *encryptionEngine)
Compute overhead caused by encryption.
Definition: dtls13_misc.c:416
#define STORE24BE(a, p)
Definition: cpu_endian.h:273
error_t dtls13SendAck(TlsContext *context)
Send ACK message.
Definition: dtls13_misc.c:117
@ CIPHER_MODE_NULL
Definition: crypto.h:1060
@ TLS_TYPE_NEW_SESSION_TICKET
Definition: tls.h:1105
@ TLS_TYPE_HELLO_REQUEST
Definition: tls.h:1101
DtlsRetransmitState
DTLS retransmission states.
Definition: dtls_misc.h:125
@ ERROR_RECORD_OVERFLOW
Definition: error.h:233
error_t dtlsProcessRecord(TlsContext *context)
Process incoming DTLS record.
Definition: dtls_record.c:536
@ TLS_TYPE_HELLO_RETRY_REQUEST
Definition: tls.h:1107
#define PRIuSIZE
unsigned int uint_t
Definition: compiler_port.h:57
#define osMemset(p, value, length)
Definition: os_port.h:138
error_t dtls13EncryptRecord(TlsContext *context, TlsEncryptionEngine *encryptionEngine, uint8_t type, const uint8_t *data, size_t dataLen, uint8_t *record, size_t *recordLen)
Encrypt an outgoing DTLS 1.3 record.
@ TLS_STATE_SERVER_HELLO_DONE
Definition: tls.h:1573
@ TLS_STATE_SERVER_HELLO_2
Definition: tls.h:1565
@ TLS_STATE_CLIENT_FINISHED
Definition: tls.h:1579
@ TLS_STATE_KEY_UPDATE_ACK
Definition: tls.h:1593
@ DTLS_RETRANSMIT_STATE_PREPARING
Definition: dtls_misc.h:126
#define TLS_MAX_ENCRYPTION_ENGINES
Definition: tls.h:972
void dtls13SaveRecordNumber(TlsContext *context, uint64_t epoch, uint64_t seqNum)
Update the list of record numbers.
Definition: dtls13_misc.c:53
@ TLS_TYPE_KEY_UPDATE
Definition: tls.h:1121
#define TlsEncryptionEngine
Definition: tls.h:40
DTLS 1.3 record encryption.
@ NO_ERROR
Success.
Definition: error.h:44
Debugging facilities.
@ TLS_STATE_NEW_SESSION_TICKET_ACK
Definition: tls.h:1591
#define osMemmove(dest, src, length)
Definition: os_port.h:150
DTLS 1.3 record decryption.
#define TLS13_NEW_SESSION_TICKET_COUNT
Definition: tls13_misc.h:141
#define INFINITE_DELAY
Definition: os_port.h:75
@ ERROR_INVALID_SEQUENCE_NUMBER
Definition: error.h:109
systime_t osGetSystemTime(void)
Retrieve system time.
void dtlsIncSequenceNumber(DtlsSequenceNumber *seqNum)
Increment sequence number.
Definition: dtls_record.c:1730