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.2
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  //NIST's special publication 800-56C approves the usage of HKDF with two
562  //distinct shared secrets, with the condition that the first one is
563  //computed by a FIPS-approved key-establishment scheme
564  if(context->namedGroup == TLS_GROUP_X25519_MLKEM768)
565  {
566  keyShareOffset = kemAlgo->publicKeySize;
567  sharedSecretOffset = kemAlgo->sharedSecretSize;
568  }
569  else
570  {
571  keyShareOffset = 0;
572  sharedSecretOffset = 0;
573  }
574 
575  //Save elliptic curve parameters
576  error = ecdhSetCurve(&context->ecdhContext, curve);
577 
578  //Check status code
579  if(!error)
580  {
581  //DH key exchange can be modeled as a KEM, with encapsulation
582  //corresponding to selecting an exponent y, computing the
583  //ciphertext g^y and the shared secret g^(xy)
584  error = ecdhGenerateKeyPair(&context->ecdhContext,
585  context->prngAlgo, context->prngContext);
586  }
587 
588  //Check status code
589  if(!error)
590  {
591  //The ECDHE share is the serialized value of the uncompressed ECDH
592  //point representation
593  error = ecdhImportPeerPublicKey(&context->ecdhContext,
594  keyShare + keyShareOffset, length - kemAlgo->publicKeySize,
596  }
597 
598  //Check status code
599  if(!error)
600  {
601  //Compute the shared secret g^(xy)
602  error = ecdhComputeSharedSecret(&context->ecdhContext,
603  context->premasterSecret + sharedSecretOffset,
604  TLS_PREMASTER_SECRET_SIZE - sharedSecretOffset,
605  &context->premasterSecretLen);
606  }
607 
608  //Check status code
609  if(!error)
610  {
611  //X25519MLKEM768 group?
612  if(context->namedGroup == TLS_GROUP_X25519_MLKEM768)
613  {
614  keyShareOffset = 0;
615  }
616  else
617  {
618  keyShareOffset = length - kemAlgo->publicKeySize;
619  }
620 
621  //The encapsulation algorithm takes as input a public key pk and
622  //outputs a ciphertext ct and shared secret ss
623  error = kemLoadPublicKey(&context->kemContext,
624  keyShare + keyShareOffset);
625  }
626  }
627  else
628  {
629  //The length of the key share is not valid
630  error = ERROR_ILLEGAL_PARAMETER;
631  }
632  }
633  else
634  {
635  //Unsupported hybrid key exchange method
636  error = ERROR_ILLEGAL_PARAMETER;
637  }
638  }
639  else
640 #endif
641  //Unknown key exchange method?
642  {
643  //Report an error
644  error = ERROR_ILLEGAL_PARAMETER;
645  }
646 
647  //Return status code
648  return error;
649 }
650 
651 
652 /**
653  * @brief Decapsulation algorithm
654  * @param[in] context Pointer to the TLS context
655  * @param[in] keyShare Pointer to the server's key share
656  * @param[in] length Length of the client's key share, in bytes
657  * @return Error code
658  **/
659 
660 error_t tls13Decapsulate(TlsContext *context, const uint8_t *keyShare,
661  size_t length)
662 {
663  error_t error;
664 
665 #if (TLS13_MLKEM_KE_SUPPORT == ENABLED || TLS13_PSK_MLKEM_KE_SUPPORT == ENABLED)
666  //ML-KEM key exchange method?
667  if(tls13IsMlkemGroupSupported(context, context->namedGroup))
668  {
669  const KemAlgo *kemAlgo;
670 
671  //Retrieve the ML-KEM algorithm to be used
672  kemAlgo = tls13GetMlkemAlgo(context, context->namedGroup);
673 
674  //The length of the ciphertext is fixed
675  if(length == kemAlgo->ciphertextSize)
676  {
677  //The decapsulation algorithm takes as input a secret key sk and
678  //ciphertext ct and outputs a shared secret ss
679  error = kemDecapsulate(&context->kemContext, keyShare,
680  context->premasterSecret);
681 
682  //Check status code
683  if(!error)
684  {
685  //The shared secret output from the ML-KEM Decaps is inserted into
686  //the TLS 1.3 key schedule in place of the (EC)DHE shared secret
687  context->premasterSecretLen = kemAlgo->sharedSecretSize;
688  }
689  }
690  else
691  {
692  //The length of the key share is not valid
693  error = ERROR_ILLEGAL_PARAMETER;
694  }
695  }
696  else
697 #endif
698 #if (TLS13_HYBRID_KE_SUPPORT == ENABLED || TLS13_PSK_HYBRID_KE_SUPPORT == ENABLED)
699  //Hybrid key exchange method?
700  if(tls13IsHybridGroupSupported(context, context->namedGroup))
701  {
702  size_t keyShareOffset;
703  size_t sharedSecretOffset;
704  const KemAlgo *kemAlgo;
705 
706  //Point to the KEM algorithm
707  kemAlgo = context->kemContext.kemAlgo;
708 
709  //The server's share is a fixed-size concatenation of the ECDH ephemeral
710  //key share and the ct outputs of the KEM Encaps algorithm
711  if(length > kemAlgo->ciphertextSize)
712  {
713  //NIST's special publication 800-56C approves the usage of HKDF with two
714  //distinct shared secrets, with the condition that the first one is
715  //computed by a FIPS-approved key-establishment scheme
716  if(context->namedGroup == TLS_GROUP_X25519_MLKEM768)
717  {
718  keyShareOffset = kemAlgo->ciphertextSize;
719  sharedSecretOffset = kemAlgo->sharedSecretSize;
720  }
721  else
722  {
723  keyShareOffset = 0;
724  sharedSecretOffset = 0;
725  }
726 
727  //Decode the server's ECDH ephemeral share
728  error = ecdhImportPeerPublicKey(&context->ecdhContext,
729  keyShare + keyShareOffset, length - kemAlgo->ciphertextSize,
731 
732  //Check status code
733  if(!error)
734  {
735  //DH key exchange can be modeled as a KEM, with decapsulation
736  //corresponding to computing the shared secret g^(xy)
737  error = ecdhComputeSharedSecret(&context->ecdhContext,
738  context->premasterSecret + sharedSecretOffset,
739  TLS_PREMASTER_SECRET_SIZE - sharedSecretOffset,
740  &context->premasterSecretLen);
741  }
742 
743  //Check status code
744  if(!error)
745  {
746  //X25519MLKEM768 group?
747  if(context->namedGroup == TLS_GROUP_X25519_MLKEM768)
748  {
749  keyShareOffset = 0;
750  sharedSecretOffset = 0;
751  }
752  else
753  {
754  keyShareOffset = length - kemAlgo->ciphertextSize;
755  sharedSecretOffset = context->premasterSecretLen;
756  }
757 
758  //The decapsulation algorithm takes as input a secret key sk and
759  //ciphertext ct and outputs a shared secret ss
760  error = kemDecapsulate(&context->kemContext, keyShare + keyShareOffset,
761  context->premasterSecret + sharedSecretOffset);
762  }
763 
764  //Check status code
765  if(!error)
766  {
767  //The two shared secrets are concatenated together and used as the
768  //shared secret in the existing TLS 1.3 key schedule
769  context->premasterSecretLen += kemAlgo->sharedSecretSize;
770  }
771  }
772  else
773  {
774  //The length of the key share is not valid
775  error = ERROR_ILLEGAL_PARAMETER;
776  }
777  }
778  else
779 #endif
780  //Unknown key exchange method?
781  {
782  //Report an error
783  error = ERROR_ILLEGAL_PARAMETER;
784  }
785 
786  //Return status code
787  return error;
788 }
789 
790 
791 /**
792  * @brief Compute message authentication code
793  * @param[in] context Pointer to the TLS context
794  * @param[in] encryptionEngine Pointer to the encryption/decryption engine
795  * @param[in] record Pointer to the TLS record
796  * @param[in] data Pointer to the record data
797  * @param[in] dataLen Length of the data
798  * @param[out] mac The computed MAC value
799  * @return Error code
800  **/
801 
803  void *record, const uint8_t *data, size_t dataLen, uint8_t *mac)
804 {
805  size_t aadLen;
806  size_t nonceLen;
807  uint8_t aad[13];
808  uint8_t nonce[48];
809  HmacContext *hmacContext;
810 
811  //Point to the HMAC context
812  hmacContext = encryptionEngine->hmacContext;
813 
814  //Initialize HMAC calculation
815  hmacInit(hmacContext, encryptionEngine->hashAlgo,
816  encryptionEngine->encKey, encryptionEngine->encKeyLen);
817 
818  //Additional data to be authenticated
819  tlsFormatAad(context, encryptionEngine, record, aad, &aadLen);
820 
821  //Generate the nonce
822  tlsFormatNonce(context, encryptionEngine, record, data, nonce,
823  &nonceLen);
824 
825  //Compute HMAC(write_key, nonce || additional_data || plaintext)
826  hmacUpdate(hmacContext, nonce, nonceLen);
827  hmacUpdate(hmacContext, aad, aadLen);
828  hmacUpdate(hmacContext, data, dataLen);
829 
830  //Finalize HMAC computation
831  hmacFinal(hmacContext, mac);
832 
833  //Successful processing
834  return NO_ERROR;
835 }
836 
837 
838 /**
839  * @brief Hash ClientHello1 in the transcript when HelloRetryRequest is used
840  * @param[in] context Pointer to the TLS context
841  * @return Error code
842  **/
843 
845 {
847  const HashAlgo *hash;
848 
849  //Invalid hash context?
850  if(context->transcriptHashContext == NULL)
851  return ERROR_FAILURE;
852 
853  //The hash function used by HKDF is the cipher suite hash algorithm
854  hash = context->cipherSuite.prfHashAlgo;
855  //Make sure the hash algorithm is valid
856  if(hash == NULL)
857  return ERROR_FAILURE;
858 
859  //Point to the buffer where to format the handshake message
860  message = (TlsHandshake *) context->txBuffer;
861 
862  //Handshake message type
863  message->msgType = TLS_TYPE_MESSAGE_HASH;
864  //Number of bytes in the message
865  STORE24BE(hash->digestSize, message->length);
866 
867 #if (DTLS_SUPPORT == ENABLED)
868  //Check current state
869  if(context->state == TLS_STATE_CLIENT_HELLO ||
870  context->state == TLS_STATE_CLIENT_HELLO_2)
871  {
872  //Restore Hash(ClientHello1)
873  osMemcpy(message->data, context->clientHelloDigest, hash->digestSize);
874  }
875  else
876  {
877  //Compute Hash(ClientHello1)
878  hash->final(context->transcriptHashContext, message->data);
879 
880  //Save Hash(ClientHello1)
881  osMemcpy(context->clientHelloDigest, message->data, hash->digestSize);
882  context->clientHelloDigestLen = hash->digestSize;
883  }
884 #else
885  //Compute Hash(ClientHello1)
886  hash->final(context->transcriptHashContext, message->data);
887 #endif
888 
889  //Re-initialize hash algorithm context
890  hash->init(context->transcriptHashContext);
891 
892  //When the server responds to a ClientHello with a HelloRetryRequest, the
893  //value of ClientHello1 is replaced with a special synthetic handshake
894  //message of handshake type MessageHash containing Hash(ClientHello1)
895  hash->update(context->transcriptHashContext, message,
896  hash->digestSize + sizeof(TlsHandshake));
897 
898  //Successful processing
899  return NO_ERROR;
900 }
901 
902 
903 /**
904  * @brief Check whether an externally established PSK is valid
905  * @param[in] context Pointer to the TLS context
906  * @return TRUE is the PSK is valid, else FALSE
907  **/
908 
910 {
911  bool_t valid = FALSE;
912 
913  //Make sure the hash algorithm associated with the PSK is valid
914  if(tlsGetHashAlgo(context->pskHashAlgo) != NULL)
915  {
916  //Valid PSK?
917  if(context->psk != NULL && context->pskLen > 0)
918  {
919  //Check whether TLS operates as a client or a server
920  if(context->entity == TLS_CONNECTION_END_CLIENT)
921  {
922  //Valid PSK identity?
923  if(context->pskIdentity != NULL)
924  {
925  valid = TRUE;
926  }
927  }
928  else
929  {
930  valid = TRUE;
931  }
932  }
933  }
934 
935  //Return TRUE is the PSK is valid, else FALSE
936  return valid;
937 }
938 
939 
940 /**
941  * @brief Check whether a given named group is supported
942  * @param[in] context Pointer to the TLS context
943  * @param[in] namedGroup Named group
944  * @return TRUE is the named group is supported, else FALSE
945  **/
946 
947 bool_t tls13IsGroupSupported(TlsContext *context, uint16_t namedGroup)
948 {
949  bool_t acceptable;
950 
951  //Initialize flag
952  acceptable = FALSE;
953 
954  //Check whether the specified named group is supported
955  if(tls13IsFfdheGroupSupported(context, namedGroup))
956  {
957  acceptable = TRUE;
958  }
959  else if(tls13IsEcdheGroupSupported(context, namedGroup))
960  {
961  acceptable = TRUE;
962  }
963  else if(tls13IsMlkemGroupSupported(context, namedGroup))
964  {
965  acceptable = TRUE;
966  }
967  else if(tls13IsHybridGroupSupported(context, namedGroup))
968  {
969  acceptable = TRUE;
970  }
971  else
972  {
973  acceptable = FALSE;
974  }
975 
976  //Return TRUE is the named group is supported
977  return acceptable;
978 }
979 
980 
981 /**
982  * @brief Check whether a given FFDHE group is supported
983  * @param[in] context Pointer to the TLS context
984  * @param[in] namedGroup Named group
985  * @return TRUE is the FFDHE group is supported, else FALSE
986  **/
987 
988 bool_t tls13IsFfdheGroupSupported(TlsContext *context, uint16_t namedGroup)
989 {
990  bool_t acceptable;
991 
992  //Initialize flag
993  acceptable = FALSE;
994 
995 #if ((TLS13_DHE_KE_SUPPORT == ENABLED || TLS13_PSK_DHE_KE_SUPPORT == ENABLED) && \
996  TLS_FFDHE_SUPPORT == ENABLED)
997  //Finite field group?
998  if(namedGroup == TLS_GROUP_FFDHE2048 ||
999  namedGroup == TLS_GROUP_FFDHE3072 ||
1000  namedGroup == TLS_GROUP_FFDHE4096 ||
1001  namedGroup == TLS_GROUP_FFDHE6144 ||
1002  namedGroup == TLS_GROUP_FFDHE8192)
1003  {
1004  //Any TLS 1.3 cipher suite proposed by the client?
1005  if((context->cipherSuiteTypes & TLS_CIPHER_SUITE_TYPE_TLS13) != 0)
1006  {
1007  //Check whether the FFDHE group is supported
1008  if(tlsGetFfdheGroup(context, namedGroup) != NULL)
1009  {
1010  acceptable = TRUE;
1011  }
1012  }
1013  }
1014 #endif
1015 
1016  //Return TRUE is the named group is supported
1017  return acceptable;
1018 }
1019 
1020 
1021 /**
1022  * @brief Check whether a given ECDHE group is supported
1023  * @param[in] context Pointer to the TLS context
1024  * @param[in] namedGroup Named group
1025  * @return TRUE is the ECDHE group is supported, else FALSE
1026  **/
1027 
1028 bool_t tls13IsEcdheGroupSupported(TlsContext *context, uint16_t namedGroup)
1029 {
1030  bool_t acceptable;
1031 
1032  //Initialize flag
1033  acceptable = FALSE;
1034 
1035 #if (TLS13_ECDHE_KE_SUPPORT == ENABLED || TLS13_PSK_ECDHE_KE_SUPPORT == ENABLED)
1036  //Elliptic curve group?
1037  if(namedGroup == TLS_GROUP_SECP256R1 ||
1038  namedGroup == TLS_GROUP_SECP384R1 ||
1039  namedGroup == TLS_GROUP_SECP521R1 ||
1040  namedGroup == TLS_GROUP_X25519 ||
1041  namedGroup == TLS_GROUP_X448 ||
1042  namedGroup == TLS_GROUP_BRAINPOOLP256R1_TLS13 ||
1043  namedGroup == TLS_GROUP_BRAINPOOLP384R1_TLS13 ||
1044  namedGroup == TLS_GROUP_BRAINPOOLP512R1_TLS13)
1045  {
1046  //Any TLS 1.3 cipher suite proposed by the client?
1047  if((context->cipherSuiteTypes & TLS_CIPHER_SUITE_TYPE_TLS13) != 0)
1048  {
1049  //Check whether the ECDHE group is supported
1050  if(tlsGetCurve(context, namedGroup) != NULL)
1051  {
1052  acceptable = TRUE;
1053  }
1054  }
1055  }
1056  else if(namedGroup == TLS_GROUP_CURVE_SM2)
1057  {
1058  //Any ShangMi cipher suite proposed by the client?
1059  if((context->cipherSuiteTypes & TLS_CIPHER_SUITE_TYPE_SM) != 0)
1060  {
1061  //Check whether the SM2 group is supported
1062  if(tlsGetCurve(context, namedGroup) != NULL)
1063  {
1064  acceptable = TRUE;
1065  }
1066  }
1067  }
1068  else
1069  {
1070  //Unknown group
1071  }
1072 #endif
1073 
1074  //Return TRUE is the named group is supported
1075  return acceptable;
1076 }
1077 
1078 
1079 /**
1080  * @brief Check whether a given ML-KEM exchange method is supported
1081  * @param[in] context Pointer to the TLS context
1082  * @param[in] namedGroup Named group
1083  * @return TRUE is the ML-KEM key exchange is supported, else FALSE
1084  **/
1085 
1086 bool_t tls13IsMlkemGroupSupported(TlsContext *context, uint16_t namedGroup)
1087 {
1088  bool_t acceptable;
1089 
1090  //Initialize flag
1091  acceptable = FALSE;
1092 
1093 #if (TLS13_MLKEM_KE_SUPPORT == ENABLED || TLS13_PSK_MLKEM_KE_SUPPORT == ENABLED)
1094  //ML-KEM key exchange method?
1095  if(namedGroup == TLS_GROUP_MLKEM512 ||
1096  namedGroup == TLS_GROUP_MLKEM768 ||
1097  namedGroup == TLS_GROUP_MLKEM1024)
1098  {
1099  //Any TLS 1.3 cipher suite proposed by the client?
1100  if((context->cipherSuiteTypes & TLS_CIPHER_SUITE_TYPE_TLS13) != 0)
1101  {
1102  //Check whether the ML-KEM key exchange method is supported
1103  if(tls13GetMlkemAlgo(context, namedGroup) != NULL)
1104  {
1105  acceptable = TRUE;
1106  }
1107  }
1108  }
1109  else
1110  {
1111  //Unknown group
1112  }
1113 #endif
1114 
1115  //Return TRUE is the named group is supported
1116  return acceptable;
1117 }
1118 
1119 
1120 /**
1121  * @brief Check whether a given hybrid key exchange method is supported
1122  * @param[in] context Pointer to the TLS context
1123  * @param[in] namedGroup Named group
1124  * @return TRUE is the hybrid key exchange is supported, else FALSE
1125  **/
1126 
1127 bool_t tls13IsHybridGroupSupported(TlsContext *context, uint16_t namedGroup)
1128 {
1129  bool_t acceptable;
1130 
1131  //Initialize flag
1132  acceptable = FALSE;
1133 
1134 #if (TLS13_HYBRID_KE_SUPPORT == ENABLED || TLS13_PSK_HYBRID_KE_SUPPORT == ENABLED)
1135  //Hybrid key exchange method?
1136  if(namedGroup == TLS_GROUP_SECP256R1_MLKEM768 ||
1137  namedGroup == TLS_GROUP_SECP384R1_MLKEM1024 ||
1138  namedGroup == TLS_GROUP_CURVE_SM2_MLKEM768 ||
1139  namedGroup == TLS_GROUP_X25519_MLKEM768)
1140  {
1141  //Any TLS 1.3 cipher suite proposed by the client?
1142  if((context->cipherSuiteTypes & TLS_CIPHER_SUITE_TYPE_TLS13) != 0)
1143  {
1144  //Check whether the hybrid key exchange method is supported
1145  if(tls13GetTraditionalAlgo(context, namedGroup) != NULL &&
1146  tls13GetNextGenAlgo(context, namedGroup) != NULL)
1147  {
1148  acceptable = TRUE;
1149  }
1150  }
1151  }
1152  else
1153  {
1154  //Unknown group
1155  }
1156 #endif
1157 
1158  //Return TRUE is the named group is supported
1159  return acceptable;
1160 }
1161 
1162 
1163 /**
1164  * @brief Get the ML-KEM algorithm that matches the specified named group
1165  * @param[in] context Pointer to the TLS context
1166  * @param[in] namedGroup Hybrid key exchange method
1167  * @return ML-KEM algorithm
1168  **/
1169 
1170 const KemAlgo *tls13GetMlkemAlgo(TlsContext *context, uint16_t namedGroup)
1171 {
1172  const KemAlgo *kemAlgo;
1173 
1174  //Default KEM algorithm
1175  kemAlgo = NULL;
1176 
1177 #if (TLS13_MLKEM_KE_SUPPORT == ENABLED || TLS13_PSK_MLKEM_KE_SUPPORT == ENABLED)
1178  //Check named group
1179  switch(namedGroup)
1180  {
1181 #if (TLS_MLKEM512_SUPPORT == ENABLED)
1182  //ML-KEM-512 key encapsulation mechanism?
1183  case TLS_GROUP_MLKEM512:
1184  kemAlgo = MLKEM512_KEM_ALGO;
1185  break;
1186 #endif
1187 #if (TLS_MLKEM768_SUPPORT == ENABLED)
1188  //ML-KEM-768 key encapsulation mechanism?
1189  case TLS_GROUP_MLKEM768:
1190  kemAlgo = MLKEM768_KEM_ALGO;
1191  break;
1192 #endif
1193 #if (TLS_MLKEM1024_SUPPORT == ENABLED)
1194  //ML-KEM-1024 key encapsulation mechanism?
1195  case TLS_GROUP_MLKEM1024:
1196  kemAlgo = MLKEM1024_KEM_ALGO;
1197  break;
1198 #endif
1199  //Unknown group?
1200  default:
1201  kemAlgo = NULL;
1202  break;
1203  }
1204 
1205  //Restrict the use of certain algorithms
1206  if(context->numSupportedGroups > 0)
1207  {
1208  uint_t i;
1209 
1210  //Loop through the list of allowed named groups
1211  for(i = 0; i < context->numSupportedGroups; i++)
1212  {
1213  //Compare named groups
1214  if(context->supportedGroups[i] == namedGroup)
1215  break;
1216  }
1217 
1218  //Check whether the use of the algorithm is restricted
1219  if(i >= context->numSupportedGroups)
1220  {
1221  kemAlgo = NULL;
1222  }
1223  }
1224 #endif
1225 
1226  //Return KEM algorithm, if any
1227  return kemAlgo;
1228 }
1229 
1230 
1231 /**
1232  * @brief Get the traditional algorithm used by the hybrid key exchange method
1233  * @param[in] context Pointer to the TLS context
1234  * @param[in] namedGroup Hybrid key exchange method
1235  * @return Traditional algorithm
1236  **/
1237 
1239  uint16_t namedGroup)
1240 {
1241  const EcCurve *curve;
1242 
1243  //Default elliptic curve parameters
1244  curve = NULL;
1245 
1246 #if (TLS13_HYBRID_KE_SUPPORT == ENABLED || TLS13_PSK_HYBRID_KE_SUPPORT == ENABLED)
1247  //Check named group
1248  switch(namedGroup)
1249  {
1250 #if (TLS_SECP256R1_SUPPORT == ENABLED)
1251  //secp256r1 elliptic curve?
1253  curve = ecGetCurve(SECP256R1_OID, sizeof(SECP256R1_OID));
1254  break;
1255 #endif
1256 #if (TLS_SECP384R1_SUPPORT == ENABLED)
1257  //secp384r1 elliptic curve?
1259  curve = ecGetCurve(SECP384R1_OID, sizeof(SECP384R1_OID));
1260  break;
1261 #endif
1262 #if (TLS_SM2_SUPPORT == ENABLED)
1263  //SM2 elliptic curve?
1265  curve = ecGetCurve(SM2_OID, sizeof(SM2_OID));
1266  break;
1267 #endif
1268 #if (TLS_X25519_SUPPORT == ENABLED)
1269  //Curve25519 elliptic curve?
1271  curve = ecGetCurve(X25519_OID, sizeof(X25519_OID));
1272  break;
1273 #endif
1274  //Unknown group?
1275  default:
1276  curve = NULL;
1277  break;
1278  }
1279 
1280  //Restrict the use of certain algorithms
1281  if(context->numSupportedGroups > 0)
1282  {
1283  uint_t i;
1284 
1285  //Loop through the list of allowed named groups
1286  for(i = 0; i < context->numSupportedGroups; i++)
1287  {
1288  //Compare named groups
1289  if(context->supportedGroups[i] == namedGroup)
1290  break;
1291  }
1292 
1293  //Check whether the use of the algorithm is restricted
1294  if(i >= context->numSupportedGroups)
1295  {
1296  curve = NULL;
1297  }
1298  }
1299 #endif
1300 
1301  //Return the elliptic curve parameters, if any
1302  return curve;
1303 }
1304 
1305 
1306 /**
1307  * @brief Get the next-gen algorithm used by the hybrid key exchange method
1308  * @param[in] context Pointer to the TLS context
1309  * @param[in] namedGroup Hybrid key exchange method
1310  * @return Next-gen algorithm
1311  **/
1312 
1313 const KemAlgo *tls13GetNextGenAlgo(TlsContext *context, uint16_t namedGroup)
1314 {
1315  const KemAlgo *kemAlgo;
1316 
1317  //Default KEM algorithm
1318  kemAlgo = NULL;
1319 
1320 #if (TLS13_HYBRID_KE_SUPPORT == ENABLED || TLS13_PSK_HYBRID_KE_SUPPORT == ENABLED)
1321  //Check named group
1322  switch(namedGroup)
1323  {
1324 #if (TLS_MLKEM768_SUPPORT == ENABLED)
1325  //ML-KEM-768 key encapsulation mechanism?
1329  kemAlgo = MLKEM768_KEM_ALGO;
1330  break;
1331 #endif
1332 #if (TLS_MLKEM1024_SUPPORT == ENABLED)
1333  //ML-KEM-1024 key encapsulation mechanism?
1335  kemAlgo = MLKEM1024_KEM_ALGO;
1336  break;
1337 #endif
1338  //Unknown group?
1339  default:
1340  kemAlgo = NULL;
1341  break;
1342  }
1343 
1344  //Restrict the use of certain algorithms
1345  if(context->numSupportedGroups > 0)
1346  {
1347  uint_t i;
1348 
1349  //Loop through the list of allowed named groups
1350  for(i = 0; i < context->numSupportedGroups; i++)
1351  {
1352  //Compare named groups
1353  if(context->supportedGroups[i] == namedGroup)
1354  break;
1355  }
1356 
1357  //Check whether the use of the algorithm is restricted
1358  if(i >= context->numSupportedGroups)
1359  {
1360  kemAlgo = NULL;
1361  }
1362  }
1363 #endif
1364 
1365  //Return KEM algorithm, if any
1366  return kemAlgo;
1367 }
1368 
1369 
1370 /**
1371  * @brief Check whether the specified key share group is a duplicate
1372  * @param[in] namedGroup Named group
1373  * @param[in] p List of key share entries
1374  * @param[in] length Length of the list, in bytes
1375  * @return Error code
1376  **/
1377 
1378 error_t tls13CheckDuplicateKeyShare(uint16_t namedGroup, const uint8_t *p,
1379  size_t length)
1380 {
1381  size_t n;
1382  const Tls13KeyShareEntry *keyShareEntry;
1383 
1384  //Parse the list of key share entries offered by the peer
1385  while(length > 0)
1386  {
1387  //Malformed extension?
1388  if(length < sizeof(Tls13KeyShareEntry))
1389  return ERROR_DECODING_FAILED;
1390 
1391  //Point to the current key share entry
1392  keyShareEntry = (Tls13KeyShareEntry *) p;
1393  //Retrieve the length of the key_exchange field
1394  n = ntohs(keyShareEntry->length);
1395 
1396  //Malformed extension?
1397  if(length < (sizeof(Tls13KeyShareEntry) + n))
1398  return ERROR_DECODING_FAILED;
1399 
1400  //Clients must not offer multiple KeyShareEntry values for the same
1401  //group. Servers may check for violations of this rule and abort the
1402  //handshake with an illegal_parameter alert
1403  if(ntohs(keyShareEntry->group) == namedGroup)
1404  return ERROR_ILLEGAL_PARAMETER;
1405 
1406  //Jump to the next key share entry
1407  p += sizeof(Tls13KeyShareEntry) + n;
1408  //Number of bytes left to process
1409  length -= sizeof(Tls13KeyShareEntry) + n;
1410  }
1411 
1412  //Successful verification
1413  return NO_ERROR;
1414 }
1415 
1416 
1417 /**
1418  * @brief Format certificate extensions
1419  * @param[in] p Output stream where to write the list of extensions
1420  * @param[out] written Total number of bytes that have been written
1421  * @return Error code
1422  **/
1423 
1424 error_t tls13FormatCertExtensions(uint8_t *p, size_t *written)
1425 {
1426  TlsExtensionList *extensionList;
1427 
1428  //Point to the list of extensions
1429  extensionList = (TlsExtensionList *) p;
1430 
1431  //Extensions in the Certificate message from the server must correspond to
1432  //ones from the ClientHello message. Extensions in the Certificate message
1433  //from the client must correspond to extensions in the CertificateRequest
1434  //message from the server
1435  extensionList->length = HTONS(0);
1436 
1437  //Total number of bytes that have been written
1438  *written = sizeof(TlsExtensionList);
1439 
1440  //Successful processing
1441  return NO_ERROR;
1442 }
1443 
1444 
1445 /**
1446  * @brief Parse certificate extensions
1447  * @param[in] p Input stream where to read the list of extensions
1448  * @param[in] length Number of bytes available in the input stream
1449  * @param[out] consumed Total number of bytes that have been consumed
1450  * @return Error code
1451  **/
1452 
1453 error_t tls13ParseCertExtensions(const uint8_t *p, size_t length,
1454  size_t *consumed)
1455 {
1456  error_t error;
1457  size_t n;
1459  const TlsExtensionList *extensionList;
1460 
1461  //Point to the list of extensions
1462  extensionList = (TlsExtensionList *) p;
1463 
1464  //Malformed CertificateEntry?
1465  if(length < sizeof(TlsExtensionList))
1466  return ERROR_DECODING_FAILED;
1467 
1468  //Retrieve the length of the list
1469  n = sizeof(TlsExtensionList) + ntohs(extensionList->length);
1470 
1471  //Malformed CertificateEntry?
1472  if(length < n)
1473  return ERROR_DECODING_FAILED;
1474 
1475  //Parse the list of extensions for the current CertificateEntry
1477  &extensions);
1478  //Any error to report?
1479  if(error)
1480  return error;
1481 
1482  //Check the list of extensions
1484  &extensions);
1485  //Any error to report?
1486  if(error)
1487  return error;
1488 
1489  //Total number of bytes that have been consumed
1490  *consumed = n;
1491 
1492  //Successful processing
1493  return NO_ERROR;
1494 }
1495 
1496 #endif
@ TLS_GROUP_X25519_MLKEM768
Definition: tls.h:1520
@ TLS_GROUP_BRAINPOOLP512R1_TLS13
Definition: tls.h:1501
#define tlsAllocMem(size)
Definition: tls.h:889
@ TLS_TYPE_MESSAGE_HASH
Definition: tls.h:1124
Parsing and checking of TLS extensions.
TLS helper functions.
const uint8_t tls11DowngradeRandom[8]
Definition: tls13_misc.c:53
HashAlgoInit init
Definition: crypto.h:1161
uint8_t extensions[]
Definition: ntp_common.h:213
@ TLS_GROUP_BRAINPOOLP256R1_TLS13
Definition: tls.h:1499
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:1491
@ TLS_GROUP_CURVE_SM2
Definition: tls.h:1509
size_t digestSize
Definition: crypto.h:1157
TLS 1.3 session tickets.
HashAlgoUpdate update
Definition: crypto.h:1162
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:1086
@ 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:1212
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:1498
@ TLS_CIPHER_SUITE_TYPE_TLS13
@ TLS_GROUP_FFDHE6144
Definition: tls.h:1513
size_t contextSize
Definition: crypto.h:1155
@ TLS_STATE_CLIENT_HELLO
Definition: tls.h:1559
error_t tls13ParseCertExtensions(const uint8_t *p, size_t length, size_t *consumed)
Parse certificate extensions.
Definition: tls13_misc.c:1453
@ TLS_CIPHER_SUITE_TYPE_SM
TLS 1.3 helper functions.
@ TLS_GROUP_CURVE_SM2_MLKEM768
Definition: tls.h:1522
@ TLS_TYPE_CERTIFICATE
Definition: tls.h:1111
TlsExtensionList
Definition: tls.h:1727
TlsHandshake
Definition: tls.h:1897
#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:144
#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:947
@ TLS_GROUP_SECP256R1_MLKEM768
Definition: tls.h:1519
size_t sharedSecretSize
Definition: crypto.h:1215
#define TLS_PREMASTER_SECRET_SIZE
Definition: tls.h:844
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:1028
const KemAlgo * tls13GetMlkemAlgo(TlsContext *context, uint16_t namedGroup)
Get the ML-KEM algorithm that matches the specified named group.
Definition: tls13_misc.c:1170
const KemAlgo * tls13GetNextGenAlgo(TlsContext *context, uint16_t namedGroup)
Get the next-gen algorithm used by the hybrid key exchange method.
Definition: tls13_misc.c:1313
@ 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:802
error_t tls13Decapsulate(TlsContext *context, const uint8_t *keyShare, size_t length)
Decapsulation algorithm.
Definition: tls13_misc.c:660
@ TLS_GROUP_FFDHE4096
Definition: tls.h:1512
@ TLS_TYPE_CLIENT_HELLO
Definition: tls.h:1102
#define MLKEM512_KEM_ALGO
Definition: mlkem512.h:47
#define TLS_VERSION_1_3
Definition: tls.h:98
@ ERROR_INVALID_LENGTH
Definition: error.h:111
@ TLS_GROUP_SECP384R1
Definition: tls.h:1492
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:988
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:1127
uint8_t length
Definition: tcp.h:375
@ TLS_GROUP_FFDHE2048
Definition: tls.h:1510
error_t tls13FormatCertExtensions(uint8_t *p, size_t *written)
Format certificate extensions.
Definition: tls13_misc.c:1424
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:1516
@ TLS_GROUP_SECP521R1
Definition: tls.h:1493
@ TLS_GROUP_FFDHE3072
Definition: tls.h:1511
Hello extensions.
Definition: tls.h:2278
@ TLS_GROUP_BRAINPOOLP384R1_TLS13
Definition: tls.h:1500
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:1163
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:1560
#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:909
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
@ TLS_GROUP_MLKEM1024
Definition: tls.h:1518
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:965
Common interface for key encapsulation mechanisms (KEM)
Definition: crypto.h:1210
@ TLS_CONNECTION_END_CLIENT
Definition: tls.h:1029
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:1214
@ 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:1497
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:1151
error_t hkdfExtract(const HashAlgo *hash, const uint8_t *ikm, size_t ikmLen, const uint8_t *salt, size_t saltLen, uint8_t *prk)
HKDF extract step.
Definition: hkdf.c:97
const EcCurve * tls13GetTraditionalAlgo(TlsContext *context, uint16_t namedGroup)
Get the traditional algorithm used by the hybrid key exchange method.
Definition: tls13_misc.c:1238
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:1517
#define tlsFreeMem(p)
Definition: tls.h:894
error_t tls13DigestClientHello1(TlsContext *context)
Hash ClientHello1 in the transcript when HelloRetryRequest is used.
Definition: tls13_misc.c:844
__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:1378
#define TlsEncryptionEngine
Definition: tls.h:40
#define MLKEM768_KEM_ALGO
Definition: mlkem768.h:47
@ TLS_GROUP_FFDHE8192
Definition: tls.h:1514
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:1521
uint_t mpiGetByteLength(const Mpi *a)
Get the actual length in bytes.
Definition: mpi.c:216