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.4
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->generate(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->generate(context->prngContext,
280  context->sessionId, 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] level Encryption level
671  * @param[in] secret Pointer to the secret value
672  * @return Error code
673  **/
674 
676  TlsEncryptionEngine *encryptionEngine, TlsConnectionEnd entity,
677  TlsEncryptionLevel level, const uint8_t *secret)
678 {
679  error_t error;
680  const CipherAlgo *cipherAlgo;
682 
683  //Point to the negotiated cipher suite
684  cipherSuite = &context->cipherSuite;
685  //Point to the cipher algorithm
686  cipherAlgo = cipherSuite->cipherAlgo;
687 
688  //Save the negotiated TLS version
689  encryptionEngine->version = context->version;
690 
691  //The sequence number is set to zero at the beginning of a connection
692  //and whenever the key is changed
693  osMemset(&encryptionEngine->seqNum, 0, sizeof(TlsSequenceNumber));
694 
695 #if (DTLS_SUPPORT == ENABLED)
696  //The epoch number is initially zero and is incremented each time a
697  //ChangeCipherSpec message is sent
698  encryptionEngine->epoch++;
699 
700  //Sequence numbers are maintained separately for each epoch, with each
701  //sequence number initially being 0 for each epoch
702  osMemset(&encryptionEngine->dtlsSeqNum, 0, sizeof(DtlsSequenceNumber));
703 #endif
704 
705 #if (TLS_QUIC_SUPPORT == ENABLED)
706  //TLS encryption level determines the QUIC packet type and keys that are
707  //used for protecting data (refer to RFC 9001, section 4.1.3)
708  encryptionEngine->level = level;
709 #endif
710 
711 #if (TLS_RECORD_SIZE_LIMIT_SUPPORT == ENABLED)
712  //The value of RecordSizeLimit is used to limit the size of records
713  //that are created when encoding application data and the protected
714  //handshake message into records (refer to RFC 8449, section 4)
715  if(entity == context->entity)
716  {
717  encryptionEngine->recordSizeLimit = context->recordSizeLimit;
718  }
719  else
720  {
721  encryptionEngine->recordSizeLimit = MIN(context->rxBufferMaxLen,
723  }
724 #endif
725 
726 #if (TLS_ENCRYPT_THEN_MAC_SUPPORT == ENABLED)
727  //If an upgrade from MAC-then-encrypt to encrypt-then-MAC is negotiated,
728  //then the change will take place in the first message that follows the
729  //ChangeCipherSpec message (refer to RFC 7366, section 3.1)
730  encryptionEngine->encryptThenMac = context->etmExtReceived;
731 #endif
732 
733  //Set appropriate length for MAC key, encryption key, authentication
734  //tag and IV
735  encryptionEngine->macKeyLen = cipherSuite->macKeyLen;
736  encryptionEngine->encKeyLen = cipherSuite->encKeyLen;
737  encryptionEngine->fixedIvLen = cipherSuite->fixedIvLen;
738  encryptionEngine->recordIvLen = cipherSuite->recordIvLen;
739  encryptionEngine->authTagLen = cipherSuite->authTagLen;
740 
741  //Set cipher and hash algorithms
742  encryptionEngine->cipherAlgo = cipherSuite->cipherAlgo;
743  encryptionEngine->cipherMode = cipherSuite->cipherMode;
744  encryptionEngine->hashAlgo = cipherSuite->hashAlgo;
745 
746  //Initialize cipher context
747  encryptionEngine->cipherContext = NULL;
748 
749 #if (TLS_MAX_VERSION >= TLS_VERSION_1_0 && TLS_MIN_VERSION <= TLS_VERSION_1_2)
750  //Initialize HMAC context
751  encryptionEngine->hmacContext = &context->hmacContext;
752 #endif
753 
754 #if (TLS_GCM_CIPHER_SUPPORT == ENABLED)
755  //Initialize GCM context
756  encryptionEngine->gcmContext = NULL;
757 #endif
758 
759 #if (TLS_MAX_VERSION >= TLS_VERSION_1_0 && TLS_MIN_VERSION <= TLS_VERSION_1_2)
760  //TLS 1.0, TLS 1.1 or TLS 1.2 currently selected?
761  if(context->version <= TLS_VERSION_1_2)
762  {
763  const uint8_t *p;
764 
765  //Check whether client or server write keys shall be used
766  if(entity == TLS_CONNECTION_END_CLIENT)
767  {
768  //Point to the key material
769  p = context->keyBlock;
770  //Save MAC key
771  osMemcpy(encryptionEngine->macKey, p, cipherSuite->macKeyLen);
772 
773  //Advance current position in the key block
774  p += 2 * cipherSuite->macKeyLen;
775  //Save encryption key
776  osMemcpy(encryptionEngine->encKey, p, cipherSuite->encKeyLen);
777 
778  //Advance current position in the key block
779  p += 2 * cipherSuite->encKeyLen;
780  //Save initialization vector
781  osMemcpy(encryptionEngine->iv, p, cipherSuite->fixedIvLen);
782  }
783  else
784  {
785  //Point to the key material
786  p = context->keyBlock + cipherSuite->macKeyLen;
787  //Save MAC key
788  osMemcpy(encryptionEngine->macKey, p, cipherSuite->macKeyLen);
789 
790  //Advance current position in the key block
791  p += cipherSuite->macKeyLen + cipherSuite->encKeyLen;
792  //Save encryption key
793  osMemcpy(encryptionEngine->encKey, p, cipherSuite->encKeyLen);
794 
795  //Advance current position in the key block
796  p += cipherSuite->encKeyLen + cipherSuite->fixedIvLen;
797  //Save initialization vector
798  osMemcpy(encryptionEngine->iv, p, cipherSuite->fixedIvLen);
799  }
800 
801  //Successful processing
802  error = NO_ERROR;
803  }
804  else
805 #endif
806 #if (TLS_MAX_VERSION >= TLS_VERSION_1_3 && TLS_MIN_VERSION <= TLS_VERSION_1_3)
807  //TLS 1.3 currently selected?
808  if(context->version == TLS_VERSION_1_3)
809  {
810  const HashAlgo *hashAlgo;
811 
812  //The hash function used by HKDF is the cipher suite hash algorithm
813  hashAlgo = cipherSuite->prfHashAlgo;
814 
815  //Make sure the hash algorithm is valid
816  if(hashAlgo != NULL)
817  {
818  //Calculate the write key
819  error = tls13HkdfExpandLabel(context->transportProtocol, hashAlgo,
820  secret, hashAlgo->digestSize, "key", NULL, 0,
821  encryptionEngine->encKey, cipherSuite->encKeyLen);
822 
823  //Debug message
824  TRACE_DEBUG("Write Key:\r\n");
825  TRACE_DEBUG_ARRAY(" ", encryptionEngine->encKey, cipherSuite->encKeyLen);
826 
827  //Check status code
828  if(!error)
829  {
830  //Calculate the write IV
831  error = tls13HkdfExpandLabel(context->transportProtocol, hashAlgo,
832  secret, hashAlgo->digestSize, "iv", NULL, 0,
833  encryptionEngine->iv, cipherSuite->fixedIvLen);
834  }
835 
836  //Debug message
837  TRACE_DEBUG("Write IV:\r\n");
838  TRACE_DEBUG_ARRAY(" ", encryptionEngine->iv, cipherSuite->fixedIvLen);
839  }
840  else
841  {
842  //Invalid HKDF hash algorithm
843  error = ERROR_FAILURE;
844  }
845  }
846  else
847 #endif
848  //Invalid TLS version?
849  {
850  //Report an error
851  error = ERROR_INVALID_VERSION;
852  }
853 
854  //Check status code
855  if(!error)
856  {
857  //Check cipher mode of operation
858  if(encryptionEngine->cipherMode == CIPHER_MODE_STREAM ||
859  encryptionEngine->cipherMode == CIPHER_MODE_CBC ||
860  encryptionEngine->cipherMode == CIPHER_MODE_CCM ||
861  encryptionEngine->cipherMode == CIPHER_MODE_GCM)
862  {
863  //Allocate encryption context
864  encryptionEngine->cipherContext = tlsAllocMem(cipherAlgo->contextSize);
865 
866  //Successful memory allocation?
867  if(encryptionEngine->cipherContext != NULL)
868  {
869  //Configure the encryption engine with the write key
870  error = cipherAlgo->init(encryptionEngine->cipherContext,
871  encryptionEngine->encKey, cipherSuite->encKeyLen);
872  }
873  else
874  {
875  //Failed to allocate memory
876  error = ERROR_OUT_OF_MEMORY;
877  }
878  }
879  else if(encryptionEngine->cipherMode == CIPHER_MODE_NULL ||
880  encryptionEngine->cipherMode == CIPHER_MODE_CHACHA20_POLY1305)
881  {
882  //No need to allocate an encryption context
883  error = NO_ERROR;
884  }
885  else
886  {
887  //Unsupported mode of operation
888  error = ERROR_FAILURE;
889  }
890  }
891 
892 #if (TLS_GCM_CIPHER_SUPPORT == ENABLED)
893  //Check status code
894  if(!error)
895  {
896  //GCM cipher mode?
897  if(encryptionEngine->cipherMode == CIPHER_MODE_GCM)
898  {
899  //Allocate a memory buffer to hold the GCM context
900  encryptionEngine->gcmContext = tlsAllocMem(sizeof(GcmContext));
901 
902  //Successful memory allocation?
903  if(encryptionEngine->gcmContext != NULL)
904  {
905  //Initialize GCM context
906  error = gcmInit(encryptionEngine->gcmContext, cipherAlgo,
907  encryptionEngine->cipherContext);
908  }
909  else
910  {
911  //Failed to allocate memory
912  error = ERROR_OUT_OF_MEMORY;
913  }
914  }
915  }
916 #endif
917 
918  //Return status code
919  return error;
920 }
921 
922 
923 /**
924  * @brief Release encryption engine
925  * @param[in] encryptionEngine Pointer to the encryption/decryption engine
926  **/
927 
929 {
930  //Valid cipher context?
931  if(encryptionEngine->cipherContext != NULL)
932  {
933  //Erase cipher context
934  encryptionEngine->cipherAlgo->deinit(encryptionEngine->cipherContext);
935 
936  //Release memory
937  tlsFreeMem(encryptionEngine->cipherContext);
938  encryptionEngine->cipherContext = NULL;
939  }
940 
941 #if (TLS_GCM_CIPHER_SUPPORT == ENABLED)
942  //Valid GCM context?
943  if(encryptionEngine->gcmContext != NULL)
944  {
945  //Erase GCM context
946  osMemset(encryptionEngine->gcmContext, 0, sizeof(GcmContext));
947 
948  //Release memory
949  tlsFreeMem(encryptionEngine->gcmContext);
950  encryptionEngine->gcmContext = NULL;
951  }
952 #endif
953 
954  //Reset encryption parameters
955  encryptionEngine->cipherAlgo = NULL;
956  encryptionEngine->cipherMode = CIPHER_MODE_NULL;
957  encryptionEngine->hashAlgo = NULL;
958 }
959 
960 
961 /**
962  * @brief Encode a multiple precision integer to an opaque vector
963  * @param[in] a Pointer to a multiple precision integer
964  * @param[out] data Buffer where to store the opaque vector
965  * @param[out] length Total number of bytes that have been written
966  * @return Error code
967  **/
968 
969 error_t tlsWriteMpi(const Mpi *a, uint8_t *data, size_t *length)
970 {
971  error_t error;
972  size_t n;
973 
974  //Retrieve the actual size of the integer
975  n = mpiGetByteLength(a);
976 
977  //The data is preceded by a 2-byte length field
978  STORE16BE(n, data);
979 
980  //Convert the integer to an octet string
981  error = mpiExport(a, data + 2, n, MPI_FORMAT_BIG_ENDIAN);
982  //Conversion failed?
983  if(error)
984  return error;
985 
986  //Return the total number of bytes that have been written
987  *length = n + 2;
988 
989  //Successful processing
990  return NO_ERROR;
991 }
992 
993 
994 /**
995  * @brief Read a multiple precision integer from an opaque vector
996  * @param[out] a Resulting multiple precision integer
997  * @param[in] data Buffer where to read the opaque vector
998  * @param[in] size Total number of bytes available in the buffer
999  * @param[out] length Total number of bytes that have been read
1000  * @return Error code
1001  **/
1002 
1003 error_t tlsReadMpi(Mpi *a, const uint8_t *data, size_t size, size_t *length)
1004 {
1005  error_t error;
1006  size_t n;
1007 
1008  //Buffer underrun?
1009  if(size < 2)
1010  return ERROR_DECODING_FAILED;
1011 
1012  //Decode the length field
1013  n = LOAD16BE(data);
1014 
1015  //Invalid length?
1016  if(n < 1)
1017  return ERROR_DECODING_FAILED;
1018 
1019  //Buffer underrun?
1020  if(size < (n + 2))
1021  return ERROR_DECODING_FAILED;
1022 
1023  //Convert the octet string to a multiple precision integer
1024  error = mpiImport(a, data + 2, n, MPI_FORMAT_BIG_ENDIAN);
1025  //Any error to report?
1026  if(error)
1027  return error;
1028 
1029  //Return the total number of bytes that have been read
1030  *length = n + 2;
1031 
1032  //Successful processing
1033  return NO_ERROR;
1034 }
1035 
1036 
1037 /**
1038  * @brief Encode an EC point to an opaque vector
1039  * @param[in] publicKey EC public key to be encoded
1040  * @param[out] data Buffer where to store the opaque vector
1041  * @param[out] length Total number of bytes that have been written
1042  * @return Error code
1043  **/
1044 
1045 error_t tlsWriteEcPoint(const EcPublicKey *publicKey, uint8_t *data,
1046  size_t *length)
1047 {
1048 #if (TLS_ECDH_ANON_KE_SUPPORT == ENABLED || TLS_ECDHE_RSA_KE_SUPPORT == ENABLED || \
1049  TLS_ECDHE_ECDSA_KE_SUPPORT == ENABLED || TLS_ECDHE_PSK_KE_SUPPORT == ENABLED)
1050  error_t error;
1051 
1052  //Convert the EC point to an octet string
1053  error = ecExportPublicKey(publicKey, data + 1, length,
1055  //Any error to report?
1056  if(error)
1057  return error;
1058 
1059  //Set the length of the opaque vector
1060  data[0] = (uint8_t) (*length);
1061 
1062  //Return the total number of bytes that have been written
1063  *length += 1;
1064 
1065  //Successful processing
1066  return NO_ERROR;
1067 #else
1068  //Not implemented
1069  return ERROR_NOT_IMPLEMENTED;
1070 #endif
1071 }
1072 
1073 
1074 /**
1075  * @brief Read an EC point from an opaque vector
1076  * @param[out] publicKey Resulting EC public key
1077  * @param[in] curve Elliptic curve parameters
1078  * @param[in] data Buffer where to read the opaque vector
1079  * @param[in] size Total number of bytes available in the buffer
1080  * @param[out] length Total number of bytes that have been read
1081  * @return Error code
1082  **/
1083 
1084 error_t tlsReadEcPoint(EcPublicKey *publicKey, const EcCurve *curve,
1085  const uint8_t *data, size_t size, size_t *length)
1086 {
1087 #if (TLS_ECDH_ANON_KE_SUPPORT == ENABLED || TLS_ECDHE_RSA_KE_SUPPORT == ENABLED || \
1088  TLS_ECDHE_ECDSA_KE_SUPPORT == ENABLED || TLS_ECDHE_PSK_KE_SUPPORT == ENABLED)
1089  error_t error;
1090  size_t n;
1091 
1092  //Buffer underrun?
1093  if(size < 1)
1094  return ERROR_DECODING_FAILED;
1095 
1096  //The EC point representation is preceded by a length field
1097  n = data[0];
1098 
1099  //Invalid EC point representation?
1100  if(n == 0)
1101  return ERROR_DECODING_FAILED;
1102 
1103  //Buffer underrun?
1104  if(size < (n + 1))
1105  return ERROR_DECODING_FAILED;
1106 
1107  //Convert the octet string to an EC point
1108  error = ecImportPublicKey(publicKey, curve, data + 1, n,
1110  //Any error to report?
1111  if(error)
1112  return error;
1113 
1114  //Return the total number of bytes that have been read
1115  *length = n + 1;
1116 
1117  //Successful processing
1118  return NO_ERROR;
1119 #else
1120  //Not implemented
1121  return ERROR_NOT_IMPLEMENTED;
1122 #endif
1123 }
1124 
1125 
1126 /**
1127  * @brief Convert TLS version to string representation
1128  * @param[in] version Version number
1129  * @return String representation
1130  **/
1131 
1133 {
1134  const char_t *s;
1135 
1136  //TLS versions
1137  static const char_t *const label[] =
1138  {
1139  "SSL 3.0",
1140  "TLS 1.0",
1141  "TLS 1.1",
1142  "TLS 1.2",
1143  "TLS 1.3",
1144  "DTLS 1.0",
1145  "DTLS 1.2",
1146  "DTLS 1.3",
1147  "Unknown"
1148  };
1149 
1150  //Check current version
1151  switch(version)
1152  {
1153  case SSL_VERSION_3_0:
1154  s = label[0];
1155  break;
1156  case TLS_VERSION_1_0:
1157  s = label[1];
1158  break;
1159  case TLS_VERSION_1_1:
1160  s = label[2];
1161  break;
1162  case TLS_VERSION_1_2:
1163  s = label[3];
1164  break;
1165  case TLS_VERSION_1_3:
1166  s = label[4];
1167  break;
1168  case DTLS_VERSION_1_0:
1169  s = label[5];
1170  break;
1171  case DTLS_VERSION_1_2:
1172  s = label[6];
1173  break;
1174  case DTLS_VERSION_1_3:
1175  s = label[7];
1176  break;
1177  default:
1178  s = label[8];
1179  break;
1180  }
1181 
1182  //Return the string representation
1183  return s;
1184 }
1185 
1186 
1187 /**
1188  * @brief Get the hash algorithm that matches the specified identifier
1189  * @param[in] hashAlgoId Hash algorithm identifier
1190  * @return Pointer to the hash algorithm
1191  **/
1192 
1194 {
1195  const HashAlgo *hashAlgo;
1196 
1197  //Check hash algorithm identifier
1198  switch(hashAlgoId)
1199  {
1200 #if (TLS_MD5_SUPPORT == ENABLED)
1201  //MD5 hash identifier?
1202  case TLS_HASH_ALGO_MD5:
1203  hashAlgo = MD5_HASH_ALGO;
1204  break;
1205 #endif
1206 #if (TLS_SHA1_SUPPORT == ENABLED)
1207  //SHA-1 hash identifier?
1208  case TLS_HASH_ALGO_SHA1:
1209  hashAlgo = SHA1_HASH_ALGO;
1210  break;
1211 #endif
1212 #if (TLS_SHA224_SUPPORT == ENABLED)
1213  //SHA-224 hash identifier?
1214  case TLS_HASH_ALGO_SHA224:
1215  hashAlgo = SHA224_HASH_ALGO;
1216  break;
1217 #endif
1218 #if (TLS_SHA256_SUPPORT == ENABLED)
1219  //SHA-256 hash identifier?
1220  case TLS_HASH_ALGO_SHA256:
1221  hashAlgo = SHA256_HASH_ALGO;
1222  break;
1223 #endif
1224 #if (TLS_SHA384_SUPPORT == ENABLED)
1225  //SHA-384 hash identifier?
1226  case TLS_HASH_ALGO_SHA384:
1227  hashAlgo = SHA384_HASH_ALGO;
1228  break;
1229 #endif
1230 #if (TLS_SHA512_SUPPORT == ENABLED)
1231  //SHA-512 hash identifier?
1232  case TLS_HASH_ALGO_SHA512:
1233  hashAlgo = SHA512_HASH_ALGO;
1234  break;
1235 #endif
1236 #if (TLS_SM3_SUPPORT == ENABLED)
1237  //SM3 hash identifier?
1238  case TLS_HASH_ALGO_SM3:
1239  hashAlgo = SM3_HASH_ALGO;
1240  break;
1241 #endif
1242  //Unknown hash identifier?
1243  default:
1244  hashAlgo = NULL;
1245  break;
1246  }
1247 
1248  //Return a pointer to the corresponding hash algorithm
1249  return hashAlgo;
1250 }
1251 
1252 
1253 /**
1254  * @brief Get the EC domain parameters that match the specified named curve
1255  * @param[in] context Pointer to the TLS context
1256  * @param[in] namedCurve Elliptic curve identifier
1257  * @return Elliptic curve parameters
1258  **/
1259 
1260 const EcCurve *tlsGetCurve(TlsContext *context, uint16_t namedCurve)
1261 {
1262  uint_t i;
1263  const EcCurve *curve;
1264 
1265  //Default elliptic curve parameters
1266  curve = NULL;
1267 
1268 #if (TLS_ECDH_SUPPORT == ENABLED)
1269  //Check named curve
1270  switch(namedCurve)
1271  {
1272 #if (TLS_SECP160K1_SUPPORT == ENABLED)
1273  //secp160k1 elliptic curve?
1274  case TLS_GROUP_SECP160K1:
1275  curve = ecGetCurve(SECP160K1_OID, sizeof(SECP160K1_OID));
1276  break;
1277 #endif
1278 #if (TLS_SECP160R1_SUPPORT == ENABLED)
1279  //secp160r1 elliptic curve?
1280  case TLS_GROUP_SECP160R1:
1281  curve = ecGetCurve(SECP160R1_OID, sizeof(SECP160R1_OID));
1282  break;
1283 #endif
1284 #if (TLS_SECP160R2_SUPPORT == ENABLED)
1285  //secp160r2 elliptic curve?
1286  case TLS_GROUP_SECP160R2:
1287  curve = ecGetCurve(SECP160R2_OID, sizeof(SECP160R2_OID));
1288  break;
1289 #endif
1290 #if (TLS_SECP192K1_SUPPORT == ENABLED)
1291  //secp192k1 elliptic curve?
1292  case TLS_GROUP_SECP192K1:
1293  curve = ecGetCurve(SECP192K1_OID, sizeof(SECP192K1_OID));
1294  break;
1295 #endif
1296 #if (TLS_SECP192R1_SUPPORT == ENABLED)
1297  //secp192r1 elliptic curve?
1298  case TLS_GROUP_SECP192R1:
1299  curve = ecGetCurve(SECP192R1_OID, sizeof(SECP192R1_OID));
1300  break;
1301 #endif
1302 #if (TLS_SECP224K1_SUPPORT == ENABLED)
1303  //secp224k1 elliptic curve?
1304  case TLS_GROUP_SECP224K1:
1305  curve = ecGetCurve(SECP224K1_OID, sizeof(SECP224K1_OID));
1306  break;
1307 #endif
1308 #if (TLS_SECP224R1_SUPPORT == ENABLED)
1309  //secp224r1 elliptic curve?
1310  case TLS_GROUP_SECP224R1:
1311  curve = ecGetCurve(SECP224R1_OID, sizeof(SECP224R1_OID));
1312  break;
1313 #endif
1314 #if (TLS_SECP256K1_SUPPORT == ENABLED)
1315  //secp256k1 elliptic curve?
1316  case TLS_GROUP_SECP256K1:
1317  curve = ecGetCurve(SECP256K1_OID, sizeof(SECP256K1_OID));
1318  break;
1319 #endif
1320 #if (TLS_SECP256R1_SUPPORT == ENABLED)
1321  //secp256r1 elliptic curve?
1322  case TLS_GROUP_SECP256R1:
1323  curve = ecGetCurve(SECP256R1_OID, sizeof(SECP256R1_OID));
1324  break;
1325 #endif
1326 #if (TLS_SECP384R1_SUPPORT == ENABLED)
1327  //secp384r1 elliptic curve?
1328  case TLS_GROUP_SECP384R1:
1329  curve = ecGetCurve(SECP384R1_OID, sizeof(SECP384R1_OID));
1330  break;
1331 #endif
1332 #if (TLS_SECP521R1_SUPPORT == ENABLED)
1333  //secp521r1 elliptic curve?
1334  case TLS_GROUP_SECP521R1:
1335  curve = ecGetCurve(SECP521R1_OID, sizeof(SECP521R1_OID));
1336  break;
1337 #endif
1338 #if (TLS_BRAINPOOLP256R1_SUPPORT == ENABLED)
1339  //brainpoolP256r1 elliptic curve?
1343  break;
1344 #endif
1345 #if (TLS_BRAINPOOLP384R1_SUPPORT == ENABLED)
1346  //brainpoolP384r1 elliptic curve?
1350  break;
1351 #endif
1352 #if (TLS_BRAINPOOLP512R1_SUPPORT == ENABLED)
1353  //brainpoolP512r1 elliptic curve?
1357  break;
1358 #endif
1359 #if (TLS_SM2_SUPPORT == ENABLED)
1360  //SM2 elliptic curve?
1361  case TLS_GROUP_CURVE_SM2:
1362  curve = ecGetCurve(SM2_OID, sizeof(SM2_OID));
1363  break;
1364 #endif
1365 #if (TLS_X25519_SUPPORT == ENABLED)
1366  //Curve25519 elliptic curve?
1367  case TLS_GROUP_X25519:
1368  curve = ecGetCurve(X25519_OID, sizeof(X25519_OID));
1369  break;
1370 #endif
1371 #if (TLS_X448_SUPPORT == ENABLED)
1372  //Curve448 elliptic curve?
1373  case TLS_GROUP_X448:
1374  curve = ecGetCurve(X448_OID, sizeof(X448_OID));
1375  break;
1376 #endif
1377  //Unknown elliptic curve identifier?
1378  default:
1379  curve = NULL;
1380  break;
1381  }
1382 #endif
1383 
1384  //Restrict the use of certain elliptic curves
1385  if(context->numSupportedGroups > 0)
1386  {
1387  //Loop through the list of allowed named groups
1388  for(i = 0; i < context->numSupportedGroups; i++)
1389  {
1390  //Compare named groups
1391  if(context->supportedGroups[i] == namedCurve)
1392  break;
1393  }
1394 
1395  //Check whether the use of the elliptic curve is restricted
1396  if(i >= context->numSupportedGroups)
1397  {
1398  curve = NULL;
1399  }
1400  }
1401 
1402  //Return the elliptic curve parameters, if any
1403  return curve;
1404 }
1405 
1406 
1407 /**
1408  * @brief Get the named curve that matches the specified OID
1409  * @param[in] oid Object identifier
1410  * @param[in] length OID length
1411  * @return Named curve
1412  **/
1413 
1414 TlsNamedGroup tlsGetNamedCurve(const uint8_t *oid, size_t length)
1415 {
1416  TlsNamedGroup namedCurve;
1417 
1418  //Default named curve
1419  namedCurve = TLS_GROUP_NONE;
1420 
1421 #if (TLS_ECDSA_SIGN_SUPPORT == ENABLED)
1422  //Invalid parameters?
1423  if(oid == NULL || length == 0)
1424  {
1425  namedCurve = TLS_GROUP_NONE;
1426  }
1427 #if (TLS_SECP160K1_SUPPORT == ENABLED)
1428  //secp160k1 elliptic curve?
1429  else if(OID_COMP(oid, length, SECP160K1_OID) == 0)
1430  {
1431  namedCurve = TLS_GROUP_SECP160K1;
1432  }
1433 #endif
1434 #if (TLS_SECP160R1_SUPPORT == ENABLED)
1435  //secp160r1 elliptic curve?
1436  else if(OID_COMP(oid, length, SECP160R1_OID) == 0)
1437  {
1438  namedCurve = TLS_GROUP_SECP160R1;
1439  }
1440 #endif
1441 #if (TLS_SECP160R2_SUPPORT == ENABLED)
1442  //secp160r2 elliptic curve?
1443  else if(OID_COMP(oid, length, SECP160R2_OID) == 0)
1444  {
1445  namedCurve = TLS_GROUP_SECP160R2;
1446  }
1447 #endif
1448 #if (TLS_SECP192K1_SUPPORT == ENABLED)
1449  //secp192k1 elliptic curve?
1450  else if(OID_COMP(oid, length, SECP192K1_OID) == 0)
1451  {
1452  namedCurve = TLS_GROUP_SECP192K1;
1453  }
1454 #endif
1455 #if (TLS_SECP192R1_SUPPORT == ENABLED)
1456  //secp192r1 elliptic curve?
1457  else if(OID_COMP(oid, length, SECP192R1_OID) == 0)
1458  {
1459  namedCurve = TLS_GROUP_SECP192R1;
1460  }
1461 #endif
1462 #if (TLS_SECP224K1_SUPPORT == ENABLED)
1463  //secp224k1 elliptic curve?
1464  else if(OID_COMP(oid, length, SECP224K1_OID) == 0)
1465  {
1466  namedCurve = TLS_GROUP_SECP224K1;
1467  }
1468 #endif
1469 #if (TLS_SECP224R1_SUPPORT == ENABLED)
1470  //secp224r1 elliptic curve?
1471  else if(OID_COMP(oid, length, SECP224R1_OID) == 0)
1472  {
1473  namedCurve = TLS_GROUP_SECP224R1;
1474  }
1475 #endif
1476 #if (TLS_SECP256K1_SUPPORT == ENABLED)
1477  //secp256k1 elliptic curve?
1478  else if(OID_COMP(oid, length, SECP256K1_OID) == 0)
1479  {
1480  namedCurve = TLS_GROUP_SECP256K1;
1481  }
1482 #endif
1483 #if (TLS_SECP256R1_SUPPORT == ENABLED)
1484  //secp256r1 elliptic curve?
1485  else if(OID_COMP(oid, length, SECP256R1_OID) == 0)
1486  {
1487  namedCurve = TLS_GROUP_SECP256R1;
1488  }
1489 #endif
1490 #if (TLS_SECP384R1_SUPPORT == ENABLED)
1491  //secp384r1 elliptic curve?
1492  else if(OID_COMP(oid, length, SECP384R1_OID) == 0)
1493  {
1494  namedCurve = TLS_GROUP_SECP384R1;
1495  }
1496 #endif
1497 #if (TLS_SECP521R1_SUPPORT == ENABLED)
1498  //secp521r1 elliptic curve?
1499  else if(OID_COMP(oid, length, SECP521R1_OID) == 0)
1500  {
1501  namedCurve = TLS_GROUP_SECP521R1;
1502  }
1503 #endif
1504 #if (TLS_BRAINPOOLP256R1_SUPPORT == ENABLED)
1505  //brainpoolP256r1 elliptic curve?
1506  else if(OID_COMP(oid, length, BRAINPOOLP256R1_OID) == 0)
1507  {
1508  namedCurve = TLS_GROUP_BRAINPOOLP256R1;
1509  }
1510 #endif
1511 #if (TLS_BRAINPOOLP384R1_SUPPORT == ENABLED)
1512  //brainpoolP384r1 elliptic curve?
1513  else if(OID_COMP(oid, length, BRAINPOOLP384R1_OID) == 0)
1514  {
1515  namedCurve = TLS_GROUP_BRAINPOOLP384R1;
1516  }
1517 #endif
1518 #if (TLS_BRAINPOOLP512R1_SUPPORT == ENABLED)
1519  //brainpoolP512r1 elliptic curve?
1520  else if(OID_COMP(oid, length, BRAINPOOLP512R1_OID) == 0)
1521  {
1522  namedCurve = TLS_GROUP_BRAINPOOLP512R1;
1523  }
1524 #endif
1525 #if (TLS_SM2_SUPPORT == ENABLED)
1526  //SM2 elliptic curve?
1527  else if(OID_COMP(oid, length, SM2_OID) == 0)
1528  {
1529  namedCurve = TLS_GROUP_CURVE_SM2;
1530  }
1531 #endif
1532  //Unknown identifier?
1533  else
1534  {
1535  namedCurve = TLS_GROUP_NONE;
1536  }
1537 #endif
1538 
1539  //Return the corresponding named curve
1540  return namedCurve;
1541 }
1542 
1543 
1544 /**
1545  * @brief Compute overhead caused by encryption
1546  * @param[in] encryptionEngine Pointer to the encryption engine
1547  * @param[in] payloadLen Length of the payload, in bytes
1548  * @return Overhead, in bytes, caused by encryption
1549  **/
1550 
1552  size_t payloadLen)
1553 {
1554  size_t n;
1555 
1556  //Initialize variable
1557  n = 0;
1558 
1559  //Message authentication?
1560  if(encryptionEngine->hashAlgo != NULL)
1561  n += encryptionEngine->hashAlgo->digestSize;
1562 
1563  //Check cipher mode
1564  if(encryptionEngine->cipherMode == CIPHER_MODE_CBC)
1565  {
1566  //TLS 1.1 and 1.2 use an explicit IV
1567  if(encryptionEngine->version >= TLS_VERSION_1_1)
1568  {
1569  n += encryptionEngine->recordIvLen;
1570  }
1571 
1572  //Padding is added to force the length of the plaintext to be an integral
1573  //multiple of the cipher's block length
1574  n += encryptionEngine->cipherAlgo->blockSize -
1575  ((payloadLen + n) % encryptionEngine->cipherAlgo->blockSize);
1576  }
1577  else if(encryptionEngine->cipherMode == CIPHER_MODE_CCM ||
1578  encryptionEngine->cipherMode == CIPHER_MODE_GCM)
1579  {
1580  //Consider the explicit nonce and the authentication tag
1581  n += encryptionEngine->recordIvLen + encryptionEngine->authTagLen;
1582  }
1583  else if(encryptionEngine->cipherMode == CIPHER_MODE_CHACHA20_POLY1305)
1584  {
1585  //Consider the authentication tag only
1586  n += encryptionEngine->authTagLen;
1587  }
1588  else
1589  {
1590  //Stream ciphers do not cause any overhead
1591  }
1592 
1593  //Return the total overhead caused by encryption
1594  return n;
1595 }
1596 
1597 
1598 /**
1599  * @brief DNS hostname verification
1600  * @param[in] name Pointer to the hostname
1601  * @param[in] length Length of the hostname
1602  * @return The function returns TRUE is the name is a valid DNS hostname
1603  **/
1604 
1606 {
1607  size_t i;
1608  bool_t valid;
1609 
1610  //Initialize flag
1611  valid = TRUE;
1612 
1613  //Loop through the hostname
1614  for(i = 0; i < length && valid; i++)
1615  {
1616  //DNS hostnames must start with a letter, end with a letter or
1617  //digit, and have as interior characters only letters, digits,
1618  //and hyphen (refer to RFC 1034, section 3.5)
1619  if(name[i] == '-' || name[i] == '.')
1620  {
1621  //Valid character
1622  }
1623  else if(name[i] >= '0' && name[i] <= '9')
1624  {
1625  //Valid character
1626  }
1627  else if(name[i] >= 'A' && name[i] <= 'Z')
1628  {
1629  //Valid character
1630  }
1631  else if(name[i] >= 'a' && name[i] <= 'z')
1632  {
1633  //Valid character
1634  }
1635  else if(name[i] == '_')
1636  {
1637  //In practice, DNS allows underscores to be used in hostnames
1638  }
1639  else
1640  {
1641  //Invalid character
1642  valid = FALSE;
1643  }
1644  }
1645 
1646  //Return TRUE is the name is a valid DNS hostname
1647  return valid;
1648 }
1649 
1650 #endif
@ TLS_GROUP_BRAINPOOLP512R1_TLS13
Definition: tls.h:1481
#define TLS_MAX_RECORD_LENGTH
Definition: tls.h:977
#define tlsAllocMem(size)
Definition: tls.h:888
size_t ticketLen
Length of the session ticket.
Definition: tls.h:2204
TLS helper functions.
@ TLS_ALERT_DECODE_ERROR
Definition: tls.h:1144
const uint8_t tls11DowngradeRandom[8]
Definition: tls13_misc.c:53
@ TLS_ALERT_UNEXPECTED_MESSAGE
Definition: tls.h:1129
@ TLS_GROUP_BRAINPOOLP256R1_TLS13
Definition: tls.h:1479
#define SHA256_HASH_ALGO
Definition: sha256.h:49
int bool_t
Definition: compiler_port.h:61
@ TLS_GROUP_SECP160R2
Definition: tls.h:1465
TLS cipher suites.
uint16_t cipherSuite
Cipher suite identifier.
Definition: tls.h:2001
error_t tlsSaveSessionTicket(const TlsContext *context, TlsSessionState *session)
Save session ticket.
Definition: tls_misc.c:504
@ TLS_ALERT_CERTIFICATE_REQUIRED
Definition: tls.h:1161
#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:1193
@ CIPHER_MODE_CBC
Definition: crypto.h:1036
@ 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:1141
@ ERROR_VERSION_NOT_SUPPORTED
Definition: error.h:67
uint8_t * ticket
Session ticket.
Definition: tls.h:2203
@ 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:1260
@ 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:2197
@ TLS_ALERT_UNSUPPORTED_EXTENSION
Definition: tls.h:1155
@ ERROR_UNEXPECTED_MESSAGE
Definition: error.h:195
TlsState
TLS FSM states.
Definition: tls.h:1537
OID (Object Identifier)
uint8_t p
Definition: ndp.h:300
@ CIPHER_MODE_GCM
Definition: crypto.h:1041
@ TLS_ALERT_RECORD_OVERFLOW
Definition: tls.h:1132
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:1011
systime_t timestamp
Time stamp to manage entry lifetime.
Definition: tls.h:2196
@ TLS_GROUP_SECP256K1
Definition: tls.h:1470
#define TRUE
Definition: os_port.h:50
uint8_t data[]
Definition: ethernet.h:224
@ TLS_GROUP_SECP256R1
Definition: tls.h:1471
@ TLS_GROUP_CURVE_SM2
Definition: tls.h:1489
size_t digestSize
Definition: crypto.h:1130
@ TLS_GROUP_SECP224K1
Definition: tls.h:1468
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:2171
const uint8_t SECP160K1_OID[5]
Definition: ec_curves.c:54
@ TLS_HASH_ALGO_SHA1
Definition: tls.h:1262
size_t sessionIdLen
Length of the session identifier.
Definition: tls.h:2200
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:969
TlsHashAlgo
Hash algorithms.
Definition: tls.h:1259
@ 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:1145
@ ERROR_INVALID_VERSION
Definition: error.h:118
@ TLS_GROUP_BRAINPOOLP256R1
Definition: tls.h:1474
const uint8_t SECP256R1_OID[8]
Definition: ec_curves.c:70
@ TLS_GROUP_X448
Definition: tls.h:1478
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:1263
CipherAlgoInit init
Definition: crypto.h:1169
@ TLS_ALERT_UNKNOWN_CA
Definition: tls.h:1142
const uint8_t SECP521R1_OID[5]
Definition: ec_curves.c:74
TlsEncryptionLevel
Encryption level.
Definition: tls.h:1579
@ TLS_HASH_ALGO_SHA512
Definition: tls.h:1266
uint16_t cipherSuite
Cipher suite identifier.
Definition: tls.h:2195
#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:524
#define osMemcpy(dest, src, length)
Definition: os_port.h:144
@ ERROR_UNSUPPORTED_EXTENSION
Definition: error.h:246
@ TLS_HASH_ALGO_SM3
Definition: tls.h:1268
#define TlsContext
Definition: tls.h:36
error_t
Error codes.
Definition: error.h:43
@ TLS_ALERT_BAD_RECORD_MAC
Definition: tls.h:1130
@ TLS_CONNECTION_END_SERVER
Definition: tls.h:1013
void tlsFreeEncryptionEngine(TlsEncryptionEngine *encryptionEngine)
Release encryption engine.
Definition: tls_misc.c:928
#define TLS_VERSION_1_2
Definition: tls.h:96
@ TLS_GROUP_NONE
Definition: tls.h:1448
@ 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:714
@ TLS_ALERT_UNSUPPORTED_CERTIFICATE
Definition: tls.h:1137
bool_t tlsCheckDnsHostname(const char_t *name, size_t length)
DNS hostname verification.
Definition: tls_misc.c:1605
@ 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:1265
@ TLS_GROUP_SECP384R1
Definition: tls.h:1472
@ TLS_GROUP_SECP192K1
Definition: tls.h:1466
@ ERROR_BAD_CERTIFICATE
Definition: error.h:236
@ TLS_ALERT_MISSING_EXTENSION
Definition: tls.h:1154
@ TLS_TRANSPORT_PROTOCOL_EAP
Definition: tls.h:1002
@ TLS_HASH_ALGO_SHA256
Definition: tls.h:1264
#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:811
size_t tlsComputeEncryptionOverhead(TlsEncryptionEngine *encryptionEngine, size_t payloadLen)
Compute overhead caused by encryption.
Definition: tls_misc.c:1551
TlsNamedGroup tlsGetNamedCurve(const uint8_t *oid, size_t length)
Get the named curve that matches the specified OID.
Definition: tls_misc.c:1414
uint8_t length
Definition: tcp.h:375
@ CIPHER_MODE_STREAM
Definition: crypto.h:1034
@ TLS_GROUP_BRAINPOOLP512R1
Definition: tls.h:1476
@ TLS_GROUP_SECP160K1
Definition: tls.h:1463
#define MIN(a, b)
Definition: os_port.h:63
@ TLS_GROUP_SECP521R1
Definition: tls.h:1473
@ TLS_GROUP_SECP192R1
Definition: tls.h:1467
@ TLS_ALERT_PROTOCOL_VERSION
Definition: tls.h:1148
@ TLS_GROUP_SECP160R1
Definition: tls.h:1464
const uint8_t SECP192R1_OID[8]
Definition: ec_curves.c:62
#define TLS_MASTER_SECRET_SIZE
Definition: tls.h:836
@ TLS_GROUP_BRAINPOOLP384R1_TLS13
Definition: tls.h:1480
@ TLS_HASH_ALGO_MD5
Definition: tls.h:1261
const uint8_t SECP384R1_OID[5]
Definition: ec_curves.c:72
uint8_t secret[TLS_MASTER_SECRET_SIZE]
Master secret.
Definition: tls.h:2002
uint8_t random[32]
Definition: tls.h:1889
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:2214
error_t tlsWriteEcPoint(const EcPublicKey *publicKey, uint8_t *data, size_t *length)
Encode an EC point to an opaque vector.
Definition: tls_misc.c:1045
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:1469
GCM context.
Definition: gcm.h:64
#define TLS_VERSION_1_1
Definition: tls.h:95
@ CIPHER_MODE_CCM
Definition: crypto.h:1040
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:1003
@ TLS_ALERT_BAD_CERTIFICATE
Definition: tls.h:1136
size_t contextSize
Definition: crypto.h:1166
@ TLS_ALERT_INAPPROPRIATE_FALLBACK
Definition: tls.h:1151
#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:1118
TLS session state.
Definition: tls.h:2193
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:2199
@ ERROR_INAPPROPRIATE_FALLBACK
Definition: error.h:247
#define TLS_VERSION_1_0
Definition: tls.h:94
@ TLS_ALERT_CERTIFICATE_EXPIRED
Definition: tls.h:1139
const TlsCipherSuiteInfo tlsSupportedCipherSuites[]
@ TLS_STATE_INIT
Definition: tls.h:1538
@ ERROR_CERTIFICATE_EXPIRED
Definition: error.h:239
@ TLS_ALERT_NO_APPLICATION_PROTOCOL
Definition: tls.h:1162
@ TLS_CONNECTION_END_CLIENT
Definition: tls.h:1012
Common interface for encryption algorithms.
Definition: crypto.h:1164
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:1084
uint16_t version
TLS protocol version.
Definition: tls.h:2194
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:1477
const uint8_t SECP160R2_OID[5]
Definition: ec_curves.c:58
@ TLS_TRANSPORT_PROTOCOL_STREAM
Definition: tls.h:999
@ 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:1124
FFDHE key exchange.
#define EcCurve
Definition: ec.h:346
@ CIPHER_MODE_NULL
Definition: crypto.h:1033
@ CIPHER_MODE_CHACHA20_POLY1305
Definition: crypto.h:1043
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:1132
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:1447
@ 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:893
@ TLS_ALERT_HANDSHAKE_FAILURE
Definition: tls.h:1134
@ 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:1150
@ 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:2201
@ 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:1602
@ TLS_GROUP_BRAINPOOLP384R1
Definition: tls.h:1475
__weak_func error_t tlsInitEncryptionEngine(TlsContext *context, TlsEncryptionEngine *encryptionEngine, TlsConnectionEnd entity, TlsEncryptionLevel level, const uint8_t *secret)
Initialize encryption engine.
Definition: tls_misc.c:675
@ TLS_ALERT_CERTIFICATE_UNKNOWN
Definition: tls.h:1140
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:216
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:1570