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