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