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-2024 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.4.4
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 EcCurveInfo *curveInfo;
304 
305  //Retrieve the elliptic curve to be used
306  curveInfo = tlsGetCurveInfo(context, namedGroup);
307 
308  //Valid elliptic curve?
309  if(curveInfo != NULL)
310  {
311  //Save the named group
312  context->namedGroup = namedGroup;
313 
314  //Load EC domain parameters
315  error = ecLoadDomainParameters(&context->ecdhContext.params, curveInfo);
316 
317  //Check status code
318  if(!error)
319  {
320  //Generate an ephemeral key pair
321  error = ecdhGenerateKeyPair(&context->ecdhContext, context->prngAlgo,
322  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_HYBRID_KE_SUPPORT == ENABLED || TLS13_PSK_HYBRID_KE_SUPPORT == ENABLED)
334  //Hybrid key exchange method?
335  if(tls13IsHybridKeMethodSupported(context, namedGroup))
336  {
337  const EcCurveInfo *curveInfo;
338  const KemAlgo *kemAlgo;
339 
340  //Retrieve the traditional and the next-gen algorithms to be used
341  curveInfo = tls13GetTraditionalAlgo(context, namedGroup);
342  kemAlgo = tls13GetNextGenAlgo(context, namedGroup);
343 
344  //Valid algorithms?
345  if(curveInfo != NULL && kemAlgo != NULL)
346  {
347  //Save the named group
348  context->namedGroup = namedGroup;
349 
350  //Load EC domain parameters
351  error = ecLoadDomainParameters(&context->ecdhContext.params, curveInfo);
352 
353  //Check status code
354  if(!error)
355  {
356  //DH key exchange can be modeled as a KEM, with KeyGen corresponding
357  //to selecting an exponent x as the secret key and computing the
358  //public key g^x
359  error = ecdhGenerateKeyPair(&context->ecdhContext, context->prngAlgo,
360  context->prngContext);
361  }
362 
363  //Check status code
364  if(!error)
365  {
366  //Initialize KEM context
367  kemFree(&context->kemContext);
368  kemInit(&context->kemContext, kemAlgo);
369 
370  //Generate a public key pk and a secret key sk
371  error = kemGenerateKeyPair(&context->kemContext, context->prngAlgo,
372  context->prngContext);
373  }
374  }
375  else
376  {
377  //Unsupported hybrid key exchange method
378  error = ERROR_ILLEGAL_PARAMETER;
379  }
380  }
381  else
382 #endif
383  //Unknown group?
384  {
385  //Report an error
386  error = ERROR_ILLEGAL_PARAMETER;
387  }
388 
389  //Return status code
390  return error;
391 }
392 
393 
394 /**
395  * @brief (EC)DHE shared secret generation
396  * @param[in] context Pointer to the TLS context
397  * @param[in] keyShare Pointer to the peer's (EC)DHE parameters
398  * @param[in] length Length of the (EC)DHE parameters, in bytes
399  * @return Error code
400  **/
401 
402 error_t tls13GenerateSharedSecret(TlsContext *context, const uint8_t *keyShare,
403  size_t length)
404 {
405  error_t error;
406 
407 #if (TLS13_DHE_KE_SUPPORT == ENABLED || TLS13_PSK_DHE_KE_SUPPORT == ENABLED)
408  //Finite field group?
409  if(tls13IsFfdheGroupSupported(context, context->namedGroup))
410  {
411  size_t n;
412 
413  //Retrieve the length of the modulus
414  n = mpiGetByteLength(&context->dhContext.params.p);
415 
416  //For a given Diffie-Hellman group, the padding results in all public
417  //keys having the same length (refer to RFC 8446, section 4.2.8.1)
418  if(length == n)
419  {
420  //The Diffie-Hellman public value is encoded as a big-endian integer
421  error = mpiImport(&context->dhContext.yb, keyShare, length,
423 
424  //Check status code
425  if(!error)
426  {
427  //Verify peer's public key
428  error = dhCheckPublicKey(&context->dhContext.params,
429  &context->dhContext.yb);
430  }
431 
432  //Check status code
433  if(!error)
434  {
435  //The negotiated key (Z) is converted to a byte string by encoding
436  //in big-endian and left padded with zeros up to the size of the
437  //prime (refer to RFC 8446, section 7.4.1)
438  error = dhComputeSharedSecret(&context->dhContext,
439  context->premasterSecret, TLS_PREMASTER_SECRET_SIZE,
440  &context->premasterSecretLen);
441  }
442  }
443  else
444  {
445  //The length of the public key is not valid
446  error = ERROR_ILLEGAL_PARAMETER;
447  }
448  }
449  else
450 #endif
451 #if (TLS13_ECDHE_KE_SUPPORT == ENABLED || TLS13_PSK_ECDHE_KE_SUPPORT == ENABLED)
452  //Elliptic curve group?
453  if(tls13IsEcdheGroupSupported(context, context->namedGroup))
454  {
455  //Read peer's public key (refer to RFC 8446, section 4.2.8.2)
456  error = ecImport(&context->ecdhContext.params,
457  &context->ecdhContext.qb.q, keyShare, length);
458 
459  //Check status code
460  if(!error)
461  {
462  //Verify peer's public key
463  error = ecdhCheckPublicKey(&context->ecdhContext.params,
464  &context->ecdhContext.qb.q);
465  }
466 
467  //Check status code
468  if(!error)
469  {
470  //ECDH shared secret calculation is performed according to IEEE Std
471  //1363-2000 (refer to RFC 8446, section 7.4.2)
472  error = ecdhComputeSharedSecret(&context->ecdhContext,
473  context->premasterSecret, TLS_PREMASTER_SECRET_SIZE,
474  &context->premasterSecretLen);
475  }
476  }
477  else
478 #endif
479  //Unknown group?
480  {
481  //Report an error
482  error = ERROR_HANDSHAKE_FAILED;
483  }
484 
485  //Return status code
486  return error;
487 }
488 
489 
490 /**
491  * @brief Encapsulation algorithm
492  * @param[in] context Pointer to the TLS context
493  * @param[in] keyShare Pointer to the client's key share
494  * @param[in] length Length of the client's key share, in bytes
495  * @return Error code
496  **/
497 
498 error_t tls13Encapsulate(TlsContext *context, uint16_t namedGroup,
499  const uint8_t *keyShare, size_t length)
500 {
501 #if (TLS13_HYBRID_KE_SUPPORT == ENABLED || TLS13_PSK_HYBRID_KE_SUPPORT == ENABLED)
502  error_t error;
503  const EcCurveInfo *curveInfo;
504  const KemAlgo *kemAlgo;
505 
506  //Retrieve the traditional and the next-gen algorithms to be used
507  curveInfo = tls13GetTraditionalAlgo(context, namedGroup);
508  kemAlgo = tls13GetNextGenAlgo(context, namedGroup);
509 
510  //Valid algorithms?
511  if(curveInfo != NULL && kemAlgo != NULL)
512  {
513  //The client's share is a fixed-size concatenation of the ECDH ephemeral
514  //key share and the pk outputs of the KEM KeyGen algorithm
515  if(length > kemAlgo->publicKeySize)
516  {
517  //Save the named group
518  context->namedGroup = namedGroup;
519 
520  //Initialize KEM context
521  kemFree(&context->kemContext);
522  kemInit(&context->kemContext, kemAlgo);
523 
524  //Load EC domain parameters
525  error = ecLoadDomainParameters(&context->ecdhContext.params,
526  curveInfo);
527 
528  //Check status code
529  if(!error)
530  {
531  //DH key exchange can be modeled as a KEM, with encapsulation
532  //corresponding to selecting an exponent y, computing the ciphertext
533  //g^y and the shared secret g^(xy)
534  error = ecdhGenerateKeyPair(&context->ecdhContext,
535  context->prngAlgo, context->prngContext);
536  }
537 
538  //Check status code
539  if(!error)
540  {
541  //The ECDHE share is the serialized value of the uncompressed ECDH
542  //point representation
543  error = ecImport(&context->ecdhContext.params,
544  &context->ecdhContext.qb.q, keyShare,
545  length - kemAlgo->publicKeySize);
546  }
547 
548  //Check status code
549  if(!error)
550  {
551  //Verify client's public key
552  error = ecdhCheckPublicKey(&context->ecdhContext.params,
553  &context->ecdhContext.qb.q);
554  }
555 
556  //Check status code
557  if(!error)
558  {
559  //Compute the shared secret g^(xy)
560  error = ecdhComputeSharedSecret(&context->ecdhContext,
561  context->premasterSecret, TLS_PREMASTER_SECRET_SIZE,
562  &context->premasterSecretLen);
563  }
564 
565  //Check status code
566  if(!error)
567  {
568  //The encapsulation algorithm takes as input a public key pk and
569  //outputs a ciphertext ct and shared secret ss
570  error = kemLoadPublicKey(&context->kemContext,
571  keyShare + length - kemAlgo->publicKeySize);
572  }
573  }
574  else
575  {
576  //The length of the key share is not valid
577  error = ERROR_ILLEGAL_PARAMETER;
578  }
579  }
580  else
581  {
582  //Unsupported hybrid key exchange method
583  error = ERROR_ILLEGAL_PARAMETER;
584  }
585 
586  //Return status code
587  return error;
588 #else
589  //Hybrid key exchange is not implemented
590  return ERROR_NOT_IMPLEMENTED;
591 #endif
592 }
593 
594 
595 /**
596  * @brief Decapsulation algorithm
597  * @param[in] context Pointer to the TLS context
598  * @param[in] keyShare Pointer to the server's key share
599  * @param[in] length Length of the client's key share, in bytes
600  * @return Error code
601  **/
602 
603 error_t tls13Decapsulate(TlsContext *context, const uint8_t *keyShare,
604  size_t length)
605 {
606 #if (TLS13_HYBRID_KE_SUPPORT == ENABLED || TLS13_PSK_HYBRID_KE_SUPPORT == ENABLED)
607  error_t error;
608  size_t n;
609 
610  //Get the length of the KEM ciphertext
611  n = context->kemContext.kemAlgo->ciphertextSize;
612 
613  //The server's share is a fixed-size concatenation of the ECDH ephemeral
614  //key share and the ct outputs of the KEM Encaps algorithm
615  if(length > n)
616  {
617  //The ECDHE share is the serialized value of the uncompressed ECDH point
618  //representation
619  error = ecImport(&context->ecdhContext.params, &context->ecdhContext.qb.q,
620  keyShare, length - n);
621 
622  //Check status code
623  if(!error)
624  {
625  //Verify server's public key
626  error = ecdhCheckPublicKey(&context->ecdhContext.params,
627  &context->ecdhContext.qb.q);
628  }
629 
630  //Check status code
631  if(!error)
632  {
633  //DH key exchange can be modeled as a KEM, with decapsulation
634  //corresponding to computing the shared secret g^(xy)
635  error = ecdhComputeSharedSecret(&context->ecdhContext,
636  context->premasterSecret, TLS_PREMASTER_SECRET_SIZE,
637  &context->premasterSecretLen);
638  }
639 
640  //Check status code
641  if(!error)
642  {
643  //The decapsulation algorithm takes as input a secret key sk and
644  //ciphertext ct and outputs a shared secret ss
645  error = kemDecapsulate(&context->kemContext, keyShare + length - n,
646  context->premasterSecret + context->premasterSecretLen);
647  }
648 
649  //Check status code
650  if(!error)
651  {
652  //The two shared secrets are concatenated together and used as the
653  //shared secret in the existing TLS 1.3 key schedule
654  context->premasterSecretLen += context->kemContext.kemAlgo->sharedSecretSize;
655  }
656  }
657  else
658  {
659  //The length of the key share is not valid
660  error = ERROR_ILLEGAL_PARAMETER;
661  }
662 
663  //Return status code
664  return error;
665 #else
666  //Hybrid key exchange is not implemented
667  return ERROR_NOT_IMPLEMENTED;
668 #endif
669 }
670 
671 
672 /**
673  * @brief Compute message authentication code
674  * @param[in] context Pointer to the TLS context
675  * @param[in] encryptionEngine Pointer to the encryption/decryption engine
676  * @param[in] record Pointer to the TLS record
677  * @param[in] data Pointer to the record data
678  * @param[in] dataLen Length of the data
679  * @param[out] mac The computed MAC value
680  * @return Error code
681  **/
682 
684  void *record, const uint8_t *data, size_t dataLen, uint8_t *mac)
685 {
686  size_t aadLen;
687  size_t nonceLen;
688  uint8_t aad[13];
689  uint8_t nonce[12];
690  HmacContext *hmacContext;
691 
692  //Point to the HMAC context
693  hmacContext = encryptionEngine->hmacContext;
694 
695  //Initialize HMAC calculation
696  hmacInit(hmacContext, encryptionEngine->hashAlgo,
697  encryptionEngine->encKey, encryptionEngine->encKeyLen);
698 
699  //Additional data to be authenticated
700  tlsFormatAad(context, encryptionEngine, record, aad, &aadLen);
701 
702  //Generate the nonce
703  tlsFormatNonce(context, encryptionEngine, record, data, nonce,
704  &nonceLen);
705 
706  //Compute HMAC(write_key, nonce || additional_data || plaintext)
707  hmacUpdate(hmacContext, nonce, nonceLen);
708  hmacUpdate(hmacContext, aad, aadLen);
709  hmacUpdate(hmacContext, data, dataLen);
710 
711  //Finalize HMAC computation
712  hmacFinal(hmacContext, mac);
713 
714  //Successful processing
715  return NO_ERROR;
716 }
717 
718 
719 /**
720  * @brief Hash ClientHello1 in the transcript when HelloRetryRequest is used
721  * @param[in] context Pointer to the TLS context
722  * @return Error code
723  **/
724 
726 {
728  const HashAlgo *hash;
729 
730  //Invalid hash context?
731  if(context->transcriptHashContext == NULL)
732  return ERROR_FAILURE;
733 
734  //The hash function used by HKDF is the cipher suite hash algorithm
735  hash = context->cipherSuite.prfHashAlgo;
736  //Make sure the hash algorithm is valid
737  if(hash == NULL)
738  return ERROR_FAILURE;
739 
740  //Point to the buffer where to format the handshake message
741  message = (TlsHandshake *) context->txBuffer;
742 
743  //Handshake message type
744  message->msgType = TLS_TYPE_MESSAGE_HASH;
745  //Number of bytes in the message
746  STORE24BE(hash->digestSize, message->length);
747 
748  //Compute Hash(ClientHello1)
749  hash->final(context->transcriptHashContext, message->data);
750  //Re-initialize hash algorithm context
751  hash->init(context->transcriptHashContext);
752 
753  //When the server responds to a ClientHello with a HelloRetryRequest, the
754  //value of ClientHello1 is replaced with a special synthetic handshake
755  //message of handshake type MessageHash containing Hash(ClientHello1)
756  hash->update(context->transcriptHashContext, message,
757  hash->digestSize + sizeof(TlsHandshake));
758 
759  //Successful processing
760  return NO_ERROR;
761 }
762 
763 
764 /**
765  * @brief Check whether an externally established PSK is valid
766  * @param[in] context Pointer to the TLS context
767  * @return TRUE is the PSK is valid, else FALSE
768  **/
769 
771 {
772  bool_t valid = FALSE;
773 
774  //Make sure the hash algorithm associated with the PSK is valid
775  if(tlsGetHashAlgo(context->pskHashAlgo) != NULL)
776  {
777  //Valid PSK?
778  if(context->psk != NULL && context->pskLen > 0)
779  {
780  //Check whether TLS operates as a client or a server
781  if(context->entity == TLS_CONNECTION_END_CLIENT)
782  {
783  //Valid PSK identity?
784  if(context->pskIdentity != NULL)
785  {
786  valid = TRUE;
787  }
788  }
789  else
790  {
791  valid = TRUE;
792  }
793  }
794  }
795 
796  //Return TRUE is the PSK is valid, else FALSE
797  return valid;
798 }
799 
800 
801 /**
802  * @brief Check whether a given named group is supported
803  * @param[in] context Pointer to the TLS context
804  * @param[in] namedGroup Named group
805  * @return TRUE is the named group is supported, else FALSE
806  **/
807 
808 bool_t tls13IsGroupSupported(TlsContext *context, uint16_t namedGroup)
809 {
810  bool_t acceptable;
811 
812  //Initialize flag
813  acceptable = FALSE;
814 
815  //Check whether the specified named group is supported
816  if(tls13IsFfdheGroupSupported(context, namedGroup))
817  {
818  acceptable = TRUE;
819  }
820  else if(tls13IsEcdheGroupSupported(context, namedGroup))
821  {
822  acceptable = TRUE;
823  }
824  else if(tls13IsHybridKeMethodSupported(context, namedGroup))
825  {
826  acceptable = TRUE;
827  }
828  else
829  {
830  acceptable = FALSE;
831  }
832 
833  //Return TRUE is the named group is supported
834  return acceptable;
835 }
836 
837 
838 /**
839  * @brief Check whether a given FFDHE group is supported
840  * @param[in] context Pointer to the TLS context
841  * @param[in] namedGroup Named group
842  * @return TRUE is the FFDHE group is supported, else FALSE
843  **/
844 
845 bool_t tls13IsFfdheGroupSupported(TlsContext *context, uint16_t namedGroup)
846 {
847  bool_t acceptable;
848 
849  //Initialize flag
850  acceptable = FALSE;
851 
852 #if ((TLS13_DHE_KE_SUPPORT == ENABLED || TLS13_PSK_DHE_KE_SUPPORT == ENABLED) && \
853  TLS_FFDHE_SUPPORT == ENABLED)
854  //Finite field group?
855  if(namedGroup == TLS_GROUP_FFDHE2048 ||
856  namedGroup == TLS_GROUP_FFDHE3072 ||
857  namedGroup == TLS_GROUP_FFDHE4096 ||
858  namedGroup == TLS_GROUP_FFDHE6144 ||
859  namedGroup == TLS_GROUP_FFDHE8192)
860  {
861  //Any TLS 1.3 cipher suite proposed by the client?
862  if((context->cipherSuiteTypes & TLS_CIPHER_SUITE_TYPE_TLS13) != 0)
863  {
864  //Check whether the FFDHE group is supported
865  if(tlsGetFfdheGroup(context, namedGroup) != NULL)
866  {
867  acceptable = TRUE;
868  }
869  }
870  }
871 #endif
872 
873  //Return TRUE is the named group is supported
874  return acceptable;
875 }
876 
877 
878 /**
879  * @brief Check whether a given ECDHE group is supported
880  * @param[in] context Pointer to the TLS context
881  * @param[in] namedGroup Named group
882  * @return TRUE is the ECDHE group is supported, else FALSE
883  **/
884 
885 bool_t tls13IsEcdheGroupSupported(TlsContext *context, uint16_t namedGroup)
886 {
887  bool_t acceptable;
888 
889  //Initialize flag
890  acceptable = FALSE;
891 
892 #if (TLS13_ECDHE_KE_SUPPORT == ENABLED || TLS13_PSK_ECDHE_KE_SUPPORT == ENABLED)
893  //Elliptic curve group?
894  if(namedGroup == TLS_GROUP_SECP256R1 ||
895  namedGroup == TLS_GROUP_SECP384R1 ||
896  namedGroup == TLS_GROUP_SECP521R1 ||
897  namedGroup == TLS_GROUP_X25519 ||
898  namedGroup == TLS_GROUP_X448 ||
899  namedGroup == TLS_GROUP_BRAINPOOLP256R1_TLS13 ||
900  namedGroup == TLS_GROUP_BRAINPOOLP384R1_TLS13 ||
901  namedGroup == TLS_GROUP_BRAINPOOLP512R1_TLS13)
902  {
903  //Any TLS 1.3 cipher suite proposed by the client?
904  if((context->cipherSuiteTypes & TLS_CIPHER_SUITE_TYPE_TLS13) != 0)
905  {
906  //Check whether the ECDHE group is supported
907  if(tlsGetCurveInfo(context, namedGroup) != NULL)
908  {
909  acceptable = TRUE;
910  }
911  }
912  }
913  else if(namedGroup == TLS_GROUP_CURVE_SM2)
914  {
915  //Any ShangMi cipher suite proposed by the client?
916  if((context->cipherSuiteTypes & TLS_CIPHER_SUITE_TYPE_SM) != 0)
917  {
918  //Check whether the SM2 group is supported
919  if(tlsGetCurveInfo(context, namedGroup) != NULL)
920  {
921  acceptable = TRUE;
922  }
923  }
924  }
925  else
926  {
927  //Unknown group
928  }
929 #endif
930 
931  //Return TRUE is the named group is supported
932  return acceptable;
933 }
934 
935 
936 /**
937  * @brief Check whether a given hybrid key exchange method is supported
938  * @param[in] context Pointer to the TLS context
939  * @param[in] namedGroup Named group
940  * @return TRUE is the hybrid key exchange is supported, else FALSE
941  **/
942 
943 bool_t tls13IsHybridKeMethodSupported(TlsContext *context, uint16_t namedGroup)
944 {
945  bool_t acceptable;
946 
947  //Initialize flag
948  acceptable = FALSE;
949 
950 #if (TLS13_HYBRID_KE_SUPPORT == ENABLED || TLS13_PSK_HYBRID_KE_SUPPORT == ENABLED)
951  //Hybrid key exchange method?
952  if(namedGroup == TLS_GROUP_X25519_KYBER768_DRAFT00 ||
954  {
955  //Any TLS 1.3 cipher suite proposed by the client?
956  if((context->cipherSuiteTypes & TLS_CIPHER_SUITE_TYPE_TLS13) != 0)
957  {
958  //Check whether the hybrid key exchange method is supported
959  if(tls13GetTraditionalAlgo(context, namedGroup) != NULL &&
960  tls13GetNextGenAlgo(context, namedGroup) != NULL)
961  {
962  acceptable = TRUE;
963  }
964  }
965  }
966  else
967  {
968  //Unknown group
969  }
970 #endif
971 
972  //Return TRUE is the named group is supported
973  return acceptable;
974 }
975 
976 
977 /**
978  * @brief Get the traditional algorithm used by the hybrid key exchange method
979  * @param[in] context Pointer to the TLS context
980  * @param[in] namedGroup Hybrid key exchange method
981  * @return Traditional algorithm
982  **/
983 
985  uint16_t namedGroup)
986 {
987  const EcCurveInfo *curveInfo;
988 
989  //Default elliptic curve domain parameters
990  curveInfo = NULL;
991 
992 #if (TLS13_HYBRID_KE_SUPPORT == ENABLED || TLS13_PSK_HYBRID_KE_SUPPORT == ENABLED)
993  //Check hybrid key exchange method
994  switch(namedGroup)
995  {
996 #if (TLS_SECP256R1_SUPPORT == ENABLED)
997  //secp256r1 elliptic curve?
999  curveInfo = ecGetCurveInfo(SECP256R1_OID, sizeof(SECP256R1_OID));
1000  break;
1001 #endif
1002 #if (TLS_X25519_SUPPORT == ENABLED)
1003  //Curve25519 elliptic curve?
1005  curveInfo = ecGetCurveInfo(X25519_OID, sizeof(X25519_OID));
1006  break;
1007 #endif
1008  //Unknown group?
1009  default:
1010  curveInfo = NULL;
1011  break;
1012  }
1013 
1014  //Restrict the use of certain algorithms
1015  if(context->numSupportedGroups > 0)
1016  {
1017  uint_t i;
1018 
1019  //Loop through the list of allowed named groups
1020  for(i = 0; i < context->numSupportedGroups; i++)
1021  {
1022  //Compare named groups
1023  if(context->supportedGroups[i] == namedGroup)
1024  break;
1025  }
1026 
1027  //Check whether the use of the algorithm is restricted
1028  if(i >= context->numSupportedGroups)
1029  {
1030  curveInfo = NULL;
1031  }
1032  }
1033 #endif
1034 
1035  //Return elliptic curve domain parameters, if any
1036  return curveInfo;
1037 }
1038 
1039 
1040 /**
1041  * @brief Get the next-gen algorithm used by the hybrid key exchange method
1042  * @param[in] context Pointer to the TLS context
1043  * @param[in] namedGroup Hybrid key exchange method
1044  * @return Next-gen algorithm
1045  **/
1046 
1048  uint16_t namedGroup)
1049 {
1050  const KemAlgo *kemAlgo;
1051 
1052  //Default KEM algorithm
1053  kemAlgo = NULL;
1054 
1055 #if (TLS13_HYBRID_KE_SUPPORT == ENABLED || TLS13_PSK_HYBRID_KE_SUPPORT == ENABLED)
1056  //Check hybrid key exchange method
1057  switch(namedGroup)
1058  {
1059 #if (TLS_MLKEM768_SUPPORT == ENABLED)
1060  //ML-KEM-768 key encapsulation mechanism?
1063  kemAlgo = MLKEM768_KEM_ALGO;
1064  break;
1065 #endif
1066  //Unknown group?
1067  default:
1068  kemAlgo = NULL;
1069  break;
1070  }
1071 
1072  //Restrict the use of certain algorithms
1073  if(context->numSupportedGroups > 0)
1074  {
1075  uint_t i;
1076 
1077  //Loop through the list of allowed named groups
1078  for(i = 0; i < context->numSupportedGroups; i++)
1079  {
1080  //Compare named groups
1081  if(context->supportedGroups[i] == namedGroup)
1082  break;
1083  }
1084 
1085  //Check whether the use of the algorithm is restricted
1086  if(i >= context->numSupportedGroups)
1087  {
1088  kemAlgo = NULL;
1089  }
1090  }
1091 #endif
1092 
1093  //Return KEM algorithm, if any
1094  return kemAlgo;
1095 }
1096 
1097 
1098 /**
1099  * @brief Check whether the specified key share group is a duplicate
1100  * @param[in] namedGroup Named group
1101  * @param[in] p List of key share entries
1102  * @param[in] length Length of the list, in bytes
1103  * @return Error code
1104  **/
1105 
1106 error_t tls13CheckDuplicateKeyShare(uint16_t namedGroup, const uint8_t *p,
1107  size_t length)
1108 {
1109  size_t n;
1110  const Tls13KeyShareEntry *keyShareEntry;
1111 
1112  //Parse the list of key share entries offered by the peer
1113  while(length > 0)
1114  {
1115  //Malformed extension?
1116  if(length < sizeof(Tls13KeyShareEntry))
1117  return ERROR_DECODING_FAILED;
1118 
1119  //Point to the current key share entry
1120  keyShareEntry = (Tls13KeyShareEntry *) p;
1121  //Retrieve the length of the key_exchange field
1122  n = ntohs(keyShareEntry->length);
1123 
1124  //Malformed extension?
1125  if(length < (sizeof(Tls13KeyShareEntry) + n))
1126  return ERROR_DECODING_FAILED;
1127 
1128  //Clients must not offer multiple KeyShareEntry values for the same
1129  //group. Servers may check for violations of this rule and abort the
1130  //handshake with an illegal_parameter alert
1131  if(ntohs(keyShareEntry->group) == namedGroup)
1132  return ERROR_ILLEGAL_PARAMETER;
1133 
1134  //Jump to the next key share entry
1135  p += sizeof(Tls13KeyShareEntry) + n;
1136  //Number of bytes left to process
1137  length -= sizeof(Tls13KeyShareEntry) + n;
1138  }
1139 
1140  //Successful verification
1141  return NO_ERROR;
1142 }
1143 
1144 
1145 /**
1146  * @brief Format certificate extensions
1147  * @param[in] p Output stream where to write the list of extensions
1148  * @param[out] written Total number of bytes that have been written
1149  * @return Error code
1150  **/
1151 
1152 error_t tls13FormatCertExtensions(uint8_t *p, size_t *written)
1153 {
1154  TlsExtensionList *extensionList;
1155 
1156  //Point to the list of extensions
1157  extensionList = (TlsExtensionList *) p;
1158 
1159  //Extensions in the Certificate message from the server must correspond to
1160  //ones from the ClientHello message. Extensions in the Certificate message
1161  //from the client must correspond to extensions in the CertificateRequest
1162  //message from the server
1163  extensionList->length = HTONS(0);
1164 
1165  //Total number of bytes that have been written
1166  *written = sizeof(TlsExtensionList);
1167 
1168  //Successful processing
1169  return NO_ERROR;
1170 }
1171 
1172 
1173 /**
1174  * @brief Parse certificate extensions
1175  * @param[in] p Input stream where to read the list of extensions
1176  * @param[in] length Number of bytes available in the input stream
1177  * @param[out] consumed Total number of bytes that have been consumed
1178  * @return Error code
1179  **/
1180 
1181 error_t tls13ParseCertExtensions(const uint8_t *p, size_t length,
1182  size_t *consumed)
1183 {
1184  error_t error;
1185  size_t n;
1187  const TlsExtensionList *extensionList;
1188 
1189  //Point to the list of extensions
1190  extensionList = (TlsExtensionList *) p;
1191 
1192  //Malformed CertificateEntry?
1193  if(length < sizeof(TlsExtensionList))
1194  return ERROR_DECODING_FAILED;
1195 
1196  //Retrieve the length of the list
1197  n = sizeof(TlsExtensionList) + ntohs(extensionList->length);
1198 
1199  //Malformed CertificateEntry?
1200  if(length < n)
1201  return ERROR_DECODING_FAILED;
1202 
1203  //Parse the list of extensions for the current CertificateEntry
1205  &extensions);
1206  //Any error to report?
1207  if(error)
1208  return error;
1209 
1210  //Check the list of extensions
1212  &extensions);
1213  //Any error to report?
1214  if(error)
1215  return error;
1216 
1217  //Total number of bytes that have been consumed
1218  *consumed = n;
1219 
1220  //Successful processing
1221  return NO_ERROR;
1222 }
1223 
1224 #endif
@ TLS_GROUP_BRAINPOOLP512R1_TLS13
Definition: tls.h:1403
#define tlsAllocMem(size)
Definition: tls.h:853
@ TLS_TYPE_MESSAGE_HASH
Definition: tls.h:1063
#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:1056
@ TLS_GROUP_SECP256R1_KYBER768_DRAFT00
Definition: tls.h:1419
uint8_t extensions[]
Definition: ntp_common.h:207
@ TLS_GROUP_BRAINPOOLP256R1_TLS13
Definition: tls.h:1401
int bool_t
Definition: compiler_port.h:53
HMAC algorithm context.
Definition: hmac.h:59
TLS cipher suites.
const EcCurveInfo * ecGetCurveInfo(const uint8_t *oid, size_t length)
Get the elliptic curve that matches the specified OID.
Definition: ec_curves.c:2422
const HashAlgo * tlsGetHashAlgo(TlsHashAlgo hashAlgoId)
Get the hash algorithm that matches the specified identifier.
Definition: tls_misc.c:1173
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:96
@ ERROR_NOT_IMPLEMENTED
Definition: error.h:66
@ ERROR_ILLEGAL_PARAMETER
Definition: error.h:243
error_t ecImport(const EcDomainParameters *params, EcPoint *r, const uint8_t *data, size_t length)
Convert an octet string to an EC point.
Definition: ec.c:365
uint8_t p
Definition: ndp.h:300
uint8_t message[]
Definition: chap.h:154
error_t dhCheckPublicKey(DhParameters *params, const Mpi *publicKey)
Check Diffie-Hellman public value.
Definition: dh.c:183
#define TRUE
Definition: os_port.h:50
uint8_t data[]
Definition: ethernet.h:222
@ TLS_GROUP_SECP256R1
Definition: tls.h:1393
@ TLS_GROUP_CURVE_SM2
Definition: tls.h:1411
size_t digestSize
Definition: crypto.h:1052
TLS 1.3 session tickets.
@ TLS_TRANSPORT_PROTOCOL_DATAGRAM
Definition: tls.h:957
HashAlgoUpdate update
Definition: crypto.h:1057
void kemInit(KemContext *context, const KemAlgo *kemAlgo)
Initialize KEM context.
Definition: kem.c:48
@ ERROR_HANDSHAKE_FAILED
Definition: error.h:233
@ 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
size_t publicKeySize
Definition: crypto.h:1089
Tls13KeyShareEntry
Definition: tls13_misc.h:195
error_t mpiImport(Mpi *r, const uint8_t *data, uint_t length, MpiFormat format)
Octet string to integer conversion.
Definition: mpi.c:624
void kemFree(KemContext *context)
Release KEM context.
Definition: kem.c:62
const uint8_t SECP256R1_OID[8]
Definition: ec_curves.c:72
@ TLS_GROUP_X448
Definition: tls.h:1400
@ TLS_CIPHER_SUITE_TYPE_TLS13
const EcCurveInfo * tls13GetTraditionalAlgo(TlsContext *context, uint16_t namedGroup)
Get the traditional algorithm used by the hybrid key exchange method.
Definition: tls13_misc.c:984
@ TLS_GROUP_FFDHE6144
Definition: tls.h:1415
bool_t tls13IsHybridKeMethodSupported(TlsContext *context, uint16_t namedGroup)
Check whether a given hybrid key exchange method is supported.
Definition: tls13_misc.c:943
size_t contextSize
Definition: crypto.h:1050
error_t tls13ParseCertExtensions(const uint8_t *p, size_t length, size_t *consumed)
Parse certificate extensions.
Definition: tls13_misc.c:1181
@ TLS_CIPHER_SUITE_TYPE_SM
TLS 1.3 helper functions.
@ TLS_TYPE_CERTIFICATE
Definition: tls.h:1050
TlsExtensionList
Definition: tls.h:1584
error_t ecLoadDomainParameters(EcDomainParameters *params, const EcCurveInfo *curveInfo)
Load EC domain parameters.
Definition: ec.c:90
TlsHandshake
Definition: tls.h:1754
#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:223
Elliptic curve parameters.
Definition: ec_curves.h:302
@ ERROR_INVALID_PARAMETER
Invalid parameter.
Definition: error.h:47
#define osMemcpy(dest, src, length)
Definition: os_port.h:141
#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:808
#define TLS_PREMASTER_SECRET_SIZE
Definition: tls.h:808
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:885
const KemAlgo * tls13GetNextGenAlgo(TlsContext *context, uint16_t namedGroup)
Get the next-gen algorithm used by the hybrid key exchange method.
Definition: tls13_misc.c:1047
@ 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:683
error_t tls13Decapsulate(TlsContext *context, const uint8_t *keyShare, size_t length)
Decapsulation algorithm.
Definition: tls13_misc.c:603
@ TLS_GROUP_FFDHE4096
Definition: tls.h:1414
@ TLS_TYPE_CLIENT_HELLO
Definition: tls.h:1041
#define TLS_VERSION_1_3
Definition: tls.h:97
@ ERROR_INVALID_LENGTH
Definition: error.h:111
@ TLS_GROUP_SECP384R1
Definition: tls.h:1394
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:845
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
uint8_t length
Definition: tcp.h:368
@ TLS_GROUP_FFDHE2048
Definition: tls.h:1412
error_t tls13FormatCertExtensions(uint8_t *p, size_t *written)
Format certificate extensions.
Definition: tls13_misc.c:1152
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_SECP521R1
Definition: tls.h:1395
@ TLS_GROUP_FFDHE3072
Definition: tls.h:1413
Hello extensions.
Definition: tls.h:2098
@ TLS_GROUP_BRAINPOOLP384R1_TLS13
Definition: tls.h:1402
Transcript hash calculation.
error_t ecdhComputeSharedSecret(EcdhContext *context, uint8_t *output, size_t outputSize, size_t *outputLen)
Compute ECDH shared secret.
Definition: ecdh.c:340
HashAlgoFinal final
Definition: crypto.h:1058
#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:107
__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:108
error_t tls13GenerateSharedSecret(TlsContext *context, const uint8_t *keyShare, size_t length)
(EC)DHE shared secret generation
Definition: tls13_misc.c:402
bool_t tls13IsPskValid(TlsContext *context)
Check whether an externally established PSK is valid.
Definition: tls13_misc.c:770
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
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:921
Common interface for key encapsulation mechanisms (KEM)
Definition: crypto.h:1087
@ TLS_CONNECTION_END_CLIENT
Definition: tls.h:968
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
const EcCurveInfo * tlsGetCurveInfo(TlsContext *context, uint16_t namedCurve)
Get the EC domain parameters that match the specified named curve.
Definition: tls_misc.c:1240
@ MPI_FORMAT_BIG_ENDIAN
Definition: mpi.h:71
TLS (Transport Layer Security)
#define STORE24BE(a, p)
Definition: cpu_endian.h:273
@ TLS_GROUP_X25519
Definition: tls.h:1399
error_t tlsCheckHelloExtensions(TlsMessageType msgType, uint16_t version, TlsHelloExtensions *extensions)
Check Hello extensions.
TLS 1.3 key schedule.
Common interface for hash algorithms.
Definition: crypto.h:1046
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
FFDHE key exchange.
error_t tls13Encapsulate(TlsContext *context, uint16_t namedGroup, const uint8_t *keyShare, size_t length)
Encapsulation algorithm.
Definition: tls13_misc.c:498
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:228
@ ERROR_DECODING_FAILED
Definition: error.h:241
unsigned int uint_t
Definition: compiler_port.h:50
@ TLS_GROUP_X25519_KYBER768_DRAFT00
Definition: tls.h:1418
#define tlsFreeMem(p)
Definition: tls.h:858
error_t tls13DigestClientHello1(TlsContext *context)
Hash ClientHello1 in the transcript when HelloRetryRequest is used.
Definition: tls13_misc.c:725
__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:1106
error_t ecdhCheckPublicKey(const EcDomainParameters *params, EcPoint *publicKey)
Check ECDH public key.
Definition: ecdh.c:227
#define TlsEncryptionEngine
Definition: tls.h:40
#define MLKEM768_KEM_ALGO
Definition: mlkem768.h:47
@ TLS_GROUP_FFDHE8192
Definition: tls.h:1416
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:85
uint_t mpiGetByteLength(const Mpi *a)
Get the actual length in bytes.
Definition: mpi.c:195