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