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