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.0
29  **/
30 
31 //Switch to the appropriate trace level
32 #define TRACE_LEVEL TLS_TRACE_LEVEL
33 
34 //Dependencies
35 #include "tls.h"
36 #include "tls_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  cipherSuite = NULL;
374  }
375 
376  //Acceptable cipher suite?
377  if(cipherSuite != NULL)
378  {
379  //Check whether the cipher suite can be negotiated with the negotiated
380  //protocol version
381  if(!tlsIsCipherSuiteAcceptable(cipherSuite, context->version,
382  context->version, context->transportProtocol))
383  {
384  cipherSuite = NULL;
385  }
386  }
387 
388  //Ensure that the selected cipher suite matches all the criteria
389  if(cipherSuite != NULL)
390  {
391  //Save the negotiated cipher suite
392  context->cipherSuite = *cipherSuite;
393  //Set the key exchange method to be used
394  context->keyExchMethod = cipherSuite->keyExchMethod;
395 
396  //PRF with the SHA-256 is used for all cipher suites published prior
397  //than TLS 1.2 when TLS 1.2 is negotiated
398  if(context->cipherSuite.prfHashAlgo == NULL)
399  {
400  context->cipherSuite.prfHashAlgo = SHA256_HASH_ALGO;
401  }
402 
403  //The length of the verify data depends on the TLS version currently used
404  if(context->version <= TLS_VERSION_1_1)
405  {
406  //Verify data is always 12-byte long for TLS 1.0 and 1.1
407  context->cipherSuite.verifyDataLen = 12;
408  }
409  else
410  {
411  //The length of the verify data depends on the cipher suite for TLS 1.2
412  }
413 
414  //The specified cipher suite is acceptable
415  error = NO_ERROR;
416  }
417 
418  //Return status code
419  return error;
420 }
421 
422 
423 /**
424  * @brief Save session ID
425  * @param[in] context Pointer to the TLS context
426  * @param[out] session Pointer to the session state
427  * @return Error code
428  **/
429 
431  TlsSessionState *session)
432 {
433 #if (TLS_MAX_VERSION >= TLS_VERSION_1_0 && TLS_MIN_VERSION <= TLS_VERSION_1_2)
434  //Check TLS version
435  if(context->version < TLS_VERSION_1_0 || context->version > TLS_VERSION_1_2)
436  return ERROR_INVALID_VERSION;
437 
438  //Invalid session identifier?
439  if(context->sessionIdLen == 0)
440  return ERROR_INVALID_TICKET;
441 
442  //Invalid session parameters?
443  if(context->cipherSuite.identifier == 0)
444  return ERROR_INVALID_SESSION;
445 
446  //Save current time
447  session->timestamp = osGetSystemTime();
448 
449  //Save session parameters
450  session->version = context->version;
451  session->cipherSuite = context->cipherSuite.identifier;
452 
453  //Copy session identifier
454  osMemcpy(session->sessionId, context->sessionId, context->sessionIdLen);
455  session->sessionIdLen = context->sessionIdLen;
456 
457  //Save master secret
458  osMemcpy(session->secret, context->masterSecret, TLS_MASTER_SECRET_SIZE);
459 
460 #if (TLS_EXT_MASTER_SECRET_SUPPORT == ENABLED)
461  //Extended master secret computation
462  session->extendedMasterSecret = context->emsExtReceived;
463 #endif
464 
465 #if (TLS_SNI_SUPPORT == ENABLED)
466  //Any ServerName extension received by the server?
467  if(context->entity == TLS_CONNECTION_END_SERVER &&
468  context->serverName != NULL)
469  {
470  size_t n;
471 
472  //Retrieve the length of the server name
473  n = osStrlen(context->serverName);
474 
475  //Allocate a memory block to hold the server name
476  session->serverName = tlsAllocMem(n + 1);
477  //Failed to allocate memory?
478  if(session->serverName == NULL)
479  return ERROR_OUT_OF_MEMORY;
480 
481  //Copy the server name
482  osStrcpy(session->serverName, context->serverName);
483  }
484 #endif
485 
486  //Successful processing
487  return NO_ERROR;
488 #else
489  //Not implemented
490  return ERROR_NOT_IMPLEMENTED;
491 #endif
492 }
493 
494 
495 /**
496  * @brief Save session ticket
497  * @param[in] context Pointer to the TLS context
498  * @param[out] session Pointer to the session state
499  * @return Error code
500  **/
501 
503  TlsSessionState *session)
504 {
505 #if (TLS_MAX_VERSION >= TLS_VERSION_1_0 && TLS_MIN_VERSION <= TLS_VERSION_1_2)
506  //Check TLS version
507  if(context->version < TLS_VERSION_1_0 || context->version > TLS_VERSION_1_2)
508  return ERROR_INVALID_VERSION;
509 
510  //Invalid session ticket?
511  if(context->ticket == NULL || context->ticketLen == 0)
512  return ERROR_INVALID_TICKET;
513 
514  //Invalid session parameters?
515  if(context->cipherSuite.identifier == 0)
516  return ERROR_INVALID_SESSION;
517 
518  //Save session parameters
519  session->version = context->version;
520  session->cipherSuite = context->cipherSuite.identifier;
521 
522  //Allocate a memory block to hold the ticket
523  session->ticket = tlsAllocMem(context->ticketLen);
524  //Failed to allocate memory?
525  if(session->ticket == NULL)
526  return ERROR_OUT_OF_MEMORY;
527 
528  //Copy session ticket
529  osMemcpy(session->ticket, context->ticket, context->ticketLen);
530  session->ticketLen = context->ticketLen;
531 
532  //Save master secret
533  osMemcpy(session->secret, context->masterSecret, TLS_MASTER_SECRET_SIZE);
534 
535 #if (TLS_EXT_MASTER_SECRET_SUPPORT == ENABLED)
536  //Extended master secret computation
537  session->extendedMasterSecret = context->emsExtReceived;
538 #endif
539 
540  //Successful processing
541  return NO_ERROR;
542 #else
543  //Not implemented
544  return ERROR_NOT_IMPLEMENTED;
545 #endif
546 }
547 
548 
549 /**
550  * @brief Restore a TLS session using session ID
551  * @param[in] context Pointer to the TLS context
552  * @param[in] session Pointer to the session state
553  * @return Error code
554  **/
555 
557  const TlsSessionState *session)
558 {
559 #if (TLS_MAX_VERSION >= TLS_VERSION_1_0 && TLS_MIN_VERSION <= TLS_VERSION_1_2)
560  //Check TLS version
561  if(session->version < TLS_VERSION_1_0 || session->version > TLS_VERSION_1_2)
562  return ERROR_INVALID_VERSION;
563 
564  //Invalid session identifier?
565  if(session->sessionIdLen == 0)
566  return ERROR_INVALID_SESSION;
567 
568  //Invalid session parameters?
569  if(session->cipherSuite == 0)
570  return ERROR_INVALID_SESSION;
571 
572  //Restore session parameters
573  context->version = session->version;
574  context->cipherSuite.identifier = session->cipherSuite;
575  context->sessionIdLen = 0;
576 
577  //Copy session identifier
578  osMemcpy(context->sessionId, session->sessionId, session->sessionIdLen);
579  context->sessionIdLen = session->sessionIdLen;
580 
581  //Restore master secret
582  osMemcpy(context->masterSecret, session->secret, TLS_MASTER_SECRET_SIZE);
583 
584 #if (TLS_EXT_MASTER_SECRET_SUPPORT == ENABLED)
585  //Extended master secret computation
586  context->emsExtReceived = session->extendedMasterSecret;
587 #endif
588 
589  //Successful processing
590  return NO_ERROR;
591 #else
592  //Not implemented
593  return ERROR_NOT_IMPLEMENTED;
594 #endif
595 }
596 
597 
598 /**
599  * @brief Restore a TLS session using session ticket
600  * @param[in] context Pointer to the TLS context
601  * @param[in] session Pointer to the session state
602  * @return Error code
603  **/
604 
606  const TlsSessionState *session)
607 {
608 #if (TLS_MAX_VERSION >= TLS_VERSION_1_0 && TLS_MIN_VERSION <= TLS_VERSION_1_2)
609  //Check TLS version
610  if(session->version < TLS_VERSION_1_0 || session->version > TLS_VERSION_1_2)
611  return ERROR_INVALID_VERSION;
612 
613  //Invalid session ticket?
614  if(session->ticket == NULL || session->ticketLen == 0)
615  return ERROR_INVALID_TICKET;
616 
617  //Invalid session parameters?
618  if(session->cipherSuite == 0)
619  return ERROR_INVALID_SESSION;
620 
621  //Restore session parameters
622  context->version = session->version;
623  context->cipherSuite.identifier = session->cipherSuite;
624  context->sessionIdLen = 0;
625 
626  //Release existing session ticket, if any
627  if(context->ticket != NULL)
628  {
629  osMemset(context->ticket, 0, context->ticketLen);
630  tlsFreeMem(context->ticket);
631  context->ticket = NULL;
632  context->ticketLen = 0;
633  }
634 
635  //Allocate a memory block to hold the ticket
636  context->ticket = tlsAllocMem(session->ticketLen);
637  //Failed to allocate memory?
638  if(context->ticket == NULL)
639  return ERROR_OUT_OF_MEMORY;
640 
641  //Copy session ticket
642  osMemcpy(context->ticket, session->ticket, session->ticketLen);
643  context->ticketLen = session->ticketLen;
644 
645  //Restore master secret
646  osMemcpy(context->masterSecret, session->secret, TLS_MASTER_SECRET_SIZE);
647 
648 #if (TLS_EXT_MASTER_SECRET_SUPPORT == ENABLED)
649  //Extended master secret computation
650  context->emsExtReceived = session->extendedMasterSecret;
651 #endif
652 
653  //Successful processing
654  return NO_ERROR;
655 #else
656  //Not implemented
657  return ERROR_NOT_IMPLEMENTED;
658 #endif
659 }
660 
661 
662 /**
663  * @brief Initialize encryption engine
664  * @param[in] context Pointer to the TLS context
665  * @param[in] encryptionEngine Pointer to the encryption/decryption engine to
666  * be initialized
667  * @param[in] entity Specifies whether client or server write keys shall be used
668  * @param[in] secret Pointer to the secret value
669  * @return Error code
670  **/
671 
673  TlsEncryptionEngine *encryptionEngine, TlsConnectionEnd entity,
674  const uint8_t *secret)
675 {
676  error_t error;
677  const CipherAlgo *cipherAlgo;
679 
680  //Point to the negotiated cipher suite
681  cipherSuite = &context->cipherSuite;
682  //Point to the cipher algorithm
683  cipherAlgo = cipherSuite->cipherAlgo;
684 
685  //Save the negotiated TLS version
686  encryptionEngine->version = context->version;
687 
688  //The sequence number is set to zero at the beginning of a connection
689  //and whenever the key is changed
690  osMemset(&encryptionEngine->seqNum, 0, sizeof(TlsSequenceNumber));
691 
692 #if (DTLS_SUPPORT == ENABLED)
693  //The epoch number is initially zero and is incremented each time a
694  //ChangeCipherSpec message is sent
695  encryptionEngine->epoch++;
696 
697  //Sequence numbers are maintained separately for each epoch, with each
698  //sequence number initially being 0 for each epoch
699  osMemset(&encryptionEngine->dtlsSeqNum, 0, sizeof(DtlsSequenceNumber));
700 #endif
701 
702 #if (TLS_RECORD_SIZE_LIMIT_SUPPORT == ENABLED)
703  //The value of RecordSizeLimit is used to limit the size of records
704  //that are created when encoding application data and the protected
705  //handshake message into records (refer to RFC 8449, section 4)
706  if(entity == context->entity)
707  {
708  encryptionEngine->recordSizeLimit = context->recordSizeLimit;
709  }
710  else
711  {
712  encryptionEngine->recordSizeLimit = MIN(context->rxBufferMaxLen,
714  }
715 #endif
716 
717 #if (TLS_ENCRYPT_THEN_MAC_SUPPORT == ENABLED)
718  //If an upgrade from MAC-then-encrypt to encrypt-then-MAC is negotiated,
719  //then the change will take place in the first message that follows the
720  //ChangeCipherSpec message (refer to RFC 7366, section 3.1)
721  encryptionEngine->encryptThenMac = context->etmExtReceived;
722 #endif
723 
724  //Set appropriate length for MAC key, encryption key, authentication
725  //tag and IV
726  encryptionEngine->macKeyLen = cipherSuite->macKeyLen;
727  encryptionEngine->encKeyLen = cipherSuite->encKeyLen;
728  encryptionEngine->fixedIvLen = cipherSuite->fixedIvLen;
729  encryptionEngine->recordIvLen = cipherSuite->recordIvLen;
730  encryptionEngine->authTagLen = cipherSuite->authTagLen;
731 
732  //Set cipher and hash algorithms
733  encryptionEngine->cipherAlgo = cipherSuite->cipherAlgo;
734  encryptionEngine->cipherMode = cipherSuite->cipherMode;
735  encryptionEngine->hashAlgo = cipherSuite->hashAlgo;
736 
737  //Initialize cipher context
738  encryptionEngine->cipherContext = NULL;
739 
740 #if (TLS_MAX_VERSION >= TLS_VERSION_1_0 && TLS_MIN_VERSION <= TLS_VERSION_1_2)
741  //Initialize HMAC context
742  encryptionEngine->hmacContext = &context->hmacContext;
743 #endif
744 
745 #if (TLS_GCM_CIPHER_SUPPORT == ENABLED)
746  //Initialize GCM context
747  encryptionEngine->gcmContext = NULL;
748 #endif
749 
750 #if (TLS_MAX_VERSION >= TLS_VERSION_1_0 && TLS_MIN_VERSION <= TLS_VERSION_1_2)
751  //TLS 1.0, TLS 1.1 or TLS 1.2 currently selected?
752  if(context->version <= TLS_VERSION_1_2)
753  {
754  const uint8_t *p;
755 
756  //Check whether client or server write keys shall be used
757  if(entity == TLS_CONNECTION_END_CLIENT)
758  {
759  //Point to the key material
760  p = context->keyBlock;
761  //Save MAC key
762  osMemcpy(encryptionEngine->macKey, p, cipherSuite->macKeyLen);
763 
764  //Advance current position in the key block
765  p += 2 * cipherSuite->macKeyLen;
766  //Save encryption key
767  osMemcpy(encryptionEngine->encKey, p, cipherSuite->encKeyLen);
768 
769  //Advance current position in the key block
770  p += 2 * cipherSuite->encKeyLen;
771  //Save initialization vector
772  osMemcpy(encryptionEngine->iv, p, cipherSuite->fixedIvLen);
773  }
774  else
775  {
776  //Point to the key material
777  p = context->keyBlock + cipherSuite->macKeyLen;
778  //Save MAC key
779  osMemcpy(encryptionEngine->macKey, p, cipherSuite->macKeyLen);
780 
781  //Advance current position in the key block
782  p += cipherSuite->macKeyLen + cipherSuite->encKeyLen;
783  //Save encryption key
784  osMemcpy(encryptionEngine->encKey, p, cipherSuite->encKeyLen);
785 
786  //Advance current position in the key block
787  p += cipherSuite->encKeyLen + cipherSuite->fixedIvLen;
788  //Save initialization vector
789  osMemcpy(encryptionEngine->iv, p, cipherSuite->fixedIvLen);
790  }
791 
792  //Successful processing
793  error = NO_ERROR;
794  }
795  else
796 #endif
797 #if (TLS_MAX_VERSION >= TLS_VERSION_1_3 && TLS_MIN_VERSION <= TLS_VERSION_1_3)
798  //TLS 1.3 currently selected?
799  if(context->version == TLS_VERSION_1_3)
800  {
801  const HashAlgo *hashAlgo;
802 
803  //The hash function used by HKDF is the cipher suite hash algorithm
804  hashAlgo = cipherSuite->prfHashAlgo;
805 
806  //Make sure the hash algorithm is valid
807  if(hashAlgo != NULL)
808  {
809  //Calculate the write key
810  error = tls13HkdfExpandLabel(context->transportProtocol, hashAlgo,
811  secret, hashAlgo->digestSize, "key", NULL, 0,
812  encryptionEngine->encKey, cipherSuite->encKeyLen);
813 
814  //Debug message
815  TRACE_DEBUG("Write Key:\r\n");
816  TRACE_DEBUG_ARRAY(" ", encryptionEngine->encKey, cipherSuite->encKeyLen);
817 
818  //Check status code
819  if(!error)
820  {
821  //Calculate the write IV
822  error = tls13HkdfExpandLabel(context->transportProtocol, hashAlgo,
823  secret, hashAlgo->digestSize, "iv", NULL, 0,
824  encryptionEngine->iv, cipherSuite->fixedIvLen);
825  }
826 
827  //Debug message
828  TRACE_DEBUG("Write IV:\r\n");
829  TRACE_DEBUG_ARRAY(" ", encryptionEngine->iv, cipherSuite->fixedIvLen);
830  }
831  else
832  {
833  //Invalid HKDF hash algorithm
834  error = ERROR_FAILURE;
835  }
836  }
837  else
838 #endif
839  //Invalid TLS version?
840  {
841  //Report an error
842  error = ERROR_INVALID_VERSION;
843  }
844 
845  //Check status code
846  if(!error)
847  {
848  //Check cipher mode of operation
849  if(encryptionEngine->cipherMode == CIPHER_MODE_STREAM ||
850  encryptionEngine->cipherMode == CIPHER_MODE_CBC ||
851  encryptionEngine->cipherMode == CIPHER_MODE_CCM ||
852  encryptionEngine->cipherMode == CIPHER_MODE_GCM)
853  {
854  //Allocate encryption context
855  encryptionEngine->cipherContext = tlsAllocMem(cipherAlgo->contextSize);
856 
857  //Successful memory allocation?
858  if(encryptionEngine->cipherContext != NULL)
859  {
860  //Configure the encryption engine with the write key
861  error = cipherAlgo->init(encryptionEngine->cipherContext,
862  encryptionEngine->encKey, cipherSuite->encKeyLen);
863  }
864  else
865  {
866  //Failed to allocate memory
867  error = ERROR_OUT_OF_MEMORY;
868  }
869  }
870  else if(encryptionEngine->cipherMode == CIPHER_MODE_NULL ||
871  encryptionEngine->cipherMode == CIPHER_MODE_CHACHA20_POLY1305)
872  {
873  //No need to allocate an encryption context
874  error = NO_ERROR;
875  }
876  else
877  {
878  //Unsupported mode of operation
879  error = ERROR_FAILURE;
880  }
881  }
882 
883 #if (TLS_GCM_CIPHER_SUPPORT == ENABLED)
884  //Check status code
885  if(!error)
886  {
887  //GCM cipher mode?
888  if(encryptionEngine->cipherMode == CIPHER_MODE_GCM)
889  {
890  //Allocate a memory buffer to hold the GCM context
891  encryptionEngine->gcmContext = tlsAllocMem(sizeof(GcmContext));
892 
893  //Successful memory allocation?
894  if(encryptionEngine->gcmContext != NULL)
895  {
896  //Initialize GCM context
897  error = gcmInit(encryptionEngine->gcmContext, cipherAlgo,
898  encryptionEngine->cipherContext);
899  }
900  else
901  {
902  //Failed to allocate memory
903  error = ERROR_OUT_OF_MEMORY;
904  }
905  }
906  }
907 #endif
908 
909  //Return status code
910  return error;
911 }
912 
913 
914 /**
915  * @brief Release encryption engine
916  * @param[in] encryptionEngine Pointer to the encryption/decryption engine
917  **/
918 
920 {
921  //Valid cipher context?
922  if(encryptionEngine->cipherContext != NULL)
923  {
924  //Erase cipher context
925  encryptionEngine->cipherAlgo->deinit(encryptionEngine->cipherContext);
926 
927  //Release memory
928  tlsFreeMem(encryptionEngine->cipherContext);
929  encryptionEngine->cipherContext = NULL;
930  }
931 
932 #if (TLS_GCM_CIPHER_SUPPORT == ENABLED)
933  //Valid GCM context?
934  if(encryptionEngine->gcmContext != NULL)
935  {
936  //Erase GCM context
937  osMemset(encryptionEngine->gcmContext, 0, sizeof(GcmContext));
938 
939  //Release memory
940  tlsFreeMem(encryptionEngine->gcmContext);
941  encryptionEngine->gcmContext = NULL;
942  }
943 #endif
944 
945  //Reset encryption parameters
946  encryptionEngine->cipherAlgo = NULL;
947  encryptionEngine->cipherMode = CIPHER_MODE_NULL;
948  encryptionEngine->hashAlgo = NULL;
949 }
950 
951 
952 /**
953  * @brief Encode a multiple precision integer to an opaque vector
954  * @param[in] a Pointer to a multiple precision integer
955  * @param[out] data Buffer where to store the opaque vector
956  * @param[out] length Total number of bytes that have been written
957  * @return Error code
958  **/
959 
960 error_t tlsWriteMpi(const Mpi *a, uint8_t *data, size_t *length)
961 {
962  error_t error;
963  size_t n;
964 
965  //Retrieve the actual size of the integer
966  n = mpiGetByteLength(a);
967 
968  //The data is preceded by a 2-byte length field
969  STORE16BE(n, data);
970 
971  //Convert the integer to an octet string
972  error = mpiExport(a, data + 2, n, MPI_FORMAT_BIG_ENDIAN);
973  //Conversion failed?
974  if(error)
975  return error;
976 
977  //Return the total number of bytes that have been written
978  *length = n + 2;
979 
980  //Successful processing
981  return NO_ERROR;
982 }
983 
984 
985 /**
986  * @brief Read a multiple precision integer from an opaque vector
987  * @param[out] a Resulting multiple precision integer
988  * @param[in] data Buffer where to read the opaque vector
989  * @param[in] size Total number of bytes available in the buffer
990  * @param[out] length Total number of bytes that have been read
991  * @return Error code
992  **/
993 
994 error_t tlsReadMpi(Mpi *a, const uint8_t *data, size_t size, size_t *length)
995 {
996  error_t error;
997  size_t n;
998 
999  //Buffer underrun?
1000  if(size < 2)
1001  return ERROR_DECODING_FAILED;
1002 
1003  //Decode the length field
1004  n = LOAD16BE(data);
1005 
1006  //Invalid length?
1007  if(n < 1)
1008  return ERROR_DECODING_FAILED;
1009 
1010  //Buffer underrun?
1011  if(size < (n + 2))
1012  return ERROR_DECODING_FAILED;
1013 
1014  //Convert the octet string to a multiple precision integer
1015  error = mpiImport(a, data + 2, n, MPI_FORMAT_BIG_ENDIAN);
1016  //Any error to report?
1017  if(error)
1018  return error;
1019 
1020  //Return the total number of bytes that have been read
1021  *length = n + 2;
1022 
1023  //Successful processing
1024  return NO_ERROR;
1025 }
1026 
1027 
1028 /**
1029  * @brief Encode an EC point to an opaque vector
1030  * @param[in] publicKey EC public key to be encoded
1031  * @param[out] data Buffer where to store the opaque vector
1032  * @param[out] length Total number of bytes that have been written
1033  * @return Error code
1034  **/
1035 
1036 error_t tlsWriteEcPoint(const EcPublicKey *publicKey, uint8_t *data,
1037  size_t *length)
1038 {
1039 #if (TLS_ECDH_ANON_KE_SUPPORT == ENABLED || TLS_ECDHE_RSA_KE_SUPPORT == ENABLED || \
1040  TLS_ECDHE_ECDSA_KE_SUPPORT == ENABLED || TLS_ECDHE_PSK_KE_SUPPORT == ENABLED)
1041  error_t error;
1042 
1043  //Convert the EC point to an octet string
1044  error = ecExportPublicKey(publicKey, data + 1, length,
1046  //Any error to report?
1047  if(error)
1048  return error;
1049 
1050  //Set the length of the opaque vector
1051  data[0] = (uint8_t) (*length);
1052 
1053  //Return the total number of bytes that have been written
1054  *length += 1;
1055 
1056  //Successful processing
1057  return NO_ERROR;
1058 #else
1059  //Not implemented
1060  return ERROR_NOT_IMPLEMENTED;
1061 #endif
1062 }
1063 
1064 
1065 /**
1066  * @brief Read an EC point from an opaque vector
1067  * @param[out] publicKey Resulting EC public key
1068  * @param[in] curve Elliptic curve parameters
1069  * @param[in] data Buffer where to read the opaque vector
1070  * @param[in] size Total number of bytes available in the buffer
1071  * @param[out] length Total number of bytes that have been read
1072  * @return Error code
1073  **/
1074 
1075 error_t tlsReadEcPoint(EcPublicKey *publicKey, const EcCurve *curve,
1076  const uint8_t *data, size_t size, size_t *length)
1077 {
1078 #if (TLS_ECDH_ANON_KE_SUPPORT == ENABLED || TLS_ECDHE_RSA_KE_SUPPORT == ENABLED || \
1079  TLS_ECDHE_ECDSA_KE_SUPPORT == ENABLED || TLS_ECDHE_PSK_KE_SUPPORT == ENABLED)
1080  error_t error;
1081  size_t n;
1082 
1083  //Buffer underrun?
1084  if(size < 1)
1085  return ERROR_DECODING_FAILED;
1086 
1087  //The EC point representation is preceded by a length field
1088  n = data[0];
1089 
1090  //Invalid EC point representation?
1091  if(n == 0)
1092  return ERROR_DECODING_FAILED;
1093 
1094  //Buffer underrun?
1095  if(size < (n + 1))
1096  return ERROR_DECODING_FAILED;
1097 
1098  //Convert the octet string to an EC point
1099  error = ecImportPublicKey(publicKey, curve, data + 1, n,
1101  //Any error to report?
1102  if(error)
1103  return error;
1104 
1105  //Return the total number of bytes that have been read
1106  *length = n + 1;
1107 
1108  //Successful processing
1109  return NO_ERROR;
1110 #else
1111  //Not implemented
1112  return ERROR_NOT_IMPLEMENTED;
1113 #endif
1114 }
1115 
1116 
1117 /**
1118  * @brief Convert TLS version to string representation
1119  * @param[in] version Version number
1120  * @return String representation
1121  **/
1122 
1124 {
1125  const char_t *s;
1126 
1127  //TLS versions
1128  static const char_t *const label[] =
1129  {
1130  "SSL 3.0",
1131  "TLS 1.0",
1132  "TLS 1.1",
1133  "TLS 1.2",
1134  "TLS 1.3",
1135  "DTLS 1.0",
1136  "DTLS 1.2",
1137  "DTLS 1.3",
1138  "Unknown"
1139  };
1140 
1141  //Check current version
1142  switch(version)
1143  {
1144  case SSL_VERSION_3_0:
1145  s = label[0];
1146  break;
1147  case TLS_VERSION_1_0:
1148  s = label[1];
1149  break;
1150  case TLS_VERSION_1_1:
1151  s = label[2];
1152  break;
1153  case TLS_VERSION_1_2:
1154  s = label[3];
1155  break;
1156  case TLS_VERSION_1_3:
1157  s = label[4];
1158  break;
1159  case DTLS_VERSION_1_0:
1160  s = label[5];
1161  break;
1162  case DTLS_VERSION_1_2:
1163  s = label[6];
1164  break;
1165  case DTLS_VERSION_1_3:
1166  s = label[7];
1167  break;
1168  default:
1169  s = label[8];
1170  break;
1171  }
1172 
1173  //Return the string representation
1174  return s;
1175 }
1176 
1177 
1178 /**
1179  * @brief Get the hash algorithm that matches the specified identifier
1180  * @param[in] hashAlgoId Hash algorithm identifier
1181  * @return Pointer to the hash algorithm
1182  **/
1183 
1185 {
1186  const HashAlgo *hashAlgo;
1187 
1188  //Check hash algorithm identifier
1189  switch(hashAlgoId)
1190  {
1191 #if (TLS_MD5_SUPPORT == ENABLED)
1192  //MD5 hash identifier?
1193  case TLS_HASH_ALGO_MD5:
1194  hashAlgo = MD5_HASH_ALGO;
1195  break;
1196 #endif
1197 #if (TLS_SHA1_SUPPORT == ENABLED)
1198  //SHA-1 hash identifier?
1199  case TLS_HASH_ALGO_SHA1:
1200  hashAlgo = SHA1_HASH_ALGO;
1201  break;
1202 #endif
1203 #if (TLS_SHA224_SUPPORT == ENABLED)
1204  //SHA-224 hash identifier?
1205  case TLS_HASH_ALGO_SHA224:
1206  hashAlgo = SHA224_HASH_ALGO;
1207  break;
1208 #endif
1209 #if (TLS_SHA256_SUPPORT == ENABLED)
1210  //SHA-256 hash identifier?
1211  case TLS_HASH_ALGO_SHA256:
1212  hashAlgo = SHA256_HASH_ALGO;
1213  break;
1214 #endif
1215 #if (TLS_SHA384_SUPPORT == ENABLED)
1216  //SHA-384 hash identifier?
1217  case TLS_HASH_ALGO_SHA384:
1218  hashAlgo = SHA384_HASH_ALGO;
1219  break;
1220 #endif
1221 #if (TLS_SHA512_SUPPORT == ENABLED)
1222  //SHA-512 hash identifier?
1223  case TLS_HASH_ALGO_SHA512:
1224  hashAlgo = SHA512_HASH_ALGO;
1225  break;
1226 #endif
1227 #if (TLS_SM3_SUPPORT == ENABLED)
1228  //SM3 hash identifier?
1229  case TLS_HASH_ALGO_SM3:
1230  hashAlgo = SM3_HASH_ALGO;
1231  break;
1232 #endif
1233  //Unknown hash identifier?
1234  default:
1235  hashAlgo = NULL;
1236  break;
1237  }
1238 
1239  //Return a pointer to the corresponding hash algorithm
1240  return hashAlgo;
1241 }
1242 
1243 
1244 /**
1245  * @brief Get the EC domain parameters that match the specified named curve
1246  * @param[in] context Pointer to the TLS context
1247  * @param[in] namedCurve Elliptic curve identifier
1248  * @return Elliptic curve parameters
1249  **/
1250 
1251 const EcCurve *tlsGetCurve(TlsContext *context, uint16_t namedCurve)
1252 {
1253  uint_t i;
1254  const EcCurve *curve;
1255 
1256  //Default elliptic curve parameters
1257  curve = NULL;
1258 
1259 #if (TLS_ECDH_SUPPORT == ENABLED)
1260  //Check named curve
1261  switch(namedCurve)
1262  {
1263 #if (TLS_SECP160K1_SUPPORT == ENABLED)
1264  //secp160k1 elliptic curve?
1265  case TLS_GROUP_SECP160K1:
1266  curve = ecGetCurve(SECP160K1_OID, sizeof(SECP160K1_OID));
1267  break;
1268 #endif
1269 #if (TLS_SECP160R1_SUPPORT == ENABLED)
1270  //secp160r1 elliptic curve?
1271  case TLS_GROUP_SECP160R1:
1272  curve = ecGetCurve(SECP160R1_OID, sizeof(SECP160R1_OID));
1273  break;
1274 #endif
1275 #if (TLS_SECP160R2_SUPPORT == ENABLED)
1276  //secp160r2 elliptic curve?
1277  case TLS_GROUP_SECP160R2:
1278  curve = ecGetCurve(SECP160R2_OID, sizeof(SECP160R2_OID));
1279  break;
1280 #endif
1281 #if (TLS_SECP192K1_SUPPORT == ENABLED)
1282  //secp192k1 elliptic curve?
1283  case TLS_GROUP_SECP192K1:
1284  curve = ecGetCurve(SECP192K1_OID, sizeof(SECP192K1_OID));
1285  break;
1286 #endif
1287 #if (TLS_SECP192R1_SUPPORT == ENABLED)
1288  //secp192r1 elliptic curve?
1289  case TLS_GROUP_SECP192R1:
1290  curve = ecGetCurve(SECP192R1_OID, sizeof(SECP192R1_OID));
1291  break;
1292 #endif
1293 #if (TLS_SECP224K1_SUPPORT == ENABLED)
1294  //secp224k1 elliptic curve?
1295  case TLS_GROUP_SECP224K1:
1296  curve = ecGetCurve(SECP224K1_OID, sizeof(SECP224K1_OID));
1297  break;
1298 #endif
1299 #if (TLS_SECP224R1_SUPPORT == ENABLED)
1300  //secp224r1 elliptic curve?
1301  case TLS_GROUP_SECP224R1:
1302  curve = ecGetCurve(SECP224R1_OID, sizeof(SECP224R1_OID));
1303  break;
1304 #endif
1305 #if (TLS_SECP256K1_SUPPORT == ENABLED)
1306  //secp256k1 elliptic curve?
1307  case TLS_GROUP_SECP256K1:
1308  curve = ecGetCurve(SECP256K1_OID, sizeof(SECP256K1_OID));
1309  break;
1310 #endif
1311 #if (TLS_SECP256R1_SUPPORT == ENABLED)
1312  //secp256r1 elliptic curve?
1313  case TLS_GROUP_SECP256R1:
1314  curve = ecGetCurve(SECP256R1_OID, sizeof(SECP256R1_OID));
1315  break;
1316 #endif
1317 #if (TLS_SECP384R1_SUPPORT == ENABLED)
1318  //secp384r1 elliptic curve?
1319  case TLS_GROUP_SECP384R1:
1320  curve = ecGetCurve(SECP384R1_OID, sizeof(SECP384R1_OID));
1321  break;
1322 #endif
1323 #if (TLS_SECP521R1_SUPPORT == ENABLED)
1324  //secp521r1 elliptic curve?
1325  case TLS_GROUP_SECP521R1:
1326  curve = ecGetCurve(SECP521R1_OID, sizeof(SECP521R1_OID));
1327  break;
1328 #endif
1329 #if (TLS_BRAINPOOLP256R1_SUPPORT == ENABLED)
1330  //brainpoolP256r1 elliptic curve?
1334  break;
1335 #endif
1336 #if (TLS_BRAINPOOLP384R1_SUPPORT == ENABLED)
1337  //brainpoolP384r1 elliptic curve?
1341  break;
1342 #endif
1343 #if (TLS_BRAINPOOLP512R1_SUPPORT == ENABLED)
1344  //brainpoolP512r1 elliptic curve?
1348  break;
1349 #endif
1350 #if (TLS_SM2_SUPPORT == ENABLED)
1351  //SM2 elliptic curve?
1352  case TLS_GROUP_CURVE_SM2:
1353  curve = ecGetCurve(SM2_OID, sizeof(SM2_OID));
1354  break;
1355 #endif
1356 #if (TLS_X25519_SUPPORT == ENABLED)
1357  //Curve25519 elliptic curve?
1358  case TLS_GROUP_X25519:
1359  curve = ecGetCurve(X25519_OID, sizeof(X25519_OID));
1360  break;
1361 #endif
1362 #if (TLS_X448_SUPPORT == ENABLED)
1363  //Curve448 elliptic curve?
1364  case TLS_GROUP_X448:
1365  curve = ecGetCurve(X448_OID, sizeof(X448_OID));
1366  break;
1367 #endif
1368  //Unknown elliptic curve identifier?
1369  default:
1370  curve = NULL;
1371  break;
1372  }
1373 #endif
1374 
1375  //Restrict the use of certain elliptic curves
1376  if(context->numSupportedGroups > 0)
1377  {
1378  //Loop through the list of allowed named groups
1379  for(i = 0; i < context->numSupportedGroups; i++)
1380  {
1381  //Compare named groups
1382  if(context->supportedGroups[i] == namedCurve)
1383  break;
1384  }
1385 
1386  //Check whether the use of the elliptic curve is restricted
1387  if(i >= context->numSupportedGroups)
1388  {
1389  curve = NULL;
1390  }
1391  }
1392 
1393  //Return the elliptic curve parameters, if any
1394  return curve;
1395 }
1396 
1397 
1398 /**
1399  * @brief Get the named curve that matches the specified OID
1400  * @param[in] oid Object identifier
1401  * @param[in] length OID length
1402  * @return Named curve
1403  **/
1404 
1405 TlsNamedGroup tlsGetNamedCurve(const uint8_t *oid, size_t length)
1406 {
1407  TlsNamedGroup namedCurve;
1408 
1409  //Default named curve
1410  namedCurve = TLS_GROUP_NONE;
1411 
1412 #if (TLS_ECDSA_SIGN_SUPPORT == ENABLED)
1413  //Invalid parameters?
1414  if(oid == NULL || length == 0)
1415  {
1416  namedCurve = TLS_GROUP_NONE;
1417  }
1418 #if (TLS_SECP160K1_SUPPORT == ENABLED)
1419  //secp160k1 elliptic curve?
1420  else if(OID_COMP(oid, length, SECP160K1_OID) == 0)
1421  {
1422  namedCurve = TLS_GROUP_SECP160K1;
1423  }
1424 #endif
1425 #if (TLS_SECP160R1_SUPPORT == ENABLED)
1426  //secp160r1 elliptic curve?
1427  else if(OID_COMP(oid, length, SECP160R1_OID) == 0)
1428  {
1429  namedCurve = TLS_GROUP_SECP160R1;
1430  }
1431 #endif
1432 #if (TLS_SECP160R2_SUPPORT == ENABLED)
1433  //secp160r2 elliptic curve?
1434  else if(OID_COMP(oid, length, SECP160R2_OID) == 0)
1435  {
1436  namedCurve = TLS_GROUP_SECP160R2;
1437  }
1438 #endif
1439 #if (TLS_SECP192K1_SUPPORT == ENABLED)
1440  //secp192k1 elliptic curve?
1441  else if(OID_COMP(oid, length, SECP192K1_OID) == 0)
1442  {
1443  namedCurve = TLS_GROUP_SECP192K1;
1444  }
1445 #endif
1446 #if (TLS_SECP192R1_SUPPORT == ENABLED)
1447  //secp192r1 elliptic curve?
1448  else if(OID_COMP(oid, length, SECP192R1_OID) == 0)
1449  {
1450  namedCurve = TLS_GROUP_SECP192R1;
1451  }
1452 #endif
1453 #if (TLS_SECP224K1_SUPPORT == ENABLED)
1454  //secp224k1 elliptic curve?
1455  else if(OID_COMP(oid, length, SECP224K1_OID) == 0)
1456  {
1457  namedCurve = TLS_GROUP_SECP224K1;
1458  }
1459 #endif
1460 #if (TLS_SECP224R1_SUPPORT == ENABLED)
1461  //secp224r1 elliptic curve?
1462  else if(OID_COMP(oid, length, SECP224R1_OID) == 0)
1463  {
1464  namedCurve = TLS_GROUP_SECP224R1;
1465  }
1466 #endif
1467 #if (TLS_SECP256K1_SUPPORT == ENABLED)
1468  //secp256k1 elliptic curve?
1469  else if(OID_COMP(oid, length, SECP256K1_OID) == 0)
1470  {
1471  namedCurve = TLS_GROUP_SECP256K1;
1472  }
1473 #endif
1474 #if (TLS_SECP256R1_SUPPORT == ENABLED)
1475  //secp256r1 elliptic curve?
1476  else if(OID_COMP(oid, length, SECP256R1_OID) == 0)
1477  {
1478  namedCurve = TLS_GROUP_SECP256R1;
1479  }
1480 #endif
1481 #if (TLS_SECP384R1_SUPPORT == ENABLED)
1482  //secp384r1 elliptic curve?
1483  else if(OID_COMP(oid, length, SECP384R1_OID) == 0)
1484  {
1485  namedCurve = TLS_GROUP_SECP384R1;
1486  }
1487 #endif
1488 #if (TLS_SECP521R1_SUPPORT == ENABLED)
1489  //secp521r1 elliptic curve?
1490  else if(OID_COMP(oid, length, SECP521R1_OID) == 0)
1491  {
1492  namedCurve = TLS_GROUP_SECP521R1;
1493  }
1494 #endif
1495 #if (TLS_BRAINPOOLP256R1_SUPPORT == ENABLED)
1496  //brainpoolP256r1 elliptic curve?
1497  else if(OID_COMP(oid, length, BRAINPOOLP256R1_OID) == 0)
1498  {
1499  namedCurve = TLS_GROUP_BRAINPOOLP256R1;
1500  }
1501 #endif
1502 #if (TLS_BRAINPOOLP384R1_SUPPORT == ENABLED)
1503  //brainpoolP384r1 elliptic curve?
1504  else if(OID_COMP(oid, length, BRAINPOOLP384R1_OID) == 0)
1505  {
1506  namedCurve = TLS_GROUP_BRAINPOOLP384R1;
1507  }
1508 #endif
1509 #if (TLS_BRAINPOOLP512R1_SUPPORT == ENABLED)
1510  //brainpoolP512r1 elliptic curve?
1511  else if(OID_COMP(oid, length, BRAINPOOLP512R1_OID) == 0)
1512  {
1513  namedCurve = TLS_GROUP_BRAINPOOLP512R1;
1514  }
1515 #endif
1516 #if (TLS_SM2_SUPPORT == ENABLED)
1517  //SM2 elliptic curve?
1518  else if(OID_COMP(oid, length, SM2_OID) == 0)
1519  {
1520  namedCurve = TLS_GROUP_CURVE_SM2;
1521  }
1522 #endif
1523  //Unknown identifier?
1524  else
1525  {
1526  namedCurve = TLS_GROUP_NONE;
1527  }
1528 #endif
1529 
1530  //Return the corresponding named curve
1531  return namedCurve;
1532 }
1533 
1534 
1535 /**
1536  * @brief Compute overhead caused by encryption
1537  * @param[in] encryptionEngine Pointer to the encryption engine
1538  * @param[in] payloadLen Length of the payload, in bytes
1539  * @return Overhead, in bytes, caused by encryption
1540  **/
1541 
1543  size_t payloadLen)
1544 {
1545  size_t n;
1546 
1547  //Initialize variable
1548  n = 0;
1549 
1550  //Message authentication?
1551  if(encryptionEngine->hashAlgo != NULL)
1552  n += encryptionEngine->hashAlgo->digestSize;
1553 
1554  //Check cipher mode
1555  if(encryptionEngine->cipherMode == CIPHER_MODE_CBC)
1556  {
1557  //TLS 1.1 and 1.2 use an explicit IV
1558  if(encryptionEngine->version >= TLS_VERSION_1_1)
1559  {
1560  n += encryptionEngine->recordIvLen;
1561  }
1562 
1563  //Padding is added to force the length of the plaintext to be an integral
1564  //multiple of the cipher's block length
1565  n += encryptionEngine->cipherAlgo->blockSize -
1566  ((payloadLen + n) % encryptionEngine->cipherAlgo->blockSize);
1567  }
1568  else if(encryptionEngine->cipherMode == CIPHER_MODE_CCM ||
1569  encryptionEngine->cipherMode == CIPHER_MODE_GCM)
1570  {
1571  //Consider the explicit nonce and the authentication tag
1572  n += encryptionEngine->recordIvLen + encryptionEngine->authTagLen;
1573  }
1574  else if(encryptionEngine->cipherMode == CIPHER_MODE_CHACHA20_POLY1305)
1575  {
1576  //Consider the authentication tag only
1577  n += encryptionEngine->authTagLen;
1578  }
1579  else
1580  {
1581  //Stream ciphers do not cause any overhead
1582  }
1583 
1584  //Return the total overhead caused by encryption
1585  return n;
1586 }
1587 
1588 
1589 /**
1590  * @brief DNS hostname verification
1591  * @param[in] name Pointer to the hostname
1592  * @param[in] length Length of the hostname
1593  * @return The function returns TRUE is the name is a valid DNS hostname
1594  **/
1595 
1597 {
1598  size_t i;
1599  bool_t valid;
1600 
1601  //Initialize flag
1602  valid = TRUE;
1603 
1604  //Loop through the hostname
1605  for(i = 0; i < length && valid; i++)
1606  {
1607  //DNS hostnames must start with a letter, end with a letter or
1608  //digit, and have as interior characters only letters, digits,
1609  //and hyphen (refer to RFC 1034, section 3.5)
1610  if(name[i] == '-' || name[i] == '.')
1611  {
1612  //Valid character
1613  }
1614  else if(name[i] >= '0' && name[i] <= '9')
1615  {
1616  //Valid character
1617  }
1618  else if(name[i] >= 'A' && name[i] <= 'Z')
1619  {
1620  //Valid character
1621  }
1622  else if(name[i] >= 'a' && name[i] <= 'z')
1623  {
1624  //Valid character
1625  }
1626  else if(name[i] == '_')
1627  {
1628  //In practice, DNS allows underscores to be used in hostnames
1629  }
1630  else
1631  {
1632  //Invalid character
1633  valid = FALSE;
1634  }
1635  }
1636 
1637  //Return TRUE is the name is a valid DNS hostname
1638  return valid;
1639 }
1640 
1641 #endif
@ TLS_GROUP_BRAINPOOLP512R1_TLS13
Definition: tls.h:1437
#define TLS_MAX_RECORD_LENGTH
Definition: tls.h:956
#define tlsAllocMem(size)
Definition: tls.h:867
size_t ticketLen
Length of the session ticket.
Definition: tls.h:2087
TLS helper functions.
@ TLS_ALERT_DECODE_ERROR
Definition: tls.h:1122
const uint8_t tls11DowngradeRandom[8]
Definition: tls13_misc.c:53
@ TLS_ALERT_UNEXPECTED_MESSAGE
Definition: tls.h:1107
@ TLS_GROUP_BRAINPOOLP256R1_TLS13
Definition: tls.h:1435
#define SHA256_HASH_ALGO
Definition: sha256.h:49
int bool_t
Definition: compiler_port.h:61
@ TLS_GROUP_SECP160R2
Definition: tls.h:1421
TLS cipher suites.
uint16_t cipherSuite
Cipher suite identifier.
Definition: tls.h:1921
error_t tlsSaveSessionTicket(const TlsContext *context, TlsSessionState *session)
Save session ticket.
Definition: tls_misc.c:502
@ TLS_ALERT_CERTIFICATE_REQUIRED
Definition: tls.h:1139
#define SHA1_HASH_ALGO
Definition: sha1.h:49
error_t ecImportPublicKey(EcPublicKey *key, const EcCurve *curve, const uint8_t *data, size_t length, EcPublicKeyFormat format)
Import an EC public key.
Definition: ec.c:263
const HashAlgo * tlsGetHashAlgo(TlsHashAlgo hashAlgoId)
Get the hash algorithm that matches the specified identifier.
Definition: tls_misc.c:1184
@ CIPHER_MODE_CBC
Definition: crypto.h:1001
@ 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:1119
@ ERROR_VERSION_NOT_SUPPORTED
Definition: error.h:67
uint8_t * ticket
Session ticket.
Definition: tls.h:2086
@ 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:1251
@ 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:2080
@ TLS_ALERT_UNSUPPORTED_EXTENSION
Definition: tls.h:1133
@ ERROR_UNEXPECTED_MESSAGE
Definition: error.h:195
TlsState
TLS FSM states.
Definition: tls.h:1492
OID (Object Identifier)
uint8_t p
Definition: ndp.h:300
@ CIPHER_MODE_GCM
Definition: crypto.h:1006
@ TLS_ALERT_RECORD_OVERFLOW
Definition: tls.h:1110
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:989
systime_t timestamp
Time stamp to manage entry lifetime.
Definition: tls.h:2079
@ TLS_GROUP_SECP256K1
Definition: tls.h:1426
#define TRUE
Definition: os_port.h:50
uint8_t data[]
Definition: ethernet.h:222
@ TLS_GROUP_SECP256R1
Definition: tls.h:1427
@ TLS_GROUP_CURVE_SM2
Definition: tls.h:1445
size_t digestSize
Definition: crypto.h:1088
@ TLS_GROUP_SECP224K1
Definition: tls.h:1424
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:430
const uint8_t BRAINPOOLP512R1_OID[9]
Definition: ec_curves.c:100
Structure describing a cipher suite.
Definition: tls.h:2054
const uint8_t SECP160K1_OID[5]
Definition: ec_curves.c:54
@ TLS_HASH_ALGO_SHA1
Definition: tls.h:1239
size_t sessionIdLen
Length of the session identifier.
Definition: tls.h:2083
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:960
TlsHashAlgo
Hash algorithms.
Definition: tls.h:1236
@ 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_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:1123
@ ERROR_INVALID_VERSION
Definition: error.h:118
@ TLS_GROUP_BRAINPOOLP256R1
Definition: tls.h:1430
const uint8_t SECP256R1_OID[8]
Definition: ec_curves.c:70
@ TLS_GROUP_X448
Definition: tls.h:1434
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:1240
CipherAlgoInit init
Definition: crypto.h:1109
@ TLS_ALERT_UNKNOWN_CA
Definition: tls.h:1120
const uint8_t SECP521R1_OID[5]
Definition: ec_curves.c:74
@ TLS_HASH_ALGO_SHA512
Definition: tls.h:1243
uint16_t cipherSuite
Cipher suite identifier.
Definition: tls.h:2078
#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:516
#define osMemcpy(dest, src, length)
Definition: os_port.h:144
@ ERROR_UNSUPPORTED_EXTENSION
Definition: error.h:246
@ TLS_HASH_ALGO_SM3
Definition: tls.h:1245
#define TlsContext
Definition: tls.h:36
error_t
Error codes.
Definition: error.h:43
@ TLS_ALERT_BAD_RECORD_MAC
Definition: tls.h:1108
@ TLS_CONNECTION_END_SERVER
Definition: tls.h:991
void tlsFreeEncryptionEngine(TlsEncryptionEngine *encryptionEngine)
Release encryption engine.
Definition: tls_misc.c:919
#define TLS_VERSION_1_2
Definition: tls.h:96
@ TLS_GROUP_NONE
Definition: tls.h:1404
@ 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:1115
bool_t tlsCheckDnsHostname(const char_t *name, size_t length)
DNS hostname verification.
Definition: tls_misc.c:1596
@ 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:1242
@ TLS_GROUP_SECP384R1
Definition: tls.h:1428
@ TLS_GROUP_SECP192K1
Definition: tls.h:1422
@ ERROR_BAD_CERTIFICATE
Definition: error.h:236
@ TLS_ALERT_MISSING_EXTENSION
Definition: tls.h:1132
@ TLS_TRANSPORT_PROTOCOL_EAP
Definition: tls.h:980
@ TLS_HASH_ALGO_SHA256
Definition: tls.h:1241
#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:1542
TlsNamedGroup tlsGetNamedCurve(const uint8_t *oid, size_t length)
Get the named curve that matches the specified OID.
Definition: tls_misc.c:1405
uint8_t length
Definition: tcp.h:375
@ CIPHER_MODE_STREAM
Definition: crypto.h:999
@ TLS_GROUP_BRAINPOOLP512R1
Definition: tls.h:1432
@ TLS_GROUP_SECP160K1
Definition: tls.h:1419
#define MIN(a, b)
Definition: os_port.h:63
@ TLS_GROUP_SECP521R1
Definition: tls.h:1429
@ TLS_GROUP_SECP192R1
Definition: tls.h:1423
@ TLS_ALERT_PROTOCOL_VERSION
Definition: tls.h:1126
@ TLS_GROUP_SECP160R1
Definition: tls.h:1420
const uint8_t SECP192R1_OID[8]
Definition: ec_curves.c:62
error_t ecExportPublicKey(const EcPublicKey *key, uint8_t *data, size_t *length, EcPublicKeyFormat format)
Export an EC public key.
Definition: ec.c:378
#define TLS_MASTER_SECRET_SIZE
Definition: tls.h:815
@ TLS_GROUP_BRAINPOOLP384R1_TLS13
Definition: tls.h:1436
@ TLS_HASH_ALGO_MD5
Definition: tls.h:1238
const uint8_t SECP384R1_OID[5]
Definition: ec_curves.c:72
uint8_t secret[TLS_MASTER_SECRET_SIZE]
Master secret.
Definition: tls.h:1922
uint8_t random[32]
Definition: tls.h:1809
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:556
char_t * serverName
ServerName extension.
Definition: tls.h:2097
error_t tlsWriteEcPoint(const EcPublicKey *publicKey, uint8_t *data, size_t *length)
Encode an EC point to an opaque vector.
Definition: tls_misc.c:1036
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:1425
GCM context.
Definition: gcm.h:64
#define TLS_VERSION_1_1
Definition: tls.h:95
@ CIPHER_MODE_CCM
Definition: crypto.h:1005
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:994
@ TLS_ALERT_BAD_CERTIFICATE
Definition: tls.h:1114
size_t contextSize
Definition: crypto.h:1106
@ TLS_ALERT_INAPPROPRIATE_FALLBACK
Definition: tls.h:1129
#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:1096
TLS session state.
Definition: tls.h:2076
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:2082
@ ERROR_INAPPROPRIATE_FALLBACK
Definition: error.h:247
#define TLS_VERSION_1_0
Definition: tls.h:94
@ TLS_ALERT_CERTIFICATE_EXPIRED
Definition: tls.h:1117
const TlsCipherSuiteInfo tlsSupportedCipherSuites[]
@ TLS_STATE_INIT
Definition: tls.h:1493
@ ERROR_CERTIFICATE_EXPIRED
Definition: error.h:239
@ TLS_ALERT_NO_APPLICATION_PROTOCOL
Definition: tls.h:1140
@ TLS_CONNECTION_END_CLIENT
Definition: tls.h:990
Common interface for encryption algorithms.
Definition: crypto.h:1104
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:1075
uint16_t version
TLS protocol version.
Definition: tls.h:2077
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:1433
const uint8_t SECP160R2_OID[5]
Definition: ec_curves.c:58
@ TLS_TRANSPORT_PROTOCOL_STREAM
Definition: tls.h:978
@ 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:1082
__weak_func error_t tlsInitEncryptionEngine(TlsContext *context, TlsEncryptionEngine *encryptionEngine, TlsConnectionEnd entity, const uint8_t *secret)
Initialize encryption engine.
Definition: tls_misc.c:672
FFDHE key exchange.
#define EcCurve
Definition: ec.h:346
@ CIPHER_MODE_NULL
Definition: crypto.h:998
@ CIPHER_MODE_CHACHA20_POLY1305
Definition: crypto.h:1008
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:1123
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:1403
@ 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:872
@ TLS_ALERT_HANDSHAKE_FAILURE
Definition: tls.h:1112
@ 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:1128
@ 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:2084
@ 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:1544
@ TLS_GROUP_BRAINPOOLP384R1
Definition: tls.h:1431
@ TLS_ALERT_CERTIFICATE_UNKNOWN
Definition: tls.h:1118
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:605
@ TLS_STATE_CLOSED
Definition: tls.h:1525