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.0
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  //Save elliptic curve parameters
314  context->ecdhContext.curve = curve;
315 
316  //Generate an ephemeral key pair
317  error = ecdhGenerateKeyPair(&context->ecdhContext, context->prngAlgo,
318  context->prngContext);
319  }
320  else
321  {
322  //Unsupported elliptic curve
323  error = ERROR_ILLEGAL_PARAMETER;
324  }
325  }
326  else
327 #endif
328 #if (TLS13_MLKEM_KE_SUPPORT == ENABLED || TLS13_PSK_MLKEM_KE_SUPPORT == ENABLED)
329  //ML-KEM key exchange method?
330  if(tls13IsMlkemGroupSupported(context, namedGroup))
331  {
332  const KemAlgo *kemAlgo;
333 
334  //Retrieve the ML-KEM algorithm to be used
335  kemAlgo = tls13GetMlkemAlgo(context, namedGroup);
336 
337  //Valid algorithm?
338  if(kemAlgo != NULL)
339  {
340  //Save the named group
341  context->namedGroup = namedGroup;
342 
343  //Initialize KEM context
344  kemFree(&context->kemContext);
345  kemInit(&context->kemContext, kemAlgo);
346 
347  //Generate a public key pk and a secret key sk
348  error = kemGenerateKeyPair(&context->kemContext, context->prngAlgo,
349  context->prngContext);
350  }
351  else
352  {
353  //Unsupported ML-KEM key exchange method
354  error = ERROR_ILLEGAL_PARAMETER;
355  }
356  }
357  else
358 #endif
359 #if (TLS13_HYBRID_KE_SUPPORT == ENABLED || TLS13_PSK_HYBRID_KE_SUPPORT == ENABLED)
360  //Hybrid key exchange method?
361  if(tls13IsHybridGroupSupported(context, namedGroup))
362  {
363  const EcCurve *curve;
364  const KemAlgo *kemAlgo;
365 
366  //Retrieve the traditional and the next-gen algorithms to be used
367  curve = tls13GetTraditionalAlgo(context, namedGroup);
368  kemAlgo = tls13GetNextGenAlgo(context, namedGroup);
369 
370  //Valid algorithms?
371  if(curve != NULL && kemAlgo != NULL)
372  {
373  //Save the named group
374  context->namedGroup = namedGroup;
375  //Save elliptic curve parameters
376  context->ecdhContext.curve = curve;
377 
378  //DH key exchange can be modeled as a KEM, with KeyGen corresponding
379  //to selecting an exponent x as the secret key and computing the
380  //public key g^x
381  error = ecdhGenerateKeyPair(&context->ecdhContext, context->prngAlgo,
382  context->prngContext);
383 
384  //Check status code
385  if(!error)
386  {
387  //Initialize KEM context
388  kemFree(&context->kemContext);
389  kemInit(&context->kemContext, kemAlgo);
390 
391  //Generate a public key pk and a secret key sk
392  error = kemGenerateKeyPair(&context->kemContext, context->prngAlgo,
393  context->prngContext);
394  }
395  }
396  else
397  {
398  //Unsupported hybrid key exchange method
399  error = ERROR_ILLEGAL_PARAMETER;
400  }
401  }
402  else
403 #endif
404  //Unknown group?
405  {
406  //Report an error
407  error = ERROR_ILLEGAL_PARAMETER;
408  }
409 
410  //Return status code
411  return error;
412 }
413 
414 
415 /**
416  * @brief (EC)DHE shared secret generation
417  * @param[in] context Pointer to the TLS context
418  * @param[in] keyShare Pointer to the peer's (EC)DHE parameters
419  * @param[in] length Length of the (EC)DHE parameters, in bytes
420  * @return Error code
421  **/
422 
423 error_t tls13GenerateSharedSecret(TlsContext *context, const uint8_t *keyShare,
424  size_t length)
425 {
426  error_t error;
427 
428 #if (TLS13_DHE_KE_SUPPORT == ENABLED || TLS13_PSK_DHE_KE_SUPPORT == ENABLED)
429  //Finite field group?
430  if(tls13IsFfdheGroupSupported(context, context->namedGroup))
431  {
432  size_t n;
433 
434  //Retrieve the length of the modulus
435  n = mpiGetByteLength(&context->dhContext.params.p);
436 
437  //For a given Diffie-Hellman group, the padding results in all public
438  //keys having the same length (refer to RFC 8446, section 4.2.8.1)
439  if(length == n)
440  {
441  //The Diffie-Hellman public value is encoded as a big-endian integer
442  error = mpiImport(&context->dhContext.yb, keyShare, length,
444 
445  //Check status code
446  if(!error)
447  {
448  //Verify peer's public key
449  error = dhCheckPublicKey(&context->dhContext,
450  &context->dhContext.yb);
451  }
452 
453  //Check status code
454  if(!error)
455  {
456  //The negotiated key (Z) is converted to a byte string by encoding
457  //in big-endian and left padded with zeros up to the size of the
458  //prime (refer to RFC 8446, section 7.4.1)
459  error = dhComputeSharedSecret(&context->dhContext,
460  context->premasterSecret, TLS_PREMASTER_SECRET_SIZE,
461  &context->premasterSecretLen);
462  }
463  }
464  else
465  {
466  //The length of the public key is not valid
467  error = ERROR_ILLEGAL_PARAMETER;
468  }
469  }
470  else
471 #endif
472 #if (TLS13_ECDHE_KE_SUPPORT == ENABLED || TLS13_PSK_ECDHE_KE_SUPPORT == ENABLED)
473  //Elliptic curve group?
474  if(tls13IsEcdheGroupSupported(context, context->namedGroup))
475  {
476  //Read peer's public key (refer to RFC 8446, section 4.2.8.2)
477  error = ecImportPublicKey(&context->ecdhContext.qb,
478  context->ecdhContext.curve, keyShare, length,
480 
481  //Check status code
482  if(!error)
483  {
484  //Verify peer's public key
485  error = ecdhCheckPublicKey(&context->ecdhContext,
486  &context->ecdhContext.qb);
487  }
488 
489  //Check status code
490  if(!error)
491  {
492  //ECDH shared secret calculation is performed according to IEEE Std
493  //1363-2000 (refer to RFC 8446, section 7.4.2)
494  error = ecdhComputeSharedSecret(&context->ecdhContext,
495  context->premasterSecret, TLS_PREMASTER_SECRET_SIZE,
496  &context->premasterSecretLen);
497  }
498  }
499  else
500 #endif
501  //Unknown group?
502  {
503  //Report an error
504  error = ERROR_HANDSHAKE_FAILED;
505  }
506 
507  //Return status code
508  return error;
509 }
510 
511 
512 /**
513  * @brief Encapsulation algorithm
514  * @param[in] context Pointer to the TLS context
515  * @param[in] namedGroup Named group
516  * @param[in] keyShare Pointer to the client's key share
517  * @param[in] length Length of the client's key share, in bytes
518  * @return Error code
519  **/
520 
521 error_t tls13Encapsulate(TlsContext *context, uint16_t namedGroup,
522  const uint8_t *keyShare, size_t length)
523 {
524 
525  error_t error;
526 
527 #if (TLS13_MLKEM_KE_SUPPORT == ENABLED || TLS13_PSK_MLKEM_KE_SUPPORT == ENABLED)
528  //ML-KEM key exchange method?
529  if(tls13IsMlkemGroupSupported(context, namedGroup))
530  {
531  const KemAlgo *kemAlgo;
532 
533  //Retrieve the ML-KEM algorithm to be used
534  kemAlgo = tls13GetMlkemAlgo(context, namedGroup);
535 
536  //Valid algorithm?
537  if(kemAlgo != NULL)
538  {
539  //The length of the public key is fixed
540  if(length == kemAlgo->publicKeySize)
541  {
542  //Save the named group
543  context->namedGroup = namedGroup;
544 
545  //Initialize KEM context
546  kemFree(&context->kemContext);
547  kemInit(&context->kemContext, kemAlgo);
548 
549  //The encapsulation algorithm takes as input a public key pk and
550  //outputs a ciphertext ct and shared secret ss
551  error = kemLoadPublicKey(&context->kemContext, keyShare);
552  }
553  else
554  {
555  //The length of the key share is not valid
556  error = ERROR_ILLEGAL_PARAMETER;
557  }
558  }
559  else
560  {
561  //Unsupported ML-KEM key exchange method
562  error = ERROR_ILLEGAL_PARAMETER;
563  }
564  }
565  else
566 #endif
567 #if (TLS13_HYBRID_KE_SUPPORT == ENABLED || TLS13_PSK_HYBRID_KE_SUPPORT == ENABLED)
568  //Hybrid key exchange method?
569  if(tls13IsHybridGroupSupported(context, namedGroup))
570  {
571  size_t keyShareOffset;
572  size_t sharedSecretOffset;
573  const EcCurve *curve;
574  const KemAlgo *kemAlgo;
575 
576  //Retrieve the traditional and the next-gen algorithms to be used
577  curve = tls13GetTraditionalAlgo(context, namedGroup);
578  kemAlgo = tls13GetNextGenAlgo(context, namedGroup);
579 
580  //Valid algorithms?
581  if(curve != NULL && kemAlgo != NULL)
582  {
583  //The client's share is a fixed-size concatenation of the ECDH ephemeral
584  //key share and the pk outputs of the KEM KeyGen algorithm
585  if(length > kemAlgo->publicKeySize)
586  {
587  //Save the named group
588  context->namedGroup = namedGroup;
589  //Save elliptic curve parameters
590  context->ecdhContext.curve = curve;
591 
592  //Initialize KEM context
593  kemFree(&context->kemContext);
594  kemInit(&context->kemContext, kemAlgo);
595 
596  //NIST's special publication 800-56C approves the usage of HKDF with two
597  //distinct shared secrets, with the condition that the first one is
598  //computed by a FIPS-approved key-establishment scheme
599  if(context->namedGroup == TLS_GROUP_X25519_MLKEM768)
600  {
601  keyShareOffset = kemAlgo->publicKeySize;
602  sharedSecretOffset = kemAlgo->sharedSecretSize;
603  }
604  else
605  {
606  keyShareOffset = 0;
607  sharedSecretOffset = 0;
608  }
609 
610  //DH key exchange can be modeled as a KEM, with encapsulation
611  //corresponding to selecting an exponent y, computing the ciphertext
612  //g^y and the shared secret g^(xy)
613  error = ecdhGenerateKeyPair(&context->ecdhContext,
614  context->prngAlgo, context->prngContext);
615 
616  //Check status code
617  if(!error)
618  {
619  //The ECDHE share is the serialized value of the uncompressed ECDH
620  //point representation
621  error = ecImportPublicKey(&context->ecdhContext.qb,
622  context->ecdhContext.curve, keyShare + keyShareOffset,
624  }
625 
626  //Check status code
627  if(!error)
628  {
629  //Verify client's public key
630  error = ecdhCheckPublicKey(&context->ecdhContext,
631  &context->ecdhContext.qb);
632  }
633 
634  //Check status code
635  if(!error)
636  {
637  //Compute the shared secret g^(xy)
638  error = ecdhComputeSharedSecret(&context->ecdhContext,
639  context->premasterSecret + sharedSecretOffset,
640  TLS_PREMASTER_SECRET_SIZE - sharedSecretOffset,
641  &context->premasterSecretLen);
642  }
643 
644  //Check status code
645  if(!error)
646  {
647  //X25519MLKEM768 group?
648  if(context->namedGroup == TLS_GROUP_X25519_MLKEM768)
649  {
650  keyShareOffset = 0;
651  }
652  else
653  {
654  keyShareOffset = length - kemAlgo->publicKeySize;
655  }
656 
657  //The encapsulation algorithm takes as input a public key pk and
658  //outputs a ciphertext ct and shared secret ss
659  error = kemLoadPublicKey(&context->kemContext,
660  keyShare + keyShareOffset);
661  }
662  }
663  else
664  {
665  //The length of the key share is not valid
666  error = ERROR_ILLEGAL_PARAMETER;
667  }
668  }
669  else
670  {
671  //Unsupported hybrid key exchange method
672  error = ERROR_ILLEGAL_PARAMETER;
673  }
674  }
675  else
676 #endif
677  //Unknown key exchange method?
678  {
679  //Report an error
680  error = ERROR_ILLEGAL_PARAMETER;
681  }
682 
683  //Return status code
684  return error;
685 }
686 
687 
688 /**
689  * @brief Decapsulation algorithm
690  * @param[in] context Pointer to the TLS context
691  * @param[in] keyShare Pointer to the server's key share
692  * @param[in] length Length of the client's key share, in bytes
693  * @return Error code
694  **/
695 
696 error_t tls13Decapsulate(TlsContext *context, const uint8_t *keyShare,
697  size_t length)
698 {
699  error_t error;
700 
701 #if (TLS13_MLKEM_KE_SUPPORT == ENABLED || TLS13_PSK_MLKEM_KE_SUPPORT == ENABLED)
702  //ML-KEM key exchange method?
703  if(tls13IsMlkemGroupSupported(context, context->namedGroup))
704  {
705  const KemAlgo *kemAlgo;
706 
707  //Retrieve the ML-KEM algorithm to be used
708  kemAlgo = tls13GetMlkemAlgo(context, context->namedGroup);
709 
710  //The length of the ciphertext is fixed
711  if(length == kemAlgo->ciphertextSize)
712  {
713  //The decapsulation algorithm takes as input a secret key sk and
714  //ciphertext ct and outputs a shared secret ss
715  error = kemDecapsulate(&context->kemContext, keyShare,
716  context->premasterSecret);
717 
718  //Check status code
719  if(!error)
720  {
721  //The shared secret output from the ML-KEM Decaps is inserted into
722  //the TLS 1.3 key schedule in place of the (EC)DHE shared secret
723  context->premasterSecretLen = kemAlgo->sharedSecretSize;
724  }
725  }
726  else
727  {
728  //The length of the key share is not valid
729  error = ERROR_ILLEGAL_PARAMETER;
730  }
731  }
732  else
733 #endif
734 #if (TLS13_HYBRID_KE_SUPPORT == ENABLED || TLS13_PSK_HYBRID_KE_SUPPORT == ENABLED)
735  //Hybrid key exchange method?
736  if(tls13IsHybridGroupSupported(context, context->namedGroup))
737  {
738  size_t keyShareOffset;
739  size_t sharedSecretOffset;
740  const KemAlgo *kemAlgo;
741 
742  //Point to the KEM algorithm
743  kemAlgo = context->kemContext.kemAlgo;
744 
745  //The server's share is a fixed-size concatenation of the ECDH ephemeral
746  //key share and the ct outputs of the KEM Encaps algorithm
747  if(length > kemAlgo->ciphertextSize)
748  {
749  //NIST's special publication 800-56C approves the usage of HKDF with two
750  //distinct shared secrets, with the condition that the first one is
751  //computed by a FIPS-approved key-establishment scheme
752  if(context->namedGroup == TLS_GROUP_X25519_MLKEM768)
753  {
754  keyShareOffset = kemAlgo->ciphertextSize;
755  sharedSecretOffset = kemAlgo->sharedSecretSize;
756  }
757  else
758  {
759  keyShareOffset = 0;
760  sharedSecretOffset = 0;
761  }
762 
763  //Decode the server's ECDH ephemeral share
764  error = ecImportPublicKey(&context->ecdhContext.qb,
765  context->ecdhContext.curve, keyShare + keyShareOffset,
767 
768  //Check status code
769  if(!error)
770  {
771  //Verify server's public key
772  error = ecdhCheckPublicKey(&context->ecdhContext,
773  &context->ecdhContext.qb);
774  }
775 
776  //Check status code
777  if(!error)
778  {
779  //DH key exchange can be modeled as a KEM, with decapsulation
780  //corresponding to computing the shared secret g^(xy)
781  error = ecdhComputeSharedSecret(&context->ecdhContext,
782  context->premasterSecret + sharedSecretOffset,
783  TLS_PREMASTER_SECRET_SIZE - sharedSecretOffset,
784  &context->premasterSecretLen);
785  }
786 
787  //Check status code
788  if(!error)
789  {
790  //X25519MLKEM768 group?
791  if(context->namedGroup == TLS_GROUP_X25519_MLKEM768)
792  {
793  keyShareOffset = 0;
794  sharedSecretOffset = 0;
795  }
796  else
797  {
798  keyShareOffset = length - kemAlgo->ciphertextSize;
799  sharedSecretOffset = context->premasterSecretLen;
800  }
801 
802  //The decapsulation algorithm takes as input a secret key sk and
803  //ciphertext ct and outputs a shared secret ss
804  error = kemDecapsulate(&context->kemContext, keyShare + keyShareOffset,
805  context->premasterSecret + sharedSecretOffset);
806  }
807 
808  //Check status code
809  if(!error)
810  {
811  //The two shared secrets are concatenated together and used as the
812  //shared secret in the existing TLS 1.3 key schedule
813  context->premasterSecretLen += kemAlgo->sharedSecretSize;
814  }
815  }
816  else
817  {
818  //The length of the key share is not valid
819  error = ERROR_ILLEGAL_PARAMETER;
820  }
821  }
822  else
823 #endif
824  //Unknown key exchange method?
825  {
826  //Report an error
827  error = ERROR_ILLEGAL_PARAMETER;
828  }
829 
830  //Return status code
831  return error;
832 }
833 
834 
835 /**
836  * @brief Compute message authentication code
837  * @param[in] context Pointer to the TLS context
838  * @param[in] encryptionEngine Pointer to the encryption/decryption engine
839  * @param[in] record Pointer to the TLS record
840  * @param[in] data Pointer to the record data
841  * @param[in] dataLen Length of the data
842  * @param[out] mac The computed MAC value
843  * @return Error code
844  **/
845 
847  void *record, const uint8_t *data, size_t dataLen, uint8_t *mac)
848 {
849  size_t aadLen;
850  size_t nonceLen;
851  uint8_t aad[13];
852  uint8_t nonce[12];
853  HmacContext *hmacContext;
854 
855  //Point to the HMAC context
856  hmacContext = encryptionEngine->hmacContext;
857 
858  //Initialize HMAC calculation
859  hmacInit(hmacContext, encryptionEngine->hashAlgo,
860  encryptionEngine->encKey, encryptionEngine->encKeyLen);
861 
862  //Additional data to be authenticated
863  tlsFormatAad(context, encryptionEngine, record, aad, &aadLen);
864 
865  //Generate the nonce
866  tlsFormatNonce(context, encryptionEngine, record, data, nonce,
867  &nonceLen);
868 
869  //Compute HMAC(write_key, nonce || additional_data || plaintext)
870  hmacUpdate(hmacContext, nonce, nonceLen);
871  hmacUpdate(hmacContext, aad, aadLen);
872  hmacUpdate(hmacContext, data, dataLen);
873 
874  //Finalize HMAC computation
875  hmacFinal(hmacContext, mac);
876 
877  //Successful processing
878  return NO_ERROR;
879 }
880 
881 
882 /**
883  * @brief Hash ClientHello1 in the transcript when HelloRetryRequest is used
884  * @param[in] context Pointer to the TLS context
885  * @return Error code
886  **/
887 
889 {
891  const HashAlgo *hash;
892 
893  //Invalid hash context?
894  if(context->transcriptHashContext == NULL)
895  return ERROR_FAILURE;
896 
897  //The hash function used by HKDF is the cipher suite hash algorithm
898  hash = context->cipherSuite.prfHashAlgo;
899  //Make sure the hash algorithm is valid
900  if(hash == NULL)
901  return ERROR_FAILURE;
902 
903  //Point to the buffer where to format the handshake message
904  message = (TlsHandshake *) context->txBuffer;
905 
906  //Handshake message type
907  message->msgType = TLS_TYPE_MESSAGE_HASH;
908  //Number of bytes in the message
909  STORE24BE(hash->digestSize, message->length);
910 
911  //Compute Hash(ClientHello1)
912  hash->final(context->transcriptHashContext, message->data);
913  //Re-initialize hash algorithm context
914  hash->init(context->transcriptHashContext);
915 
916  //When the server responds to a ClientHello with a HelloRetryRequest, the
917  //value of ClientHello1 is replaced with a special synthetic handshake
918  //message of handshake type MessageHash containing Hash(ClientHello1)
919  hash->update(context->transcriptHashContext, message,
920  hash->digestSize + sizeof(TlsHandshake));
921 
922  //Successful processing
923  return NO_ERROR;
924 }
925 
926 
927 /**
928  * @brief Check whether an externally established PSK is valid
929  * @param[in] context Pointer to the TLS context
930  * @return TRUE is the PSK is valid, else FALSE
931  **/
932 
934 {
935  bool_t valid = FALSE;
936 
937  //Make sure the hash algorithm associated with the PSK is valid
938  if(tlsGetHashAlgo(context->pskHashAlgo) != NULL)
939  {
940  //Valid PSK?
941  if(context->psk != NULL && context->pskLen > 0)
942  {
943  //Check whether TLS operates as a client or a server
944  if(context->entity == TLS_CONNECTION_END_CLIENT)
945  {
946  //Valid PSK identity?
947  if(context->pskIdentity != NULL)
948  {
949  valid = TRUE;
950  }
951  }
952  else
953  {
954  valid = TRUE;
955  }
956  }
957  }
958 
959  //Return TRUE is the PSK is valid, else FALSE
960  return valid;
961 }
962 
963 
964 /**
965  * @brief Check whether a given named group is supported
966  * @param[in] context Pointer to the TLS context
967  * @param[in] namedGroup Named group
968  * @return TRUE is the named group is supported, else FALSE
969  **/
970 
971 bool_t tls13IsGroupSupported(TlsContext *context, uint16_t namedGroup)
972 {
973  bool_t acceptable;
974 
975  //Initialize flag
976  acceptable = FALSE;
977 
978  //Check whether the specified named group is supported
979  if(tls13IsFfdheGroupSupported(context, namedGroup))
980  {
981  acceptable = TRUE;
982  }
983  else if(tls13IsEcdheGroupSupported(context, namedGroup))
984  {
985  acceptable = TRUE;
986  }
987  else if(tls13IsMlkemGroupSupported(context, namedGroup))
988  {
989  acceptable = TRUE;
990  }
991  else if(tls13IsHybridGroupSupported(context, namedGroup))
992  {
993  acceptable = TRUE;
994  }
995  else
996  {
997  acceptable = FALSE;
998  }
999 
1000  //Return TRUE is the named group is supported
1001  return acceptable;
1002 }
1003 
1004 
1005 /**
1006  * @brief Check whether a given FFDHE group is supported
1007  * @param[in] context Pointer to the TLS context
1008  * @param[in] namedGroup Named group
1009  * @return TRUE is the FFDHE group is supported, else FALSE
1010  **/
1011 
1012 bool_t tls13IsFfdheGroupSupported(TlsContext *context, uint16_t namedGroup)
1013 {
1014  bool_t acceptable;
1015 
1016  //Initialize flag
1017  acceptable = FALSE;
1018 
1019 #if ((TLS13_DHE_KE_SUPPORT == ENABLED || TLS13_PSK_DHE_KE_SUPPORT == ENABLED) && \
1020  TLS_FFDHE_SUPPORT == ENABLED)
1021  //Finite field group?
1022  if(namedGroup == TLS_GROUP_FFDHE2048 ||
1023  namedGroup == TLS_GROUP_FFDHE3072 ||
1024  namedGroup == TLS_GROUP_FFDHE4096 ||
1025  namedGroup == TLS_GROUP_FFDHE6144 ||
1026  namedGroup == TLS_GROUP_FFDHE8192)
1027  {
1028  //Any TLS 1.3 cipher suite proposed by the client?
1029  if((context->cipherSuiteTypes & TLS_CIPHER_SUITE_TYPE_TLS13) != 0)
1030  {
1031  //Check whether the FFDHE group is supported
1032  if(tlsGetFfdheGroup(context, namedGroup) != NULL)
1033  {
1034  acceptable = TRUE;
1035  }
1036  }
1037  }
1038 #endif
1039 
1040  //Return TRUE is the named group is supported
1041  return acceptable;
1042 }
1043 
1044 
1045 /**
1046  * @brief Check whether a given ECDHE group is supported
1047  * @param[in] context Pointer to the TLS context
1048  * @param[in] namedGroup Named group
1049  * @return TRUE is the ECDHE group is supported, else FALSE
1050  **/
1051 
1052 bool_t tls13IsEcdheGroupSupported(TlsContext *context, uint16_t namedGroup)
1053 {
1054  bool_t acceptable;
1055 
1056  //Initialize flag
1057  acceptable = FALSE;
1058 
1059 #if (TLS13_ECDHE_KE_SUPPORT == ENABLED || TLS13_PSK_ECDHE_KE_SUPPORT == ENABLED)
1060  //Elliptic curve group?
1061  if(namedGroup == TLS_GROUP_SECP256R1 ||
1062  namedGroup == TLS_GROUP_SECP384R1 ||
1063  namedGroup == TLS_GROUP_SECP521R1 ||
1064  namedGroup == TLS_GROUP_X25519 ||
1065  namedGroup == TLS_GROUP_X448 ||
1066  namedGroup == TLS_GROUP_BRAINPOOLP256R1_TLS13 ||
1067  namedGroup == TLS_GROUP_BRAINPOOLP384R1_TLS13 ||
1068  namedGroup == TLS_GROUP_BRAINPOOLP512R1_TLS13)
1069  {
1070  //Any TLS 1.3 cipher suite proposed by the client?
1071  if((context->cipherSuiteTypes & TLS_CIPHER_SUITE_TYPE_TLS13) != 0)
1072  {
1073  //Check whether the ECDHE group is supported
1074  if(tlsGetCurve(context, namedGroup) != NULL)
1075  {
1076  acceptable = TRUE;
1077  }
1078  }
1079  }
1080  else if(namedGroup == TLS_GROUP_CURVE_SM2)
1081  {
1082  //Any ShangMi cipher suite proposed by the client?
1083  if((context->cipherSuiteTypes & TLS_CIPHER_SUITE_TYPE_SM) != 0)
1084  {
1085  //Check whether the SM2 group is supported
1086  if(tlsGetCurve(context, namedGroup) != NULL)
1087  {
1088  acceptable = TRUE;
1089  }
1090  }
1091  }
1092  else
1093  {
1094  //Unknown group
1095  }
1096 #endif
1097 
1098  //Return TRUE is the named group is supported
1099  return acceptable;
1100 }
1101 
1102 
1103 /**
1104  * @brief Check whether a given ML-KEM exchange method is supported
1105  * @param[in] context Pointer to the TLS context
1106  * @param[in] namedGroup Named group
1107  * @return TRUE is the ML-KEM key exchange is supported, else FALSE
1108  **/
1109 
1110 bool_t tls13IsMlkemGroupSupported(TlsContext *context, uint16_t namedGroup)
1111 {
1112  bool_t acceptable;
1113 
1114  //Initialize flag
1115  acceptable = FALSE;
1116 
1117 #if (TLS13_MLKEM_KE_SUPPORT == ENABLED || TLS13_PSK_MLKEM_KE_SUPPORT == ENABLED)
1118  //ML-KEM key exchange method?
1119  if(namedGroup == TLS_GROUP_MLKEM512 ||
1120  namedGroup == TLS_GROUP_MLKEM768 ||
1121  namedGroup == TLS_GROUP_MLKEM1024)
1122  {
1123  //Any TLS 1.3 cipher suite proposed by the client?
1124  if((context->cipherSuiteTypes & TLS_CIPHER_SUITE_TYPE_TLS13) != 0)
1125  {
1126  //Check whether the ML-KEM key exchange method is supported
1127  if(tls13GetMlkemAlgo(context, namedGroup) != NULL)
1128  {
1129  acceptable = TRUE;
1130  }
1131  }
1132  }
1133  else
1134  {
1135  //Unknown group
1136  }
1137 #endif
1138 
1139  //Return TRUE is the named group is supported
1140  return acceptable;
1141 }
1142 
1143 
1144 /**
1145  * @brief Check whether a given hybrid key exchange method is supported
1146  * @param[in] context Pointer to the TLS context
1147  * @param[in] namedGroup Named group
1148  * @return TRUE is the hybrid key exchange is supported, else FALSE
1149  **/
1150 
1151 bool_t tls13IsHybridGroupSupported(TlsContext *context, uint16_t namedGroup)
1152 {
1153  bool_t acceptable;
1154 
1155  //Initialize flag
1156  acceptable = FALSE;
1157 
1158 #if (TLS13_HYBRID_KE_SUPPORT == ENABLED || TLS13_PSK_HYBRID_KE_SUPPORT == ENABLED)
1159  //Hybrid key exchange method?
1160  if(namedGroup == TLS_GROUP_SECP256R1_MLKEM768 ||
1161  namedGroup == TLS_GROUP_SECP384R1_MLKEM1024 ||
1162  namedGroup == TLS_GROUP_X25519_MLKEM768)
1163  {
1164  //Any TLS 1.3 cipher suite proposed by the client?
1165  if((context->cipherSuiteTypes & TLS_CIPHER_SUITE_TYPE_TLS13) != 0)
1166  {
1167  //Check whether the hybrid key exchange method is supported
1168  if(tls13GetTraditionalAlgo(context, namedGroup) != NULL &&
1169  tls13GetNextGenAlgo(context, namedGroup) != NULL)
1170  {
1171  acceptable = TRUE;
1172  }
1173  }
1174  }
1175  else
1176  {
1177  //Unknown group
1178  }
1179 #endif
1180 
1181  //Return TRUE is the named group is supported
1182  return acceptable;
1183 }
1184 
1185 
1186 /**
1187  * @brief Get the ML-KEM algorithm that matches the specified named group
1188  * @param[in] context Pointer to the TLS context
1189  * @param[in] namedGroup Hybrid key exchange method
1190  * @return ML-KEM algorithm
1191  **/
1192 
1193 const KemAlgo *tls13GetMlkemAlgo(TlsContext *context, uint16_t namedGroup)
1194 {
1195  const KemAlgo *kemAlgo;
1196 
1197  //Default KEM algorithm
1198  kemAlgo = NULL;
1199 
1200 #if (TLS13_MLKEM_KE_SUPPORT == ENABLED || TLS13_PSK_MLKEM_KE_SUPPORT == ENABLED)
1201  //Check named group
1202  switch(namedGroup)
1203  {
1204 #if (TLS_MLKEM512_SUPPORT == ENABLED)
1205  //ML-KEM-512 key encapsulation mechanism?
1206  case TLS_GROUP_MLKEM512:
1207  kemAlgo = MLKEM512_KEM_ALGO;
1208  break;
1209 #endif
1210 #if (TLS_MLKEM768_SUPPORT == ENABLED)
1211  //ML-KEM-768 key encapsulation mechanism?
1212  case TLS_GROUP_MLKEM768:
1213  kemAlgo = MLKEM768_KEM_ALGO;
1214  break;
1215 #endif
1216 #if (TLS_MLKEM1024_SUPPORT == ENABLED)
1217  //ML-KEM-1024 key encapsulation mechanism?
1218  case TLS_GROUP_MLKEM1024:
1219  kemAlgo = MLKEM1024_KEM_ALGO;
1220  break;
1221 #endif
1222  //Unknown group?
1223  default:
1224  kemAlgo = NULL;
1225  break;
1226  }
1227 
1228  //Restrict the use of certain algorithms
1229  if(context->numSupportedGroups > 0)
1230  {
1231  uint_t i;
1232 
1233  //Loop through the list of allowed named groups
1234  for(i = 0; i < context->numSupportedGroups; i++)
1235  {
1236  //Compare named groups
1237  if(context->supportedGroups[i] == namedGroup)
1238  break;
1239  }
1240 
1241  //Check whether the use of the algorithm is restricted
1242  if(i >= context->numSupportedGroups)
1243  {
1244  kemAlgo = NULL;
1245  }
1246  }
1247 #endif
1248 
1249  //Return KEM algorithm, if any
1250  return kemAlgo;
1251 }
1252 
1253 
1254 /**
1255  * @brief Get the traditional algorithm used by the hybrid key exchange method
1256  * @param[in] context Pointer to the TLS context
1257  * @param[in] namedGroup Hybrid key exchange method
1258  * @return Traditional algorithm
1259  **/
1260 
1262  uint16_t namedGroup)
1263 {
1264  const EcCurve *curve;
1265 
1266  //Default elliptic curve parameters
1267  curve = NULL;
1268 
1269 #if (TLS13_HYBRID_KE_SUPPORT == ENABLED || TLS13_PSK_HYBRID_KE_SUPPORT == ENABLED)
1270  //Check named group
1271  switch(namedGroup)
1272  {
1273 #if (TLS_SECP256R1_SUPPORT == ENABLED)
1274  //secp256r1 elliptic curve?
1276  curve = ecGetCurve(SECP256R1_OID, sizeof(SECP256R1_OID));
1277  break;
1278 #endif
1279 #if (TLS_SECP384R1_SUPPORT == ENABLED)
1280  //secp384r1 elliptic curve?
1282  curve = ecGetCurve(SECP384R1_OID, sizeof(SECP384R1_OID));
1283  break;
1284 #endif
1285 #if (TLS_X25519_SUPPORT == ENABLED)
1286  //Curve25519 elliptic curve?
1288  curve = ecGetCurve(X25519_OID, sizeof(X25519_OID));
1289  break;
1290 #endif
1291  //Unknown group?
1292  default:
1293  curve = NULL;
1294  break;
1295  }
1296 
1297  //Restrict the use of certain algorithms
1298  if(context->numSupportedGroups > 0)
1299  {
1300  uint_t i;
1301 
1302  //Loop through the list of allowed named groups
1303  for(i = 0; i < context->numSupportedGroups; i++)
1304  {
1305  //Compare named groups
1306  if(context->supportedGroups[i] == namedGroup)
1307  break;
1308  }
1309 
1310  //Check whether the use of the algorithm is restricted
1311  if(i >= context->numSupportedGroups)
1312  {
1313  curve = NULL;
1314  }
1315  }
1316 #endif
1317 
1318  //Return the elliptic curve parameters, if any
1319  return curve;
1320 }
1321 
1322 
1323 /**
1324  * @brief Get the next-gen algorithm used by the hybrid key exchange method
1325  * @param[in] context Pointer to the TLS context
1326  * @param[in] namedGroup Hybrid key exchange method
1327  * @return Next-gen algorithm
1328  **/
1329 
1330 const KemAlgo *tls13GetNextGenAlgo(TlsContext *context, uint16_t namedGroup)
1331 {
1332  const KemAlgo *kemAlgo;
1333 
1334  //Default KEM algorithm
1335  kemAlgo = NULL;
1336 
1337 #if (TLS13_HYBRID_KE_SUPPORT == ENABLED || TLS13_PSK_HYBRID_KE_SUPPORT == ENABLED)
1338  //Check named group
1339  switch(namedGroup)
1340  {
1341 #if (TLS_MLKEM768_SUPPORT == ENABLED)
1342  //ML-KEM-768 key encapsulation mechanism?
1345  kemAlgo = MLKEM768_KEM_ALGO;
1346  break;
1347 #endif
1348 #if (TLS_MLKEM1024_SUPPORT == ENABLED)
1349  //ML-KEM-1024 key encapsulation mechanism?
1351  kemAlgo = MLKEM1024_KEM_ALGO;
1352  break;
1353 #endif
1354  //Unknown group?
1355  default:
1356  kemAlgo = NULL;
1357  break;
1358  }
1359 
1360  //Restrict the use of certain algorithms
1361  if(context->numSupportedGroups > 0)
1362  {
1363  uint_t i;
1364 
1365  //Loop through the list of allowed named groups
1366  for(i = 0; i < context->numSupportedGroups; i++)
1367  {
1368  //Compare named groups
1369  if(context->supportedGroups[i] == namedGroup)
1370  break;
1371  }
1372 
1373  //Check whether the use of the algorithm is restricted
1374  if(i >= context->numSupportedGroups)
1375  {
1376  kemAlgo = NULL;
1377  }
1378  }
1379 #endif
1380 
1381  //Return KEM algorithm, if any
1382  return kemAlgo;
1383 }
1384 
1385 
1386 /**
1387  * @brief Check whether the specified key share group is a duplicate
1388  * @param[in] namedGroup Named group
1389  * @param[in] p List of key share entries
1390  * @param[in] length Length of the list, in bytes
1391  * @return Error code
1392  **/
1393 
1394 error_t tls13CheckDuplicateKeyShare(uint16_t namedGroup, const uint8_t *p,
1395  size_t length)
1396 {
1397  size_t n;
1398  const Tls13KeyShareEntry *keyShareEntry;
1399 
1400  //Parse the list of key share entries offered by the peer
1401  while(length > 0)
1402  {
1403  //Malformed extension?
1404  if(length < sizeof(Tls13KeyShareEntry))
1405  return ERROR_DECODING_FAILED;
1406 
1407  //Point to the current key share entry
1408  keyShareEntry = (Tls13KeyShareEntry *) p;
1409  //Retrieve the length of the key_exchange field
1410  n = ntohs(keyShareEntry->length);
1411 
1412  //Malformed extension?
1413  if(length < (sizeof(Tls13KeyShareEntry) + n))
1414  return ERROR_DECODING_FAILED;
1415 
1416  //Clients must not offer multiple KeyShareEntry values for the same
1417  //group. Servers may check for violations of this rule and abort the
1418  //handshake with an illegal_parameter alert
1419  if(ntohs(keyShareEntry->group) == namedGroup)
1420  return ERROR_ILLEGAL_PARAMETER;
1421 
1422  //Jump to the next key share entry
1423  p += sizeof(Tls13KeyShareEntry) + n;
1424  //Number of bytes left to process
1425  length -= sizeof(Tls13KeyShareEntry) + n;
1426  }
1427 
1428  //Successful verification
1429  return NO_ERROR;
1430 }
1431 
1432 
1433 /**
1434  * @brief Format certificate extensions
1435  * @param[in] p Output stream where to write the list of extensions
1436  * @param[out] written Total number of bytes that have been written
1437  * @return Error code
1438  **/
1439 
1440 error_t tls13FormatCertExtensions(uint8_t *p, size_t *written)
1441 {
1442  TlsExtensionList *extensionList;
1443 
1444  //Point to the list of extensions
1445  extensionList = (TlsExtensionList *) p;
1446 
1447  //Extensions in the Certificate message from the server must correspond to
1448  //ones from the ClientHello message. Extensions in the Certificate message
1449  //from the client must correspond to extensions in the CertificateRequest
1450  //message from the server
1451  extensionList->length = HTONS(0);
1452 
1453  //Total number of bytes that have been written
1454  *written = sizeof(TlsExtensionList);
1455 
1456  //Successful processing
1457  return NO_ERROR;
1458 }
1459 
1460 
1461 /**
1462  * @brief Parse certificate extensions
1463  * @param[in] p Input stream where to read the list of extensions
1464  * @param[in] length Number of bytes available in the input stream
1465  * @param[out] consumed Total number of bytes that have been consumed
1466  * @return Error code
1467  **/
1468 
1469 error_t tls13ParseCertExtensions(const uint8_t *p, size_t length,
1470  size_t *consumed)
1471 {
1472  error_t error;
1473  size_t n;
1475  const TlsExtensionList *extensionList;
1476 
1477  //Point to the list of extensions
1478  extensionList = (TlsExtensionList *) p;
1479 
1480  //Malformed CertificateEntry?
1481  if(length < sizeof(TlsExtensionList))
1482  return ERROR_DECODING_FAILED;
1483 
1484  //Retrieve the length of the list
1485  n = sizeof(TlsExtensionList) + ntohs(extensionList->length);
1486 
1487  //Malformed CertificateEntry?
1488  if(length < n)
1489  return ERROR_DECODING_FAILED;
1490 
1491  //Parse the list of extensions for the current CertificateEntry
1493  &extensions);
1494  //Any error to report?
1495  if(error)
1496  return error;
1497 
1498  //Check the list of extensions
1500  &extensions);
1501  //Any error to report?
1502  if(error)
1503  return error;
1504 
1505  //Total number of bytes that have been consumed
1506  *consumed = n;
1507 
1508  //Successful processing
1509  return NO_ERROR;
1510 }
1511 
1512 #endif
@ TLS_GROUP_X25519_MLKEM768
Definition: tls.h:1456
@ TLS_GROUP_BRAINPOOLP512R1_TLS13
Definition: tls.h:1437
#define tlsAllocMem(size)
Definition: tls.h:867
@ TLS_TYPE_MESSAGE_HASH
Definition: tls.h:1085
#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:1092
uint8_t extensions[]
Definition: ntp_common.h:207
@ TLS_GROUP_BRAINPOOLP256R1_TLS13
Definition: tls.h:1435
int bool_t
Definition: compiler_port.h:61
HMAC algorithm context.
Definition: hmac.h:59
TLS cipher suites.
error_t ecImportPublicKey(EcPublicKey *key, const EcCurve *curve, const uint8_t *data, size_t length, EcPublicKeyFormat format)
Import an EC public key.
Definition: ec.c:263
const HashAlgo * tlsGetHashAlgo(TlsHashAlgo hashAlgoId)
Get the hash algorithm that matches the specified identifier.
Definition: tls_misc.c:1184
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:1251
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:222
@ TLS_GROUP_SECP256R1
Definition: tls.h:1427
@ TLS_GROUP_CURVE_SM2
Definition: tls.h:1445
size_t digestSize
Definition: crypto.h:1088
TLS 1.3 session tickets.
@ TLS_TRANSPORT_PROTOCOL_DATAGRAM
Definition: tls.h:979
HashAlgoUpdate update
Definition: crypto.h:1093
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:1110
@ 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:49
@ EC_PUBLIC_KEY_FORMAT_X963
Definition: ec.h:386
size_t publicKeySize
Definition: crypto.h:1125
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:1434
@ TLS_CIPHER_SUITE_TYPE_TLS13
@ TLS_GROUP_FFDHE6144
Definition: tls.h:1449
size_t contextSize
Definition: crypto.h:1086
error_t tls13ParseCertExtensions(const uint8_t *p, size_t length, size_t *consumed)
Parse certificate extensions.
Definition: tls13_misc.c:1469
@ TLS_CIPHER_SUITE_TYPE_SM
TLS 1.3 helper functions.
@ TLS_TYPE_CERTIFICATE
Definition: tls.h:1072
TlsExtensionList
Definition: tls.h:1622
TlsHandshake
Definition: tls.h:1792
#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:226
@ ERROR_INVALID_PARAMETER
Invalid parameter.
Definition: error.h:47
#define osMemcpy(dest, src, length)
Definition: os_port.h:144
error_t ecdhCheckPublicKey(EcdhContext *context, const EcPublicKey *publicKey)
Check ECDH public key.
Definition: ecdh.c:224
#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:971
@ TLS_GROUP_SECP256R1_MLKEM768
Definition: tls.h:1455
size_t sharedSecretSize
Definition: crypto.h:1128
#define TLS_PREMASTER_SECRET_SIZE
Definition: tls.h:822
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:1052
const KemAlgo * tls13GetMlkemAlgo(TlsContext *context, uint16_t namedGroup)
Get the ML-KEM algorithm that matches the specified named group.
Definition: tls13_misc.c:1193
const KemAlgo * tls13GetNextGenAlgo(TlsContext *context, uint16_t namedGroup)
Get the next-gen algorithm used by the hybrid key exchange method.
Definition: tls13_misc.c:1330
@ 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:846
error_t tls13Decapsulate(TlsContext *context, const uint8_t *keyShare, size_t length)
Decapsulation algorithm.
Definition: tls13_misc.c:696
@ TLS_GROUP_FFDHE4096
Definition: tls.h:1448
@ TLS_TYPE_CLIENT_HELLO
Definition: tls.h:1063
error_t mpiImport(Mpi *r, const uint8_t *input, size_t length, MpiFormat format)
Octet string to integer conversion.
Definition: mpi.c:712
#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:1428
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:1012
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 dhCheckPublicKey(DhContext *context, const Mpi *publicKey)
Check Diffie-Hellman public value.
Definition: dh.c:183
bool_t tls13IsHybridGroupSupported(TlsContext *context, uint16_t namedGroup)
Check whether a given hybrid key exchange method is supported.
Definition: tls13_misc.c:1151
uint8_t length
Definition: tcp.h:375
@ TLS_GROUP_FFDHE2048
Definition: tls.h:1446
error_t tls13FormatCertExtensions(uint8_t *p, size_t *written)
Format certificate extensions.
Definition: tls13_misc.c:1440
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:374
const uint8_t tls13HelloRetryRequestRandom[32]
Definition: tls13_misc.c:65
uint32_t dataLen
Definition: sftp_common.h:229
@ TLS_GROUP_MLKEM512
Definition: tls.h:1452
@ TLS_GROUP_SECP521R1
Definition: tls.h:1429
@ TLS_GROUP_FFDHE3072
Definition: tls.h:1447
Hello extensions.
Definition: tls.h:2136
@ TLS_GROUP_BRAINPOOLP384R1_TLS13
Definition: tls.h:1436
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:338
HashAlgoFinal final
Definition: crypto.h:1094
#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:423
bool_t tls13IsPskValid(TlsContext *context)
Check whether an externally established PSK is valid.
Definition: tls13_misc.c:933
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:1454
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:943
Common interface for key encapsulation mechanisms (KEM)
Definition: crypto.h:1123
@ TLS_CONNECTION_END_CLIENT
Definition: tls.h:990
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:1127
@ 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:1433
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.
Common interface for hash algorithms.
Definition: crypto.h:1082
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:1261
FFDHE key exchange.
error_t tls13Encapsulate(TlsContext *context, uint16_t namedGroup, const uint8_t *keyShare, size_t length)
Encapsulation algorithm.
Definition: tls13_misc.c:521
#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:1453
#define tlsFreeMem(p)
Definition: tls.h:872
error_t tls13DigestClientHello1(TlsContext *context)
Hash ClientHello1 in the transcript when HelloRetryRequest is used.
Definition: tls13_misc.c:888
__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:1394
#define TlsEncryptionEngine
Definition: tls.h:40
#define MLKEM768_KEM_ALGO
Definition: mlkem768.h:47
@ TLS_GROUP_FFDHE8192
Definition: tls.h:1450
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:84
@ TLS_GROUP_SECP384R1_MLKEM1024
Definition: tls.h:1457
uint_t mpiGetByteLength(const Mpi *a)
Get the actual length in bytes.
Definition: mpi.c:215