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  * Copyright (C) 2010-2018 Oryx Embedded SARL. All rights reserved.
8  *
9  * This file is part of CycloneSSL Open.
10  *
11  * This program is free software; you can redistribute it and/or
12  * modify it under the terms of the GNU General Public License
13  * as published by the Free Software Foundation; either version 2
14  * of the License, or (at your option) any later version.
15  *
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19  * GNU General Public License for more details.
20  *
21  * You should have received a copy of the GNU General Public License
22  * along with this program; if not, write to the Free Software Foundation,
23  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
24  *
25  * @author Oryx Embedded SARL (www.oryx-embedded.com)
26  * @version 1.9.0
27  **/
28 
29 //Switch to the appropriate trace level
30 #define TRACE_LEVEL TLS_TRACE_LEVEL
31 
32 //Dependencies
33 #include <string.h>
34 #include "tls.h"
35 #include "tls_common.h"
36 #include "tls_record.h"
37 #include "tls_misc.h"
38 #include "ssl_misc.h"
39 #include "cipher_mode/cbc.h"
40 #include "aead/ccm.h"
41 #include "aead/gcm.h"
42 #include "aead/chacha20_poly1305.h"
43 #include "debug.h"
44 
45 //Check TLS library configuration
46 #if (TLS_SUPPORT == ENABLED)
47 
48 
49 /**
50  * @brief Write protocol data
51  * @param[in] context Pointer to the TLS context
52  * @param[in] data Pointer to the data buffer
53  * @param[in] length Number of data bytes to be written
54  * @param[in] contentType Higher level protocol
55  * @return Error code
56  **/
57 
59  const uint8_t *data, size_t length, TlsContentType contentType)
60 {
61  error_t error;
62  size_t n;
63  uint8_t *p;
64 
65  //Initialize status code
66  error = NO_ERROR;
67 
68  //Fragmentation process
69  while(!error)
70  {
71  if(context->txBufferLen == 0)
72  {
73  //Check the length of the data
74  if(length > context->txBufferMaxLen)
75  {
76  //Report an error
77  error = ERROR_MESSAGE_TOO_LONG;
78  }
79  else if(length > 0)
80  {
81  //Make room for the encryption overhead
82  memmove(context->txBuffer + context->txBufferSize - length, data,
83  length);
84 
85  //Save record type
86  context->txBufferType = contentType;
87  //Set the length of the buffer
88  context->txBufferLen = length;
89  //Point to the beginning of the buffer
90  context->txBufferPos = 0;
91  }
92  else
93  {
94  //We are done
95  break;
96  }
97  }
98  else if(context->txBufferPos < context->txBufferLen)
99  {
100  //Number of bytes left to send
101  n = context->txBufferLen - context->txBufferPos;
102  //Point to the current fragment
103  p = context->txBuffer + context->txBufferSize - n;
104 
105  //The record length must not exceed 16384 bytes
107 
108 #if (TLS_MAX_FRAG_LEN_SUPPORT == ENABLED)
109  //Do not exceed the negotiated maximum fragment length
110  n = MIN(n, context->maxFragLen);
111 #endif
112 #if (TLS_RECORD_SIZE_LIMIT_SUPPORT == ENABLED)
113  //Maximum record size the peer is willing to receive
114  n = MIN(n, context->recordSizeLimit);
115 #endif
116  //Send TLS record
117  error = tlsWriteRecord(context, p, n, context->txBufferType);
118 
119  //Check status code
120  if(!error)
121  {
122  //Advance data pointer
123  context->txBufferPos += n;
124  }
125  }
126  else
127  {
128  //Prepare to send new protocol data
129  context->txBufferLen = 0;
130  context->txBufferPos = 0;
131 
132  //We are done
133  break;
134  }
135  }
136 
137  //Return status code
138  return error;
139 }
140 
141 
142 /**
143  * @brief Read protocol data
144  * @param[in] context Pointer to the TLS context
145  * @param[out] data Pointer to the received data
146  * @param[out] length Number of data bytes that were received
147  * @param[out] contentType Higher level protocol
148  * @return Error code
149  **/
150 
152  uint8_t **data, size_t *length, TlsContentType *contentType)
153 {
154  error_t error;
155  size_t n;
158 
159  //Initialize status code
160  error = NO_ERROR;
161 
162  //Fragment reassembly process
163  do
164  {
165  //Empty receive buffer?
166  if(context->rxBufferLen == 0)
167  {
168  //Read a TLS record
169  error = tlsReadRecord(context, context->rxBuffer,
170  context->rxBufferSize, &n, &type);
171 
172  //Check status code
173  if(!error)
174  {
175  //Save record type
176  context->rxBufferType = type;
177  //Number of bytes available for reading
178  context->rxBufferLen = n;
179  //Rewind to the beginning of the buffer
180  context->rxBufferPos = 0;
181  }
182  }
183  //Imcomplete message received?
184  else if(error == ERROR_MORE_DATA_REQUIRED)
185  {
186  //Make room at the end of the buffer
187  if(context->rxBufferPos > 0)
188  {
189  //Move unread data to the beginning of the buffer
190  memmove(context->rxBuffer, context->rxBuffer +
191  context->rxBufferPos, context->rxBufferLen);
192 
193  //Rewind to the beginning of the buffer
194  context->rxBufferPos = 0;
195  }
196 
197  //Read a TLS record
198  error = tlsReadRecord(context, context->rxBuffer + context->rxBufferLen,
199  context->rxBufferSize - context->rxBufferLen, &n, &type);
200 
201  //Check status code
202  if(!error)
203  {
204  //Fragmented records with mixed types cannot be interleaved
205  if(type != context->rxBufferType)
206  error = ERROR_UNEXPECTED_MESSAGE;
207  }
208 
209  //Check status code
210  if(!error)
211  {
212  //Number of bytes available for reading
213  context->rxBufferLen += n;
214  }
215  }
216 
217  //Check status code
218  if(!error)
219  {
220  //Handshake message received?
221  if(context->rxBufferType == TLS_TYPE_HANDSHAKE)
222  {
223  //A message may be fragmented across several records
224  if(context->rxBufferLen < sizeof(TlsHandshake))
225  {
226  //Read an additional record
227  error = ERROR_MORE_DATA_REQUIRED;
228  }
229  else
230  {
231  //Point to the handshake message
232  message = (TlsHandshake *) (context->rxBuffer + context->rxBufferPos);
233  //Retrieve the length of the handshake message
234  n = sizeof(TlsHandshake) + LOAD24BE(message->length);
235 
236  //A message may be fragmented across several records
237  if(context->rxBufferLen < n)
238  {
239  //Read an additional record
240  error = ERROR_MORE_DATA_REQUIRED;
241  }
242  else
243  {
244  //Pass the handshake message to the higher layer
245  error = NO_ERROR;
246  }
247  }
248  }
249  //ChangeCipherSpec message received?
250  else if(context->rxBufferType == TLS_TYPE_CHANGE_CIPHER_SPEC)
251  {
252  //A message may be fragmented across several records
253  if(context->rxBufferLen < sizeof(TlsChangeCipherSpec))
254  {
255  //Read an additional record
256  error = ERROR_MORE_DATA_REQUIRED;
257  }
258  else
259  {
260  //Length of the ChangeCipherSpec message
261  n = sizeof(TlsChangeCipherSpec);
262  //Pass the ChangeCipherSpec message to the higher layer
263  error = NO_ERROR;
264  }
265  }
266  //Alert message received?
267  else if(context->rxBufferType == TLS_TYPE_ALERT)
268  {
269  //A message may be fragmented across several records
270  if(context->rxBufferLen < sizeof(TlsAlert))
271  {
272  //Read an additional record
273  error = ERROR_MORE_DATA_REQUIRED;
274  }
275  else
276  {
277  //Length of the Alert message
278  n = sizeof(TlsAlert);
279  //Pass the Alert message to the higher layer
280  error = NO_ERROR;
281  }
282  }
283  //Application data received?
284  else if(context->rxBufferType == TLS_TYPE_APPLICATION_DATA)
285  {
286  //Length of the application data
287  n = context->rxBufferLen;
288  //Pass the application data to the higher layer
289  error = NO_ERROR;
290  }
291  //Unknown content type?
292  else
293  {
294  //Report an error
295  error = ERROR_UNEXPECTED_MESSAGE;
296  }
297  }
298 
299  //Read as many records as necessary to reassemble the data
300  } while(error == ERROR_MORE_DATA_REQUIRED);
301 
302  //Successful processing?
303  if(!error)
304  {
305 #if (TLS_MAX_WARNING_ALERTS > 0)
306  //Reset the count of consecutive warning alerts
307  if(context->rxBufferType != TLS_TYPE_ALERT)
308  context->alertCount = 0;
309 #endif
310 #if (TLS_MAX_KEY_UPDATE_MESSAGES > 0)
311  //Reset the count of consecutive KeyUpdate messages
312  if(context->rxBufferType != TLS_TYPE_HANDSHAKE)
313  context->keyUpdateCount = 0;
314 #endif
315 
316  //Pointer to the received data
317  *data = context->rxBuffer + context->rxBufferPos;
318  //Length, in byte, of the data
319  *length = n;
320  //Protocol type
321  *contentType = context->rxBufferType;
322  }
323 
324  //Return status code
325  return error;
326 }
327 
328 
329 /**
330  * @brief Send a TLS record
331  * @param[in] context Pointer to the TLS context
332  * @param[in] data Pointer to the record data
333  * @param[in] length Length of the record data
334  * @param[in] contentType Record type
335  * @return Error code
336  **/
337 
338 error_t tlsWriteRecord(TlsContext *context, const uint8_t *data,
339  size_t length, TlsContentType contentType)
340 {
341  error_t error;
342  size_t n;
343  uint16_t legacyVersion;
344  TlsRecord *record;
345  TlsEncryptionEngine *encryptionEngine;
346 
347  //Point to the encryption engine
348  encryptionEngine = &context->encryptionEngine;
349 
350  //Point to the TLS record
351  record = (TlsRecord *) context->txBuffer;
352 
353  //Initialize status code
354  error = NO_ERROR;
355 
356  //Send process
357  while(!error)
358  {
359  //Send as much data as possible
360  if(context->txRecordLen == 0)
361  {
362  //The record version must be set to 0x0303 for all records generated
363  //by a TLS 1.3 implementation other than an initial ClientHello
364  legacyVersion = MIN(context->version, TLS_VERSION_1_2);
365 
366  //Format TLS record
367  record->type = contentType;
368  record->version = htons(legacyVersion);
369  record->length = htons(length);
370 
371  //Copy record data
372  memmove(record->data, data, length);
373 
374  //Debug message
375  TRACE_DEBUG("Sending TLS record (%" PRIuSIZE " bytes)...\r\n", length);
376  TRACE_DEBUG_ARRAY(" ", record, length + sizeof(TlsRecord));
377 
378  //Protect record payload?
379  if(encryptionEngine->cipherMode != CIPHER_MODE_NULL ||
380  encryptionEngine->hashAlgo != NULL)
381  {
382  //Encrypt TLS record
383  error = tlsEncryptRecord(context, encryptionEngine, record);
384  }
385 
386  //Check status code
387  if(!error)
388  {
389  //Actual length of the record data
390  context->txRecordLen = sizeof(TlsRecord) + ntohs(record->length);
391  //Point to the beginning of the record
392  context->txRecordPos = 0;
393  }
394  }
395  else if(context->txRecordPos < context->txRecordLen)
396  {
397  //Total number of bytes that have been written
398  n = 0;
399 
400  //Send more data
401  error = context->socketSendCallback(context->socketHandle,
402  context->txBuffer + context->txRecordPos,
403  context->txRecordLen - context->txRecordPos, &n, 0);
404 
405  //Check status code
406  if(error == NO_ERROR || error == ERROR_WOULD_BLOCK || error == ERROR_TIMEOUT)
407  {
408  //Advance data pointer
409  context->txRecordPos += n;
410  }
411  else
412  {
413  //The write operation has failed
414  error = ERROR_WRITE_FAILED;
415  }
416  }
417  else
418  {
419  //Prepare to send the next TLS record
420  context->txRecordLen = 0;
421  context->txRecordPos = 0;
422 
423  //We are done
424  break;
425  }
426  }
427 
428  //Return status code
429  return error;
430 }
431 
432 
433 /**
434  * @brief Receive a TLS record
435  * @param[in] context Pointer to the TLS context
436  * @param[out] data Buffer where to store the record data
437  * @param[in] size Maximum acceptable size for the incoming record
438  * @param[out] length Length of the record data
439  * @param[out] contentType Record type
440  * @return Error code
441  **/
442 
444  size_t size, size_t *length, TlsContentType *contentType)
445 {
446  error_t error;
447  size_t n;
448  TlsRecord *record;
449 
450  //Initialize status code
451  error = NO_ERROR;
452 
453  //Point to the buffer where to store the incoming TLS record
454  record = (TlsRecord *) data;
455 
456  //Receive process
457  while(!error)
458  {
459  //Read as much data as possible
460  if(context->rxRecordPos < sizeof(TlsRecord))
461  {
462  //Make sure that the buffer is large enough to hold the record header
463  if(size >= sizeof(TlsRecord))
464  {
465  //Total number of bytes that have been received
466  n = 0;
467 
468  //Read TLS record header
469  error = context->socketReceiveCallback(context->socketHandle,
470  data + context->rxRecordPos,
471  sizeof(TlsRecord) - context->rxRecordPos, &n, 0);
472 
473  //Check status code
474  if(error == NO_ERROR || error == ERROR_WOULD_BLOCK || error == ERROR_TIMEOUT)
475  {
476  //Advance data pointer
477  context->rxRecordPos += n;
478 
479  //TLS record header successfully received?
480  if(context->rxRecordPos >= sizeof(TlsRecord))
481  {
482  //Debug message
483  TRACE_DEBUG("Record header received:\r\n");
484  TRACE_DEBUG_ARRAY(" ", record, sizeof(TlsRecord));
485 
486  //Retrieve the length of the TLS record
487  context->rxRecordLen = sizeof(TlsRecord) + ntohs(record->length);
488  }
489  }
490  else
491  {
492  //The read operation has failed
493  error = ERROR_READ_FAILED;
494  }
495  }
496  else
497  {
498  //Report an error
499  error = ERROR_RECORD_OVERFLOW;
500  }
501  }
502  else if(context->rxRecordPos < context->rxRecordLen)
503  {
504  //Make sure that the buffer is large enough to hold the entire record
505  if(size >= context->rxRecordLen)
506  {
507  //Total number of bytes that have been received
508  n = 0;
509 
510  //Read TLS record contents
511  error = context->socketReceiveCallback(context->socketHandle,
512  data + context->rxRecordPos,
513  context->rxRecordLen - context->rxRecordPos, &n, 0);
514 
515  //Check status code
516  if(error == NO_ERROR || error == ERROR_WOULD_BLOCK || error == ERROR_TIMEOUT)
517  {
518  //Advance data pointer
519  context->rxRecordPos += n;
520  }
521  else
522  {
523  //The read operation has failed
524  error = ERROR_READ_FAILED;
525  }
526  }
527  else
528  {
529  //Report an error
530  error = ERROR_RECORD_OVERFLOW;
531  }
532  }
533  else
534  {
535  //Process the incoming TLS record
536  error = tlsProcessRecord(context, record);
537 
538  //Check status code
539  if(error == NO_ERROR)
540  {
541  //Actual length of the record data
542  *length = ntohs(record->length);
543  //Record type
544  *contentType = (TlsContentType) record->type;
545 
546  //Debug message
547  TRACE_DEBUG("TLS record received (%" PRIuSIZE " bytes)...\r\n", *length);
548  TRACE_DEBUG_ARRAY(" ", record, *length + sizeof(TlsRecord));
549 
550  //Discard record header
551  memmove(data, record->data, *length);
552 
553  //Prepare to receive the next TLS record
554  context->rxRecordLen = 0;
555  context->rxRecordPos = 0;
556 
557  //We are done
558  break;
559  }
560 #if (TLS_MAX_VERSION >= TLS_VERSION_1_3 && TLS_MIN_VERSION <= TLS_VERSION_1_3)
561  else if(error == ERROR_BAD_RECORD_MAC)
562  {
563  //Check current state
564  if(context->version == TLS_VERSION_1_3 &&
565  context->entity == TLS_CONNECTION_END_SERVER &&
566  context->state == TLS_STATE_CLIENT_FINISHED &&
567  context->rxBufferLen == 0)
568  {
569  //Early data received?
570  if(!context->updatedClientHelloReceived &&
571  context->earlyDataExtReceived)
572  {
573  //Amount of 0-RTT data received by the server
574  context->earlyDataLen += ntohs(record->length);
575 
576  //Discard records which fail deprotection (up to the configured
577  //max_early_data_size)
578  if(context->earlyDataLen <= context->maxEarlyDataSize)
579  {
580  //Debug message
581  TRACE_INFO("Discarding early data (%" PRIuSIZE " bytes)...\r\n",
582  ntohs(record->length));
583 
584  //Prepare to receive the next TLS record
585  context->rxRecordLen = 0;
586  context->rxRecordPos = 0;
587 
588  //Catch exception
589  error = NO_ERROR;
590  }
591  }
592  }
593  }
594 #endif
595  else
596  {
597  //Invalid record received
598  }
599  }
600  }
601 
602  //Return status code
603  return error;
604 }
605 
606 
607 /**
608  * @brief Process incoming TLS record
609  * @param[in] context Pointer to the TLS context
610  * @param[in] record Pointer to the received TLS record
611  * @return Error code
612  **/
613 
615 {
616  error_t error;
617  TlsEncryptionEngine *decryptionEngine;
618 
619  //Point to the decryption engine
620  decryptionEngine = &context->decryptionEngine;
621 
622  //Check current state
623  if(context->state > TLS_STATE_SERVER_HELLO)
624  {
625  //Once the server has sent the ServerHello message, enforce the version
626  //of incoming records. In TLS 1.3, this field is deprecated. It may be
627  //validated to match the fixed constant value 0x0303
628  if(ntohs(record->version) != MIN(context->version, TLS_VERSION_1_2))
630  }
631  else
632  {
633  //Compliant servers must accept any value {03,XX} as the record layer
634  //version number for ClientHello
635  if(LSB(record->version) != MSB(TLS_VERSION_1_0))
637  }
638 
639  //Version of TLS prior to TLS 1.3?
640  if(context->version <= TLS_VERSION_1_2)
641  {
642  //Check whether the record payload is protected
643  if(decryptionEngine->cipherMode != CIPHER_MODE_NULL ||
644  decryptionEngine->hashAlgo != NULL)
645  {
646  //Decrypt TLS record
647  error = tlsDecryptRecord(context, decryptionEngine, record);
648  //Any error to report?
649  if(error)
650  return error;
651  }
652  }
653  else
654  {
655  //An implementation may receive an unencrypted ChangeCipherSpec at a point
656  //at the handshake where the implementation is expecting protected records
657  //and so it is necessary to detect this condition prior to attempting to
658  //deprotect the record
659  if(record->type != TLS_TYPE_CHANGE_CIPHER_SPEC)
660  {
661 #if (TLS_MAX_CHANGE_CIPHER_SPEC_MESSAGES > 0)
662  //Reset the count of consecutive ChangeCipherSpec messages
663  context->changeCipherSpecCount = 0;
664 #endif
665  //Check whether the record payload is protected
666  if(decryptionEngine->cipherMode != CIPHER_MODE_NULL ||
667  decryptionEngine->hashAlgo != NULL)
668  {
669  //Decrypt TLS record
670  error = tlsDecryptRecord(context, decryptionEngine, record);
671  //Any error to report?
672  if(error)
673  return error;
674  }
675 
676  //Abort the handshake with an unexpected_message alert if a protected
677  //ChangeCipherSpec record was received
678  if(record->type == TLS_TYPE_CHANGE_CIPHER_SPEC)
680  }
681 
682  //Implementations must not send Handshake and Alert records that have a
683  //zero-length plaintext content (refer to RFC 8446, section 5.4)
684  if(record->type == TLS_TYPE_HANDSHAKE ||
685  record->type == TLS_TYPE_ALERT)
686  {
687  //If such a message is received, the receiving implementation must
688  //terminate the connection with an unexpected_message alert
689  if(ntohs(record->length) == 0)
691  }
692  }
693 
694  //The length of the plaintext record must not exceed 2^14 bytes
695  if(ntohs(record->length) > TLS_MAX_RECORD_LENGTH)
696  return ERROR_RECORD_OVERFLOW;
697 
698 #if (TLS_MAX_EMPTY_RECORDS > 0)
699  //Empty record received?
700  if(ntohs(record->length) == 0)
701  {
702  //Increment the count of consecutive empty records
703  context->emptyRecordCount++;
704 
705  //Do not allow too many consecutive empty records
706  if(context->emptyRecordCount > TLS_MAX_EMPTY_RECORDS)
708  }
709  else
710  {
711  //Reset the count of consecutive empty records
712  context->emptyRecordCount = 0;
713  }
714 #endif
715 
716  //Successful processing
717  return NO_ERROR;
718 }
719 
720 
721 /**
722  * @brief Encrypt an outgoing TLS record
723  * @param[in] context Pointer to the TLS context
724  * @param[in] encryptionEngine Pointer to the encryption engine
725  * @param[in,out] record TLS record to be encrypted
726  * @return Error code
727  **/
728 
730  TlsEncryptionEngine *encryptionEngine, void *record)
731 {
732  error_t error;
733  size_t length;
734  uint8_t *data;
735 
736  //Get the length of the TLS record
737  length = tlsGetRecordLength(context, record);
738  //Point to the payload
739  data = tlsGetRecordData(context, record);
740 
741  //Message authentication is required?
742  if(encryptionEngine->hashAlgo != NULL)
743  {
744 #if (TLS_MAX_VERSION >= SSL_VERSION_3_0 && TLS_MIN_VERSION <= SSL_VERSION_3_0)
745  //SSL 3.0 currently selected?
746  if(encryptionEngine->version == SSL_VERSION_3_0)
747  {
748  //SSL 3.0 uses an older obsolete version of the HMAC construction
749  error = sslComputeMac(encryptionEngine, record, data, length,
750  data + length);
751  //Any error to report?
752  if(error)
753  return error;
754  }
755  else
756 #endif
757 #if (TLS_MAX_VERSION >= TLS_VERSION_1_0 && TLS_MIN_VERSION <= TLS_VERSION_1_2)
758  //TLS 1.0, TLS 1.1 or TLS 1.2 currently selected?
759  if(encryptionEngine->version >= TLS_VERSION_1_0)
760  {
761  //TLS uses a HMAC construction
762  error = tlsComputeMac(context, encryptionEngine, record, data,
763  length, data + length);
764  //Any error to report?
765  if(error)
766  return error;
767  }
768  else
769 #endif
770  //Invalid TLS version?
771  {
772  //Report an error
773  return ERROR_INVALID_VERSION;
774  }
775 
776  //Debug message
777  TRACE_DEBUG("Write sequence number:\r\n");
778  TRACE_DEBUG_ARRAY(" ", &encryptionEngine->seqNum, sizeof(TlsSequenceNumber));
779  TRACE_DEBUG("Computed MAC:\r\n");
780  TRACE_DEBUG_ARRAY(" ", data + length, encryptionEngine->hashAlgo->digestSize);
781 
782  //Adjust the length of the message
783  length += encryptionEngine->hashAlgo->digestSize;
784  //Fix length field
785  tlsSetRecordLength(context, record, length);
786 
787  //Increment sequence number
788  tlsIncSequenceNumber(&encryptionEngine->seqNum);
789  }
790 
791  //Encryption is required?
792  if(encryptionEngine->cipherMode != CIPHER_MODE_NULL)
793  {
794  //Debug message
795  TRACE_DEBUG("Record to be encrypted (%" PRIuSIZE " bytes):\r\n", length);
796  TRACE_DEBUG_ARRAY(" ", record, length + sizeof(TlsRecord));
797 
798 #if (TLS_STREAM_CIPHER_SUPPORT == ENABLED)
799  //Stream cipher?
800  if(encryptionEngine->cipherMode == CIPHER_MODE_STREAM)
801  {
802  //Encrypt record contents
803  encryptionEngine->cipherAlgo->encryptStream(encryptionEngine->cipherContext,
804  data, data, length);
805  }
806  else
807 #endif
808 #if (TLS_CBC_CIPHER_SUPPORT == ENABLED)
809  //CBC block cipher?
810  if(encryptionEngine->cipherMode == CIPHER_MODE_CBC)
811  {
812  size_t i;
813  size_t paddingLen;
814 
815 #if (TLS_MAX_VERSION >= TLS_VERSION_1_1 && TLS_MIN_VERSION <= TLS_VERSION_1_2)
816  //TLS 1.1 and 1.2 use an explicit IV
817  if(encryptionEngine->version >= TLS_VERSION_1_1)
818  {
819  //Make room for the IV at the beginning of the data
820  memmove(data + encryptionEngine->recordIvLen, data, length);
821 
822  //The initialization vector should be chosen at random
823  error = context->prngAlgo->read(context->prngContext, data,
824  encryptionEngine->recordIvLen);
825  //Any error to report?
826  if(error)
827  return error;
828 
829  //Adjust the length of the message
830  length += encryptionEngine->recordIvLen;
831  }
832 #endif
833  //Get the actual amount of bytes in the last block
834  paddingLen = (length + 1) % encryptionEngine->cipherAlgo->blockSize;
835 
836  //Padding is added to force the length of the plaintext to be an
837  //integral multiple of the cipher's block length
838  if(paddingLen > 0)
839  paddingLen = encryptionEngine->cipherAlgo->blockSize - paddingLen;
840 
841  //Write padding bytes
842  for(i = 0; i <= paddingLen; i++)
843  data[length + i] = (uint8_t) paddingLen;
844 
845  //Compute the length of the resulting message
846  length += paddingLen + 1;
847  //Fix length field
848  tlsSetRecordLength(context, record, length);
849 
850  //Debug message
851  TRACE_DEBUG("Record with padding (%" PRIuSIZE " bytes):\r\n", length);
852  TRACE_DEBUG_ARRAY(" ", record, length + sizeof(TlsRecord));
853 
854  //CBC encryption
855  error = cbcEncrypt(encryptionEngine->cipherAlgo,
856  encryptionEngine->cipherContext, encryptionEngine->iv, data, data, length);
857  //Any error to report?
858  if(error)
859  return error;
860  }
861  else
862 #endif
863 #if (TLS_CCM_CIPHER_SUPPORT == ENABLED || TLS_CCM_8_CIPHER_SUPPORT == ENABLED || \
864  TLS_GCM_CIPHER_SUPPORT == ENABLED || TLS_CHACHA20_POLY1305_SUPPORT == ENABLED)
865  //AEAD cipher?
866  if(encryptionEngine->cipherMode == CIPHER_MODE_CCM ||
867  encryptionEngine->cipherMode == CIPHER_MODE_GCM ||
868  encryptionEngine->cipherMode == CIPHER_MODE_CHACHA20_POLY1305)
869  {
870  uint8_t *tag;
871  size_t aadLen;
872  size_t nonceLen;
873  uint8_t aad[13];
874  uint8_t nonce[12];
875 
876  //TLS 1.3 currently selected?
877  if(encryptionEngine->version == TLS_VERSION_1_3)
878  {
879  //The type field indicates the higher-level protocol used to process
880  //the enclosed fragment
881  data[length++] = tlsGetRecordType(context, record);
882 
883  //In TLS 1.3, the outer opaque_type field of a TLS record is always
884  //set to the value 23 (application data)
886 
887  //Fix the length field of the TLS record
888  tlsSetRecordLength(context, record, length +
889  encryptionEngine->authTagLen);
890  }
891 
892  //Additional data to be authenticated
893  tlsFormatAad(context, encryptionEngine, record, aad, &aadLen);
894 
895  //Check the length of the nonce explicit part
896  if(encryptionEngine->recordIvLen != 0)
897  {
898  //Make room for the explicit nonce at the beginning of the record
899  memmove(data + encryptionEngine->recordIvLen, data, length);
900 
901  //The explicit part of the nonce is chosen by the sender and is
902  //carried in each TLS record
903  error = context->prngAlgo->read(context->prngContext, data,
904  encryptionEngine->recordIvLen);
905  //Any error to report?
906  if(error)
907  return error;
908  }
909 
910  //Generate the nonce
911  tlsFormatNonce(context, encryptionEngine, record, data, nonce,
912  &nonceLen);
913 
914  //Point to the plaintext
915  data += encryptionEngine->recordIvLen;
916  //Point to the buffer where to store the authentication tag
917  tag = data + length;
918 
919 #if (TLS_CCM_CIPHER_SUPPORT == ENABLED || TLS_CCM_8_CIPHER_SUPPORT == ENABLED)
920  //CCM AEAD cipher?
921  if(encryptionEngine->cipherMode == CIPHER_MODE_CCM)
922  {
923  //Authenticated encryption using CCM
924  error = ccmEncrypt(encryptionEngine->cipherAlgo,
925  encryptionEngine->cipherContext, nonce, nonceLen, aad, aadLen,
926  data, data, length, tag, encryptionEngine->authTagLen);
927  }
928  else
929 #endif
930 #if (TLS_GCM_CIPHER_SUPPORT == ENABLED)
931  //GCM AEAD cipher?
932  if(encryptionEngine->cipherMode == CIPHER_MODE_GCM)
933  {
934  //Authenticated encryption using GCM
935  error = gcmEncrypt(encryptionEngine->gcmContext, nonce, nonceLen,
936  aad, aadLen, data, data, length, tag, encryptionEngine->authTagLen);
937  }
938  else
939 #endif
940 #if (TLS_CHACHA20_POLY1305_SUPPORT == ENABLED)
941  //ChaCha20Poly1305 AEAD cipher?
942  if(encryptionEngine->cipherMode == CIPHER_MODE_CHACHA20_POLY1305)
943  {
944  //Authenticated encryption using ChaCha20Poly1305
945  error = chacha20Poly1305Encrypt(encryptionEngine->encKey,
946  encryptionEngine->encKeyLen, nonce, nonceLen, aad, aadLen,
947  data, data, length, tag, encryptionEngine->authTagLen);
948  }
949  else
950 #endif
951  //Invalid cipher mode?
952  {
953  //The specified cipher mode is not supported
955  }
956 
957  //Failed to encrypt data?
958  if(error)
959  return error;
960 
961  //Compute the length of the resulting message
962  length += encryptionEngine->recordIvLen + encryptionEngine->authTagLen;
963  //Fix length field
964  tlsSetRecordLength(context, record, length);
965 
966  //Increment sequence number
967  tlsIncSequenceNumber(&encryptionEngine->seqNum);
968  }
969  else
970 #endif
971  //Invalid cipher mode?
972  {
973  //The specified cipher mode is not supported
975  }
976 
977  //Debug message
978  TRACE_DEBUG("Encrypted record (%" PRIuSIZE " bytes):\r\n", length);
979  TRACE_DEBUG_ARRAY(" ", record, length + sizeof(TlsRecord));
980  }
981 
982  //Successful encryption
983  return NO_ERROR;
984 }
985 
986 
987 /**
988  * @brief Decrypt an incoming TLS record
989  * @param[in] context Pointer to the TLS context
990  * @param[in] decryptionEngine Pointer to the decryption engine
991  * @param[in,out] record TLS record to be decrypted
992  * @return Error code
993  **/
994 
996  TlsEncryptionEngine *decryptionEngine, void *record)
997 {
998  error_t error;
999  size_t length;
1000  uint8_t *data;
1001 
1002  //Get the length of the TLS record
1003  length = tlsGetRecordLength(context, record);
1004  //Point to the payload
1005  data = tlsGetRecordData(context, record);
1006 
1007  //Decrypt record if necessary
1008  if(decryptionEngine->cipherMode != CIPHER_MODE_NULL)
1009  {
1010  //Debug message
1011  TRACE_DEBUG("Record to be decrypted (%" PRIuSIZE " bytes):\r\n", length);
1012  TRACE_DEBUG_ARRAY(" ", record, length + sizeof(TlsRecord));
1013 
1014 #if (TLS_STREAM_CIPHER_SUPPORT == ENABLED)
1015  //Stream cipher?
1016  if(decryptionEngine->cipherMode == CIPHER_MODE_STREAM)
1017  {
1018  //Decrypt record contents
1019  decryptionEngine->cipherAlgo->decryptStream(decryptionEngine->cipherContext,
1020  data, data, length);
1021  }
1022  else
1023 #endif
1024 #if (TLS_CBC_CIPHER_SUPPORT == ENABLED)
1025  //CBC block cipher?
1026  if(decryptionEngine->cipherMode == CIPHER_MODE_CBC)
1027  {
1028  size_t i;
1029  size_t paddingLen;
1030 
1031  //The length of the data must be a multiple of the block size
1032  if((length % decryptionEngine->cipherAlgo->blockSize) != 0)
1033  return ERROR_BAD_RECORD_MAC;
1034 
1035  //CBC decryption
1036  error = cbcDecrypt(decryptionEngine->cipherAlgo,
1037  decryptionEngine->cipherContext, decryptionEngine->iv, data, data, length);
1038  //Any error to report?
1039  if(error)
1040  return error;
1041 
1042  //Debug message
1043  TRACE_DEBUG("Record with padding (%" PRIuSIZE " bytes):\r\n", length);
1044  TRACE_DEBUG_ARRAY(" ", record, length + sizeof(TlsRecord));
1045 
1046 #if (TLS_MAX_VERSION >= TLS_VERSION_1_1 && TLS_MIN_VERSION <= TLS_VERSION_1_2)
1047  //TLS 1.1 and 1.2 use an explicit IV
1048  if(decryptionEngine->version >= TLS_VERSION_1_1)
1049  {
1050  //Make sure the message length is acceptable
1051  if(length < decryptionEngine->recordIvLen)
1052  return ERROR_BAD_RECORD_MAC;
1053 
1054  //Adjust the length of the message
1055  length -= decryptionEngine->recordIvLen;
1056 
1057  //Discard the first cipher block (corresponding to the explicit IV)
1058  memmove(data, data + decryptionEngine->recordIvLen, length);
1059  }
1060 #endif
1061  //Make sure the message length is acceptable
1062  if(length < decryptionEngine->cipherAlgo->blockSize)
1063  return ERROR_BAD_RECORD_MAC;
1064 
1065  //Compute the length of the padding string
1066  paddingLen = data[length - 1];
1067  //Erroneous padding length?
1068  if(paddingLen >= length)
1069  return ERROR_BAD_RECORD_MAC;
1070 
1071  //The receiver must check the padding
1072  for(i = 0; i <= paddingLen; i++)
1073  {
1074  //Each byte in the padding data must be filled with the padding
1075  //length value
1076  if(data[length - 1 - i] != paddingLen)
1077  return ERROR_BAD_RECORD_MAC;
1078  }
1079 
1080  //Remove padding bytes
1081  length -= paddingLen + 1;
1082  //Fix the length field of the TLS record
1083  tlsSetRecordLength(context, record, length);
1084  }
1085  else
1086 #endif
1087 #if (TLS_CCM_CIPHER_SUPPORT == ENABLED || TLS_CCM_8_CIPHER_SUPPORT == ENABLED || \
1088  TLS_GCM_CIPHER_SUPPORT == ENABLED || TLS_CHACHA20_POLY1305_SUPPORT == ENABLED)
1089  //AEAD cipher?
1090  if(decryptionEngine->cipherMode == CIPHER_MODE_CCM ||
1091  decryptionEngine->cipherMode == CIPHER_MODE_GCM ||
1092  decryptionEngine->cipherMode == CIPHER_MODE_CHACHA20_POLY1305)
1093  {
1094  uint8_t *ciphertext;
1095  uint8_t *tag;
1096  size_t aadLen;
1097  size_t nonceLen;
1098  uint8_t aad[13];
1099  uint8_t nonce[12];
1100 
1101  //Make sure the message length is acceptable
1102  if(length < (decryptionEngine->recordIvLen + decryptionEngine->authTagLen))
1103  return ERROR_BAD_RECORD_MAC;
1104 
1105  //Calculate the length of the ciphertext
1106  length -= decryptionEngine->recordIvLen + decryptionEngine->authTagLen;
1107 
1108  //Version of TLS prior to TLS 1.3?
1109  if(decryptionEngine->version <= TLS_VERSION_1_2)
1110  {
1111  //Fix the length field of the TLS record
1112  tlsSetRecordLength(context, record, length);
1113  }
1114  else
1115  {
1116  //The length must not exceed 2^14 octets + 1 octet for ContentType +
1117  //the maximum AEAD expansion. An endpoint that receives a record
1118  //that exceeds this length must terminate the connection with a
1119  //record_overflow alert
1120  if(length > (TLS_MAX_RECORD_LENGTH + 1))
1121  return ERROR_RECORD_OVERFLOW;
1122 
1123  //In TLS 1.3, the outer opaque_type field of a TLS record is always
1124  //set to the value 23 (application data)
1125  if(tlsGetRecordType(context, record) != TLS_TYPE_APPLICATION_DATA)
1126  return ERROR_BAD_RECORD_MAC;
1127  }
1128 
1129  //Additional data to be authenticated
1130  tlsFormatAad(context, decryptionEngine, record, aad, &aadLen);
1131 
1132  //Generate the nonce
1133  tlsFormatNonce(context, decryptionEngine, record, data, nonce,
1134  &nonceLen);
1135 
1136  //Point to the ciphertext
1137  ciphertext = data + decryptionEngine->recordIvLen;
1138  //Point to the authentication tag
1139  tag = ciphertext + length;
1140 
1141 #if (TLS_CCM_CIPHER_SUPPORT == ENABLED || TLS_CCM_8_CIPHER_SUPPORT == ENABLED)
1142  //CCM AEAD cipher?
1143  if(decryptionEngine->cipherMode == CIPHER_MODE_CCM)
1144  {
1145  //Authenticated decryption using CCM
1146  error = ccmDecrypt(decryptionEngine->cipherAlgo,
1147  decryptionEngine->cipherContext, nonce, nonceLen, aad, aadLen,
1148  ciphertext, ciphertext, length, tag, decryptionEngine->authTagLen);
1149  }
1150  else
1151 #endif
1152 #if (TLS_GCM_CIPHER_SUPPORT == ENABLED)
1153  //GCM AEAD cipher?
1154  if(decryptionEngine->cipherMode == CIPHER_MODE_GCM)
1155  {
1156  //Authenticated decryption using GCM
1157  error = gcmDecrypt(decryptionEngine->gcmContext, nonce, nonceLen,
1158  aad, aadLen, ciphertext, ciphertext, length, tag,
1159  decryptionEngine->authTagLen);
1160  }
1161  else
1162 #endif
1163 #if (TLS_CHACHA20_POLY1305_SUPPORT == ENABLED)
1164  //ChaCha20Poly1305 AEAD cipher?
1165  if(decryptionEngine->cipherMode == CIPHER_MODE_CHACHA20_POLY1305)
1166  {
1167  //Authenticated decryption using ChaCha20Poly1305
1168  error = chacha20Poly1305Decrypt(decryptionEngine->encKey,
1169  decryptionEngine->encKeyLen, nonce, 12, aad, aadLen, data,
1170  data, length, tag, decryptionEngine->authTagLen);
1171  }
1172  else
1173 #endif
1174  //Invalid cipher mode?
1175  {
1176  //The specified cipher mode is not supported
1178  }
1179 
1180  //Wrong authentication tag?
1181  if(error)
1182  return ERROR_BAD_RECORD_MAC;
1183 
1184  //Discard the explicit part of the nonce
1185  if(decryptionEngine->recordIvLen != 0)
1186  {
1187  memmove(data, data + decryptionEngine->recordIvLen, length);
1188  }
1189 
1190  //TLS 1.3 currently selected?
1191  if(decryptionEngine->version == TLS_VERSION_1_3)
1192  {
1193  //Upon successful decryption of an encrypted record, the receiving
1194  //implementation scans the field from the end toward the beginning
1195  //until it finds a non-zero octet
1196  while(length > 0 && data[length - 1] == 0)
1197  {
1198  length--;
1199  }
1200 
1201  //If a receiving implementation does not find a non-zero octet
1202  //in the cleartext, it must terminate the connection with an
1203  //unexpected_message alert
1204  if(length == 0)
1205  return ERROR_UNEXPECTED_MESSAGE;
1206 
1207  //Retrieve the length of the plaintext
1208  length--;
1209 
1210  //The actual content type of the record is found in the type field
1211  tlsSetRecordType(context, record, data[length]);
1212  //Fix the length field of the TLS record
1213  tlsSetRecordLength(context, record, length);
1214  }
1215 
1216  //Increment sequence number
1217  tlsIncSequenceNumber(&decryptionEngine->seqNum);
1218  }
1219  else
1220 #endif
1221  //Invalid cipher mode?
1222  {
1223  //The specified cipher mode is not supported
1225  }
1226 
1227  //Debug message
1228  TRACE_DEBUG("Decrypted record (%" PRIuSIZE " bytes):\r\n", length);
1229  TRACE_DEBUG_ARRAY(" ", record, length + sizeof(TlsRecord));
1230  }
1231 
1232  //Check message authentication code if necessary
1233  if(decryptionEngine->hashAlgo != NULL)
1234  {
1235  //Make sure the message length is acceptable
1236  if(length < decryptionEngine->hashAlgo->digestSize)
1237  return ERROR_BAD_RECORD_MAC;
1238 
1239  //Adjust the length of the message
1240  length -= decryptionEngine->hashAlgo->digestSize;
1241  //Fix the length field of the TLS record
1242  tlsSetRecordLength(context, record, length);
1243 
1244 #if (TLS_MAX_VERSION >= SSL_VERSION_3_0 && TLS_MIN_VERSION <= SSL_VERSION_3_0)
1245  //SSL 3.0 currently selected?
1246  if(decryptionEngine->version == SSL_VERSION_3_0)
1247  {
1248  //SSL 3.0 uses an older obsolete version of the HMAC construction
1249  error = sslComputeMac(decryptionEngine, record, data, length,
1250  decryptionEngine->hmacContext->digest);
1251  //Any error to report?
1252  if(error)
1253  return error;
1254  }
1255  else
1256 #endif
1257 #if (TLS_MAX_VERSION >= TLS_VERSION_1_0 && TLS_MIN_VERSION <= TLS_VERSION_1_2)
1258  //TLS 1.0, TLS 1.1 or TLS 1.2 currently selected?
1259  if(decryptionEngine->version >= TLS_VERSION_1_0)
1260  {
1261  //TLS uses a HMAC construction
1262  error = tlsComputeMac(context, decryptionEngine, record, data,
1263  length, decryptionEngine->hmacContext->digest);
1264  //Any error to report?
1265  if(error)
1266  return error;
1267  }
1268  else
1269 #endif
1270  //Invalid TLS version?
1271  {
1272  //Report an error
1273  return ERROR_INVALID_VERSION;
1274  }
1275 
1276  //Debug message
1277  TRACE_DEBUG("Read sequence number:\r\n");
1278  TRACE_DEBUG_ARRAY(" ", &decryptionEngine->seqNum, sizeof(TlsSequenceNumber));
1279  TRACE_DEBUG("Computed MAC:\r\n");
1280  TRACE_DEBUG_ARRAY(" ", decryptionEngine->hmacContext->digest, decryptionEngine->hashAlgo->digestSize);
1281 
1282  //Check the message authentication code
1283  if(memcmp(data + length, decryptionEngine->hmacContext->digest,
1284  decryptionEngine->hashAlgo->digestSize))
1285  {
1286  //Invalid MAC
1287  return ERROR_BAD_RECORD_MAC;
1288  }
1289 
1290  //Increment sequence number
1291  tlsIncSequenceNumber(&decryptionEngine->seqNum);
1292  }
1293 
1294  //Successful decryption
1295  return NO_ERROR;
1296 }
1297 
1298 
1299 /**
1300  * @brief Set TLS record type
1301  * @param[in] context Pointer to the TLS context
1302  * @param[in] record Pointer to the TLS record
1303  * @param[in] type Record type
1304  **/
1305 
1306 void tlsSetRecordType(TlsContext *context, void *record, uint8_t type)
1307 {
1308 #if (DTLS_SUPPORT == ENABLED)
1309  //DTLS protocol?
1310  if(context->transportProtocol == TLS_TRANSPORT_PROTOCOL_DATAGRAM)
1311  {
1312  //Set the type of the DTLS record
1313  ((DtlsRecord *) record)->type = type;
1314  }
1315  else
1316 #endif
1317  //TLS protocol?
1318  {
1319  //Set the type of the DTLS record
1320  ((TlsRecord *) record)->type = type;
1321  }
1322 }
1323 
1324 
1325 /**
1326  * @brief Get TLS record type
1327  * @param[in] context Pointer to the TLS context
1328  * @param[in] record Pointer to the TLS record
1329  * @return Record type
1330  **/
1331 
1332 uint8_t tlsGetRecordType(TlsContext *context, void *record)
1333 {
1334  uint8_t type;
1335 
1336 #if (DTLS_SUPPORT == ENABLED)
1337  //DTLS protocol?
1338  if(context->transportProtocol == TLS_TRANSPORT_PROTOCOL_DATAGRAM)
1339  {
1340  //Get the type of the DTLS record
1341  type = ((DtlsRecord *) record)->type;
1342  }
1343  else
1344 #endif
1345  //TLS protocol?
1346  {
1347  //Get the type of the TLS record
1348  type = ((TlsRecord *) record)->type;
1349  }
1350 
1351  //Return the content type of the record
1352  return type;
1353 }
1354 
1355 
1356 /**
1357  * @brief Set TLS record length
1358  * @param[in] context Pointer to the TLS context
1359  * @param[in] record Pointer to the TLS record
1360  * @param[in] length Record length
1361  **/
1362 
1363 void tlsSetRecordLength(TlsContext *context, void *record, size_t length)
1364 {
1365 #if (DTLS_SUPPORT == ENABLED)
1366  //DTLS protocol?
1367  if(context->transportProtocol == TLS_TRANSPORT_PROTOCOL_DATAGRAM)
1368  {
1369  //Set the length of the DTLS record
1370  ((DtlsRecord *) record)->length = htons(length);
1371  }
1372  else
1373 #endif
1374  //TLS protocol?
1375  {
1376  //Set the length of the DTLS record
1377  ((TlsRecord *) record)->length = htons(length);
1378  }
1379 }
1380 
1381 
1382 /**
1383  * @brief Get TLS record length
1384  * @param[in] context Pointer to the TLS context
1385  * @param[in] record Pointer to the TLS record
1386  * @return Record length
1387  **/
1388 
1389 size_t tlsGetRecordLength(TlsContext *context, void *record)
1390 {
1391  size_t length;
1392 
1393 #if (DTLS_SUPPORT == ENABLED)
1394  //DTLS protocol?
1395  if(context->transportProtocol == TLS_TRANSPORT_PROTOCOL_DATAGRAM)
1396  {
1397  //Get the length of the DTLS record
1398  length = ((DtlsRecord *) record)->length;
1399  }
1400  else
1401 #endif
1402  //TLS protocol?
1403  {
1404  //Get the length of the TLS record
1405  length = ((TlsRecord *) record)->length;
1406  }
1407 
1408  //Convert the length field to host byte order
1409  return htons(length);
1410 }
1411 
1412 
1413 /**
1414  * @brief Get TLS record payload
1415  * @param[in] context Pointer to the TLS context
1416  * @param[in] record Pointer to the TLS record
1417  * @return Pointer to the first byte of the payload
1418  **/
1419 
1420 uint8_t *tlsGetRecordData(TlsContext *context, void *record)
1421 {
1422  uint8_t *data;
1423 
1424 #if (DTLS_SUPPORT == ENABLED)
1425  //DTLS protocol?
1426  if(context->transportProtocol == TLS_TRANSPORT_PROTOCOL_DATAGRAM)
1427  {
1428  //Point to the payload of the DTLS record
1429  data = ((DtlsRecord *) record)->data;
1430  }
1431  else
1432 #endif
1433  //TLS protocol?
1434  {
1435  //Point to the payload of the TLS record
1436  data = ((TlsRecord *) record)->data;
1437  }
1438 
1439  //Return a pointer to the first byte of the payload
1440  return data;
1441 }
1442 
1443 
1444 /**
1445  * @brief Compute message authentication code
1446  * @param[in] context Pointer to the TLS context
1447  * @param[in] encryptionEngine Pointer to the encryption/decryption engine
1448  * @param[in] record Pointer to the TLS record
1449  * @param[in] data Pointer to the record data
1450  * @param[in] dataLen Length of the data
1451  * @param[out] mac The computed MAC value
1452  * @return Error code
1453  **/
1454 
1456  void *record, const uint8_t *data, size_t dataLen, uint8_t *mac)
1457 {
1458  //Initialize HMAC calculation
1459  hmacInit(encryptionEngine->hmacContext, encryptionEngine->hashAlgo,
1460  encryptionEngine->macKey, encryptionEngine->macKeyLen);
1461 
1462 #if (DTLS_SUPPORT == ENABLED)
1463  //DTLS protocol?
1464  if(context->transportProtocol == TLS_TRANSPORT_PROTOCOL_DATAGRAM)
1465  {
1466  const DtlsRecord *dtlsRecord;
1467 
1468  //Point to the DTLS record
1469  dtlsRecord = (DtlsRecord *) record;
1470 
1471  //Compute the MAC over the 64-bit value formed by concatenating the epoch
1472  //and the sequence number in the order they appear on the wire
1473  hmacUpdate(encryptionEngine->hmacContext, (void *) &dtlsRecord->epoch, 2);
1474  hmacUpdate(encryptionEngine->hmacContext, &dtlsRecord->seqNum, 6);
1475 
1476  //Compute MAC over the record contents
1477  hmacUpdate(encryptionEngine->hmacContext, &dtlsRecord->type, 3);
1478  hmacUpdate(encryptionEngine->hmacContext, (void *) &dtlsRecord->length, 2);
1479  hmacUpdate(encryptionEngine->hmacContext, data, dataLen);
1480  }
1481  else
1482 #endif
1483  //TLS protocol?
1484  {
1485  const TlsRecord *tlsRecord;
1486 
1487  //Point to the TLS record
1488  tlsRecord = (TlsRecord *) record;
1489 
1490  //Compute MAC over the implicit sequence number
1491  hmacUpdate(encryptionEngine->hmacContext, &encryptionEngine->seqNum,
1492  sizeof(TlsSequenceNumber));
1493 
1494  //Compute MAC over the record contents
1495  hmacUpdate(encryptionEngine->hmacContext, tlsRecord, sizeof(TlsRecord));
1496  hmacUpdate(encryptionEngine->hmacContext, data, dataLen);
1497  }
1498 
1499  //Append the resulting MAC to the message
1500  hmacFinal(encryptionEngine->hmacContext, mac);
1501 
1502  //Successful processing
1503  return NO_ERROR;
1504 }
1505 
1506 
1507 /**
1508  * @brief Format additional authenticated data (AAD)
1509  * @param[in] context Pointer to the TLS context
1510  * @param[in] encryptionEngine Pointer to the encryption engine
1511  * @param[in] record Pointer to the TLS record
1512  * @param[out] aad Pointer to the buffer where to store the resulting AAD
1513  * @param[out] aadLen Length of the AAD, in bytes
1514  **/
1515 
1516 void tlsFormatAad(TlsContext *context, TlsEncryptionEngine *encryptionEngine,
1517  const void *record, uint8_t *aad, size_t *aadLen)
1518 {
1519 #if (DTLS_SUPPORT == ENABLED)
1520  //DTLS protocol?
1521  if(context->transportProtocol == TLS_TRANSPORT_PROTOCOL_DATAGRAM)
1522  {
1523  const DtlsRecord *dtlsRecord;
1524 
1525  //Point to the DTLS record
1526  dtlsRecord = (DtlsRecord *) record;
1527 
1528  //Additional data to be authenticated
1529  memcpy(aad, (void *) &dtlsRecord->epoch, 2);
1530  memcpy(aad + 2, &dtlsRecord->seqNum, 6);
1531  memcpy(aad + 8, &dtlsRecord->type, 3);
1532  memcpy(aad + 11, (void *) &dtlsRecord->length, 2);
1533 
1534  //Length of the additional data, in bytes
1535  *aadLen = 13;
1536  }
1537  else
1538 #endif
1539  //TLS protocol?
1540  {
1541  //Version of TLS prior to TLS 1.3?
1542  if(context->version <= TLS_VERSION_1_2)
1543  {
1544  //Additional data to be authenticated
1545  memcpy(aad, &encryptionEngine->seqNum, 8);
1546  memcpy(aad + 8, record, 5);
1547 
1548  //Length of the additional data, in bytes
1549  *aadLen = 13;
1550  }
1551  else
1552  {
1553 #if (TLS_VERSION_1_3 == TLS_VERSION_1_3_DRAFT(23) || \
1554  TLS_VERSION_1_3 == TLS_VERSION_1_3_DRAFT(24))
1555  //The additional data input is empty (zero length)
1556  *aadLen = 0;
1557 #else
1558  //The additional data input is the record header (refer to RFC 8446,
1559  //section 5.2)
1560  memcpy(aad, record, 5);
1561 
1562  //Length of the additional data, in bytes
1563  *aadLen = 5;
1564 #endif
1565  }
1566  }
1567 }
1568 
1569 
1570 /**
1571  * @brief Format nonce
1572  * @param[in] context Pointer to the TLS context
1573  * @param[in] encryptionEngine Pointer to the encryption engine
1574  * @param[in] record Pointer to the TLS record
1575  * @param[in] recordIv Explicit part of the nonce
1576  * @param[out] nonce Pointer to the buffer where to store the resulting nonce
1577  * @param[out] nonceLen Length of the nonce, in bytes
1578  **/
1579 
1580 void tlsFormatNonce(TlsContext *context, TlsEncryptionEngine *encryptionEngine,
1581  const void *record, const uint8_t *recordIv, uint8_t *nonce, size_t *nonceLen)
1582 {
1583  size_t i;
1584  size_t n;
1585 
1586  //Check the length of the nonce explicit part
1587  if(encryptionEngine->recordIvLen != 0)
1588  {
1589  //Calculate the total length of the nonce
1590  n = encryptionEngine->fixedIvLen + encryptionEngine->recordIvLen;
1591 
1592  //The salt is the implicit part of the nonce and is not sent in the packet
1593  memcpy(nonce, encryptionEngine->iv, encryptionEngine->fixedIvLen);
1594 
1595  //The explicit part of the nonce is chosen by the sender
1596  memcpy(nonce + encryptionEngine->fixedIvLen, recordIv,
1597  encryptionEngine->recordIvLen);
1598  }
1599  else
1600  {
1601  //Calculate the total length of the nonce
1602  n = encryptionEngine->fixedIvLen;
1603 
1604 #if (DTLS_SUPPORT == ENABLED)
1605  //DTLS protocol?
1606  if(context->transportProtocol == TLS_TRANSPORT_PROTOCOL_DATAGRAM)
1607  {
1608  const DtlsRecord *dtlsRecord;
1609 
1610  //Point to the DTLS record
1611  dtlsRecord = (DtlsRecord *) record;
1612 
1613  //The 64-bit record sequence number is serialized as an 8-byte,
1614  //big-endian value
1615  memcpy(nonce + n - 8, (void *) &dtlsRecord->epoch, 2);
1616  memcpy(nonce + n - 6, &dtlsRecord->seqNum, 6);
1617  }
1618  else
1619 #endif
1620  //TLS protocol?
1621  {
1622  //The 64-bit record sequence number is serialized as an 8-byte,
1623  //big-endian value
1624  memcpy(nonce + n - 8, &encryptionEngine->seqNum, 8);
1625  }
1626 
1627  //The 64-bit record sequence number is padded on the left by zeros
1628  memset(nonce, 0, n - 8);
1629 
1630  //The padded sequence number is XORed with the IV to form the nonce
1631  for(i = 0; i < n; i++)
1632  {
1633  nonce[i] ^= encryptionEngine->iv[i];
1634  }
1635  }
1636 
1637  //Return the total length of the nonce
1638  *nonceLen = n;
1639 }
1640 
1641 
1642 /**
1643  * @brief Increment sequence number
1644  * @param[in] seqNum Sequence number to increment
1645  **/
1646 
1648 {
1649  int_t i;
1650 
1651  //Sequence numbers are stored MSB first
1652  for(i = 7; i >= 0; i--)
1653  {
1654  //Increment the current byte
1655  seqNum->b[i]++;
1656 
1657  //Propagate the carry if necessary
1658  if(seqNum->b[i] != 0)
1659  break;
1660  }
1661 }
1662 
1663 #endif
TLS (Transport Layer Security)
__start_packed struct @83 TlsRecord
TLS record.
size_t fixedIvLen
Length of the fixed part of the IV.
Definition: tls.h:1934
error_t tlsReadRecord(TlsContext *context, uint8_t *data, size_t size, size_t *length, TlsContentType *contentType)
Receive a TLS record.
Definition: tls_record.c:443
error_t tlsWriteRecord(TlsContext *context, const uint8_t *data, size_t length, TlsContentType contentType)
Send a TLS record.
Definition: tls_record.c:338
#define MSB(x)
Definition: os_port.h:56
error_t cbcDecrypt(const CipherAlgo *cipher, void *context, uint8_t *iv, const uint8_t *c, uint8_t *p, size_t length)
CBC decryption.
Definition: cbc.c:104
size_t encKeyLen
Length of the encryption key.
Definition: tls.h:1932
Debugging facilities.
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:1580
uint8_t p
Definition: ndp.h:295
uint8_t message[]
Definition: chap.h:150
void hmacFinal(HmacContext *context, uint8_t *digest)
Finish the HMAC calculation.
Definition: hmac.c:183
void tlsSetRecordType(TlsContext *context, void *record, uint8_t type)
Set TLS record type.
Definition: tls_record.c:1306
void tlsFormatAad(TlsContext *context, TlsEncryptionEngine *encryptionEngine, const void *record, uint8_t *aad, size_t *aadLen)
Format additional authenticated data (AAD)
Definition: tls_record.c:1516
size_t authTagLen
Length of the authentication tag.
Definition: tls.h:1936
size_t recordIvLen
Length of the IV.
Definition: tls.h:1935
#define TLS_VERSION_1_3
Definition: tls.h:90
error_t ccmEncrypt(const CipherAlgo *cipher, void *context, const uint8_t *n, size_t nLen, const uint8_t *a, size_t aLen, const uint8_t *p, uint8_t *c, size_t length, uint8_t *t, size_t tLen)
Authenticated encryption using CCM.
Definition: ccm.c:65
char_t type
error_t chacha20Poly1305Encrypt(const uint8_t *k, size_t kLen, const uint8_t *n, size_t nLen, const uint8_t *a, size_t aLen, const uint8_t *p, uint8_t *c, size_t length, uint8_t *t, size_t tLen)
Authenticated encryption using ChaCha20Poly1305.
#define htons(value)
Definition: cpu_endian.h:390
HmacContext * hmacContext
HMAC context.
Definition: tls.h:1941
#define TRACE_DEBUG_ARRAY(p, a, n)
Definition: debug.h:99
#define TLS_MAX_EMPTY_RECORDS
Definition: tls.h:734
#define LSB(x)
Definition: os_port.h:52
__start_packed struct @84 TlsHandshake
TLS handshake message.
error_t tlsComputeMac(TlsContext *context, TlsEncryptionEngine *encryptionEngine, void *record, const uint8_t *data, size_t dataLen, uint8_t *mac)
Compute message authentication code.
Definition: tls_record.c:1455
__start_packed struct @58 DtlsRecord
DTLS record.
CipherAlgoDecryptStream decryptStream
Definition: crypto.h:1081
error_t gcmEncrypt(GcmContext *context, const uint8_t *iv, size_t ivLen, const uint8_t *a, size_t aLen, const uint8_t *p, uint8_t *c, size_t length, uint8_t *t, size_t tLen)
Authenticated encryption using GCM.
Definition: gcm.c:188
#define TLS_MAX_RECORD_LENGTH
Definition: tls.h:828
__start_packed struct @89 TlsAlert
Alert message.
error_t tlsWriteProtocolData(TlsContext *context, const uint8_t *data, size_t length, TlsContentType contentType)
Write protocol data.
Definition: tls_record.c:58
TLS record protocol.
size_t blockSize
Definition: crypto.h:1078
TlsSequenceNumber seqNum
TLS sequence number.
Definition: tls.h:1945
error_t tlsEncryptRecord(TlsContext *context, TlsEncryptionEngine *encryptionEngine, void *record)
Encrypt an outgoing TLS record.
Definition: tls_record.c:729
TLS helper functions.
error_t tlsProcessRecord(TlsContext *context, TlsRecord *record)
Process incoming TLS record.
Definition: tls_record.c:614
#define ntohs(value)
Definition: cpu_endian.h:396
size_t tlsGetRecordLength(TlsContext *context, void *record)
Get TLS record length.
Definition: tls_record.c:1389
__start_packed struct @88 TlsChangeCipherSpec
ChangeCipherSpec message.
signed int int_t
Definition: compiler_port.h:42
uint8_t encKey[32]
Encryption key.
Definition: tls.h:1931
uint16_t version
Negotiated TLS version.
Definition: tls.h:1928
#define LOAD24BE(p)
Definition: cpu_endian.h:179
const HashAlgo * hashAlgo
Hash algorithm for MAC operations.
Definition: tls.h:1940
Handshake message processing (TLS client and server)
TlsContentType
Content type.
Definition: tls.h:910
ChaCha20Poly1305 AEAD.
#define MIN(a, b)
Definition: os_port.h:60
uint8_t * tlsGetRecordData(TlsContext *context, void *record)
Get TLS record payload.
Definition: tls_record.c:1420
Encryption engine.
Definition: tls.h:1926
void tlsIncSequenceNumber(TlsSequenceNumber *seqNum)
Increment sequence number.
Definition: tls_record.c:1647
uint8_t macKey[48]
MAC key.
Definition: tls.h:1929
error_t tlsDecryptRecord(TlsContext *context, TlsEncryptionEngine *decryptionEngine, void *record)
Decrypt an incoming TLS record.
Definition: tls_record.c:995
uint8_t digest[MAX_HASH_DIGEST_SIZE]
Definition: hmac.h:185
#define TLS_VERSION_1_2
Definition: tls.h:83
#define TLS_VERSION_1_1
Definition: tls.h:82
#define TRACE_INFO(...)
Definition: debug.h:86
error_t gcmDecrypt(GcmContext *context, const uint8_t *iv, size_t ivLen, const uint8_t *a, size_t aLen, const uint8_t *c, uint8_t *p, size_t length, const uint8_t *t, size_t tLen)
Authenticated decryption using GCM.
Definition: gcm.c:335
uint8_t iv[16]
Initialization vector.
Definition: tls.h:1933
Cipher Block Chaining (CBC) mode.
SSL 3.0 helper functions.
Success.
Definition: error.h:42
error_t
Error codes.
Definition: error.h:40
DtlsSequenceNumber seqNum
Definition: dtls_misc.h:165
uint8_t tlsGetRecordType(TlsContext *context, void *record)
Get TLS record type.
Definition: tls_record.c:1332
void * cipherContext
Cipher context.
Definition: tls.h:1938
CipherAlgoEncryptStream encryptStream
Definition: crypto.h:1080
#define TLS_VERSION_1_0
Definition: tls.h:81
uint8_t data[]
Definition: dtls_misc.h:167
#define PRIuSIZE
Definition: compiler_port.h:72
__start_packed struct @61 TlsSequenceNumber
Sequence number.
void tlsSetRecordLength(TlsContext *context, void *record, size_t length)
Set TLS record length.
Definition: tls_record.c:1363
size_t macKeyLen
Length of the MAC key.
Definition: tls.h:1930
Galois/Counter Mode (GCM)
error_t ccmDecrypt(const CipherAlgo *cipher, void *context, const uint8_t *n, size_t nLen, const uint8_t *a, size_t aLen, const uint8_t *c, uint8_t *p, size_t length, const uint8_t *t, size_t tLen)
Authenticated decryption using CCM.
Definition: ccm.c:233
GcmContext * gcmContext
GCM context.
Definition: tls.h:1943
error_t sslComputeMac(TlsEncryptionEngine *encryptionEngine, const TlsRecord *record, const uint8_t *data, size_t dataLen, uint8_t *mac)
error_t tlsReadProtocolData(TlsContext *context, uint8_t **data, size_t *length, TlsContentType *contentType)
Read protocol data.
Definition: tls_record.c:151
error_t chacha20Poly1305Decrypt(const uint8_t *k, size_t kLen, const uint8_t *n, size_t nLen, const uint8_t *a, size_t aLen, const uint8_t *c, uint8_t *p, size_t length, const uint8_t *t, size_t tLen)
Authenticated decryption using ChaCha20Poly1305.
const CipherAlgo * cipherAlgo
Cipher algorithm.
Definition: tls.h:1937
void hmacInit(HmacContext *context, const HashAlgo *hash, const void *key, size_t keyLen)
Initialize HMAC calculation.
Definition: hmac.c:116
void hmacUpdate(HmacContext *context, const void *data, size_t length)
Update the HMAC context with a portion of the message being hashed.
Definition: hmac.c:166
size_t digestSize
Definition: crypto.h:1061
uint8_t length
Definition: dtls_misc.h:140
uint8_t n
error_t cbcEncrypt(const CipherAlgo *cipher, void *context, uint8_t *iv, const uint8_t *p, uint8_t *c, size_t length)
CBC encryption.
Definition: cbc.c:59
#define TlsContext
Definition: tls.h:34
Cipher Block Chaining-Message Authentication Code (CCM)
#define SSL_VERSION_3_0
Definition: tls.h:80
#define TRACE_DEBUG(...)
Definition: debug.h:98
CipherMode cipherMode
Cipher mode of operation.
Definition: tls.h:1939