tls_record.c
Go to the documentation of this file.
1 /**
2  * @file tls_record.c
3  * @brief TLS record protocol
4  *
5  * @section License
6  *
7  * SPDX-License-Identifier: GPL-2.0-or-later
8  *
9  * Copyright (C) 2010-2024 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.4.0
29  **/
30 
31 //Switch to the appropriate trace level
32 #define TRACE_LEVEL TLS_TRACE_LEVEL
33 
34 //Dependencies
35 #include "tls.h"
36 #include "tls_record.h"
37 #include "tls_record_encryption.h"
38 #include "tls_record_decryption.h"
39 #include "debug.h"
40 
41 //Check TLS library configuration
42 #if (TLS_SUPPORT == ENABLED)
43 
44 
45 /**
46  * @brief Write protocol data
47  * @param[in] context Pointer to the TLS context
48  * @param[in] data Pointer to the data buffer
49  * @param[in] length Number of data bytes to be written
50  * @param[in] contentType Higher level protocol
51  * @return Error code
52  **/
53 
55  const uint8_t *data, size_t length, TlsContentType contentType)
56 {
57  error_t error;
58  size_t n;
59  uint8_t *p;
60 
61  //Initialize status code
62  error = NO_ERROR;
63 
64  //Fragmentation process
65  while(!error)
66  {
67  if(context->txBufferLen == 0)
68  {
69  //Check the length of the data
70  if(length > context->txBufferMaxLen)
71  {
72  //Report an error
73  error = ERROR_MESSAGE_TOO_LONG;
74  }
75  else if(length > 0)
76  {
77  //Make room for the encryption overhead
78  osMemmove(context->txBuffer + context->txBufferSize - length, data,
79  length);
80 
81  //Save record type
82  context->txBufferType = contentType;
83  //Set the length of the buffer
84  context->txBufferLen = length;
85  //Point to the beginning of the buffer
86  context->txBufferPos = 0;
87  }
88  else
89  {
90  //We are done
91  break;
92  }
93  }
94  else if(context->txBufferPos < context->txBufferLen)
95  {
96  //Number of bytes left to send
97  n = context->txBufferLen - context->txBufferPos;
98  //Point to the current fragment
99  p = context->txBuffer + context->txBufferSize - n;
100 
101  //The record length must not exceed 16384 bytes
103 
104 #if (TLS_MAX_FRAG_LEN_SUPPORT == ENABLED)
105  //Do not exceed the negotiated maximum fragment length
106  n = MIN(n, context->maxFragLen);
107 #endif
108 
109 #if (TLS_RECORD_SIZE_LIMIT_SUPPORT == ENABLED)
110  //The value of RecordSizeLimit is used to limit the size of records
111  //that are created when encoding application data and the protected
112  //handshake message into records
113  if(context->encryptionEngine.cipherMode != CIPHER_MODE_NULL ||
114  context->encryptionEngine.hashAlgo != NULL)
115  {
116  //An endpoint must not generate a protected record with plaintext
117  //that is larger than the RecordSizeLimit value it receives from
118  //its peer (refer to RFC 8449, section 4)
119  n = MIN(n, context->encryptionEngine.recordSizeLimit);
120  }
121 #endif
122  //Send TLS record
123  error = tlsWriteRecord(context, p, n, context->txBufferType);
124 
125  //Check status code
126  if(!error)
127  {
128  //Advance data pointer
129  context->txBufferPos += n;
130  }
131  }
132  else
133  {
134  //Prepare to send new protocol data
135  context->txBufferLen = 0;
136  context->txBufferPos = 0;
137 
138  //We are done
139  break;
140  }
141  }
142 
143  //Return status code
144  return error;
145 }
146 
147 
148 /**
149  * @brief Read protocol data
150  * @param[in] context Pointer to the TLS context
151  * @param[out] data Pointer to the received data
152  * @param[out] length Number of data bytes that were received
153  * @param[out] contentType Higher level protocol
154  * @return Error code
155  **/
156 
158  uint8_t **data, size_t *length, TlsContentType *contentType)
159 {
160  error_t error;
161  size_t n;
164 
165  //Initialize status code
166  error = NO_ERROR;
167 
168  //Fragment reassembly process
169  do
170  {
171  //Empty receive buffer?
172  if(context->rxBufferLen == 0)
173  {
174  //Read a TLS record
175  error = tlsReadRecord(context, context->rxBuffer,
176  context->rxBufferSize, &n, &type);
177 
178  //Check status code
179  if(!error)
180  {
181  //Save record type
182  context->rxBufferType = type;
183  //Number of bytes available for reading
184  context->rxBufferLen = n;
185  //Rewind to the beginning of the buffer
186  context->rxBufferPos = 0;
187  }
188  }
189  //Imcomplete message received?
190  else if(error == ERROR_MORE_DATA_REQUIRED)
191  {
192  //Make room at the end of the buffer
193  if(context->rxBufferPos > 0)
194  {
195  //Move unread data to the beginning of the buffer
196  osMemmove(context->rxBuffer, context->rxBuffer +
197  context->rxBufferPos, context->rxBufferLen);
198 
199  //Rewind to the beginning of the buffer
200  context->rxBufferPos = 0;
201  }
202 
203  //Read a TLS record
204  error = tlsReadRecord(context, context->rxBuffer + context->rxBufferLen,
205  context->rxBufferSize - context->rxBufferLen, &n, &type);
206 
207  //Check status code
208  if(!error)
209  {
210  //Fragmented records with mixed types cannot be interleaved
211  if(type != context->rxBufferType)
212  {
213  error = ERROR_UNEXPECTED_MESSAGE;
214  }
215  }
216 
217  //Check status code
218  if(!error)
219  {
220  //Number of bytes available for reading
221  context->rxBufferLen += n;
222  }
223  }
224 
225  //Check status code
226  if(!error)
227  {
228  //Handshake message received?
229  if(context->rxBufferType == TLS_TYPE_HANDSHAKE)
230  {
231  //A message may be fragmented across several records
232  if(context->rxBufferLen < sizeof(TlsHandshake))
233  {
234  //Read an additional record
235  error = ERROR_MORE_DATA_REQUIRED;
236  }
237  else
238  {
239  //Point to the handshake message
240  message = (TlsHandshake *) (context->rxBuffer + context->rxBufferPos);
241  //Retrieve the length of the handshake message
242  n = sizeof(TlsHandshake) + LOAD24BE(message->length);
243 
244  //A message may be fragmented across several records
245  if(context->rxBufferLen < n)
246  {
247  //Read an additional record
248  error = ERROR_MORE_DATA_REQUIRED;
249  }
250  else
251  {
252  //Pass the handshake message to the higher layer
253  error = NO_ERROR;
254  }
255  }
256  }
257  //ChangeCipherSpec message received?
258  else if(context->rxBufferType == TLS_TYPE_CHANGE_CIPHER_SPEC)
259  {
260  //A message may be fragmented across several records
261  if(context->rxBufferLen < sizeof(TlsChangeCipherSpec))
262  {
263  //Read an additional record
264  error = ERROR_MORE_DATA_REQUIRED;
265  }
266  else
267  {
268  //Length of the ChangeCipherSpec message
269  n = sizeof(TlsChangeCipherSpec);
270  //Pass the ChangeCipherSpec message to the higher layer
271  error = NO_ERROR;
272  }
273  }
274  //Alert message received?
275  else if(context->rxBufferType == TLS_TYPE_ALERT)
276  {
277  //A message may be fragmented across several records
278  if(context->rxBufferLen < sizeof(TlsAlert))
279  {
280  //Read an additional record
281  error = ERROR_MORE_DATA_REQUIRED;
282  }
283  else
284  {
285  //Length of the Alert message
286  n = sizeof(TlsAlert);
287  //Pass the Alert message to the higher layer
288  error = NO_ERROR;
289  }
290  }
291  //Application data received?
292  else if(context->rxBufferType == TLS_TYPE_APPLICATION_DATA)
293  {
294  //Length of the application data
295  n = context->rxBufferLen;
296  //Pass the application data to the higher layer
297  error = NO_ERROR;
298  }
299  //Unknown content type?
300  else
301  {
302  //Report an error
303  error = ERROR_UNEXPECTED_MESSAGE;
304  }
305  }
306 
307  //Read as many records as necessary to reassemble the data
308  } while(error == ERROR_MORE_DATA_REQUIRED);
309 
310  //Successful processing?
311  if(!error)
312  {
313 #if (TLS_MAX_WARNING_ALERTS > 0)
314  //Reset the count of consecutive warning alerts
315  if(context->rxBufferType != TLS_TYPE_ALERT)
316  {
317  context->alertCount = 0;
318  }
319 #endif
320 #if (TLS_MAX_KEY_UPDATE_MESSAGES > 0)
321  //Reset the count of consecutive KeyUpdate messages
322  if(context->rxBufferType != TLS_TYPE_HANDSHAKE)
323  {
324  context->keyUpdateCount = 0;
325  }
326 #endif
327 
328  //Pointer to the received data
329  *data = context->rxBuffer + context->rxBufferPos;
330  //Length, in byte, of the data
331  *length = n;
332  //Protocol type
333  *contentType = context->rxBufferType;
334  }
335 
336  //Return status code
337  return error;
338 }
339 
340 
341 /**
342  * @brief Send a TLS record
343  * @param[in] context Pointer to the TLS context
344  * @param[in] data Pointer to the record data
345  * @param[in] length Length of the record data
346  * @param[in] contentType Record type
347  * @return Error code
348  **/
349 
350 error_t tlsWriteRecord(TlsContext *context, const uint8_t *data,
351  size_t length, TlsContentType contentType)
352 {
353  error_t error;
354  size_t n;
355  uint16_t legacyVersion;
356  TlsRecord *record;
357  TlsEncryptionEngine *encryptionEngine;
358 
359  //Point to the encryption engine
360  encryptionEngine = &context->encryptionEngine;
361 
362  //Point to the TLS record
363  record = (TlsRecord *) context->txBuffer;
364 
365  //Initialize status code
366  error = NO_ERROR;
367 
368  //Send process
369  while(!error)
370  {
371  //Send as much data as possible
372  if(context->txRecordLen == 0)
373  {
374  //The record version must be set to 0x0303 for all records generated
375  //by a TLS 1.3 implementation other than an initial ClientHello
376  legacyVersion = MIN(context->version, TLS_VERSION_1_2);
377 
378  //Format TLS record
379  record->type = contentType;
380  record->version = htons(legacyVersion);
381  record->length = htons(length);
382 
383  //Copy record data
384  osMemmove(record->data, data, length);
385 
386  //Debug message
387  TRACE_DEBUG("Sending TLS record (%" PRIuSIZE " bytes)...\r\n", length);
388  TRACE_DEBUG_ARRAY(" ", record, length + sizeof(TlsRecord));
389 
390  //Protect record payload?
391  if(encryptionEngine->cipherMode != CIPHER_MODE_NULL ||
392  encryptionEngine->hashAlgo != NULL)
393  {
394  //Encrypt TLS record
395  error = tlsEncryptRecord(context, encryptionEngine, record);
396  }
397 
398  //Check status code
399  if(!error)
400  {
401  //Actual length of the record data
402  context->txRecordLen = sizeof(TlsRecord) + ntohs(record->length);
403  //Point to the beginning of the record
404  context->txRecordPos = 0;
405  }
406  }
407  else if(context->txRecordPos < context->txRecordLen)
408  {
409  //Total number of bytes that have been written
410  n = 0;
411 
412  //Send more data
413  error = context->socketSendCallback(context->socketHandle,
414  context->txBuffer + context->txRecordPos,
415  context->txRecordLen - context->txRecordPos, &n, 0);
416 
417  //Check status code
418  if(error == NO_ERROR || error == ERROR_WOULD_BLOCK || error == ERROR_TIMEOUT)
419  {
420  //Advance data pointer
421  context->txRecordPos += n;
422  }
423  else
424  {
425  //The write operation has failed
426  error = ERROR_WRITE_FAILED;
427  }
428  }
429  else
430  {
431  //Prepare to send the next TLS record
432  context->txRecordLen = 0;
433  context->txRecordPos = 0;
434 
435  //We are done
436  break;
437  }
438  }
439 
440  //Return status code
441  return error;
442 }
443 
444 
445 /**
446  * @brief Receive a TLS record
447  * @param[in] context Pointer to the TLS context
448  * @param[out] data Buffer where to store the record data
449  * @param[in] size Maximum acceptable size for the incoming record
450  * @param[out] length Length of the record data
451  * @param[out] contentType Record type
452  * @return Error code
453  **/
454 
456  size_t size, size_t *length, TlsContentType *contentType)
457 {
458  error_t error;
459  size_t n;
460  TlsRecord *record;
461 
462  //Initialize status code
463  error = NO_ERROR;
464 
465  //Point to the buffer where to store the incoming TLS record
466  record = (TlsRecord *) data;
467 
468  //Receive process
469  while(!error)
470  {
471  //Read as much data as possible
472  if(context->rxRecordPos < sizeof(TlsRecord))
473  {
474  //Make sure that the buffer is large enough to hold the record header
475  if(size >= sizeof(TlsRecord))
476  {
477  //Total number of bytes that have been received
478  n = 0;
479 
480  //Read TLS record header
481  error = context->socketReceiveCallback(context->socketHandle,
482  data + context->rxRecordPos,
483  sizeof(TlsRecord) - context->rxRecordPos, &n, 0);
484 
485  //Check status code
486  if(error == NO_ERROR || error == ERROR_WOULD_BLOCK || error == ERROR_TIMEOUT)
487  {
488  //Advance data pointer
489  context->rxRecordPos += n;
490 
491  //TLS record header successfully received?
492  if(context->rxRecordPos >= sizeof(TlsRecord))
493  {
494  //Debug message
495  TRACE_DEBUG("Record header received:\r\n");
496  TRACE_DEBUG_ARRAY(" ", record, sizeof(TlsRecord));
497 
498  //Retrieve the length of the TLS record
499  context->rxRecordLen = sizeof(TlsRecord) + ntohs(record->length);
500  }
501  }
502  else
503  {
504  //The read operation has failed
505  error = ERROR_READ_FAILED;
506  }
507  }
508  else
509  {
510  //Report an error
511  error = ERROR_RECORD_OVERFLOW;
512  }
513  }
514  else if(context->rxRecordPos < context->rxRecordLen)
515  {
516  //Make sure that the buffer is large enough to hold the entire record
517  if(size >= context->rxRecordLen)
518  {
519  //Total number of bytes that have been received
520  n = 0;
521 
522  //Read TLS record contents
523  error = context->socketReceiveCallback(context->socketHandle,
524  data + context->rxRecordPos,
525  context->rxRecordLen - context->rxRecordPos, &n, 0);
526 
527  //Check status code
528  if(error == NO_ERROR || error == ERROR_WOULD_BLOCK || error == ERROR_TIMEOUT)
529  {
530  //Advance data pointer
531  context->rxRecordPos += n;
532  }
533  else
534  {
535  //The read operation has failed
536  error = ERROR_READ_FAILED;
537  }
538  }
539  else
540  {
541  //Report an error
542  error = ERROR_RECORD_OVERFLOW;
543  }
544  }
545  else
546  {
547  //Process the incoming TLS record
548  error = tlsProcessRecord(context, record);
549 
550  //Check status code
551  if(error == NO_ERROR)
552  {
553  //Actual length of the record data
554  *length = ntohs(record->length);
555  //Record type
556  *contentType = (TlsContentType) record->type;
557 
558  //Debug message
559  TRACE_DEBUG("TLS record received (%" PRIuSIZE " bytes)...\r\n", *length);
560  TRACE_DEBUG_ARRAY(" ", record, *length + sizeof(TlsRecord));
561 
562  //Discard record header
563  osMemmove(data, record->data, *length);
564 
565  //Prepare to receive the next TLS record
566  context->rxRecordLen = 0;
567  context->rxRecordPos = 0;
568 
569  //We are done
570  break;
571  }
572 #if (TLS_MAX_VERSION >= TLS_VERSION_1_3 && TLS_MIN_VERSION <= TLS_VERSION_1_3)
573  else if(error == ERROR_BAD_RECORD_MAC)
574  {
575  //Check current state
576  if(context->version == TLS_VERSION_1_3 &&
577  context->entity == TLS_CONNECTION_END_SERVER &&
578  context->state == TLS_STATE_CLIENT_FINISHED &&
579  context->rxBufferLen == 0)
580  {
581  //Early data received?
582  if(!context->updatedClientHelloReceived &&
583  context->earlyDataExtReceived)
584  {
585  //Amount of 0-RTT data received by the server
586  context->earlyDataLen += ntohs(record->length);
587 
588  //Discard records which fail deprotection (up to the configured
589  //max_early_data_size)
590  if(context->earlyDataLen <= context->maxEarlyDataSize)
591  {
592  //Debug message
593  TRACE_INFO("Discarding early data (%" PRIu16 " bytes)...\r\n",
594  ntohs(record->length));
595 
596  //Prepare to receive the next TLS record
597  context->rxRecordLen = 0;
598  context->rxRecordPos = 0;
599 
600  //Catch exception
601  error = NO_ERROR;
602  }
603  }
604  }
605  }
606 #endif
607  else
608  {
609  //Invalid record received
610  }
611  }
612  }
613 
614  //Return status code
615  return error;
616 }
617 
618 
619 /**
620  * @brief Process incoming TLS record
621  * @param[in] context Pointer to the TLS context
622  * @param[in] record Pointer to the received TLS record
623  * @return Error code
624  **/
625 
627 {
628  error_t error;
629  TlsEncryptionEngine *decryptionEngine;
630 
631  //Point to the decryption engine
632  decryptionEngine = &context->decryptionEngine;
633 
634  //Check current state
635  if(context->state > TLS_STATE_SERVER_HELLO)
636  {
637  //Once the server has sent the ServerHello message, enforce the version
638  //of incoming records. In TLS 1.3, this field is deprecated. It may be
639  //validated to match the fixed constant value 0x0303
640  if(ntohs(record->version) != MIN(context->version, TLS_VERSION_1_2))
642  }
643  else
644  {
645  //Compliant servers must accept any value {03,XX} as the record layer
646  //version number for ClientHello
647  if(LSB(record->version) != MSB(TLS_VERSION_1_0))
649  }
650 
651  //Version of TLS prior to TLS 1.3?
652  if(context->version <= TLS_VERSION_1_2)
653  {
654  //Check whether the record payload is protected
655  if(decryptionEngine->cipherMode != CIPHER_MODE_NULL ||
656  decryptionEngine->hashAlgo != NULL)
657  {
658  //Decrypt TLS record
659  error = tlsDecryptRecord(context, decryptionEngine, record);
660  //Any error to report?
661  if(error)
662  return error;
663  }
664  }
665  else
666  {
667  //An implementation may receive an unencrypted ChangeCipherSpec at a point
668  //at the handshake where the implementation is expecting protected records
669  //and so it is necessary to detect this condition prior to attempting to
670  //deprotect the record
671  if(record->type != TLS_TYPE_CHANGE_CIPHER_SPEC)
672  {
673 #if (TLS_MAX_CHANGE_CIPHER_SPEC_MESSAGES > 0)
674  //Reset the count of consecutive ChangeCipherSpec messages
675  context->changeCipherSpecCount = 0;
676 #endif
677  //Check whether the record payload is protected
678  if(decryptionEngine->cipherMode != CIPHER_MODE_NULL ||
679  decryptionEngine->hashAlgo != NULL)
680  {
681  //Decrypt TLS record
682  error = tlsDecryptRecord(context, decryptionEngine, record);
683  //Any error to report?
684  if(error)
685  return error;
686  }
687 
688  //Abort the handshake with an unexpected_message alert if a protected
689  //ChangeCipherSpec record was received
690  if(record->type == TLS_TYPE_CHANGE_CIPHER_SPEC)
692  }
693 
694  //Implementations must not send Handshake and Alert records that have a
695  //zero-length plaintext content (refer to RFC 8446, section 5.4)
696  if(record->type == TLS_TYPE_HANDSHAKE ||
697  record->type == TLS_TYPE_ALERT)
698  {
699  //If such a message is received, the receiving implementation must
700  //terminate the connection with an unexpected_message alert
701  if(ntohs(record->length) == 0)
703  }
704  }
705 
706  //The length of the plaintext record must not exceed 2^14 bytes
707  if(ntohs(record->length) > TLS_MAX_RECORD_LENGTH)
708  return ERROR_RECORD_OVERFLOW;
709 
710 #if (TLS_RECORD_SIZE_LIMIT_SUPPORT == ENABLED)
711  //Check whether the RecordSizeLimit extension has been negotiated
712  if(context->recordSizeLimitExtReceived)
713  {
714  //The value of RecordSizeLimit is used to limit the size of records
715  //that are created when encoding application data and the protected
716  //handshake message into records
717  if(decryptionEngine->cipherMode != CIPHER_MODE_NULL ||
718  decryptionEngine->hashAlgo != NULL)
719  {
720  //A TLS endpoint that receives a record larger than its advertised
721  //limit must generate a fatal record_overflow alert
722  if(ntohs(record->length) > decryptionEngine->recordSizeLimit)
723  return ERROR_RECORD_OVERFLOW;
724  }
725  }
726 #endif
727 
728 #if (TLS_MAX_EMPTY_RECORDS > 0)
729  //Empty record received?
730  if(ntohs(record->length) == 0)
731  {
732  //Increment the count of consecutive empty records
733  context->emptyRecordCount++;
734 
735  //Do not allow too many consecutive empty records
736  if(context->emptyRecordCount > TLS_MAX_EMPTY_RECORDS)
738  }
739  else
740  {
741  //Reset the count of consecutive empty records
742  context->emptyRecordCount = 0;
743  }
744 #endif
745 
746  //Successful processing
747  return NO_ERROR;
748 }
749 
750 
751 /**
752  * @brief Set TLS record type
753  * @param[in] context Pointer to the TLS context
754  * @param[in] record Pointer to the TLS record
755  * @param[in] type Record type
756  **/
757 
758 void tlsSetRecordType(TlsContext *context, void *record, uint8_t type)
759 {
760 #if (DTLS_SUPPORT == ENABLED)
761  //DTLS protocol?
762  if(context->transportProtocol == TLS_TRANSPORT_PROTOCOL_DATAGRAM)
763  {
764  //Set the type of the DTLS record
765  ((DtlsRecord *) record)->type = type;
766  }
767  else
768 #endif
769  //TLS protocol?
770  {
771  //Set the type of the DTLS record
772  ((TlsRecord *) record)->type = type;
773  }
774 }
775 
776 
777 /**
778  * @brief Get TLS record type
779  * @param[in] context Pointer to the TLS context
780  * @param[in] record Pointer to the TLS record
781  * @return Record type
782  **/
783 
784 uint8_t tlsGetRecordType(TlsContext *context, void *record)
785 {
786  uint8_t type;
787 
788 #if (DTLS_SUPPORT == ENABLED)
789  //DTLS protocol?
790  if(context->transportProtocol == TLS_TRANSPORT_PROTOCOL_DATAGRAM)
791  {
792  //Get the type of the DTLS record
793  type = ((DtlsRecord *) record)->type;
794  }
795  else
796 #endif
797  //TLS protocol?
798  {
799  //Get the type of the TLS record
800  type = ((TlsRecord *) record)->type;
801  }
802 
803  //Return the content type of the record
804  return type;
805 }
806 
807 
808 /**
809  * @brief Set TLS record length
810  * @param[in] context Pointer to the TLS context
811  * @param[in] record Pointer to the TLS record
812  * @param[in] length Record length
813  **/
814 
815 void tlsSetRecordLength(TlsContext *context, void *record, size_t length)
816 {
817 #if (DTLS_SUPPORT == ENABLED)
818  //DTLS protocol?
819  if(context->transportProtocol == TLS_TRANSPORT_PROTOCOL_DATAGRAM)
820  {
821  //Set the length of the DTLS record
822  ((DtlsRecord *) record)->length = htons(length);
823  }
824  else
825 #endif
826  //TLS protocol?
827  {
828  //Set the length of the DTLS record
829  ((TlsRecord *) record)->length = htons(length);
830  }
831 }
832 
833 
834 /**
835  * @brief Get TLS record length
836  * @param[in] context Pointer to the TLS context
837  * @param[in] record Pointer to the TLS record
838  * @return Record length
839  **/
840 
841 size_t tlsGetRecordLength(TlsContext *context, void *record)
842 {
843  size_t length;
844 
845 #if (DTLS_SUPPORT == ENABLED)
846  //DTLS protocol?
847  if(context->transportProtocol == TLS_TRANSPORT_PROTOCOL_DATAGRAM)
848  {
849  //Get the length of the DTLS record
850  length = ((DtlsRecord *) record)->length;
851  }
852  else
853 #endif
854  //TLS protocol?
855  {
856  //Get the length of the TLS record
857  length = ((TlsRecord *) record)->length;
858  }
859 
860  //Convert the length field to host byte order
861  return htons(length);
862 }
863 
864 
865 /**
866  * @brief Get TLS record payload
867  * @param[in] context Pointer to the TLS context
868  * @param[in] record Pointer to the TLS record
869  * @return Pointer to the first byte of the payload
870  **/
871 
872 uint8_t *tlsGetRecordData(TlsContext *context, void *record)
873 {
874  uint8_t *data;
875 
876 #if (DTLS_SUPPORT == ENABLED)
877  //DTLS protocol?
878  if(context->transportProtocol == TLS_TRANSPORT_PROTOCOL_DATAGRAM)
879  {
880  //Point to the payload of the DTLS record
881  data = ((DtlsRecord *) record)->data;
882  }
883  else
884 #endif
885  //TLS protocol?
886  {
887  //Point to the payload of the TLS record
888  data = ((TlsRecord *) record)->data;
889  }
890 
891  //Return a pointer to the first byte of the payload
892  return data;
893 }
894 
895 
896 /**
897  * @brief Format additional authenticated data (AAD)
898  * @param[in] context Pointer to the TLS context
899  * @param[in] encryptionEngine Pointer to the encryption engine
900  * @param[in] record Pointer to the TLS record
901  * @param[out] aad Pointer to the buffer where to store the resulting AAD
902  * @param[out] aadLen Length of the AAD, in bytes
903  **/
904 
905 void tlsFormatAad(TlsContext *context, TlsEncryptionEngine *encryptionEngine,
906  const void *record, uint8_t *aad, size_t *aadLen)
907 {
908 #if (DTLS_SUPPORT == ENABLED)
909  //DTLS protocol?
910  if(context->transportProtocol == TLS_TRANSPORT_PROTOCOL_DATAGRAM)
911  {
912  const DtlsRecord *dtlsRecord;
913 
914  //Point to the DTLS record
915  dtlsRecord = (DtlsRecord *) record;
916 
917  //Additional data to be authenticated
918  osMemcpy(aad, (void *) &dtlsRecord->epoch, 2);
919  osMemcpy(aad + 2, &dtlsRecord->seqNum, 6);
920  osMemcpy(aad + 8, &dtlsRecord->type, 3);
921  osMemcpy(aad + 11, (void *) &dtlsRecord->length, 2);
922 
923  //Length of the additional data, in bytes
924  *aadLen = 13;
925  }
926  else
927 #endif
928  //TLS protocol?
929  {
930  //Version of TLS prior to TLS 1.3?
931  if(context->version <= TLS_VERSION_1_2)
932  {
933  //Additional data to be authenticated
934  osMemcpy(aad, &encryptionEngine->seqNum, 8);
935  osMemcpy(aad + 8, record, 5);
936 
937  //Length of the additional data, in bytes
938  *aadLen = 13;
939  }
940  else
941  {
942  //The additional data input is the record header (refer to RFC 8446,
943  //section 5.2)
944  osMemcpy(aad, record, 5);
945 
946  //Length of the additional data, in bytes
947  *aadLen = 5;
948  }
949  }
950 }
951 
952 
953 /**
954  * @brief Format nonce
955  * @param[in] context Pointer to the TLS context
956  * @param[in] encryptionEngine Pointer to the encryption engine
957  * @param[in] record Pointer to the TLS record
958  * @param[in] recordIv Explicit part of the nonce
959  * @param[out] nonce Pointer to the buffer where to store the resulting nonce
960  * @param[out] nonceLen Length of the nonce, in bytes
961  **/
962 
963 void tlsFormatNonce(TlsContext *context, TlsEncryptionEngine *encryptionEngine,
964  const void *record, const uint8_t *recordIv, uint8_t *nonce, size_t *nonceLen)
965 {
966  size_t i;
967  size_t n;
968 
969  //Check the length of the nonce explicit part
970  if(encryptionEngine->recordIvLen != 0)
971  {
972  //Calculate the total length of the nonce
973  n = encryptionEngine->fixedIvLen + encryptionEngine->recordIvLen;
974 
975  //The salt is the implicit part of the nonce and is not sent in the packet
976  osMemcpy(nonce, encryptionEngine->iv, encryptionEngine->fixedIvLen);
977 
978  //The explicit part of the nonce is chosen by the sender
979  osMemcpy(nonce + encryptionEngine->fixedIvLen, recordIv,
980  encryptionEngine->recordIvLen);
981  }
982  else
983  {
984  //Calculate the total length of the nonce
985  n = encryptionEngine->fixedIvLen;
986 
987 #if (DTLS_SUPPORT == ENABLED)
988  //DTLS protocol?
989  if(context->transportProtocol == TLS_TRANSPORT_PROTOCOL_DATAGRAM)
990  {
991  const DtlsRecord *dtlsRecord;
992 
993  //Point to the DTLS record
994  dtlsRecord = (DtlsRecord *) record;
995 
996  //The 64-bit record sequence number is serialized as an 8-byte,
997  //big-endian value
998  osMemcpy(nonce + n - 8, (void *) &dtlsRecord->epoch, 2);
999  osMemcpy(nonce + n - 6, &dtlsRecord->seqNum, 6);
1000  }
1001  else
1002 #endif
1003  //TLS protocol?
1004  {
1005  //The 64-bit record sequence number is serialized as an 8-byte,
1006  //big-endian value
1007  osMemcpy(nonce + n - 8, &encryptionEngine->seqNum, 8);
1008  }
1009 
1010  //The 64-bit record sequence number is padded on the left by zeros
1011  osMemset(nonce, 0, n - 8);
1012 
1013  //The padded sequence number is XORed with the IV to form the nonce
1014  for(i = 0; i < n; i++)
1015  {
1016  nonce[i] ^= encryptionEngine->iv[i];
1017  }
1018  }
1019 
1020  //Return the total length of the nonce
1021  *nonceLen = n;
1022 }
1023 
1024 
1025 /**
1026  * @brief Increment sequence number
1027  * @param[in,out] seqNum Pointer to the 64-bit sequence number
1028  **/
1029 
1031 {
1032  uint16_t temp;
1033 
1034  //Sequence numbers are stored MSB first
1035  temp = seqNum->b[7] + 1;
1036  seqNum->b[7] = temp & 0xFF;
1037  temp = (temp >> 8) + seqNum->b[6];
1038  seqNum->b[6] = temp & 0xFF;
1039  temp = (temp >> 8) + seqNum->b[5];
1040  seqNum->b[5] = temp & 0xFF;
1041  temp = (temp >> 8) + seqNum->b[4];
1042  seqNum->b[4] = temp & 0xFF;
1043  temp = (temp >> 8) + seqNum->b[3];
1044  seqNum->b[3] = temp & 0xFF;
1045  temp = (temp >> 8) + seqNum->b[2];
1046  seqNum->b[2] = temp & 0xFF;
1047  temp = (temp >> 8) + seqNum->b[1];
1048  seqNum->b[1] = temp & 0xFF;
1049  temp = (temp >> 8) + seqNum->b[0];
1050  seqNum->b[0] = temp & 0xFF;
1051 }
1052 
1053 #endif
uint8_t message[]
Definition: chap.h:154
uint8_t type
Definition: coap_common.h:176
#define PRIuSIZE
#define htons(value)
Definition: cpu_endian.h:413
#define ntohs(value)
Definition: cpu_endian.h:421
#define LOAD24BE(p)
Definition: cpu_endian.h:197
@ CIPHER_MODE_NULL
Definition: crypto.h:942
Debugging facilities.
#define TRACE_DEBUG_ARRAY(p, a, n)
Definition: debug.h:108
#define TRACE_DEBUG(...)
Definition: debug.h:107
#define TRACE_INFO(...)
Definition: debug.h:95
uint8_t n
DtlsRecord
Definition: dtls_misc.h:180
error_t
Error codes.
Definition: error.h:43
@ ERROR_WOULD_BLOCK
Definition: error.h:96
@ ERROR_VERSION_NOT_SUPPORTED
Definition: error.h:67
@ ERROR_TIMEOUT
Definition: error.h:95
@ ERROR_BAD_RECORD_MAC
Definition: error.h:230
@ ERROR_MESSAGE_TOO_LONG
Definition: error.h:136
@ ERROR_WRITE_FAILED
Definition: error.h:221
@ NO_ERROR
Success.
Definition: error.h:44
@ ERROR_RECORD_OVERFLOW
Definition: error.h:231
@ ERROR_READ_FAILED
Definition: error.h:222
@ ERROR_MORE_DATA_REQUIRED
Definition: error.h:248
@ ERROR_UNEXPECTED_MESSAGE
Definition: error.h:194
uint8_t data[]
Definition: ethernet.h:222
uint8_t p
Definition: ndp.h:300
#define osMemset(p, value, length)
Definition: os_port.h:135
#define osMemmove(dest, src, length)
Definition: os_port.h:147
#define osMemcpy(dest, src, length)
Definition: os_port.h:141
#define LSB(x)
Definition: os_port.h:55
#define MIN(a, b)
Definition: os_port.h:63
#define MSB(x)
Definition: os_port.h:59
uint8_t length
Definition: tcp.h:368
uint32_t seqNum
Definition: tcp.h:341
TLS (Transport Layer Security)
@ TLS_STATE_CLIENT_FINISHED
Definition: tls.h:1459
@ TLS_STATE_SERVER_HELLO
Definition: tls.h:1444
@ TLS_TRANSPORT_PROTOCOL_DATAGRAM
Definition: tls.h:942
TlsChangeCipherSpec
Definition: tls.h:1845
TlsContentType
Content type.
Definition: tls.h:1007
@ TLS_TYPE_CHANGE_CIPHER_SPEC
Definition: tls.h:1009
@ TLS_TYPE_HANDSHAKE
Definition: tls.h:1011
@ TLS_TYPE_APPLICATION_DATA
Definition: tls.h:1012
@ TLS_TYPE_ALERT
Definition: tls.h:1010
#define TLS_MAX_EMPTY_RECORDS
Definition: tls.h:815
#define TLS_MAX_RECORD_LENGTH
Definition: tls.h:919
TlsAlert
Definition: tls.h:1856
#define TLS_VERSION_1_3
Definition: tls.h:97
#define TlsContext
Definition: tls.h:36
TlsSequenceNumber
Definition: tls.h:1489
@ TLS_CONNECTION_END_SERVER
Definition: tls.h:954
#define TLS_VERSION_1_0
Definition: tls.h:94
#define TlsEncryptionEngine
Definition: tls.h:40
TlsHandshake
Definition: tls.h:1737
TlsRecord
Definition: tls.h:1725
#define TLS_VERSION_1_2
Definition: tls.h:96
error_t tlsReadRecord(TlsContext *context, uint8_t *data, size_t size, size_t *length, TlsContentType *contentType)
Receive a TLS record.
Definition: tls_record.c:455
void tlsSetRecordType(TlsContext *context, void *record, uint8_t type)
Set TLS record type.
Definition: tls_record.c:758
uint8_t tlsGetRecordType(TlsContext *context, void *record)
Get TLS record type.
Definition: tls_record.c:784
void tlsIncSequenceNumber(TlsSequenceNumber *seqNum)
Increment sequence number.
Definition: tls_record.c:1030
error_t tlsProcessRecord(TlsContext *context, TlsRecord *record)
Process incoming TLS record.
Definition: tls_record.c:626
error_t tlsReadProtocolData(TlsContext *context, uint8_t **data, size_t *length, TlsContentType *contentType)
Read protocol data.
Definition: tls_record.c:157
uint8_t * tlsGetRecordData(TlsContext *context, void *record)
Get TLS record payload.
Definition: tls_record.c:872
void tlsSetRecordLength(TlsContext *context, void *record, size_t length)
Set TLS record length.
Definition: tls_record.c:815
void tlsFormatNonce(TlsContext *context, TlsEncryptionEngine *encryptionEngine, const void *record, const uint8_t *recordIv, uint8_t *nonce, size_t *nonceLen)
Format nonce.
Definition: tls_record.c:963
error_t tlsWriteRecord(TlsContext *context, const uint8_t *data, size_t length, TlsContentType contentType)
Send a TLS record.
Definition: tls_record.c:350
size_t tlsGetRecordLength(TlsContext *context, void *record)
Get TLS record length.
Definition: tls_record.c:841
void tlsFormatAad(TlsContext *context, TlsEncryptionEngine *encryptionEngine, const void *record, uint8_t *aad, size_t *aadLen)
Format additional authenticated data (AAD)
Definition: tls_record.c:905
error_t tlsWriteProtocolData(TlsContext *context, const uint8_t *data, size_t length, TlsContentType contentType)
Write protocol data.
Definition: tls_record.c:54
TLS record protocol.
error_t tlsDecryptRecord(TlsContext *context, TlsEncryptionEngine *decryptionEngine, void *record)
Decrypt an incoming TLS record.
TLS record decryption.
error_t tlsEncryptRecord(TlsContext *context, TlsEncryptionEngine *encryptionEngine, void *record)
Encrypt an outgoing TLS record.
TLS record encryption.