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