tls_misc.c
Go to the documentation of this file.
1 /**
2  * @file tls_misc.c
3  * @brief TLS helper functions
4  *
5  * @section License
6  *
7  * SPDX-License-Identifier: GPL-2.0-or-later
8  *
9  * Copyright (C) 2010-2025 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.5.2
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_cipher_suites.h"
37 #include "tls_common.h"
38 #include "tls_ffdhe.h"
39 #include "tls_misc.h"
40 #include "tls13_key_material.h"
41 #include "encoding/oid.h"
42 #include "debug.h"
43 
44 //Check TLS library configuration
45 #if (TLS_SUPPORT == ENABLED)
46 
47 
48 /**
49  * @brief Update TLS state
50  * @param[in] context Pointer to the TLS context
51  * @param[in] newState New state to switch to
52  **/
53 
54 void tlsChangeState(TlsContext *context, TlsState newState)
55 {
56  //Switch to the new state
57  context->state = newState;
58 
59  //Any registered callback?
60  if(context->stateChangeCallback != NULL)
61  {
62  //Invoke user callback function
63  context->stateChangeCallback(context, newState);
64  }
65 }
66 
67 
68 /**
69  * @brief Translate an error code to an alert message
70  * @param[in] context Pointer to the TLS context
71  * @param[in] errorCode Internal error code
72  **/
73 
75 {
76  //Check current state
77  if(context->state != TLS_STATE_INIT &&
78  context->state != TLS_STATE_CLOSED)
79  {
80  //Check status code
81  switch(errorCode)
82  {
83  //The timeout interval has elapsed
84  case ERROR_TIMEOUT:
85  break;
86 
87  //The read/write operation would have blocked
88  case ERROR_WOULD_BLOCK:
89  break;
90 
91  //Failed to allocate memory
93  break;
94 
95  //The read/write operation has failed
96  case ERROR_WRITE_FAILED:
97  case ERROR_READ_FAILED:
99  break;
100 
101  //An inappropriate message was received
104  break;
105 
106  //A record is received with an incorrect MAC
109  break;
110 
111  //Invalid record length
114  break;
115 
116  //Unable to negotiate an acceptable set of security parameters
119  break;
120 
121  //A certificate was corrupt
124  break;
125 
126  //A certificate was of an unsupported type
129  break;
130 
131  //A certificate has expired or is not currently valid
134  break;
135  //Some other issue arose in processing the certificate, rendering it unacceptable
138  break;
139 
140  //A field in the handshake was out of range or inconsistent with other fields
143  break;
144 
145  //The certificate could not be matched with a known, trusted CA
146  case ERROR_UNKNOWN_CA:
148  break;
149 
150  //A message could not be decoded because some field was incorrect
153  break;
154 
155  //A handshake cryptographic operation failed
159  break;
160 
161  //The protocol version the client has attempted to negotiate is not supported
164  break;
165 
166  //Inappropriate fallback detected by the server
169  break;
170 
171  //Handshake message not containing an extension that is mandatory
174  break;
175 
176  //The ServerHello contains an extension not present in the ClientHello
179  break;
180 
181  //A client certificate is desired but none was provided by the client
184  break;
185 
186  //No application protocol supported by the server
189  break;
190 
191  //Internal error
192  default:
194  break;
195  }
196  }
197 }
198 
199 
200 /**
201  * @brief Generate client or server random value
202  * @param[in] context Pointer to the TLS context
203  * @param[out] random Pointer to the random value
204  * @return Error code
205  **/
206 
208 {
209  error_t error;
210 
211  //Verify that the pseudorandom number generator is properly configured
212  if(context->prngAlgo != NULL && context->prngContext != NULL)
213  {
214  //Generate a 32-byte random value using a cryptographically-safe
215  //pseudorandom number generator
216  error = context->prngAlgo->read(context->prngContext, random, 32);
217  }
218  else
219  {
220  //Report an error
221  error = ERROR_NOT_CONFIGURED;
222  }
223 
224 #if (TLS_MAX_VERSION >= TLS_VERSION_1_3 && TLS_MIN_VERSION <= TLS_VERSION_1_3)
225  //Check status code
226  if(!error)
227  {
228  //TLS 1.3 has a downgrade protection mechanism embedded in the server's
229  //random value
230  if(context->entity == TLS_CONNECTION_END_SERVER)
231  {
232  //Check negotiated version
233  if(context->version <= TLS_VERSION_1_1 &&
234  context->versionMax >= TLS_VERSION_1_2)
235  {
236  //If negotiating TLS 1.1 or below, TLS 1.3 servers must, and TLS 1.2
237  //servers should, set the last eight bytes of their random value to
238  //the bytes 44 4F 57 4E 47 52 44 00
240  }
241  else if(context->version == TLS_VERSION_1_2 &&
242  context->versionMax >= TLS_VERSION_1_3 &&
243  (context->transportProtocol == TLS_TRANSPORT_PROTOCOL_STREAM ||
244  context->transportProtocol == TLS_TRANSPORT_PROTOCOL_EAP))
245  {
246  //If negotiating TLS 1.2, TLS 1.3 servers must set the last eight
247  //bytes of their random value to the bytes 44 4F 57 4E 47 52 44 01
249  }
250  else
251  {
252  //No downgrade protection mechanism
253  }
254  }
255  }
256 #endif
257 
258  //Return status code
259  return error;
260 }
261 
262 
263 /**
264  * @brief Generate a random session identifier
265  * @param[in] context Pointer to the TLS context
266  * @param[out] length Desired length of the session ID
267  * @return Error code
268  **/
269 
271 {
272  error_t error;
273 
274  //Verify that the pseudorandom number generator is properly configured
275  if(context->prngAlgo != NULL && context->prngContext != NULL)
276  {
277  //Generate a random value using a cryptographically-safe pseudorandom
278  //number generator
279  error = context->prngAlgo->read(context->prngContext, context->sessionId,
280  length);
281 
282  //Check status code
283  if(!error)
284  {
285  //Save the length of the session identifier
286  context->sessionIdLen = length;
287  }
288  }
289  else
290  {
291  //Report an error
292  error = ERROR_NOT_CONFIGURED;
293  }
294 
295  //Return status code
296  return error;
297 }
298 
299 
300 /**
301  * @brief Set the TLS version to be used
302  * @param[in] context Pointer to the TLS context
303  * @param[in] version TLS version
304  * @return Error code
305  **/
306 
308 {
309  error_t error;
310 
311  //Initialize status code
313 
314  //Check TLS version
315  if(version >= context->versionMin && version <= context->versionMax)
316  {
317  //Save the TLS protocol version to be used
318  context->version = version;
319  //The specified TLS version is acceptable
320  error = NO_ERROR;
321  }
322 
323  //Return status code
324  return error;
325 }
326 
327 
328 /**
329  * @brief Set cipher suite
330  * @param[in] context Pointer to the TLS context
331  * @param[in] identifier Cipher suite identifier
332  * @return Error code
333  **/
334 
336 {
337  error_t error;
338  uint_t i;
339  uint_t n;
341 
342  //Initialize status code
343  error = ERROR_HANDSHAKE_FAILED;
344 
345  //Determine the number of supported cipher suites
347 
348  //Loop through the list of supported cipher suites
349  for(cipherSuite = NULL, i = 0; i < n; i++)
350  {
351  //Compare cipher suite identifiers
353  {
354  //The cipher suite is supported
356  break;
357  }
358  }
359 
360  //Restrict the use of certain cipher suites
361  if(context->numCipherSuites > 0)
362  {
363  //Loop through the list of allowed cipher suites
364  for(i = 0; i < context->numCipherSuites; i++)
365  {
366  //Compare cipher suite identifiers
367  if(context->cipherSuites[i] == identifier)
368  break;
369  }
370 
371  //Check whether the use of the cipher suite is restricted
372  if(i >= context->numCipherSuites)
373  {
374  cipherSuite = NULL;
375  }
376  }
377 
378  //Acceptable cipher suite?
379  if(cipherSuite != NULL)
380  {
381  //Check whether the cipher suite can be negotiated with the negotiated
382  //protocol version
383  if(!tlsIsCipherSuiteAcceptable(cipherSuite, context->version,
384  context->version, context->transportProtocol))
385  {
386  cipherSuite = NULL;
387  }
388  }
389 
390  //Ensure that the selected cipher suite matches all the criteria
391  if(cipherSuite != NULL)
392  {
393  //Save the negotiated cipher suite
394  context->cipherSuite = *cipherSuite;
395  //Set the key exchange method to be used
396  context->keyExchMethod = cipherSuite->keyExchMethod;
397 
398  //PRF with the SHA-256 is used for all cipher suites published prior
399  //than TLS 1.2 when TLS 1.2 is negotiated
400  if(context->cipherSuite.prfHashAlgo == NULL)
401  {
402  context->cipherSuite.prfHashAlgo = SHA256_HASH_ALGO;
403  }
404 
405  //The length of the verify data depends on the TLS version currently used
406  if(context->version <= TLS_VERSION_1_1)
407  {
408  //Verify data is always 12-byte long for TLS 1.0 and 1.1
409  context->cipherSuite.verifyDataLen = 12;
410  }
411  else
412  {
413  //The length of the verify data depends on the cipher suite for TLS 1.2
414  }
415 
416  //The specified cipher suite is acceptable
417  error = NO_ERROR;
418  }
419 
420  //Return status code
421  return error;
422 }
423 
424 
425 /**
426  * @brief Save session ID
427  * @param[in] context Pointer to the TLS context
428  * @param[out] session Pointer to the session state
429  * @return Error code
430  **/
431 
433  TlsSessionState *session)
434 {
435 #if (TLS_MAX_VERSION >= TLS_VERSION_1_0 && TLS_MIN_VERSION <= TLS_VERSION_1_2)
436  //Check TLS version
437  if(context->version < TLS_VERSION_1_0 || context->version > TLS_VERSION_1_2)
438  return ERROR_INVALID_VERSION;
439 
440  //Invalid session identifier?
441  if(context->sessionIdLen == 0)
442  return ERROR_INVALID_TICKET;
443 
444  //Invalid session parameters?
445  if(context->cipherSuite.identifier == 0)
446  return ERROR_INVALID_SESSION;
447 
448  //Save current time
449  session->timestamp = osGetSystemTime();
450 
451  //Save session parameters
452  session->version = context->version;
453  session->cipherSuite = context->cipherSuite.identifier;
454 
455  //Copy session identifier
456  osMemcpy(session->sessionId, context->sessionId, context->sessionIdLen);
457  session->sessionIdLen = context->sessionIdLen;
458 
459  //Save master secret
460  osMemcpy(session->secret, context->masterSecret, TLS_MASTER_SECRET_SIZE);
461 
462 #if (TLS_EXT_MASTER_SECRET_SUPPORT == ENABLED)
463  //Extended master secret computation
464  session->extendedMasterSecret = context->emsExtReceived;
465 #endif
466 
467 #if (TLS_SNI_SUPPORT == ENABLED)
468  //Any ServerName extension received by the server?
469  if(context->entity == TLS_CONNECTION_END_SERVER &&
470  context->serverName != NULL)
471  {
472  size_t n;
473 
474  //Retrieve the length of the server name
475  n = osStrlen(context->serverName);
476 
477  //Allocate a memory block to hold the server name
478  session->serverName = tlsAllocMem(n + 1);
479  //Failed to allocate memory?
480  if(session->serverName == NULL)
481  return ERROR_OUT_OF_MEMORY;
482 
483  //Copy the server name
484  osStrcpy(session->serverName, context->serverName);
485  }
486 #endif
487 
488  //Successful processing
489  return NO_ERROR;
490 #else
491  //Not implemented
492  return ERROR_NOT_IMPLEMENTED;
493 #endif
494 }
495 
496 
497 /**
498  * @brief Save session ticket
499  * @param[in] context Pointer to the TLS context
500  * @param[out] session Pointer to the session state
501  * @return Error code
502  **/
503 
505  TlsSessionState *session)
506 {
507 #if (TLS_MAX_VERSION >= TLS_VERSION_1_0 && TLS_MIN_VERSION <= TLS_VERSION_1_2)
508  //Check TLS version
509  if(context->version < TLS_VERSION_1_0 || context->version > TLS_VERSION_1_2)
510  return ERROR_INVALID_VERSION;
511 
512  //Invalid session ticket?
513  if(context->ticket == NULL || context->ticketLen == 0)
514  return ERROR_INVALID_TICKET;
515 
516  //Invalid session parameters?
517  if(context->cipherSuite.identifier == 0)
518  return ERROR_INVALID_SESSION;
519 
520  //Save session parameters
521  session->version = context->version;
522  session->cipherSuite = context->cipherSuite.identifier;
523 
524  //Allocate a memory block to hold the ticket
525  session->ticket = tlsAllocMem(context->ticketLen);
526  //Failed to allocate memory?
527  if(session->ticket == NULL)
528  return ERROR_OUT_OF_MEMORY;
529 
530  //Copy session ticket
531  osMemcpy(session->ticket, context->ticket, context->ticketLen);
532  session->ticketLen = context->ticketLen;
533 
534  //Save master secret
535  osMemcpy(session->secret, context->masterSecret, TLS_MASTER_SECRET_SIZE);
536 
537 #if (TLS_EXT_MASTER_SECRET_SUPPORT == ENABLED)
538  //Extended master secret computation
539  session->extendedMasterSecret = context->emsExtReceived;
540 #endif
541 
542  //Successful processing
543  return NO_ERROR;
544 #else
545  //Not implemented
546  return ERROR_NOT_IMPLEMENTED;
547 #endif
548 }
549 
550 
551 /**
552  * @brief Restore a TLS session using session ID
553  * @param[in] context Pointer to the TLS context
554  * @param[in] session Pointer to the session state
555  * @return Error code
556  **/
557 
559  const TlsSessionState *session)
560 {
561 #if (TLS_MAX_VERSION >= TLS_VERSION_1_0 && TLS_MIN_VERSION <= TLS_VERSION_1_2)
562  //Check TLS version
563  if(session->version < TLS_VERSION_1_0 || session->version > TLS_VERSION_1_2)
564  return ERROR_INVALID_VERSION;
565 
566  //Invalid session identifier?
567  if(session->sessionIdLen == 0)
568  return ERROR_INVALID_SESSION;
569 
570  //Invalid session parameters?
571  if(session->cipherSuite == 0)
572  return ERROR_INVALID_SESSION;
573 
574  //Restore session parameters
575  context->version = session->version;
576  context->cipherSuite.identifier = session->cipherSuite;
577  context->sessionIdLen = 0;
578 
579  //Copy session identifier
580  osMemcpy(context->sessionId, session->sessionId, session->sessionIdLen);
581  context->sessionIdLen = session->sessionIdLen;
582 
583  //Restore master secret
584  osMemcpy(context->masterSecret, session->secret, TLS_MASTER_SECRET_SIZE);
585 
586 #if (TLS_EXT_MASTER_SECRET_SUPPORT == ENABLED)
587  //Extended master secret computation
588  context->emsExtReceived = session->extendedMasterSecret;
589 #endif
590 
591  //Successful processing
592  return NO_ERROR;
593 #else
594  //Not implemented
595  return ERROR_NOT_IMPLEMENTED;
596 #endif
597 }
598 
599 
600 /**
601  * @brief Restore a TLS session using session ticket
602  * @param[in] context Pointer to the TLS context
603  * @param[in] session Pointer to the session state
604  * @return Error code
605  **/
606 
608  const TlsSessionState *session)
609 {
610 #if (TLS_MAX_VERSION >= TLS_VERSION_1_0 && TLS_MIN_VERSION <= TLS_VERSION_1_2)
611  //Check TLS version
612  if(session->version < TLS_VERSION_1_0 || session->version > TLS_VERSION_1_2)
613  return ERROR_INVALID_VERSION;
614 
615  //Invalid session ticket?
616  if(session->ticket == NULL || session->ticketLen == 0)
617  return ERROR_INVALID_TICKET;
618 
619  //Invalid session parameters?
620  if(session->cipherSuite == 0)
621  return ERROR_INVALID_SESSION;
622 
623  //Restore session parameters
624  context->version = session->version;
625  context->cipherSuite.identifier = session->cipherSuite;
626  context->sessionIdLen = 0;
627 
628  //Release existing session ticket, if any
629  if(context->ticket != NULL)
630  {
631  osMemset(context->ticket, 0, context->ticketLen);
632  tlsFreeMem(context->ticket);
633  context->ticket = NULL;
634  context->ticketLen = 0;
635  }
636 
637  //Allocate a memory block to hold the ticket
638  context->ticket = tlsAllocMem(session->ticketLen);
639  //Failed to allocate memory?
640  if(context->ticket == NULL)
641  return ERROR_OUT_OF_MEMORY;
642 
643  //Copy session ticket
644  osMemcpy(context->ticket, session->ticket, session->ticketLen);
645  context->ticketLen = session->ticketLen;
646 
647  //Restore master secret
648  osMemcpy(context->masterSecret, session->secret, TLS_MASTER_SECRET_SIZE);
649 
650 #if (TLS_EXT_MASTER_SECRET_SUPPORT == ENABLED)
651  //Extended master secret computation
652  context->emsExtReceived = session->extendedMasterSecret;
653 #endif
654 
655  //Successful processing
656  return NO_ERROR;
657 #else
658  //Not implemented
659  return ERROR_NOT_IMPLEMENTED;
660 #endif
661 }
662 
663 
664 /**
665  * @brief Initialize encryption engine
666  * @param[in] context Pointer to the TLS context
667  * @param[in] encryptionEngine Pointer to the encryption/decryption engine to
668  * be initialized
669  * @param[in] entity Specifies whether client or server write keys shall be used
670  * @param[in] secret Pointer to the secret value
671  * @return Error code
672  **/
673 
675  TlsEncryptionEngine *encryptionEngine, TlsConnectionEnd entity,
676  const uint8_t *secret)
677 {
678  error_t error;
679  const CipherAlgo *cipherAlgo;
681 
682  //Point to the negotiated cipher suite
683  cipherSuite = &context->cipherSuite;
684  //Point to the cipher algorithm
685  cipherAlgo = cipherSuite->cipherAlgo;
686 
687  //Save the negotiated TLS version
688  encryptionEngine->version = context->version;
689 
690  //The sequence number is set to zero at the beginning of a connection
691  //and whenever the key is changed
692  osMemset(&encryptionEngine->seqNum, 0, sizeof(TlsSequenceNumber));
693 
694 #if (DTLS_SUPPORT == ENABLED)
695  //The epoch number is initially zero and is incremented each time a
696  //ChangeCipherSpec message is sent
697  encryptionEngine->epoch++;
698 
699  //Sequence numbers are maintained separately for each epoch, with each
700  //sequence number initially being 0 for each epoch
701  osMemset(&encryptionEngine->dtlsSeqNum, 0, sizeof(DtlsSequenceNumber));
702 #endif
703 
704 #if (TLS_RECORD_SIZE_LIMIT_SUPPORT == ENABLED)
705  //The value of RecordSizeLimit is used to limit the size of records
706  //that are created when encoding application data and the protected
707  //handshake message into records (refer to RFC 8449, section 4)
708  if(entity == context->entity)
709  {
710  encryptionEngine->recordSizeLimit = context->recordSizeLimit;
711  }
712  else
713  {
714  encryptionEngine->recordSizeLimit = MIN(context->rxBufferMaxLen,
716  }
717 #endif
718 
719 #if (TLS_ENCRYPT_THEN_MAC_SUPPORT == ENABLED)
720  //If an upgrade from MAC-then-encrypt to encrypt-then-MAC is negotiated,
721  //then the change will take place in the first message that follows the
722  //ChangeCipherSpec message (refer to RFC 7366, section 3.1)
723  encryptionEngine->encryptThenMac = context->etmExtReceived;
724 #endif
725 
726  //Set appropriate length for MAC key, encryption key, authentication
727  //tag and IV
728  encryptionEngine->macKeyLen = cipherSuite->macKeyLen;
729  encryptionEngine->encKeyLen = cipherSuite->encKeyLen;
730  encryptionEngine->fixedIvLen = cipherSuite->fixedIvLen;
731  encryptionEngine->recordIvLen = cipherSuite->recordIvLen;
732  encryptionEngine->authTagLen = cipherSuite->authTagLen;
733 
734  //Set cipher and hash algorithms
735  encryptionEngine->cipherAlgo = cipherSuite->cipherAlgo;
736  encryptionEngine->cipherMode = cipherSuite->cipherMode;
737  encryptionEngine->hashAlgo = cipherSuite->hashAlgo;
738 
739  //Initialize cipher context
740  encryptionEngine->cipherContext = NULL;
741 
742 #if (TLS_MAX_VERSION >= TLS_VERSION_1_0 && TLS_MIN_VERSION <= TLS_VERSION_1_2)
743  //Initialize HMAC context
744  encryptionEngine->hmacContext = &context->hmacContext;
745 #endif
746 
747 #if (TLS_GCM_CIPHER_SUPPORT == ENABLED)
748  //Initialize GCM context
749  encryptionEngine->gcmContext = NULL;
750 #endif
751 
752 #if (TLS_MAX_VERSION >= TLS_VERSION_1_0 && TLS_MIN_VERSION <= TLS_VERSION_1_2)
753  //TLS 1.0, TLS 1.1 or TLS 1.2 currently selected?
754  if(context->version <= TLS_VERSION_1_2)
755  {
756  const uint8_t *p;
757 
758  //Check whether client or server write keys shall be used
759  if(entity == TLS_CONNECTION_END_CLIENT)
760  {
761  //Point to the key material
762  p = context->keyBlock;
763  //Save MAC key
764  osMemcpy(encryptionEngine->macKey, p, cipherSuite->macKeyLen);
765 
766  //Advance current position in the key block
767  p += 2 * cipherSuite->macKeyLen;
768  //Save encryption key
769  osMemcpy(encryptionEngine->encKey, p, cipherSuite->encKeyLen);
770 
771  //Advance current position in the key block
772  p += 2 * cipherSuite->encKeyLen;
773  //Save initialization vector
774  osMemcpy(encryptionEngine->iv, p, cipherSuite->fixedIvLen);
775  }
776  else
777  {
778  //Point to the key material
779  p = context->keyBlock + cipherSuite->macKeyLen;
780  //Save MAC key
781  osMemcpy(encryptionEngine->macKey, p, cipherSuite->macKeyLen);
782 
783  //Advance current position in the key block
784  p += cipherSuite->macKeyLen + cipherSuite->encKeyLen;
785  //Save encryption key
786  osMemcpy(encryptionEngine->encKey, p, cipherSuite->encKeyLen);
787 
788  //Advance current position in the key block
789  p += cipherSuite->encKeyLen + cipherSuite->fixedIvLen;
790  //Save initialization vector
791  osMemcpy(encryptionEngine->iv, p, cipherSuite->fixedIvLen);
792  }
793 
794  //Successful processing
795  error = NO_ERROR;
796  }
797  else
798 #endif
799 #if (TLS_MAX_VERSION >= TLS_VERSION_1_3 && TLS_MIN_VERSION <= TLS_VERSION_1_3)
800  //TLS 1.3 currently selected?
801  if(context->version == TLS_VERSION_1_3)
802  {
803  const HashAlgo *hashAlgo;
804 
805  //The hash function used by HKDF is the cipher suite hash algorithm
806  hashAlgo = cipherSuite->prfHashAlgo;
807 
808  //Make sure the hash algorithm is valid
809  if(hashAlgo != NULL)
810  {
811  //Calculate the write key
812  error = tls13HkdfExpandLabel(context->transportProtocol, hashAlgo,
813  secret, hashAlgo->digestSize, "key", NULL, 0,
814  encryptionEngine->encKey, cipherSuite->encKeyLen);
815 
816  //Debug message
817  TRACE_DEBUG("Write Key:\r\n");
818  TRACE_DEBUG_ARRAY(" ", encryptionEngine->encKey, cipherSuite->encKeyLen);
819 
820  //Check status code
821  if(!error)
822  {
823  //Calculate the write IV
824  error = tls13HkdfExpandLabel(context->transportProtocol, hashAlgo,
825  secret, hashAlgo->digestSize, "iv", NULL, 0,
826  encryptionEngine->iv, cipherSuite->fixedIvLen);
827  }
828 
829  //Debug message
830  TRACE_DEBUG("Write IV:\r\n");
831  TRACE_DEBUG_ARRAY(" ", encryptionEngine->iv, cipherSuite->fixedIvLen);
832  }
833  else
834  {
835  //Invalid HKDF hash algorithm
836  error = ERROR_FAILURE;
837  }
838  }
839  else
840 #endif
841  //Invalid TLS version?
842  {
843  //Report an error
844  error = ERROR_INVALID_VERSION;
845  }
846 
847  //Check status code
848  if(!error)
849  {
850  //Check cipher mode of operation
851  if(encryptionEngine->cipherMode == CIPHER_MODE_STREAM ||
852  encryptionEngine->cipherMode == CIPHER_MODE_CBC ||
853  encryptionEngine->cipherMode == CIPHER_MODE_CCM ||
854  encryptionEngine->cipherMode == CIPHER_MODE_GCM)
855  {
856  //Allocate encryption context
857  encryptionEngine->cipherContext = tlsAllocMem(cipherAlgo->contextSize);
858 
859  //Successful memory allocation?
860  if(encryptionEngine->cipherContext != NULL)
861  {
862  //Configure the encryption engine with the write key
863  error = cipherAlgo->init(encryptionEngine->cipherContext,
864  encryptionEngine->encKey, cipherSuite->encKeyLen);
865  }
866  else
867  {
868  //Failed to allocate memory
869  error = ERROR_OUT_OF_MEMORY;
870  }
871  }
872  else if(encryptionEngine->cipherMode == CIPHER_MODE_NULL ||
873  encryptionEngine->cipherMode == CIPHER_MODE_CHACHA20_POLY1305)
874  {
875  //No need to allocate an encryption context
876  error = NO_ERROR;
877  }
878  else
879  {
880  //Unsupported mode of operation
881  error = ERROR_FAILURE;
882  }
883  }
884 
885 #if (TLS_GCM_CIPHER_SUPPORT == ENABLED)
886  //Check status code
887  if(!error)
888  {
889  //GCM cipher mode?
890  if(encryptionEngine->cipherMode == CIPHER_MODE_GCM)
891  {
892  //Allocate a memory buffer to hold the GCM context
893  encryptionEngine->gcmContext = tlsAllocMem(sizeof(GcmContext));
894 
895  //Successful memory allocation?
896  if(encryptionEngine->gcmContext != NULL)
897  {
898  //Initialize GCM context
899  error = gcmInit(encryptionEngine->gcmContext, cipherAlgo,
900  encryptionEngine->cipherContext);
901  }
902  else
903  {
904  //Failed to allocate memory
905  error = ERROR_OUT_OF_MEMORY;
906  }
907  }
908  }
909 #endif
910 
911  //Return status code
912  return error;
913 }
914 
915 
916 /**
917  * @brief Release encryption engine
918  * @param[in] encryptionEngine Pointer to the encryption/decryption engine
919  **/
920 
922 {
923  //Valid cipher context?
924  if(encryptionEngine->cipherContext != NULL)
925  {
926  //Erase cipher context
927  encryptionEngine->cipherAlgo->deinit(encryptionEngine->cipherContext);
928 
929  //Release memory
930  tlsFreeMem(encryptionEngine->cipherContext);
931  encryptionEngine->cipherContext = NULL;
932  }
933 
934 #if (TLS_GCM_CIPHER_SUPPORT == ENABLED)
935  //Valid GCM context?
936  if(encryptionEngine->gcmContext != NULL)
937  {
938  //Erase GCM context
939  osMemset(encryptionEngine->gcmContext, 0, sizeof(GcmContext));
940 
941  //Release memory
942  tlsFreeMem(encryptionEngine->gcmContext);
943  encryptionEngine->gcmContext = NULL;
944  }
945 #endif
946 
947  //Reset encryption parameters
948  encryptionEngine->cipherAlgo = NULL;
949  encryptionEngine->cipherMode = CIPHER_MODE_NULL;
950  encryptionEngine->hashAlgo = NULL;
951 }
952 
953 
954 /**
955  * @brief Encode a multiple precision integer to an opaque vector
956  * @param[in] a Pointer to a multiple precision integer
957  * @param[out] data Buffer where to store the opaque vector
958  * @param[out] length Total number of bytes that have been written
959  * @return Error code
960  **/
961 
962 error_t tlsWriteMpi(const Mpi *a, uint8_t *data, size_t *length)
963 {
964  error_t error;
965  size_t n;
966 
967  //Retrieve the actual size of the integer
968  n = mpiGetByteLength(a);
969 
970  //The data is preceded by a 2-byte length field
971  STORE16BE(n, data);
972 
973  //Convert the integer to an octet string
974  error = mpiExport(a, data + 2, n, MPI_FORMAT_BIG_ENDIAN);
975  //Conversion failed?
976  if(error)
977  return error;
978 
979  //Return the total number of bytes that have been written
980  *length = n + 2;
981 
982  //Successful processing
983  return NO_ERROR;
984 }
985 
986 
987 /**
988  * @brief Read a multiple precision integer from an opaque vector
989  * @param[out] a Resulting multiple precision integer
990  * @param[in] data Buffer where to read the opaque vector
991  * @param[in] size Total number of bytes available in the buffer
992  * @param[out] length Total number of bytes that have been read
993  * @return Error code
994  **/
995 
996 error_t tlsReadMpi(Mpi *a, const uint8_t *data, size_t size, size_t *length)
997 {
998  error_t error;
999  size_t n;
1000 
1001  //Buffer underrun?
1002  if(size < 2)
1003  return ERROR_DECODING_FAILED;
1004 
1005  //Decode the length field
1006  n = LOAD16BE(data);
1007 
1008  //Invalid length?
1009  if(n < 1)
1010  return ERROR_DECODING_FAILED;
1011 
1012  //Buffer underrun?
1013  if(size < (n + 2))
1014  return ERROR_DECODING_FAILED;
1015 
1016  //Convert the octet string to a multiple precision integer
1017  error = mpiImport(a, data + 2, n, MPI_FORMAT_BIG_ENDIAN);
1018  //Any error to report?
1019  if(error)
1020  return error;
1021 
1022  //Return the total number of bytes that have been read
1023  *length = n + 2;
1024 
1025  //Successful processing
1026  return NO_ERROR;
1027 }
1028 
1029 
1030 /**
1031  * @brief Encode an EC point to an opaque vector
1032  * @param[in] publicKey EC public key to be encoded
1033  * @param[out] data Buffer where to store the opaque vector
1034  * @param[out] length Total number of bytes that have been written
1035  * @return Error code
1036  **/
1037 
1038 error_t tlsWriteEcPoint(const EcPublicKey *publicKey, uint8_t *data,
1039  size_t *length)
1040 {
1041 #if (TLS_ECDH_ANON_KE_SUPPORT == ENABLED || TLS_ECDHE_RSA_KE_SUPPORT == ENABLED || \
1042  TLS_ECDHE_ECDSA_KE_SUPPORT == ENABLED || TLS_ECDHE_PSK_KE_SUPPORT == ENABLED)
1043  error_t error;
1044 
1045  //Convert the EC point to an octet string
1046  error = ecExportPublicKey(publicKey, data + 1, length,
1048  //Any error to report?
1049  if(error)
1050  return error;
1051 
1052  //Set the length of the opaque vector
1053  data[0] = (uint8_t) (*length);
1054 
1055  //Return the total number of bytes that have been written
1056  *length += 1;
1057 
1058  //Successful processing
1059  return NO_ERROR;
1060 #else
1061  //Not implemented
1062  return ERROR_NOT_IMPLEMENTED;
1063 #endif
1064 }
1065 
1066 
1067 /**
1068  * @brief Read an EC point from an opaque vector
1069  * @param[out] publicKey Resulting EC public key
1070  * @param[in] curve Elliptic curve parameters
1071  * @param[in] data Buffer where to read the opaque vector
1072  * @param[in] size Total number of bytes available in the buffer
1073  * @param[out] length Total number of bytes that have been read
1074  * @return Error code
1075  **/
1076 
1077 error_t tlsReadEcPoint(EcPublicKey *publicKey, const EcCurve *curve,
1078  const uint8_t *data, size_t size, size_t *length)
1079 {
1080 #if (TLS_ECDH_ANON_KE_SUPPORT == ENABLED || TLS_ECDHE_RSA_KE_SUPPORT == ENABLED || \
1081  TLS_ECDHE_ECDSA_KE_SUPPORT == ENABLED || TLS_ECDHE_PSK_KE_SUPPORT == ENABLED)
1082  error_t error;
1083  size_t n;
1084 
1085  //Buffer underrun?
1086  if(size < 1)
1087  return ERROR_DECODING_FAILED;
1088 
1089  //The EC point representation is preceded by a length field
1090  n = data[0];
1091 
1092  //Invalid EC point representation?
1093  if(n == 0)
1094  return ERROR_DECODING_FAILED;
1095 
1096  //Buffer underrun?
1097  if(size < (n + 1))
1098  return ERROR_DECODING_FAILED;
1099 
1100  //Convert the octet string to an EC point
1101  error = ecImportPublicKey(publicKey, curve, data + 1, n,
1103  //Any error to report?
1104  if(error)
1105  return error;
1106 
1107  //Return the total number of bytes that have been read
1108  *length = n + 1;
1109 
1110  //Successful processing
1111  return NO_ERROR;
1112 #else
1113  //Not implemented
1114  return ERROR_NOT_IMPLEMENTED;
1115 #endif
1116 }
1117 
1118 
1119 /**
1120  * @brief Convert TLS version to string representation
1121  * @param[in] version Version number
1122  * @return String representation
1123  **/
1124 
1126 {
1127  const char_t *s;
1128 
1129  //TLS versions
1130  static const char_t *const label[] =
1131  {
1132  "SSL 3.0",
1133  "TLS 1.0",
1134  "TLS 1.1",
1135  "TLS 1.2",
1136  "TLS 1.3",
1137  "DTLS 1.0",
1138  "DTLS 1.2",
1139  "DTLS 1.3",
1140  "Unknown"
1141  };
1142 
1143  //Check current version
1144  switch(version)
1145  {
1146  case SSL_VERSION_3_0:
1147  s = label[0];
1148  break;
1149  case TLS_VERSION_1_0:
1150  s = label[1];
1151  break;
1152  case TLS_VERSION_1_1:
1153  s = label[2];
1154  break;
1155  case TLS_VERSION_1_2:
1156  s = label[3];
1157  break;
1158  case TLS_VERSION_1_3:
1159  s = label[4];
1160  break;
1161  case DTLS_VERSION_1_0:
1162  s = label[5];
1163  break;
1164  case DTLS_VERSION_1_2:
1165  s = label[6];
1166  break;
1167  case DTLS_VERSION_1_3:
1168  s = label[7];
1169  break;
1170  default:
1171  s = label[8];
1172  break;
1173  }
1174 
1175  //Return the string representation
1176  return s;
1177 }
1178 
1179 
1180 /**
1181  * @brief Get the hash algorithm that matches the specified identifier
1182  * @param[in] hashAlgoId Hash algorithm identifier
1183  * @return Pointer to the hash algorithm
1184  **/
1185 
1187 {
1188  const HashAlgo *hashAlgo;
1189 
1190  //Check hash algorithm identifier
1191  switch(hashAlgoId)
1192  {
1193 #if (TLS_MD5_SUPPORT == ENABLED)
1194  //MD5 hash identifier?
1195  case TLS_HASH_ALGO_MD5:
1196  hashAlgo = MD5_HASH_ALGO;
1197  break;
1198 #endif
1199 #if (TLS_SHA1_SUPPORT == ENABLED)
1200  //SHA-1 hash identifier?
1201  case TLS_HASH_ALGO_SHA1:
1202  hashAlgo = SHA1_HASH_ALGO;
1203  break;
1204 #endif
1205 #if (TLS_SHA224_SUPPORT == ENABLED)
1206  //SHA-224 hash identifier?
1207  case TLS_HASH_ALGO_SHA224:
1208  hashAlgo = SHA224_HASH_ALGO;
1209  break;
1210 #endif
1211 #if (TLS_SHA256_SUPPORT == ENABLED)
1212  //SHA-256 hash identifier?
1213  case TLS_HASH_ALGO_SHA256:
1214  hashAlgo = SHA256_HASH_ALGO;
1215  break;
1216 #endif
1217 #if (TLS_SHA384_SUPPORT == ENABLED)
1218  //SHA-384 hash identifier?
1219  case TLS_HASH_ALGO_SHA384:
1220  hashAlgo = SHA384_HASH_ALGO;
1221  break;
1222 #endif
1223 #if (TLS_SHA512_SUPPORT == ENABLED)
1224  //SHA-512 hash identifier?
1225  case TLS_HASH_ALGO_SHA512:
1226  hashAlgo = SHA512_HASH_ALGO;
1227  break;
1228 #endif
1229 #if (TLS_SM3_SUPPORT == ENABLED)
1230  //SM3 hash identifier?
1231  case TLS_HASH_ALGO_SM3:
1232  hashAlgo = SM3_HASH_ALGO;
1233  break;
1234 #endif
1235  //Unknown hash identifier?
1236  default:
1237  hashAlgo = NULL;
1238  break;
1239  }
1240 
1241  //Return a pointer to the corresponding hash algorithm
1242  return hashAlgo;
1243 }
1244 
1245 
1246 /**
1247  * @brief Get the EC domain parameters that match the specified named curve
1248  * @param[in] context Pointer to the TLS context
1249  * @param[in] namedCurve Elliptic curve identifier
1250  * @return Elliptic curve parameters
1251  **/
1252 
1253 const EcCurve *tlsGetCurve(TlsContext *context, uint16_t namedCurve)
1254 {
1255  uint_t i;
1256  const EcCurve *curve;
1257 
1258  //Default elliptic curve parameters
1259  curve = NULL;
1260 
1261 #if (TLS_ECDH_SUPPORT == ENABLED)
1262  //Check named curve
1263  switch(namedCurve)
1264  {
1265 #if (TLS_SECP160K1_SUPPORT == ENABLED)
1266  //secp160k1 elliptic curve?
1267  case TLS_GROUP_SECP160K1:
1268  curve = ecGetCurve(SECP160K1_OID, sizeof(SECP160K1_OID));
1269  break;
1270 #endif
1271 #if (TLS_SECP160R1_SUPPORT == ENABLED)
1272  //secp160r1 elliptic curve?
1273  case TLS_GROUP_SECP160R1:
1274  curve = ecGetCurve(SECP160R1_OID, sizeof(SECP160R1_OID));
1275  break;
1276 #endif
1277 #if (TLS_SECP160R2_SUPPORT == ENABLED)
1278  //secp160r2 elliptic curve?
1279  case TLS_GROUP_SECP160R2:
1280  curve = ecGetCurve(SECP160R2_OID, sizeof(SECP160R2_OID));
1281  break;
1282 #endif
1283 #if (TLS_SECP192K1_SUPPORT == ENABLED)
1284  //secp192k1 elliptic curve?
1285  case TLS_GROUP_SECP192K1:
1286  curve = ecGetCurve(SECP192K1_OID, sizeof(SECP192K1_OID));
1287  break;
1288 #endif
1289 #if (TLS_SECP192R1_SUPPORT == ENABLED)
1290  //secp192r1 elliptic curve?
1291  case TLS_GROUP_SECP192R1:
1292  curve = ecGetCurve(SECP192R1_OID, sizeof(SECP192R1_OID));
1293  break;
1294 #endif
1295 #if (TLS_SECP224K1_SUPPORT == ENABLED)
1296  //secp224k1 elliptic curve?
1297  case TLS_GROUP_SECP224K1:
1298  curve = ecGetCurve(SECP224K1_OID, sizeof(SECP224K1_OID));
1299  break;
1300 #endif
1301 #if (TLS_SECP224R1_SUPPORT == ENABLED)
1302  //secp224r1 elliptic curve?
1303  case TLS_GROUP_SECP224R1:
1304  curve = ecGetCurve(SECP224R1_OID, sizeof(SECP224R1_OID));
1305  break;
1306 #endif
1307 #if (TLS_SECP256K1_SUPPORT == ENABLED)
1308  //secp256k1 elliptic curve?
1309  case TLS_GROUP_SECP256K1:
1310  curve = ecGetCurve(SECP256K1_OID, sizeof(SECP256K1_OID));
1311  break;
1312 #endif
1313 #if (TLS_SECP256R1_SUPPORT == ENABLED)
1314  //secp256r1 elliptic curve?
1315  case TLS_GROUP_SECP256R1:
1316  curve = ecGetCurve(SECP256R1_OID, sizeof(SECP256R1_OID));
1317  break;
1318 #endif
1319 #if (TLS_SECP384R1_SUPPORT == ENABLED)
1320  //secp384r1 elliptic curve?
1321  case TLS_GROUP_SECP384R1:
1322  curve = ecGetCurve(SECP384R1_OID, sizeof(SECP384R1_OID));
1323  break;
1324 #endif
1325 #if (TLS_SECP521R1_SUPPORT == ENABLED)
1326  //secp521r1 elliptic curve?
1327  case TLS_GROUP_SECP521R1:
1328  curve = ecGetCurve(SECP521R1_OID, sizeof(SECP521R1_OID));
1329  break;
1330 #endif
1331 #if (TLS_BRAINPOOLP256R1_SUPPORT == ENABLED)
1332  //brainpoolP256r1 elliptic curve?
1336  break;
1337 #endif
1338 #if (TLS_BRAINPOOLP384R1_SUPPORT == ENABLED)
1339  //brainpoolP384r1 elliptic curve?
1343  break;
1344 #endif
1345 #if (TLS_BRAINPOOLP512R1_SUPPORT == ENABLED)
1346  //brainpoolP512r1 elliptic curve?
1350  break;
1351 #endif
1352 #if (TLS_SM2_SUPPORT == ENABLED)
1353  //SM2 elliptic curve?
1354  case TLS_GROUP_CURVE_SM2:
1355  curve = ecGetCurve(SM2_OID, sizeof(SM2_OID));
1356  break;
1357 #endif
1358 #if (TLS_X25519_SUPPORT == ENABLED)
1359  //Curve25519 elliptic curve?
1360  case TLS_GROUP_X25519:
1361  curve = ecGetCurve(X25519_OID, sizeof(X25519_OID));
1362  break;
1363 #endif
1364 #if (TLS_X448_SUPPORT == ENABLED)
1365  //Curve448 elliptic curve?
1366  case TLS_GROUP_X448:
1367  curve = ecGetCurve(X448_OID, sizeof(X448_OID));
1368  break;
1369 #endif
1370  //Unknown elliptic curve identifier?
1371  default:
1372  curve = NULL;
1373  break;
1374  }
1375 #endif
1376 
1377  //Restrict the use of certain elliptic curves
1378  if(context->numSupportedGroups > 0)
1379  {
1380  //Loop through the list of allowed named groups
1381  for(i = 0; i < context->numSupportedGroups; i++)
1382  {
1383  //Compare named groups
1384  if(context->supportedGroups[i] == namedCurve)
1385  break;
1386  }
1387 
1388  //Check whether the use of the elliptic curve is restricted
1389  if(i >= context->numSupportedGroups)
1390  {
1391  curve = NULL;
1392  }
1393  }
1394 
1395  //Return the elliptic curve parameters, if any
1396  return curve;
1397 }
1398 
1399 
1400 /**
1401  * @brief Get the named curve that matches the specified OID
1402  * @param[in] oid Object identifier
1403  * @param[in] length OID length
1404  * @return Named curve
1405  **/
1406 
1407 TlsNamedGroup tlsGetNamedCurve(const uint8_t *oid, size_t length)
1408 {
1409  TlsNamedGroup namedCurve;
1410 
1411  //Default named curve
1412  namedCurve = TLS_GROUP_NONE;
1413 
1414 #if (TLS_ECDSA_SIGN_SUPPORT == ENABLED)
1415  //Invalid parameters?
1416  if(oid == NULL || length == 0)
1417  {
1418  namedCurve = TLS_GROUP_NONE;
1419  }
1420 #if (TLS_SECP160K1_SUPPORT == ENABLED)
1421  //secp160k1 elliptic curve?
1422  else if(OID_COMP(oid, length, SECP160K1_OID) == 0)
1423  {
1424  namedCurve = TLS_GROUP_SECP160K1;
1425  }
1426 #endif
1427 #if (TLS_SECP160R1_SUPPORT == ENABLED)
1428  //secp160r1 elliptic curve?
1429  else if(OID_COMP(oid, length, SECP160R1_OID) == 0)
1430  {
1431  namedCurve = TLS_GROUP_SECP160R1;
1432  }
1433 #endif
1434 #if (TLS_SECP160R2_SUPPORT == ENABLED)
1435  //secp160r2 elliptic curve?
1436  else if(OID_COMP(oid, length, SECP160R2_OID) == 0)
1437  {
1438  namedCurve = TLS_GROUP_SECP160R2;
1439  }
1440 #endif
1441 #if (TLS_SECP192K1_SUPPORT == ENABLED)
1442  //secp192k1 elliptic curve?
1443  else if(OID_COMP(oid, length, SECP192K1_OID) == 0)
1444  {
1445  namedCurve = TLS_GROUP_SECP192K1;
1446  }
1447 #endif
1448 #if (TLS_SECP192R1_SUPPORT == ENABLED)
1449  //secp192r1 elliptic curve?
1450  else if(OID_COMP(oid, length, SECP192R1_OID) == 0)
1451  {
1452  namedCurve = TLS_GROUP_SECP192R1;
1453  }
1454 #endif
1455 #if (TLS_SECP224K1_SUPPORT == ENABLED)
1456  //secp224k1 elliptic curve?
1457  else if(OID_COMP(oid, length, SECP224K1_OID) == 0)
1458  {
1459  namedCurve = TLS_GROUP_SECP224K1;
1460  }
1461 #endif
1462 #if (TLS_SECP224R1_SUPPORT == ENABLED)
1463  //secp224r1 elliptic curve?
1464  else if(OID_COMP(oid, length, SECP224R1_OID) == 0)
1465  {
1466  namedCurve = TLS_GROUP_SECP224R1;
1467  }
1468 #endif
1469 #if (TLS_SECP256K1_SUPPORT == ENABLED)
1470  //secp256k1 elliptic curve?
1471  else if(OID_COMP(oid, length, SECP256K1_OID) == 0)
1472  {
1473  namedCurve = TLS_GROUP_SECP256K1;
1474  }
1475 #endif
1476 #if (TLS_SECP256R1_SUPPORT == ENABLED)
1477  //secp256r1 elliptic curve?
1478  else if(OID_COMP(oid, length, SECP256R1_OID) == 0)
1479  {
1480  namedCurve = TLS_GROUP_SECP256R1;
1481  }
1482 #endif
1483 #if (TLS_SECP384R1_SUPPORT == ENABLED)
1484  //secp384r1 elliptic curve?
1485  else if(OID_COMP(oid, length, SECP384R1_OID) == 0)
1486  {
1487  namedCurve = TLS_GROUP_SECP384R1;
1488  }
1489 #endif
1490 #if (TLS_SECP521R1_SUPPORT == ENABLED)
1491  //secp521r1 elliptic curve?
1492  else if(OID_COMP(oid, length, SECP521R1_OID) == 0)
1493  {
1494  namedCurve = TLS_GROUP_SECP521R1;
1495  }
1496 #endif
1497 #if (TLS_BRAINPOOLP256R1_SUPPORT == ENABLED)
1498  //brainpoolP256r1 elliptic curve?
1499  else if(OID_COMP(oid, length, BRAINPOOLP256R1_OID) == 0)
1500  {
1501  namedCurve = TLS_GROUP_BRAINPOOLP256R1;
1502  }
1503 #endif
1504 #if (TLS_BRAINPOOLP384R1_SUPPORT == ENABLED)
1505  //brainpoolP384r1 elliptic curve?
1506  else if(OID_COMP(oid, length, BRAINPOOLP384R1_OID) == 0)
1507  {
1508  namedCurve = TLS_GROUP_BRAINPOOLP384R1;
1509  }
1510 #endif
1511 #if (TLS_BRAINPOOLP512R1_SUPPORT == ENABLED)
1512  //brainpoolP512r1 elliptic curve?
1513  else if(OID_COMP(oid, length, BRAINPOOLP512R1_OID) == 0)
1514  {
1515  namedCurve = TLS_GROUP_BRAINPOOLP512R1;
1516  }
1517 #endif
1518 #if (TLS_SM2_SUPPORT == ENABLED)
1519  //SM2 elliptic curve?
1520  else if(OID_COMP(oid, length, SM2_OID) == 0)
1521  {
1522  namedCurve = TLS_GROUP_CURVE_SM2;
1523  }
1524 #endif
1525  //Unknown identifier?
1526  else
1527  {
1528  namedCurve = TLS_GROUP_NONE;
1529  }
1530 #endif
1531 
1532  //Return the corresponding named curve
1533  return namedCurve;
1534 }
1535 
1536 
1537 /**
1538  * @brief Compute overhead caused by encryption
1539  * @param[in] encryptionEngine Pointer to the encryption engine
1540  * @param[in] payloadLen Length of the payload, in bytes
1541  * @return Overhead, in bytes, caused by encryption
1542  **/
1543 
1545  size_t payloadLen)
1546 {
1547  size_t n;
1548 
1549  //Initialize variable
1550  n = 0;
1551 
1552  //Message authentication?
1553  if(encryptionEngine->hashAlgo != NULL)
1554  n += encryptionEngine->hashAlgo->digestSize;
1555 
1556  //Check cipher mode
1557  if(encryptionEngine->cipherMode == CIPHER_MODE_CBC)
1558  {
1559  //TLS 1.1 and 1.2 use an explicit IV
1560  if(encryptionEngine->version >= TLS_VERSION_1_1)
1561  {
1562  n += encryptionEngine->recordIvLen;
1563  }
1564 
1565  //Padding is added to force the length of the plaintext to be an integral
1566  //multiple of the cipher's block length
1567  n += encryptionEngine->cipherAlgo->blockSize -
1568  ((payloadLen + n) % encryptionEngine->cipherAlgo->blockSize);
1569  }
1570  else if(encryptionEngine->cipherMode == CIPHER_MODE_CCM ||
1571  encryptionEngine->cipherMode == CIPHER_MODE_GCM)
1572  {
1573  //Consider the explicit nonce and the authentication tag
1574  n += encryptionEngine->recordIvLen + encryptionEngine->authTagLen;
1575  }
1576  else if(encryptionEngine->cipherMode == CIPHER_MODE_CHACHA20_POLY1305)
1577  {
1578  //Consider the authentication tag only
1579  n += encryptionEngine->authTagLen;
1580  }
1581  else
1582  {
1583  //Stream ciphers do not cause any overhead
1584  }
1585 
1586  //Return the total overhead caused by encryption
1587  return n;
1588 }
1589 
1590 
1591 /**
1592  * @brief DNS hostname verification
1593  * @param[in] name Pointer to the hostname
1594  * @param[in] length Length of the hostname
1595  * @return The function returns TRUE is the name is a valid DNS hostname
1596  **/
1597 
1599 {
1600  size_t i;
1601  bool_t valid;
1602 
1603  //Initialize flag
1604  valid = TRUE;
1605 
1606  //Loop through the hostname
1607  for(i = 0; i < length && valid; i++)
1608  {
1609  //DNS hostnames must start with a letter, end with a letter or
1610  //digit, and have as interior characters only letters, digits,
1611  //and hyphen (refer to RFC 1034, section 3.5)
1612  if(name[i] == '-' || name[i] == '.')
1613  {
1614  //Valid character
1615  }
1616  else if(name[i] >= '0' && name[i] <= '9')
1617  {
1618  //Valid character
1619  }
1620  else if(name[i] >= 'A' && name[i] <= 'Z')
1621  {
1622  //Valid character
1623  }
1624  else if(name[i] >= 'a' && name[i] <= 'z')
1625  {
1626  //Valid character
1627  }
1628  else if(name[i] == '_')
1629  {
1630  //In practice, DNS allows underscores to be used in hostnames
1631  }
1632  else
1633  {
1634  //Invalid character
1635  valid = FALSE;
1636  }
1637  }
1638 
1639  //Return TRUE is the name is a valid DNS hostname
1640  return valid;
1641 }
1642 
1643 #endif
@ TLS_GROUP_BRAINPOOLP512R1_TLS13
Definition: tls.h:1454
#define TLS_MAX_RECORD_LENGTH
Definition: tls.h:963
#define tlsAllocMem(size)
Definition: tls.h:874
size_t ticketLen
Length of the session ticket.
Definition: tls.h:2105
TLS helper functions.
@ TLS_ALERT_DECODE_ERROR
Definition: tls.h:1130
const uint8_t tls11DowngradeRandom[8]
Definition: tls13_misc.c:53
@ TLS_ALERT_UNEXPECTED_MESSAGE
Definition: tls.h:1115
@ TLS_GROUP_BRAINPOOLP256R1_TLS13
Definition: tls.h:1452
#define SHA256_HASH_ALGO
Definition: sha256.h:49
int bool_t
Definition: compiler_port.h:61
@ TLS_GROUP_SECP160R2
Definition: tls.h:1438
TLS cipher suites.
uint16_t cipherSuite
Cipher suite identifier.
Definition: tls.h:1939
error_t tlsSaveSessionTicket(const TlsContext *context, TlsSessionState *session)
Save session ticket.
Definition: tls_misc.c:504
@ TLS_ALERT_CERTIFICATE_REQUIRED
Definition: tls.h:1147
#define SHA1_HASH_ALGO
Definition: sha1.h:49
const HashAlgo * tlsGetHashAlgo(TlsHashAlgo hashAlgoId)
Get the hash algorithm that matches the specified identifier.
Definition: tls_misc.c:1186
@ CIPHER_MODE_CBC
Definition: crypto.h:1008
@ ERROR_WOULD_BLOCK
Definition: error.h:96
uint8_t a
Definition: ndp.h:411
#define SHA512_HASH_ALGO
Definition: sha512.h:49
const uint8_t X25519_OID[3]
Definition: ec_curves.c:108
Arbitrary precision integer.
Definition: mpi.h:102
error_t tlsGenerateSessionId(TlsContext *context, size_t length)
Generate a random session identifier.
Definition: tls_misc.c:270
@ TLS_ALERT_ILLEGAL_PARAMETER
Definition: tls.h:1127
@ ERROR_VERSION_NOT_SUPPORTED
Definition: error.h:67
uint8_t * ticket
Session ticket.
Definition: tls.h:2104
@ ERROR_UNKNOWN_CERTIFICATE
Definition: error.h:238
@ ERROR_NOT_IMPLEMENTED
Definition: error.h:66
@ ERROR_ILLEGAL_PARAMETER
Definition: error.h:244
const EcCurve * tlsGetCurve(TlsContext *context, uint16_t namedCurve)
Get the EC domain parameters that match the specified named curve.
Definition: tls_misc.c:1253
@ ERROR_DECRYPTION_FAILED
Definition: error.h:243
uint8_t secret[TLS_MASTER_SECRET_SIZE]
Master secret (TLS 1.2) or ticket PSK (TLS 1.3)
Definition: tls.h:2098
@ TLS_ALERT_UNSUPPORTED_EXTENSION
Definition: tls.h:1141
@ ERROR_UNEXPECTED_MESSAGE
Definition: error.h:195
TlsState
TLS FSM states.
Definition: tls.h:1510
OID (Object Identifier)
uint8_t p
Definition: ndp.h:300
@ CIPHER_MODE_GCM
Definition: crypto.h:1013
@ TLS_ALERT_RECORD_OVERFLOW
Definition: tls.h:1118
error_t tlsSelectVersion(TlsContext *context, uint16_t version)
Set the TLS version to be used.
Definition: tls_misc.c:307
TlsConnectionEnd
TLS connection end.
Definition: tls.h:997
systime_t timestamp
Time stamp to manage entry lifetime.
Definition: tls.h:2097
@ TLS_GROUP_SECP256K1
Definition: tls.h:1443
#define TRUE
Definition: os_port.h:50
uint8_t data[]
Definition: ethernet.h:224
@ TLS_GROUP_SECP256R1
Definition: tls.h:1444
@ TLS_GROUP_CURVE_SM2
Definition: tls.h:1462
size_t digestSize
Definition: crypto.h:1095
@ TLS_GROUP_SECP224K1
Definition: tls.h:1441
const uint8_t SECP224R1_OID[5]
Definition: ec_curves.c:66
error_t tlsSaveSessionId(const TlsContext *context, TlsSessionState *session)
Save session ID.
Definition: tls_misc.c:432
error_t ecImportPublicKey(EcPublicKey *key, const EcCurve *curve, const uint8_t *input, size_t length, EcPublicKeyFormat format)
Import an EC public key.
Definition: ec.c:263
const uint8_t BRAINPOOLP512R1_OID[9]
Definition: ec_curves.c:100
Structure describing a cipher suite.
Definition: tls.h:2072
const uint8_t SECP160K1_OID[5]
Definition: ec_curves.c:54
@ TLS_HASH_ALGO_SHA1
Definition: tls.h:1248
size_t sessionIdLen
Length of the session identifier.
Definition: tls.h:2101
const uint8_t SECP256K1_OID[5]
Definition: ec_curves.c:68
error_t tlsWriteMpi(const Mpi *a, uint8_t *data, size_t *length)
Encode a multiple precision integer to an opaque vector.
Definition: tls_misc.c:962
TlsHashAlgo
Hash algorithms.
Definition: tls.h:1245
@ ERROR_HANDSHAKE_FAILED
Definition: error.h:234
@ ERROR_OUT_OF_MEMORY
Definition: error.h:63
#define SM3_HASH_ALGO
Definition: sm3.h:49
const uint8_t BRAINPOOLP384R1_OID[9]
Definition: ec_curves.c:96
const uint8_t tls12DowngradeRandom[8]
Definition: tls13_misc.c:59
char_t name[]
@ EC_PUBLIC_KEY_FORMAT_X963
Definition: ec.h:386
error_t ecExportPublicKey(const EcPublicKey *key, uint8_t *output, size_t *written, EcPublicKeyFormat format)
Export an EC public key.
Definition: ec.c:378
@ ERROR_BAD_RECORD_MAC
Definition: error.h:232
@ ERROR_NOT_CONFIGURED
Definition: error.h:218
__weak_func error_t gcmInit(GcmContext *context, const CipherAlgo *cipherAlgo, void *cipherContext)
Initialize GCM context.
Definition: gcm.c:99
@ ERROR_UNSUPPORTED_CERTIFICATE
Definition: error.h:237
#define osStrlen(s)
Definition: os_port.h:168
uint8_t version
Definition: coap_common.h:177
uint16_t errorCode
Definition: tftp_common.h:138
@ TLS_ALERT_DECRYPT_ERROR
Definition: tls.h:1131
@ ERROR_INVALID_VERSION
Definition: error.h:118
@ TLS_GROUP_BRAINPOOLP256R1
Definition: tls.h:1447
const uint8_t SECP256R1_OID[8]
Definition: ec_curves.c:70
@ TLS_GROUP_X448
Definition: tls.h:1451
uint8_t oid[]
Definition: lldp_tlv.h:300
const uint8_t SECP224K1_OID[5]
Definition: ec_curves.c:64
@ TLS_HASH_ALGO_SHA224
Definition: tls.h:1249
CipherAlgoInit init
Definition: crypto.h:1116
@ TLS_ALERT_UNKNOWN_CA
Definition: tls.h:1128
const uint8_t SECP521R1_OID[5]
Definition: ec_curves.c:74
@ TLS_HASH_ALGO_SHA512
Definition: tls.h:1252
uint16_t cipherSuite
Cipher suite identifier.
Definition: tls.h:2096
#define DTLS_VERSION_1_0
Definition: dtls_misc.h:35
#define FALSE
Definition: os_port.h:46
error_t tlsSendAlert(TlsContext *context, uint8_t level, uint8_t description)
Send Alert message.
Definition: tls_common.c:515
#define osMemcpy(dest, src, length)
Definition: os_port.h:144
@ ERROR_UNSUPPORTED_EXTENSION
Definition: error.h:246
@ TLS_HASH_ALGO_SM3
Definition: tls.h:1254
#define TlsContext
Definition: tls.h:36
error_t
Error codes.
Definition: error.h:43
@ TLS_ALERT_BAD_RECORD_MAC
Definition: tls.h:1116
@ TLS_CONNECTION_END_SERVER
Definition: tls.h:999
void tlsFreeEncryptionEngine(TlsEncryptionEngine *encryptionEngine)
Release encryption engine.
Definition: tls_misc.c:921
#define TLS_VERSION_1_2
Definition: tls.h:96
@ TLS_GROUP_NONE
Definition: tls.h:1421
@ ERROR_FAILURE
Generic error code.
Definition: error.h:45
error_t tlsSelectCipherSuite(TlsContext *context, uint16_t identifier)
Set cipher suite.
Definition: tls_misc.c:335
#define STORE16BE(a, p)
Definition: cpu_endian.h:262
#define MD5_HASH_ALGO
Definition: md5.h:49
error_t mpiImport(Mpi *r, const uint8_t *input, size_t length, MpiFormat format)
Octet string to integer conversion.
Definition: mpi.c:712
@ TLS_ALERT_UNSUPPORTED_CERTIFICATE
Definition: tls.h:1123
bool_t tlsCheckDnsHostname(const char_t *name, size_t length)
DNS hostname verification.
Definition: tls_misc.c:1598
@ ERROR_MISSING_EXTENSION
Definition: error.h:245
#define TLS_VERSION_1_3
Definition: tls.h:97
Handshake message processing (TLS client and server)
@ TLS_HASH_ALGO_SHA384
Definition: tls.h:1251
@ TLS_GROUP_SECP384R1
Definition: tls.h:1445
@ TLS_GROUP_SECP192K1
Definition: tls.h:1439
@ ERROR_BAD_CERTIFICATE
Definition: error.h:236
@ TLS_ALERT_MISSING_EXTENSION
Definition: tls.h:1140
@ TLS_TRANSPORT_PROTOCOL_EAP
Definition: tls.h:988
@ TLS_HASH_ALGO_SHA256
Definition: tls.h:1250
#define SSL_VERSION_3_0
Definition: tls.h:93
const uint8_t SECP160R1_OID[5]
Definition: ec_curves.c:56
error_t mpiExport(const Mpi *a, uint8_t *output, size_t length, MpiFormat format)
Integer to octet string conversion.
Definition: mpi.c:809
size_t tlsComputeEncryptionOverhead(TlsEncryptionEngine *encryptionEngine, size_t payloadLen)
Compute overhead caused by encryption.
Definition: tls_misc.c:1544
TlsNamedGroup tlsGetNamedCurve(const uint8_t *oid, size_t length)
Get the named curve that matches the specified OID.
Definition: tls_misc.c:1407
uint8_t length
Definition: tcp.h:375
@ CIPHER_MODE_STREAM
Definition: crypto.h:1006
@ TLS_GROUP_BRAINPOOLP512R1
Definition: tls.h:1449
@ TLS_GROUP_SECP160K1
Definition: tls.h:1436
#define MIN(a, b)
Definition: os_port.h:63
@ TLS_GROUP_SECP521R1
Definition: tls.h:1446
@ TLS_GROUP_SECP192R1
Definition: tls.h:1440
@ TLS_ALERT_PROTOCOL_VERSION
Definition: tls.h:1134
@ TLS_GROUP_SECP160R1
Definition: tls.h:1437
const uint8_t SECP192R1_OID[8]
Definition: ec_curves.c:62
#define TLS_MASTER_SECRET_SIZE
Definition: tls.h:822
@ TLS_GROUP_BRAINPOOLP384R1_TLS13
Definition: tls.h:1453
@ TLS_HASH_ALGO_MD5
Definition: tls.h:1247
const uint8_t SECP384R1_OID[5]
Definition: ec_curves.c:72
uint8_t secret[TLS_MASTER_SECRET_SIZE]
Master secret.
Definition: tls.h:1940
uint8_t random[32]
Definition: tls.h:1827
const uint8_t X448_OID[3]
Definition: ec_curves.c:110
bool_t tlsIsCipherSuiteAcceptable(const TlsCipherSuiteInfo *cipherSuite, uint16_t minVersion, uint16_t maxVersion, TlsTransportProtocol transportProtocol)
Check whether a cipher suite can be used with a given protocol version.
error_t tlsRestoreSessionId(TlsContext *context, const TlsSessionState *session)
Restore a TLS session using session ID.
Definition: tls_misc.c:558
char_t * serverName
ServerName extension.
Definition: tls.h:2115
error_t tlsWriteEcPoint(const EcPublicKey *publicKey, uint8_t *data, size_t *length)
Encode an EC point to an opaque vector.
Definition: tls_misc.c:1038
EC public key.
Definition: ec.h:421
#define SHA384_HASH_ALGO
Definition: sha384.h:45
#define TRACE_DEBUG(...)
Definition: debug.h:119
const uint8_t SECP192K1_OID[5]
Definition: ec_curves.c:60
@ ERROR_TIMEOUT
Definition: error.h:95
char char_t
Definition: compiler_port.h:55
@ TLS_GROUP_SECP224R1
Definition: tls.h:1442
GCM context.
Definition: gcm.h:64
#define TLS_VERSION_1_1
Definition: tls.h:95
@ CIPHER_MODE_CCM
Definition: crypto.h:1012
error_t tlsReadMpi(Mpi *a, const uint8_t *data, size_t size, size_t *length)
Read a multiple precision integer from an opaque vector.
Definition: tls_misc.c:996
@ TLS_ALERT_BAD_CERTIFICATE
Definition: tls.h:1122
size_t contextSize
Definition: crypto.h:1113
@ TLS_ALERT_INAPPROPRIATE_FALLBACK
Definition: tls.h:1137
#define TRACE_DEBUG_ARRAY(p, a, n)
Definition: debug.h:120
@ ERROR_NO_APPLICATION_PROTOCOL
Definition: error.h:248
#define OID_COMP(oid1, oidLen1, oid2)
Definition: oid.h:42
@ TLS_ALERT_LEVEL_FATAL
Definition: tls.h:1104
TLS session state.
Definition: tls.h:2094
uint8_t n
#define DTLS_VERSION_1_3
Definition: dtls_misc.h:37
@ ERROR_READ_FAILED
Definition: error.h:224
@ ERROR_WRITE_FAILED
Definition: error.h:223
uint8_t sessionId[32]
Session identifier.
Definition: tls.h:2100
@ ERROR_INAPPROPRIATE_FALLBACK
Definition: error.h:247
#define TLS_VERSION_1_0
Definition: tls.h:94
@ TLS_ALERT_CERTIFICATE_EXPIRED
Definition: tls.h:1125
const TlsCipherSuiteInfo tlsSupportedCipherSuites[]
@ TLS_STATE_INIT
Definition: tls.h:1511
@ ERROR_CERTIFICATE_EXPIRED
Definition: error.h:239
@ TLS_ALERT_NO_APPLICATION_PROTOCOL
Definition: tls.h:1148
@ TLS_CONNECTION_END_CLIENT
Definition: tls.h:998
Common interface for encryption algorithms.
Definition: crypto.h:1111
DtlsSequenceNumber
Definition: dtls_misc.h:143
@ MPI_FORMAT_BIG_ENDIAN
Definition: mpi.h:93
TLS (Transport Layer Security)
uint8_t identifier[]
error_t tlsReadEcPoint(EcPublicKey *publicKey, const EcCurve *curve, const uint8_t *data, size_t size, size_t *length)
Read an EC point from an opaque vector.
Definition: tls_misc.c:1077
uint16_t version
TLS protocol version.
Definition: tls.h:2095
uint8_t s
Definition: igmp_common.h:234
const EcCurve * ecGetCurve(const uint8_t *oid, size_t length)
Get the elliptic curve that matches the specified OID.
Definition: ec_curves.c:5888
@ TLS_GROUP_X25519
Definition: tls.h:1450
const uint8_t SECP160R2_OID[5]
Definition: ec_curves.c:58
@ TLS_TRANSPORT_PROTOCOL_STREAM
Definition: tls.h:985
@ ERROR_UNKNOWN_CA
Definition: error.h:241
TLS 1.3 key schedule.
#define SHA224_HASH_ALGO
Definition: sha224.h:45
Common interface for hash algorithms.
Definition: crypto.h:1089
__weak_func error_t tlsInitEncryptionEngine(TlsContext *context, TlsEncryptionEngine *encryptionEngine, TlsConnectionEnd entity, const uint8_t *secret)
Initialize encryption engine.
Definition: tls_misc.c:674
FFDHE key exchange.
#define EcCurve
Definition: ec.h:346
@ CIPHER_MODE_NULL
Definition: crypto.h:1005
@ CIPHER_MODE_CHACHA20_POLY1305
Definition: crypto.h:1015
void tlsProcessError(TlsContext *context, error_t errorCode)
Translate an error code to an alert message.
Definition: tls_misc.c:74
error_t tls13HkdfExpandLabel(TlsTransportProtocol transportProtocol, const HashAlgo *hash, const uint8_t *secret, size_t secretLen, const char_t *label, const uint8_t *context, size_t contextLen, uint8_t *output, size_t outputLen)
HKDF-Expand-Label function.
uint16_t payloadLen
Definition: ipv6.h:281
const char_t * tlsGetVersionName(uint16_t version)
Convert TLS version to string representation.
Definition: tls_misc.c:1125
uint_t tlsGetNumSupportedCipherSuites(void)
Determine the number of cipher suites supported.
void tlsChangeState(TlsContext *context, TlsState newState)
Update TLS state.
Definition: tls_misc.c:54
TlsNamedGroup
Named groups.
Definition: tls.h:1420
@ ERROR_RECORD_OVERFLOW
Definition: error.h:233
@ ERROR_DECODING_FAILED
Definition: error.h:242
unsigned int uint_t
Definition: compiler_port.h:57
#define LOAD16BE(p)
Definition: cpu_endian.h:186
#define osMemset(p, value, length)
Definition: os_port.h:138
#define tlsFreeMem(p)
Definition: tls.h:879
@ TLS_ALERT_HANDSHAKE_FAILURE
Definition: tls.h:1120
@ ERROR_CERTIFICATE_REQUIRED
Definition: error.h:136
error_t tlsGenerateRandomValue(TlsContext *context, uint8_t *random)
Generate client or server random value.
Definition: tls_misc.c:207
@ TLS_ALERT_INTERNAL_ERROR
Definition: tls.h:1136
@ ERROR_INVALID_SIGNATURE
Definition: error.h:228
#define osStrcpy(s1, s2)
Definition: os_port.h:210
#define DTLS_VERSION_1_2
Definition: dtls_misc.h:36
#define TlsEncryptionEngine
Definition: tls.h:40
bool_t extendedMasterSecret
Extended master secret computation.
Definition: tls.h:2102
@ ERROR_INVALID_SESSION
Definition: error.h:287
@ ERROR_INVALID_TICKET
Definition: error.h:229
@ NO_ERROR
Success.
Definition: error.h:44
Debugging facilities.
TlsSequenceNumber
Definition: tls.h:1562
@ TLS_GROUP_BRAINPOOLP384R1
Definition: tls.h:1448
@ TLS_ALERT_CERTIFICATE_UNKNOWN
Definition: tls.h:1126
const uint8_t BRAINPOOLP256R1_OID[9]
Definition: ec_curves.c:88
const uint8_t SM2_OID[8]
Definition: ec_curves.c:106
uint_t mpiGetByteLength(const Mpi *a)
Get the actual length in bytes.
Definition: mpi.c:215
systime_t osGetSystemTime(void)
Retrieve system time.
error_t tlsRestoreSessionTicket(TlsContext *context, const TlsSessionState *session)
Restore a TLS session using session ticket.
Definition: tls_misc.c:607
@ TLS_STATE_CLOSED
Definition: tls.h:1543