tls13_server_extensions.c
Go to the documentation of this file.
1 /**
2  * @file tls13_server_extensions.c
3  * @brief Formatting and parsing of extensions (TLS 1.3 server)
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_server_misc.h"
39 #include "tls13_ticket.h"
40 #include "debug.h"
41 
42 //Check TLS library configuration
43 #if (TLS_SUPPORT == ENABLED && TLS_SERVER_SUPPORT == ENABLED && \
44  TLS_MAX_VERSION >= TLS_VERSION_1_3)
45 
46 
47 /**
48  * @brief Format SupportedVersions extension
49  * @param[in] context Pointer to the TLS context
50  * @param[in] p Output stream where to write the SupportedVersions extension
51  * @param[out] written Total number of bytes that have been written
52  * @return Error code
53  **/
54 
56  uint8_t *p, size_t *written)
57 {
58  size_t n;
59  uint16_t version;
60  TlsExtension *extension;
61 
62  //Add the SupportedVersions extension
63  extension = (TlsExtension *) p;
64  //Type of the extension
65  extension->type = HTONS(TLS_EXT_SUPPORTED_VERSIONS);
66 
67 #if (DTLS_SUPPORT == ENABLED)
68  //DTLS protocol?
69  if(context->transportProtocol == TLS_TRANSPORT_PROTOCOL_DATAGRAM)
70  {
71  //Retrieve the selected DTLS version
72  version = dtlsTranslateVersion(context->version);
73  }
74  else
75 #endif
76  {
77  //Retrieve the selected TLS version
78  version = context->version;
79  }
80 
81  //The extension contains the selected version value
82  STORE16BE(version, extension->value);
83 
84  //The extension data field contains a 16-bit unsigned integer
85  n = sizeof(uint16_t);
86  //Fix the length of the extension
87  extension->length = htons(n);
88 
89  //Compute the length, in bytes, of the SupportedVersions extension
90  n += sizeof(TlsExtension);
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 (HelloRetryRequest 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  //Check whether the selected ECDHE or FFDHE group is valid
117  if(context->namedGroup != TLS_GROUP_NONE)
118  {
119  TlsExtension *extension;
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 the mutually supported group the server intends
127  //to negotiate
128  STORE16BE(context->namedGroup, extension->value);
129 
130  //The extension data field contains a 16-bit unsigned integer
131  n = sizeof(uint16_t);
132  //Fix the length of the extension
133  extension->length = htons(n);
134 
135  //Compute the length, in bytes, of the KeyShare extension
136  n += sizeof(TlsExtension);
137  }
138 #endif
139 
140  //Total number of bytes that have been written
141  *written = n;
142 
143  //Successful processing
144  return NO_ERROR;
145 }
146 
147 
148 /**
149  * @brief Format KeyShare extension (ServerHello message)
150  * @param[in] context Pointer to the TLS context
151  * @param[in] p Output stream where to write the KeyShare extension
152  * @param[out] written Total number of bytes that have been written
153  * @return Error code
154  **/
155 
157  uint8_t *p, size_t *written)
158 {
159  size_t n = 0;
160 
161 #if (TLS13_DHE_KE_SUPPORT == ENABLED || TLS13_PSK_DHE_KE_SUPPORT == ENABLED || \
162  TLS13_ECDHE_KE_SUPPORT == ENABLED || TLS13_PSK_ECDHE_KE_SUPPORT == ENABLED || \
163  TLS13_HYBRID_KE_SUPPORT == ENABLED || TLS13_PSK_HYBRID_KE_SUPPORT == ENABLED)
164  //If using (EC)DHE key establishment, servers offer exactly one
165  //KeyShareEntry in the ServerHello
166  if(context->keyExchMethod == TLS13_KEY_EXCH_DHE ||
167  context->keyExchMethod == TLS13_KEY_EXCH_ECDHE ||
168  context->keyExchMethod == TLS13_KEY_EXCH_HYBRID ||
169  context->keyExchMethod == TLS13_KEY_EXCH_PSK_DHE ||
170  context->keyExchMethod == TLS13_KEY_EXCH_PSK_ECDHE ||
171  context->keyExchMethod == TLS13_KEY_EXCH_PSK_HYBRID)
172  {
173  error_t error;
174  TlsExtension *extension;
175  Tls13KeyShareEntry *keyShareEntry;
176 
177  //Add the KeyShare extension
178  extension = (TlsExtension *) p;
179  //Type of the extension
180  extension->type = HTONS(TLS_EXT_KEY_SHARE);
181 
182  //If using (EC)DHE key establishment, servers offer exactly one
183  //KeyShareEntry in the ServerHello
184  keyShareEntry = (Tls13KeyShareEntry *) extension->value;
185 
186  //The key share value must be in the same group as the KeyShareEntry
187  //value offered by the client that the server has selected for the
188  //negotiated key exchange
189  keyShareEntry->group = htons(context->namedGroup);
190 
191 #if (TLS13_DHE_KE_SUPPORT == ENABLED || TLS13_PSK_DHE_KE_SUPPORT == ENABLED)
192  //DHE key exchange method?
193  if(context->keyExchMethod == TLS13_KEY_EXCH_DHE ||
194  context->keyExchMethod == TLS13_KEY_EXCH_PSK_DHE)
195  {
196  //Retrieve the length of the modulus
197  n = mpiGetByteLength(&context->dhContext.params.p);
198 
199  //Diffie-Hellman parameters are encoded in the opaque key_exchange field
200  //of the KeyShareEntry. The opaque value contains the Diffie-Hellman
201  //public value for the specified group encoded as a big-endian integer
202  //and padded to the left with zeros to the size of p in bytes
203  error = mpiExport(&context->dhContext.ya,
204  keyShareEntry->keyExchange, n, MPI_FORMAT_BIG_ENDIAN);
205  //Any error to report?
206  if(error)
207  return error;
208  }
209  else
210 #endif
211 #if (TLS13_ECDHE_KE_SUPPORT == ENABLED || TLS13_PSK_ECDHE_KE_SUPPORT == ENABLED)
212  //ECDHE key exchange method?
213  if(context->keyExchMethod == TLS13_KEY_EXCH_ECDHE ||
214  context->keyExchMethod == TLS13_KEY_EXCH_PSK_ECDHE)
215  {
216  //ECDHE parameters are encoded in the opaque key_exchange field of
217  //the KeyShareEntry
218  error = ecExport(&context->ecdhContext.params,
219  &context->ecdhContext.qa.q, keyShareEntry->keyExchange, &n);
220  //Any error to report?
221  if(error)
222  return error;
223  }
224  else
225 #endif
226 #if (TLS13_HYBRID_KE_SUPPORT == ENABLED || TLS13_PSK_HYBRID_KE_SUPPORT == ENABLED)
227  //Hybrid key exchange method?
228  if(context->keyExchMethod == TLS13_KEY_EXCH_HYBRID ||
229  context->keyExchMethod == TLS13_KEY_EXCH_PSK_HYBRID)
230  {
231  //The server ECDHE share is the serialized value of the uncompressed
232  //ECDH point representation
233  error = ecExport(&context->ecdhContext.params,
234  &context->ecdhContext.qa.q, keyShareEntry->keyExchange, &n);
235  //Any error to report?
236  if(error)
237  return error;
238 
239  //The server share is the Kyber's ciphertext returned from the
240  //Encapsulate step represented as an octet string
241  error = kemEncapsulate(&context->kemContext, context->prngAlgo,
242  context->prngContext, keyShareEntry->keyExchange + n,
243  context->premasterSecret + context->premasterSecretLen);
244  //Any error to report?
245  if(error)
246  return error;
247 
248  //The server's share is a fixed-size concatenation of ECDHE share and
249  //Kyber's ciphertext returned from encapsulation
250  n += context->kemContext.kemAlgo->ciphertextSize;
251 
252  //Finally, the shared secret is a concatenation of the ECDHE and the
253  //Kyber shared secrets
254  context->premasterSecretLen += context->kemContext.kemAlgo->sharedSecretSize;
255  }
256  else
257 #endif
258  //Unknown key exchange method?
259  {
260  //Report an error
261  return ERROR_FAILURE;
262  }
263 
264  //Set the length of the key_exchange field
265  keyShareEntry->length = htons(n);
266 
267  //Compute the length, in bytes, of the KeyShareEntry
268  n += sizeof(Tls13KeyShareEntry);
269  //Fix the length of the extension
270  extension->length = htons(n);
271 
272  //Compute the length, in bytes, of the KeyShare extension
273  n += sizeof(TlsExtension);
274  }
275 #endif
276 
277  //Total number of bytes that have been written
278  *written = n;
279 
280  //Successful processing
281  return NO_ERROR;
282 }
283 
284 
285 /**
286  * @brief Format PreSharedKey extension
287  * @param[in] context Pointer to the TLS context
288  * @param[in] p Output stream where to write the PreSharedKey extension
289  * @param[out] written Total number of bytes that have been written
290  * @return Error code
291  **/
292 
294  uint8_t *p, size_t *written)
295 {
296  size_t n = 0;
297 
298 #if (TLS13_PSK_KE_SUPPORT == ENABLED || TLS13_PSK_DHE_KE_SUPPORT == ENABLED || \
299  TLS13_PSK_ECDHE_KE_SUPPORT == ENABLED || TLS13_PSK_HYBRID_KE_SUPPORT == ENABLED)
300  //PSK key exchange method?
301  if(context->keyExchMethod == TLS13_KEY_EXCH_PSK ||
302  context->keyExchMethod == TLS13_KEY_EXCH_PSK_DHE ||
303  context->keyExchMethod == TLS13_KEY_EXCH_PSK_ECDHE ||
304  context->keyExchMethod == TLS13_KEY_EXCH_PSK_HYBRID)
305  {
306  TlsExtension *extension;
307 
308  //Add the PreSharedKey extension
309  extension = (TlsExtension *) p;
310  //Type of the extension
311  extension->type = HTONS(TLS_EXT_PRE_SHARED_KEY);
312 
313  //The extension contains the selected identity
314  STORE16BE(context->selectedIdentity, extension->value);
315 
316  //The extension data field contains a 16-bit unsigned integer
317  n = sizeof(uint16_t);
318  //Fix the length of the extension
319  extension->length = htons(n);
320 
321  //Compute the length, in bytes, of the PreSharedKey extension
322  n += sizeof(TlsExtension);
323  }
324 #endif
325 
326  //Total number of bytes that have been written
327  *written = n;
328 
329  //Successful processing
330  return NO_ERROR;
331 }
332 
333 
334 /**
335  * @brief Format EarlyData extension
336  * @param[in] context Pointer to the TLS context
337  * @param[in] msgType Handshake message type
338  * @param[in] p Output stream where to write the EarlyData extension
339  * @param[out] written Total number of bytes that have been written
340  * @return Error code
341  **/
342 
344  TlsMessageType msgType, uint8_t *p, size_t *written)
345 {
346  size_t n = 0;
347 
348 #if (TLS13_EARLY_DATA_SUPPORT == ENABLED)
349  //The extension may appear in EncryptedExtensions and NewSessionTicket
350  //messages
352  {
353  //If the server intends to process the early data, then it returns its
354  //own EarlyData extension in EncryptedExtensions
355  if(context->earlyDataExtReceived && !context->earlyDataRejected)
356  {
357  TlsExtension *extension;
358 
359  //Add the EarlyData extension
360  extension = (TlsExtension *) p;
361  //Type of the extension
362  extension->type = HTONS(TLS_EXT_EARLY_DATA);
363 
364  //The extension data field of this extension is empty
365  extension->length = HTONS(0);
366 
367  //Compute the length, in bytes, of the EarlyData extension
368  n = sizeof(TlsExtension);
369  }
370  }
372  {
373  TlsExtension *extension;
374 
375  //Add the EarlyData extension
376  extension = (TlsExtension *) p;
377  //Type of the extension
378  extension->type = HTONS(TLS_EXT_EARLY_DATA);
379 
380  //The extension contains the maximum amount of 0-RTT data that the
381  //client is allowed to send when using this ticket, in bytes
382  STORE32BE(context->maxEarlyDataSize, extension->value);
383 
384  //The extension data field contains a 32-bit unsigned integer
385  n = sizeof(uint32_t);
386  //Fix the length of the extension
387  extension->length = htons(n);
388 
389  //Compute the length, in bytes, of the EarlyData extension
390  n += sizeof(TlsExtension);
391  }
392  else
393  {
394  //Just for sanity
395  }
396 #endif
397 
398  //Total number of bytes that have been written
399  *written = n;
400 
401  //Successful processing
402  return NO_ERROR;
403 }
404 
405 
406 /**
407  * @brief Parse KeyShare extension
408  * @param[in] context Pointer to the TLS context
409  * @param[in] keyShareList Pointer to the KeyShare extension
410  * @param[in] groupList Pointer to the SupportedGroups extension
411  * @return Error code
412  **/
413 
415  const Tls13KeyShareList *keyShareList,
416  const TlsSupportedGroupList *groupList)
417 {
418 #if (TLS13_DHE_KE_SUPPORT == ENABLED || TLS13_PSK_DHE_KE_SUPPORT == ENABLED || \
419  TLS13_ECDHE_KE_SUPPORT == ENABLED || TLS13_PSK_ECDHE_KE_SUPPORT == ENABLED || \
420  TLS13_HYBRID_KE_SUPPORT == ENABLED || TLS13_PSK_HYBRID_KE_SUPPORT == ENABLED)
421  //KeyShare extension found?
422  if(keyShareList != NULL)
423  {
424  error_t error;
425  bool_t acceptable;
426  uint16_t namedGroup;
427  size_t n;
428  size_t length;
429  const uint8_t *p;
430  const Tls13KeyShareEntry *keyShareEntry;
431 
432  //Initialize variables
433  acceptable = FALSE;
434  keyShareEntry = NULL;
435 
436  //Point to the first KeyShareEntry of the list
437  p = keyShareList->value;
438  //Retrieve the length of the list
439  length = ntohs(keyShareList->length);
440 
441  //The extension contains a list of KeyShareEntry values offered by the
442  //client. The values are indicated in descending order of preference
443  while(length > 0 && !acceptable)
444  {
445  //Malformed extension?
446  if(length < sizeof(Tls13KeyShareEntry))
447  return ERROR_DECODING_FAILED;
448 
449  //Point to the current key share entry
450  keyShareEntry = (Tls13KeyShareEntry *) p;
451  //Retrieve the length of the key_exchange field
452  n = ntohs(keyShareEntry->length);
453 
454  //Malformed extension?
455  if(length < (sizeof(Tls13KeyShareEntry) + n))
456  return ERROR_DECODING_FAILED;
457 
458  //Each KeyShareEntry value must correspond to a group offered in the
459  //SupportedGroups extension (refer to RFC 8446, section 4.2.8)
460  if(!tls13IsGroupOffered(ntohs(keyShareEntry->group), groupList))
462 
463  //Initial or updated ClientHello?
464  if(context->state == TLS_STATE_CLIENT_HELLO)
465  {
466  //Check whether the ECDHE or FFDHE group is supported
467  acceptable = tls13IsGroupSupported(context,
468  ntohs(keyShareEntry->group));
469  }
470  else
471  {
472  //If the server has sent a HelloRetryRequest, the client needs
473  //to restart the handshake with an appropriate group
474  if(ntohs(keyShareEntry->group) == context->namedGroup)
475  {
476  //Check whether the ECDHE or FFDHE group is supported
477  acceptable = tls13IsGroupSupported(context,
478  ntohs(keyShareEntry->group));
479  }
480  }
481 
482  //Point to the next entry
483  p += sizeof(Tls13KeyShareEntry) + n;
484  //Remaining bytes to process
485  length -= sizeof(Tls13KeyShareEntry) + n;
486  }
487 
488  //Acceptable ECDHE or FFDHE group found?
489  if(acceptable)
490  {
491  //Convert the named group to host byte order
492  namedGroup = ntohs(keyShareEntry->group);
493 
494  //Finite field group?
495  if(tls13IsFfdheGroupSupported(context, namedGroup))
496  {
497  //Generate an ephemeral key pair
498  error = tls13GenerateKeyShare(context, namedGroup);
499  //Any error to report?
500  if(error)
501  return error;
502 
503  //Compute DHE shared secret
504  error = tls13GenerateSharedSecret(context,
505  keyShareEntry->keyExchange, ntohs(keyShareEntry->length));
506  //Any error to report?
507  if(error)
508  return error;
509 
510  //DHE key exchange mechanism provides forward secrecy
511  if(context->keyExchMethod == TLS13_KEY_EXCH_PSK)
512  {
513  context->keyExchMethod = TLS13_KEY_EXCH_PSK_DHE;
514  }
515  else
516  {
517  context->keyExchMethod = TLS13_KEY_EXCH_DHE;
518  }
519  }
520  //Elliptic curve group?
521  else if(tls13IsEcdheGroupSupported(context, namedGroup))
522  {
523  //Generate an ephemeral key pair
524  error = tls13GenerateKeyShare(context, namedGroup);
525  //Any error to report?
526  if(error)
527  return error;
528 
529  //Compute ECDHE shared secret
530  error = tls13GenerateSharedSecret(context,
531  keyShareEntry->keyExchange, ntohs(keyShareEntry->length));
532  //Any error to report?
533  if(error)
534  return error;
535 
536  //ECDHE key exchange mechanism provides forward secrecy
537  if(context->keyExchMethod == TLS13_KEY_EXCH_PSK)
538  {
539  context->keyExchMethod = TLS13_KEY_EXCH_PSK_ECDHE;
540  }
541  else
542  {
543  context->keyExchMethod = TLS13_KEY_EXCH_ECDHE;
544  }
545  }
546  //Hybrid key exchange method?
547  else if(tls13IsHybridKeMethodSupported(context, namedGroup))
548  {
549  //Encapsulation algorithm
550  error = tls13Encapsulate(context, namedGroup,
551  keyShareEntry->keyExchange, ntohs(keyShareEntry->length));
552  //Any error to report?
553  if(error)
554  return error;
555 
556  //Hybrid key exchange makes use of two key exchange algorithms
557  //based on different cryptographic assumptions
558  if(context->keyExchMethod == TLS13_KEY_EXCH_PSK)
559  {
560  context->keyExchMethod = TLS13_KEY_EXCH_PSK_HYBRID;
561  }
562  else
563  {
564  context->keyExchMethod = TLS13_KEY_EXCH_HYBRID;
565  }
566  }
567  //Unknown group?
568  else
569  {
570  //Just for sanity
571  return ERROR_FAILURE;
572  }
573  }
574  else
575  {
576  //If no common cryptographic parameters can be negotiated, the server
577  //must abort the handshake with an appropriate alert
578  if(context->state == TLS_STATE_CLIENT_HELLO_2)
579  return ERROR_HANDSHAKE_FAILED;
580  }
581  }
582 #endif
583 
584  //Successful processing
585  return NO_ERROR;
586 }
587 
588 
589 /**
590  * @brief Parse PskKeyExchangeModes extension
591  * @param[in] context Pointer to the TLS context
592  * @param[in] pskKeModeList Pointer to the PskKeyExchangeModes extension
593  * @return Error code
594  **/
595 
597  const Tls13PskKeModeList *pskKeModeList)
598 {
599  error_t error;
600  uint_t i;
601 
602  //PskKeyExchangeModes extension found?
603  if(pskKeModeList != NULL)
604  {
605  //Check whether the client supports session resumption with a PSK
606  for(i = 0; i < pskKeModeList->length; i++)
607  {
608  //PSK key establishment supported?
609  if(pskKeModeList->value[i] == TLS_PSK_KEY_EXCH_MODE_PSK_KE ||
610  pskKeModeList->value[i] == TLS_PSK_KEY_EXCH_MODE_PSK_DHE_KE)
611  {
612  context->pskKeModeSupported = TRUE;
613  }
614  }
615  }
616 
617  //PSK key exchange method?
618  if(context->keyExchMethod == TLS13_KEY_EXCH_PSK ||
619  context->keyExchMethod == TLS13_KEY_EXCH_PSK_DHE ||
620  context->keyExchMethod == TLS13_KEY_EXCH_PSK_ECDHE ||
621  context->keyExchMethod == TLS13_KEY_EXCH_PSK_HYBRID)
622  {
623  //PskKeyExchangeModes extension found?
624  if(pskKeModeList != NULL)
625  {
626  //Initialize status code
627  error = ERROR_HANDSHAKE_FAILED;
628 
629  //The extension contains a list of supported PSK key exchange modes
630  for(i = 0; i < pskKeModeList->length && error; i++)
631  {
632 #if (TLS13_PSK_KE_SUPPORT == ENABLED)
633  //PSK-only key establishment?
634  if(pskKeModeList->value[i] == TLS_PSK_KEY_EXCH_MODE_PSK_KE)
635  {
636  //Servers must not select a key exchange mode that is not listed
637  //by the client
638  if(context->keyExchMethod == TLS13_KEY_EXCH_PSK)
639  {
640  error = NO_ERROR;
641  }
642  }
643  else
644 #endif
645 #if (TLS13_PSK_DHE_KE_SUPPORT == ENABLED || TLS13_PSK_ECDHE_KE_SUPPORT == ENABLED || \
646  TLS13_PSK_HYBRID_KE_SUPPORT == ENABLED)
647  //PSK with (EC)DHE key establishment?
648  if(pskKeModeList->value[i] == TLS_PSK_KEY_EXCH_MODE_PSK_DHE_KE)
649  {
650  //Servers must not select a key exchange mode that is not listed
651  //by the client
652  if(context->keyExchMethod == TLS13_KEY_EXCH_PSK_DHE ||
653  context->keyExchMethod == TLS13_KEY_EXCH_PSK_ECDHE ||
654  context->keyExchMethod == TLS13_KEY_EXCH_PSK_HYBRID)
655  {
656  error = NO_ERROR;
657  }
658  }
659  else
660 #endif
661  //Unknown key exchange method?
662  {
663  //Just for sanity
664  }
665  }
666  }
667  else
668  {
669  //A client must provide a PskKeyExchangeModes extension if it offers a
670  //PreSharedKey extension
671  error = ERROR_MISSING_EXTENSION;
672  }
673  }
674  else
675  {
676  //If no acceptable PSKs are found, the server should perform a non-PSK
677  //handshake if possible
678  error = NO_ERROR;
679  }
680 
681  //Return status code
682  return error;
683 }
684 
685 
686 /**
687  * @brief Parse PreSharedKey extension
688  * @param[in] context Pointer to the TLS context
689  * @param[in] clientHello Pointer to the ClientHello message
690  * @param[in] clientHelloLen Length of the ClientHello message
691  * @param[in] identityList List of the identities that the client is willing
692  * to negotiate with the server
693  * @param[in] binderList List of HMAC values, one for each PSK offered in the
694  * PreSharedKey extension
695  * @return Error code
696  **/
697 
699  const TlsClientHello *clientHello, size_t clientHelloLen,
700  const Tls13PskIdentityList *identityList, const Tls13PskBinderList *binderList)
701 {
702  #if (TLS13_PSK_KE_SUPPORT == ENABLED || TLS13_PSK_DHE_KE_SUPPORT == ENABLED || \
703  TLS13_PSK_ECDHE_KE_SUPPORT == ENABLED || TLS13_PSK_HYBRID_KE_SUPPORT == ENABLED)
704  //PreSharedKey extension found?
705  if(identityList != NULL && binderList != NULL)
706  {
707  error_t error;
708  int_t i;
709  size_t n;
710  size_t m;
711  uint32_t obfuscatedTicketAge;
712  const uint8_t *p;
713  const uint8_t *q;
714  const Tls13PskIdentity *identity;
715  const Tls13PskBinder *binder;
716  const HashAlgo *hashAlgo;
717 
718  //Initialize variables
719  identity = NULL;
720  binder = NULL;
721 
722  //Reset the server's chosen identity to its default value
723  context->selectedIdentity = -1;
724 
725  //Debug message
726  TRACE_DEBUG("PSK identity list:\r\n");
727  TRACE_DEBUG_ARRAY(" ", identityList, ntohs(identityList->length) + 2);
728  TRACE_DEBUG("PSK binder list:\r\n");
729  TRACE_DEBUG_ARRAY(" ", binderList, ntohs(binderList->length) + 2);
730 
731  //Point to the list of the identities that the client is willing to
732  //negotiate with the server
733  p = identityList->value;
734  n = ntohs(identityList->length);
735 
736  //Point to the list of HMAC values, one for each PSK offered in the
737  //PreSharedKey extension
738  q = binderList->value;
739  m = ntohs(binderList->length);
740 
741  //Loop through the list of PSK identities
742  for(i = 0; n > 0; i++)
743  {
744  //Point to the current PskIdentity entry
745  identity = (Tls13PskIdentity *) p;
746 
747  //Malformed PreSharedKey extension?
748  if(n < sizeof(TlsPskIdentity))
749  return ERROR_DECODING_FAILED;
750  if(n < (sizeof(TlsPskIdentity) + ntohs(identity->length)))
751  return ERROR_DECODING_FAILED;
752 
753  //Debug message
754  TRACE_DEBUG("PSK identity #%u:\r\n", i);
755  TRACE_DEBUG_ARRAY(" ", identity->value, ntohs(identity->length));
756 
757  //Point to the obfuscated_ticket_age field
758  p += sizeof(TlsPskIdentity) + ntohs(identity->length);
759  n -= sizeof(TlsPskIdentity) + ntohs(identity->length);
760 
761  //Malformed PreSharedKey extension?
762  if(n < sizeof(uint32_t))
763  return ERROR_DECODING_FAILED;
764 
765  //The obfuscated_ticket_age field is a 32-bit unsigned integer
766  obfuscatedTicketAge = LOAD32BE(p);
767 
768  //Point to the next PskIdentity entry
769  p += sizeof(uint32_t);
770  n -= sizeof(uint32_t);
771 
772  //Point to the PskBinderEntry
773  binder = (Tls13PskBinder *) q;
774 
775  //If the binder is not present, the server must abort the handshake
776  if(context->selectedIdentity >= 0 && m == 0)
778 
779  //Malformed PreSharedKey extension?
780  if(m < sizeof(Tls13PskBinder))
781  return ERROR_DECODING_FAILED;
782  if(m < (sizeof(Tls13PskBinder) + binder->length))
783  return ERROR_DECODING_FAILED;
784 
785  //Debug message
786  TRACE_DEBUG("PSK binder #%u:\r\n", i);
787  TRACE_DEBUG_ARRAY(" ", binder->value, binder->length);
788 
789  //Point to the next PskBinderEntry
790  q += sizeof(Tls13PskBinder) + binder->length;
791  m -= sizeof(Tls13PskBinder) + binder->length;
792 
793  //The server should select a single PSK
794  if(context->selectedIdentity < 0)
795  {
796  //Any registered callback?
797  if(context->pskCallback != NULL)
798  {
799  //Check whether the PSK identity provided by the client matches
800  //any externally established PSK
801  error = context->pskCallback(context, identity->value,
802  ntohs(identity->length));
803 
804  //Valid PSK?
805  if(!error && tls13IsPskValid(context))
806  {
807  //For externally established PSKs, the hash algorithm must be
808  //set when the PSK is established
809  hashAlgo = tlsGetHashAlgo(context->pskHashAlgo);
810 
811  //Make sure the hash algorithm is valid
812  if(hashAlgo != NULL)
813  {
814  //Save the hash algorithm associated with the PSK
815  context->cipherSuite.prfHashAlgo = hashAlgo;
816 
817  //The server's chosen identity is expressed as a 0-based
818  //index into the identities in the client's list
819  context->selectedIdentity = i;
820  }
821  }
822  }
823  }
824 
825  //The server should select a single PSK
826  if(context->selectedIdentity < 0)
827  {
828  //Decrypt the received ticket and verify the ticket's validity
829  error = tls13VerifyTicket(context, identity->value,
830  htons(identity->length), obfuscatedTicketAge);
831 
832  //Valid ticket?
833  if(!error)
834  {
835  //The server's chosen identity is expressed as a 0-based index
836  //into the identities in the client's list
837  context->selectedIdentity = i;
838  }
839  }
840  }
841 
842  //Extra binders found?
843  if(m != 0)
844  {
846  }
847  }
848  else
849 #endif
850  {
851  //Initial or updated ClientHello?
852  if(context->state == TLS_STATE_CLIENT_HELLO_2)
853  {
854  //When responding to a HelloRetryRequest, the client must send the
855  //same ClientHello without modification
856  if(context->selectedIdentity >= 0)
857  {
859  }
860  }
861 
862  //The ClientHello message does not contain any PreSharedKey extension
863  context->selectedIdentity = -1;
864  }
865 
866  //Successful processing
867  return NO_ERROR;
868 }
869 
870 
871 /**
872  * @brief Parse EarlyData extension
873  * @param[in] context Pointer to the TLS context
874  * @param[in] earlyDataIndication Pointer to the EarlyData extension
875  * @return Error code
876  **/
877 
879  const TlsExtension *earlyDataIndication)
880 {
881  //EarlyData extension found?
882  if(earlyDataIndication != NULL)
883  {
884  //Early data is not permitted after a HelloRetryRequest (refer to
885  //RFC 8446, section 4.1.2)
886  if(context->state == TLS_STATE_CLIENT_HELLO_2)
887  {
888  context->earlyDataRejected = TRUE;
889  }
890 
891  //In order to accept early data, the server must have accepted a PSK
892  //cipher suite and selected the first key offered in the client's
893  //PreSharedKey extension (refer to RFC 8446, section 4.2.10)
894  if(context->selectedIdentity != 0)
895  {
896  context->earlyDataRejected = TRUE;
897  }
898 
899  //A valid EarlyData extension has been received
900  context->earlyDataExtReceived = TRUE;
901  }
902  else
903  {
904  //The ClientHello message does not contain any EarlyData extension
905  context->earlyDataExtReceived = FALSE;
906  }
907 
908  //Successful processing
909  return NO_ERROR;
910 }
911 
912 #endif
@ TLS13_KEY_EXCH_PSK
Definition: tls.h:1161
#define htons(value)
Definition: cpu_endian.h:413
TLS helper functions.
Tls13PskBinderList
Definition: tls13_misc.h:261
int bool_t
Definition: compiler_port.h:53
error_t tls13ParsePskKeModesExtension(TlsContext *context, const Tls13PskKeModeList *pskKeModeList)
Parse PskKeyExchangeModes extension.
error_t tls13VerifyTicket(TlsContext *context, const uint8_t *ticket, size_t length, uint32_t obfuscatedTicketAge)
Session ticket verification.
Definition: tls13_ticket.c:377
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
signed int int_t
Definition: compiler_port.h:49
#define LOAD32BE(p)
Definition: cpu_endian.h:210
@ ERROR_ILLEGAL_PARAMETER
Definition: error.h:243
@ TLS_EXT_SUPPORTED_VERSIONS
Definition: tls.h:1322
uint8_t p
Definition: ndp.h:300
#define TRUE
Definition: os_port.h:50
TLS 1.3 session tickets.
@ TLS_TRANSPORT_PROTOCOL_DATAGRAM
Definition: tls.h:957
TlsPskIdentity
Definition: tls.h:1695
TlsMessageType
Handshake message type.
Definition: tls.h:1039
@ ERROR_HANDSHAKE_FAILED
Definition: error.h:233
@ TLS13_KEY_EXCH_ECDHE
Definition: tls.h:1159
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
error_t kemEncapsulate(KemContext *context, const PrngAlgo *prngAlgo, void *prngContext, uint8_t *ct, uint8_t *ss)
Encapsulation algorithm.
Definition: kem.c:209
bool_t tls13IsHybridKeMethodSupported(TlsContext *context, uint16_t namedGroup)
Check whether a given hybrid key exchange method is supported.
Definition: tls13_misc.c:943
@ TLS_STATE_CLIENT_HELLO
Definition: tls.h:1456
@ TLS_PSK_KEY_EXCH_MODE_PSK_KE
Definition: tls13_misc.h:151
@ 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
#define TlsContext
Definition: tls.h:36
error_t
Error codes.
Definition: error.h:43
bool_t tls13IsGroupSupported(TlsContext *context, uint16_t namedGroup)
Check whether a given named group is supported.
Definition: tls13_misc.c:808
@ TLS_GROUP_NONE
Definition: tls.h:1370
Formatting and parsing of extensions (TLS 1.3 server)
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
#define STORE16BE(a, p)
Definition: cpu_endian.h:262
@ TLS_EXT_KEY_SHARE
Definition: tls.h:1329
error_t tls13FormatServerPreSharedKeyExtension(TlsContext *context, uint8_t *p, size_t *written)
Format PreSharedKey extension.
@ ERROR_MISSING_EXTENSION
Definition: error.h:244
@ TLS_TYPE_ENCRYPTED_EXTENSIONS
Definition: tls.h:1047
bool_t tls13IsFfdheGroupSupported(TlsContext *context, uint16_t namedGroup)
Check whether a given FFDHE group is supported.
Definition: tls13_misc.c:845
error_t tls13ParseClientEarlyDataExtension(TlsContext *context, const TlsExtension *earlyDataIndication)
Parse EarlyData extension.
Tls13PskBinder
Definition: tls13_misc.h:250
uint8_t length
Definition: tcp.h:368
error_t tls13FormatSelectedGroupExtension(TlsContext *context, uint8_t *p, size_t *written)
Format KeyShare extension (HelloRetryRequest message)
uint16_t dtlsTranslateVersion(uint16_t version)
Translate TLS version into DTLS version.
Definition: dtls_misc.c:112
error_t tls13FormatServerSupportedVersionsExtension(TlsContext *context, uint8_t *p, size_t *written)
Format SupportedVersions extension.
Helper functions for TLS 1.3 server.
Tls13KeyShareList
Definition: tls13_misc.h:206
#define ntohs(value)
Definition: cpu_endian.h:421
#define TRACE_DEBUG(...)
Definition: debug.h:107
@ TLS13_KEY_EXCH_PSK_ECDHE
Definition: tls.h:1163
@ TLS_STATE_CLIENT_HELLO_2
Definition: tls.h:1457
#define TRACE_DEBUG_ARRAY(p, a, n)
Definition: debug.h:108
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 tls13ParseClientKeyShareExtension(TlsContext *context, const Tls13KeyShareList *keyShareList, const TlsSupportedGroupList *groupList)
Parse KeyShare extension.
@ TLS13_KEY_EXCH_HYBRID
Definition: tls.h:1160
TlsClientHello
Definition: tls.h:1774
Tls13PskKeModeList
Definition: tls13_misc.h:217
error_t tls13FormatServerEarlyDataExtension(TlsContext *context, TlsMessageType msgType, uint8_t *p, size_t *written)
Format EarlyData extension.
@ TLS_EXT_PRE_SHARED_KEY
Definition: tls.h:1320
@ MPI_FORMAT_BIG_ENDIAN
Definition: mpi.h:71
TLS (Transport Layer Security)
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
error_t tls13FormatServerKeyShareExtension(TlsContext *context, uint8_t *p, size_t *written)
Format KeyShare extension (ServerHello message)
bool_t tls13IsGroupOffered(uint16_t namedGroup, const TlsSupportedGroupList *groupList)
Check whether a group is offered in the SupportedGroups extension.
error_t tls13Encapsulate(TlsContext *context, uint16_t namedGroup, const uint8_t *keyShare, size_t length)
Encapsulation algorithm.
Definition: tls13_misc.c:498
@ TLS_TYPE_NEW_SESSION_TICKET
Definition: tls.h:1044
Tls13PskIdentity
Definition: tls13_misc.h:228
@ ERROR_DECODING_FAILED
Definition: error.h:241
Tls13PskIdentityList
Definition: tls13_misc.h:239
unsigned int uint_t
Definition: compiler_port.h:50
TlsSupportedGroupList
Definition: tls.h:1651
#define STORE32BE(a, p)
Definition: cpu_endian.h:286
@ NO_ERROR
Success.
Definition: error.h:44
error_t tls13ParseClientPreSharedKeyExtension(TlsContext *context, const TlsClientHello *clientHello, size_t clientHelloLen, const Tls13PskIdentityList *identityList, const Tls13PskBinderList *binderList)
Parse PreSharedKey extension.
Debugging facilities.
uint_t mpiGetByteLength(const Mpi *a)
Get the actual length in bytes.
Definition: mpi.c:195