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