tls13_misc.c
Go to the documentation of this file.
1 /**
2  * @file tls13_misc.c
3  * @brief TLS 1.3 helper functions
4  *
5  * @section License
6  *
7  * SPDX-License-Identifier: GPL-2.0-or-later
8  *
9  * Copyright (C) 2010-2026 Oryx Embedded SARL. All rights reserved.
10  *
11  * This file is part of CycloneSSL Open.
12  *
13  * This program is free software; you can redistribute it and/or
14  * modify it under the terms of the GNU General Public License
15  * as published by the Free Software Foundation; either version 2
16  * of the License, or (at your option) any later version.
17  *
18  * This program is distributed in the hope that it will be useful,
19  * but WITHOUT ANY WARRANTY; without even the implied warranty of
20  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21  * GNU General Public License for more details.
22  *
23  * You should have received a copy of the GNU General Public License
24  * along with this program; if not, write to the Free Software Foundation,
25  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
26  *
27  * @author Oryx Embedded SARL (www.oryx-embedded.com)
28  * @version 2.6.6
29  **/
30 
31 //Switch to the appropriate trace level
32 #define TRACE_LEVEL TLS_TRACE_LEVEL
33 
34 //Dependencies
35 #include "tls/tls.h"
36 #include "tls/tls_cipher_suites.h"
37 #include "tls/tls_extensions.h"
38 #include "tls/tls_certificate.h"
40 #include "tls/tls_ffdhe.h"
41 #include "tls/tls_record.h"
42 #include "tls/tls_misc.h"
44 #include "tls13/tls13_ticket.h"
45 #include "tls13/tls13_misc.h"
46 #include "kdf/hkdf.h"
47 #include "debug.h"
48 
49 //Check TLS library configuration
50 #if (TLS_SUPPORT == ENABLED && TLS_MAX_VERSION >= TLS_VERSION_1_3)
51 
52 //Downgrade protection mechanism (TLS 1.1 or below)
53 const uint8_t tls11DowngradeRandom[8] =
54 {
55  0x44, 0x4F, 0x57, 0x4E, 0x47, 0x52, 0x44, 0x00
56 };
57 
58 //Downgrade protection mechanism (TLS 1.2)
59 const uint8_t tls12DowngradeRandom[8] =
60 {
61  0x44, 0x4F, 0x57, 0x4E, 0x47, 0x52, 0x44, 0x01
62 };
63 
64 //Special random value for HelloRetryRequest message
65 const uint8_t tls13HelloRetryRequestRandom[32] =
66 {
67  0xCF, 0x21, 0xAD, 0x74, 0xE5, 0x9A, 0x61, 0x11,
68  0xBE, 0x1D, 0x8C, 0x02, 0x1E, 0x65, 0xB8, 0x91,
69  0xC2, 0xA2, 0x11, 0x16, 0x7A, 0xBB, 0x8C, 0x5E,
70  0x07, 0x9E, 0x09, 0xE2, 0xC8, 0xA8, 0x33, 0x9C
71 };
72 
73 
74 /**
75  * @brief Compute PSK binder value
76  * @param[in] context Pointer to the TLS context
77  * @param[in] clientHello Pointer to the ClientHello message
78  * @param[in] clientHelloLen Length of the ClientHello message
79  * @param[in] truncatedClientHelloLen Length of the partial ClientHello message
80  * @param[in] identity Pointer to the PSK identity
81  * @param[out] binder Buffer where to store the resulting PSK binder
82  * @param[in] binderLen Expected length of the PSK binder
83  * @return Error code
84  **/
85 
86 error_t tls13ComputePskBinder(TlsContext *context, const void *clientHello,
87  size_t clientHelloLen, size_t truncatedClientHelloLen,
88  const Tls13PskIdentity *identity, uint8_t *binder, size_t binderLen)
89 {
90  error_t error;
91  const HashAlgo *hash;
92  uint8_t *hashContext;
93  TlsHandshake header;
94  uint8_t key[TLS_MAX_HKDF_DIGEST_SIZE];
95  uint8_t digest[TLS_MAX_HKDF_DIGEST_SIZE];
96 
97  //Check parameters
98  if(truncatedClientHelloLen >= clientHelloLen)
100 
101  //The hash function used by HKDF is the cipher suite hash algorithm
102  hash = context->cipherSuite.prfHashAlgo;
103  //Make sure the hash algorithm is valid
104  if(hash == NULL)
105  return ERROR_FAILURE;
106 
107  //Check the length of the PSK binder
108  if(binderLen != hash->digestSize)
109  return ERROR_INVALID_LENGTH;
110 
111  //Allocate a memory buffer to hold the hash context
112  hashContext = tlsAllocMem(hash->contextSize);
113  //Failed to allocate memory?
114  if(hashContext == NULL)
115  return ERROR_OUT_OF_MEMORY;
116 
117  //Intialize transcript hash
118  if(context->transcriptHashContext != NULL)
119  {
120  osMemcpy(hashContext, context->transcriptHashContext, hash->contextSize);
121  }
122  else
123  {
124  hash->init(hashContext);
125  }
126 
127  //In DTLS 1.3, the message transcript is computed over the original
128  //TLS 1.3-style handshake messages without the message_seq, fragment_offset,
129  //and fragment_length values (refer to RFC 9147, section 5.2)
130  header.msgType = TLS_TYPE_CLIENT_HELLO;
131  STORE24BE(clientHelloLen, header.length);
132 
133  //Digest the handshake message header
134  hash->update(hashContext, &header, sizeof(TlsHandshake));
135  //Digest the partial ClientHello
136  hash->update(hashContext, clientHello, truncatedClientHelloLen);
137  //Calculate transcript hash
138  hash->final(hashContext, digest);
139 
140  //Release previously allocated memory
141  tlsFreeMem(hashContext);
142 
143  //Debug message
144  TRACE_DEBUG("Transcript hash (partial ClientHello):\r\n");
145  TRACE_DEBUG_ARRAY(" ", digest, hash->digestSize);
146 
147  //Although PSKs can be established out of band, PSKs can also be established
148  //in a previous connection
149  if(tls13IsPskValid(context))
150  {
151  //Calculate early secret
152  error = hkdfExtract(hash, context->psk, context->pskLen, NULL, 0,
153  context->secret);
154  //Any error to report?
155  if(error)
156  return error;
157 
158  //Debug message
159  TRACE_DEBUG("Early secret:\r\n");
160  TRACE_DEBUG_ARRAY(" ", context->secret, hash->digestSize);
161 
162  //Calculate binder key
163  error = tls13DeriveSecret(context, context->secret, hash->digestSize,
164  "ext binder", "", 0, key, hash->digestSize);
165  //Any error to report?
166  if(error)
167  return error;
168  }
169  else if(tls13IsTicketValid(context))
170  {
171  //Calculate early secret
172  error = hkdfExtract(hash, context->ticketPsk, context->ticketPskLen,
173  NULL, 0, context->secret);
174  //Any error to report?
175  if(error)
176  return error;
177 
178  //Debug message
179  TRACE_DEBUG("Early secret:\r\n");
180  TRACE_DEBUG_ARRAY(" ", context->secret, hash->digestSize);
181 
182  //Calculate binder key
183  error = tls13DeriveSecret(context, context->secret, hash->digestSize,
184  "res binder", "", 0, key, hash->digestSize);
185  //Any error to report?
186  if(error)
187  return error;
188  }
189  else
190  {
191  //The pre-shared key is not valid
192  return ERROR_FAILURE;
193  }
194 
195  //Debug message
196  TRACE_DEBUG("Binder key:\r\n");
197  TRACE_DEBUG_ARRAY(" ", key, hash->digestSize);
198 
199  //The PskBinderEntry is computed in the same way as the Finished message
200  //but with the base key being the binder key
201  error = tls13HkdfExpandLabel(context->transportProtocol, hash, key,
202  hash->digestSize, "finished", NULL, 0, key, hash->digestSize);
203  //Any error to report?
204  if(error)
205  return error;
206 
207  //Debug message
208  TRACE_DEBUG("Finished key:\r\n");
209  TRACE_DEBUG_ARRAY(" ", key, hash->digestSize);
210 
211  //Compute PSK binder
212  error = hmacCompute(hash, key, hash->digestSize, digest, hash->digestSize,
213  binder);
214  //Any error to report?
215  if(error)
216  return error;
217 
218  //Debug message
219  TRACE_DEBUG("PSK binder:\r\n");
220  TRACE_DEBUG_ARRAY(" ", binder, binderLen);
221 
222  //Successful processing
223  return NO_ERROR;
224 }
225 
226 
227 /**
228  * @brief Key share generation
229  * @param[in] context Pointer to the TLS context
230  * @param[in] namedGroup Named group
231  * @return Error code
232  **/
233 
234 error_t tls13GenerateKeyShare(TlsContext *context, uint16_t namedGroup)
235 {
236  error_t error;
237 
238 #if ((TLS13_DHE_KE_SUPPORT == ENABLED || TLS13_PSK_DHE_KE_SUPPORT == ENABLED) && \
239  TLS_FFDHE_SUPPORT == ENABLED)
240  //Finite field group?
241  if(tls13IsFfdheGroupSupported(context, namedGroup))
242  {
243  const TlsFfdheGroup *ffdheGroup;
244 
245  //Get the FFDHE parameters that match the specified named group
246  ffdheGroup = tlsGetFfdheGroup(context, namedGroup);
247 
248  //Valid FFDHE group?
249  if(ffdheGroup != NULL)
250  {
251  //Save the named group
252  context->namedGroup = namedGroup;
253 
254  //Load FFDHE parameters
255  error = tlsLoadFfdheParameters(&context->dhContext.params, ffdheGroup);
256 
257  //Check status code
258  if(!error)
259  {
260  //Generate an ephemeral key pair
261  error = dhGenerateKeyPair(&context->dhContext, context->prngAlgo,
262  context->prngContext);
263  }
264  }
265  else
266  {
267  //The specified FFDHE group is not supported
268  error = ERROR_ILLEGAL_PARAMETER;
269  }
270  }
271  else
272 #endif
273 #if (TLS13_ECDHE_KE_SUPPORT == ENABLED || TLS13_PSK_ECDHE_KE_SUPPORT == ENABLED)
274  //Elliptic curve group?
275  if(tls13IsEcdheGroupSupported(context, namedGroup))
276  {
277  const EcCurve *curve;
278 
279  //Retrieve the elliptic curve to be used
280  curve = tlsGetCurve(context, namedGroup);
281 
282  //Valid elliptic curve?
283  if(curve != NULL)
284  {
285  //Save the named group
286  context->namedGroup = namedGroup;
287 
288  //Save elliptic curve parameters
289  error = ecdhSetCurve(&context->ecdhContext, curve);
290 
291  //Check status code
292  if(!error)
293  {
294  //Generate an ephemeral key pair
295  error = ecdhGenerateKeyPair(&context->ecdhContext,
296  context->prngAlgo, context->prngContext);
297  }
298  }
299  else
300  {
301  //Unsupported elliptic curve
302  error = ERROR_ILLEGAL_PARAMETER;
303  }
304  }
305  else
306 #endif
307 #if (TLS13_MLKEM_KE_SUPPORT == ENABLED || TLS13_PSK_MLKEM_KE_SUPPORT == ENABLED)
308  //ML-KEM key exchange method?
309  if(tls13IsMlkemGroupSupported(context, namedGroup))
310  {
311  const KemAlgo *kemAlgo;
312 
313  //Retrieve the ML-KEM algorithm to be used
314  kemAlgo = tls13GetMlkemAlgo(context, namedGroup);
315 
316  //Valid algorithm?
317  if(kemAlgo != NULL)
318  {
319  //Save the named group
320  context->namedGroup = namedGroup;
321 
322  //Initialize KEM context
323  kemFree(&context->kemContext);
324  kemInit(&context->kemContext, kemAlgo);
325 
326  //Generate a public key pk and a secret key sk
327  error = kemGenerateKeyPair(&context->kemContext, context->prngAlgo,
328  context->prngContext);
329  }
330  else
331  {
332  //Unsupported ML-KEM key exchange method
333  error = ERROR_ILLEGAL_PARAMETER;
334  }
335  }
336  else
337 #endif
338 #if (TLS13_HYBRID_KE_SUPPORT == ENABLED || TLS13_PSK_HYBRID_KE_SUPPORT == ENABLED)
339  //Hybrid key exchange method?
340  if(tls13IsHybridGroupSupported(context, namedGroup))
341  {
342  const EcCurve *curve;
343  const KemAlgo *kemAlgo;
344 
345  //Retrieve the traditional and the next-gen algorithms to be used
346  curve = tls13GetTraditionalAlgo(context, namedGroup);
347  kemAlgo = tls13GetNextGenAlgo(context, namedGroup);
348 
349  //Valid algorithms?
350  if(curve != NULL && kemAlgo != NULL)
351  {
352  //Save the named group
353  context->namedGroup = namedGroup;
354 
355  //Save elliptic curve parameters
356  error = ecdhSetCurve(&context->ecdhContext, curve);
357 
358  //Check status code
359  if(!error)
360  {
361  //DH key exchange can be modeled as a KEM, with KeyGen corresponding
362  //to selecting an exponent x as the secret key and computing the
363  //public key g^x
364  error = ecdhGenerateKeyPair(&context->ecdhContext,
365  context->prngAlgo, context->prngContext);
366  }
367 
368  //Check status code
369  if(!error)
370  {
371  //Initialize KEM context
372  kemFree(&context->kemContext);
373  kemInit(&context->kemContext, kemAlgo);
374 
375  //Generate a public key pk and a secret key sk
376  error = kemGenerateKeyPair(&context->kemContext, context->prngAlgo,
377  context->prngContext);
378  }
379  }
380  else
381  {
382  //Unsupported hybrid key exchange method
383  error = ERROR_ILLEGAL_PARAMETER;
384  }
385  }
386  else
387 #endif
388  //Unknown group?
389  {
390  //Report an error
391  error = ERROR_ILLEGAL_PARAMETER;
392  }
393 
394  //Return status code
395  return error;
396 }
397 
398 
399 /**
400  * @brief (EC)DHE shared secret generation
401  * @param[in] context Pointer to the TLS context
402  * @param[in] keyShare Pointer to the peer's (EC)DHE parameters
403  * @param[in] length Length of the (EC)DHE parameters, in bytes
404  * @return Error code
405  **/
406 
407 error_t tls13GenerateSharedSecret(TlsContext *context, const uint8_t *keyShare,
408  size_t length)
409 {
410  error_t error;
411 
412 #if (TLS13_DHE_KE_SUPPORT == ENABLED || TLS13_PSK_DHE_KE_SUPPORT == ENABLED)
413  //Finite field group?
414  if(tls13IsFfdheGroupSupported(context, context->namedGroup))
415  {
416  size_t n;
417 
418  //Retrieve the length of the modulus
419  n = mpiGetByteLength(&context->dhContext.params.p);
420 
421  //For a given Diffie-Hellman group, the padding results in all public
422  //keys having the same length (refer to RFC 8446, section 4.2.8.1)
423  if(length == n)
424  {
425  //The Diffie-Hellman public value is encoded as a big-endian integer
426  error = dhImportPeerPublicKey(&context->dhContext, keyShare, length,
428 
429  //Check status code
430  if(!error)
431  {
432  //The negotiated key (Z) is converted to a byte string by encoding
433  //in big-endian and left padded with zeros up to the size of the
434  //prime (refer to RFC 8446, section 7.4.1)
435  error = dhComputeSharedSecret(&context->dhContext,
436  context->premasterSecret, TLS_PREMASTER_SECRET_SIZE,
437  &context->premasterSecretLen);
438  }
439  }
440  else
441  {
442  //The length of the public key is not valid
443  error = ERROR_ILLEGAL_PARAMETER;
444  }
445  }
446  else
447 #endif
448 #if (TLS13_ECDHE_KE_SUPPORT == ENABLED || TLS13_PSK_ECDHE_KE_SUPPORT == ENABLED)
449  //Elliptic curve group?
450  if(tls13IsEcdheGroupSupported(context, context->namedGroup))
451  {
452  //Read peer's public key (refer to RFC 8446, section 4.2.8.2)
453  error = ecdhImportPeerPublicKey(&context->ecdhContext,
454  keyShare, length, EC_PUBLIC_KEY_FORMAT_X963);
455 
456  //Check status code
457  if(!error)
458  {
459  //ECDH shared secret calculation is performed according to IEEE Std
460  //1363-2000 (refer to RFC 8446, section 7.4.2)
461  error = ecdhComputeSharedSecret(&context->ecdhContext,
462  context->premasterSecret, TLS_PREMASTER_SECRET_SIZE,
463  &context->premasterSecretLen);
464  }
465  }
466  else
467 #endif
468  //Unknown group?
469  {
470  //Report an error
471  error = ERROR_HANDSHAKE_FAILED;
472  }
473 
474  //Return status code
475  return error;
476 }
477 
478 
479 /**
480  * @brief Encapsulation algorithm
481  * @param[in] context Pointer to the TLS context
482  * @param[in] namedGroup Named group
483  * @param[in] keyShare Pointer to the client's key share
484  * @param[in] length Length of the client's key share, in bytes
485  * @return Error code
486  **/
487 
488 error_t tls13Encapsulate(TlsContext *context, uint16_t namedGroup,
489  const uint8_t *keyShare, size_t length)
490 {
491 
492  error_t error;
493 
494 #if (TLS13_MLKEM_KE_SUPPORT == ENABLED || TLS13_PSK_MLKEM_KE_SUPPORT == ENABLED)
495  //ML-KEM key exchange method?
496  if(tls13IsMlkemGroupSupported(context, namedGroup))
497  {
498  const KemAlgo *kemAlgo;
499 
500  //Retrieve the ML-KEM algorithm to be used
501  kemAlgo = tls13GetMlkemAlgo(context, namedGroup);
502 
503  //Valid algorithm?
504  if(kemAlgo != NULL)
505  {
506  //The length of the public key is fixed
507  if(length == kemAlgo->publicKeySize)
508  {
509  //Save the named group
510  context->namedGroup = namedGroup;
511 
512  //Initialize KEM context
513  kemFree(&context->kemContext);
514  kemInit(&context->kemContext, kemAlgo);
515 
516  //The encapsulation algorithm takes as input a public key pk and
517  //outputs a ciphertext ct and shared secret ss
518  error = kemLoadPublicKey(&context->kemContext, keyShare);
519  }
520  else
521  {
522  //The length of the key share is not valid
523  error = ERROR_ILLEGAL_PARAMETER;
524  }
525  }
526  else
527  {
528  //Unsupported ML-KEM key exchange method
529  error = ERROR_ILLEGAL_PARAMETER;
530  }
531  }
532  else
533 #endif
534 #if (TLS13_HYBRID_KE_SUPPORT == ENABLED || TLS13_PSK_HYBRID_KE_SUPPORT == ENABLED)
535  //Hybrid key exchange method?
536  if(tls13IsHybridGroupSupported(context, namedGroup))
537  {
538  size_t keyShareOffset;
539  size_t sharedSecretOffset;
540  const EcCurve *curve;
541  const KemAlgo *kemAlgo;
542 
543  //Retrieve the traditional and the next-gen algorithms to be used
544  curve = tls13GetTraditionalAlgo(context, namedGroup);
545  kemAlgo = tls13GetNextGenAlgo(context, namedGroup);
546 
547  //Valid algorithms?
548  if(curve != NULL && kemAlgo != NULL)
549  {
550  //The client's share is a fixed-size concatenation of the ECDH ephemeral
551  //key share and the pk outputs of the KEM KeyGen algorithm
552  if(length > kemAlgo->publicKeySize)
553  {
554  //Save the named group
555  context->namedGroup = namedGroup;
556 
557  //Initialize KEM context
558  kemFree(&context->kemContext);
559  kemInit(&context->kemContext, kemAlgo);
560 
561  //The group name X25519MLKEM768 does not adhere to the naming
562  //convention outlined in Section 3.2 of RFC 9954. Specifically, the
563  //order of shares in the concatenation has been reversed. This is
564  //due to historical reasons (refer to RFC 10024, section 4.1)
565  if(context->namedGroup == TLS_GROUP_X25519_MLKEM768)
566  {
567  keyShareOffset = kemAlgo->publicKeySize;
568  sharedSecretOffset = kemAlgo->sharedSecretSize;
569  }
570  else
571  {
572  keyShareOffset = 0;
573  sharedSecretOffset = 0;
574  }
575 
576  //Save elliptic curve parameters
577  error = ecdhSetCurve(&context->ecdhContext, curve);
578 
579  //Check status code
580  if(!error)
581  {
582  //DH key exchange can be modeled as a KEM, with encapsulation
583  //corresponding to selecting an exponent y, computing the
584  //ciphertext g^y and the shared secret g^(xy)
585  error = ecdhGenerateKeyPair(&context->ecdhContext,
586  context->prngAlgo, context->prngContext);
587  }
588 
589  //Check status code
590  if(!error)
591  {
592  //The ECDHE share is the serialized value of the uncompressed ECDH
593  //point representation
594  error = ecdhImportPeerPublicKey(&context->ecdhContext,
595  keyShare + keyShareOffset, length - kemAlgo->publicKeySize,
597  }
598 
599  //Check status code
600  if(!error)
601  {
602  //Compute the shared secret g^(xy)
603  error = ecdhComputeSharedSecret(&context->ecdhContext,
604  context->premasterSecret + sharedSecretOffset,
605  TLS_PREMASTER_SECRET_SIZE - sharedSecretOffset,
606  &context->premasterSecretLen);
607  }
608 
609  //Check status code
610  if(!error)
611  {
612  //X25519MLKEM768 group?
613  if(context->namedGroup == TLS_GROUP_X25519_MLKEM768)
614  {
615  keyShareOffset = 0;
616  }
617  else
618  {
619  keyShareOffset = length - kemAlgo->publicKeySize;
620  }
621 
622  //The encapsulation algorithm takes as input a public key pk and
623  //outputs a ciphertext ct and shared secret ss
624  error = kemLoadPublicKey(&context->kemContext,
625  keyShare + keyShareOffset);
626  }
627  }
628  else
629  {
630  //The length of the key share is not valid
631  error = ERROR_ILLEGAL_PARAMETER;
632  }
633  }
634  else
635  {
636  //Unsupported hybrid key exchange method
637  error = ERROR_ILLEGAL_PARAMETER;
638  }
639  }
640  else
641 #endif
642  //Unknown key exchange method?
643  {
644  //Report an error
645  error = ERROR_ILLEGAL_PARAMETER;
646  }
647 
648  //Return status code
649  return error;
650 }
651 
652 
653 /**
654  * @brief Decapsulation algorithm
655  * @param[in] context Pointer to the TLS context
656  * @param[in] keyShare Pointer to the server's key share
657  * @param[in] length Length of the client's key share, in bytes
658  * @return Error code
659  **/
660 
661 error_t tls13Decapsulate(TlsContext *context, const uint8_t *keyShare,
662  size_t length)
663 {
664  error_t error;
665 
666 #if (TLS13_MLKEM_KE_SUPPORT == ENABLED || TLS13_PSK_MLKEM_KE_SUPPORT == ENABLED)
667  //ML-KEM key exchange method?
668  if(tls13IsMlkemGroupSupported(context, context->namedGroup))
669  {
670  const KemAlgo *kemAlgo;
671 
672  //Retrieve the ML-KEM algorithm to be used
673  kemAlgo = tls13GetMlkemAlgo(context, context->namedGroup);
674 
675  //The length of the ciphertext is fixed
676  if(length == kemAlgo->ciphertextSize)
677  {
678  //The decapsulation algorithm takes as input a secret key sk and
679  //ciphertext ct and outputs a shared secret ss
680  error = kemDecapsulate(&context->kemContext, keyShare,
681  context->premasterSecret);
682 
683  //Check status code
684  if(!error)
685  {
686  //The shared secret output from the ML-KEM Decaps is inserted into
687  //the TLS 1.3 key schedule in place of the (EC)DHE shared secret
688  context->premasterSecretLen = kemAlgo->sharedSecretSize;
689  }
690  }
691  else
692  {
693  //The length of the key share is not valid
694  error = ERROR_ILLEGAL_PARAMETER;
695  }
696  }
697  else
698 #endif
699 #if (TLS13_HYBRID_KE_SUPPORT == ENABLED || TLS13_PSK_HYBRID_KE_SUPPORT == ENABLED)
700  //Hybrid key exchange method?
701  if(tls13IsHybridGroupSupported(context, context->namedGroup))
702  {
703  size_t keyShareOffset;
704  size_t sharedSecretOffset;
705  const KemAlgo *kemAlgo;
706 
707  //Point to the KEM algorithm
708  kemAlgo = context->kemContext.kemAlgo;
709 
710  //The server's share is a fixed-size concatenation of the ECDH ephemeral
711  //key share and the ct outputs of the KEM Encaps algorithm
712  if(length > kemAlgo->ciphertextSize)
713  {
714  //The group name X25519MLKEM768 does not adhere to the naming
715  //convention outlined in Section 3.2 of RFC 9954. Specifically, the
716  //order of shares in the concatenation has been reversed. This is due
717  //to historical reasons (refer to RFC 10024, section 4.1)
718  if(context->namedGroup == TLS_GROUP_X25519_MLKEM768)
719  {
720  keyShareOffset = kemAlgo->ciphertextSize;
721  sharedSecretOffset = kemAlgo->sharedSecretSize;
722  }
723  else
724  {
725  keyShareOffset = 0;
726  sharedSecretOffset = 0;
727  }
728 
729  //Decode the server's ECDH ephemeral share
730  error = ecdhImportPeerPublicKey(&context->ecdhContext,
731  keyShare + keyShareOffset, length - kemAlgo->ciphertextSize,
733 
734  //Check status code
735  if(!error)
736  {
737  //DH key exchange can be modeled as a KEM, with decapsulation
738  //corresponding to computing the shared secret g^(xy)
739  error = ecdhComputeSharedSecret(&context->ecdhContext,
740  context->premasterSecret + sharedSecretOffset,
741  TLS_PREMASTER_SECRET_SIZE - sharedSecretOffset,
742  &context->premasterSecretLen);
743  }
744 
745  //Check status code
746  if(!error)
747  {
748  //X25519MLKEM768 group?
749  if(context->namedGroup == TLS_GROUP_X25519_MLKEM768)
750  {
751  keyShareOffset = 0;
752  sharedSecretOffset = 0;
753  }
754  else
755  {
756  keyShareOffset = length - kemAlgo->ciphertextSize;
757  sharedSecretOffset = context->premasterSecretLen;
758  }
759 
760  //The decapsulation algorithm takes as input a secret key sk and
761  //ciphertext ct and outputs a shared secret ss
762  error = kemDecapsulate(&context->kemContext, keyShare + keyShareOffset,
763  context->premasterSecret + sharedSecretOffset);
764  }
765 
766  //Check status code
767  if(!error)
768  {
769  //The two shared secrets are concatenated together and used as the
770  //shared secret in the existing TLS 1.3 key schedule
771  context->premasterSecretLen += kemAlgo->sharedSecretSize;
772  }
773  }
774  else
775  {
776  //The length of the key share is not valid
777  error = ERROR_ILLEGAL_PARAMETER;
778  }
779  }
780  else
781 #endif
782  //Unknown key exchange method?
783  {
784  //Report an error
785  error = ERROR_ILLEGAL_PARAMETER;
786  }
787 
788  //Return status code
789  return error;
790 }
791 
792 
793 /**
794  * @brief Compute message authentication code
795  * @param[in] context Pointer to the TLS context
796  * @param[in] encryptionEngine Pointer to the encryption/decryption engine
797  * @param[in] record Pointer to the TLS record
798  * @param[in] data Pointer to the record data
799  * @param[in] dataLen Length of the data
800  * @param[out] mac The computed MAC value
801  * @return Error code
802  **/
803 
805  void *record, const uint8_t *data, size_t dataLen, uint8_t *mac)
806 {
807  size_t aadLen;
808  size_t nonceLen;
809  uint8_t aad[13];
810  uint8_t nonce[48];
811  HmacContext *hmacContext;
812 
813  //Point to the HMAC context
814  hmacContext = encryptionEngine->hmacContext;
815 
816  //Initialize HMAC calculation
817  hmacInit(hmacContext, encryptionEngine->hashAlgo,
818  encryptionEngine->encKey, encryptionEngine->encKeyLen);
819 
820  //Additional data to be authenticated
821  tlsFormatAad(context, encryptionEngine, record, aad, &aadLen);
822 
823  //Generate the nonce
824  tlsFormatNonce(context, encryptionEngine, record, data, nonce,
825  &nonceLen);
826 
827  //Compute HMAC(write_key, nonce || additional_data || plaintext)
828  hmacUpdate(hmacContext, nonce, nonceLen);
829  hmacUpdate(hmacContext, aad, aadLen);
830  hmacUpdate(hmacContext, data, dataLen);
831 
832  //Finalize HMAC computation
833  hmacFinal(hmacContext, mac);
834 
835  //Successful processing
836  return NO_ERROR;
837 }
838 
839 
840 /**
841  * @brief Hash ClientHello1 in the transcript when HelloRetryRequest is used
842  * @param[in] context Pointer to the TLS context
843  * @return Error code
844  **/
845 
847 {
849  const HashAlgo *hash;
850 
851  //Invalid hash context?
852  if(context->transcriptHashContext == NULL)
853  return ERROR_FAILURE;
854 
855  //The hash function used by HKDF is the cipher suite hash algorithm
856  hash = context->cipherSuite.prfHashAlgo;
857  //Make sure the hash algorithm is valid
858  if(hash == NULL)
859  return ERROR_FAILURE;
860 
861  //Point to the buffer where to format the handshake message
862  message = (TlsHandshake *) context->txBuffer;
863 
864  //Handshake message type
865  message->msgType = TLS_TYPE_MESSAGE_HASH;
866  //Number of bytes in the message
867  STORE24BE(hash->digestSize, message->length);
868 
869 #if (DTLS_SUPPORT == ENABLED)
870  //Check current state
871  if(context->state == TLS_STATE_CLIENT_HELLO ||
872  context->state == TLS_STATE_CLIENT_HELLO_2)
873  {
874  //Restore Hash(ClientHello1)
875  osMemcpy(message->data, context->clientHelloDigest, hash->digestSize);
876  }
877  else
878  {
879  //Compute Hash(ClientHello1)
880  hash->final(context->transcriptHashContext, message->data);
881 
882  //Save Hash(ClientHello1)
883  osMemcpy(context->clientHelloDigest, message->data, hash->digestSize);
884  context->clientHelloDigestLen = hash->digestSize;
885  }
886 #else
887  //Compute Hash(ClientHello1)
888  hash->final(context->transcriptHashContext, message->data);
889 #endif
890 
891  //Re-initialize hash algorithm context
892  hash->init(context->transcriptHashContext);
893 
894  //When the server responds to a ClientHello with a HelloRetryRequest, the
895  //value of ClientHello1 is replaced with a special synthetic handshake
896  //message of handshake type MessageHash containing Hash(ClientHello1)
897  hash->update(context->transcriptHashContext, message,
898  hash->digestSize + sizeof(TlsHandshake));
899 
900  //Successful processing
901  return NO_ERROR;
902 }
903 
904 
905 /**
906  * @brief Check whether an externally established PSK is valid
907  * @param[in] context Pointer to the TLS context
908  * @return TRUE is the PSK is valid, else FALSE
909  **/
910 
912 {
913  bool_t valid = FALSE;
914 
915  //Make sure the hash algorithm associated with the PSK is valid
916  if(tlsGetHashAlgo(context->pskHashAlgo) != NULL)
917  {
918  //Valid PSK?
919  if(context->psk != NULL && context->pskLen > 0)
920  {
921  //Check whether TLS operates as a client or a server
922  if(context->entity == TLS_CONNECTION_END_CLIENT)
923  {
924  //Valid PSK identity?
925  if(context->pskIdentity != NULL)
926  {
927  valid = TRUE;
928  }
929  }
930  else
931  {
932  valid = TRUE;
933  }
934  }
935  }
936 
937  //Return TRUE is the PSK is valid, else FALSE
938  return valid;
939 }
940 
941 
942 /**
943  * @brief Check whether a given named group is supported
944  * @param[in] context Pointer to the TLS context
945  * @param[in] namedGroup Named group
946  * @return TRUE is the named group is supported, else FALSE
947  **/
948 
949 bool_t tls13IsGroupSupported(TlsContext *context, uint16_t namedGroup)
950 {
951  bool_t acceptable;
952 
953  //Initialize flag
954  acceptable = FALSE;
955 
956  //Check whether the specified named group is supported
957  if(tls13IsFfdheGroupSupported(context, namedGroup))
958  {
959  acceptable = TRUE;
960  }
961  else if(tls13IsEcdheGroupSupported(context, namedGroup))
962  {
963  acceptable = TRUE;
964  }
965  else if(tls13IsMlkemGroupSupported(context, namedGroup))
966  {
967  acceptable = TRUE;
968  }
969  else if(tls13IsHybridGroupSupported(context, namedGroup))
970  {
971  acceptable = TRUE;
972  }
973  else
974  {
975  acceptable = FALSE;
976  }
977 
978  //Return TRUE is the named group is supported
979  return acceptable;
980 }
981 
982 
983 /**
984  * @brief Check whether a given FFDHE group is supported
985  * @param[in] context Pointer to the TLS context
986  * @param[in] namedGroup Named group
987  * @return TRUE is the FFDHE group is supported, else FALSE
988  **/
989 
990 bool_t tls13IsFfdheGroupSupported(TlsContext *context, uint16_t namedGroup)
991 {
992  bool_t acceptable;
993 
994  //Initialize flag
995  acceptable = FALSE;
996 
997 #if ((TLS13_DHE_KE_SUPPORT == ENABLED || TLS13_PSK_DHE_KE_SUPPORT == ENABLED) && \
998  TLS_FFDHE_SUPPORT == ENABLED)
999  //Finite field group?
1000  if(namedGroup == TLS_GROUP_FFDHE2048 ||
1001  namedGroup == TLS_GROUP_FFDHE3072 ||
1002  namedGroup == TLS_GROUP_FFDHE4096 ||
1003  namedGroup == TLS_GROUP_FFDHE6144 ||
1004  namedGroup == TLS_GROUP_FFDHE8192)
1005  {
1006  //Any TLS 1.3 cipher suite proposed by the client?
1007  if((context->cipherSuiteTypes & TLS_CIPHER_SUITE_TYPE_TLS13) != 0)
1008  {
1009  //Check whether the FFDHE group is supported
1010  if(tlsGetFfdheGroup(context, namedGroup) != NULL)
1011  {
1012  acceptable = TRUE;
1013  }
1014  }
1015  }
1016 #endif
1017 
1018  //Return TRUE is the named group is supported
1019  return acceptable;
1020 }
1021 
1022 
1023 /**
1024  * @brief Check whether a given ECDHE group is supported
1025  * @param[in] context Pointer to the TLS context
1026  * @param[in] namedGroup Named group
1027  * @return TRUE is the ECDHE group is supported, else FALSE
1028  **/
1029 
1030 bool_t tls13IsEcdheGroupSupported(TlsContext *context, uint16_t namedGroup)
1031 {
1032  bool_t acceptable;
1033 
1034  //Initialize flag
1035  acceptable = FALSE;
1036 
1037 #if (TLS13_ECDHE_KE_SUPPORT == ENABLED || TLS13_PSK_ECDHE_KE_SUPPORT == ENABLED)
1038  //Elliptic curve group?
1039  if(namedGroup == TLS_GROUP_SECP256R1 ||
1040  namedGroup == TLS_GROUP_SECP384R1 ||
1041  namedGroup == TLS_GROUP_SECP521R1 ||
1042  namedGroup == TLS_GROUP_X25519 ||
1043  namedGroup == TLS_GROUP_X448 ||
1044  namedGroup == TLS_GROUP_BRAINPOOLP256R1_TLS13 ||
1045  namedGroup == TLS_GROUP_BRAINPOOLP384R1_TLS13 ||
1046  namedGroup == TLS_GROUP_BRAINPOOLP512R1_TLS13)
1047  {
1048  //Any TLS 1.3 cipher suite proposed by the client?
1049  if((context->cipherSuiteTypes & TLS_CIPHER_SUITE_TYPE_TLS13) != 0)
1050  {
1051  //Check whether the ECDHE group is supported
1052  if(tlsGetCurve(context, namedGroup) != NULL)
1053  {
1054  acceptable = TRUE;
1055  }
1056  }
1057  }
1058  else if(namedGroup == TLS_GROUP_CURVE_SM2)
1059  {
1060  //Any ShangMi cipher suite proposed by the client?
1061  if((context->cipherSuiteTypes & TLS_CIPHER_SUITE_TYPE_SM) != 0)
1062  {
1063  //Check whether the SM2 group is supported
1064  if(tlsGetCurve(context, namedGroup) != NULL)
1065  {
1066  acceptable = TRUE;
1067  }
1068  }
1069  }
1070  else
1071  {
1072  //Unknown group
1073  }
1074 #endif
1075 
1076  //Return TRUE is the named group is supported
1077  return acceptable;
1078 }
1079 
1080 
1081 /**
1082  * @brief Check whether a given ML-KEM exchange method is supported
1083  * @param[in] context Pointer to the TLS context
1084  * @param[in] namedGroup Named group
1085  * @return TRUE is the ML-KEM key exchange is supported, else FALSE
1086  **/
1087 
1088 bool_t tls13IsMlkemGroupSupported(TlsContext *context, uint16_t namedGroup)
1089 {
1090  bool_t acceptable;
1091 
1092  //Initialize flag
1093  acceptable = FALSE;
1094 
1095 #if (TLS13_MLKEM_KE_SUPPORT == ENABLED || TLS13_PSK_MLKEM_KE_SUPPORT == ENABLED)
1096  //ML-KEM key exchange method?
1097  if(namedGroup == TLS_GROUP_MLKEM512 ||
1098  namedGroup == TLS_GROUP_MLKEM768 ||
1099  namedGroup == TLS_GROUP_MLKEM1024)
1100  {
1101  //Any TLS 1.3 cipher suite proposed by the client?
1102  if((context->cipherSuiteTypes & TLS_CIPHER_SUITE_TYPE_TLS13) != 0)
1103  {
1104  //Check whether the ML-KEM key exchange method is supported
1105  if(tls13GetMlkemAlgo(context, namedGroup) != NULL)
1106  {
1107  acceptable = TRUE;
1108  }
1109  }
1110  }
1111  else
1112  {
1113  //Unknown group
1114  }
1115 #endif
1116 
1117  //Return TRUE is the named group is supported
1118  return acceptable;
1119 }
1120 
1121 
1122 /**
1123  * @brief Check whether a given hybrid key exchange method is supported
1124  * @param[in] context Pointer to the TLS context
1125  * @param[in] namedGroup Named group
1126  * @return TRUE is the hybrid key exchange is supported, else FALSE
1127  **/
1128 
1129 bool_t tls13IsHybridGroupSupported(TlsContext *context, uint16_t namedGroup)
1130 {
1131  bool_t acceptable;
1132 
1133  //Initialize flag
1134  acceptable = FALSE;
1135 
1136 #if (TLS13_HYBRID_KE_SUPPORT == ENABLED || TLS13_PSK_HYBRID_KE_SUPPORT == ENABLED)
1137  //Hybrid key exchange method?
1138  if(namedGroup == TLS_GROUP_SECP256R1_MLKEM768 ||
1139  namedGroup == TLS_GROUP_SECP384R1_MLKEM1024 ||
1140  namedGroup == TLS_GROUP_CURVE_SM2_MLKEM768 ||
1141  namedGroup == TLS_GROUP_X25519_MLKEM768)
1142  {
1143  //Any TLS 1.3 cipher suite proposed by the client?
1144  if((context->cipherSuiteTypes & TLS_CIPHER_SUITE_TYPE_TLS13) != 0)
1145  {
1146  //Check whether the hybrid key exchange method is supported
1147  if(tls13GetTraditionalAlgo(context, namedGroup) != NULL &&
1148  tls13GetNextGenAlgo(context, namedGroup) != NULL)
1149  {
1150  acceptable = TRUE;
1151  }
1152  }
1153  }
1154  else
1155  {
1156  //Unknown group
1157  }
1158 #endif
1159 
1160  //Return TRUE is the named group is supported
1161  return acceptable;
1162 }
1163 
1164 
1165 /**
1166  * @brief Get the ML-KEM algorithm that matches the specified named group
1167  * @param[in] context Pointer to the TLS context
1168  * @param[in] namedGroup Hybrid key exchange method
1169  * @return ML-KEM algorithm
1170  **/
1171 
1172 const KemAlgo *tls13GetMlkemAlgo(TlsContext *context, uint16_t namedGroup)
1173 {
1174  const KemAlgo *kemAlgo;
1175 
1176  //Default KEM algorithm
1177  kemAlgo = NULL;
1178 
1179 #if (TLS13_MLKEM_KE_SUPPORT == ENABLED || TLS13_PSK_MLKEM_KE_SUPPORT == ENABLED)
1180  //Check named group
1181  switch(namedGroup)
1182  {
1183 #if (TLS_MLKEM512_SUPPORT == ENABLED)
1184  //ML-KEM-512 key encapsulation mechanism?
1185  case TLS_GROUP_MLKEM512:
1186  kemAlgo = MLKEM512_KEM_ALGO;
1187  break;
1188 #endif
1189 #if (TLS_MLKEM768_SUPPORT == ENABLED)
1190  //ML-KEM-768 key encapsulation mechanism?
1191  case TLS_GROUP_MLKEM768:
1192  kemAlgo = MLKEM768_KEM_ALGO;
1193  break;
1194 #endif
1195 #if (TLS_MLKEM1024_SUPPORT == ENABLED)
1196  //ML-KEM-1024 key encapsulation mechanism?
1197  case TLS_GROUP_MLKEM1024:
1198  kemAlgo = MLKEM1024_KEM_ALGO;
1199  break;
1200 #endif
1201  //Unknown group?
1202  default:
1203  kemAlgo = NULL;
1204  break;
1205  }
1206 
1207  //Restrict the use of certain algorithms
1208  if(context->numSupportedGroups > 0)
1209  {
1210  uint_t i;
1211 
1212  //Loop through the list of allowed named groups
1213  for(i = 0; i < context->numSupportedGroups; i++)
1214  {
1215  //Compare named groups
1216  if(context->supportedGroups[i] == namedGroup)
1217  break;
1218  }
1219 
1220  //Check whether the use of the algorithm is restricted
1221  if(i >= context->numSupportedGroups)
1222  {
1223  kemAlgo = NULL;
1224  }
1225  }
1226 #endif
1227 
1228  //Return KEM algorithm, if any
1229  return kemAlgo;
1230 }
1231 
1232 
1233 /**
1234  * @brief Get the traditional algorithm used by the hybrid key exchange method
1235  * @param[in] context Pointer to the TLS context
1236  * @param[in] namedGroup Hybrid key exchange method
1237  * @return Traditional algorithm
1238  **/
1239 
1241  uint16_t namedGroup)
1242 {
1243  const EcCurve *curve;
1244 
1245  //Default elliptic curve parameters
1246  curve = NULL;
1247 
1248 #if (TLS13_HYBRID_KE_SUPPORT == ENABLED || TLS13_PSK_HYBRID_KE_SUPPORT == ENABLED)
1249  //Check named group
1250  switch(namedGroup)
1251  {
1252 #if (TLS_SECP256R1_SUPPORT == ENABLED)
1253  //secp256r1 elliptic curve?
1255  curve = ecGetCurve(SECP256R1_OID, sizeof(SECP256R1_OID));
1256  break;
1257 #endif
1258 #if (TLS_SECP384R1_SUPPORT == ENABLED)
1259  //secp384r1 elliptic curve?
1261  curve = ecGetCurve(SECP384R1_OID, sizeof(SECP384R1_OID));
1262  break;
1263 #endif
1264 #if (TLS_SM2_SUPPORT == ENABLED)
1265  //SM2 elliptic curve?
1267  curve = ecGetCurve(SM2_OID, sizeof(SM2_OID));
1268  break;
1269 #endif
1270 #if (TLS_X25519_SUPPORT == ENABLED)
1271  //Curve25519 elliptic curve?
1273  curve = ecGetCurve(X25519_OID, sizeof(X25519_OID));
1274  break;
1275 #endif
1276  //Unknown group?
1277  default:
1278  curve = NULL;
1279  break;
1280  }
1281 
1282  //Restrict the use of certain algorithms
1283  if(context->numSupportedGroups > 0)
1284  {
1285  uint_t i;
1286 
1287  //Loop through the list of allowed named groups
1288  for(i = 0; i < context->numSupportedGroups; i++)
1289  {
1290  //Compare named groups
1291  if(context->supportedGroups[i] == namedGroup)
1292  break;
1293  }
1294 
1295  //Check whether the use of the algorithm is restricted
1296  if(i >= context->numSupportedGroups)
1297  {
1298  curve = NULL;
1299  }
1300  }
1301 #endif
1302 
1303  //Return the elliptic curve parameters, if any
1304  return curve;
1305 }
1306 
1307 
1308 /**
1309  * @brief Get the next-gen algorithm used by the hybrid key exchange method
1310  * @param[in] context Pointer to the TLS context
1311  * @param[in] namedGroup Hybrid key exchange method
1312  * @return Next-gen algorithm
1313  **/
1314 
1315 const KemAlgo *tls13GetNextGenAlgo(TlsContext *context, uint16_t namedGroup)
1316 {
1317  const KemAlgo *kemAlgo;
1318 
1319  //Default KEM algorithm
1320  kemAlgo = NULL;
1321 
1322 #if (TLS13_HYBRID_KE_SUPPORT == ENABLED || TLS13_PSK_HYBRID_KE_SUPPORT == ENABLED)
1323  //Check named group
1324  switch(namedGroup)
1325  {
1326 #if (TLS_MLKEM768_SUPPORT == ENABLED)
1327  //ML-KEM-768 key encapsulation mechanism?
1331  kemAlgo = MLKEM768_KEM_ALGO;
1332  break;
1333 #endif
1334 #if (TLS_MLKEM1024_SUPPORT == ENABLED)
1335  //ML-KEM-1024 key encapsulation mechanism?
1337  kemAlgo = MLKEM1024_KEM_ALGO;
1338  break;
1339 #endif
1340  //Unknown group?
1341  default:
1342  kemAlgo = NULL;
1343  break;
1344  }
1345 
1346  //Restrict the use of certain algorithms
1347  if(context->numSupportedGroups > 0)
1348  {
1349  uint_t i;
1350 
1351  //Loop through the list of allowed named groups
1352  for(i = 0; i < context->numSupportedGroups; i++)
1353  {
1354  //Compare named groups
1355  if(context->supportedGroups[i] == namedGroup)
1356  break;
1357  }
1358 
1359  //Check whether the use of the algorithm is restricted
1360  if(i >= context->numSupportedGroups)
1361  {
1362  kemAlgo = NULL;
1363  }
1364  }
1365 #endif
1366 
1367  //Return KEM algorithm, if any
1368  return kemAlgo;
1369 }
1370 
1371 
1372 /**
1373  * @brief Check whether the specified key share group is a duplicate
1374  * @param[in] namedGroup Named group
1375  * @param[in] p List of key share entries
1376  * @param[in] length Length of the list, in bytes
1377  * @return Error code
1378  **/
1379 
1380 error_t tls13CheckDuplicateKeyShare(uint16_t namedGroup, const uint8_t *p,
1381  size_t length)
1382 {
1383  size_t n;
1384  const Tls13KeyShareEntry *keyShareEntry;
1385 
1386  //Parse the list of key share entries offered by the peer
1387  while(length > 0)
1388  {
1389  //Malformed extension?
1390  if(length < sizeof(Tls13KeyShareEntry))
1391  return ERROR_DECODING_FAILED;
1392 
1393  //Point to the current key share entry
1394  keyShareEntry = (Tls13KeyShareEntry *) p;
1395  //Retrieve the length of the key_exchange field
1396  n = ntohs(keyShareEntry->length);
1397 
1398  //Malformed extension?
1399  if(length < (sizeof(Tls13KeyShareEntry) + n))
1400  return ERROR_DECODING_FAILED;
1401 
1402  //Clients must not offer multiple KeyShareEntry values for the same
1403  //group. Servers may check for violations of this rule and abort the
1404  //handshake with an illegal_parameter alert
1405  if(ntohs(keyShareEntry->group) == namedGroup)
1406  return ERROR_ILLEGAL_PARAMETER;
1407 
1408  //Jump to the next key share entry
1409  p += sizeof(Tls13KeyShareEntry) + n;
1410  //Number of bytes left to process
1411  length -= sizeof(Tls13KeyShareEntry) + n;
1412  }
1413 
1414  //Successful verification
1415  return NO_ERROR;
1416 }
1417 
1418 
1419 /**
1420  * @brief Format certificate extensions
1421  * @param[in] p Output stream where to write the list of extensions
1422  * @param[out] written Total number of bytes that have been written
1423  * @return Error code
1424  **/
1425 
1426 error_t tls13FormatCertExtensions(uint8_t *p, size_t *written)
1427 {
1428  TlsExtensionList *extensionList;
1429 
1430  //Point to the list of extensions
1431  extensionList = (TlsExtensionList *) p;
1432 
1433  //Extensions in the Certificate message from the server must correspond to
1434  //ones from the ClientHello message. Extensions in the Certificate message
1435  //from the client must correspond to extensions in the CertificateRequest
1436  //message from the server
1437  extensionList->length = HTONS(0);
1438 
1439  //Total number of bytes that have been written
1440  *written = sizeof(TlsExtensionList);
1441 
1442  //Successful processing
1443  return NO_ERROR;
1444 }
1445 
1446 
1447 /**
1448  * @brief Parse certificate extensions
1449  * @param[in] p Input stream where to read the list of extensions
1450  * @param[in] length Number of bytes available in the input stream
1451  * @param[out] consumed Total number of bytes that have been consumed
1452  * @return Error code
1453  **/
1454 
1455 error_t tls13ParseCertExtensions(const uint8_t *p, size_t length,
1456  size_t *consumed)
1457 {
1458  error_t error;
1459  size_t n;
1461  const TlsExtensionList *extensionList;
1462 
1463  //Point to the list of extensions
1464  extensionList = (TlsExtensionList *) p;
1465 
1466  //Malformed CertificateEntry?
1467  if(length < sizeof(TlsExtensionList))
1468  return ERROR_DECODING_FAILED;
1469 
1470  //Retrieve the length of the list
1471  n = sizeof(TlsExtensionList) + ntohs(extensionList->length);
1472 
1473  //Malformed CertificateEntry?
1474  if(length < n)
1475  return ERROR_DECODING_FAILED;
1476 
1477  //Parse the list of extensions for the current CertificateEntry
1479  &extensions);
1480  //Any error to report?
1481  if(error)
1482  return error;
1483 
1484  //Check the list of extensions
1486  &extensions);
1487  //Any error to report?
1488  if(error)
1489  return error;
1490 
1491  //Total number of bytes that have been consumed
1492  *consumed = n;
1493 
1494  //Successful processing
1495  return NO_ERROR;
1496 }
1497 
1498 #endif
@ TLS_GROUP_X25519_MLKEM768
Definition: tls.h:1546
@ TLS_GROUP_BRAINPOOLP512R1_TLS13
Definition: tls.h:1527
#define tlsAllocMem(size)
Definition: tls.h:911
@ TLS_TYPE_MESSAGE_HASH
Definition: tls.h:1146
Parsing and checking of TLS extensions.
TLS helper functions.
const uint8_t tls11DowngradeRandom[8]
Definition: tls13_misc.c:53
HashAlgoInit init
Definition: crypto.h:1253
uint8_t extensions[]
Definition: ntp_common.h:213
@ TLS_GROUP_BRAINPOOLP256R1_TLS13
Definition: tls.h:1525
int bool_t
Definition: compiler_port.h:63
HMAC algorithm context.
Definition: hmac.h:59
TLS cipher suites.
const HashAlgo * tlsGetHashAlgo(TlsHashAlgo hashAlgoId)
Get the hash algorithm that matches the specified identifier.
Definition: tls_misc.c:1431
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.
const uint8_t X25519_OID[3]
Definition: ec_curves.c:108
@ ERROR_ILLEGAL_PARAMETER
Definition: error.h:244
const EcCurve * tlsGetCurve(TlsContext *context, uint16_t namedCurve)
Get the EC domain parameters that match the specified named curve.
Definition: tls_misc.c:1498
uint8_t p
Definition: ndp.h:300
uint8_t message[]
Definition: chap.h:154
#define TRUE
Definition: os_port.h:50
uint8_t data[]
Definition: ethernet.h:224
@ TLS_GROUP_SECP256R1
Definition: tls.h:1517
@ TLS_GROUP_CURVE_SM2
Definition: tls.h:1535
size_t digestSize
Definition: crypto.h:1249
TLS 1.3 session tickets.
HashAlgoUpdate update
Definition: crypto.h:1254
void kemInit(KemContext *context, const KemAlgo *kemAlgo)
Initialize KEM context.
Definition: kem.c:48
bool_t tls13IsMlkemGroupSupported(TlsContext *context, uint16_t namedGroup)
Check whether a given ML-KEM exchange method is supported.
Definition: tls13_misc.c:1088
@ ERROR_HANDSHAKE_FAILED
Definition: error.h:234
@ ERROR_OUT_OF_MEMORY
Definition: error.h:63
const uint8_t tls12DowngradeRandom[8]
Definition: tls13_misc.c:59
FFDHE parameters.
Definition: tls_ffdhe.h:58
@ EC_PUBLIC_KEY_FORMAT_X963
Definition: ec.h:386
size_t publicKeySize
Definition: crypto.h:1306
Tls13KeyShareEntry
Definition: tls13_misc.h:209
void kemFree(KemContext *context)
Release KEM context.
Definition: kem.c:62
const uint8_t SECP256R1_OID[8]
Definition: ec_curves.c:70
@ TLS_GROUP_X448
Definition: tls.h:1524
@ TLS_CIPHER_SUITE_TYPE_TLS13
@ TLS_GROUP_FFDHE6144
Definition: tls.h:1539
size_t contextSize
Definition: crypto.h:1247
@ TLS_STATE_CLIENT_HELLO
Definition: tls.h:1585
error_t tls13ParseCertExtensions(const uint8_t *p, size_t length, size_t *consumed)
Parse certificate extensions.
Definition: tls13_misc.c:1455
@ TLS_CIPHER_SUITE_TYPE_SM
TLS 1.3 helper functions.
@ TLS_GROUP_CURVE_SM2_MLKEM768
Definition: tls.h:1548
@ TLS_TYPE_CERTIFICATE
Definition: tls.h:1133
TlsExtensionList
Definition: tls.h:1753
TlsHandshake
Definition: tls.h:1923
#define FALSE
Definition: os_port.h:46
error_t dhComputeSharedSecret(DhContext *context, uint8_t *output, size_t outputSize, size_t *outputLen)
Compute Diffie-Hellman shared secret.
Definition: dh.c:289
@ ERROR_INVALID_PARAMETER
Invalid parameter.
Definition: error.h:47
#define osMemcpy(dest, src, length)
Definition: os_port.h:147
#define TlsContext
Definition: tls.h:36
error_t
Error codes.
Definition: error.h:43
bool_t tls13IsGroupSupported(TlsContext *context, uint16_t namedGroup)
Check whether a given named group is supported.
Definition: tls13_misc.c:949
@ TLS_GROUP_SECP256R1_MLKEM768
Definition: tls.h:1545
size_t sharedSecretSize
Definition: crypto.h:1309
#define TLS_PREMASTER_SECRET_SIZE
Definition: tls.h:866
void tlsFormatAad(TlsContext *context, TlsEncryptionEngine *encryptionEngine, const void *record, uint8_t *aad, size_t *aadLen)
Format additional authenticated data (AAD)
Definition: tls_record.c:905
bool_t tls13IsEcdheGroupSupported(TlsContext *context, uint16_t namedGroup)
Check whether a given ECDHE group is supported.
Definition: tls13_misc.c:1030
const KemAlgo * tls13GetMlkemAlgo(TlsContext *context, uint16_t namedGroup)
Get the ML-KEM algorithm that matches the specified named group.
Definition: tls13_misc.c:1172
const KemAlgo * tls13GetNextGenAlgo(TlsContext *context, uint16_t namedGroup)
Get the next-gen algorithm used by the hybrid key exchange method.
Definition: tls13_misc.c:1315
@ ERROR_FAILURE
Generic error code.
Definition: error.h:45
error_t tlsParseHelloExtensions(TlsMessageType msgType, const uint8_t *p, size_t length, TlsHelloExtensions *extensions)
Parse Hello extensions.
error_t tls13ComputeMac(TlsContext *context, TlsEncryptionEngine *encryptionEngine, void *record, const uint8_t *data, size_t dataLen, uint8_t *mac)
Compute message authentication code.
Definition: tls13_misc.c:804
error_t tls13Decapsulate(TlsContext *context, const uint8_t *keyShare, size_t length)
Decapsulation algorithm.
Definition: tls13_misc.c:661
@ TLS_GROUP_FFDHE4096
Definition: tls.h:1538
@ TLS_TYPE_CLIENT_HELLO
Definition: tls.h:1124
#define MLKEM512_KEM_ALGO
Definition: mlkem512.h:47
#define TLS_VERSION_1_3
Definition: tls.h:99
@ ERROR_INVALID_LENGTH
Definition: error.h:111
@ TLS_GROUP_SECP384R1
Definition: tls.h:1518
bool_t tls13IsTicketValid(TlsContext *context)
Check whether a session ticket is valid.
Definition: tls13_ticket.c:51
TLS record protocol.
bool_t tls13IsFfdheGroupSupported(TlsContext *context, uint16_t namedGroup)
Check whether a given FFDHE group is supported.
Definition: tls13_misc.c:990
void tlsFormatNonce(TlsContext *context, TlsEncryptionEngine *encryptionEngine, const void *record, const uint8_t *recordIv, uint8_t *nonce, size_t *nonceLen)
Format nonce.
Definition: tls_record.c:963
error_t dhImportPeerPublicKey(DhContext *context, const uint8_t *input, size_t length, MpiFormat format)
Import peer's public key.
Definition: dh.c:218
bool_t tls13IsHybridGroupSupported(TlsContext *context, uint16_t namedGroup)
Check whether a given hybrid key exchange method is supported.
Definition: tls13_misc.c:1129
uint8_t length
Definition: tcp.h:375
@ TLS_GROUP_FFDHE2048
Definition: tls.h:1536
error_t tls13FormatCertExtensions(uint8_t *p, size_t *written)
Format certificate extensions.
Definition: tls13_misc.c:1426
const TlsFfdheGroup * tlsGetFfdheGroup(TlsContext *context, uint16_t namedGroup)
Get the FFDHE parameters that match the specified named group.
Definition: tls_ffdhe.c:314
error_t tlsLoadFfdheParameters(DhParameters *params, const TlsFfdheGroup *ffdheGroup)
Load FFDHE parameters.
Definition: tls_ffdhe.c:376
const uint8_t tls13HelloRetryRequestRandom[32]
Definition: tls13_misc.c:65
uint32_t dataLen
Definition: sftp_common.h:229
@ TLS_GROUP_MLKEM512
Definition: tls.h:1542
@ TLS_GROUP_SECP521R1
Definition: tls.h:1519
@ TLS_GROUP_FFDHE3072
Definition: tls.h:1537
Hello extensions.
Definition: tls.h:2304
@ TLS_GROUP_BRAINPOOLP384R1_TLS13
Definition: tls.h:1526
Transcript hash calculation.
const uint8_t SECP384R1_OID[5]
Definition: ec_curves.c:72
error_t ecdhComputeSharedSecret(EcdhContext *context, uint8_t *output, size_t outputSize, size_t *outputLen)
Compute ECDH shared secret.
Definition: ecdh.c:415
HashAlgoFinal final
Definition: crypto.h:1255
error_t ecdhImportPeerPublicKey(EcdhContext *context, const uint8_t *input, size_t length, EcPublicKeyFormat format)
Import peer's public key.
Definition: ecdh.c:274
#define ntohs(value)
Definition: cpu_endian.h:421
__weak_func void hmacUpdate(HmacContext *context, const void *data, size_t length)
Update the HMAC context with a portion of the message being hashed.
Definition: hmac.c:201
#define TRACE_DEBUG(...)
Definition: debug.h:119
__weak_func error_t hmacCompute(const HashAlgo *hash, const void *key, size_t keyLen, const void *data, size_t dataLen, uint8_t *digest)
Compute HMAC using the specified hash function.
Definition: hmac.c:91
@ TLS_STATE_CLIENT_HELLO_2
Definition: tls.h:1586
#define TRACE_DEBUG_ARRAY(p, a, n)
Definition: debug.h:120
error_t tls13GenerateSharedSecret(TlsContext *context, const uint8_t *keyShare, size_t length)
(EC)DHE shared secret generation
Definition: tls13_misc.c:407
bool_t tls13IsPskValid(TlsContext *context)
Check whether an externally established PSK is valid.
Definition: tls13_misc.c:911
error_t tls13GenerateKeyShare(TlsContext *context, uint16_t namedGroup)
Key share generation.
Definition: tls13_misc.c:234
error_t tls13ComputePskBinder(TlsContext *context, const void *clientHello, size_t clientHelloLen, size_t truncatedClientHelloLen, const Tls13PskIdentity *identity, uint8_t *binder, size_t binderLen)
Compute PSK binder value.
Definition: tls13_misc.c:86
#define HTONS(value)
Definition: cpu_endian.h:410
error_t hkdfExtract(const HashAlgo *hashAlgo, const uint8_t *ikm, size_t ikmLen, const uint8_t *salt, size_t saltLen, uint8_t *prk)
HKDF extract step.
Definition: hkdf.c:97
@ TLS_GROUP_MLKEM1024
Definition: tls.h:1544
uint8_t n
HKDF (HMAC-based Key Derivation Function)
__weak_func void hmacFinal(HmacContext *context, uint8_t *digest)
Finish the HMAC calculation.
Definition: hmac.c:218
error_t kemGenerateKeyPair(KemContext *context, const PrngAlgo *prngAlgo, void *prngContext)
Key pair generation.
Definition: kem.c:100
#define TLS_MAX_HKDF_DIGEST_SIZE
Definition: tls.h:987
Common interface for key encapsulation mechanisms (KEM)
Definition: crypto.h:1304
@ TLS_CONNECTION_END_CLIENT
Definition: tls.h:1051
X.509 certificate handling.
error_t kemLoadPublicKey(KemContext *context, const uint8_t *pk)
Load public key.
Definition: kem.c:160
error_t kemDecapsulate(KemContext *context, const uint8_t *ct, uint8_t *ss)
Decapsulation algorithm.
Definition: kem.c:240
size_t ciphertextSize
Definition: crypto.h:1308
@ MPI_FORMAT_BIG_ENDIAN
Definition: mpi.h:93
TLS (Transport Layer Security)
#define STORE24BE(a, p)
Definition: cpu_endian.h:273
const EcCurve * ecGetCurve(const uint8_t *oid, size_t length)
Get the elliptic curve that matches the specified OID.
Definition: ec_curves.c:5888
@ TLS_GROUP_X25519
Definition: tls.h:1523
error_t tlsCheckHelloExtensions(TlsMessageType msgType, uint16_t version, TlsHelloExtensions *extensions)
Check Hello extensions.
#define MLKEM1024_KEM_ALGO
Definition: mlkem1024.h:47
TLS 1.3 key schedule.
error_t ecdhSetCurve(EcdhContext *context, const EcCurve *curve)
Specify the elliptic curve to use.
Definition: ecdh.c:83
Common interface for hash algorithms.
Definition: crypto.h:1243
const EcCurve * tls13GetTraditionalAlgo(TlsContext *context, uint16_t namedGroup)
Get the traditional algorithm used by the hybrid key exchange method.
Definition: tls13_misc.c:1240
FFDHE key exchange.
error_t tls13Encapsulate(TlsContext *context, uint16_t namedGroup, const uint8_t *keyShare, size_t length)
Encapsulation algorithm.
Definition: tls13_misc.c:488
#define EcCurve
Definition: ec.h:346
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 dhGenerateKeyPair(DhContext *context, const PrngAlgo *prngAlgo, void *prngContext)
Diffie-Hellman key pair generation.
Definition: dh.c:119
Tls13PskIdentity
Definition: tls13_misc.h:242
@ ERROR_DECODING_FAILED
Definition: error.h:242
unsigned int uint_t
Definition: compiler_port.h:57
@ TLS_GROUP_MLKEM768
Definition: tls.h:1543
#define tlsFreeMem(p)
Definition: tls.h:916
error_t tls13DigestClientHello1(TlsContext *context)
Hash ClientHello1 in the transcript when HelloRetryRequest is used.
Definition: tls13_misc.c:846
__weak_func error_t hmacInit(HmacContext *context, const HashAlgo *hash, const void *key, size_t keyLen)
Initialize HMAC calculation.
Definition: hmac.c:140
error_t tls13CheckDuplicateKeyShare(uint16_t namedGroup, const uint8_t *p, size_t length)
Check whether the specified key share group is a duplicate.
Definition: tls13_misc.c:1380
#define TlsEncryptionEngine
Definition: tls.h:40
#define MLKEM768_KEM_ALGO
Definition: mlkem768.h:47
@ TLS_GROUP_FFDHE8192
Definition: tls.h:1540
uint8_t nonce[]
Definition: ntp_common.h:239
@ NO_ERROR
Success.
Definition: error.h:44
Debugging facilities.
error_t ecdhGenerateKeyPair(EcdhContext *context, const PrngAlgo *prngAlgo, void *prngContext)
ECDH key pair generation.
Definition: ecdh.c:115
const uint8_t SM2_OID[8]
Definition: ec_curves.c:106
@ TLS_GROUP_SECP384R1_MLKEM1024
Definition: tls.h:1547
uint_t mpiGetByteLength(const Mpi *a)
Get the actual length in bytes.
Definition: mpi.c:216