tls.c
Go to the documentation of this file.
1 /**
2  * @file tls.c
3  * @brief TLS (Transport Layer Security)
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  * @section Description
28  *
29  * The TLS protocol provides communications security over the Internet. The
30  * protocol allows client/server applications to communicate in a way that
31  * is designed to prevent eavesdropping, tampering, or message forgery
32  *
33  * @author Oryx Embedded SARL (www.oryx-embedded.com)
34  * @version 2.6.4
35  **/
36 
37 //Switch to the appropriate trace level
38 #define TRACE_LEVEL TLS_TRACE_LEVEL
39 
40 //Dependencies
41 #include "tls/tls.h"
42 #include "tls/tls_cipher_suites.h"
43 #include "tls/tls_handshake.h"
44 #include "tls/tls_common.h"
45 #include "tls/tls_certificate.h"
46 #include "tls/tls_key_material.h"
48 #include "tls/tls_record.h"
49 #include "tls/tls_misc.h"
52 #include "tls13/tls13_ticket.h"
53 #include "dtls/dtls_record.h"
54 #include "dtls13/dtls13_misc.h"
55 #include "pkix/pem_import.h"
56 #include "pkix/x509_cert_parse.h"
57 #include "debug.h"
58 
59 //Check TLS library configuration
60 #if (TLS_SUPPORT == ENABLED)
61 
62 
63 /**
64  * @brief TLS context initialization
65  * @return Handle referencing the fully initialized TLS context
66  **/
67 
69 {
70  TlsContext *context;
71 
72  //Allocate a memory buffer to hold the TLS context
73  context = tlsAllocMem(sizeof(TlsContext));
74 
75  //Successful memory allocation?
76  if(context != NULL)
77  {
78  //Clear TLS context
79  osMemset(context, 0, sizeof(TlsContext));
80 
81  //Default state
82  context->state = TLS_STATE_INIT;
83  //Default transport protocol
84  context->transportProtocol = TLS_TRANSPORT_PROTOCOL_STREAM;
85  //Default operation mode
86  context->entity = TLS_CONNECTION_END_CLIENT;
87  //Default client authentication mode
88  context->clientAuthMode = TLS_CLIENT_AUTH_NONE;
89 
90  //Minimum and maximum versions accepted by the implementation
91  context->versionMin = TLS_MIN_VERSION;
92  context->versionMax = TLS_MAX_VERSION;
93 
94  //Default record layer version number
95  context->version = TLS_MIN_VERSION;
96  context->encryptionEngine[0].version = TLS_MIN_VERSION;
97 
98 #if (TLS_MAX_VERSION >= TLS_VERSION_1_3 && TLS_MIN_VERSION <= TLS_VERSION_1_3)
99  //A TLS 1.3 client may pregenerate key shares
100  context->cipherSuiteTypes = TLS_CIPHER_SUITE_TYPE_TLS13 |
102 
103  //Select default named group
105  {
106  context->preferredGroup = TLS_GROUP_X25519;
107  }
108  else if(tls13IsGroupSupported(context, TLS_GROUP_SECP256R1))
109  {
110  context->preferredGroup = TLS_GROUP_SECP256R1;
111  }
112  else
113  {
114  context->preferredGroup = TLS_GROUP_NONE;
115  }
116 #endif
117 
118 #if (DTLS_SUPPORT == ENABLED)
119  //Default PMTU
120  context->pmtu = DTLS_DEFAULT_PMTU;
121  //Default timeout
122  context->timeout = INFINITE_DELAY;
123 #endif
124 
125 #if (DTLS_SUPPORT == ENABLED && DTLS_REPLAY_DETECTION_SUPPORT == ENABLED)
126  //Anti-replay mechanism is enabled by default
127  context->replayDetectionEnabled = TRUE;
128 #endif
129 
130 #if (TLS_QUIC_SUPPORT == ENABLED)
131  //Select initial encryption level
132  context->encryptionEngine[0].level = TLS_ENCRYPTION_LEVEL_INITIAL;
133  context->decryptionEngine[0].level = TLS_ENCRYPTION_LEVEL_INITIAL;
134 #endif
135 
136 #if (TLS_DH_SUPPORT == ENABLED)
137  //Initialize Diffie-Hellman context
138  dhInit(&context->dhContext);
139 #endif
140 
141 #if (TLS_ECDH_SUPPORT == ENABLED || TLS_HYBRID_SUPPORT == ENABLED)
142  //Initialize ECDH context
143  ecdhInit(&context->ecdhContext);
144 #endif
145 
146 #if (TLS_MLKEM_SUPPORT == ENABLED || TLS_HYBRID_SUPPORT == ENABLED)
147  //Initialize KEM context
148  kemInit(&context->kemContext, NULL);
149 #endif
150 
151 #if (TLS_RSA_SUPPORT == ENABLED)
152  //Initialize peer's RSA public key
153  rsaInitPublicKey(&context->peerRsaPublicKey);
154 #endif
155 
156 #if (TLS_DSA_SIGN_SUPPORT == ENABLED)
157  //Initialize peer's DSA public key
158  dsaInitPublicKey(&context->peerDsaPublicKey);
159 #endif
160 
161 #if (TLS_ECDSA_SIGN_SUPPORT == ENABLED || TLS_SM2_SIGN_SUPPORT == ENABLED)
162  //Initialize peer's EC public key
163  ecInitPublicKey(&context->peerEcPublicKey);
164 #endif
165 
166 #if (TLS_ED25519_SIGN_SUPPORT == ENABLED || TLS_ED448_SIGN_SUPPORT == ENABLED)
167  //Initialize peer's EdDSA public key
168  eddsaInitPublicKey(&context->peerEddsaPublicKey);
169 #endif
170 
171 #if (TLS_MLDSA44_SIGN_SUPPORT == ENABLED || TLS_MLDSA65_SIGN_SUPPORT == ENABLED || \
172  TLS_MLDSA87_SIGN_SUPPORT == ENABLED)
173  //Initialize peer's ML-DSA public key
174  mldsaInitPublicKey(&context->peerMldsaPublicKey);
175 #endif
176 
177  //Maximum number of plaintext data the TX and RX buffers can hold
178  context->txBufferMaxLen = TLS_MAX_RECORD_LENGTH;
179  context->rxBufferMaxLen = TLS_MAX_RECORD_LENGTH;
180 
181 #if (TLS_MAX_FRAG_LEN_SUPPORT == ENABLED)
182  //Maximum fragment length
183  context->maxFragLen = TLS_MAX_RECORD_LENGTH;
184 #endif
185 #if (TLS_RECORD_SIZE_LIMIT_SUPPORT == ENABLED)
186  //Maximum record size the peer is willing to receive
187  context->recordSizeLimit = TLS_MAX_RECORD_LENGTH;
188 #endif
189 
190 #if (DTLS_SUPPORT == ENABLED)
191  //Calculate the required size for the TX buffer
192  context->txBufferSize = context->txBufferMaxLen + sizeof(DtlsRecord) +
194 
195  //Calculate the required size for the RX buffer
196  context->rxBufferSize = context->rxBufferMaxLen + sizeof(DtlsRecord) +
198 #else
199  //Calculate the required size for the TX buffer
200  context->txBufferSize = context->txBufferMaxLen + sizeof(TlsRecord) +
202 
203  //Calculate the required size for the RX buffer
204  context->rxBufferSize = context->rxBufferMaxLen + sizeof(TlsRecord) +
206 #endif
207  }
208 
209  //Return a pointer to the freshly created TLS context
210  return context;
211 }
212 
213 
214 /**
215  * @brief Retrieve current TLS state
216  * @param[in] context Pointer to the TLS context
217  * @return Current TLS state
218  **/
219 
221 {
222  TlsState state;
223 
224  //Valid TLS context?
225  if(context != NULL)
226  {
227  state = context->state;
228  }
229  else
230  {
231  state = TLS_STATE_INIT;
232  }
233 
234  //Return current state
235  return state;
236 }
237 
238 
239 /**
240  * @brief Register TLS state change callback
241  * @param[in] context Pointer to the TLS context
242  * @param[in] stateChangeCallback TLS state change callback
243  * @return Error code
244  **/
245 
247  TlsStateChangeCallback stateChangeCallback)
248 {
249  //Check parameters
250  if(context == NULL || stateChangeCallback == NULL)
252 
253  //Save TLS state change callback
254  context->stateChangeCallback = stateChangeCallback;
255 
256  //Successful processing
257  return NO_ERROR;
258 }
259 
260 
261 /**
262  * @brief Set socket send and receive callbacks
263  * @param[in] context Pointer to the TLS context
264  * @param[in] socketSendCallback Send callback function
265  * @param[in] socketReceiveCallback Receive callback function
266  * @param[in] handle Socket handle
267  * @return Error code
268  **/
269 
271  TlsSocketSendCallback socketSendCallback,
272  TlsSocketReceiveCallback socketReceiveCallback, TlsSocketHandle handle)
273 {
274  //Invalid TLS context?
275  if(context == NULL)
277 
278  //Check parameters
279  if(socketSendCallback == NULL || socketReceiveCallback == NULL)
281 
282  //Save send and receive callback functions
283  context->socketSendCallback = socketSendCallback;
284  context->socketReceiveCallback = socketReceiveCallback;
285 
286  //This socket handle will be directly passed to the callback functions
287  context->socketHandle = handle;
288 
289  //Successful processing
290  return NO_ERROR;
291 }
292 
293 
294 /**
295  * @brief Set minimum and maximum versions permitted
296  * @param[in] context Pointer to the TLS context
297  * @param[in] versionMin Minimum version accepted by the TLS implementation
298  * @param[in] versionMax Maximum version accepted by the TLS implementation
299  * @return Error code
300  **/
301 
302 error_t tlsSetVersion(TlsContext *context, uint16_t versionMin,
303  uint16_t versionMax)
304 {
305  //Invalid TLS context?
306  if(context == NULL)
308 
309  //Check parameters
310  if(versionMin < TLS_VERSION_1_0 || versionMin > TLS_MAX_VERSION)
312 
313  if(versionMax > TLS_VERSION_1_3 || versionMax < TLS_MIN_VERSION)
315 
316  if(versionMin > versionMax)
318 
319  //Minimum version accepted by the implementation
320  context->versionMin = MAX(versionMin, TLS_MIN_VERSION);
321  //Maximum version accepted by the implementation
322  context->versionMax = MIN(versionMax, TLS_MAX_VERSION);
323 
324  //Default record layer version number
325  context->version = context->versionMin;
326  context->encryptionEngine[0].version = context->versionMin;
327 
328  //Successful processing
329  return NO_ERROR;
330 }
331 
332 
333 /**
334  * @brief Set the transport protocol to be used
335  * @param[in] context Pointer to the TLS context
336  * @param[in] transportProtocol Transport protocol to be used
337  * @return Error code
338  **/
339 
341  TlsTransportProtocol transportProtocol)
342 {
343  //Invalid TLS context?
344  if(context == NULL)
346 
347  //Check parameters
348  if(transportProtocol != TLS_TRANSPORT_PROTOCOL_STREAM &&
349  transportProtocol != TLS_TRANSPORT_PROTOCOL_DATAGRAM &&
350  transportProtocol != TLS_TRANSPORT_PROTOCOL_QUIC &&
351  transportProtocol != TLS_TRANSPORT_PROTOCOL_EAP)
352  {
354  }
355 
356  //Set transport protocol
357  context->transportProtocol = transportProtocol;
358 
359  //Successful processing
360  return NO_ERROR;
361 }
362 
363 
364 /**
365  * @brief Set operation mode (client or server)
366  * @param[in] context Pointer to the TLS context
367  * @param[in] entity Specifies whether this entity is considered a client or a server
368  * @return Error code
369  **/
370 
372 {
373  //Invalid TLS context?
374  if(context == NULL)
376 
377  //Check parameters
378  if(entity != TLS_CONNECTION_END_CLIENT && entity != TLS_CONNECTION_END_SERVER)
380 
381  //Check whether TLS operates as a client or a server
382  context->entity = entity;
383 
384  //Successful processing
385  return NO_ERROR;
386 }
387 
388 
389 /**
390  * @brief Set the pseudo-random number generator to be used
391  * @param[in] context Pointer to the TLS context
392  * @param[in] prngAlgo PRNG algorithm
393  * @param[in] prngContext Pointer to the PRNG context
394  * @return Error code
395  **/
396 
397 error_t tlsSetPrng(TlsContext *context, const PrngAlgo *prngAlgo,
398  void *prngContext)
399 {
400  //Invalid TLS context?
401  if(context == NULL)
403 
404  //Check parameters
405  if(prngAlgo == NULL || prngContext == NULL)
407 
408  //PRNG algorithm that will be used to generate random numbers
409  context->prngAlgo = prngAlgo;
410  //PRNG context
411  context->prngContext = prngContext;
412 
413  //Successful processing
414  return NO_ERROR;
415 }
416 
417 
418 /**
419  * @brief Set the server name
420  * @param[in] context Pointer to the TLS context
421  * @param[in] serverName Fully qualified domain name of the server
422  * @return Error code
423  **/
424 
425 error_t tlsSetServerName(TlsContext *context, const char_t *serverName)
426 {
427  size_t i;
428  size_t length;
429 
430  //Check parameters
431  if(context == NULL || serverName == NULL)
433 
434  //Retrieve the length of the server name
435  length = osStrlen(serverName);
436 
437  //Check whether the server name has already been configured
438  if(context->serverName != NULL)
439  {
440  //Release memory
441  tlsFreeMem(context->serverName);
442  context->serverName = NULL;
443  }
444 
445  //Valid server name?
446  if(length > 0)
447  {
448  //Allocate a memory block to hold the hostname
449  context->serverName = tlsAllocMem(length + 1);
450  //Failed to allocate memory?
451  if(context->serverName == NULL)
452  return ERROR_OUT_OF_MEMORY;
453 
454  //Convert the hostname into lowercase
455  for(i = 0; i < length; i++)
456  {
457  context->serverName[i] = osTolower(serverName[i]);
458  }
459 
460  //Properly terminate the string with a NULL character
461  context->serverName[length] = '\0';
462  }
463 
464  //Successful processing
465  return NO_ERROR;
466 }
467 
468 
469 /**
470  * @brief Get the server name
471  * @param[in] context Pointer to the TLS context
472  * @return Fully qualified domain name of the server
473  **/
474 
476 {
477  static const char_t defaultServerName[] = "";
478 
479  //Valid protocol name?
480  if(context != NULL && context->serverName != NULL)
481  {
482  //Return the fully qualified domain name of the server
483  return context->serverName;
484  }
485  else
486  {
487  //Return an empty string
488  return defaultServerName;
489  }
490 }
491 
492 
493 /**
494  * @brief Set session cache
495  * @param[in] context Pointer to the TLS context
496  * @param[in] cache Session cache that will be used to save/resume TLS sessions
497  * @return Error code
498  **/
499 
501 {
502  //Check parameters
503  if(context == NULL)
505 
506  //The cache will be used to save/resume TLS sessions
507  context->cache = cache;
508 
509  //Successful processing
510  return NO_ERROR;
511 }
512 
513 
514 /**
515  * @brief Set client authentication mode (for servers only)
516  * @param[in] context Pointer to the TLS context
517  * @param[in] mode Client authentication mode
518  * @return Error code
519  **/
520 
522 {
523  //Invalid TLS context?
524  if(context == NULL)
526 
527  //Save client authentication mode
528  context->clientAuthMode = mode;
529 
530  //Successful processing
531  return NO_ERROR;
532 }
533 
534 
535 /**
536  * @brief Set TLS buffer size
537  * @param[in] context Pointer to the TLS context
538  * @param[in] txBufferSize TX buffer size
539  * @param[in] rxBufferSize RX buffer size
540  * @return Error code
541  **/
542 
543 error_t tlsSetBufferSize(TlsContext *context, size_t txBufferSize,
544  size_t rxBufferSize)
545 {
546  //Invalid TLS context?
547  if(context == NULL)
549 
550  //Check parameters
551  if(txBufferSize < TLS_MIN_RECORD_LENGTH ||
552  rxBufferSize < TLS_MIN_RECORD_LENGTH)
553  {
555  }
556 
557  //Maximum number of plaintext data the TX and RX buffers can hold
558  context->txBufferMaxLen = txBufferSize;
559  context->rxBufferMaxLen = rxBufferSize;
560 
561 #if (DTLS_SUPPORT == ENABLED)
562  //Calculate the required size for the TX buffer
563  context->txBufferSize = txBufferSize + sizeof(DtlsRecord) +
565 
566  //Calculate the required size for the RX buffer
567  context->rxBufferSize = rxBufferSize + sizeof(DtlsRecord) +
569 #else
570  //Calculate the required size for the TX buffer
571  context->txBufferSize = txBufferSize + sizeof(TlsRecord) +
573 
574  //Calculate the required size for the RX buffer
575  context->rxBufferSize = rxBufferSize + sizeof(TlsRecord) +
577 #endif
578 
579  //Successful processing
580  return NO_ERROR;
581 }
582 
583 
584 /**
585  * @brief Set maximum fragment length
586  * @param[in] context Pointer to the TLS context
587  * @param[in] maxFragLen Maximum fragment length
588  * @return Error code
589  **/
590 
591 error_t tlsSetMaxFragmentLength(TlsContext *context, size_t maxFragLen)
592 {
593 #if (TLS_MAX_FRAG_LEN_SUPPORT == ENABLED)
594  //Invalid TLS context?
595  if(context == NULL)
597 
598  //Make sure the specified value is acceptable (ref to RFC 6066, section 4)
599  if(maxFragLen != 512 && maxFragLen != 1024 &&
600  maxFragLen != 2048 && maxFragLen != 4096 &&
601  maxFragLen != 16384)
602  {
604  }
605 
606  //Set maximum fragment length
607  context->maxFragLen = maxFragLen;
608 
609  //Successful processing
610  return NO_ERROR;
611 #else
612  //Not implemented
613  return ERROR_NOT_IMPLEMENTED;
614 #endif
615 }
616 
617 
618 /**
619  * @brief Specify the list of allowed cipher suites
620  * @param[in] context Pointer to the TLS context
621  * @param[in] cipherSuites List of allowed cipher suites (most preferred
622  * first). This parameter is taken as reference
623  * @param[in] length Number of cipher suites in the list
624  * @return Error code
625  **/
626 
627 error_t tlsSetCipherSuites(TlsContext *context, const uint16_t *cipherSuites,
628  uint_t length)
629 {
630  //Invalid TLS context?
631  if(context == NULL)
633 
634  //Check parameters
635  if(cipherSuites == NULL && length != 0)
637 
638  //Restrict the cipher suites that can be used
639  context->cipherSuites = cipherSuites;
640  context->numCipherSuites = length;
641 
642  //Successful processing
643  return NO_ERROR;
644 }
645 
646 
647 /**
648  * @brief Specify the list of allowed ECDHE and FFDHE groups
649  * @param[in] context Pointer to the TLS context
650  * @param[in] groups List of named groups (most preferred first). This
651  * parameter is taken as reference
652  * @param[in] length Number of named groups in the list
653  * @return Error code
654  **/
655 
656 error_t tlsSetSupportedGroups(TlsContext *context, const uint16_t *groups,
657  uint_t length)
658 {
659  //Invalid TLS context?
660  if(context == NULL)
662 
663  //Check parameters
664  if(groups == NULL && length != 0)
666 
667  //Restrict the named groups that can be used
668  context->supportedGroups = groups;
669  context->numSupportedGroups = length;
670 
671  //Successful processing
672  return NO_ERROR;
673 }
674 
675 
676 /**
677  * @brief Specify the preferred ECDHE or FFDHE group
678  * @param[in] context Pointer to the TLS context
679  * @param[in] group Preferred ECDHE or FFDHE named group
680  * @return Error code
681  **/
682 
683 error_t tlsSetPreferredGroup(TlsContext *context, uint16_t group)
684 {
685 #if (TLS_MAX_VERSION >= TLS_VERSION_1_3 && TLS_MIN_VERSION <= TLS_VERSION_1_3)
686  //Invalid TLS context?
687  if(context == NULL)
689 
690  //Save the preferred named group
691  context->preferredGroup = group;
692 
693  //Successful processing
694  return NO_ERROR;
695 #else
696  //Not implemented
697  return ERROR_NOT_IMPLEMENTED;
698 #endif
699 }
700 
701 
702 /**
703  * @brief Specify the list of allowed signature algorithms
704  * @param[in] context Pointer to the TLS context
705  * @param[in] signAlgos List of signature algorithms (most preferred first). This
706  * parameter is taken as reference
707  * @param[in] length Number of signature algorithms in the list
708  * @return Error code
709  **/
710 
712  const uint16_t *signAlgos, uint_t length)
713 {
714 #if (TLS_MAX_VERSION >= TLS_VERSION_1_2 && TLS_MIN_VERSION <= TLS_VERSION_1_3)
715  //Invalid TLS context?
716  if(context == NULL)
718 
719  //Check parameters
720  if(signAlgos == NULL && length != 0)
722 
723  //Restrict the signature algorithms that can be used
724  context->supportedSignAlgos = signAlgos;
725  context->numSupportedSignAlgos = length;
726 
727  //Successful processing
728  return NO_ERROR;
729 #else
730  //Not implemented
731  return ERROR_NOT_IMPLEMENTED;
732 #endif
733 }
734 
735 
736 /**
737  * @brief Import Diffie-Hellman parameters
738  * @param[in] context Pointer to the TLS context
739  * @param[in] params PEM structure that holds Diffie-Hellman parameters. This
740  * parameter is taken as reference
741  * @param[in] length Total length of the DER structure
742  * @return Error code
743  **/
744 
745 error_t tlsSetDhParameters(TlsContext *context, const char_t *params,
746  size_t length)
747 {
748 #if (TLS_DH_SUPPORT == ENABLED)
749  //Invalid TLS context?
750  if(context == NULL)
752 
753  //Check parameters
754  if(params == NULL && length != 0)
756 
757  //Decode the PEM structure that holds Diffie-Hellman parameters
758  return pemImportDhParameters(&context->dhContext.params, params, length);
759 #else
760  //Diffie-Hellman is not implemented
761  return ERROR_NOT_IMPLEMENTED;
762 #endif
763 }
764 
765 
766 /**
767  * @brief Register ECDH key agreement callback function
768  * @param[in] context Pointer to the TLS context
769  * @param[in] ecdhCallback ECDH callback function
770  * @return Error code
771  **/
772 
774 {
775 #if (TLS_ECC_CALLBACK_SUPPORT == ENABLED)
776  //Check parameters
777  if(context == NULL || ecdhCallback == NULL)
779 
780  //Save ECDH key agreement callback function
781  context->ecdhCallback = ecdhCallback;
782 
783  //Successful processing
784  return NO_ERROR;
785 #else
786  //PSK key exchange is not implemented
787  return ERROR_NOT_IMPLEMENTED;
788 #endif
789 }
790 
791 
792 /**
793  * @brief Register ECDSA signature generation callback function
794  * @param[in] context Pointer to the TLS context
795  * @param[in] ecdsaSignCallback ECDSA signature generation callback function
796  * @return Error code
797  **/
798 
800  TlsEcdsaSignCallback ecdsaSignCallback)
801 {
802 #if (TLS_ECC_CALLBACK_SUPPORT == ENABLED)
803  //Check parameters
804  if(context == NULL || ecdsaSignCallback == NULL)
806 
807  //Save ECDSA signature generation callback function
808  context->ecdsaSignCallback = ecdsaSignCallback;
809 
810  //Successful processing
811  return NO_ERROR;
812 #else
813  //PSK key exchange is not implemented
814  return ERROR_NOT_IMPLEMENTED;
815 #endif
816 }
817 
818 
819 /**
820  * @brief Register ECDSA signature verification callback function
821  * @param[in] context Pointer to the TLS context
822  * @param[in] ecdsaVerifyCallback ECDSA signature verification callback function
823  * @return Error code
824  **/
825 
827  TlsEcdsaVerifyCallback ecdsaVerifyCallback)
828 {
829 #if (TLS_ECC_CALLBACK_SUPPORT == ENABLED)
830  //Check parameters
831  if(context == NULL || ecdsaVerifyCallback == NULL)
833 
834  //Save ECDSA signature verification callback function
835  context->ecdsaVerifyCallback = ecdsaVerifyCallback;
836 
837  //Successful processing
838  return NO_ERROR;
839 #else
840  //PSK key exchange is not implemented
841  return ERROR_NOT_IMPLEMENTED;
842 #endif
843 }
844 
845 
846 /**
847  * @brief Register key logging callback function (for debugging purpose only)
848  * @param[in] context Pointer to the TLS context
849  * @param[in] keyLogCallback Key logging callback function
850  * @return Error code
851  **/
852 
854  TlsKeyLogCallback keyLogCallback)
855 {
856 #if (TLS_KEY_LOG_SUPPORT == ENABLED)
857  //Check parameters
858  if(context == NULL || keyLogCallback == NULL)
860 
861  //Save key logging callback function
862  context->keyLogCallback = keyLogCallback;
863 
864  //Successful processing
865  return NO_ERROR;
866 #else
867  //Key logging is not implemented
868  return ERROR_NOT_IMPLEMENTED;
869 #endif
870 }
871 
872 
873 /**
874  * @brief Allow unknown ALPN protocols
875  * @param[in] context Pointer to the TLS context
876  * @param[in] allowed Specifies whether unknown ALPN protocols are allowed
877  * @return Error code
878  **/
879 
881 {
882 #if (TLS_ALPN_SUPPORT == ENABLED)
883  //Invalid TLS context?
884  if(context == NULL)
886 
887  //Allow or disallow unknown ALPN protocols
888  context->unknownProtocolsAllowed = allowed;
889 
890  //Successful processing
891  return NO_ERROR;
892 #else
893  //ALPN is not implemented
894  return ERROR_NOT_IMPLEMENTED;
895 #endif
896 }
897 
898 
899 /**
900  * @brief Set the list of supported ALPN protocols
901  * @param[in] context Pointer to the TLS context
902  * @param[in] protocolList Comma-delimited list of supported protocols
903  * @return Error code
904  **/
905 
906 error_t tlsSetAlpnProtocolList(TlsContext *context, const char_t *protocolList)
907 {
908 #if (TLS_ALPN_SUPPORT == ENABLED)
909  size_t length;
910 
911  //Check parameters
912  if(context == NULL || protocolList == NULL)
914 
915  //Retrieve the length of the list
916  length = osStrlen(protocolList);
917 
918  //Check whether the list of supported protocols has already been configured
919  if(context->protocolList != NULL)
920  {
921  //Release memory
922  tlsFreeMem(context->protocolList);
923  context->protocolList = NULL;
924  }
925 
926  //Check whether the list of protocols is valid
927  if(length > 0)
928  {
929  //Allocate a memory block to hold the list
930  context->protocolList = tlsAllocMem(length + 1);
931  //Failed to allocate memory?
932  if(context->protocolList == NULL)
933  return ERROR_OUT_OF_MEMORY;
934 
935  //Save the list of supported protocols
936  osStrcpy(context->protocolList, protocolList);
937  }
938 
939  //Successful processing
940  return NO_ERROR;
941 #else
942  //ALPN is not implemented
943  return ERROR_NOT_IMPLEMENTED;
944 #endif
945 }
946 
947 
948 /**
949  * @brief Register ALPN callback function
950  * @param[in] context Pointer to the TLS context
951  * @param[in] alpnCallback ALPN callback function
952  * @return Error code
953  **/
954 
956 {
957 #if (TLS_ALPN_SUPPORT == ENABLED)
958  //Check parameters
959  if(context == NULL || alpnCallback == NULL)
961 
962  //Save ALPN callback function
963  context->alpnCallback = alpnCallback;
964 
965  //Successful processing
966  return NO_ERROR;
967 #else
968  //ALPN is not implemented
969  return ERROR_NOT_IMPLEMENTED;
970 #endif
971 }
972 
973 
974 /**
975  * @brief Get the name of the selected ALPN protocol
976  * @param[in] context Pointer to the TLS context
977  * @return Pointer to the protocol name
978  **/
979 
981 {
982  static const char_t defaultProtocolName[] = "";
983 
984 #if (TLS_ALPN_SUPPORT == ENABLED)
985  //Valid protocol name?
986  if(context != NULL && context->selectedProtocol != NULL)
987  {
988  //Return the name of the selected protocol
989  return context->selectedProtocol;
990  }
991  else
992 #endif
993  {
994  //Return an empty string
995  return defaultProtocolName;
996  }
997 }
998 
999 
1000 /**
1001  * @brief Set the pre-shared key to be used
1002  * @param[in] context Pointer to the TLS context
1003  * @param[in] psk Pointer to the pre-shared key
1004  * @param[in] length Length of the pre-shared key, in bytes
1005  * @return Error code
1006  **/
1007 
1008 error_t tlsSetPsk(TlsContext *context, const uint8_t *psk, size_t length)
1009 {
1010 #if (TLS_PSK_SUPPORT == ENABLED)
1011  //Invalid TLS context?
1012  if(context == NULL)
1013  return ERROR_INVALID_PARAMETER;
1014 
1015  //Check parameters
1016  if(psk == NULL && length != 0)
1017  return ERROR_INVALID_PARAMETER;
1018 
1019  //Check whether the pre-shared key has already been configured
1020  if(context->psk != NULL)
1021  {
1022  //Release memory
1023  osMemset(context->psk, 0, context->pskLen);
1024  tlsFreeMem(context->psk);
1025  context->psk = NULL;
1026  context->pskLen = 0;
1027  }
1028 
1029  //Valid PSK?
1030  if(length > 0)
1031  {
1032  //Allocate a memory block to hold the pre-shared key
1033  context->psk = tlsAllocMem(length);
1034  //Failed to allocate memory?
1035  if(context->psk == NULL)
1036  return ERROR_OUT_OF_MEMORY;
1037 
1038  //Save the pre-shared key
1039  osMemcpy(context->psk, psk, length);
1040  //Save the length of the key
1041  context->pskLen = length;
1042  }
1043 
1044 #if (TLS_MAX_VERSION >= TLS_VERSION_1_3 && TLS_MIN_VERSION <= TLS_VERSION_1_3)
1045  //For externally established PSKs, the hash algorithm must be set when the
1046  //PSK is established, or default to SHA-256 if no such algorithm is defined
1047  context->pskHashAlgo = TLS_HASH_ALGO_SHA256;
1048 
1049  //The cipher suite must be provisioned along with the key
1050  context->pskCipherSuite = 0;
1051 #endif
1052 
1053  //Successful processing
1054  return NO_ERROR;
1055 #else
1056  //PSK key exchange is not implemented
1057  return ERROR_NOT_IMPLEMENTED;
1058 #endif
1059 }
1060 
1061 
1062 /**
1063  * @brief Set the PSK identity to be used by the client
1064  * @param[in] context Pointer to the TLS context
1065  * @param[in] pskIdentity NULL-terminated string that contains the PSK identity
1066  * @return Error code
1067  **/
1068 
1069 error_t tlsSetPskIdentity(TlsContext *context, const char_t *pskIdentity)
1070 {
1071 #if (TLS_PSK_SUPPORT == ENABLED)
1072  size_t length;
1073 
1074  //Check parameters
1075  if(context == NULL || pskIdentity == NULL)
1076  return ERROR_INVALID_PARAMETER;
1077 
1078  //Retrieve the length of the PSK identity
1079  length = osStrlen(pskIdentity);
1080 
1081  //Check whether the PSK identity has already been configured
1082  if(context->pskIdentity != NULL)
1083  {
1084  //Release memory
1085  tlsFreeMem(context->pskIdentity);
1086  context->pskIdentity = NULL;
1087  }
1088 
1089  //Valid PSK identity?
1090  if(length > 0)
1091  {
1092  //Allocate a memory block to hold the PSK identity
1093  context->pskIdentity = tlsAllocMem(length + 1);
1094  //Failed to allocate memory?
1095  if(context->pskIdentity == NULL)
1096  return ERROR_OUT_OF_MEMORY;
1097 
1098  //Save the PSK identity
1099  osStrcpy(context->pskIdentity, pskIdentity);
1100  }
1101 
1102  //Successful processing
1103  return NO_ERROR;
1104 #else
1105  //PSK key exchange is not implemented
1106  return ERROR_NOT_IMPLEMENTED;
1107 #endif
1108 }
1109 
1110 
1111 /**
1112  * @brief Set the PSK identity hint to be used by the server
1113  * @param[in] context Pointer to the TLS context
1114  * @param[in] pskIdentityHint NULL-terminated string that contains the PSK identity hint
1115  * @return Error code
1116  **/
1117 
1118 error_t tlsSetPskIdentityHint(TlsContext *context, const char_t *pskIdentityHint)
1119 {
1120 #if (TLS_PSK_SUPPORT == ENABLED)
1121  size_t length;
1122 
1123  //Check parameters
1124  if(context == NULL || pskIdentityHint == NULL)
1125  return ERROR_INVALID_PARAMETER;
1126 
1127  //Retrieve the length of the PSK identity hint
1128  length = osStrlen(pskIdentityHint);
1129 
1130  //Check whether the PSK identity hint has already been configured
1131  if(context->pskIdentityHint != NULL)
1132  {
1133  //Release memory
1134  tlsFreeMem(context->pskIdentityHint);
1135  context->pskIdentityHint = NULL;
1136  }
1137 
1138  //Valid PSK identity hint?
1139  if(length > 0)
1140  {
1141  //Allocate a memory block to hold the PSK identity hint
1142  context->pskIdentityHint = tlsAllocMem(length + 1);
1143  //Failed to allocate memory?
1144  if(context->pskIdentityHint == NULL)
1145  return ERROR_OUT_OF_MEMORY;
1146 
1147  //Save the PSK identity hint
1148  osStrcpy(context->pskIdentityHint, pskIdentityHint);
1149  }
1150 
1151  //Successful processing
1152  return NO_ERROR;
1153 #else
1154  //PSK key exchange is not implemented
1155  return ERROR_NOT_IMPLEMENTED;
1156 #endif
1157 }
1158 
1159 
1160 /**
1161  * @brief Register PSK callback function
1162  * @param[in] context Pointer to the TLS context
1163  * @param[in] pskCallback PSK callback function
1164  * @return Error code
1165  **/
1166 
1168 {
1169 #if (TLS_PSK_SUPPORT == ENABLED)
1170  //Check parameters
1171  if(context == NULL || pskCallback == NULL)
1172  return ERROR_INVALID_PARAMETER;
1173 
1174  //Save PSK callback function
1175  context->pskCallback = pskCallback;
1176 
1177  //Successful processing
1178  return NO_ERROR;
1179 #else
1180  //PSK key exchange is not implemented
1181  return ERROR_NOT_IMPLEMENTED;
1182 #endif
1183 }
1184 
1185 
1186 /**
1187  * @brief Register the raw public key verification callback function
1188  * @param[in] context Pointer to the TLS context
1189  * @param[in] rpkVerifyCallback RPK verification callback function
1190  * @return Error code
1191  **/
1192 
1194  TlsRpkVerifyCallback rpkVerifyCallback)
1195 {
1196 #if (TLS_RAW_PUBLIC_KEY_SUPPORT == ENABLED)
1197  //Check parameters
1198  if(context == NULL || rpkVerifyCallback == NULL)
1199  return ERROR_INVALID_PARAMETER;
1200 
1201  //Save raw public key verification callback function
1202  context->rpkVerifyCallback = rpkVerifyCallback;
1203 
1204  //Successful processing
1205  return NO_ERROR;
1206 #else
1207  //Raw public keys are not implemented
1208  return ERROR_NOT_IMPLEMENTED;
1209 #endif
1210 }
1211 
1212 
1213 /**
1214  * @brief Import a trusted CA list
1215  * @param[in] context Pointer to the TLS context
1216  * @param[in] trustedCaList List of trusted CA (PEM format)
1217  * @param[in] length Total length of the list
1218  * @return Error code
1219  **/
1220 
1221 error_t tlsSetTrustedCaList(TlsContext *context, const char_t *trustedCaList,
1222  size_t length)
1223 {
1224  //Invalid TLS context?
1225  if(context == NULL)
1226  return ERROR_INVALID_PARAMETER;
1227 
1228  //Check parameters
1229  if(trustedCaList == NULL && length != 0)
1230  return ERROR_INVALID_PARAMETER;
1231 
1232  //Save the list of trusted CA
1233  context->trustedCaList = trustedCaList;
1234  context->trustedCaListLen = length;
1235 
1236  //Successful processing
1237  return NO_ERROR;
1238 }
1239 
1240 
1241 /**
1242  * @brief Load entity's certificate
1243  * @param[in] context Pointer to the TLS context
1244  * @param[in] index Zero-based index identifying a slot
1245  * @param[in] certChain Certificate chain (PEM format). This parameter is
1246  * taken as reference
1247  * @param[in] certChainLen Length of the certificate chain
1248  * @param[in] privateKey Private key (PEM format). This parameter is taken
1249  * as reference
1250  * @param[in] privateKeyLen Length of the private key
1251  * @param[in] password NULL-terminated string containing the password. This
1252  * parameter is required if the private key is encrypted
1253  * @return Error code
1254  **/
1255 
1257  const char_t *certChain, size_t certChainLen, const char_t *privateKey,
1258  size_t privateKeyLen, const char_t *password)
1259 {
1260  error_t error;
1261  uint8_t *derCert;
1262  size_t derCertLen;
1263  X509CertInfo *certInfo;
1264  TlsCertDesc *cert;
1265  TlsCertificateType certType;
1266  TlsNamedGroup namedCurve;
1267  TlsSignatureScheme certSignScheme;
1268 
1269  //Make sure the TLS context is valid
1270  if(context == NULL)
1271  return ERROR_INVALID_PARAMETER;
1272 
1273  //The implementation limits the number of certificates that can be loaded
1274  if(index >= TLS_MAX_CERTIFICATES)
1275  return ERROR_INVALID_PARAMETER;
1276 
1277  //Check whether the certificate chain is valid
1278  if(certChain == NULL || certChainLen == 0)
1279  return ERROR_INVALID_PARAMETER;
1280 
1281  //The private key is optional
1282  if(privateKey == NULL && privateKeyLen != 0)
1283  return ERROR_INVALID_PARAMETER;
1284 
1285  //The password if required only for encrypted private keys
1286  if(password != NULL && osStrlen(password) > TLS_MAX_PASSWORD_LEN)
1287  return ERROR_INVALID_PASSWORD;
1288 
1289  //The first pass calculates the length of the DER-encoded certificate
1290  error = pemImportCertificate(certChain, certChainLen, NULL, &derCertLen,
1291  NULL);
1292 
1293  //Check status code
1294  if(!error)
1295  {
1296  //Allocate a memory buffer to hold the DER-encoded certificate
1297  derCert = tlsAllocMem(derCertLen);
1298 
1299  //Successful memory allocation?
1300  if(derCert != NULL)
1301  {
1302  //The second pass decodes the PEM certificate
1303  error = pemImportCertificate(certChain, certChainLen, derCert,
1304  &derCertLen, NULL);
1305 
1306  //Check status code
1307  if(!error)
1308  {
1309  //Allocate a memory buffer to store X.509 certificate info
1310  certInfo = tlsAllocMem(sizeof(X509CertInfo));
1311 
1312  //Successful memory allocation?
1313  if(certInfo != NULL)
1314  {
1316 
1317  //Additional certificate parsing options
1319  options.ignoreUnknownExtensions = TRUE;
1320 
1321  //Parse X.509 certificate
1322  error = x509ParseCertificateEx(derCert, derCertLen, certInfo,
1323  &options);
1324 
1325  //Check status code
1326  if(!error)
1327  {
1328  //Retrieve the type of the X.509 certificate
1329  error = tlsGetCertificateType(certInfo, &certType,
1330  &namedCurve);
1331  }
1332 
1333  //Check status code
1334  if(!error)
1335  {
1336  //Retrieve the signature algorithm that has been used to sign
1337  //the certificate
1338  error = tlsGetCertificateSignAlgo(certInfo, &certSignScheme);
1339  }
1340 
1341  //Release previously allocated memory
1342  tlsFreeMem(certInfo);
1343  }
1344  else
1345  {
1346  //Failed to allocate memory
1347  error = ERROR_OUT_OF_MEMORY;
1348  }
1349  }
1350 
1351  //Release previously allocated memory
1352  tlsFreeMem(derCert);
1353  }
1354  else
1355  {
1356  //Failed to allocate memory
1357  error = ERROR_OUT_OF_MEMORY;
1358  }
1359  }
1360 
1361  //Check status code
1362  if(!error)
1363  {
1364  //Point to the structure that describes the certificate
1365  cert = &context->certs[index];
1366 
1367  //Save the certificate chain and the corresponding private key
1368  cert->certChain = certChain;
1369  cert->certChainLen = certChainLen;
1370  cert->privateKey = privateKey;
1371  cert->privateKeyLen = privateKeyLen;
1372  cert->type = certType;
1373  cert->signScheme = certSignScheme;
1374  cert->namedCurve = namedCurve;
1375 
1376  //The password if required only for encrypted private keys
1377  if(password != NULL)
1378  {
1379  osStrcpy(cert->password, password);
1380  }
1381  else
1382  {
1383  osStrcpy(cert->password, "");
1384  }
1385  }
1386 
1387  //Return status code
1388  return error;
1389 }
1390 
1391 
1392 /**
1393  * @brief Register certificate verification callback function
1394  * @param[in] context Pointer to the TLS context
1395  * @param[in] certVerifyCallback Certificate verification callback function
1396  * @param[in] param An opaque pointer passed to the callback function
1397  * @return Error code
1398  **/
1399 
1401  TlsCertVerifyCallback certVerifyCallback, void *param)
1402 {
1403  //Invalid TLS context?
1404  if(context == NULL)
1405  return ERROR_INVALID_PARAMETER;
1406 
1407  //Save certificate verification callback function
1408  context->certVerifyCallback = certVerifyCallback;
1409  //This opaque pointer will be directly passed to the callback function
1410  context->certVerifyParam = param;
1411 
1412  //Successful processing
1413  return NO_ERROR;
1414 }
1415 
1416 
1417 /**
1418  * @brief Enable session ticket mechanism
1419  * @param[in] context Pointer to the TLS context
1420  * @param[in] enabled Specifies whether session tickets are allowed
1421  * @return Error code
1422  **/
1423 
1425 {
1426 #if (TLS_TICKET_SUPPORT == ENABLED)
1427  //Invalid TLS context?
1428  if(context == NULL)
1429  return ERROR_INVALID_PARAMETER;
1430 
1431  //Enable or disable session ticket mechanism
1432  context->sessionTicketEnabled = enabled;
1433 
1434  //Successful processing
1435  return NO_ERROR;
1436 #else
1437  //Session ticket mechanism is not implemented
1438  return ERROR_NOT_IMPLEMENTED;
1439 #endif
1440 }
1441 
1442 
1443 /**
1444  * @brief Enable TrustedCaKeys extension
1445  * @param[in] context Pointer to the TLS context
1446  * @param[in] enabled Specifies whether TrustedCaKeys extension is enabled
1447  * @return Error code
1448  **/
1449 
1451 {
1452 #if (TLS_TRUSTED_CA_KEYS_SUPPORT == ENABLED)
1453  //Invalid TLS context?
1454  if(context == NULL)
1455  return ERROR_INVALID_PARAMETER;
1456 
1457  //Enable or disable support for TrustedCaKeys extension
1458  context->trustedCaKeysEnabled = enabled;
1459 
1460  //Successful processing
1461  return NO_ERROR;
1462 #else
1463  //TrustedCaKeys extension is not implemented
1464  return ERROR_NOT_IMPLEMENTED;
1465 #endif
1466 }
1467 
1468 
1469 /**
1470  * @brief Enable CertificateAuthorities extension
1471  * @param[in] context Pointer to the TLS context
1472  * @param[in] enabled Specifies whether CertificateAuthorities extension is
1473  * enabled
1474  * @return Error code
1475  **/
1476 
1478 {
1479 #if (TLS_CERT_AUTHORITIES_SUPPORT == ENABLED)
1480  //Invalid TLS context?
1481  if(context == NULL)
1482  return ERROR_INVALID_PARAMETER;
1483 
1484  //Enable or disable support for CertificateAuthorities extension
1485  context->certAuthoritiesEnabled = enabled;
1486 
1487  //Successful processing
1488  return NO_ERROR;
1489 #else
1490  //CertificateAuthorities extension is not implemented
1491  return ERROR_NOT_IMPLEMENTED;
1492 #endif
1493 }
1494 
1495 
1496 /**
1497  * @brief Enable secure renegotiation
1498  * @param[in] context Pointer to the TLS context
1499  * @param[in] enabled Specifies whether secure renegotiation is allowed
1500  * @return Error code
1501  **/
1502 
1504 {
1505 #if (TLS_SECURE_RENEGOTIATION_SUPPORT == ENABLED)
1506  //Invalid TLS context?
1507  if(context == NULL)
1508  return ERROR_INVALID_PARAMETER;
1509 
1510  //Enable or disable secure renegotiation
1511  context->secureRenegoEnabled = enabled;
1512 
1513  //Successful processing
1514  return NO_ERROR;
1515 #else
1516  //Secure renegotiation is not implemented
1517  return ERROR_NOT_IMPLEMENTED;
1518 #endif
1519 }
1520 
1521 
1522 /**
1523  * @brief Perform fallback retry (for clients only)
1524  * @param[in] context Pointer to the TLS context
1525  * @param[in] enabled Specifies whether FALLBACK_SCSV is enabled
1526  * @return Error code
1527  **/
1528 
1530 {
1531 #if (TLS_FALLBACK_SCSV_SUPPORT == ENABLED)
1532  //Invalid TLS context?
1533  if(context == NULL)
1534  return ERROR_INVALID_PARAMETER;
1535 
1536  //Enable or disable support for FALLBACK_SCSV
1537  context->fallbackScsvEnabled = enabled;
1538 
1539  //Successful processing
1540  return NO_ERROR;
1541 #else
1542  //Not implemented
1543  return ERROR_NOT_IMPLEMENTED;
1544 #endif
1545 }
1546 
1547 
1548 /**
1549  * @brief Set ticket encryption/decryption callbacks
1550  * @param[in] context Pointer to the TLS context
1551  * @param[in] ticketEncryptCallback Ticket encryption callback function
1552  * @param[in] ticketDecryptCallback Ticket decryption callback function
1553  * @param[in] param An opaque pointer passed to the callback functions
1554  * @return Error code
1555  **/
1556 
1558  TlsTicketEncryptCallback ticketEncryptCallback,
1559  TlsTicketDecryptCallback ticketDecryptCallback, void *param)
1560 {
1561 #if (TLS_TICKET_SUPPORT == ENABLED)
1562  //Invalid TLS context?
1563  if(context == NULL)
1564  return ERROR_INVALID_PARAMETER;
1565 
1566  //Save ticket encryption/decryption callback functions
1567  context->ticketEncryptCallback = ticketEncryptCallback;
1568  context->ticketDecryptCallback = ticketDecryptCallback;
1569 
1570  //This opaque pointer will be directly passed to the callback functions
1571  context->ticketParam = param;
1572 
1573  //Successful processing
1574  return NO_ERROR;
1575 #else
1576  //Session ticket mechanism is not implemented
1577  return ERROR_NOT_IMPLEMENTED;
1578 #endif
1579 }
1580 
1581 
1582 /**
1583  * @brief Set PMTU value (for DTLS only)
1584  * @param[in] context Pointer to the TLS context
1585  * @param[in] pmtu PMTU value
1586  * @return Error code
1587  **/
1588 
1589 error_t tlsSetPmtu(TlsContext *context, size_t pmtu)
1590 {
1591 #if (DTLS_SUPPORT == ENABLED)
1592  //Invalid TLS context?
1593  if(context == NULL)
1594  return ERROR_INVALID_PARAMETER;
1595 
1596  //Make sure the PMTU value is acceptable
1597  if(pmtu < DTLS_MIN_PMTU)
1598  return ERROR_INVALID_PARAMETER;
1599 
1600  //Save PMTU value
1601  context->pmtu = pmtu;
1602 
1603  //Successful processing
1604  return NO_ERROR;
1605 #else
1606  //DTLS is not implemented
1607  return ERROR_NOT_IMPLEMENTED;
1608 #endif
1609 }
1610 
1611 
1612 /**
1613  * @brief Set timeout for blocking calls (for DTLS only)
1614  * @param[in] context Pointer to the TLS context
1615  * @param[in] timeout Maximum time to wait
1616  * @return Error code
1617  **/
1618 
1620 {
1621 #if (DTLS_SUPPORT == ENABLED)
1622  //Invalid TLS context?
1623  if(context == NULL)
1624  return ERROR_INVALID_PARAMETER;
1625 
1626  //Save timeout value
1627  context->timeout = timeout;
1628 
1629  //Successful processing
1630  return NO_ERROR;
1631 #else
1632  //DTLS is not implemented
1633  return ERROR_NOT_IMPLEMENTED;
1634 #endif
1635 }
1636 
1637 
1638 /**
1639  * @brief Set cookie generation/verification callbacks (for DTLS only)
1640  * @param[in] context Pointer to the TLS context
1641  * @param[in] cookieGenerateCallback Cookie generation callback function
1642  * @param[in] cookieVerifyCallback Cookie verification callback function
1643  * @param[in] param An opaque pointer passed to the callback functions
1644  * @return Error code
1645  **/
1646 
1648  DtlsCookieGenerateCallback cookieGenerateCallback,
1649  DtlsCookieVerifyCallback cookieVerifyCallback, void *param)
1650 {
1651 #if (DTLS_SUPPORT == ENABLED)
1652  //Invalid TLS context?
1653  if(context == NULL)
1654  return ERROR_INVALID_PARAMETER;
1655 
1656  //Check parameters
1657  if(cookieGenerateCallback == NULL || cookieVerifyCallback == NULL)
1658  return ERROR_INVALID_PARAMETER;
1659 
1660  //Save cookie generation/verification callback functions
1661  context->cookieGenerateCallback = cookieGenerateCallback;
1662  context->cookieVerifyCallback = cookieVerifyCallback;
1663 
1664  //This opaque pointer will be directly passed to the callback functions
1665  context->cookieParam = param;
1666 
1667  //Successful processing
1668  return NO_ERROR;
1669 #else
1670  //DTLS is not implemented
1671  return ERROR_NOT_IMPLEMENTED;
1672 #endif
1673 }
1674 
1675 
1676 /**
1677  * @brief Enable anti-replay mechanism (for DTLS only)
1678  * @param[in] context Pointer to the TLS context
1679  * @param[in] enabled Specifies whether anti-replay protection is enabled
1680  * @return Error code
1681  **/
1682 
1684 {
1685 #if (DTLS_SUPPORT == ENABLED && DTLS_REPLAY_DETECTION_SUPPORT == ENABLED)
1686  //Invalid TLS context?
1687  if(context == NULL)
1688  return ERROR_INVALID_PARAMETER;
1689 
1690  //Enable or disable anti-replay mechanism
1691  context->replayDetectionEnabled = enabled;
1692 
1693  //Successful processing
1694  return NO_ERROR;
1695 #else
1696  //Anti-replay mechanism is not implemented
1697  return ERROR_NOT_IMPLEMENTED;
1698 #endif
1699 }
1700 
1701 
1702 /**
1703  * @brief Send the maximum amount of 0-RTT data the server can accept
1704  * @param[in] context Pointer to the TLS context
1705  * @param[in] maxEarlyDataSize Maximum amount of 0-RTT data that the client
1706  * is allowed to send
1707  * @return Error code
1708  **/
1709 
1710 
1711 error_t tlsSetMaxEarlyDataSize(TlsContext *context, size_t maxEarlyDataSize)
1712 {
1713 #if (TLS_MAX_VERSION >= TLS_VERSION_1_3 && TLS_MIN_VERSION <= TLS_VERSION_1_3)
1714  //Invalid TLS context?
1715  if(context == NULL)
1716  return ERROR_INVALID_PARAMETER;
1717 
1718  //Save the maximum amount of 0-RTT data that the client is allowed to send
1719  context->maxEarlyDataSize = maxEarlyDataSize;
1720 
1721  //Successful processing
1722  return NO_ERROR;
1723 #else
1724  //Not implemented
1725  return ERROR_NOT_IMPLEMENTED;
1726 #endif
1727 }
1728 
1729 
1730 /**
1731  * @brief Send early data to the remote TLS server
1732  * @param[in] context Pointer to the TLS context
1733  * @param[in] data Pointer to a buffer containing the data to be transmitted
1734  * @param[in] length Number of bytes to be transmitted
1735  * @param[out] written Actual number of bytes written (optional parameter)
1736  * @param[in] flags Set of flags that influences the behavior of this function
1737  * @return Error code
1738  **/
1739 
1741  size_t length, size_t *written, uint_t flags)
1742 {
1743 #if (TLS_MAX_VERSION >= TLS_VERSION_1_3 && TLS_MIN_VERSION <= TLS_VERSION_1_3 && \
1744  TLS_CLIENT_SUPPORT == ENABLED && TLS13_EARLY_DATA_SUPPORT == ENABLED)
1745  size_t n;
1746  error_t error;
1747 
1748  //Invalid TLS context?
1749  if(context == NULL)
1750  return ERROR_INVALID_PARAMETER;
1751 
1752  //Check parameters
1753  if(data == NULL && length != 0)
1754  return ERROR_INVALID_PARAMETER;
1755 
1756  //Check operation mode
1757  if(context->entity != TLS_CONNECTION_END_CLIENT)
1758  return ERROR_FAILURE;
1759 
1760  //Check transport protocol
1761  if(context->transportProtocol != TLS_TRANSPORT_PROTOCOL_STREAM)
1762  return ERROR_FAILURE;
1763 
1764  //Make sure TLS 1.3 is supported by the client
1765  if(context->versionMax < TLS_VERSION_1_3)
1766  return ERROR_FAILURE;
1767 
1768  //Ensure the send/receive functions are properly registered
1769  if(context->socketSendCallback == NULL || context->socketReceiveCallback == NULL)
1770  return ERROR_NOT_CONFIGURED;
1771 
1772  //Verify that the PRNG is properly set
1773  if(context->prngAlgo == NULL || context->prngContext == NULL)
1774  return ERROR_NOT_CONFIGURED;
1775 
1776 #if (DTLS_SUPPORT == ENABLED)
1777  //Save current time
1778  context->startTime = osGetSystemTime();
1779 #endif
1780 
1781  //Send 0-RTT data
1782  error = tls13SendEarlyData(context, data, length, &n);
1783 
1784  //Total number of data that have been written
1785  if(written != NULL)
1786  {
1787  *written = n;
1788  }
1789 
1790  //Return status code
1791  return error;
1792 #else
1793  //Not implemented
1794  return ERROR_NOT_IMPLEMENTED;
1795 #endif
1796 }
1797 
1798 
1799 /**
1800  * @brief Initiate the TLS handshake
1801  * @param[in] context Pointer to the TLS context
1802  * @return Error code
1803  **/
1804 
1806 {
1807  error_t error;
1808 
1809  //Invalid TLS context?
1810  if(context == NULL)
1811  return ERROR_INVALID_PARAMETER;
1812 
1813  //Ensure the send/receive functions are properly registered
1814  if(context->socketSendCallback == NULL || context->socketReceiveCallback == NULL)
1815  return ERROR_NOT_CONFIGURED;
1816 
1817  //Verify that the PRNG is properly set
1818  if(context->prngAlgo == NULL || context->prngContext == NULL)
1819  return ERROR_NOT_CONFIGURED;
1820 
1821 #if (DTLS_SUPPORT == ENABLED)
1822  //Save current time
1823  context->startTime = osGetSystemTime();
1824 #endif
1825 
1826 #if (TLS_MAX_VERSION >= TLS_VERSION_1_3 && TLS_MIN_VERSION <= TLS_VERSION_1_3 && \
1827  TLS_CLIENT_SUPPORT == ENABLED && TLS13_EARLY_DATA_SUPPORT == ENABLED)
1828  //Any 0-RTT data sent by the client?
1829  if(context->entity == TLS_CONNECTION_END_CLIENT &&
1830  context->state == TLS_STATE_EARLY_DATA)
1831  {
1832  //Save current sequence number
1833  context->earlyDataSeqNum = context->encryptionEngine[0].seqNum;
1834  //Wait for a ServerHello message
1836  }
1837 #endif
1838 
1839  //Perform TLS handshake
1840  error = tlsPerformHandshake(context);
1841  //Return status code
1842  return error;
1843 }
1844 
1845 
1846 /**
1847  * @brief Check whether the server has accepted or rejected the early data
1848  * @param[in] context Pointer to the TLS context
1849  * @return TLS_EARLY_DATA_ACCEPTED if the early data was accepted, else
1850  * TLS_EARLY_DATA_REJECT if the early data was rejected
1851  **/
1852 
1854 {
1855  TlsEarlyDataStatus status;
1856 
1857  //Initialize early data status
1858  status = TLS_EARLY_DATA_REJECTED;
1859 
1860 #if (TLS_MAX_VERSION >= TLS_VERSION_1_3 && TLS_MIN_VERSION <= TLS_VERSION_1_3 && \
1861  TLS_CLIENT_SUPPORT == ENABLED && TLS13_EARLY_DATA_SUPPORT == ENABLED)
1862  //Make sure the TLS context is valid
1863  if(context != NULL)
1864  {
1865  //Client mode?
1866  if(context->entity == TLS_CONNECTION_END_CLIENT)
1867  {
1868  //Any 0-RTT data sent by the client?
1869  if(context->earlyDataEnabled)
1870  {
1871  //Check whether the server has accepted or rejected the early data
1872  if(context->earlyDataExtReceived && !context->earlyDataRejected)
1873  {
1874  status = TLS_EARLY_DATA_ACCEPTED;
1875  }
1876  }
1877  }
1878  }
1879 #endif
1880 
1881  //Return early data status
1882  return status;
1883 }
1884 
1885 
1886 /**
1887  * @brief Export keying material per RFC 5705 standard
1888  * @param[in] context Pointer to the TLS context
1889  * @param[in] label Identifying label (NULL-terminated string)
1890  * @param[in] useContextValue Specifies whether upper-layer context should
1891  * be used when exporting keying material
1892  * @param[in] contextValue Pointer to the upper-layer context
1893  * @param[in] contextValueLen Length of the upper-layer context
1894  * @param[out] output Buffer where to store the keying material
1895  * @param[in] outputLen Desired output length
1896  * @return Error code
1897  **/
1898 
1900  bool_t useContextValue, const uint8_t *contextValue,
1901  size_t contextValueLen, uint8_t *output, size_t outputLen)
1902 {
1903  error_t error;
1904  size_t n;
1905  uint8_t *seed;
1906 
1907  //Invalid TLS context?
1908  if(context == NULL)
1909  return ERROR_INVALID_PARAMETER;
1910 
1911  //Check parameters
1912  if(label == NULL || output == NULL)
1913  return ERROR_INVALID_PARAMETER;
1914 
1915  //Make sure the upper-layer context is valid
1916  if(contextValue == NULL && contextValueLen != 0)
1917  return ERROR_INVALID_PARAMETER;
1918 
1919  //Calculate the length of the seed
1920  n = 2 * TLS_RANDOM_SIZE;
1921 
1922  //Check whether a context is provided
1923  if(useContextValue)
1924  {
1925  n += contextValueLen + 2;
1926  }
1927 
1928  //Allocate a memory buffer to hold the seed
1929  seed = tlsAllocMem(n);
1930  //Failed to allocate memory?
1931  if(seed == NULL)
1932  return ERROR_OUT_OF_RESOURCES;
1933 
1934  //Concatenate client_random and server_random values
1935  osMemcpy(seed, context->clientRandom, TLS_RANDOM_SIZE);
1936  osMemcpy(seed + 32, context->serverRandom, TLS_RANDOM_SIZE);
1937 
1938  //Check whether a context is provided
1939  if(useContextValue)
1940  {
1941  //The context_value_length is encoded as an unsigned, 16-bit quantity
1942  //representing the length of the context value
1943  STORE16BE(contextValueLen, seed + 64);
1944 
1945  //Copy the context value provided by the application using the exporter
1946  osMemcpy(seed + 66, contextValue, contextValueLen);
1947  }
1948 
1949 #if (TLS_MAX_VERSION >= TLS_VERSION_1_0 && TLS_MIN_VERSION <= TLS_VERSION_1_1)
1950  //TLS 1.0 or TLS 1.1 currently selected?
1951  if(context->version == TLS_VERSION_1_0 || context->version == TLS_VERSION_1_1)
1952  {
1953  //TLS 1.0 and 1.1 use a PRF that combines MD5 and SHA-1
1954  error = tlsPrf(context->masterSecret, TLS_MASTER_SECRET_SIZE,
1955  label, seed, n, output, outputLen);
1956  }
1957  else
1958 #endif
1959 #if (TLS_MAX_VERSION >= TLS_VERSION_1_2 && TLS_MIN_VERSION <= TLS_VERSION_1_2)
1960  //TLS 1.2 currently selected?
1961  if(context->version == TLS_VERSION_1_2)
1962  {
1963  //Make sure the PRF hash algorithm is valid
1964  if(context->cipherSuite.prfHashAlgo != NULL)
1965  {
1966  //TLS 1.2 PRF uses SHA-256 or a stronger hash algorithm as the core
1967  //function in its construction
1968  error = tls12Prf(context->cipherSuite.prfHashAlgo, context->masterSecret,
1969  TLS_MASTER_SECRET_SIZE, label, seed, n, output, outputLen);
1970  }
1971  else
1972  {
1973  //Invalid PRF hash algorithm
1974  error = ERROR_FAILURE;
1975  }
1976  }
1977  else
1978 #endif
1979 #if (TLS_MAX_VERSION >= TLS_VERSION_1_3 && TLS_MIN_VERSION <= TLS_VERSION_1_3)
1980  //TLS 1.3 currently selected?
1981  if(context->version == TLS_VERSION_1_3)
1982  {
1983  const HashAlgo *hash;
1985  uint8_t digest[TLS_MAX_HKDF_DIGEST_SIZE];
1986 
1987  //The hash function used by HKDF is the cipher suite hash algorithm
1988  hash = context->cipherSuite.prfHashAlgo;
1989 
1990  //Make sure the HKDF hash algorithm is valid
1991  if(hash != NULL)
1992  {
1993  //Derive exporter master secret
1994  error = tls13DeriveSecret(context, context->exporterMasterSecret,
1995  hash->digestSize, label, "", 0, secret, hash->digestSize);
1996 
1997  //Check status code
1998  if(!error)
1999  {
2000  //Hash context_value input
2001  error = hash->compute(contextValue, contextValueLen, digest);
2002  }
2003 
2004  //Check status code
2005  if(!error)
2006  {
2007  //Export keying material
2008  error = tls13HkdfExpandLabel(context->transportProtocol, hash,
2009  secret, hash->digestSize, "exporter", digest, hash->digestSize,
2010  output, outputLen);
2011  }
2012  }
2013  else
2014  {
2015  //Invalid HKDF hash algorithm
2016  error = ERROR_FAILURE;
2017  }
2018  }
2019  else
2020 #endif
2021  //Invalid TLS version?
2022  {
2023  //Report an error
2024  error = ERROR_INVALID_VERSION;
2025  }
2026 
2027  //Release previously allocated memory
2028  tlsFreeMem(seed);
2029 
2030  //Return status code
2031  return error;
2032 }
2033 
2034 
2035 /**
2036  * @brief Export channel binding value
2037  * @param[in] context Pointer to the TLS context
2038  * @param[in] type Channel binding type
2039  * @param[out] output Buffer where to store the channel binding value
2040  * @param[out] length Length of the channel binding value, in bytes
2041  * @return Error code
2042  **/
2043 
2045  uint8_t *output, size_t *length)
2046 {
2047  error_t error;
2048 
2049  //Check parameters
2050  if(context == NULL || type == NULL || length == 0)
2051  return ERROR_INVALID_PARAMETER;
2052 
2053  //Initialize status code
2054  error = NO_ERROR;
2055 
2056  //Check channel binding type
2057  if(osStrcmp(type, "tls-unique") == 0)
2058  {
2059  //Check TLS version
2060  if(context->version <= TLS_VERSION_1_2)
2061  {
2062  //The "tls-unique" channel binding value is the first TLS Finished
2063  //message sent in the most recent TLS handshake of the TLS connection
2064  //being bound to (refer to RFC 5929, section 3.1)
2065  if(context->resume)
2066  {
2067  //For abbreviated TLS handshakes (session resumption), the first
2068  //Finished message is sent by the server
2069  if(output != NULL)
2070  {
2071  osMemcpy(output, context->serverVerifyData,
2072  context->serverVerifyDataLen);
2073  }
2074 
2075  //Length of the channel binding value
2076  *length = context->clientVerifyDataLen;
2077 
2078 #if (TLS_EXT_MASTER_SECRET_SUPPORT == ENABLED)
2079  //If a client or server chooses to continue an abbreviated handshake
2080  //to resume a session that does not use the extended master secret,
2081  //then the client must disable any use of the "tls-unique" channel
2082  //binding on the current connection (refer to RFC 7627, section 5.4)
2083  error = (context->emsExtReceived) ? NO_ERROR : ERROR_FAILURE;
2084 #else
2085  //The session does not use the extended master secret
2086  error = ERROR_FAILURE;
2087 #endif
2088  }
2089  else
2090  {
2091  //For full TLS handshakes, the first Finished message is sent by
2092  //the client
2093  if(output != NULL)
2094  {
2095  osMemcpy(output, context->clientVerifyData,
2096  context->clientVerifyDataLen);
2097  }
2098 
2099  //Length of the channel binding value
2100  *length = context->clientVerifyDataLen;
2101  }
2102  }
2103  else
2104  {
2105  //Appendix C.5 of RFC 8446 notes the lack of channel bindings for
2106  //TLS 1.3 (refer to to RFC 9266, section 1)
2107  }
2108  }
2109  else if(osStrcmp(type, "tls-exporter") == 0)
2110  {
2111  //The "tls-exporter" channel binding type uses Exported Keying Material
2112  //(EKM), which is already widely exposed by TLS implementations (refer
2113  //to RFC 9266, section 2)
2114  error = tlsExportKeyingMaterial(context, "EXPORTER-Channel-Binding",
2115  TRUE, NULL, 0, output, 32);
2116 
2117  //Check status code
2118  if(!error)
2119  {
2120  //The derived value consists of 32 bytes
2121  *length = 32;
2122  }
2123  }
2124  else
2125  {
2126  //Report an error
2127  error = ERROR_INVALID_TYPE;
2128  }
2129 
2130  //Return status code
2131  return error;
2132 }
2133 
2134 
2135 /**
2136  * @brief Send application data to the remote host using TLS
2137  * @param[in] context Pointer to the TLS context
2138  * @param[in] data Pointer to a buffer containing the data to be transmitted
2139  * @param[in] length Number of bytes to be transmitted
2140  * @param[out] written Actual number of bytes written (optional parameter)
2141  * @param[in] flags Set of flags that influences the behavior of this function
2142  * @return Error code
2143  **/
2144 
2145 error_t tlsWrite(TlsContext *context, const void *data, size_t length,
2146  size_t *written, uint_t flags)
2147 {
2148  error_t error;
2149  size_t n;
2150  size_t totalLength;
2151 
2152  //Invalid TLS context?
2153  if(context == NULL)
2154  return ERROR_INVALID_PARAMETER;
2155 
2156  //Check parameters
2157  if(data == NULL && length != 0)
2158  return ERROR_INVALID_PARAMETER;
2159 
2160  //Ensure the send/receive functions are properly registered
2161  if(context->socketSendCallback == NULL || context->socketReceiveCallback == NULL)
2162  return ERROR_NOT_CONFIGURED;
2163 
2164 #if (DTLS_SUPPORT == ENABLED)
2165  //Save current time
2166  context->startTime = osGetSystemTime();
2167 #endif
2168 
2169  //Initialize status code
2170  error = NO_ERROR;
2171 
2172  //Actual number of bytes written
2173  totalLength = 0;
2174 
2175  //Send as much data as possible
2176  while(totalLength < length)
2177  {
2178  //Check current state
2179  if(context->state < TLS_STATE_APPLICATION_DATA ||
2180  context->state == TLS_STATE_KEY_UPDATE)
2181  {
2182  //Perform TLS handshake
2183  error = tlsConnect(context);
2184  }
2185  else if(context->state == TLS_STATE_APPLICATION_DATA ||
2186  context->state == TLS_STATE_CLIENT_FINISHED_ACK ||
2187  context->state == TLS_STATE_NEW_SESSION_TICKET_ACK ||
2188  context->state == TLS_STATE_KEY_UPDATE_ACK)
2189  {
2190 #if (DTLS_SUPPORT == ENABLED)
2191  //DTLS protocol?
2192  if(context->transportProtocol == TLS_TRANSPORT_PROTOCOL_DATAGRAM)
2193  {
2194  //Length of the payload data
2195  n = length;
2196 
2197  //Send a datagram
2198  error = dtlsWriteProtocolData(context, data, n,
2200  }
2201  else
2202 #endif
2203  //TLS protocol?
2204  {
2205  //Calculate the number of bytes to write at a time
2206  n = MIN(length - totalLength, context->txBufferMaxLen);
2207  //The record length must not exceed 16384 bytes
2209 
2210 #if (TLS_MAX_FRAG_LEN_SUPPORT == ENABLED)
2211  //Do not exceed the negotiated maximum fragment length
2212  n = MIN(n, context->maxFragLen);
2213 #endif
2214 
2215 #if (TLS_RECORD_SIZE_LIMIT_SUPPORT == ENABLED)
2216  //Maximum record size the peer is willing to receive
2217  n = MIN(n, context->recordSizeLimit);
2218 #endif
2219 
2220 #if (TLS_MAX_VERSION >= TLS_VERSION_1_0 && TLS_MIN_VERSION <= TLS_VERSION_1_0)
2221  //The 1/n-1 record splitting technique is a workaround for the
2222  //BEAST attack
2223  if(context->version <= TLS_VERSION_1_0 &&
2224  context->cipherSuite.cipherMode == CIPHER_MODE_CBC &&
2225  context->txLastRecordLen != 1 &&
2226  totalLength == 0)
2227  {
2228  n = 1;
2229  }
2230 #endif
2231  //Send application data
2232  error = tlsWriteProtocolData(context, data, n,
2234  }
2235 
2236  //Check status code
2237  if(!error)
2238  {
2239 #if (TLS_MAX_VERSION >= TLS_VERSION_1_0 && TLS_MIN_VERSION <= TLS_VERSION_1_0)
2240  //Save the length of the TLS record
2241  context->txLastRecordLen = n;
2242 #endif
2243  //Advance data pointer
2244  data = (uint8_t *) data + n;
2245  //Update byte counter
2246  totalLength += n;
2247  }
2248  else
2249  {
2250  //Send an alert message to the peer, if applicable
2251  tlsProcessError(context, error);
2252  }
2253  }
2254  else
2255  {
2256  //The connection has not yet been established
2257  error = ERROR_NOT_CONNECTED;
2258  }
2259 
2260  //Any error to report?
2261  if(error)
2262  break;
2263  }
2264 
2265  //Total number of data that have been written
2266  if(written != NULL)
2267  {
2268  *written = totalLength;
2269  }
2270 
2271  //Return status code
2272  return error;
2273 }
2274 
2275 
2276 /**
2277  * @brief Receive application data from a the remote host using TLS
2278  * @param[in] context Pointer to the TLS context
2279  * @param[out] data Buffer into which received data will be placed
2280  * @param[in] size Maximum number of bytes that can be received
2281  * @param[out] received Number of bytes that have been received
2282  * @param[in] flags Set of flags that influences the behavior of this function
2283  * @return Error code
2284  **/
2285 
2286 error_t tlsRead(TlsContext *context, void *data, size_t size, size_t *received,
2287  uint_t flags)
2288 {
2289  error_t error;
2290  size_t i;
2291  size_t n;
2292  uint8_t *p;
2293  TlsContentType contentType;
2294 
2295  //Invalid TLS context?
2296  if(context == NULL)
2297  return ERROR_INVALID_PARAMETER;
2298 
2299  //Check parameters
2300  if(data == NULL || received == NULL)
2301  return ERROR_INVALID_PARAMETER;
2302 
2303  //Ensure the send/receive functions are properly registered
2304  if(context->socketSendCallback == NULL || context->socketReceiveCallback == NULL)
2305  return ERROR_NOT_CONFIGURED;
2306 
2307 #if (DTLS_SUPPORT == ENABLED)
2308  //Save current time
2309  context->startTime = osGetSystemTime();
2310 #endif
2311 
2312  //Initialize status code
2313  error = NO_ERROR;
2314 
2315  //No data has been read yet
2316  *received = 0;
2317 
2318  //Read as much data as possible
2319  while(*received < size)
2320  {
2321  //Check current state
2322  if(context->state < TLS_STATE_APPLICATION_DATA ||
2323  context->state == TLS_STATE_KEY_UPDATE)
2324  {
2325  //Perform TLS handshake
2326  error = tlsConnect(context);
2327  }
2328  else if(context->state == TLS_STATE_APPLICATION_DATA ||
2329  context->state == TLS_STATE_CLIENT_FINISHED_ACK ||
2330  context->state == TLS_STATE_NEW_SESSION_TICKET_ACK ||
2331  context->state == TLS_STATE_KEY_UPDATE_ACK)
2332  {
2333 #if (DTLS_SUPPORT == ENABLED)
2334  //DTLS protocol?
2335  if(context->transportProtocol == TLS_TRANSPORT_PROTOCOL_DATAGRAM)
2336  {
2337  //Receive a datagram
2338  error = dtlsReadProtocolData(context, &p, &n, &contentType);
2339  }
2340  else
2341 #endif
2342  //TLS protocol?
2343  {
2344  //The record layer receives uninterpreted data from higher layers
2345  error = tlsReadProtocolData(context, &p, &n, &contentType);
2346  }
2347 
2348  //Check status code
2349  if(!error)
2350  {
2351  //Application data received?
2352  if(contentType == TLS_TYPE_APPLICATION_DATA)
2353  {
2354 #if (DTLS_SUPPORT == ENABLED)
2355  //DTLS protocol?
2356  if(context->transportProtocol == TLS_TRANSPORT_PROTOCOL_DATAGRAM)
2357  {
2358  //Make sure the user buffer is large enough to hold the whole
2359  //datagram
2360  if(n > size)
2361  {
2362  //Report an error
2363  error = ERROR_BUFFER_OVERFLOW;
2364  }
2365  else
2366  {
2367  //Copy data to user buffer
2368  osMemcpy(data, p, n);
2369  //Total number of data that have been read
2370  *received = n;
2371  }
2372 
2373  //If the TLS_FLAG_PEEK flag is set, the data is copied into
2374  //the buffer but is not removed from the receive queue
2375  if((flags & TLS_FLAG_PEEK) == 0)
2376  {
2377  //Flush receive buffer
2378  context->rxBufferPos = 0;
2379  context->rxBufferLen = 0;
2380  }
2381 
2382  //We are done
2383  break;
2384  }
2385  else
2386 #endif
2387  //TLS protocol?
2388  {
2389  //Limit the number of bytes to read at a time
2390  n = MIN(n, size - *received);
2391 
2392  //The TLS_FLAG_BREAK_CHAR flag causes the function to stop reading
2393  //data as soon as the specified break character is encountered
2394  if((flags & TLS_FLAG_BREAK_CHAR) != 0)
2395  {
2396  //Retrieve the break character code
2397  char_t c = LSB(flags);
2398 
2399  //Search for the specified break character
2400  for(i = 0; i < n && p[i] != c; i++)
2401  {
2402  }
2403 
2404  //Adjust the number of data to read
2405  n = MIN(n, i + 1);
2406 
2407  //Copy data to user buffer
2408  osMemcpy(data, p, n);
2409  //Total number of data that have been read
2410  *received += n;
2411 
2412  //Advance data pointer
2413  context->rxBufferPos += n;
2414  //Number of bytes still pending in the receive buffer
2415  context->rxBufferLen -= n;
2416 
2417  //Check whether a break character has been found
2418  if(n > 0 && p[n - 1] == c)
2419  break;
2420  }
2421  else
2422  {
2423  //Copy data to user buffer
2424  osMemcpy(data, p, n);
2425  //Total number of data that have been read
2426  *received += n;
2427 
2428  //Advance data pointer
2429  context->rxBufferPos += n;
2430  //Number of bytes still pending in the receive buffer
2431  context->rxBufferLen -= n;
2432 
2433  //The TLS_FLAG_WAIT_ALL flag causes the function to return
2434  //only when the requested number of bytes have been read
2435  if((flags & TLS_FLAG_WAIT_ALL) == 0)
2436  break;
2437  }
2438 
2439  //Advance data pointer
2440  data = (uint8_t *) data + n;
2441  }
2442  }
2443  //Handshake message received?
2444  else if(contentType == TLS_TYPE_HANDSHAKE)
2445  {
2446  //Advance data pointer
2447  context->rxBufferPos += n;
2448  //Number of bytes still pending in the receive buffer
2449  context->rxBufferLen -= n;
2450 
2451  //Parse handshake message
2452  error = tlsParseHandshakeMessage(context, p, n);
2453  }
2454  //Alert message received?
2455  else if(contentType == TLS_TYPE_ALERT)
2456  {
2457  //Advance data pointer
2458  context->rxBufferPos += n;
2459  //Number of bytes still pending in the receive buffer
2460  context->rxBufferLen -= n;
2461 
2462  //Parse Alert message
2463  error = tlsParseAlert(context, (TlsAlert *) p, n);
2464  }
2465 #if (DTLS_SUPPORT == ENABLED && TLS_MAX_VERSION >= TLS_VERSION_1_3)
2466  //ACK message received?
2467  else if(contentType == TLS_TYPE_ACK)
2468  {
2469  //Advance data pointer
2470  context->rxBufferPos += n;
2471  //Number of bytes still pending in the receive buffer
2472  context->rxBufferLen -= n;
2473 
2474  //Parse ACK message
2475  error = dtls13ParseAck(context, (Dtls13Ack *) p, n);
2476  }
2477 #endif
2478  //An inappropriate message was received?
2479  else
2480  {
2481  //Report an error
2482  error = ERROR_UNEXPECTED_MESSAGE;
2483  }
2484  }
2485 
2486  //Any error to report?
2487  if(error)
2488  {
2489  //Send an alert message to the peer, if applicable
2490  tlsProcessError(context, error);
2491  }
2492  }
2493  else if(context->state == TLS_STATE_CLOSING ||
2494  context->state == TLS_STATE_CLOSED)
2495  {
2496  //Check whether a fatal alert message has been sent or received
2497  if(context->fatalAlertSent || context->fatalAlertReceived)
2498  {
2499  //Alert messages with a level of fatal result in the immediate
2500  //termination of the connection
2501  error = ERROR_FAILURE;
2502  }
2503  else
2504  {
2505  //The user must be satisfied with data already on hand
2506  if(*received > 0)
2507  {
2508  //Some data are pending in the receive buffer
2509  error = NO_ERROR;
2510  break;
2511  }
2512  else
2513  {
2514  //The receive buffer is empty
2515  error = ERROR_END_OF_STREAM;
2516  }
2517  }
2518  }
2519  else
2520  {
2521  //The connection has not yet been established
2522  error = ERROR_NOT_CONNECTED;
2523  }
2524 
2525  //Any error to report?
2526  if(error)
2527  break;
2528  }
2529 
2530  //Return status code
2531  return error;
2532 }
2533 
2534 
2535 /**
2536  * @brief Check whether some data is ready for transmission
2537  * @param[in] context Pointer to the TLS context
2538  * @return The function returns TRUE if some data is ready for transmission.
2539  * Otherwise, FALSE is returned
2540  **/
2541 
2543 {
2544  bool_t ready;
2545 
2546  //Initialize flag
2547  ready = FALSE;
2548 
2549  //Make sure the TLS context is valid
2550  if(context != NULL)
2551  {
2552  //TLS protocol?
2553  if(context->transportProtocol == TLS_TRANSPORT_PROTOCOL_STREAM ||
2554  context->transportProtocol == TLS_TRANSPORT_PROTOCOL_EAP)
2555  {
2556  //Check whether some data is pending in the transmit buffer
2557  if(context->txBufferPos < context->txBufferLen)
2558  {
2559  ready = TRUE;
2560  }
2561  }
2562  }
2563 
2564  //The function returns TRUE if some data is ready for transmission
2565  return ready;
2566 }
2567 
2568 
2569 /**
2570  * @brief Check whether some data is available in the receive buffer
2571  * @param[in] context Pointer to the TLS context
2572  * @return The function returns TRUE if some data is pending and can be read
2573  * immediately without blocking. Otherwise, FALSE is returned
2574  **/
2575 
2577 {
2578  bool_t ready;
2579 
2580  //Initialize flag
2581  ready = FALSE;
2582 
2583  //Make sure the TLS context is valid
2584  if(context != NULL)
2585  {
2586 #if (DTLS_SUPPORT == ENABLED)
2587  //DTLS protocol?
2588  if(context->transportProtocol == TLS_TRANSPORT_PROTOCOL_DATAGRAM)
2589  {
2590  //Check whether a datagram is pending in the receive buffer
2591  if(context->rxBufferLen > 0 ||
2592  context->rxRecordLen > 0 ||
2593  context->rxDatagramLen > 0)
2594  {
2595  ready = TRUE;
2596  }
2597  }
2598  else
2599 #endif
2600  //TLS protocol?
2601  {
2602  //Check whether some data is pending in the receive buffer
2603  if(context->rxBufferLen > 0)
2604  {
2605  ready = TRUE;
2606  }
2607  }
2608  }
2609 
2610  //The function returns TRUE if some data can be read immediately without
2611  //blocking
2612  return ready;
2613 }
2614 
2615 
2616 /**
2617  * @brief Gracefully close TLS session
2618  * @param[in] context Pointer to the TLS context
2619  **/
2620 
2622 {
2623  //Either party may initiate a close by sending a close_notify alert
2624  return tlsShutdownEx(context, FALSE);
2625 }
2626 
2627 
2628 /**
2629  * @brief Gracefully close TLS session
2630  * @param[in] context Pointer to the TLS context
2631  * @param[in] waitForCloseNotify Wait for the close notify alert from the peer
2632  **/
2633 
2634 error_t tlsShutdownEx(TlsContext *context, bool_t waitForCloseNotify)
2635 {
2636  error_t error;
2637  size_t n;
2638  uint8_t *p;
2639  TlsContentType contentType;
2640 
2641  //Invalid TLS context?
2642  if(context == NULL)
2643  return ERROR_INVALID_PARAMETER;
2644 
2645  //Ensure the send/receive functions are properly registered
2646  if(context->socketSendCallback == NULL || context->socketReceiveCallback == NULL)
2647  return ERROR_NOT_CONFIGURED;
2648 
2649 #if (DTLS_SUPPORT == ENABLED)
2650  //Save current time
2651  context->startTime = osGetSystemTime();
2652 #endif
2653 
2654  //Initialize status code
2655  error = NO_ERROR;
2656 
2657  //Wait for the TLS session to be closed
2658  while(context->state != TLS_STATE_CLOSED)
2659  {
2660  //Check current state
2661  if(context->state == TLS_STATE_APPLICATION_DATA ||
2662  context->state == TLS_STATE_CLIENT_FINISHED_ACK ||
2663  context->state == TLS_STATE_NEW_SESSION_TICKET_ACK ||
2664  context->state == TLS_STATE_KEY_UPDATE_ACK)
2665  {
2666  //TLS protocol?
2667  if(context->transportProtocol == TLS_TRANSPORT_PROTOCOL_STREAM ||
2668  context->transportProtocol == TLS_TRANSPORT_PROTOCOL_EAP)
2669  {
2670  //Flush send buffer
2671  error = tlsWriteProtocolData(context, NULL, 0, TLS_TYPE_NONE);
2672  }
2673 
2674  //Check status code
2675  if(!error)
2676  {
2677  //Either party may initiate a close by sending a close_notify alert
2679  }
2680  }
2681  else if(context->state == TLS_STATE_CLOSING)
2682  {
2683  //TLS protocol?
2684  if(context->transportProtocol == TLS_TRANSPORT_PROTOCOL_STREAM ||
2685  context->transportProtocol == TLS_TRANSPORT_PROTOCOL_EAP)
2686  {
2687  //Flush send buffer
2688  error = tlsWriteProtocolData(context, NULL, 0, TLS_TYPE_NONE);
2689  }
2690 
2691  //Check status code
2692  if(!error)
2693  {
2694  //Unless some other fatal alert has been transmitted, each party
2695  //is required to send a close_notify alert before closing the
2696  //write side of the connection
2697  if(context->fatalAlertSent || context->fatalAlertReceived)
2698  {
2699  //Close the connection immediately
2700  tlsChangeState(context, TLS_STATE_CLOSED);
2701  }
2702  else if(!context->closeNotifySent)
2703  {
2704  //Notifies the recipient that the sender will not send any
2705  //more messages on this connection
2706  error = tlsSendAlert(context, TLS_ALERT_LEVEL_WARNING,
2708  }
2709  else if(!context->closeNotifyReceived && waitForCloseNotify)
2710  {
2711 #if (DTLS_SUPPORT == ENABLED)
2712  //DTLS protocol?
2713  if(context->transportProtocol == TLS_TRANSPORT_PROTOCOL_DATAGRAM)
2714  {
2715  //Wait for the responding close_notify alert
2716  error = dtlsReadProtocolData(context, &p, &n, &contentType);
2717  }
2718  else
2719 #endif
2720  //TLS protocol?
2721  {
2722  //Wait for the responding close_notify alert
2723  error = tlsReadProtocolData(context, &p, &n, &contentType);
2724  }
2725 
2726  //Check status code
2727  if(!error)
2728  {
2729  //Advance data pointer
2730  context->rxBufferPos += n;
2731  //Number of bytes still pending in the receive buffer
2732  context->rxBufferLen -= n;
2733 
2734  //Application data received?
2735  if(contentType == TLS_TYPE_APPLICATION_DATA)
2736  {
2737  //Discard application data
2738  }
2739  //Alert message received?
2740  else if(contentType == TLS_TYPE_ALERT)
2741  {
2742  //Parse Alert message
2743  error = tlsParseAlert(context, (TlsAlert *) p, n);
2744  }
2745  else if(contentType == TLS_TYPE_HANDSHAKE)
2746  {
2747  //Parse handshake message
2748  error = tlsParseHandshakeMessage(context, p, n);
2749  }
2750  //An inappropriate message was received?
2751  else
2752  {
2753  //Report an error
2754  error = ERROR_UNEXPECTED_MESSAGE;
2755  }
2756  }
2757  }
2758  else
2759  {
2760  //The connection is closed
2761  tlsChangeState(context, TLS_STATE_CLOSED);
2762  }
2763  }
2764  }
2765  else
2766  {
2767  //Report an error
2768  error = ERROR_NOT_CONNECTED;
2769  }
2770 
2771  //Any error to report?
2772  if(error)
2773  break;
2774  }
2775 
2776  //Return status code
2777  return error;
2778 }
2779 
2780 
2781 /**
2782  * @brief Handle periodic operations
2783  * @param[in] context Pointer to the TLS context
2784  * @return Error code
2785  **/
2786 
2788 {
2789  error_t error;
2790 
2791 #if (DTLS_SUPPORT == ENABLED)
2792  //Valid DTLS context?
2793  if(context != NULL &&
2794  context->transportProtocol == TLS_TRANSPORT_PROTOCOL_DATAGRAM)
2795  {
2796  //Manage retransmission timers
2797  error = dtlsTick(context);
2798  }
2799  else
2800 #endif
2801  {
2802  //Report an error
2803  error = ERROR_INVALID_PARAMETER;
2804  }
2805 
2806  //Return status code
2807  return error;
2808 }
2809 
2810 
2811 /**
2812  * @brief Release TLS context
2813  * @param[in] context Pointer to the TLS context
2814  **/
2815 
2816 void tlsFree(TlsContext *context)
2817 {
2818  uint_t i;
2819 
2820  //Valid TLS context?
2821  if(context != NULL)
2822  {
2823  //Release server name
2824  if(context->serverName != NULL)
2825  {
2826  tlsFreeMem(context->serverName);
2827  }
2828 
2829  //Release cookie
2830  if(context->cookie != NULL)
2831  {
2832  osMemset(context->cookie, 0, context->cookieLen);
2833  tlsFreeMem(context->cookie);
2834  }
2835 
2836  //Release send buffer
2837  if(context->txBuffer != NULL)
2838  {
2839  osMemset(context->txBuffer, 0, context->txBufferSize);
2840  tlsFreeMem(context->txBuffer);
2841  }
2842 
2843  //Release receive buffer
2844  if(context->rxBuffer != NULL)
2845  {
2846  osMemset(context->rxBuffer, 0, context->rxBufferSize);
2847  tlsFreeMem(context->rxBuffer);
2848  }
2849 
2850  //Release transcript hash context
2851  tlsFreeTranscriptHash(context);
2852 
2853  //Release session ticket
2854  if(context->ticket != NULL)
2855  {
2856  osMemset(context->ticket, 0, context->ticketLen);
2857  tlsFreeMem(context->ticket);
2858  }
2859 
2860 #if (TLS_MAX_VERSION >= TLS_VERSION_1_3 && TLS_MIN_VERSION <= TLS_VERSION_1_3)
2861  //Release the ALPN protocol associated with the ticket
2862  if(context->ticketAlpn != NULL)
2863  {
2864  tlsFreeMem(context->ticketAlpn);
2865  }
2866 #endif
2867 
2868 #if (TLS_DH_SUPPORT == ENABLED)
2869  //Release Diffie-Hellman context
2870  dhFree(&context->dhContext);
2871 #endif
2872 
2873 #if (TLS_ECDH_SUPPORT == ENABLED || TLS_HYBRID_SUPPORT == ENABLED)
2874  //Release ECDH context
2875  ecdhFree(&context->ecdhContext);
2876 #endif
2877 
2878 #if (TLS_MLKEM_SUPPORT == ENABLED || TLS_HYBRID_SUPPORT == ENABLED)
2879  //Release KEM context
2880  kemFree(&context->kemContext);
2881 #endif
2882 
2883 #if (TLS_RSA_SUPPORT == ENABLED)
2884  //Release peer's RSA public key
2885  rsaFreePublicKey(&context->peerRsaPublicKey);
2886 #endif
2887 
2888 #if (TLS_DSA_SIGN_SUPPORT == ENABLED)
2889  //Release peer's DSA public key
2890  dsaFreePublicKey(&context->peerDsaPublicKey);
2891 #endif
2892 
2893 #if (TLS_ECDSA_SIGN_SUPPORT == ENABLED || TLS_SM2_SIGN_SUPPORT == ENABLED)
2894  //Release peer's EC public key
2895  ecFreePublicKey(&context->peerEcPublicKey);
2896 #endif
2897 
2898 #if (TLS_ED25519_SIGN_SUPPORT == ENABLED || TLS_ED448_SIGN_SUPPORT == ENABLED)
2899  //Release peer's EdDSA public key
2900  eddsaFreePublicKey(&context->peerEddsaPublicKey);
2901 #endif
2902 
2903 #if (TLS_MLDSA44_SIGN_SUPPORT == ENABLED || TLS_MLDSA65_SIGN_SUPPORT == ENABLED || \
2904  TLS_MLDSA87_SIGN_SUPPORT == ENABLED)
2905  //Release peer's ML-DSA public key
2906  mldsaFreePublicKey(&context->peerMldsaPublicKey);
2907 #endif
2908 
2909 #if (TLS_PSK_SUPPORT == ENABLED)
2910  //Release the pre-shared key
2911  if(context->psk != NULL)
2912  {
2913  osMemset(context->psk, 0, context->pskLen);
2914  tlsFreeMem(context->psk);
2915  }
2916 
2917  //Release the PSK identity
2918  if(context->pskIdentity != NULL)
2919  {
2920  tlsFreeMem(context->pskIdentity);
2921  }
2922 
2923  //Release the PSK identity hint
2924  if(context->pskIdentityHint != NULL)
2925  {
2926  tlsFreeMem(context->pskIdentityHint);
2927  }
2928 #endif
2929 
2930 #if (TLS_ALPN_SUPPORT == ENABLED)
2931  //Release the list of supported ALPN protocols
2932  if(context->protocolList != NULL)
2933  {
2934  tlsFreeMem(context->protocolList);
2935  }
2936 
2937  //Release the selected ALPN protocol
2938  if(context->selectedProtocol != NULL)
2939  {
2940  tlsFreeMem(context->selectedProtocol);
2941  }
2942 #endif
2943 
2944  //Release encryption engines
2945  for(i = 0; i < TLS_MAX_ENCRYPTION_ENGINES; i++)
2946  {
2947  tlsFreeEncryptionEngine(&context->encryptionEngine[i]);
2948  }
2949 
2950  //Release decryption engines
2951  for(i = 0; i < TLS_MAX_DECRYPTION_ENGINES; i++)
2952  {
2953  tlsFreeEncryptionEngine(&context->decryptionEngine[i]);
2954  }
2955 
2956 #if (TLS_QUIC_SUPPORT == ENABLED)
2957  //Release local QUIC transport parameters
2958  if(context->localQuicTransportParams != NULL)
2959  {
2960  tlsFreeMem(context->localQuicTransportParams);
2961  }
2962 
2963  //Release remote QUIC transport parameters
2964  if(context->remoteQuicTransportParams != NULL)
2965  {
2966  tlsFreeMem(context->remoteQuicTransportParams);
2967  }
2968 #endif
2969 
2970  //Clear the TLS context before freeing memory
2971  osMemset(context, 0, sizeof(TlsContext));
2972  tlsFreeMem(context);
2973  }
2974 }
2975 
2976 
2977 /**
2978  * @brief Initialize session state
2979  * @param[in] session Pointer to the session state
2980  * @return Error code
2981  **/
2982 
2984 {
2985  //Make sure the session state is valid
2986  if(session == NULL)
2987  return ERROR_INVALID_PARAMETER;
2988 
2989  //Erase session state
2990  osMemset(session, 0, sizeof(TlsSessionState));
2991 
2992  //Successful initialization
2993  return NO_ERROR;
2994 }
2995 
2996 
2997 /**
2998  * @brief Save TLS session
2999  * @param[in] context Pointer to the TLS context
3000  * @param[out] session Pointer to the session state
3001  * @return Error code
3002  **/
3003 
3005  TlsSessionState *session)
3006 {
3007  error_t error;
3008 
3009  //Check parameters
3010  if(context == NULL || session == NULL)
3011  return ERROR_INVALID_PARAMETER;
3012 
3013  //Release previous session state
3014  tlsFreeSessionState(session);
3015 
3016 #if (TLS_MAX_VERSION >= TLS_VERSION_1_0 && TLS_MIN_VERSION <= TLS_VERSION_1_2)
3017  //TLS 1.0, TLS 1.1 or TLS 1.2 currently selected?
3018  if(context->version >= TLS_VERSION_1_0 && context->version <= TLS_VERSION_1_2)
3019  {
3020  //Valid session?
3021  if(context->ticketLen > 0)
3022  {
3023  //Save session ticket
3024  error = tlsSaveSessionTicket(context, session);
3025  }
3026  else if(context->sessionIdLen > 0)
3027  {
3028  //Save session identifier
3029  error = tlsSaveSessionId(context, session);
3030  }
3031  else
3032  {
3033  //No valid session to save
3034  error = ERROR_INVALID_SESSION;
3035  }
3036  }
3037  else
3038 #endif
3039 #if (TLS_MAX_VERSION >= TLS_VERSION_1_3 && TLS_MIN_VERSION <= TLS_VERSION_1_3)
3040  //TLS 1.3 currently selected?
3041  if(context->version == TLS_VERSION_1_3)
3042  {
3043  //Save session ticket
3044  error = tls13SaveSessionTicket(context, session);
3045  }
3046  else
3047 #endif
3048  //Invalid TLS version?
3049  {
3050  //Do not save session state
3051  error = ERROR_INVALID_VERSION;
3052  }
3053 
3054  //Check status code
3055  if(error)
3056  {
3057  //Clean up side effects
3058  tlsFreeSessionState(session);
3059  }
3060 
3061  //Successful processing
3062  return NO_ERROR;
3063 }
3064 
3065 
3066 /**
3067  * @brief Restore TLS session
3068  * @param[in] context Pointer to the TLS context
3069  * @param[in] session Pointer to the session state to be restored
3070  * @return Error code
3071  **/
3072 
3074  const TlsSessionState *session)
3075 {
3076  //Check parameters
3077  if(context == NULL || session == NULL)
3078  return ERROR_INVALID_PARAMETER;
3079 
3080 #if (TLS_MAX_VERSION >= TLS_VERSION_1_0 && TLS_MIN_VERSION <= TLS_VERSION_1_2)
3081  //TLS 1.0, TLS 1.1 or TLS 1.2 currently selected?
3082  if(session->version >= TLS_VERSION_1_0 && session->version <= TLS_VERSION_1_2)
3083  {
3084  //Valid session?
3085  if(session->ticketLen > 0)
3086  {
3087  //Restore a TLS session using session ticket
3088  tlsRestoreSessionTicket(context, session);
3089  }
3090  else if(session->sessionIdLen > 0)
3091  {
3092  //Restore a TLS session using session ID
3093  tlsRestoreSessionId(context, session);
3094  }
3095  else
3096  {
3097  //No valid session to restore
3098  }
3099  }
3100  else
3101 #endif
3102 #if (TLS_MAX_VERSION >= TLS_VERSION_1_3 && TLS_MIN_VERSION <= TLS_VERSION_1_3)
3103  //TLS 1.3 currently selected?
3104  if(session->version == TLS_VERSION_1_3)
3105  {
3106  //Restore TLS session using session ticket
3107  tls13RestoreSessionTicket(context, session);
3108  }
3109  else
3110 #endif
3111  //Invalid TLS version?
3112  {
3113  //Do not restore session state
3114  }
3115 
3116  //Successful processing
3117  return NO_ERROR;
3118 }
3119 
3120 
3121 /**
3122  * @brief Properly dispose a session state
3123  * @param[in] session Pointer to the session state to be released
3124  **/
3125 
3127 {
3128  //Make sure the session state is valid
3129  if(session != NULL)
3130  {
3131  //Release session ticket
3132  if(session->ticket != NULL)
3133  {
3134  osMemset(session->ticket, 0, session->ticketLen);
3135  tlsFreeMem(session->ticket);
3136  }
3137 
3138 #if (TLS_MAX_VERSION >= TLS_VERSION_1_3 && TLS_MIN_VERSION <= TLS_VERSION_1_3)
3139  //Release the ALPN protocol associated with the ticket
3140  if(session->ticketAlpn != NULL)
3141  {
3142  tlsFreeMem(session->ticketAlpn);
3143  }
3144 #endif
3145 
3146 #if (TLS_SNI_SUPPORT == ENABLED)
3147  //Release server name
3148  if(session->serverName != NULL)
3149  {
3150  tlsFreeMem(session->serverName);
3151  }
3152 #endif
3153 
3154  //Erase session state
3155  osMemset(session, 0, sizeof(TlsSessionState));
3156  }
3157 }
3158 
3159 #endif
TlsContext * tlsInit(void)
TLS context initialization.
Definition: tls.c:68
error_t tlsSetSupportedGroups(TlsContext *context, const uint16_t *groups, uint_t length)
Specify the list of allowed ECDHE and FFDHE groups.
Definition: tls.c:656
Dtls13Ack
Definition: dtls13_misc.h:84
#define TLS_MAX_RECORD_LENGTH
Definition: tls.h:1015
#define tlsAllocMem(size)
Definition: tls.h:910
size_t ticketLen
Length of the session ticket.
Definition: tls.h:2254
TLS helper functions.
X.509 certificate parsing.
error_t tlsEnableSecureRenegotiation(TlsContext *context, bool_t enabled)
Enable secure renegotiation.
Definition: tls.c:1503
error_t tlsSetConnectionEnd(TlsContext *context, TlsConnectionEnd entity)
Set operation mode (client or server)
Definition: tls.c:371
@ TLS_TRANSPORT_PROTOCOL_QUIC
Definition: tls.h:1039
error_t tlsSetMaxEarlyDataSize(TlsContext *context, size_t maxEarlyDataSize)
Send the maximum amount of 0-RTT data the server can accept.
Definition: tls.c:1711
int bool_t
Definition: compiler_port.h:63
TLS cipher suites.
void rsaFreePublicKey(RsaPublicKey *key)
Release an RSA public key.
Definition: rsa.c:113
error_t tlsSaveSessionTicket(const TlsContext *context, TlsSessionState *session)
Save session ticket.
Definition: tls_misc.c:502
error_t tlsSetTransportProtocol(TlsContext *context, TlsTransportProtocol transportProtocol)
Set the transport protocol to be used.
Definition: tls.c:340
void mldsaInitPublicKey(MldsaPublicKey *key)
Initialize an ML-DSA public key.
Definition: mldsa.c:59
error_t(* TlsTicketEncryptCallback)(TlsContext *context, const uint8_t *plaintext, size_t plaintextLen, uint8_t *ciphertext, size_t *ciphertextLen, void *param)
Ticket encryption callback function.
Definition: tls.h:2135
@ TLS_ALERT_CLOSE_NOTIFY
Definition: tls.h:1166
@ CIPHER_MODE_CBC
Definition: crypto.h:1077
#define DTLS_DEFAULT_PMTU
Definition: dtls_misc.h:48
error_t tls13DeriveSecret(TlsContext *context, const uint8_t *secret, size_t secretLen, const char_t *label, const char_t *message, size_t messageLen, uint8_t *output, size_t outputLen)
Derive-Secret function.
error_t(* TlsEcdsaVerifyCallback)(TlsContext *context, const uint8_t *digest, size_t digestLen, EcdsaSignature *signature)
ECDSA signature verification callback function.
Definition: tls.h:2168
Key material generation.
error_t tlsPerformHandshake(TlsContext *context)
Perform TLS handshake.
TLS handshake.
#define TLS_MAX_PASSWORD_LEN
Definition: tls.h:809
error_t dtlsTick(TlsContext *context)
Manage retransmission timers.
Definition: dtls_record.c:1633
@ ERROR_BUFFER_OVERFLOW
Definition: error.h:143
uint8_t * ticket
Session ticket.
Definition: tls.h:2253
@ ERROR_NOT_IMPLEMENTED
Definition: error.h:66
#define PrngAlgo
Definition: crypto.h:1049
error_t tlsExportChannelBinding(TlsContext *context, const char_t *type, uint8_t *output, size_t *length)
Export channel binding value.
Definition: tls.c:2044
@ TLS_EARLY_DATA_REJECTED
Definition: tls.h:1073
error_t tlsSetPskIdentityHint(TlsContext *context, const char_t *pskIdentityHint)
Set the PSK identity hint to be used by the server.
Definition: tls.c:1118
error_t tlsPrf(const uint8_t *secret, size_t secretLen, const char_t *label, const uint8_t *seed, size_t seedLen, uint8_t *output, size_t outputLen)
Pseudorandom function (TLS 1.0 and 1.1)
@ ERROR_UNEXPECTED_MESSAGE
Definition: error.h:195
TlsState
TLS FSM states.
Definition: tls.h:1582
DtlsRecord
Definition: dtls_misc.h:185
error_t tlsEnableCertAuthorities(TlsContext *context, bool_t enabled)
Enable CertificateAuthorities extension.
Definition: tls.c:1477
uint8_t p
Definition: ndp.h:300
error_t tlsSetEcdhCallback(TlsContext *context, TlsEcdhCallback ecdhCallback)
Register ECDH key agreement callback function.
Definition: tls.c:773
TlsConnectionEnd
TLS connection end.
Definition: tls.h:1049
error_t tlsSetCertificateVerifyCallback(TlsContext *context, TlsCertVerifyCallback certVerifyCallback, void *param)
Register certificate verification callback function.
Definition: tls.c:1400
void mldsaFreePublicKey(MldsaPublicKey *key)
Release an ML-DSA public key.
Definition: mldsa.c:75
#define TRUE
Definition: os_port.h:50
error_t(* DtlsCookieGenerateCallback)(TlsContext *context, const DtlsClientParameters *clientParams, uint8_t *cookie, size_t *length, void *param)
DTLS cookie generation callback function.
Definition: dtls_misc.h:247
@ TLS_ENCRYPTION_LEVEL_INITIAL
Definition: tls.h:1630
uint8_t data[]
Definition: ethernet.h:224
@ TLS_GROUP_SECP256R1
Definition: tls.h:1516
@ TLS_TYPE_HANDSHAKE
Definition: tls.h:1108
size_t digestSize
Definition: crypto.h:1171
error_t(* TlsSocketReceiveCallback)(TlsSocketHandle handle, void *data, size_t size, size_t *received, uint_t flags)
Socket receive callback function.
Definition: tls.h:2095
error_t tlsSetCache(TlsContext *context, TlsCache *cache)
Set session cache.
Definition: tls.c:500
TlsCertificateType type
End entity certificate type.
Definition: tls.h:2292
@ ERROR_OUT_OF_RESOURCES
Definition: error.h:64
TLS 1.3 session tickets.
@ TLS_TRANSPORT_PROTOCOL_DATAGRAM
Definition: tls.h:1038
void ecdhFree(EcdhContext *context)
Release ECDH context.
Definition: ecdh.c:65
error_t tlsSaveSessionId(const TlsContext *context, TlsSessionState *session)
Save session ID.
Definition: tls_misc.c:430
void kemInit(KemContext *context, const KemAlgo *kemAlgo)
Initialize KEM context.
Definition: kem.c:48
@ TLS_STATE_APPLICATION_DATA
Definition: tls.h:1614
error_t tlsEnableTrustedCaKeys(TlsContext *context, bool_t enabled)
Enable TrustedCaKeys extension.
Definition: tls.c:1450
size_t sessionIdLen
Length of the session identifier.
Definition: tls.h:2250
uint8_t type
Definition: coap_common.h:176
error_t tlsSetSupportedSignAlgos(TlsContext *context, const uint16_t *signAlgos, uint_t length)
Specify the list of allowed signature algorithms.
Definition: tls.c:711
error_t tlsSetAlpnCallback(TlsContext *context, TlsAlpnCallback alpnCallback)
Register ALPN callback function.
Definition: tls.c:955
@ ERROR_OUT_OF_MEMORY
Definition: error.h:63
@ TLS_TYPE_ACK
Definition: tls.h:1112
error_t tlsSetEcdsaSignCallback(TlsContext *context, TlsEcdsaSignCallback ecdsaSignCallback)
Register ECDSA signature generation callback function.
Definition: tls.c:799
#define osStrcmp(s1, s2)
Definition: os_port.h:177
@ ERROR_NOT_CONFIGURED
Definition: error.h:218
uint16_t totalLength
Definition: ipv4.h:348
#define osStrlen(s)
Definition: os_port.h:171
error_t tlsEnableReplayDetection(TlsContext *context, bool_t enabled)
Enable anti-replay mechanism (for DTLS only)
Definition: tls.c:1683
Session cache.
Definition: tls.h:2274
error_t tlsShutdownEx(TlsContext *context, bool_t waitForCloseNotify)
Gracefully close TLS session.
Definition: tls.c:2634
@ ERROR_END_OF_STREAM
Definition: error.h:211
error_t tlsSetPmtu(TlsContext *context, size_t pmtu)
Set PMTU value (for DTLS only)
Definition: tls.c:1589
@ ERROR_INVALID_VERSION
Definition: error.h:118
#define TLS_RANDOM_SIZE
Definition: tls.h:1019
void kemFree(KemContext *context)
Release KEM context.
Definition: kem.c:62
void tlsFreeSessionState(TlsSessionState *session)
Properly dispose a session state.
Definition: tls.c:3126
@ TLS_CIPHER_SUITE_TYPE_TLS13
error_t(* TlsSocketSendCallback)(TlsSocketHandle handle, const void *data, size_t length, size_t *written, uint_t flags)
Socket send callback function.
Definition: tls.h:2087
#define DTLS_MIN_PMTU
Definition: dtls_misc.h:55
error_t tlsRestoreSessionState(TlsContext *context, const TlsSessionState *session)
Restore TLS session.
Definition: tls.c:3073
Certificate parsing options.
Definition: x509_common.h:1379
error_t pemImportDhParameters(DhParameters *params, const char_t *input, size_t length)
Decode a PEM file containing Diffie-Hellman parameters.
Definition: pem_import.c:137
@ TLS_CIPHER_SUITE_TYPE_SM
error_t(* TlsAlpnCallback)(TlsContext *context, const char_t *selectedProtocol)
ALPN callback function.
Definition: tls.h:2103
error_t tlsSetVersion(TlsContext *context, uint16_t versionMin, uint16_t versionMax)
Set minimum and maximum versions permitted.
Definition: tls.c:302
error_t(* TlsRpkVerifyCallback)(TlsContext *context, const uint8_t *rawPublicKey, size_t rawPublicKeyLen)
Raw public key verification callback function.
Definition: tls.h:2127
error_t tlsEnableFallbackScsv(TlsContext *context, bool_t enabled)
Perform fallback retry (for clients only)
Definition: tls.c:1529
@ TLS_ALERT_LEVEL_WARNING
Definition: tls.h:1155
error_t tlsSetMaxFragmentLength(TlsContext *context, size_t maxFragLen)
Set maximum fragment length.
Definition: tls.c:591
@ TLS_STATE_KEY_UPDATE
Definition: tls.h:1617
const char_t * tlsGetServerName(TlsContext *context)
Get the server name.
Definition: tls.c:475
error_t tls13SaveSessionTicket(const TlsContext *context, TlsSessionState *session)
Save session ticket.
Definition: tls13_ticket.c:89
error_t tlsShutdown(TlsContext *context)
Gracefully close TLS session.
Definition: tls.c:2621
size_t certChainLen
Length of the certificate chain.
Definition: tls.h:2288
#define FALSE
Definition: os_port.h:46
error_t tlsSetPsk(TlsContext *context, const uint8_t *psk, size_t length)
Set the pre-shared key to be used.
Definition: tls.c:1008
error_t pemImportCertificate(const char_t *input, size_t inputLen, uint8_t *output, size_t *outputLen, size_t *consumed)
Decode a PEM file containing a certificate.
Definition: pem_import.c:55
error_t tlsSendAlert(TlsContext *context, uint8_t level, uint8_t description)
Send Alert message.
Definition: tls_common.c:512
error_t tlsParseAlert(TlsContext *context, const TlsAlert *message, size_t length)
Parse Alert message.
Definition: tls_common.c:1613
PEM file import functions.
@ ERROR_INVALID_PARAMETER
Invalid parameter.
Definition: error.h:47
@ TLS_FLAG_PEEK
Definition: tls.h:1084
#define osMemcpy(dest, src, length)
Definition: os_port.h:147
const X509Options X509_DEFAULT_OPTIONS
Definition: x509_common.c:173
error_t tls13SendEarlyData(TlsContext *context, const void *data, size_t length, size_t *written)
Send early data to the remote TLS server.
X.509 certificate.
Definition: x509_common.h:1164
#define TlsContext
Definition: tls.h:36
error_t
Error codes.
Definition: error.h:43
DTLS record layer.
bool_t tls13IsGroupSupported(TlsContext *context, uint16_t namedGroup)
Check whether a given named group is supported.
Definition: tls13_misc.c:947
#define TLS_MAX_DECRYPTION_ENGINES
Definition: tls.h:1002
HashAlgoCompute compute
Definition: crypto.h:1174
void ecInitPublicKey(EcPublicKey *key)
Initialize an EC public key.
Definition: ec.c:52
@ TLS_CONNECTION_END_SERVER
Definition: tls.h:1051
#define TLS_MIN_RECORD_LENGTH
Definition: tls.h:1013
error_t x509ParseCertificateEx(const uint8_t *data, size_t length, X509CertInfo *certInfo, const X509Options *options)
Parse a X.509 certificate.
void tlsFreeEncryptionEngine(TlsEncryptionEngine *encryptionEngine)
Release encryption engine.
Definition: tls_misc.c:1150
void(* TlsStateChangeCallback)(TlsContext *context, TlsState state)
TLS state change callback.
Definition: tls.h:2080
TlsClientAuthMode
Client authentication mode.
Definition: tls.h:1060
error_t tlsSetTicketCallbacks(TlsContext *context, TlsTicketEncryptCallback ticketEncryptCallback, TlsTicketDecryptCallback ticketDecryptCallback, void *param)
Set ticket encryption/decryption callbacks.
Definition: tls.c:1557
#define TLS_VERSION_1_2
Definition: tls.h:97
@ TLS_FLAG_WAIT_ALL
Definition: tls.h:1085
@ TLS_GROUP_NONE
Definition: tls.h:1493
error_t tlsSetTimeout(TlsContext *context, systime_t timeout)
Set timeout for blocking calls (for DTLS only)
Definition: tls.c:1619
error_t(* TlsEcdhCallback)(TlsContext *context)
ECDH key agreement callback function.
Definition: tls.h:2153
@ ERROR_FAILURE
Generic error code.
Definition: error.h:45
#define TLS_MAX_VERSION
Definition: tls.h:137
TlsEarlyDataStatus tlsGetEarlyDataStatus(TlsContext *context)
Check whether the server has accepted or rejected the early data.
Definition: tls.c:1853
TlsAlert
Definition: tls.h:2041
#define STORE16BE(a, p)
Definition: cpu_endian.h:262
#define TLS_MIN_VERSION
Definition: tls.h:130
@ TLS_TYPE_APPLICATION_DATA
Definition: tls.h:1109
Helper functions for TLS 1.3 client.
DTLS 1.3 (Datagram Transport Layer Security)
@ TLS_TYPE_ALERT
Definition: tls.h:1107
#define TLS_VERSION_1_3
Definition: tls.h:98
@ TLS_STATE_EARLY_DATA
Definition: tls.h:1586
Handshake message processing (TLS client and server)
void dhFree(DhContext *context)
Release Diffie-Hellman context.
Definition: dh.c:71
TlsSignatureScheme signScheme
Signature scheme used to sign the end entity certificate.
Definition: tls.h:2293
bool_t tlsIsTxReady(TlsContext *context)
Check whether some data is ready for transmission.
Definition: tls.c:2542
error_t tlsSetPreferredGroup(TlsContext *context, uint16_t group)
Specify the preferred ECDHE or FFDHE group.
Definition: tls.c:683
TLS record protocol.
#define TLS_MAX_CERTIFICATES
Definition: tls.h:284
error_t tlsReadProtocolData(TlsContext *context, uint8_t **data, size_t *length, TlsContentType *contentType)
Read protocol data.
Definition: tls_record.c:157
@ TLS_TRANSPORT_PROTOCOL_EAP
Definition: tls.h:1040
@ TLS_STATE_SERVER_HELLO_3
Definition: tls.h:1591
@ TLS_HASH_ALGO_SHA256
Definition: tls.h:1306
error_t tlsEnableSessionTickets(TlsContext *context, bool_t enabled)
Enable session ticket mechanism.
Definition: tls.c:1424
@ ERROR_INVALID_TYPE
Definition: error.h:115
error_t dtlsWriteProtocolData(TlsContext *context, const uint8_t *data, size_t length, TlsContentType contentType)
Write protocol data.
Definition: dtls_record.c:62
error_t tlsSaveSessionState(const TlsContext *context, TlsSessionState *session)
Save TLS session.
Definition: tls.c:3004
uint8_t length
Definition: tcp.h:375
#define LSB(x)
Definition: os_port.h:55
error_t tlsRead(TlsContext *context, void *data, size_t size, size_t *received, uint_t flags)
Receive application data from a the remote host using TLS.
Definition: tls.c:2286
@ TLS_CLIENT_AUTH_NONE
Definition: tls.h:1061
#define MIN(a, b)
Definition: os_port.h:63
error_t tlsSetKeyLogCallback(TlsContext *context, TlsKeyLogCallback keyLogCallback)
Register key logging callback function (for debugging purpose only)
Definition: tls.c:853
error_t(* TlsCertVerifyCallback)(TlsContext *context, const X509CertInfo *certInfo, uint_t pathLen, void *param)
Certificate verification callback function.
Definition: tls.h:2119
error_t tls12Prf(const HashAlgo *hash, const uint8_t *secret, size_t secretLen, const char_t *label, const uint8_t *seed, size_t seedLen, uint8_t *output, size_t outputLen)
Pseudorandom function (TLS 1.2)
error_t tlsWriteEarlyData(TlsContext *context, const void *data, size_t length, size_t *written, uint_t flags)
Send early data to the remote TLS server.
Definition: tls.c:1740
TlsCertificateType
Certificate types.
Definition: tls.h:1272
error_t tlsSetServerName(TlsContext *context, const char_t *serverName)
Set the server name.
Definition: tls.c:425
#define TLS_MASTER_SECRET_SIZE
Definition: tls.h:858
size_t privateKeyLen
Length of the private key.
Definition: tls.h:2290
Certificate descriptor.
Definition: tls.h:2286
Transcript hash calculation.
uint8_t secret[TLS_MASTER_SECRET_SIZE]
Master secret.
Definition: tls.h:2052
@ TLS_FLAG_BREAK_CHAR
Definition: tls.h:1086
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:2264
uint32_t systime_t
System time.
error_t tlsSetRpkVerifyCallback(TlsContext *context, TlsRpkVerifyCallback rpkVerifyCallback)
Register the raw public key verification callback function.
Definition: tls.c:1193
error_t tlsSetEcdsaVerifyCallback(TlsContext *context, TlsEcdsaVerifyCallback ecdsaVerifyCallback)
Register ECDSA signature verification callback function.
Definition: tls.c:826
bool_t tlsIsRxReady(TlsContext *context)
Check whether some data is available in the receive buffer.
Definition: tls.c:2576
TlsRecord
Definition: tls.h:1910
@ TLS_TYPE_NONE
Definition: tls.h:1105
void ecdhInit(EcdhContext *context)
Initialize ECDH context.
Definition: ecdh.c:49
#define MAX(a, b)
Definition: os_port.h:67
error_t(* TlsEcdsaSignCallback)(TlsContext *context, const uint8_t *digest, size_t digestLen, EcdsaSignature *signature)
ECDSA signature generation callback function.
Definition: tls.h:2160
char char_t
Definition: compiler_port.h:55
error_t dtls13ParseAck(TlsContext *context, const Dtls13Ack *message, size_t length)
Parse ACK message.
Definition: dtls13_misc.c:257
#define TLS_VERSION_1_1
Definition: tls.h:96
TlsContentType
Content type.
Definition: tls.h:1104
@ TLS_STATE_CLOSING
Definition: tls.h:1619
@ TLS_EARLY_DATA_ACCEPTED
Definition: tls.h:1074
error_t dtlsReadProtocolData(TlsContext *context, uint8_t **data, size_t *length, TlsContentType *contentType)
Read protocol data.
Definition: dtls_record.c:167
error_t tlsSetBufferSize(TlsContext *context, size_t txBufferSize, size_t rxBufferSize)
Set TLS buffer size.
Definition: tls.c:543
TLS session state.
Definition: tls.h:2243
@ ERROR_NOT_CONNECTED
Definition: error.h:80
uint8_t n
error_t tlsParseHandshakeMessage(TlsContext *context, const uint8_t *message, size_t length)
Parse handshake message.
TlsTransportProtocol
TLS transport protocols.
Definition: tls.h:1036
TlsState tlsGetState(TlsContext *context)
Retrieve current TLS state.
Definition: tls.c:220
error_t(* DtlsCookieVerifyCallback)(TlsContext *context, const DtlsClientParameters *clientParams, const uint8_t *cookie, size_t length, void *param)
DTLS cookie verification callback function.
Definition: dtls_misc.h:256
error_t tlsSetStateChangeCallback(TlsContext *context, TlsStateChangeCallback stateChangeCallback)
Register TLS state change callback.
Definition: tls.c:246
#define TLS_VERSION_1_0
Definition: tls.h:95
char_t password[TLS_MAX_PASSWORD_LEN+1]
Password used to decrypt the private key.
Definition: tls.h:2291
@ TLS_STATE_INIT
Definition: tls.h:1583
error_t tlsGetCertificateSignAlgo(const X509CertInfo *certInfo, TlsSignatureScheme *signScheme)
Retrieve the signature algorithm used to sign the certificate.
error_t tlsSetPskCallback(TlsContext *context, TlsPskCallback pskCallback)
Register PSK callback function.
Definition: tls.c:1167
error_t tlsWriteProtocolData(TlsContext *context, const uint8_t *data, size_t length, TlsContentType contentType)
Write protocol data.
Definition: tls_record.c:54
@ TLS_STATE_CLIENT_FINISHED_ACK
Definition: tls.h:1615
error_t tlsSetSocketCallbacks(TlsContext *context, TlsSocketSendCallback socketSendCallback, TlsSocketReceiveCallback socketReceiveCallback, TlsSocketHandle handle)
Set socket send and receive callbacks.
Definition: tls.c:270
#define TLS_MAX_HKDF_DIGEST_SIZE
Definition: tls.h:986
error_t tlsSetCipherSuites(TlsContext *context, const uint16_t *cipherSuites, uint_t length)
Specify the list of allowed cipher suites.
Definition: tls.c:627
@ TLS_CONNECTION_END_CLIENT
Definition: tls.h:1050
X.509 certificate handling.
error_t tlsWrite(TlsContext *context, const void *data, size_t length, size_t *written, uint_t flags)
Send application data to the remote host using TLS.
Definition: tls.c:2145
TLS (Transport Layer Security)
uint16_t version
TLS protocol version.
Definition: tls.h:2244
void eddsaFreePublicKey(EddsaPublicKey *key)
Release an EdDSA public key.
Definition: eddsa.c:63
#define osTolower(c)
Definition: os_port.h:273
uint8_t options[]
Definition: tcp.h:364
@ TLS_GROUP_X25519
Definition: tls.h:1522
error_t tlsSetAlpnProtocolList(TlsContext *context, const char_t *protocolList)
Set the list of supported ALPN protocols.
Definition: tls.c:906
error_t tlsLoadCertificate(TlsContext *context, uint_t index, const char_t *certChain, size_t certChainLen, const char_t *privateKey, size_t privateKeyLen, const char_t *password)
Load entity's certificate.
Definition: tls.c:1256
@ TLS_TRANSPORT_PROTOCOL_STREAM
Definition: tls.h:1037
error_t tlsTick(TlsContext *context)
Handle periodic operations.
Definition: tls.c:2787
@ ERROR_INVALID_PASSWORD
Definition: error.h:281
void tlsFree(TlsContext *context)
Release TLS context.
Definition: tls.c:2816
TLS 1.3 key schedule.
const char_t * certChain
End entity certificate chain (PEM format)
Definition: tls.h:2287
Common interface for hash algorithms.
Definition: crypto.h:1165
error_t(* TlsPskCallback)(TlsContext *context, const uint8_t *pskIdentity, size_t pskIdentityLen)
Pre-shared key callback function.
Definition: tls.h:2111
error_t tlsSetClientAuthMode(TlsContext *context, TlsClientAuthMode mode)
Set client authentication mode (for servers only)
Definition: tls.c:521
const char_t * tlsGetAlpnProtocol(TlsContext *context)
Get the name of the selected ALPN protocol.
Definition: tls.c:980
error_t tlsGetCertificateType(const X509CertInfo *certInfo, TlsCertificateType *certType, TlsNamedGroup *namedCurve)
Retrieve the certificate type.
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.
uint8_t flags
Definition: tcp.h:358
error_t tlsAllowUnknownAlpnProtocols(TlsContext *context, bool_t allowed)
Allow unknown ALPN protocols.
Definition: tls.c:880
void tlsChangeState(TlsContext *context, TlsState newState)
Update TLS state.
Definition: tls_misc.c:54
TlsNamedGroup
Named groups.
Definition: tls.h:1492
error_t tlsSetCookieCallbacks(TlsContext *context, DtlsCookieGenerateCallback cookieGenerateCallback, DtlsCookieVerifyCallback cookieVerifyCallback, void *param)
Set cookie generation/verification callbacks (for DTLS only)
Definition: tls.c:1647
const char_t * privateKey
Private key (PEM format)
Definition: tls.h:2289
TlsSignatureScheme
Signature schemes.
Definition: tls.h:1336
void(* TlsKeyLogCallback)(TlsContext *context, const char_t *key)
Key logging callback function (for debugging purpose only)
Definition: tls.h:2176
error_t tlsSetPrng(TlsContext *context, const PrngAlgo *prngAlgo, void *prngContext)
Set the pseudo-random number generator to be used.
Definition: tls.c:397
unsigned int uint_t
Definition: compiler_port.h:57
#define osMemset(p, value, length)
Definition: os_port.h:141
#define tlsFreeMem(p)
Definition: tls.h:915
#define TLS_MAX_RECORD_OVERHEAD
Definition: tls.h:1017
error_t tlsSetTrustedCaList(TlsContext *context, const char_t *trustedCaList, size_t length)
Import a trusted CA list.
Definition: tls.c:1221
@ TLS_STATE_KEY_UPDATE_ACK
Definition: tls.h:1618
#define TLS_MAX_ENCRYPTION_ENGINES
Definition: tls.h:993
void eddsaInitPublicKey(EddsaPublicKey *key)
Initialize an EdDSA public key.
Definition: eddsa.c:48
error_t tlsExportKeyingMaterial(TlsContext *context, const char_t *label, bool_t useContextValue, const uint8_t *contextValue, size_t contextValueLen, uint8_t *output, size_t outputLen)
Export keying material per RFC 5705 standard.
Definition: tls.c:1899
error_t tlsInitSessionState(TlsSessionState *session)
Initialize session state.
Definition: tls.c:2983
error_t(* TlsTicketDecryptCallback)(TlsContext *context, const uint8_t *ciphertext, size_t ciphertextLen, uint8_t *plaintext, size_t *plaintextLen, void *param)
Ticket decryption callback function.
Definition: tls.h:2144
#define osStrcpy(s1, s2)
Definition: os_port.h:213
void dhInit(DhContext *context)
Initialize Diffie-Hellman context.
Definition: dh.c:54
error_t tlsSetPskIdentity(TlsContext *context, const char_t *pskIdentity)
Set the PSK identity to be used by the client.
Definition: tls.c:1069
error_t tlsConnect(TlsContext *context)
Initiate the TLS handshake.
Definition: tls.c:1805
void dsaFreePublicKey(DsaPublicKey *key)
Release a DSA public key.
Definition: dsa.c:119
@ ERROR_INVALID_SESSION
Definition: error.h:287
error_t tls13RestoreSessionTicket(TlsContext *context, const TlsSessionState *session)
Restore a TLS session using session ticket.
Definition: tls13_ticket.c:187
TlsNamedGroup namedCurve
Named curve used to generate the EC public key.
Definition: tls.h:2294
void dsaInitPublicKey(DsaPublicKey *key)
Initialize a DSA public key.
Definition: dsa.c:105
error_t tlsSetDhParameters(TlsContext *context, const char_t *params, size_t length)
Import Diffie-Hellman parameters.
Definition: tls.c:745
@ NO_ERROR
Success.
Definition: error.h:44
uint8_t c
Definition: ndp.h:514
Debugging facilities.
@ TLS_STATE_NEW_SESSION_TICKET_ACK
Definition: tls.h:1616
void rsaInitPublicKey(RsaPublicKey *key)
Initialize an RSA public key.
Definition: rsa.c:100
void * TlsSocketHandle
Socket handle.
Definition: tls.h:2073
void ecFreePublicKey(EcPublicKey *key)
Release an EC public key.
Definition: ec.c:68
TlsEarlyDataStatus
Early data status.
Definition: tls.h:1072
char_t * ticketAlpn
ALPN protocol associated with the ticket.
Definition: tls.h:2260
void tlsFreeTranscriptHash(TlsContext *context)
Release transcript hash context.
#define INFINITE_DELAY
Definition: os_port.h:75
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:1620