tls13_client_extensions.c
Go to the documentation of this file.
1 /**
2  * @file tls13_client_extensions.c
3  * @brief Formatting and parsing of extensions (TLS 1.3 client)
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_misc.h"
38 #include "tls13_ticket.h"
39 #include "debug.h"
40 
41 //Check TLS library configuration
42 #if (TLS_SUPPORT == ENABLED && TLS_CLIENT_SUPPORT == ENABLED && \
43  TLS_MAX_VERSION >= TLS_VERSION_1_3)
44 
45 
46 /**
47  * @brief Format Cookie extension
48  * @param[in] context Pointer to the TLS context
49  * @param[in] p Output stream where to write the Cookie extension
50  * @param[out] written Total number of bytes that have been written
51  * @return Error code
52  **/
53 
55  size_t *written)
56 {
57  size_t n;
58  TlsExtension *extension;
60 
61  //Initialize length field
62  n = 0;
63 
64  //When sending a HelloRetryRequest, the server may provide a Cookie
65  //extension to the client
66  if(context->cookieLen > 0)
67  {
68  //Add the Cookie extension
69  extension = (TlsExtension *) p;
70  //Type of the extension
71  extension->type = HTONS(TLS_EXT_COOKIE);
72 
73  //Point to the extension data field
74  cookie = (Tls13Cookie *) extension->value;
75 
76  //When sending the new ClientHello, the client must copy the contents
77  //of the Cookie extension received in the HelloRetryRequest
78  osMemcpy(cookie->value, context->cookie, context->cookieLen);
79 
80  //Set the length of the cookie
81  cookie->length = ntohs(context->cookieLen);
82 
83  //Consider the 2-byte length field that precedes the cookie
84  n = sizeof(Tls13Cookie) + context->cookieLen;
85  //Fix the length of the extension
86  extension->length = htons(n);
87 
88  //Compute the length, in bytes, of the Cookie extension
89  n += sizeof(TlsExtension);
90  }
91 
92  //Total number of bytes that have been written
93  *written = n;
94 
95  //Successful processing
96  return NO_ERROR;
97 }
98 
99 
100 /**
101  * @brief Format KeyShare extension (ClientHello message)
102  * @param[in] context Pointer to the TLS context
103  * @param[in] p Output stream where to write the KeyShare extension
104  * @param[out] written Total number of bytes that have been written
105  * @return Error code
106  **/
107 
109  uint8_t *p, size_t *written)
110 {
111  size_t n = 0;
112 
113 #if (TLS13_DHE_KE_SUPPORT == ENABLED || TLS13_PSK_DHE_KE_SUPPORT == ENABLED || \
114  TLS13_ECDHE_KE_SUPPORT == ENABLED || TLS13_PSK_ECDHE_KE_SUPPORT == ENABLED)
115  error_t error;
116  TlsExtension *extension;
117  Tls13KeyShareList *keyShareList;
118  Tls13KeyShareEntry *keyShareEntry;
119 
120  //Add the KeyShare extension
121  extension = (TlsExtension *) p;
122  //Type of the extension
123  extension->type = HTONS(TLS_EXT_KEY_SHARE);
124 
125  //The extension contains a list of offered KeyShareEntry values in
126  //descending order of client preference
127  keyShareList = (Tls13KeyShareList *) extension->value;
128 
129  //Point to the KeyShareEntry
130  keyShareEntry = (Tls13KeyShareEntry *) keyShareList->value;
131 
132 #if (TLS13_DHE_KE_SUPPORT == ENABLED || TLS13_PSK_DHE_KE_SUPPORT == ENABLED)
133  //Finite field group?
134  if(tls13IsFfdheGroupSupported(context, context->namedGroup))
135  {
136  //Specify the named group for the key being exchanged
137  keyShareEntry->group = htons(context->namedGroup);
138 
139  //Retrieve the length of the modulus
140  n = mpiGetByteLength(&context->dhContext.params.p);
141 
142  //Diffie-Hellman parameters are encoded in the opaque key_exchange field
143  //of the KeyShareEntry. The opaque value contains the Diffie-Hellman
144  //public value for the specified group encoded as a big-endian integer
145  //and padded to the left with zeros to the size of p in bytes
146  error = mpiExport(&context->dhContext.ya,
147  keyShareEntry->keyExchange, n, MPI_FORMAT_BIG_ENDIAN);
148  //Any error to report?
149  if(error)
150  return error;
151 
152  //Set the length of the key_exchange field
153  keyShareEntry->length = htons(n);
154 
155  //Compute the length of the KeyShareEntry
156  n += sizeof(Tls13KeyShareEntry);
157  }
158  else
159 #endif
160 #if (TLS13_ECDHE_KE_SUPPORT == ENABLED || TLS13_PSK_ECDHE_KE_SUPPORT == ENABLED)
161  //Elliptic curve group?
162  if(tls13IsEcdheGroupSupported(context, context->namedGroup))
163  {
164  //Specify the named group for the key being exchanged
165  keyShareEntry->group = htons(context->namedGroup);
166 
167  //ECDHE parameters are encoded in the opaque key_exchange field of
168  //the KeyShareEntry
169  error = ecExport(&context->ecdhContext.params,
170  &context->ecdhContext.qa.q, keyShareEntry->keyExchange, &n);
171  //Any error to report?
172  if(error)
173  return error;
174 
175  //Set the length of the key_exchange field
176  keyShareEntry->length = htons(n);
177 
178  //Compute the length of the KeyShareEntry
179  n += sizeof(Tls13KeyShareEntry);
180  }
181  else
182 #endif
183  //Unknown group?
184  {
185  //Clients may send an empty client_shares vector in order to request group
186  //selection from the server, at the cost of an additional round trip
187  }
188 
189  //Fix the length of the list of offered key shares
190  keyShareList->length = htons(n);
191 
192  //Consider the 2-byte length field that precedes the list
193  n += sizeof(Tls13KeyShareList);
194  //Fix the length of the extension
195  extension->length = htons(n);
196 
197  //Compute the length, in bytes, of the KeyShare extension
198  n += sizeof(TlsExtension);
199 #endif
200 
201  //Total number of bytes that have been written
202  *written = n;
203 
204  //Successful processing
205  return NO_ERROR;
206 }
207 
208 
209 /**
210  * @brief Format PskKeyExchangeModes extension
211  * @param[in] context Pointer to the TLS context
212  * @param[in] p Output stream where to write the PskKeyExchangeModes extension
213  * @param[out] written Total number of bytes that have been written
214  * @return Error code
215  **/
216 
218  uint8_t *p, size_t *written)
219 {
220  size_t n = 0;
221 
222 #if (TLS13_PSK_KE_SUPPORT == ENABLED || TLS13_PSK_DHE_KE_SUPPORT == ENABLED || \
223  TLS13_PSK_ECDHE_KE_SUPPORT == ENABLED)
224  TlsExtension *extension;
225  Tls13PskKeModeList *pskKeModeList;
226 
227  //Add the PskKeyExchangeModes extension
228  extension = (TlsExtension *) p;
229  //Type of the extension
230  extension->type = HTONS(TLS_EXT_PSK_KEY_EXCHANGE_MODES);
231 
232  //Point to the extension data field
233  pskKeModeList = (Tls13PskKeModeList *) extension->value;
234  //The extension contains a list of supported PSK key exchange modes
235  n = 0;
236 
238  //PSK with (EC)DHE key establishment
239  pskKeModeList->value[n++] = TLS_PSK_KEY_EXCH_MODE_PSK_DHE_KE;
240 #endif
241 #if (TLS13_PSK_KE_SUPPORT == ENABLED)
242  //PSK-only key establishment
243  pskKeModeList->value[n++] = TLS_PSK_KEY_EXCH_MODE_PSK_KE;
244 #endif
245 
246  //Fix the length of the list
247  pskKeModeList->length = (uint8_t) n;
248 
249  //Consider the length field that precedes the list
250  n += sizeof(Tls13PskKeModeList);
251  //Fix the length of the extension
252  extension->length = htons(n);
253 
254  //Compute the length, in bytes, of the PskKeyExchangeModes extension
255  n += sizeof(TlsExtension);
256 #endif
257 
258  //Total number of bytes that have been written
259  *written = n;
260 
261  //Successful processing
262  return NO_ERROR;
263 }
264 
265 
266 /**
267  * @brief Format PreSharedKey extension
268  * @param[in] context Pointer to the TLS context
269  * @param[in] p Output stream where to write the PreSharedKey extension
270  * @param[out] written Total number of bytes that have been written
271  * @param[out] identityList Pointer to the list of the identities that the
272  * client is willing to negotiate with the server
273  * @param[out] binderList Pointer to the list of HMAC values, one for each PSK
274  * offered in the PreSharedKey extension
275  * @return Error code
276  **/
277 
279  uint8_t *p, size_t *written, Tls13PskIdentityList **identityList,
280  Tls13PskBinderList **binderList)
281 {
282  size_t n = 0;
283 
284 #if (TLS13_PSK_KE_SUPPORT == ENABLED || TLS13_PSK_DHE_KE_SUPPORT == ENABLED || \
285  TLS13_PSK_ECDHE_KE_SUPPORT == ENABLED)
286  //Check whether the client is attempting a PSK key establishment
287  if(tls13IsPskValid(context) || tls13IsTicketValid(context))
288  {
289  error_t error;
290  size_t m;
291  uint16_t cipherSuite;
292  uint32_t ticketAge;
293  TlsExtension *extension;
294  TlsPskIdentity *pskIdentity;
295  Tls13PskBinder *pskBinder;
296  const HashAlgo *hashAlgo;
297 
298  //Add the PreSharedKey extension
299  extension = (TlsExtension *) p;
300  //Type of the extension
301  extension->type = HTONS(TLS_EXT_PRE_SHARED_KEY);
302 
303  //Point to the extension data field
304  *identityList = (Tls13PskIdentityList *) extension->value;
305  //Point to the first PskIdentity entry of the list
306  pskIdentity = (TlsPskIdentity *) (*identityList)->value;
307 
308  //Although PSKs can be established out of band, PSKs can also be
309  //established in a previous connection
310  if(tls13IsPskValid(context))
311  {
312  //Retrieve the length of the PSK identity
313  n = osStrlen(context->pskIdentity);
314  //Copy PSK identity
315  osMemcpy(pskIdentity->value, context->pskIdentity, n);
316 
317  //For externally established PSKs, the hash algorithm must be set when
318  //the PSK is established or default to SHA-256 if no such algorithm is
319  //defined
320  hashAlgo = tlsGetHashAlgo(context->pskHashAlgo);
321 
322  //Retrieve the cipher suite associated with the PSK, if any
323  cipherSuite = context->pskCipherSuite;
324 
325  //For PSK identities established externally, an obfuscated_ticket_age
326  //of 0 should be used (refer to RFC 8446, section 4.2.11)
327  ticketAge = 0;
328  }
329  else if(tls13IsTicketValid(context))
330  {
331  //Retrieve the length of the session ticket
332  n = context->ticketLen;
333  //Copy session ticket
334  osMemcpy(pskIdentity->value, context->ticket, n);
335 
336  //Each PSK is associated with a single hash algorithm. For PSKs
337  //established via the ticket mechanism, this is the KDF hash algorithm
338  //on the connection where the ticket was established
339  hashAlgo = tlsGetHashAlgo(context->ticketHashAlgo);
340 
341  //Retrieve the cipher suite associated with the ticket
342  cipherSuite = context->ticketCipherSuite;
343 
344  //The client's view of the age of a ticket is the time since the
345  //receipt of the NewSessionTicket message
346  ticketAge = context->clientHelloTimestamp - context->ticketTimestamp;
347 
348  //The obfuscated_ticket_age field contains an obfuscated version of
349  //the ticket age formed by taking the age in milliseconds and adding
350  //the ticket_age_add value that was included with the ticket
351  ticketAge += context->ticketAgeAdd;
352  }
353  else
354  {
355  //Just for sanity
356  return ERROR_FAILURE;
357  }
358 
359  //Valid cipher suite provisioned?
360  if(cipherSuite != 0)
361  {
362  //Restore the cipher suite associated with the PSK
363  error = tlsSelectCipherSuite(context, cipherSuite);
364  //Any error to report?
365  if(error)
366  return error;
367  }
368  else
369  {
370  //Make sure the hash algorithm is valid
371  if(hashAlgo == NULL)
372  return ERROR_FAILURE;
373 
374  //Restore the hash algorithm associated with the PSK
375  context->cipherSuite.prfHashAlgo = hashAlgo;
376  }
377 
378  //Fix the length of the PSK identity
379  pskIdentity->length = htons(n);
380  //Consider the length field that precedes the PSK identity
381  n += sizeof(TlsPskIdentity);
382 
383  //The obfuscated_ticket_age field is a 32-bit unsigned integer
384  STORE32BE(ticketAge, (uint8_t *) pskIdentity + n);
385  //Compute the length of the PskIdentity entry
386  n += sizeof(uint32_t);
387 
388  //Fix the length of the list of PSK identities
389  (*identityList)->length = htons(n);
390  //Consider the 2-byte length field that precedes the list
391  n += sizeof(Tls13PskIdentityList);
392 
393  //Point to the list of PSK binders
394  *binderList = (Tls13PskBinderList *) ((uint8_t *) *identityList + n);
395  //Point to the first PskBinderEntry of the list
396  pskBinder = (Tls13PskBinder *) (*binderList)->value;
397 
398  //The PSK binder consists of Hash.length bytes
399  m = hashAlgo->digestSize;
400  //The value of the PSK binder will be calculated in a second step
401  osMemset(pskBinder->value, 0, m);
402 
403  //Fix the length of the PSK binder
404  pskBinder->length = (uint8_t) m;
405  //Consider the length field that precedes the PSK binder
406  m += sizeof(Tls13PskBinder);
407 
408  //Fix the length of the list of PSK binders
409  (*binderList)->length = htons(m);
410  //Consider the 2-byte length field that precedes the list
411  n += sizeof(Tls13PskBinderList) + m;
412 
413  //Fix the length of the extension
414  extension->length = htons(n);
415  //Compute the length, in bytes, of the PreSharedKey extension
416  n += sizeof(TlsExtension);
417  }
418  else
419 #endif
420  {
421  //PSK key establishment is not used
422  *identityList = NULL;
423  *binderList = NULL;
424  }
425 
426  //Total number of bytes that have been written
427  *written = n;
428 
429  //Successful processing
430  return NO_ERROR;
431 }
432 
433 
434 /**
435  * @brief Format EarlyData extension
436  * @param[in] context Pointer to the TLS context
437  * @param[in] p Output stream where to write the EarlyData extension
438  * @param[out] written Total number of bytes that have been written
439  * @return Error code
440  **/
441 
443  uint8_t *p, size_t *written)
444 {
445  size_t n = 0;
446 
447 #if (TLS13_EARLY_DATA_SUPPORT == ENABLED)
448  //If the client opts to send application data in its first flight of
449  //messages, it must supply both the PreSharedKey and EarlyData extensions
450  if(context->earlyDataEnabled && !context->earlyDataRejected)
451  {
452  TlsExtension *extension;
453 
454  //Add the EarlyData extension
455  extension = (TlsExtension *) p;
456  //Type of the extension
457  extension->type = HTONS(TLS_EXT_EARLY_DATA);
458 
459  //The extension data field of this extension is empty
460  extension->length = HTONS(0);
461 
462  //Compute the length, in bytes, of the EarlyData extension
463  n = sizeof(TlsExtension);
464  }
465 #endif
466 
467  //Total number of bytes that have been written
468  *written = n;
469 
470  //Successful processing
471  return NO_ERROR;
472 }
473 
474 
475 /**
476  * @brief Parse SupportedVersions extension
477  * @param[in] context Pointer to the TLS context
478  * @param[in] selectedVersion Pointer to the SupportedVersions extension
479  * @return Error code
480  **/
481 
483  const TlsExtension *selectedVersion)
484 {
485  error_t error;
486  uint16_t version;
487 
488  //The extension contains the selected version value
489  version = LOAD16BE(selectedVersion->value);
490 
491  //If the SupportedVersions extension contains a version prior to TLS 1.3,
492  //the client must abort the handshake with an illegal_parameter alert
495 
496  //Debug message
497  TRACE_INFO(" selectedVersion = 0x%04" PRIX16 " (%s)\r\n",
499 
500  //Set the TLS version to be used
501  error = tlsSelectVersion(context, version);
502  //Specified TLS/DTLS version not supported?
503  if(error)
504  return error;
505 
506  //Successful processing
507  return NO_ERROR;
508 }
509 
510 
511 /**
512  * @brief Parse Cookie extension
513  * @param[in] context Pointer to the TLS context
514  * @param[in] cookie Pointer to the Cookie extension
515  * @return Error code
516  **/
517 
519  const Tls13Cookie *cookie)
520 {
521  //Cookie extension found?
522  if(cookie != NULL)
523  {
524  size_t n;
525 
526  //Retrieve the length of the cookie
527  n = ntohs(cookie->length);
528 
529  //Clients must abort the handshake with an illegal_parameter alert if the
530  //HelloRetryRequest would not result in any change in the ClientHello
531  if(n == 0)
533 
534  //Check the length of the cookie
537 
538  //Sanity check
539  if(context->cookie != NULL)
540  {
541  //Release memory
542  tlsFreeMem(context->cookie);
543  context->cookie = NULL;
544  context->cookieLen = 0;
545  }
546 
547  //Allocate a memory block to store the cookie
548  context->cookie = tlsAllocMem(n);
549  //Failed to allocate memory?
550  if(context->cookie == NULL)
551  return ERROR_OUT_OF_MEMORY;
552 
553  //Save cookie
554  osMemcpy(context->cookie, cookie->value, n);
555  context->cookieLen = n;
556  }
557 
558  //Successful processing
559  return NO_ERROR;
560 }
561 
562 
563 /**
564  * @brief Parse KeyShare extension (HelloRetryRequest message)
565  * @param[in] context Pointer to the TLS context
566  * @param[in] selectedGroup Pointer to the KeyShare extension
567  * @return Error code
568  **/
569 
571  const TlsExtension *selectedGroup)
572 {
573  error_t error;
574 
575  //Initialize status code
576  error = NO_ERROR;
577 
578 #if (TLS13_DHE_KE_SUPPORT == ENABLED || TLS13_PSK_DHE_KE_SUPPORT == ENABLED || \
579  TLS13_ECDHE_KE_SUPPORT == ENABLED || TLS13_PSK_ECDHE_KE_SUPPORT == ENABLED)
580  //KeyShare extension found?
581  if(selectedGroup != NULL)
582  {
583  uint16_t namedGroup;
584 
585  //The KeyShare extension contains the mutually supported group the server
586  //intends to negotiate
587  namedGroup = LOAD16BE(selectedGroup->value);
588 
589  //Check whether the server has selected a different ECDHE or FFDHE group
590  if(namedGroup != context->namedGroup)
591  {
592  //Generate an ephemeral key pair
593  error = tls13GenerateKeyShare(context, namedGroup);
594  }
595  }
596 #else
597  //KeyShare extension found?
598  if(selectedGroup != NULL)
599  {
600  //If a client receives an extension type that it did not request in the
601  //ClientHello, it must abort the handshake with an unsupported_extension
602  //fatal alert
604  }
605 #endif
606 
607  //Return status code
608  return error;
609 }
610 
611 
612 /**
613  * @brief Parse KeyShare extension (ServerHello message)
614  * @param[in] context Pointer to the TLS context
615  * @param[in] serverShare Pointer to the KeyShare extension
616  * @return Error code
617  **/
618 
620  const Tls13KeyShareEntry *serverShare)
621 {
622 #if (TLS13_DHE_KE_SUPPORT == ENABLED || TLS13_PSK_DHE_KE_SUPPORT == ENABLED || \
623  TLS13_ECDHE_KE_SUPPORT == ENABLED || TLS13_PSK_ECDHE_KE_SUPPORT == ENABLED)
624  //If using (EC)DHE key establishment, servers offer exactly one KeyShareEntry
625  //in the ServerHello
626  if(serverShare != NULL)
627  {
628  error_t error;
629  uint16_t namedGroup;
630 
631  //Convert the selected NamedGroup to host byte order
632  namedGroup = ntohs(serverShare->group);
633 
634  //Elliptic curve group?
635  if(tls13IsEcdheGroupSupported(context, namedGroup))
636  {
637  //ECDHE key exchange mechanism provides forward secrecy
638  context->keyExchMethod = TLS13_KEY_EXCH_ECDHE;
639  }
640  //Finite field group?
641  else if(tls13IsFfdheGroupSupported(context, namedGroup))
642  {
643  //DHE key exchange mechanism provides forward secrecy
644  context->keyExchMethod = TLS13_KEY_EXCH_DHE;
645  }
646  //Unknown group?
647  else
648  {
649  //Servers must not send a KeyShareEntry for any group not indicated
650  //in the client's SupportedGroups extension
652  }
653 
654  //The client must verify that the selected NamedGroup in the ServerHello
655  //is the same as that in the HelloRetryRequest
656  if(namedGroup != context->namedGroup)
658 
659  //Compute (EC)DHE shared secret
660  error = tls13GenerateSharedSecret(context, serverShare->keyExchange,
661  ntohs(serverShare->length));
662  //Any error to report?
663  if(error)
664  return error;
665  }
666  else
667  {
668  //PSKs can be used alone, at the cost of losing forward secrecy for
669  //the application data
670  context->keyExchMethod = TLS_KEY_EXCH_NONE;
671  }
672 #else
673  //KeyShareEntry extension found?
674  if(serverShare != NULL)
675  {
676  //If a client receives an extension type that it did not request in the
677  //ClientHello, it must abort the handshake with an unsupported_extension
678  //fatal alert
680  }
681  else
682  {
683  //Perform a PSK handshake if possible
684  context->keyExchMethod = TLS_KEY_EXCH_NONE;
685  }
686 #endif
687 
688  //Successful processing
689  return NO_ERROR;
690 }
691 
692 
693 /**
694  * @brief Parse PreSharedKey extension
695  * @param[in] context Pointer to the TLS context
696  * @param[in] selectedIdentity Pointer to the PreSharedKey extension
697  * @return Error code
698  **/
699 
701  const TlsExtension *selectedIdentity)
702 {
703  //Reset the server's selected_identity to its default value
704  context->selectedIdentity = -1;
705 
706 #if (TLS13_PSK_KE_SUPPORT == ENABLED || TLS13_PSK_DHE_KE_SUPPORT == ENABLED || \
707  TLS13_PSK_ECDHE_KE_SUPPORT == ENABLED)
708  //PreSharedKey extension found?
709  if(selectedIdentity != NULL)
710  {
711  const HashAlgo *hashAlgo;
712 
713  //If a client receives an extension type that it did not request in the
714  //ClientHello, it must abort the handshake with an unsupported_extension
715  //fatal alert
716  if(!tls13IsPskValid(context) && !tls13IsTicketValid(context))
718 
719  //In order to accept PSK key establishment, the server sends a
720  //PreSharedKey extension indicating the selected identity
721  context->selectedIdentity = LOAD16BE(selectedIdentity->value);
722 
723  //Clients must verify that the server's selected_identity is within the
724  //range supplied by the client (refer to RFC 8446, section 4.2.11)
725  if(context->selectedIdentity != 0)
727 
728  //Point to the cipher suite hash algorithm
729  hashAlgo = context->cipherSuite.prfHashAlgo;
730  //Make sure the hash algorithm is valid
731  if(hashAlgo == NULL)
732  return ERROR_FAILURE;
733 
734  //Clients must also verify that the server has selected a cipher suite
735  //indicating a hash algorithm associated with the PSK
736  if(tls13IsPskValid(context))
737  {
738  //PSK incompatible with the selected cipher suite?
739  if(tlsGetHashAlgo(context->pskHashAlgo) != hashAlgo)
741  }
742  else if(tls13IsTicketValid(context))
743  {
744  //PSK incompatible with the selected cipher suite?
745  if(tlsGetHashAlgo(context->ticketHashAlgo) != hashAlgo)
747  }
748  else
749  {
750  //Just for sanity
751  }
752 
753  //PSKs can be used with (EC)DHE key exchange in order to provide forward
754  //secrecy in combination with shared keys, or can be used alone, at the
755  //cost of losing forward secrecy for the application data
756 #if (TLS13_PSK_KE_SUPPORT == ENABLED)
757  if(context->keyExchMethod == TLS_KEY_EXCH_NONE)
758  {
759  context->keyExchMethod = TLS13_KEY_EXCH_PSK;
760  }
761 #endif
762 #if (TLS13_PSK_DHE_KE_SUPPORT == ENABLED)
763  if(context->keyExchMethod == TLS13_KEY_EXCH_DHE)
764  {
765  context->keyExchMethod = TLS13_KEY_EXCH_PSK_DHE;
766  }
767 #endif
768 #if (TLS13_PSK_ECDHE_KE_SUPPORT == ENABLED)
769  if(context->keyExchMethod == TLS13_KEY_EXCH_ECDHE)
770  {
771  context->keyExchMethod = TLS13_KEY_EXCH_PSK_ECDHE;
772  }
773 #endif
774  }
775 #else
776  //PreSharedKey extension found?
777  if(selectedIdentity != NULL)
778  {
779  //If a client receives an extension type that it did not request in the
780  //ClientHello, it must abort the handshake with an unsupported_extension
781  //fatal alert
783  }
784 #endif
785 
786  //Successful processing
787  return NO_ERROR;
788 }
789 
790 
791 /**
792  * @brief Parse EarlyData extension
793  * @param[in] msgType Handshake message type
794  * @param[in] context Pointer to the TLS context
795  * @param[in] earlyDataIndication Pointer to the EarlyData extension
796  * @return Error code
797  **/
798 
800  TlsMessageType msgType, const TlsExtension *earlyDataIndication)
801 {
802 #if (TLS13_EARLY_DATA_SUPPORT == ENABLED)
803  //The extension may appear in EncryptedExtensions and NewSessionTicket
804  //messages
806  {
807  //EarlyData extension found?
808  if(earlyDataIndication != NULL)
809  {
810  //If a client receives an extension type that it did not request in the
811  //ClientHello, it must abort the handshake with an unsupported_extension
812  //fatal alert
813  if(!context->earlyDataEnabled || context->earlyDataRejected)
815 
816  //If the server has supplied an EarlyData extension, the client must
817  //verify that the server's selected_identity is 0. If any other value
818  //is returned, it must abort the handshake with an illegal_parameter
819  //fatal alert
820  if(context->selectedIdentity != 0)
822 
823  //A valid EarlyData extension has been received
824  context->earlyDataExtReceived = TRUE;
825  }
826  else
827  {
828  //The EncryptedExtensions message does not contain any EarlyData
829  //extension
830  context->earlyDataExtReceived = FALSE;
831  }
832  }
834  {
835  //The extension contains the maximum amount of 0-RTT data that the client
836  //is allowed to send
837  if(earlyDataIndication != NULL)
838  {
839  context->maxEarlyDataSize = LOAD32BE(earlyDataIndication->value);
840  }
841  else
842  {
843  context->maxEarlyDataSize = 0;
844  }
845  }
846  else
847  {
848  //Just for sanity
849  }
850 #else
851  //Check message type
853  {
854  //EarlyData extension found?
855  if(earlyDataIndication != NULL)
856  {
857  //If a client receives an extension type that it did not request in the
858  //ClientHello, it must abort the handshake with an unsupported_extension
859  //fatal alert
861  }
862  }
864  {
865  //Early data is not implemented
866  context->maxEarlyDataSize = 0;
867  }
868  else
869  {
870  //Just for sanity
871  }
872 #endif
873 
874  //Successful processing
875  return NO_ERROR;
876 }
877 
878 #endif
uint8_t version
Definition: coap_common.h:177
#define HTONS(value)
Definition: cpu_endian.h:410
#define LOAD32BE(p)
Definition: cpu_endian.h:210
#define htons(value)
Definition: cpu_endian.h:413
#define STORE32BE(a, p)
Definition: cpu_endian.h:286
#define ntohs(value)
Definition: cpu_endian.h:421
#define LOAD16BE(p)
Definition: cpu_endian.h:186
Debugging facilities.
#define TRACE_INFO(...)
Definition: debug.h:95
uint8_t n
uint8_t cookie[]
Definition: dtls_misc.h:206
error_t ecExport(const EcDomainParameters *params, const EcPoint *a, uint8_t *data, size_t *length)
Convert an EC point to an octet string.
Definition: ec.c:438
error_t
Error codes.
Definition: error.h:43
@ ERROR_UNSUPPORTED_EXTENSION
Definition: error.h:244
@ ERROR_ILLEGAL_PARAMETER
Definition: error.h:242
@ NO_ERROR
Success.
Definition: error.h:44
@ ERROR_OUT_OF_MEMORY
Definition: error.h:63
@ ERROR_FAILURE
Generic error code.
Definition: error.h:45
uint_t mpiGetByteLength(const Mpi *a)
Get the actual length in bytes.
Definition: mpi.c:195
error_t mpiExport(const Mpi *a, uint8_t *data, uint_t length, MpiFormat format)
Integer to octet string conversion.
Definition: mpi.c:709
@ MPI_FORMAT_BIG_ENDIAN
Definition: mpi.h:71
uint8_t msgType
uint8_t p
Definition: ndp.h:300
uint8_t m
Definition: ndp.h:304
#define osMemset(p, value, length)
Definition: os_port.h:135
#define osMemcpy(dest, src, length)
Definition: os_port.h:141
#define osStrlen(s)
Definition: os_port.h:165
#define ENABLED
Definition: os_port.h:37
#define TRUE
Definition: os_port.h:50
#define FALSE
Definition: os_port.h:46
Common interface for hash algorithms.
Definition: crypto.h:1014
size_t digestSize
Definition: crypto.h:1020
error_t tls13ParseCookieExtension(TlsContext *context, const Tls13Cookie *cookie)
Parse Cookie extension.
error_t tls13ParseSelectedGroupExtension(TlsContext *context, const TlsExtension *selectedGroup)
Parse KeyShare extension (HelloRetryRequest message)
error_t tls13ParseServerEarlyDataExtension(TlsContext *context, TlsMessageType msgType, const TlsExtension *earlyDataIndication)
Parse EarlyData extension.
error_t tls13ParseServerSupportedVersionsExtension(TlsContext *context, const TlsExtension *selectedVersion)
Parse SupportedVersions extension.
error_t tls13FormatClientPreSharedKeyExtension(TlsContext *context, uint8_t *p, size_t *written, Tls13PskIdentityList **identityList, Tls13PskBinderList **binderList)
Format PreSharedKey extension.
error_t tls13ParseServerPreSharedKeyExtension(TlsContext *context, const TlsExtension *selectedIdentity)
Parse PreSharedKey extension.
error_t tls13FormatClientKeyShareExtension(TlsContext *context, uint8_t *p, size_t *written)
Format KeyShare extension (ClientHello message)
error_t tls13ParseServerKeyShareExtension(TlsContext *context, const Tls13KeyShareEntry *serverShare)
Parse KeyShare extension (ServerHello message)
error_t tls13FormatCookieExtension(TlsContext *context, uint8_t *p, size_t *written)
Format Cookie extension.
error_t tls13FormatClientEarlyDataExtension(TlsContext *context, uint8_t *p, size_t *written)
Format EarlyData extension.
error_t tls13FormatPskKeModesExtension(TlsContext *context, uint8_t *p, size_t *written)
Format PskKeyExchangeModes extension.
Formatting and parsing of extensions (TLS 1.3 client)
bool_t tls13IsEcdheGroupSupported(TlsContext *context, uint16_t namedGroup)
Check whether a given ECDHE group is supported.
Definition: tls13_misc.c:649
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
bool_t tls13IsPskValid(TlsContext *context)
Check whether an externally established PSK is valid.
Definition: tls13_misc.c:538
error_t tls13GenerateKeyShare(TlsContext *context, uint16_t namedGroup)
Key share generation.
Definition: tls13_misc.c:260
Tls13PskBinderList
Definition: tls13_misc.h:247
Tls13KeyShareList
Definition: tls13_misc.h:192
#define TLS13_PSK_ECDHE_KE_SUPPORT
Definition: tls13_misc.h:64
Tls13KeyShareEntry
Definition: tls13_misc.h:181
@ TLS_PSK_KEY_EXCH_MODE_PSK_KE
Definition: tls13_misc.h:137
@ TLS_PSK_KEY_EXCH_MODE_PSK_DHE_KE
Definition: tls13_misc.h:138
Tls13Cookie
Definition: tls13_misc.h:169
Tls13PskIdentityList
Definition: tls13_misc.h:225
Tls13PskBinder
Definition: tls13_misc.h:236
#define TLS13_MAX_COOKIE_SIZE
Definition: tls13_misc.h:85
#define TLS13_PSK_DHE_KE_SUPPORT
Definition: tls13_misc.h:57
Tls13PskKeModeList
Definition: tls13_misc.h:203
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
@ TLS13_KEY_EXCH_PSK_DHE
Definition: tls.h:1146
@ TLS13_KEY_EXCH_ECDHE
Definition: tls.h:1144
@ TLS13_KEY_EXCH_PSK
Definition: tls.h:1145
@ TLS13_KEY_EXCH_DHE
Definition: tls.h:1143
@ TLS13_KEY_EXCH_PSK_ECDHE
Definition: tls.h:1147
@ TLS_KEY_EXCH_NONE
Definition: tls.h:1124
#define tlsFreeMem(p)
Definition: tls.h:851
TlsExtension
Definition: tls.h:1556
TlsPskIdentity
Definition: tls.h:1678
@ TLS_EXT_EARLY_DATA
Definition: tls.h:1304
@ TLS_EXT_PRE_SHARED_KEY
Definition: tls.h:1303
@ TLS_EXT_KEY_SHARE
Definition: tls.h:1312
@ TLS_EXT_COOKIE
Definition: tls.h:1306
@ TLS_EXT_PSK_KEY_EXCHANGE_MODES
Definition: tls.h:1307
#define TLS_VERSION_1_3
Definition: tls.h:97
#define TlsContext
Definition: tls.h:36
uint16_t cipherSuite
Cipher suite identifier.
Definition: tls.h:1866
TlsMessageType
Handshake message type.
Definition: tls.h:1024
@ TLS_TYPE_ENCRYPTED_EXTENSIONS
Definition: tls.h:1032
@ TLS_TYPE_NEW_SESSION_TICKET
Definition: tls.h:1029
error_t tlsSelectCipherSuite(TlsContext *context, uint16_t identifier)
Set cipher suite.
Definition: tls_misc.c:333
error_t tlsSelectVersion(TlsContext *context, uint16_t version)
Set the TLS version to be used.
Definition: tls_misc.c:305
const char_t * tlsGetVersionName(uint16_t version)
Convert TLS version to string representation.
Definition: tls_misc.c:1112
const HashAlgo * tlsGetHashAlgo(TlsHashAlgo hashAlgoId)
Get the hash algorithm that matches the specified identifier.
Definition: tls_misc.c:1173
TLS helper functions.