tls13_server_misc.c
Go to the documentation of this file.
1 /**
2  * @file tls13_server_misc.c
3  * @brief Helper functions for 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.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_server_misc.h"
37 #include "tls_transcript_hash.h"
38 #include "tls_ffdhe.h"
39 #include "tls_misc.h"
41 #include "tls13_server_misc.h"
42 #include "debug.h"
43 
44 //Check TLS library configuration
45 #if (TLS_SUPPORT == ENABLED && TLS_SERVER_SUPPORT == ENABLED && \
46  TLS_MAX_VERSION >= TLS_VERSION_1_3)
47 
48 
49 /**
50  * @brief Cipher suite and key exchange method negotiation
51  * @param[in] context Pointer to the TLS context
52  * @param[in] clientHello Pointer to the ClientHello message
53  * @param[in] clientHelloLen Length of the ClientHello message
54  * @param[in] cipherSuites List of cipher suites offered by the client
55  * @param[in] extensions ClientHello extensions offered by the client
56  * @return Error code
57  **/
58 
59 error_t tls13NegotiateCipherSuite(TlsContext *context, const void *clientHello,
60  size_t clientHelloLen, const TlsCipherSuites *cipherSuites,
62 {
63  error_t error;
64 
65  //In TLS 1.3, the cipher suite concept has been changed. The key exchange
66  //mechanism is negotiated separately from the cipher suite
67  context->keyExchMethod = TLS_KEY_EXCH_NONE;
68 
69  //The PreSharedKey extension is used to negotiate the identity of the
70  //pre-shared key to be used with a given handshake in association with
71  //PSK key establishment
72  error = tls13ParseClientPreSharedKeyExtension(context, clientHello,
73  clientHelloLen, extensions->identityList, extensions->binderList);
74  //Any error to report?
75  if(error)
76  return error;
77 
78  //Externally established PSKs should influence cipher suite selection
79  if(context->selectedIdentity >= 0)
80  {
81  //Select a cipher suite indicating a hash associated with the PSK
82  error = tlsNegotiateCipherSuite(context, context->cipherSuite.prfHashAlgo,
83  cipherSuites, extensions);
84 
85  //The server must ensure that it selects a compatible PSK and cipher suite
86  if(!error)
87  {
88  //Perform PSK handshake
89  context->keyExchMethod = TLS13_KEY_EXCH_PSK;
90  }
91  else
92  {
93  //Perform a non-PSK handshake if possible
94  context->keyExchMethod = TLS_KEY_EXCH_NONE;
95  context->selectedIdentity = -1;
96  }
97  }
98 
99  //Check key exchange method
100  if(context->keyExchMethod == TLS_KEY_EXCH_NONE)
101  {
102  //Perform cipher suite negotiation
103  error = tlsNegotiateCipherSuite(context, NULL, cipherSuites, extensions);
104  //If no acceptable choices are presented, terminate the handshake
105  if(error)
106  return ERROR_HANDSHAKE_FAILED;
107  }
108 
109  //If the handshake includes a HelloRetryRequest, the initial ClientHello
110  //and HelloRetryRequest are included in the transcript along with the new
111  //ClientHello
112  if(context->state != TLS_STATE_CLIENT_HELLO_2)
113  {
114  //Initialize handshake message hashing
115  error = tlsInitTranscriptHash(context);
116  //Any error to report?
117  if(error)
118  return error;
119  }
120 
121  //If the client opts to send 0-RTT data, it must supply an EarlyData
122  //extension in its ClientHello
123  error = tls13ParseClientEarlyDataExtension(context,
124  extensions->earlyDataIndication);
125  //Any error to report?
126  if(error)
127  return error;
128 
129  //The KeyShare extension contains the client's cryptographic parameters
130  error = tls13ParseClientKeyShareExtension(context, extensions->keyShareList,
131  extensions->supportedGroupList);
132  //Any error to report?
133  if(error)
134  return error;
135 
136  //Incorrect (EC)DHE share?
137  if(extensions->keyShareList != NULL && context->namedGroup == TLS_GROUP_NONE)
138  {
139  //Select an appropriate ECDHE or FFDHE group
140  error = tls13SelectGroup(context, extensions->supportedGroupList);
141  //Any error to report?
142  if(error)
143  return error;
144 
145  //The server corrects the mismatch with a HelloRetryRequest
147  }
148  else
149  {
150  //Check key exchange method
151  if(context->keyExchMethod == TLS13_KEY_EXCH_DHE ||
152  context->keyExchMethod == TLS13_KEY_EXCH_ECDHE)
153  {
154  //Check whether the client supports session resumption with a PSK
155  error = tls13ParsePskKeModesExtension(context,
156  extensions->pskKeModeList);
157  //Any error to report?
158  if(error)
159  return error;
160  }
161  else if(context->keyExchMethod == TLS13_KEY_EXCH_PSK ||
162  context->keyExchMethod == TLS13_KEY_EXCH_PSK_DHE ||
163  context->keyExchMethod == TLS13_KEY_EXCH_PSK_ECDHE)
164  {
165  //Servers must not select a key exchange mode that is not listed by
166  //the client in the PskKeyExchangeModes extension
167  error = tls13ParsePskKeModesExtension(context,
168  extensions->pskKeModeList);
169  //Any error to report?
170  if(error)
171  return error;
172 
173  //Prior to accepting PSK key establishment, the server must validate
174  //the corresponding binder value
175  error = tls13VerifyPskBinder(context, clientHello, clientHelloLen,
176  extensions->identityList, extensions->binderList,
177  context->selectedIdentity);
178  //If this value does not validate, the server must abort the handshake
179  if(error)
180  return error;
181  }
182  else
183  {
184  //If no common cryptographic parameters can be negotiated, the server
185  //must abort the handshake with an appropriate alert
186  return ERROR_HANDSHAKE_FAILED;
187  }
188  }
189 
190  //Successful processing
191  return NO_ERROR;
192 }
193 
194 
195 /**
196  * @brief Select the group to be used when performing (EC)DHE key exchange
197  * @param[in] context Pointer to the TLS context
198  * @param[in] groupList List of named groups supported by the client
199  * @return Error code
200  **/
201 
203  const TlsSupportedGroupList *groupList)
204 {
205  error_t error;
206 
207  //Initialize status code
208  error = ERROR_HANDSHAKE_FAILED;
209 
210  //Reset the named group to its default value
211  context->namedGroup = TLS_GROUP_NONE;
212 
213 #if (TLS13_DHE_KE_SUPPORT == ENABLED || TLS13_PSK_DHE_KE_SUPPORT == ENABLED || \
214  TLS13_ECDHE_KE_SUPPORT == ENABLED || TLS13_PSK_ECDHE_KE_SUPPORT == ENABLED)
215  //Valid SupportedGroups extension?
216  if(groupList != NULL)
217  {
218  uint_t i;
219  uint_t n;
220  uint16_t namedGroup;
221 
222  //Any preferred ECDHE or FFDHE groups?
223  if(context->numSupportedGroups > 0)
224  {
225  //Loop through the list of allowed groups (most preferred first)
226  for(i = 0; i < context->numSupportedGroups && error; i++)
227  {
228  //Get current named group
229  namedGroup = context->supportedGroups[i];
230 
231  //The named group to be used when performing (EC)DHE key exchange
232  //must be one of those present in the SupportedGroups extension
233  if(tls13IsGroupOffered(namedGroup, groupList))
234  {
235  //Check whether the ECDHE or FFDHE group is supported
236  if(tls13IsGroupSupported(context, namedGroup))
237  {
238  //Save the named group
239  context->namedGroup = namedGroup;
240  error = NO_ERROR;
241  }
242  }
243  }
244  }
245  else
246  {
247  //Get the number of named groups present in the list
248  n = ntohs(groupList->length) / sizeof(uint16_t);
249 
250  //The named group to be used when performing (EC)DHE key exchange must
251  //be one of those present in the SupportedGroups extension
252  for(i = 0; i < n && error; i++)
253  {
254  //Convert the named group to host byte order
255  namedGroup = ntohs(groupList->value[i]);
256 
257  //Check whether the ECDHE or FFDHE group is supported
258  if(tls13IsGroupSupported(context, namedGroup))
259  {
260  //Save the named group
261  context->namedGroup = namedGroup;
262  error = NO_ERROR;
263  }
264  }
265  }
266  }
267 #endif
268 
269  //Return status code
270  return error;
271 }
272 
273 
274 /**
275  * @brief Check whether a group is offered in the SupportedGroups extension
276  * @param[in] namedGroup Named group
277  * @param[in] groupList List of named groups supported by the client
278  * @return TRUE if the group is offered in the SupportedGroups extension,
279  * else FALSE
280  **/
281 
282 bool_t tls13IsGroupOffered(uint16_t namedGroup,
283  const TlsSupportedGroupList *groupList)
284 {
285  uint_t i;
286  uint_t n;
287  bool_t found;
288 
289  //Initialize flag
290  found = FALSE;
291 
292  //Valid SupportedGroups extension?
293  if(groupList != NULL)
294  {
295  //Get the number of named groups present in the list
296  n = ntohs(groupList->length) / sizeof(uint16_t);
297 
298  //Loop through the list of named groups the client supports
299  for(i = 0; i < n && !found; i++)
300  {
301  //Matching group?
302  if(ntohs(groupList->value[i]) == namedGroup)
303  {
304  found = TRUE;
305  }
306  }
307  }
308 
309  //Return TRUE if the group is offered in the SupportedGroups extension
310  return found;
311 }
312 
313 
314 /**
315  * @brief Verify PSK binder value
316  * @param[in] context Pointer to the TLS context
317  * @param[in] clientHello Pointer to the ClientHello message
318  * @param[in] clientHelloLen Length of the ClientHello message
319  * @param[in] identityList List of the identities that the client is willing
320  * to negotiate with the server
321  * @param[in] binderList List of HMAC values, one for each PSK offered in the
322  * PreSharedKey extension
323  * @param[in] selectedIdentity Selected PSK identity
324  * @return Error code
325  **/
326 
327 error_t tls13VerifyPskBinder(TlsContext *context, const void *clientHello,
328  size_t clientHelloLen, const Tls13PskIdentityList *identityList,
329  const Tls13PskBinderList *binderList, int_t selectedIdentity)
330 {
331 #if (TLS13_PSK_KE_SUPPORT == ENABLED || TLS13_PSK_DHE_KE_SUPPORT == ENABLED || \
332  TLS13_PSK_ECDHE_KE_SUPPORT == ENABLED)
333  error_t error;
334  int_t i;
335  size_t n;
336  const uint8_t *p;
337  const Tls13PskIdentity *identity;
338  const Tls13PskBinder *binder;
339  uint8_t calculatedBinder[TLS_MAX_HKDF_DIGEST_SIZE];
340 
341  //Initialize variables
342  identity = NULL;
343  binder = NULL;
344 
345  //Make sure the PreSharedKey extension is valid
346  if(identityList == NULL || binderList == NULL)
347  return ERROR_FAILURE;
348 
349  //Make sure the selected identity is valid
350  if(selectedIdentity < 0)
351  return ERROR_FAILURE;
352 
353  //Point to the list of the identities that the client is willing to
354  //negotiate with the server
355  p = identityList->value;
356  n = ntohs(identityList->length);
357 
358  //Loop through the list of PSK identities
359  for(i = 0; i <= selectedIdentity && n > 0; i++)
360  {
361  //Point to the current PskIdentity entry
362  identity = (Tls13PskIdentity *) p;
363 
364  //Malformed PreSharedKey extension?
365  if(n < sizeof(TlsPskIdentity))
366  return ERROR_DECODING_FAILED;
367  if(n < (sizeof(TlsPskIdentity) + ntohs(identity->length)))
368  return ERROR_DECODING_FAILED;
369 
370  //Point to the obfuscated_ticket_age field
371  p += sizeof(TlsPskIdentity) + ntohs(identity->length);
372  n -= sizeof(TlsPskIdentity) + ntohs(identity->length);
373 
374  //The obfuscated_ticket_age field is a 32-bit unsigned integer
375  if(n < sizeof(uint32_t))
376  return ERROR_DECODING_FAILED;
377 
378  //Point to the next PskIdentity entry
379  p += sizeof(uint32_t);
380  n -= sizeof(uint32_t);
381  }
382 
383  //Make sure the selected identity is within the range supplied by the client
384  if(selectedIdentity >= i)
385  return ERROR_FAILURE;
386 
387  //Point to the list of HMAC values, one for each PSK offered in the
388  //PreSharedKey extension
389  p = binderList->value;
390  n = ntohs(binderList->length);
391 
392  //Loop through the list of PSK binders
393  for(i = 0; i <= selectedIdentity && n > 0; i++)
394  {
395  //Point to the PskBinderEntry
396  binder = (Tls13PskBinder *) p;
397 
398  //Malformed PreSharedKey extension?
399  if(n < sizeof(Tls13PskBinder))
400  return ERROR_DECODING_FAILED;
401  if(n < (sizeof(Tls13PskBinder) + binder->length))
402  return ERROR_DECODING_FAILED;
403 
404  //Point to the next PskBinderEntry
405  p += sizeof(Tls13PskBinder) + binder->length;
406  n -= sizeof(Tls13PskBinder) + binder->length;
407  }
408 
409  //Make sure the selected identity is within the range supplied by the client
410  if(selectedIdentity >= i)
411  return ERROR_FAILURE;
412 
413  //Check the length of the PSK binder
414  if(binder->length > TLS_MAX_HKDF_DIGEST_SIZE)
416 
417  //The PSK binder is computed as an HMAC over a transcript hash containing
418  //a partial ClientHello up to the binders list itself
419  n = (uint8_t *) binderList - (uint8_t *) clientHello;
420 
421  //Compute PSK binder value
422  error = tls13ComputePskBinder(context, clientHello, clientHelloLen,
423  n, identity, calculatedBinder, binder->length);
424  //Any error to report?
425  if(error)
427 
428  //Debug message
429  TRACE_DEBUG("PSK binder:\r\n");
430  TRACE_DEBUG_ARRAY(" ", binder->value, binder->length);
431  TRACE_DEBUG("Calculated PSK binder:\r\n");
432  TRACE_DEBUG_ARRAY(" ", calculatedBinder, binder->length);
433 
434  //Prior to accepting PSK key establishment, the server must validate the
435  //corresponding binder value
436  if(osMemcmp(calculatedBinder, binder->value, binder->length))
437  {
438  //If this value does not validate, the server must abort the handshake
440  }
441 
442  //Successful verification
443  return NO_ERROR;
444 #else
445  //Not implemented
446  return ERROR_NOT_IMPLEMENTED;
447 #endif
448 }
449 
450 
451 /**
452  * @brief Process early data
453  * @param[in] context Pointer to the TLS context
454  * @param[in] data Pointer to the early data
455  * @param[in] length Length of the early data, in bytes
456  * @return Error code
457  **/
458 
459 error_t tls13ProcessEarlyData(TlsContext *context, const uint8_t *data,
460  size_t length)
461 {
462  //Check TLS version
463  if(context->version != TLS_VERSION_1_3)
465 
466  //Check current state
467  if(context->state != TLS_STATE_CLIENT_HELLO_2)
469 
470  //If the client opts to send 0-RTT data, it must supply an EarlyData
471  //extension in its ClientHello (refer to RFC 8446, section 4.2.10)
472  if(!context->earlyDataExtReceived)
474 
475  //Amount of 0-RTT data received by the server
476  context->earlyDataLen += length;
477 
478  //Discard records which fail deprotection (up to the configured
479  //max_early_data_size)
480  if(context->earlyDataLen > context->maxEarlyDataSize)
481  return ERROR_BAD_RECORD_MAC;
482 
483  //Debug message
484  TRACE_INFO("Discarding early data (%" PRIuSIZE " bytes)...\r\n", length);
485 
486  //The server may opt to reject early data
487  return NO_ERROR;
488 }
489 
490 #endif
signed int int_t
Definition: compiler_port.h:49
unsigned int uint_t
Definition: compiler_port.h:50
#define PRIuSIZE
int bool_t
Definition: compiler_port.h:53
#define ntohs(value)
Definition: cpu_endian.h:421
Debugging facilities.
#define TRACE_DEBUG_ARRAY(p, a, n)
Definition: debug.h:108
#define TRACE_DEBUG(...)
Definition: debug.h:107
#define TRACE_INFO(...)
Definition: debug.h:95
uint8_t n
error_t
Error codes.
Definition: error.h:43
@ ERROR_DECRYPTION_FAILED
Definition: error.h:241
@ ERROR_BAD_RECORD_MAC
Definition: error.h:230
@ ERROR_HANDSHAKE_FAILED
Definition: error.h:232
@ ERROR_DECODING_FAILED
Definition: error.h:240
@ ERROR_NOT_IMPLEMENTED
Definition: error.h:66
@ NO_ERROR
Success.
Definition: error.h:44
@ ERROR_FAILURE
Generic error code.
Definition: error.h:45
@ ERROR_UNEXPECTED_MESSAGE
Definition: error.h:194
uint8_t data[]
Definition: ethernet.h:222
uint8_t p
Definition: ndp.h:300
#define osMemcmp(p1, p2, length)
Definition: os_port.h:153
#define TRUE
Definition: os_port.h:50
#define FALSE
Definition: os_port.h:46
Hello extensions.
Definition: tls.h:2081
uint8_t length
Definition: tcp.h:368
error_t tls13ComputePskBinder(TlsContext *context, const void *clientHello, size_t clientHelloLen, size_t truncatedClientHelloLen, const Tls13PskIdentity *identity, uint8_t *binder, size_t binderLen)
Compute PSK binder value.
Definition: tls13_misc.c:86
bool_t tls13IsGroupSupported(TlsContext *context, uint16_t namedGroup)
Check whether a given named group is supported.
Definition: tls13_misc.c:576
Tls13PskBinderList
Definition: tls13_misc.h:247
uint8_t extensions[]
Definition: tls13_misc.h:300
Tls13PskIdentityList
Definition: tls13_misc.h:225
Tls13PskBinder
Definition: tls13_misc.h:236
Tls13PskIdentity
Definition: tls13_misc.h:214
error_t tls13ParseClientPreSharedKeyExtension(TlsContext *context, const TlsClientHello *clientHello, size_t clientHelloLen, const Tls13PskIdentityList *identityList, const Tls13PskBinderList *binderList)
Parse PreSharedKey extension.
error_t tls13ParseClientEarlyDataExtension(TlsContext *context, const TlsExtension *earlyDataIndication)
Parse EarlyData extension.
error_t tls13ParseClientKeyShareExtension(TlsContext *context, const Tls13KeyShareList *keyShareList, const TlsSupportedGroupList *groupList)
Parse KeyShare extension.
error_t tls13ParsePskKeModesExtension(TlsContext *context, const Tls13PskKeModeList *pskKeModeList)
Parse PskKeyExchangeModes extension.
Formatting and parsing of extensions (TLS 1.3 server)
error_t tls13ProcessEarlyData(TlsContext *context, const uint8_t *data, size_t length)
Process early data.
error_t tls13SelectGroup(TlsContext *context, const TlsSupportedGroupList *groupList)
Select the group to be used when performing (EC)DHE key exchange.
error_t tls13NegotiateCipherSuite(TlsContext *context, const void *clientHello, size_t clientHelloLen, const TlsCipherSuites *cipherSuites, TlsHelloExtensions *extensions)
Cipher suite and key exchange method negotiation.
error_t tls13VerifyPskBinder(TlsContext *context, const void *clientHello, size_t clientHelloLen, const Tls13PskIdentityList *identityList, const Tls13PskBinderList *binderList, int_t selectedIdentity)
Verify PSK binder value.
bool_t tls13IsGroupOffered(uint16_t namedGroup, const TlsSupportedGroupList *groupList)
Check whether a group is offered in the SupportedGroups extension.
Helper functions for TLS 1.3 server.
TLS (Transport Layer Security)
@ TLS_STATE_CLIENT_HELLO_2
Definition: tls.h:1440
@ TLS_STATE_HELLO_RETRY_REQUEST
Definition: tls.h:1443
@ 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
TlsCipherSuites
Definition: tls.h:1500
TlsPskIdentity
Definition: tls.h:1678
#define TLS_MAX_HKDF_DIGEST_SIZE
Definition: tls.h:906
TlsSupportedGroupList
Definition: tls.h:1634
#define TLS_VERSION_1_3
Definition: tls.h:97
#define TlsContext
Definition: tls.h:36
@ TLS_GROUP_NONE
Definition: tls.h:1353
FFDHE key exchange.
void tlsChangeState(TlsContext *context, TlsState newState)
Update TLS state.
Definition: tls_misc.c:54
TLS helper functions.
error_t tlsNegotiateCipherSuite(TlsContext *context, const HashAlgo *hashAlgo, const TlsCipherSuites *cipherSuites, TlsHelloExtensions *extensions)
Cipher suite negotiation.
Helper functions for TLS server.
error_t tlsInitTranscriptHash(TlsContext *context)
Initialize handshake message hashing.
Transcript hash calculation.