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