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.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 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  //Unknown group?
334  {
335  //Report an error
336  error = ERROR_ILLEGAL_PARAMETER;
337  }
338 
339  //Return status code
340  return error;
341 }
342 
343 
344 /**
345  * @brief (EC)DHE shared secret generation
346  * @param[in] context Pointer to the TLS context
347  * @param[in] keyShare Pointer to the peer's (EC)DHE parameters
348  * @param[in] length Length of the (EC)DHE parameters, in bytes
349  * @return Error code
350  **/
351 
352 error_t tls13GenerateSharedSecret(TlsContext *context, const uint8_t *keyShare,
353  size_t length)
354 {
355  error_t error;
356 
357 #if (TLS13_DHE_KE_SUPPORT == ENABLED || TLS13_PSK_DHE_KE_SUPPORT == ENABLED)
358  //Finite field group?
359  if(tls13IsFfdheGroupSupported(context, context->namedGroup))
360  {
361  size_t n;
362 
363  //Retrieve the length of the modulus
364  n = mpiGetByteLength(&context->dhContext.params.p);
365 
366  //For a given Diffie-Hellman group, the padding results in all public
367  //keys having the same length (refer to RFC 8446, section 4.2.8.1)
368  if(length == n)
369  {
370  //The Diffie-Hellman public value is encoded as a big-endian integer
371  error = mpiImport(&context->dhContext.yb, keyShare, length,
373 
374  //Check status code
375  if(!error)
376  {
377  //Verify peer's public key
378  error = dhCheckPublicKey(&context->dhContext.params,
379  &context->dhContext.yb);
380  }
381 
382  //Check status code
383  if(!error)
384  {
385  //The negotiated key (Z) is converted to a byte string by encoding
386  //in big-endian and left padded with zeros up to the size of the
387  //prime (refer to RFC 8446, section 7.4.1)
388  error = dhComputeSharedSecret(&context->dhContext,
389  context->premasterSecret, TLS_PREMASTER_SECRET_SIZE,
390  &context->premasterSecretLen);
391  }
392  }
393  else
394  {
395  //The length of the public key is not valid
396  error = ERROR_ILLEGAL_PARAMETER;
397  }
398  }
399  else
400 #endif
401 #if (TLS13_ECDHE_KE_SUPPORT == ENABLED || TLS13_PSK_ECDHE_KE_SUPPORT == ENABLED)
402  //Elliptic curve group?
403  if(tls13IsEcdheGroupSupported(context, context->namedGroup))
404  {
405  //Read peer's public key (refer to RFC 8446, section 4.2.8.2)
406  error = ecImport(&context->ecdhContext.params,
407  &context->ecdhContext.qb.q, keyShare, length);
408 
409  //Check status code
410  if(!error)
411  {
412  //Verify peer's public key
413  error = ecdhCheckPublicKey(&context->ecdhContext.params,
414  &context->ecdhContext.qb.q);
415  }
416 
417  //Check status code
418  if(!error)
419  {
420  //ECDH shared secret calculation is performed according to IEEE Std
421  //1363-2000 (refer to RFC 8446, section 7.4.2)
422  error = ecdhComputeSharedSecret(&context->ecdhContext,
423  context->premasterSecret, TLS_PREMASTER_SECRET_SIZE,
424  &context->premasterSecretLen);
425  }
426  }
427  else
428 #endif
429  //Unknown group?
430  {
431  //Report an error
432  error = ERROR_HANDSHAKE_FAILED;
433  }
434 
435  //Return status code
436  return error;
437 }
438 
439 
440 /**
441  * @brief Compute message authentication code
442  * @param[in] context Pointer to the TLS context
443  * @param[in] encryptionEngine Pointer to the encryption/decryption engine
444  * @param[in] record Pointer to the TLS record
445  * @param[in] data Pointer to the record data
446  * @param[in] dataLen Length of the data
447  * @param[out] mac The computed MAC value
448  * @return Error code
449  **/
450 
452  void *record, const uint8_t *data, size_t dataLen, uint8_t *mac)
453 {
454  size_t aadLen;
455  size_t nonceLen;
456  uint8_t aad[13];
457  uint8_t nonce[12];
458  HmacContext *hmacContext;
459 
460  //Point to the HMAC context
461  hmacContext = encryptionEngine->hmacContext;
462 
463  //Initialize HMAC calculation
464  hmacInit(hmacContext, encryptionEngine->hashAlgo,
465  encryptionEngine->encKey, encryptionEngine->encKeyLen);
466 
467  //Additional data to be authenticated
468  tlsFormatAad(context, encryptionEngine, record, aad, &aadLen);
469 
470  //Generate the nonce
471  tlsFormatNonce(context, encryptionEngine, record, data, nonce,
472  &nonceLen);
473 
474  //Compute HMAC(write_key, nonce || additional_data || plaintext)
475  hmacUpdate(hmacContext, nonce, nonceLen);
476  hmacUpdate(hmacContext, aad, aadLen);
477  hmacUpdate(hmacContext, data, dataLen);
478 
479  //Finalize HMAC computation
480  hmacFinal(hmacContext, mac);
481 
482  //Successful processing
483  return NO_ERROR;
484 }
485 
486 
487 /**
488  * @brief Hash ClientHello1 in the transcript when HelloRetryRequest is used
489  * @param[in] context Pointer to the TLS context
490  * @return Error code
491  **/
492 
494 {
496  const HashAlgo *hash;
497 
498  //Invalid hash context?
499  if(context->transcriptHashContext == NULL)
500  return ERROR_FAILURE;
501 
502  //The hash function used by HKDF is the cipher suite hash algorithm
503  hash = context->cipherSuite.prfHashAlgo;
504  //Make sure the hash algorithm is valid
505  if(hash == NULL)
506  return ERROR_FAILURE;
507 
508  //Point to the buffer where to format the handshake message
509  message = (TlsHandshake *) context->txBuffer;
510 
511  //Handshake message type
512  message->msgType = TLS_TYPE_MESSAGE_HASH;
513  //Number of bytes in the message
514  STORE24BE(hash->digestSize, message->length);
515 
516  //Compute Hash(ClientHello1)
517  hash->final(context->transcriptHashContext, message->data);
518  //Re-initialize hash algorithm context
519  hash->init(context->transcriptHashContext);
520 
521  //When the server responds to a ClientHello with a HelloRetryRequest, the
522  //value of ClientHello1 is replaced with a special synthetic handshake
523  //message of handshake type MessageHash containing Hash(ClientHello1)
524  hash->update(context->transcriptHashContext, message,
525  hash->digestSize + sizeof(TlsHandshake));
526 
527  //Successful processing
528  return NO_ERROR;
529 }
530 
531 
532 /**
533  * @brief Check whether an externally established PSK is valid
534  * @param[in] context Pointer to the TLS context
535  * @return TRUE is the PSK is valid, else FALSE
536  **/
537 
539 {
540  bool_t valid = FALSE;
541 
542  //Make sure the hash algorithm associated with the PSK is valid
543  if(tlsGetHashAlgo(context->pskHashAlgo) != NULL)
544  {
545  //Valid PSK?
546  if(context->psk != NULL && context->pskLen > 0)
547  {
548  //Check whether TLS operates as a client or a server
549  if(context->entity == TLS_CONNECTION_END_CLIENT)
550  {
551  //Valid PSK identity?
552  if(context->pskIdentity != NULL)
553  {
554  valid = TRUE;
555  }
556  }
557  else
558  {
559  valid = TRUE;
560  }
561  }
562  }
563 
564  //Return TRUE is the PSK is valid, else FALSE
565  return valid;
566 }
567 
568 
569 /**
570  * @brief Check whether a given named group is supported
571  * @param[in] context Pointer to the TLS context
572  * @param[in] namedGroup Named group
573  * @return TRUE is the named group is supported, else FALSE
574  **/
575 
576 bool_t tls13IsGroupSupported(TlsContext *context, uint16_t namedGroup)
577 {
578  bool_t acceptable;
579 
580  //Initialize flag
581  acceptable = FALSE;
582 
583  //Check whether the FFDHE or ECDHE group is supported
584  if(tls13IsFfdheGroupSupported(context, namedGroup))
585  {
586  acceptable = TRUE;
587  }
588  else if(tls13IsEcdheGroupSupported(context, namedGroup))
589  {
590  acceptable = TRUE;
591  }
592  else
593  {
594  acceptable = FALSE;
595  }
596 
597  //Return TRUE is the named group is supported
598  return acceptable;
599 }
600 
601 
602 /**
603  * @brief Check whether a given FFDHE group is supported
604  * @param[in] context Pointer to the TLS context
605  * @param[in] namedGroup Named group
606  * @return TRUE is the FFDHE group is supported, else FALSE
607  **/
608 
609 bool_t tls13IsFfdheGroupSupported(TlsContext *context, uint16_t namedGroup)
610 {
611  bool_t acceptable;
612 
613  //Initialize flag
614  acceptable = FALSE;
615 
616 #if ((TLS13_DHE_KE_SUPPORT == ENABLED || TLS13_PSK_DHE_KE_SUPPORT == ENABLED) && \
617  TLS_FFDHE_SUPPORT == ENABLED)
618  //Finite field group?
619  if(namedGroup == TLS_GROUP_FFDHE2048 ||
620  namedGroup == TLS_GROUP_FFDHE3072 ||
621  namedGroup == TLS_GROUP_FFDHE4096 ||
622  namedGroup == TLS_GROUP_FFDHE6144 ||
623  namedGroup == TLS_GROUP_FFDHE8192)
624  {
625  //Any TLS 1.3 cipher suite proposed by the client?
626  if((context->cipherSuiteTypes & TLS_CIPHER_SUITE_TYPE_TLS13) != 0)
627  {
628  //Check whether the FFDHE group is supported
629  if(tlsGetFfdheGroup(context, namedGroup) != NULL)
630  {
631  acceptable = TRUE;
632  }
633  }
634  }
635 #endif
636 
637  //Return TRUE is the named group is supported
638  return acceptable;
639 }
640 
641 
642 /**
643  * @brief Check whether a given ECDHE group is supported
644  * @param[in] context Pointer to the TLS context
645  * @param[in] namedGroup Named group
646  * @return TRUE is the ECDHE group is supported, else FALSE
647  **/
648 
649 bool_t tls13IsEcdheGroupSupported(TlsContext *context, uint16_t namedGroup)
650 {
651  bool_t acceptable;
652 
653  //Initialize flag
654  acceptable = FALSE;
655 
656 #if (TLS13_ECDHE_KE_SUPPORT == ENABLED || TLS13_PSK_ECDHE_KE_SUPPORT == ENABLED)
657  //Elliptic curve group?
658  if(namedGroup == TLS_GROUP_SECP256R1 ||
659  namedGroup == TLS_GROUP_SECP384R1 ||
660  namedGroup == TLS_GROUP_SECP521R1 ||
661  namedGroup == TLS_GROUP_ECDH_X25519 ||
662  namedGroup == TLS_GROUP_ECDH_X448 ||
663  namedGroup == TLS_GROUP_BRAINPOOLP256R1_TLS13 ||
664  namedGroup == TLS_GROUP_BRAINPOOLP384R1_TLS13 ||
665  namedGroup == TLS_GROUP_BRAINPOOLP512R1_TLS13)
666  {
667  //Any TLS 1.3 cipher suite proposed by the client?
668  if((context->cipherSuiteTypes & TLS_CIPHER_SUITE_TYPE_TLS13) != 0)
669  {
670  //Check whether the ECDHE group is supported
671  if(tlsGetCurveInfo(context, namedGroup) != NULL)
672  {
673  acceptable = TRUE;
674  }
675  }
676  }
677  else if(namedGroup == TLS_GROUP_SM2)
678  {
679  //Any ShangMi cipher suite proposed by the client?
680  if((context->cipherSuiteTypes & TLS_CIPHER_SUITE_TYPE_SM) != 0)
681  {
682  //Check whether the SM2 group is supported
683  if(tlsGetCurveInfo(context, namedGroup) != NULL)
684  {
685  acceptable = TRUE;
686  }
687  }
688  }
689  else
690  {
691  //Unknown group
692  }
693 #endif
694 
695  //Return TRUE is the named group is supported
696  return acceptable;
697 }
698 
699 
700 /**
701  * @brief Check whether the specified key share group is a duplicate
702  * @param[in] namedGroup Named group
703  * @param[in] p List of key share entries
704  * @param[in] length Length of the list, in bytes
705  * @return Error code
706  **/
707 
708 error_t tls13CheckDuplicateKeyShare(uint16_t namedGroup, const uint8_t *p,
709  size_t length)
710 {
711  size_t n;
712  const Tls13KeyShareEntry *keyShareEntry;
713 
714  //Parse the list of key share entries offered by the peer
715  while(length > 0)
716  {
717  //Malformed extension?
718  if(length < sizeof(Tls13KeyShareEntry))
719  return ERROR_DECODING_FAILED;
720 
721  //Point to the current key share entry
722  keyShareEntry = (Tls13KeyShareEntry *) p;
723  //Retrieve the length of the key_exchange field
724  n = ntohs(keyShareEntry->length);
725 
726  //Malformed extension?
727  if(length < (sizeof(Tls13KeyShareEntry) + n))
728  return ERROR_DECODING_FAILED;
729 
730  //Clients must not offer multiple KeyShareEntry values for the same
731  //group. Servers may check for violations of this rule and abort the
732  //handshake with an illegal_parameter alert
733  if(ntohs(keyShareEntry->group) == namedGroup)
735 
736  //Jump to the next key share entry
737  p += sizeof(Tls13KeyShareEntry) + n;
738  //Number of bytes left to process
739  length -= sizeof(Tls13KeyShareEntry) + n;
740  }
741 
742  //Successful verification
743  return NO_ERROR;
744 }
745 
746 
747 /**
748  * @brief Format certificate extensions
749  * @param[in] p Output stream where to write the list of extensions
750  * @param[out] written Total number of bytes that have been written
751  * @return Error code
752  **/
753 
754 error_t tls13FormatCertExtensions(uint8_t *p, size_t *written)
755 {
756  TlsExtensionList *extensionList;
757 
758  //Point to the list of extensions
759  extensionList = (TlsExtensionList *) p;
760 
761  //Extensions in the Certificate message from the server must correspond to
762  //ones from the ClientHello message. Extensions in the Certificate message
763  //from the client must correspond to extensions in the CertificateRequest
764  //message from the server
765  extensionList->length = HTONS(0);
766 
767  //Total number of bytes that have been written
768  *written = sizeof(TlsExtensionList);
769 
770  //Successful processing
771  return NO_ERROR;
772 }
773 
774 
775 /**
776  * @brief Parse certificate extensions
777  * @param[in] p Input stream where to read the list of extensions
778  * @param[in] length Number of bytes available in the input stream
779  * @param[out] consumed Total number of bytes that have been consumed
780  * @return Error code
781  **/
782 
783 error_t tls13ParseCertExtensions(const uint8_t *p, size_t length,
784  size_t *consumed)
785 {
786  error_t error;
787  size_t n;
789  const TlsExtensionList *extensionList;
790 
791  //Point to the list of extensions
792  extensionList = (TlsExtensionList *) p;
793 
794  //Malformed CertificateEntry?
795  if(length < sizeof(TlsExtensionList))
796  return ERROR_DECODING_FAILED;
797 
798  //Retrieve the length of the list
799  n = sizeof(TlsExtensionList) + ntohs(extensionList->length);
800 
801  //Malformed CertificateEntry?
802  if(length < n)
803  return ERROR_DECODING_FAILED;
804 
805  //Parse the list of extensions for the current CertificateEntry
807  &extensions);
808  //Any error to report?
809  if(error)
810  return error;
811 
812  //Check the list of extensions
814  &extensions);
815  //Any error to report?
816  if(error)
817  return error;
818 
819  //Total number of bytes that have been consumed
820  *consumed = n;
821 
822  //Successful processing
823  return NO_ERROR;
824 }
825 
826 #endif
uint8_t message[]
Definition: chap.h:154
int bool_t
Definition: compiler_port.h:53
#define HTONS(value)
Definition: cpu_endian.h:410
#define htons(value)
Definition: cpu_endian.h:413
#define ntohs(value)
Definition: cpu_endian.h:421
#define STORE24BE(a, p)
Definition: cpu_endian.h:273
Debugging facilities.
#define TRACE_DEBUG_ARRAY(p, a, n)
Definition: debug.h:108
#define TRACE_DEBUG(...)
Definition: debug.h:107
error_t dhGenerateKeyPair(DhContext *context, const PrngAlgo *prngAlgo, void *prngContext)
Diffie-Hellman key pair generation.
Definition: dh.c:119
error_t dhComputeSharedSecret(DhContext *context, uint8_t *output, size_t outputSize, size_t *outputLen)
Compute Diffie-Hellman shared secret.
Definition: dh.c:223
error_t dhCheckPublicKey(DhParameters *params, const Mpi *publicKey)
Check Diffie-Hellman public value.
Definition: dh.c:183
uint8_t n
DtlsHandshake
Definition: dtls_misc.h:195
error_t ecLoadDomainParameters(EcDomainParameters *params, const EcCurveInfo *curveInfo)
Load EC domain parameters.
Definition: ec.c:90
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
error_t ecdhComputeSharedSecret(EcdhContext *context, uint8_t *output, size_t outputSize, size_t *outputLen)
Compute ECDH shared secret.
Definition: ecdh.c:340
error_t ecdhGenerateKeyPair(EcdhContext *context, const PrngAlgo *prngAlgo, void *prngContext)
ECDH key pair generation.
Definition: ecdh.c:85
error_t ecdhCheckPublicKey(const EcDomainParameters *params, EcPoint *publicKey)
Check ECDH public key.
Definition: ecdh.c:227
error_t
Error codes.
Definition: error.h:43
@ ERROR_ILLEGAL_PARAMETER
Definition: error.h:242
@ ERROR_HANDSHAKE_FAILED
Definition: error.h:232
@ ERROR_DECODING_FAILED
Definition: error.h:240
@ NO_ERROR
Success.
Definition: error.h:44
@ ERROR_OUT_OF_MEMORY
Definition: error.h:63
@ ERROR_INVALID_LENGTH
Definition: error.h:111
@ ERROR_FAILURE
Generic error code.
Definition: error.h:45
@ ERROR_INVALID_PARAMETER
Invalid parameter.
Definition: error.h:47
uint8_t data[]
Definition: ethernet.h:222
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
HKDF (HMAC-based Key Derivation Function)
__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
__weak_func error_t hmacInit(HmacContext *context, const HashAlgo *hash, const void *key, size_t keyLen)
Initialize HMAC calculation.
Definition: hmac.c:140
__weak_func void hmacFinal(HmacContext *context, uint8_t *digest)
Finish the HMAC calculation.
Definition: hmac.c:218
__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
error_t mpiImport(Mpi *r, const uint8_t *data, uint_t length, MpiFormat format)
Octet string to integer conversion.
Definition: mpi.c:624
uint_t mpiGetByteLength(const Mpi *a)
Get the actual length in bytes.
Definition: mpi.c:195
@ MPI_FORMAT_BIG_ENDIAN
Definition: mpi.h:71
uint8_t p
Definition: ndp.h:300
#define osMemcpy(dest, src, length)
Definition: os_port.h:141
#define TRUE
Definition: os_port.h:50
#define FALSE
Definition: os_port.h:46
uint32_t dataLen
Definition: sftp_common.h:229
Elliptic curve parameters.
Definition: ec_curves.h:295
Common interface for hash algorithms.
Definition: crypto.h:1014
HashAlgoFinal final
Definition: crypto.h:1026
size_t contextSize
Definition: crypto.h:1018
HashAlgoUpdate update
Definition: crypto.h:1025
size_t digestSize
Definition: crypto.h:1020
HashAlgoInit init
Definition: crypto.h:1024
HMAC algorithm context.
Definition: hmac.h:59
FFDHE parameters.
Definition: tls_ffdhe.h:49
Hello extensions.
Definition: tls.h:2081
uint8_t length
Definition: tcp.h:368
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.
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.
TLS 1.3 key schedule.
error_t tls13DigestClientHello1(TlsContext *context)
Hash ClientHello1 in the transcript when HelloRetryRequest is used.
Definition: tls13_misc.c:493
error_t tls13FormatCertExtensions(uint8_t *p, size_t *written)
Format certificate extensions.
Definition: tls13_misc.c:754
bool_t tls13IsEcdheGroupSupported(TlsContext *context, uint16_t namedGroup)
Check whether a given ECDHE group is supported.
Definition: tls13_misc.c:649
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:451
bool_t tls13IsFfdheGroupSupported(TlsContext *context, uint16_t namedGroup)
Check whether a given FFDHE group is supported.
Definition: tls13_misc.c:609
error_t tls13GenerateSharedSecret(TlsContext *context, const uint8_t *keyShare, size_t length)
(EC)DHE shared secret generation
Definition: tls13_misc.c:352
const uint8_t tls12DowngradeRandom[8]
Definition: tls13_misc.c:59
bool_t tls13IsPskValid(TlsContext *context)
Check whether an externally established PSK is valid.
Definition: tls13_misc.c:538
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
const uint8_t tls11DowngradeRandom[8]
Definition: tls13_misc.c:53
bool_t tls13IsGroupSupported(TlsContext *context, uint16_t namedGroup)
Check whether a given named group is supported.
Definition: tls13_misc.c:576
error_t tls13ParseCertExtensions(const uint8_t *p, size_t length, size_t *consumed)
Parse certificate extensions.
Definition: tls13_misc.c:783
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:708
error_t tls13GenerateKeyShare(TlsContext *context, uint16_t namedGroup)
Key share generation.
Definition: tls13_misc.c:260
const uint8_t tls13HelloRetryRequestRandom[32]
Definition: tls13_misc.c:65
TLS 1.3 helper functions.
Tls13KeyShareEntry
Definition: tls13_misc.h:181
uint8_t extensions[]
Definition: tls13_misc.h:300
Tls13PskIdentity
Definition: tls13_misc.h:214
bool_t tls13IsTicketValid(TlsContext *context)
Check whether a session ticket is valid.
Definition: tls13_ticket.c:51
TLS 1.3 session tickets.
TLS (Transport Layer Security)
#define tlsAllocMem(size)
Definition: tls.h:846
@ TLS_TRANSPORT_PROTOCOL_DATAGRAM
Definition: tls.h:942
#define tlsFreeMem(p)
Definition: tls.h:851
TlsExtensionList
Definition: tls.h:1567
#define TLS_MAX_HKDF_DIGEST_SIZE
Definition: tls.h:906
#define TLS_VERSION_1_3
Definition: tls.h:97
#define TLS_PREMASTER_SECRET_SIZE
Definition: tls.h:801
#define TlsContext
Definition: tls.h:36
@ TLS_CONNECTION_END_CLIENT
Definition: tls.h:953
#define TlsEncryptionEngine
Definition: tls.h:40
TlsHandshake
Definition: tls.h:1737
@ TLS_GROUP_FFDHE6144
Definition: tls.h:1398
@ TLS_GROUP_BRAINPOOLP384R1_TLS13
Definition: tls.h:1385
@ TLS_GROUP_FFDHE4096
Definition: tls.h:1397
@ TLS_GROUP_SECP521R1
Definition: tls.h:1378
@ TLS_GROUP_BRAINPOOLP512R1_TLS13
Definition: tls.h:1386
@ TLS_GROUP_SECP256R1
Definition: tls.h:1376
@ TLS_GROUP_SECP384R1
Definition: tls.h:1377
@ TLS_GROUP_FFDHE8192
Definition: tls.h:1399
@ TLS_GROUP_FFDHE2048
Definition: tls.h:1395
@ TLS_GROUP_FFDHE3072
Definition: tls.h:1396
@ TLS_GROUP_BRAINPOOLP256R1_TLS13
Definition: tls.h:1384
@ TLS_GROUP_ECDH_X448
Definition: tls.h:1383
@ TLS_GROUP_ECDH_X25519
Definition: tls.h:1382
@ TLS_GROUP_SM2
Definition: tls.h:1394
@ TLS_TYPE_CLIENT_HELLO
Definition: tls.h:1026
@ TLS_TYPE_MESSAGE_HASH
Definition: tls.h:1048
@ TLS_TYPE_CERTIFICATE
Definition: tls.h:1035
X.509 certificate handling.
TLS cipher suites.
@ TLS_CIPHER_SUITE_TYPE_TLS13
@ TLS_CIPHER_SUITE_TYPE_SM
error_t tlsParseHelloExtensions(TlsMessageType msgType, const uint8_t *p, size_t length, TlsHelloExtensions *extensions)
Parse Hello extensions.
error_t tlsCheckHelloExtensions(TlsMessageType msgType, uint16_t version, TlsHelloExtensions *extensions)
Check Hello extensions.
Parsing and checking of TLS extensions.
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
FFDHE key exchange.
const EcCurveInfo * tlsGetCurveInfo(TlsContext *context, uint16_t namedCurve)
Get the EC domain parameters that match the specified named curve.
Definition: tls_misc.c:1240
const HashAlgo * tlsGetHashAlgo(TlsHashAlgo hashAlgoId)
Get the hash algorithm that matches the specified identifier.
Definition: tls_misc.c:1173
TLS helper functions.
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
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
TLS record protocol.
Transcript hash calculation.