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-2026 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.6.2
29  **/
30 
31 //Switch to the appropriate trace level
32 #define TRACE_LEVEL TLS_TRACE_LEVEL
33 
34 //Dependencies
35 #include "tls/tls.h"
36 #include "tls/tls_cipher_suites.h"
37 #include "tls/tls_common.h"
38 #include "tls/tls_ffdhe.h"
39 #include "tls/tls_misc.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  {
244  //If negotiating TLS 1.2, TLS 1.3 servers must set the last eight
245  //bytes of their random value to the bytes 44 4F 57 4E 47 52 44 01
247  }
248  else
249  {
250  //No downgrade protection mechanism
251  }
252  }
253  }
254 #endif
255 
256  //Return status code
257  return error;
258 }
259 
260 
261 /**
262  * @brief Generate a random session identifier
263  * @param[in] context Pointer to the TLS context
264  * @param[out] length Desired length of the session ID
265  * @return Error code
266  **/
267 
269 {
270  error_t error;
271 
272  //Verify that the pseudorandom number generator is properly configured
273  if(context->prngAlgo != NULL && context->prngContext != NULL)
274  {
275  //Generate a random value using a cryptographically-safe pseudorandom
276  //number generator
277  error = context->prngAlgo->generate(context->prngContext,
278  context->sessionId, length);
279 
280  //Check status code
281  if(!error)
282  {
283  //Save the length of the session identifier
284  context->sessionIdLen = length;
285  }
286  }
287  else
288  {
289  //Report an error
290  error = ERROR_NOT_CONFIGURED;
291  }
292 
293  //Return status code
294  return error;
295 }
296 
297 
298 /**
299  * @brief Set the TLS version to be used
300  * @param[in] context Pointer to the TLS context
301  * @param[in] version TLS version
302  * @return Error code
303  **/
304 
306 {
307  error_t error;
308 
309  //Initialize status code
311 
312  //Check TLS version
313  if(version >= context->versionMin && version <= context->versionMax)
314  {
315  //Save the TLS protocol version to be used
316  context->version = version;
317  //The specified TLS version is acceptable
318  error = NO_ERROR;
319  }
320 
321  //Return status code
322  return error;
323 }
324 
325 
326 /**
327  * @brief Set cipher suite
328  * @param[in] context Pointer to the TLS context
329  * @param[in] identifier Cipher suite identifier
330  * @return Error code
331  **/
332 
334 {
335  error_t error;
336  uint_t i;
337  uint_t n;
339 
340  //Initialize status code
341  error = ERROR_HANDSHAKE_FAILED;
342 
343  //Determine the number of supported cipher suites
345 
346  //Loop through the list of supported cipher suites
347  for(cipherSuite = NULL, i = 0; i < n; i++)
348  {
349  //Compare cipher suite identifiers
351  {
352  //The cipher suite is supported
354  break;
355  }
356  }
357 
358  //Restrict the use of certain cipher suites
359  if(context->numCipherSuites > 0)
360  {
361  //Loop through the list of allowed cipher suites
362  for(i = 0; i < context->numCipherSuites; i++)
363  {
364  //Compare cipher suite identifiers
365  if(context->cipherSuites[i] == identifier)
366  break;
367  }
368 
369  //Check whether the use of the cipher suite is restricted
370  if(i >= context->numCipherSuites)
371  {
372  cipherSuite = NULL;
373  }
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] level Encryption level
669  * @param[in] secret Pointer to the secret value
670  * @return Error code
671  **/
672 
674  TlsEncryptionEngine *encryptionEngine, TlsConnectionEnd entity,
675  TlsEncryptionLevel level, const uint8_t *secret)
676 {
677  error_t error;
678  const CipherAlgo *cipherAlgo;
680 
681  //Point to the negotiated cipher suite
682  cipherSuite = &context->cipherSuite;
683  //Point to the cipher algorithm
684  cipherAlgo = cipherSuite->cipherAlgo;
685 
686  //Operational state of the encryption engine
687  encryptionEngine->active = FALSE;
688 
689  //Save the negotiated TLS version
690  encryptionEngine->version = context->version;
691 
692  //The sequence number is set to zero at the beginning of a connection
693  //and whenever the key is changed
694  osMemset(&encryptionEngine->seqNum, 0, sizeof(TlsSequenceNumber));
695 
696 #if (DTLS_SUPPORT == ENABLED)
697  //DTLS 1.3 protocol?
698  if(context->transportProtocol == TLS_TRANSPORT_PROTOCOL_DATAGRAM &&
699  context->version == TLS_VERSION_1_3)
700  {
701  //This version of DTLS assigns dedicated epoch values to messages in the
702  //protocol exchange to allow identification of the correct cipher state
703  //(refer to RFC 9147, section 6.1)
704  if(encryptionEngine->epoch == 0 &&
706  {
707  //Epoch value 1 is used for messages protected using keys derived from
708  //client_early_traffic_secret
709  encryptionEngine->epoch = 1;
710  }
711  else if(encryptionEngine->epoch == 0 &&
713  {
714  //Epoch value 2 is used for messages protected using keys derived from
715  //client_handshake_traffic_secret or server_handshake_traffic_secret
716  encryptionEngine->epoch = 2;
717  }
718  else
719  {
720  //The epoch number is incremented each time keying material changes
721  encryptionEngine->epoch++;
722  }
723  }
724  else
725  {
726  //The epoch number is initially zero and is incremented each time a
727  //ChangeCipherSpec message is sent
728  encryptionEngine->epoch++;
729  }
730 
731  //Implementations must not allow the epoch to wrap (refer to RFC 6347,
732  //section 4.1)
733  if(encryptionEngine->epoch == 0)
734  return ERROR_FAILURE;
735 
736  //Sequence numbers are maintained separately for each epoch, with each
737  //sequence number initially being 0 for each epoch
738  osMemset(&encryptionEngine->dtlsSeqNum, 0, sizeof(DtlsSequenceNumber));
739 #endif
740 
741 #if (TLS_QUIC_SUPPORT == ENABLED)
742  //TLS encryption level determines the QUIC packet type and keys that are
743  //used for protecting data (refer to RFC 9001, section 4.1.3)
744  encryptionEngine->level = level;
745 #endif
746 
747 #if (TLS_RECORD_SIZE_LIMIT_SUPPORT == ENABLED)
748  //The value of RecordSizeLimit is used to limit the size of records
749  //that are created when encoding application data and the protected
750  //handshake message into records (refer to RFC 8449, section 4)
751  if(entity == context->entity)
752  {
753  encryptionEngine->recordSizeLimit = context->recordSizeLimit;
754  }
755  else
756  {
757  encryptionEngine->recordSizeLimit = MIN(context->rxBufferMaxLen,
759  }
760 #endif
761 
762 #if (TLS_ENCRYPT_THEN_MAC_SUPPORT == ENABLED)
763  //If an upgrade from MAC-then-encrypt to encrypt-then-MAC is negotiated,
764  //then the change will take place in the first message that follows the
765  //ChangeCipherSpec message (refer to RFC 7366, section 3.1)
766  encryptionEngine->encryptThenMac = context->etmExtReceived;
767 #endif
768 
769  //Set appropriate length for MAC key, encryption key, authentication
770  //tag and IV
771  encryptionEngine->macKeyLen = cipherSuite->macKeyLen;
772  encryptionEngine->encKeyLen = cipherSuite->encKeyLen;
773  encryptionEngine->fixedIvLen = cipherSuite->fixedIvLen;
774  encryptionEngine->recordIvLen = cipherSuite->recordIvLen;
775  encryptionEngine->authTagLen = cipherSuite->authTagLen;
776 
777  //Set cipher and hash algorithms
778  encryptionEngine->cipherAlgo = cipherSuite->cipherAlgo;
779  encryptionEngine->cipherMode = cipherSuite->cipherMode;
780  encryptionEngine->hashAlgo = cipherSuite->hashAlgo;
781 
782  //Initialize cipher context
783  encryptionEngine->cipherContext = NULL;
784 
785 #if (TLS_MAX_VERSION >= TLS_VERSION_1_0 && TLS_MIN_VERSION <= TLS_VERSION_1_2)
786  //Initialize HMAC context
787  encryptionEngine->hmacContext = &context->hmacContext;
788 #endif
789 
790 #if (TLS_GCM_CIPHER_SUPPORT == ENABLED)
791  //Initialize GCM context
792  encryptionEngine->gcmContext = NULL;
793 #endif
794 
795 #if (DTLS_SUPPORT == ENABLED && TLS_MAX_VERSION >= TLS_VERSION_1_3)
796  //Initialize sequence number encryption context
797  encryptionEngine->snCipherContext = NULL;
798 #endif
799 
800 #if (TLS_MAX_VERSION >= TLS_VERSION_1_0 && TLS_MIN_VERSION <= TLS_VERSION_1_2)
801  //TLS 1.0, TLS 1.1 or TLS 1.2 currently selected?
802  if(context->version <= TLS_VERSION_1_2)
803  {
804  const uint8_t *p;
805 
806  //Check whether client or server write keys shall be used
807  if(entity == TLS_CONNECTION_END_CLIENT)
808  {
809  //Point to the key material
810  p = context->keyBlock;
811  //Save MAC key
812  osMemcpy(encryptionEngine->macKey, p, cipherSuite->macKeyLen);
813 
814  //Advance current position in the key block
815  p += 2 * cipherSuite->macKeyLen;
816  //Save encryption key
817  osMemcpy(encryptionEngine->encKey, p, cipherSuite->encKeyLen);
818 
819  //Advance current position in the key block
820  p += 2 * cipherSuite->encKeyLen;
821  //Save initialization vector
822  osMemcpy(encryptionEngine->iv, p, cipherSuite->fixedIvLen);
823  }
824  else
825  {
826  //Point to the key material
827  p = context->keyBlock + cipherSuite->macKeyLen;
828  //Save MAC key
829  osMemcpy(encryptionEngine->macKey, p, cipherSuite->macKeyLen);
830 
831  //Advance current position in the key block
832  p += cipherSuite->macKeyLen + cipherSuite->encKeyLen;
833  //Save encryption key
834  osMemcpy(encryptionEngine->encKey, p, cipherSuite->encKeyLen);
835 
836  //Advance current position in the key block
837  p += cipherSuite->encKeyLen + cipherSuite->fixedIvLen;
838  //Save initialization vector
839  osMemcpy(encryptionEngine->iv, p, cipherSuite->fixedIvLen);
840  }
841 
842  //Successful processing
843  error = NO_ERROR;
844  }
845  else
846 #endif
847 #if (TLS_MAX_VERSION >= TLS_VERSION_1_3 && TLS_MIN_VERSION <= TLS_VERSION_1_3)
848  //TLS 1.3 currently selected?
849  if(context->version == TLS_VERSION_1_3)
850  {
851  const HashAlgo *hashAlgo;
852 
853  //The hash function used by HKDF is the cipher suite hash algorithm
854  hashAlgo = cipherSuite->prfHashAlgo;
855 
856  //Make sure the hash algorithm is valid
857  if(hashAlgo != NULL)
858  {
859  //Calculate the write key
860  error = tls13HkdfExpandLabel(context->transportProtocol, hashAlgo,
861  secret, hashAlgo->digestSize, "key", NULL, 0,
862  encryptionEngine->encKey, cipherSuite->encKeyLen);
863 
864  //Check status code
865  if(!error)
866  {
867  //Debug message
868  TRACE_DEBUG("Write Key:\r\n");
869  TRACE_DEBUG_ARRAY(" ", encryptionEngine->encKey, cipherSuite->encKeyLen);
870 
871  //Calculate the write IV
872  error = tls13HkdfExpandLabel(context->transportProtocol, hashAlgo,
873  secret, hashAlgo->digestSize, "iv", NULL, 0,
874  encryptionEngine->iv, cipherSuite->fixedIvLen);
875  }
876 
877  //Check status code
878  if(!error)
879  {
880  //Debug message
881  TRACE_DEBUG("Write IV:\r\n");
882  TRACE_DEBUG_ARRAY(" ", encryptionEngine->iv, cipherSuite->fixedIvLen);
883  }
884  }
885  else
886  {
887  //Invalid HKDF hash algorithm
888  error = ERROR_FAILURE;
889  }
890  }
891  else
892 #endif
893  //Invalid TLS version?
894  {
895  //Report an error
896  error = ERROR_INVALID_VERSION;
897  }
898 
899  //Check status code
900  if(!error)
901  {
902  //Check cipher mode of operation
903  if(encryptionEngine->cipherMode == CIPHER_MODE_STREAM ||
904  encryptionEngine->cipherMode == CIPHER_MODE_CBC ||
905  encryptionEngine->cipherMode == CIPHER_MODE_CCM ||
906  encryptionEngine->cipherMode == CIPHER_MODE_GCM)
907  {
908  //Allocate encryption context
909  encryptionEngine->cipherContext = tlsAllocMem(cipherAlgo->contextSize);
910 
911  //Successful memory allocation?
912  if(encryptionEngine->cipherContext != NULL)
913  {
914  //Configure the encryption engine with the write key
915  error = cipherAlgo->init(encryptionEngine->cipherContext,
916  encryptionEngine->encKey, cipherSuite->encKeyLen);
917  }
918  else
919  {
920  //Failed to allocate memory
921  error = ERROR_OUT_OF_MEMORY;
922  }
923  }
924  }
925 
926 #if (TLS_GCM_CIPHER_SUPPORT == ENABLED)
927  //Check status code
928  if(!error)
929  {
930  //GCM cipher mode?
931  if(encryptionEngine->cipherMode == CIPHER_MODE_GCM)
932  {
933  //Allocate a memory buffer to hold the GCM context
934  encryptionEngine->gcmContext = tlsAllocMem(sizeof(GcmContext));
935 
936  //Successful memory allocation?
937  if(encryptionEngine->gcmContext != NULL)
938  {
939  //Initialize GCM context
940  error = gcmInit(encryptionEngine->gcmContext, cipherAlgo,
941  encryptionEngine->cipherContext);
942  }
943  else
944  {
945  //Failed to allocate memory
946  error = ERROR_OUT_OF_MEMORY;
947  }
948  }
949  }
950 #endif
951 
952 #if (DTLS_SUPPORT == ENABLED && TLS_MAX_VERSION >= TLS_VERSION_1_3)
953  //DTLS 1.3 protocol?
954  if(context->transportProtocol == TLS_TRANSPORT_PROTOCOL_DATAGRAM &&
955  context->version == TLS_VERSION_1_3)
956  {
957  //Check status code
958  if(!error)
959  {
960  //Check cipher mode of operation
961  if(encryptionEngine->cipherMode == CIPHER_MODE_CCM ||
962  encryptionEngine->cipherMode == CIPHER_MODE_GCM ||
963  encryptionEngine->cipherMode == CIPHER_MODE_CHACHA20_POLY1305)
964  {
965  const HashAlgo *hashAlgo;
966 
967  //The hash function used by HKDF is the cipher suite hash algorithm
968  hashAlgo = cipherSuite->prfHashAlgo;
969 
970  //Make sure the hash algorithm is valid
971  if(hashAlgo != NULL)
972  {
973  //Calculate the sequence number encryption key (refer to
974  //RFC 9147, section 4.2.3)
975  error = tls13HkdfExpandLabel(context->transportProtocol,
976  hashAlgo, secret, hashAlgo->digestSize, "sn", NULL, 0,
977  encryptionEngine->snKey, encryptionEngine->encKeyLen);
978 
979  //Check status code
980  if(!error)
981  {
982  //Debug message
983  TRACE_DEBUG("SN Key:\r\n");
984  TRACE_DEBUG_ARRAY(" ", encryptionEngine->snKey, encryptionEngine->encKeyLen);
985  }
986  }
987  else
988  {
989  //Invalid HKDF hash algorithm
990  error = ERROR_FAILURE;
991  }
992  }
993  }
994 
995  //Check status code
996  if(!error)
997  {
998  //Check cipher mode of operation
999  if(encryptionEngine->cipherMode == CIPHER_MODE_CCM ||
1000  encryptionEngine->cipherMode == CIPHER_MODE_GCM)
1001  {
1002  //Allocate encryption context
1003  encryptionEngine->snCipherContext = tlsAllocMem(
1004  cipherAlgo->contextSize);
1005 
1006  //Successful memory allocation?
1007  if(encryptionEngine->snCipherContext != NULL)
1008  {
1009  //Configure the encryption engine with the sequence number
1010  //encryption key
1011  error = cipherAlgo->init(encryptionEngine->snCipherContext,
1012  encryptionEngine->snKey, cipherSuite->encKeyLen);
1013  }
1014  else
1015  {
1016  //Failed to allocate memory
1017  error = ERROR_OUT_OF_MEMORY;
1018  }
1019  }
1020  }
1021  }
1022 #endif
1023 
1024  //Check status code
1025  if(!error)
1026  {
1027  //Default lifetime
1028  encryptionEngine->lifetime = 0;
1029  encryptionEngine->timestamp = osGetSystemTime();
1030 
1031  //Operational state of the encryption engine
1032  encryptionEngine->active = TRUE;
1033  }
1034 
1035  //Return status code
1036  return error;
1037 }
1038 
1039 
1040 /**
1041  * @brief Update encryption engine
1042  * @param[in] context Pointer to the TLS context
1043  * @param[in] encryptionEngine Pointer to the encryption/decryption engine to
1044  * be initialized
1045  * @param[in] entity Specifies whether client or server write keys shall be used
1046  * @param[in] level Encryption level
1047  * @param[in] secret Pointer to the secret value
1048  * @return Error code
1049  **/
1050 
1052  TlsEncryptionEngine *encryptionEngine, TlsConnectionEnd entity,
1053  TlsEncryptionLevel level, const uint8_t *secret)
1054 {
1055  error_t error;
1056 
1057  //Initialize status code
1058  error = NO_ERROR;
1059 
1060 #if (DTLS_SUPPORT == ENABLED)
1061  //DTLS protocol?
1062  if(context->transportProtocol == TLS_TRANSPORT_PROTOCOL_DATAGRAM)
1063  {
1064  //Encryption or decryption engine?
1065  if(encryptionEngine == context->encryptionEngine)
1066  {
1067 #if (TLS_MAX_VERSION >= TLS_VERSION_1_3 && TLS_MIN_VERSION <= TLS_VERSION_1_3)
1068  //DTLS 1.3 protocol?
1069  if(context->version == TLS_VERSION_1_3)
1070  {
1071  //Release oldest encryption engine first
1072  tlsFreeEncryptionEngine(&context->encryptionEngine[2]);
1073 
1074  //Save encryption engines for later use
1075  context->encryptionEngine[2] = context->encryptionEngine[1];
1076  context->encryptionEngine[1] = *encryptionEngine;
1077  }
1078  else
1079 #endif
1080  {
1081  //Release previous encryption engine first
1082  tlsFreeEncryptionEngine(&context->encryptionEngine[1]);
1083 
1084  //Save current encryption engine for later use
1085  context->encryptionEngine[1] = *encryptionEngine;
1086  }
1087 
1088  //Reset current encryption engine
1089  osMemset(encryptionEngine, 0, sizeof(TlsEncryptionEngine));
1090  encryptionEngine->epoch = context->encryptionEngine[1].epoch;
1091  }
1092  else if(encryptionEngine == context->decryptionEngine)
1093  {
1094 #if (TLS_MAX_VERSION >= TLS_VERSION_1_3 && TLS_MIN_VERSION <= TLS_VERSION_1_3)
1095  //DTLS 1.3 protocol?
1096  if(context->version == TLS_VERSION_1_3)
1097  {
1098  //Release oldest encryption engine first
1099  tlsFreeEncryptionEngine(&context->decryptionEngine[1]);
1100 
1101  //Save encryption engines for later use
1102  context->decryptionEngine[1] = *encryptionEngine;
1103 
1104  //Reset current encryption engine
1105  osMemset(encryptionEngine, 0, sizeof(TlsEncryptionEngine));
1106  encryptionEngine->epoch = context->decryptionEngine[1].epoch;
1107  }
1108  else
1109 #endif
1110  {
1111  //Release decryption engine
1112  tlsFreeEncryptionEngine(encryptionEngine);
1113  }
1114 
1115  //Initialize sliding window
1116  dtlsInitReplayWindow(encryptionEngine);
1117  }
1118  else
1119  {
1120  //Report an error
1121  error = ERROR_FAILURE;
1122  }
1123  }
1124  else
1125 #endif
1126  //TLS protocol?
1127  {
1128  //Release encryption engine
1129  tlsFreeEncryptionEngine(encryptionEngine);
1130  }
1131 
1132  //Check status code
1133  if(!error)
1134  {
1135  //Re-initialize encryption engine
1136  error = tlsInitEncryptionEngine(context, encryptionEngine, entity, level,
1137  secret);
1138  }
1139 
1140  //Return status code
1141  return error;
1142 }
1143 
1144 
1145 /**
1146  * @brief Release encryption engine
1147  * @param[in] encryptionEngine Pointer to the encryption/decryption engine
1148  **/
1149 
1151 {
1152  //Valid cipher context?
1153  if(encryptionEngine->cipherContext != NULL)
1154  {
1155  //Erase cipher context
1156  encryptionEngine->cipherAlgo->deinit(encryptionEngine->cipherContext);
1157 
1158  //Release memory
1159  tlsFreeMem(encryptionEngine->cipherContext);
1160  encryptionEngine->cipherContext = NULL;
1161  }
1162 
1163 #if (TLS_GCM_CIPHER_SUPPORT == ENABLED)
1164  //Valid GCM context?
1165  if(encryptionEngine->gcmContext != NULL)
1166  {
1167  //Erase GCM context
1168  osMemset(encryptionEngine->gcmContext, 0, sizeof(GcmContext));
1169 
1170  //Release memory
1171  tlsFreeMem(encryptionEngine->gcmContext);
1172  encryptionEngine->gcmContext = NULL;
1173  }
1174 #endif
1175 
1176 #if (DTLS_SUPPORT == ENABLED && TLS_MAX_VERSION >= TLS_VERSION_1_3)
1177  //Valid sequence number encryption context?
1178  if(encryptionEngine->snCipherContext != NULL)
1179  {
1180  //Erase cipher context
1181  encryptionEngine->cipherAlgo->deinit(encryptionEngine->snCipherContext);
1182 
1183  //Release memory
1184  tlsFreeMem(encryptionEngine->snCipherContext);
1185  encryptionEngine->snCipherContext = NULL;
1186  }
1187 #endif
1188 
1189  //Reset encryption parameters
1190  encryptionEngine->cipherAlgo = NULL;
1191  encryptionEngine->cipherMode = CIPHER_MODE_NULL;
1192  encryptionEngine->hashAlgo = NULL;
1193 
1194  //Operational state of the encryption engine
1195  encryptionEngine->active = FALSE;
1196 }
1197 
1198 
1199 /**
1200  * @brief Encode a multiple precision integer to an opaque vector
1201  * @param[in] a Pointer to a multiple precision integer
1202  * @param[out] data Buffer where to store the opaque vector
1203  * @param[out] length Total number of bytes that have been written
1204  * @return Error code
1205  **/
1206 
1207 error_t tlsWriteMpi(const Mpi *a, uint8_t *data, size_t *length)
1208 {
1209  error_t error;
1210  size_t n;
1211 
1212  //Retrieve the actual size of the integer
1213  n = mpiGetByteLength(a);
1214 
1215  //The data is preceded by a 2-byte length field
1216  STORE16BE(n, data);
1217 
1218  //Convert the integer to an octet string
1219  error = mpiExport(a, data + 2, n, MPI_FORMAT_BIG_ENDIAN);
1220  //Conversion failed?
1221  if(error)
1222  return error;
1223 
1224  //Return the total number of bytes that have been written
1225  *length = n + 2;
1226 
1227  //Successful processing
1228  return NO_ERROR;
1229 }
1230 
1231 
1232 /**
1233  * @brief Read a multiple precision integer from an opaque vector
1234  * @param[out] a Resulting multiple precision integer
1235  * @param[in] data Buffer where to read the opaque vector
1236  * @param[in] size Total number of bytes available in the buffer
1237  * @param[out] length Total number of bytes that have been read
1238  * @return Error code
1239  **/
1240 
1241 error_t tlsReadMpi(Mpi *a, const uint8_t *data, size_t size, size_t *length)
1242 {
1243  error_t error;
1244  size_t n;
1245 
1246  //Buffer underrun?
1247  if(size < 2)
1248  return ERROR_DECODING_FAILED;
1249 
1250  //Decode the length field
1251  n = LOAD16BE(data);
1252 
1253  //Invalid length?
1254  if(n < 1)
1255  return ERROR_DECODING_FAILED;
1256 
1257  //Buffer underrun?
1258  if(size < (n + 2))
1259  return ERROR_DECODING_FAILED;
1260 
1261  //Convert the octet string to a multiple precision integer
1262  error = mpiImport(a, data + 2, n, MPI_FORMAT_BIG_ENDIAN);
1263  //Any error to report?
1264  if(error)
1265  return error;
1266 
1267  //Return the total number of bytes that have been read
1268  *length = n + 2;
1269 
1270  //Successful processing
1271  return NO_ERROR;
1272 }
1273 
1274 
1275 /**
1276  * @brief Encode an EC point to an opaque vector
1277  * @param[in] publicKey EC public key to be encoded
1278  * @param[out] data Buffer where to store the opaque vector
1279  * @param[out] length Total number of bytes that have been written
1280  * @return Error code
1281  **/
1282 
1283 error_t tlsWriteEcPoint(const EcPublicKey *publicKey, uint8_t *data,
1284  size_t *length)
1285 {
1286 #if (TLS_ECDH_ANON_KE_SUPPORT == ENABLED || TLS_ECDHE_RSA_KE_SUPPORT == ENABLED || \
1287  TLS_ECDHE_ECDSA_KE_SUPPORT == ENABLED || TLS_ECDHE_PSK_KE_SUPPORT == ENABLED)
1288  error_t error;
1289 
1290  //Convert the EC point to an octet string
1291  error = ecExportPublicKey(publicKey, data + 1, length,
1293  //Any error to report?
1294  if(error)
1295  return error;
1296 
1297  //Set the length of the opaque vector
1298  data[0] = (uint8_t) (*length);
1299 
1300  //Return the total number of bytes that have been written
1301  *length += 1;
1302 
1303  //Successful processing
1304  return NO_ERROR;
1305 #else
1306  //Not implemented
1307  return ERROR_NOT_IMPLEMENTED;
1308 #endif
1309 }
1310 
1311 
1312 /**
1313  * @brief Read an EC point from an opaque vector
1314  * @param[out] publicKey Resulting EC public key
1315  * @param[in] curve Elliptic curve parameters
1316  * @param[in] data Buffer where to read the opaque vector
1317  * @param[in] size Total number of bytes available in the buffer
1318  * @param[out] length Total number of bytes that have been read
1319  * @return Error code
1320  **/
1321 
1322 error_t tlsReadEcPoint(EcPublicKey *publicKey, const EcCurve *curve,
1323  const uint8_t *data, size_t size, size_t *length)
1324 {
1325 #if (TLS_ECDH_ANON_KE_SUPPORT == ENABLED || TLS_ECDHE_RSA_KE_SUPPORT == ENABLED || \
1326  TLS_ECDHE_ECDSA_KE_SUPPORT == ENABLED || TLS_ECDHE_PSK_KE_SUPPORT == ENABLED)
1327  error_t error;
1328  size_t n;
1329 
1330  //Buffer underrun?
1331  if(size < 1)
1332  return ERROR_DECODING_FAILED;
1333 
1334  //The EC point representation is preceded by a length field
1335  n = data[0];
1336 
1337  //Invalid EC point representation?
1338  if(n == 0)
1339  return ERROR_DECODING_FAILED;
1340 
1341  //Buffer underrun?
1342  if(size < (n + 1))
1343  return ERROR_DECODING_FAILED;
1344 
1345  //Convert the octet string to an EC point
1346  error = ecImportPublicKey(publicKey, curve, data + 1, n,
1348  //Any error to report?
1349  if(error)
1350  return error;
1351 
1352  //Return the total number of bytes that have been read
1353  *length = n + 1;
1354 
1355  //Successful processing
1356  return NO_ERROR;
1357 #else
1358  //Not implemented
1359  return ERROR_NOT_IMPLEMENTED;
1360 #endif
1361 }
1362 
1363 
1364 /**
1365  * @brief Convert TLS version to string representation
1366  * @param[in] version Version number
1367  * @return String representation
1368  **/
1369 
1371 {
1372  const char_t *s;
1373 
1374  //TLS versions
1375  static const char_t *const label[] =
1376  {
1377  "SSL 3.0",
1378  "TLS 1.0",
1379  "TLS 1.1",
1380  "TLS 1.2",
1381  "TLS 1.3",
1382  "DTLS 1.0",
1383  "DTLS 1.2",
1384  "DTLS 1.3",
1385  "Unknown"
1386  };
1387 
1388  //Check current version
1389  switch(version)
1390  {
1391  case SSL_VERSION_3_0:
1392  s = label[0];
1393  break;
1394  case TLS_VERSION_1_0:
1395  s = label[1];
1396  break;
1397  case TLS_VERSION_1_1:
1398  s = label[2];
1399  break;
1400  case TLS_VERSION_1_2:
1401  s = label[3];
1402  break;
1403  case TLS_VERSION_1_3:
1404  s = label[4];
1405  break;
1406  case DTLS_VERSION_1_0:
1407  s = label[5];
1408  break;
1409  case DTLS_VERSION_1_2:
1410  s = label[6];
1411  break;
1412  case DTLS_VERSION_1_3:
1413  s = label[7];
1414  break;
1415  default:
1416  s = label[8];
1417  break;
1418  }
1419 
1420  //Return the string representation
1421  return s;
1422 }
1423 
1424 
1425 /**
1426  * @brief Get the hash algorithm that matches the specified identifier
1427  * @param[in] hashAlgoId Hash algorithm identifier
1428  * @return Pointer to the hash algorithm
1429  **/
1430 
1432 {
1433  const HashAlgo *hashAlgo;
1434 
1435  //Check hash algorithm identifier
1436  switch(hashAlgoId)
1437  {
1438 #if (TLS_MD5_SUPPORT == ENABLED)
1439  //MD5 hash identifier?
1440  case TLS_HASH_ALGO_MD5:
1441  hashAlgo = MD5_HASH_ALGO;
1442  break;
1443 #endif
1444 #if (TLS_SHA1_SUPPORT == ENABLED)
1445  //SHA-1 hash identifier?
1446  case TLS_HASH_ALGO_SHA1:
1447  hashAlgo = SHA1_HASH_ALGO;
1448  break;
1449 #endif
1450 #if (TLS_SHA224_SUPPORT == ENABLED)
1451  //SHA-224 hash identifier?
1452  case TLS_HASH_ALGO_SHA224:
1453  hashAlgo = SHA224_HASH_ALGO;
1454  break;
1455 #endif
1456 #if (TLS_SHA256_SUPPORT == ENABLED)
1457  //SHA-256 hash identifier?
1458  case TLS_HASH_ALGO_SHA256:
1459  hashAlgo = SHA256_HASH_ALGO;
1460  break;
1461 #endif
1462 #if (TLS_SHA384_SUPPORT == ENABLED)
1463  //SHA-384 hash identifier?
1464  case TLS_HASH_ALGO_SHA384:
1465  hashAlgo = SHA384_HASH_ALGO;
1466  break;
1467 #endif
1468 #if (TLS_SHA512_SUPPORT == ENABLED)
1469  //SHA-512 hash identifier?
1470  case TLS_HASH_ALGO_SHA512:
1471  hashAlgo = SHA512_HASH_ALGO;
1472  break;
1473 #endif
1474 #if (TLS_SM3_SUPPORT == ENABLED)
1475  //SM3 hash identifier?
1476  case TLS_HASH_ALGO_SM3:
1477  hashAlgo = SM3_HASH_ALGO;
1478  break;
1479 #endif
1480  //Unknown hash identifier?
1481  default:
1482  hashAlgo = NULL;
1483  break;
1484  }
1485 
1486  //Return a pointer to the corresponding hash algorithm
1487  return hashAlgo;
1488 }
1489 
1490 
1491 /**
1492  * @brief Get the EC domain parameters that match the specified named curve
1493  * @param[in] context Pointer to the TLS context
1494  * @param[in] namedCurve Elliptic curve identifier
1495  * @return Elliptic curve parameters
1496  **/
1497 
1498 const EcCurve *tlsGetCurve(TlsContext *context, uint16_t namedCurve)
1499 {
1500  uint_t i;
1501  const EcCurve *curve;
1502 
1503  //Default elliptic curve parameters
1504  curve = NULL;
1505 
1506 #if (TLS_ECDH_SUPPORT == ENABLED)
1507  //Check named curve
1508  switch(namedCurve)
1509  {
1510 #if (TLS_SECP160K1_SUPPORT == ENABLED)
1511  //secp160k1 elliptic curve?
1512  case TLS_GROUP_SECP160K1:
1513  curve = ecGetCurve(SECP160K1_OID, sizeof(SECP160K1_OID));
1514  break;
1515 #endif
1516 #if (TLS_SECP160R1_SUPPORT == ENABLED)
1517  //secp160r1 elliptic curve?
1518  case TLS_GROUP_SECP160R1:
1519  curve = ecGetCurve(SECP160R1_OID, sizeof(SECP160R1_OID));
1520  break;
1521 #endif
1522 #if (TLS_SECP160R2_SUPPORT == ENABLED)
1523  //secp160r2 elliptic curve?
1524  case TLS_GROUP_SECP160R2:
1525  curve = ecGetCurve(SECP160R2_OID, sizeof(SECP160R2_OID));
1526  break;
1527 #endif
1528 #if (TLS_SECP192K1_SUPPORT == ENABLED)
1529  //secp192k1 elliptic curve?
1530  case TLS_GROUP_SECP192K1:
1531  curve = ecGetCurve(SECP192K1_OID, sizeof(SECP192K1_OID));
1532  break;
1533 #endif
1534 #if (TLS_SECP192R1_SUPPORT == ENABLED)
1535  //secp192r1 elliptic curve?
1536  case TLS_GROUP_SECP192R1:
1537  curve = ecGetCurve(SECP192R1_OID, sizeof(SECP192R1_OID));
1538  break;
1539 #endif
1540 #if (TLS_SECP224K1_SUPPORT == ENABLED)
1541  //secp224k1 elliptic curve?
1542  case TLS_GROUP_SECP224K1:
1543  curve = ecGetCurve(SECP224K1_OID, sizeof(SECP224K1_OID));
1544  break;
1545 #endif
1546 #if (TLS_SECP224R1_SUPPORT == ENABLED)
1547  //secp224r1 elliptic curve?
1548  case TLS_GROUP_SECP224R1:
1549  curve = ecGetCurve(SECP224R1_OID, sizeof(SECP224R1_OID));
1550  break;
1551 #endif
1552 #if (TLS_SECP256K1_SUPPORT == ENABLED)
1553  //secp256k1 elliptic curve?
1554  case TLS_GROUP_SECP256K1:
1555  curve = ecGetCurve(SECP256K1_OID, sizeof(SECP256K1_OID));
1556  break;
1557 #endif
1558 #if (TLS_SECP256R1_SUPPORT == ENABLED)
1559  //secp256r1 elliptic curve?
1560  case TLS_GROUP_SECP256R1:
1561  curve = ecGetCurve(SECP256R1_OID, sizeof(SECP256R1_OID));
1562  break;
1563 #endif
1564 #if (TLS_SECP384R1_SUPPORT == ENABLED)
1565  //secp384r1 elliptic curve?
1566  case TLS_GROUP_SECP384R1:
1567  curve = ecGetCurve(SECP384R1_OID, sizeof(SECP384R1_OID));
1568  break;
1569 #endif
1570 #if (TLS_SECP521R1_SUPPORT == ENABLED)
1571  //secp521r1 elliptic curve?
1572  case TLS_GROUP_SECP521R1:
1573  curve = ecGetCurve(SECP521R1_OID, sizeof(SECP521R1_OID));
1574  break;
1575 #endif
1576 #if (TLS_BRAINPOOLP256R1_SUPPORT == ENABLED)
1577  //brainpoolP256r1 elliptic curve?
1581  break;
1582 #endif
1583 #if (TLS_BRAINPOOLP384R1_SUPPORT == ENABLED)
1584  //brainpoolP384r1 elliptic curve?
1588  break;
1589 #endif
1590 #if (TLS_BRAINPOOLP512R1_SUPPORT == ENABLED)
1591  //brainpoolP512r1 elliptic curve?
1595  break;
1596 #endif
1597 #if (TLS_SM2_SUPPORT == ENABLED)
1598  //SM2 elliptic curve?
1599  case TLS_GROUP_CURVE_SM2:
1600  curve = ecGetCurve(SM2_OID, sizeof(SM2_OID));
1601  break;
1602 #endif
1603 #if (TLS_X25519_SUPPORT == ENABLED)
1604  //Curve25519 elliptic curve?
1605  case TLS_GROUP_X25519:
1606  curve = ecGetCurve(X25519_OID, sizeof(X25519_OID));
1607  break;
1608 #endif
1609 #if (TLS_X448_SUPPORT == ENABLED)
1610  //Curve448 elliptic curve?
1611  case TLS_GROUP_X448:
1612  curve = ecGetCurve(X448_OID, sizeof(X448_OID));
1613  break;
1614 #endif
1615  //Unknown elliptic curve identifier?
1616  default:
1617  curve = NULL;
1618  break;
1619  }
1620 #endif
1621 
1622  //Restrict the use of certain elliptic curves
1623  if(context->numSupportedGroups > 0)
1624  {
1625  //Loop through the list of allowed named groups
1626  for(i = 0; i < context->numSupportedGroups; i++)
1627  {
1628  //Compare named groups
1629  if(context->supportedGroups[i] == namedCurve)
1630  break;
1631  }
1632 
1633  //Check whether the use of the elliptic curve is restricted
1634  if(i >= context->numSupportedGroups)
1635  {
1636  curve = NULL;
1637  }
1638  }
1639 
1640  //Return the elliptic curve parameters, if any
1641  return curve;
1642 }
1643 
1644 
1645 /**
1646  * @brief Get the named curve that matches the specified OID
1647  * @param[in] oid Object identifier
1648  * @param[in] length OID length
1649  * @return Named curve
1650  **/
1651 
1652 TlsNamedGroup tlsGetNamedCurve(const uint8_t *oid, size_t length)
1653 {
1654  TlsNamedGroup namedCurve;
1655 
1656  //Default named curve
1657  namedCurve = TLS_GROUP_NONE;
1658 
1659 #if (TLS_ECDSA_SIGN_SUPPORT == ENABLED)
1660  //Invalid parameters?
1661  if(oid == NULL || length == 0)
1662  {
1663  namedCurve = TLS_GROUP_NONE;
1664  }
1665 #if (TLS_SECP160K1_SUPPORT == ENABLED)
1666  //secp160k1 elliptic curve?
1667  else if(OID_COMP(oid, length, SECP160K1_OID) == 0)
1668  {
1669  namedCurve = TLS_GROUP_SECP160K1;
1670  }
1671 #endif
1672 #if (TLS_SECP160R1_SUPPORT == ENABLED)
1673  //secp160r1 elliptic curve?
1674  else if(OID_COMP(oid, length, SECP160R1_OID) == 0)
1675  {
1676  namedCurve = TLS_GROUP_SECP160R1;
1677  }
1678 #endif
1679 #if (TLS_SECP160R2_SUPPORT == ENABLED)
1680  //secp160r2 elliptic curve?
1681  else if(OID_COMP(oid, length, SECP160R2_OID) == 0)
1682  {
1683  namedCurve = TLS_GROUP_SECP160R2;
1684  }
1685 #endif
1686 #if (TLS_SECP192K1_SUPPORT == ENABLED)
1687  //secp192k1 elliptic curve?
1688  else if(OID_COMP(oid, length, SECP192K1_OID) == 0)
1689  {
1690  namedCurve = TLS_GROUP_SECP192K1;
1691  }
1692 #endif
1693 #if (TLS_SECP192R1_SUPPORT == ENABLED)
1694  //secp192r1 elliptic curve?
1695  else if(OID_COMP(oid, length, SECP192R1_OID) == 0)
1696  {
1697  namedCurve = TLS_GROUP_SECP192R1;
1698  }
1699 #endif
1700 #if (TLS_SECP224K1_SUPPORT == ENABLED)
1701  //secp224k1 elliptic curve?
1702  else if(OID_COMP(oid, length, SECP224K1_OID) == 0)
1703  {
1704  namedCurve = TLS_GROUP_SECP224K1;
1705  }
1706 #endif
1707 #if (TLS_SECP224R1_SUPPORT == ENABLED)
1708  //secp224r1 elliptic curve?
1709  else if(OID_COMP(oid, length, SECP224R1_OID) == 0)
1710  {
1711  namedCurve = TLS_GROUP_SECP224R1;
1712  }
1713 #endif
1714 #if (TLS_SECP256K1_SUPPORT == ENABLED)
1715  //secp256k1 elliptic curve?
1716  else if(OID_COMP(oid, length, SECP256K1_OID) == 0)
1717  {
1718  namedCurve = TLS_GROUP_SECP256K1;
1719  }
1720 #endif
1721 #if (TLS_SECP256R1_SUPPORT == ENABLED)
1722  //secp256r1 elliptic curve?
1723  else if(OID_COMP(oid, length, SECP256R1_OID) == 0)
1724  {
1725  namedCurve = TLS_GROUP_SECP256R1;
1726  }
1727 #endif
1728 #if (TLS_SECP384R1_SUPPORT == ENABLED)
1729  //secp384r1 elliptic curve?
1730  else if(OID_COMP(oid, length, SECP384R1_OID) == 0)
1731  {
1732  namedCurve = TLS_GROUP_SECP384R1;
1733  }
1734 #endif
1735 #if (TLS_SECP521R1_SUPPORT == ENABLED)
1736  //secp521r1 elliptic curve?
1737  else if(OID_COMP(oid, length, SECP521R1_OID) == 0)
1738  {
1739  namedCurve = TLS_GROUP_SECP521R1;
1740  }
1741 #endif
1742 #if (TLS_BRAINPOOLP256R1_SUPPORT == ENABLED)
1743  //brainpoolP256r1 elliptic curve?
1744  else if(OID_COMP(oid, length, BRAINPOOLP256R1_OID) == 0)
1745  {
1746  namedCurve = TLS_GROUP_BRAINPOOLP256R1;
1747  }
1748 #endif
1749 #if (TLS_BRAINPOOLP384R1_SUPPORT == ENABLED)
1750  //brainpoolP384r1 elliptic curve?
1751  else if(OID_COMP(oid, length, BRAINPOOLP384R1_OID) == 0)
1752  {
1753  namedCurve = TLS_GROUP_BRAINPOOLP384R1;
1754  }
1755 #endif
1756 #if (TLS_BRAINPOOLP512R1_SUPPORT == ENABLED)
1757  //brainpoolP512r1 elliptic curve?
1758  else if(OID_COMP(oid, length, BRAINPOOLP512R1_OID) == 0)
1759  {
1760  namedCurve = TLS_GROUP_BRAINPOOLP512R1;
1761  }
1762 #endif
1763 #if (TLS_SM2_SUPPORT == ENABLED)
1764  //SM2 elliptic curve?
1765  else if(OID_COMP(oid, length, SM2_OID) == 0)
1766  {
1767  namedCurve = TLS_GROUP_CURVE_SM2;
1768  }
1769 #endif
1770  //Unknown identifier?
1771  else
1772  {
1773  namedCurve = TLS_GROUP_NONE;
1774  }
1775 #endif
1776 
1777  //Return the corresponding named curve
1778  return namedCurve;
1779 }
1780 
1781 
1782 /**
1783  * @brief Compute overhead caused by encryption
1784  * @param[in] encryptionEngine Pointer to the encryption engine
1785  * @param[in] payloadLen Length of the payload, in bytes
1786  * @return Overhead, in bytes, caused by encryption
1787  **/
1788 
1790  size_t payloadLen)
1791 {
1792  size_t n;
1793 
1794  //Initialize variable
1795  n = 0;
1796 
1797  //Message authentication?
1798  if(encryptionEngine->hashAlgo != NULL)
1799  {
1800  n += encryptionEngine->hashAlgo->digestSize;
1801  }
1802 
1803  //Check cipher mode of operation
1804  if(encryptionEngine->cipherMode == CIPHER_MODE_CBC)
1805  {
1806  //TLS 1.1 and 1.2 use an explicit IV
1807  if(encryptionEngine->version >= TLS_VERSION_1_1)
1808  {
1809  n += encryptionEngine->recordIvLen;
1810  }
1811 
1812  //Padding is added to force the length of the plaintext to be an integral
1813  //multiple of the cipher's block length
1814  n += encryptionEngine->cipherAlgo->blockSize -
1815  ((payloadLen + n) % encryptionEngine->cipherAlgo->blockSize);
1816  }
1817  else if(encryptionEngine->cipherMode == CIPHER_MODE_CCM ||
1818  encryptionEngine->cipherMode == CIPHER_MODE_GCM)
1819  {
1820  //Consider the explicit nonce and the authentication tag
1821  n += encryptionEngine->recordIvLen + encryptionEngine->authTagLen;
1822  }
1823  else if(encryptionEngine->cipherMode == CIPHER_MODE_CHACHA20_POLY1305)
1824  {
1825  //Consider the authentication tag only
1826  n += encryptionEngine->authTagLen;
1827  }
1828  else
1829  {
1830  //Stream ciphers do not cause any overhead
1831  }
1832 
1833  //Return the total overhead caused by encryption
1834  return n;
1835 }
1836 
1837 
1838 /**
1839  * @brief DNS hostname verification
1840  * @param[in] name Pointer to the hostname
1841  * @param[in] length Length of the hostname
1842  * @return The function returns TRUE is the name is a valid DNS hostname
1843  **/
1844 
1846 {
1847  size_t i;
1848  bool_t valid;
1849 
1850  //Initialize flag
1851  valid = TRUE;
1852 
1853  //Loop through the hostname
1854  for(i = 0; i < length && valid; i++)
1855  {
1856  //DNS hostnames must start with a letter, end with a letter or
1857  //digit, and have as interior characters only letters, digits,
1858  //and hyphen (refer to RFC 1034, section 3.5)
1859  if(name[i] == '-' || name[i] == '.')
1860  {
1861  //Valid character
1862  }
1863  else if(name[i] >= '0' && name[i] <= '9')
1864  {
1865  //Valid character
1866  }
1867  else if(name[i] >= 'A' && name[i] <= 'Z')
1868  {
1869  //Valid character
1870  }
1871  else if(name[i] >= 'a' && name[i] <= 'z')
1872  {
1873  //Valid character
1874  }
1875  else if(name[i] == '_')
1876  {
1877  //In practice, DNS allows underscores to be used in hostnames
1878  }
1879  else
1880  {
1881  //Invalid character
1882  valid = FALSE;
1883  }
1884  }
1885 
1886  //Return TRUE is the name is a valid DNS hostname
1887  return valid;
1888 }
1889 
1890 #endif
@ TLS_GROUP_BRAINPOOLP512R1_TLS13
Definition: tls.h:1501
#define TLS_MAX_RECORD_LENGTH
Definition: tls.h:994
#define tlsAllocMem(size)
Definition: tls.h:889
size_t ticketLen
Length of the session ticket.
Definition: tls.h:2229
TLS helper functions.
@ TLS_ALERT_DECODE_ERROR
Definition: tls.h:1161
const uint8_t tls11DowngradeRandom[8]
Definition: tls13_misc.c:53
@ TLS_ALERT_UNEXPECTED_MESSAGE
Definition: tls.h:1146
error_t tlsUpdateEncryptionEngine(TlsContext *context, TlsEncryptionEngine *encryptionEngine, TlsConnectionEnd entity, TlsEncryptionLevel level, const uint8_t *secret)
Update encryption engine.
Definition: tls_misc.c:1051
@ TLS_GROUP_BRAINPOOLP256R1_TLS13
Definition: tls.h:1499
#define SHA256_HASH_ALGO
Definition: sha256.h:49
int bool_t
Definition: compiler_port.h:63
@ TLS_GROUP_SECP160R2
Definition: tls.h:1485
TLS cipher suites.
uint16_t cipherSuite
Cipher suite identifier.
Definition: tls.h:2026
error_t tlsSaveSessionTicket(const TlsContext *context, TlsSessionState *session)
Save session ticket.
Definition: tls_misc.c:502
@ TLS_ALERT_CERTIFICATE_REQUIRED
Definition: tls.h:1178
#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:1431
@ CIPHER_MODE_CBC
Definition: crypto.h:1063
@ 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:268
@ TLS_ALERT_ILLEGAL_PARAMETER
Definition: tls.h:1158
@ ERROR_VERSION_NOT_SUPPORTED
Definition: error.h:67
uint8_t * ticket
Session ticket.
Definition: tls.h:2228
@ 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:1498
@ 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:2222
@ TLS_ALERT_UNSUPPORTED_EXTENSION
Definition: tls.h:1172
@ ERROR_UNEXPECTED_MESSAGE
Definition: error.h:195
TlsState
TLS FSM states.
Definition: tls.h:1557
OID (Object Identifier)
uint8_t p
Definition: ndp.h:300
@ CIPHER_MODE_GCM
Definition: crypto.h:1068
@ TLS_ALERT_RECORD_OVERFLOW
Definition: tls.h:1149
error_t tlsSelectVersion(TlsContext *context, uint16_t version)
Set the TLS version to be used.
Definition: tls_misc.c:305
TlsConnectionEnd
TLS connection end.
Definition: tls.h:1028
systime_t timestamp
Time stamp to manage entry lifetime.
Definition: tls.h:2221
@ TLS_GROUP_SECP256K1
Definition: tls.h:1490
#define TRUE
Definition: os_port.h:50
uint8_t data[]
Definition: ethernet.h:224
@ TLS_GROUP_SECP256R1
Definition: tls.h:1491
@ TLS_GROUP_CURVE_SM2
Definition: tls.h:1509
size_t digestSize
Definition: crypto.h:1157
@ TLS_GROUP_SECP224K1
Definition: tls.h:1488
const uint8_t SECP224R1_OID[5]
Definition: ec_curves.c:66
@ TLS_TRANSPORT_PROTOCOL_DATAGRAM
Definition: tls.h:1017
error_t tlsSaveSessionId(const TlsContext *context, TlsSessionState *session)
Save session ID.
Definition: tls_misc.c:430
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:2196
const uint8_t SECP160K1_OID[5]
Definition: ec_curves.c:54
@ TLS_HASH_ALGO_SHA1
Definition: tls.h:1279
size_t sessionIdLen
Length of the session identifier.
Definition: tls.h:2225
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:1207
TlsHashAlgo
Hash algorithms.
Definition: tls.h:1276
@ 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:1162
@ ERROR_INVALID_VERSION
Definition: error.h:118
@ TLS_ENCRYPTION_LEVEL_EARLY_DATA
Definition: tls.h:1606
@ TLS_GROUP_BRAINPOOLP256R1
Definition: tls.h:1494
const uint8_t SECP256R1_OID[8]
Definition: ec_curves.c:70
@ TLS_GROUP_X448
Definition: tls.h:1498
@ TLS_ENCRYPTION_LEVEL_HANDSHAKE
Definition: tls.h:1607
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:1280
CipherAlgoInit init
Definition: crypto.h:1196
@ TLS_ALERT_UNKNOWN_CA
Definition: tls.h:1159
const uint8_t SECP521R1_OID[5]
Definition: ec_curves.c:74
TlsEncryptionLevel
Encryption level.
Definition: tls.h:1604
@ TLS_HASH_ALGO_SHA512
Definition: tls.h:1283
uint16_t cipherSuite
Cipher suite identifier.
Definition: tls.h:2220
#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:509
#define osMemcpy(dest, src, length)
Definition: os_port.h:144
@ ERROR_UNSUPPORTED_EXTENSION
Definition: error.h:246
@ TLS_HASH_ALGO_SM3
Definition: tls.h:1285
#define TlsContext
Definition: tls.h:36
error_t
Error codes.
Definition: error.h:43
@ TLS_ALERT_BAD_RECORD_MAC
Definition: tls.h:1147
@ TLS_CONNECTION_END_SERVER
Definition: tls.h:1030
void tlsFreeEncryptionEngine(TlsEncryptionEngine *encryptionEngine)
Release encryption engine.
Definition: tls_misc.c:1150
#define TLS_VERSION_1_2
Definition: tls.h:97
@ TLS_GROUP_NONE
Definition: tls.h:1468
@ ERROR_FAILURE
Generic error code.
Definition: error.h:45
error_t tlsSelectCipherSuite(TlsContext *context, uint16_t identifier)
Set cipher suite.
Definition: tls_misc.c:333
#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:1154
bool_t tlsCheckDnsHostname(const char_t *name, size_t length)
DNS hostname verification.
Definition: tls_misc.c:1845
@ ERROR_MISSING_EXTENSION
Definition: error.h:245
#define TLS_VERSION_1_3
Definition: tls.h:98
Handshake message processing (TLS client and server)
@ TLS_HASH_ALGO_SHA384
Definition: tls.h:1282
@ TLS_GROUP_SECP384R1
Definition: tls.h:1492
@ TLS_GROUP_SECP192K1
Definition: tls.h:1486
@ ERROR_BAD_CERTIFICATE
Definition: error.h:236
@ TLS_ALERT_MISSING_EXTENSION
Definition: tls.h:1171
@ TLS_HASH_ALGO_SHA256
Definition: tls.h:1281
#define SSL_VERSION_3_0
Definition: tls.h:94
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:1789
TlsNamedGroup tlsGetNamedCurve(const uint8_t *oid, size_t length)
Get the named curve that matches the specified OID.
Definition: tls_misc.c:1652
uint8_t length
Definition: tcp.h:375
@ CIPHER_MODE_STREAM
Definition: crypto.h:1061
@ TLS_GROUP_BRAINPOOLP512R1
Definition: tls.h:1496
@ TLS_GROUP_SECP160K1
Definition: tls.h:1483
#define MIN(a, b)
Definition: os_port.h:63
@ TLS_GROUP_SECP521R1
Definition: tls.h:1493
@ TLS_GROUP_SECP192R1
Definition: tls.h:1487
@ TLS_ALERT_PROTOCOL_VERSION
Definition: tls.h:1165
@ TLS_GROUP_SECP160R1
Definition: tls.h:1484
const uint8_t SECP192R1_OID[8]
Definition: ec_curves.c:62
#define TLS_MASTER_SECRET_SIZE
Definition: tls.h:837
@ TLS_GROUP_BRAINPOOLP384R1_TLS13
Definition: tls.h:1500
@ TLS_HASH_ALGO_MD5
Definition: tls.h:1278
const uint8_t SECP384R1_OID[5]
Definition: ec_curves.c:72
uint8_t secret[TLS_MASTER_SECRET_SIZE]
Master secret.
Definition: tls.h:2027
uint8_t random[32]
Definition: tls.h:1914
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
void dtlsInitReplayWindow(TlsEncryptionEngine *decryptionEngine)
Initialize sliding window.
Definition: dtls_misc.c:485
char_t * serverName
ServerName extension.
Definition: tls.h:2239
error_t tlsWriteEcPoint(const EcPublicKey *publicKey, uint8_t *data, size_t *length)
Encode an EC point to an opaque vector.
Definition: tls_misc.c:1283
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:1489
GCM context.
Definition: gcm.h:64
#define TLS_VERSION_1_1
Definition: tls.h:96
@ CIPHER_MODE_CCM
Definition: crypto.h:1067
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:1241
@ TLS_ALERT_BAD_CERTIFICATE
Definition: tls.h:1153
size_t contextSize
Definition: crypto.h:1193
@ TLS_ALERT_INAPPROPRIATE_FALLBACK
Definition: tls.h:1168
#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:1135
TLS session state.
Definition: tls.h:2218
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:2224
@ ERROR_INAPPROPRIATE_FALLBACK
Definition: error.h:247
#define TLS_VERSION_1_0
Definition: tls.h:95
@ TLS_ALERT_CERTIFICATE_EXPIRED
Definition: tls.h:1156
const TlsCipherSuiteInfo tlsSupportedCipherSuites[]
@ TLS_STATE_INIT
Definition: tls.h:1558
@ ERROR_CERTIFICATE_EXPIRED
Definition: error.h:239
@ TLS_ALERT_NO_APPLICATION_PROTOCOL
Definition: tls.h:1179
@ TLS_CONNECTION_END_CLIENT
Definition: tls.h:1029
Common interface for encryption algorithms.
Definition: crypto.h:1191
DtlsSequenceNumber
Definition: dtls_misc.h:148
@ 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:1322
uint16_t version
TLS protocol version.
Definition: tls.h:2219
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:1497
const uint8_t SECP160R2_OID[5]
Definition: ec_curves.c:58
@ 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:1151
FFDHE key exchange.
#define EcCurve
Definition: ec.h:346
@ CIPHER_MODE_NULL
Definition: crypto.h:1060
@ CIPHER_MODE_CHACHA20_POLY1305
Definition: crypto.h:1070
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:301
const char_t * tlsGetVersionName(uint16_t version)
Convert TLS version to string representation.
Definition: tls_misc.c:1370
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:1467
@ 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:894
@ TLS_ALERT_HANDSHAKE_FAILURE
Definition: tls.h:1151
@ 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:1167
@ 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:2226
@ 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:1627
@ TLS_GROUP_BRAINPOOLP384R1
Definition: tls.h:1495
__weak_func error_t tlsInitEncryptionEngine(TlsContext *context, TlsEncryptionEngine *encryptionEngine, TlsConnectionEnd entity, TlsEncryptionLevel level, const uint8_t *secret)
Initialize encryption engine.
Definition: tls_misc.c:673
@ TLS_ALERT_CERTIFICATE_UNKNOWN
Definition: tls.h:1157
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:605
@ TLS_STATE_CLOSED
Definition: tls.h:1595