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