tls_client_misc.c
Go to the documentation of this file.
1 /**
2  * @file tls_client_misc.c
3  * @brief Helper functions for TLS client
4  *
5  * @section License
6  *
7  * SPDX-License-Identifier: GPL-2.0-or-later
8  *
9  * Copyright (C) 2010-2025 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.5.2
29  **/
30 
31 //Switch to the appropriate trace level
32 #define TRACE_LEVEL TLS_TRACE_LEVEL
33 
34 //Dependencies
35 #include "tls.h"
36 #include "tls_cipher_suites.h"
37 #include "tls_client.h"
38 #include "tls_client_misc.h"
39 #include "tls_common.h"
40 #include "tls_extensions.h"
41 #include "tls_sign_verify.h"
42 #include "tls_sign_misc.h"
43 #include "tls_cache.h"
44 #include "tls_ffdhe.h"
45 #include "tls_record.h"
46 #include "tls_misc.h"
47 #include "debug.h"
48 
49 //Check TLS library configuration
50 #if (TLS_SUPPORT == ENABLED && TLS_CLIENT_SUPPORT == ENABLED)
51 
52 
53 /**
54  * @brief Format initial ClientHello message
55  * @param[in] context Pointer to the TLS context
56  * @return Error code
57  **/
58 
60 {
61  error_t error;
62  size_t length;
63  TlsRecord *record;
65 
66  //Point to the buffer where to format the TLS record
67  record = (TlsRecord *) context->txBuffer;
68  //Point to the buffer where to format the handshake message
69  message = (TlsHandshake *) record->data;
70 
71  //Format ClientHello message
72  error = tlsFormatClientHello(context, (TlsClientHello *) message->data,
73  &length);
74 
75  //Check status code
76  if(!error)
77  {
78  //Set the type of the handshake message
79  message->msgType = TLS_TYPE_CLIENT_HELLO;
80  //Fix the length of the handshake message
81  STORE24BE(length, message->length);
82 
83  //Total length of the handshake message
84  length += sizeof(TlsHandshake);
85 
86  //Fix the length of the TLS record
87  record->length = htons(length);
88  }
89 
90  //Return status code
91  return error;
92 }
93 
94 
95 /**
96  * @brief Format session ID
97  * @param[in] context Pointer to the TLS context
98  * @param[in] p Output stream where to write session ID
99  * @param[out] written Total number of bytes that have been written
100  * @return Error code
101  **/
102 
104  size_t *written)
105 {
106  size_t n;
107 
108  //TLS 1.3 supported by the client?
109  if(context->versionMax >= TLS_VERSION_1_3 &&
110  (context->transportProtocol == TLS_TRANSPORT_PROTOCOL_STREAM ||
111  context->transportProtocol == TLS_TRANSPORT_PROTOCOL_EAP))
112  {
113  //A client which has a cached session ID set by a pre-TLS 1.3 server
114  //should set this field to that value
115  osMemcpy(p, context->sessionId, context->sessionIdLen);
116  n = context->sessionIdLen;
117  }
118  else
119  {
120 #if (TLS_SESSION_RESUME_SUPPORT == ENABLED)
121  //The session ID value identifies a session the client wishes to reuse
122  //for this connection
123  osMemcpy(p, context->sessionId, context->sessionIdLen);
124  n = context->sessionIdLen;
125 #else
126  //Session resumption is not supported
127  n = 0;
128 #endif
129  }
130 
131 #if (TLS_SECURE_RENEGOTIATION_SUPPORT == ENABLED)
132  //Secure renegotiation?
133  if(context->secureRenegoEnabled && context->secureRenegoFlag)
134  {
135  //Do not offer a session ID when renegotiating
136  n = 0;
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 the list of cipher suites supported by the client
150  * @param[in] context Pointer to the TLS context
151  * @param[in] p Output stream where to write the list of cipher suites
152  * @param[out] written Total number of bytes that have been written
153  * @return Error code
154  **/
155 
157  size_t *written)
158 {
159  uint_t i;
160  uint_t j;
161  uint_t k;
162  uint_t n;
163  uint16_t identifier;
164  TlsCipherSuites *cipherSuites;
165 
166  //Types of cipher suites proposed by the client
167  context->cipherSuiteTypes = TLS_CIPHER_SUITE_TYPE_UNKNOWN;
168 
169  //Point to the list of cryptographic algorithms supported by the client
170  cipherSuites = (TlsCipherSuites *) p;
171  //Number of cipher suites in the array
172  n = 0;
173 
174  //Determine the number of supported cipher suites
176 
177  //Debug message
178  TRACE_DEBUG("Cipher suites:\r\n");
179 
180  //Any preferred cipher suites?
181  if(context->numCipherSuites > 0)
182  {
183  //Loop through the list of preferred cipher suites
184  for(i = 0; i < context->numCipherSuites; i++)
185  {
186  //Loop through the list of supported cipher suites
187  for(j = 0; j < k; j++)
188  {
189  //Retrieve cipher suite identifier
191 
192  //Supported cipher suite?
193  if(identifier == context->cipherSuites[i])
194  {
195  //Check whether the cipher suite can be negotiated with the
196  //current protocol version
198  context->versionMin, context->versionMax,
199  context->transportProtocol))
200  {
201  //Copy cipher suite identifier
202  cipherSuites->value[n++] = htons(identifier);
203 
204  //Debug message
205  TRACE_DEBUG(" 0x%04" PRIX16 " (%s)\r\n", identifier,
207 
208  //Check whether the identifier matches an ECC or FFDHE cipher
209  //suite
210  context->cipherSuiteTypes |= tlsGetCipherSuiteType(identifier);
211  }
212  }
213  }
214  }
215  }
216  else
217  {
218  //Loop through the list of supported cipher suites
219  for(j = 0; j < k; j++)
220  {
221  //Retrieve cipher suite identifier
223 
224  //Check whether the cipher suite can be negotiated with the
225  //current protocol version
227  context->versionMin, context->versionMax,
228  context->transportProtocol))
229  {
230  //Copy cipher suite identifier
231  cipherSuites->value[n++] = htons(identifier);
232 
233  //Debug message
234  TRACE_DEBUG(" 0x%04" PRIX16 " (%s)\r\n", identifier,
236 
237  //Check whether the identifier matches an ECC or FFDHE cipher
238  //suite
239  context->cipherSuiteTypes |= tlsGetCipherSuiteType(identifier);
240  }
241  }
242  }
243 
244 #if (TLS_SECURE_RENEGOTIATION_SUPPORT == ENABLED)
245  //Check whether secure renegotiation is enabled
246  if(context->secureRenegoEnabled)
247  {
248  //Initial handshake?
249  if(context->clientVerifyDataLen == 0)
250  {
251  //The client includes the TLS_EMPTY_RENEGOTIATION_INFO_SCSV signaling
252  //cipher suite value in its ClientHello
253  cipherSuites->value[n++] = HTONS(TLS_EMPTY_RENEGOTIATION_INFO_SCSV);
254  }
255  }
256 #endif
257 
258 #if (TLS_FALLBACK_SCSV_SUPPORT == ENABLED)
259  //Check whether support for FALLBACK_SCSV is enabled
260  if(context->fallbackScsvEnabled)
261  {
262  //The TLS_FALLBACK_SCSV cipher suite value is meant for use by clients
263  //that repeat a connection attempt with a downgraded protocol
264  if(context->versionMax != TLS_MAX_VERSION)
265  {
266  //The client should put TLS_FALLBACK_SCSV after all cipher suites
267  //that it actually intends to negotiate
268  cipherSuites->value[n++] = HTONS(TLS_FALLBACK_SCSV);
269  }
270  }
271 #endif
272 
273  //Length of the array, in bytes
274  cipherSuites->length = htons(n * 2);
275 
276  //Total number of bytes that have been written
277  *written = sizeof(TlsCipherSuites) + n * 2;
278 
279  //Successful processing
280  return NO_ERROR;
281 }
282 
283 
284 /**
285  * @brief Format the list of compression methods supported by the client
286  * @param[in] context Pointer to the TLS context
287  * @param[in] p Output stream where to write the list of compression methods
288  * @param[out] written Total number of bytes that have been written
289  * @return Error code
290  **/
291 
293  size_t *written)
294 {
295  TlsCompressMethods *compressMethods;
296 
297  //List of compression algorithms supported by the client
298  compressMethods = (TlsCompressMethods *) p;
299 
300  //The CRIME exploit takes advantage of TLS compression, so conservative
301  //implementations do not enable compression at the TLS level
302  compressMethods->length = 1;
303  compressMethods->value[0] = TLS_COMPRESSION_METHOD_NULL;
304 
305  //Total number of bytes that have been written
306  *written = sizeof(TlsCompressMethods) + compressMethods->length;
307 
308  //Successful processing
309  return NO_ERROR;
310 }
311 
312 
313 /**
314  * @brief Format PSK identity
315  * @param[in] context Pointer to the TLS context
316  * @param[in] p Output stream where to write the PSK identity hint
317  * @param[out] written Total number of bytes that have been written
318  * @return Error code
319  **/
320 
322  size_t *written)
323 {
324  size_t n;
325  TlsPskIdentity *pskIdentity;
326 
327  //Point to the PSK identity
328  pskIdentity = (TlsPskIdentity *) p;
329 
330 #if (TLS_PSK_KE_SUPPORT == ENABLED || TLS_RSA_PSK_KE_SUPPORT == ENABLED || \
331  TLS_DHE_PSK_KE_SUPPORT == ENABLED || TLS_ECDHE_PSK_KE_SUPPORT == ENABLED)
332  //Any PSK identity defined?
333  if(context->pskIdentity != NULL)
334  {
335  //Determine the length of the PSK identity
336  n = osStrlen(context->pskIdentity);
337  //Copy PSK identity
338  osMemcpy(pskIdentity->value, context->pskIdentity, n);
339  }
340  else
341 #endif
342  {
343  //No PSK identity is provided
344  n = 0;
345  }
346 
347  //The PSK identity is preceded by a 2-byte length field
348  pskIdentity->length = htons(n);
349 
350  //Total number of bytes that have been written
351  *written = sizeof(TlsPskIdentity) + n;
352 
353  //Successful processing
354  return NO_ERROR;
355 }
356 
357 
358 /**
359  * @brief Format client's key exchange parameters
360  * @param[in] context Pointer to the TLS context
361  * @param[in] p Output stream where to write the client's key exchange parameters
362  * @param[out] written Total number of bytes that have been written
363  * @return Error code
364  **/
365 
366 __weak_func error_t tlsFormatClientKeyParams(TlsContext *context, uint8_t *p,
367  size_t *written)
368 {
369 #if (TLS_MAX_VERSION >= TLS_VERSION_1_0 && TLS_MIN_VERSION <= TLS_VERSION_1_2)
370  error_t error;
371  size_t n;
372 
373 #if (TLS_RSA_KE_SUPPORT == ENABLED || TLS_RSA_PSK_KE_SUPPORT == ENABLED)
374  //RSA key exchange method?
375  if(context->keyExchMethod == TLS_KEY_EXCH_RSA ||
376  context->keyExchMethod == TLS_KEY_EXCH_RSA_PSK)
377  {
378  //If RSA is being used for key agreement and authentication, the
379  //client generates a 48-byte premaster secret
380  context->premasterSecretLen = 48;
381 
382  //The first 2 bytes code the latest version supported by the client
383  STORE16BE(context->clientVersion, context->premasterSecret);
384 
385  //The last 46 bytes contain securely-generated random bytes
386  error = context->prngAlgo->read(context->prngContext,
387  context->premasterSecret + 2, 46);
388  //Any error to report?
389  if(error)
390  return error;
391 
392  //Encrypt the premaster secret using the server public key
393  error = rsaesPkcs1v15Encrypt(context->prngAlgo, context->prngContext,
394  &context->peerRsaPublicKey, context->premasterSecret, 48, p + 2, &n);
395  //RSA encryption failed?
396  if(error)
397  return error;
398 
399  //The RSA-encrypted premaster secret in a ClientKeyExchange is preceded by
400  //two length bytes
401  STORE16BE(n, p);
402 
403  //Total number of bytes that have been written
404  *written = n + 2;
405  }
406  else
407 #endif
408 #if (TLS_DH_ANON_KE_SUPPORT == ENABLED || TLS_DHE_RSA_KE_SUPPORT == ENABLED || \
409  TLS_DHE_DSS_KE_SUPPORT == ENABLED || TLS_DHE_PSK_KE_SUPPORT == ENABLED)
410  //Diffie-Hellman key exchange method?
411  if(context->keyExchMethod == TLS_KEY_EXCH_DH_ANON ||
412  context->keyExchMethod == TLS_KEY_EXCH_DHE_RSA ||
413  context->keyExchMethod == TLS_KEY_EXCH_DHE_DSS ||
414  context->keyExchMethod == TLS_KEY_EXCH_DHE_PSK)
415  {
416  //Generate an ephemeral key pair
417  error = dhGenerateKeyPair(&context->dhContext,
418  context->prngAlgo, context->prngContext);
419  //Any error to report?
420  if(error)
421  return error;
422 
423  //Encode the client's public value to an opaque vector
424  error = tlsWriteMpi(&context->dhContext.ya, p, &n);
425  //Any error to report?
426  if(error)
427  return error;
428 
429  //Total number of bytes that have been written
430  *written = n;
431 
432  //Calculate the negotiated key Z
433  error = dhComputeSharedSecret(&context->dhContext,
434  context->premasterSecret, TLS_PREMASTER_SECRET_SIZE,
435  &context->premasterSecretLen);
436  //Any error to report?
437  if(error)
438  return error;
439 
440  //Leading bytes of Z that contain all zero bits are stripped before
441  //it is used as the premaster secret (RFC 4346, section 8.2.1)
442  for(n = 0; n < context->premasterSecretLen; n++)
443  {
444  if(context->premasterSecret[n] != 0x00)
445  break;
446  }
447 
448  //Any leading zero bytes?
449  if(n > 0)
450  {
451  //Strip leading zero bytes from the negotiated key
452  osMemmove(context->premasterSecret, context->premasterSecret + n,
453  context->premasterSecretLen - n);
454 
455  //Adjust the length of the premaster secret
456  context->premasterSecretLen -= n;
457  }
458  }
459  else
460 #endif
461 #if (TLS_ECDH_ANON_KE_SUPPORT == ENABLED || TLS_ECDHE_RSA_KE_SUPPORT == ENABLED || \
462  TLS_ECDHE_ECDSA_KE_SUPPORT == ENABLED || TLS_ECDHE_PSK_KE_SUPPORT == ENABLED)
463  //ECDH key exchange method?
464  if(context->keyExchMethod == TLS_KEY_EXCH_ECDH_ANON ||
465  context->keyExchMethod == TLS_KEY_EXCH_ECDHE_RSA ||
466  context->keyExchMethod == TLS_KEY_EXCH_ECDHE_ECDSA ||
467  context->keyExchMethod == TLS_KEY_EXCH_ECDHE_PSK)
468  {
469 #if (TLS_ECC_CALLBACK_SUPPORT == ENABLED)
470  //Any registered callback?
471  if(context->ecdhCallback != NULL)
472  {
473  //Invoke user callback function
474  error = context->ecdhCallback(context);
475  }
476  else
477 #endif
478  {
479  //No callback function defined
481  }
482 
483  //Check status code
485  {
486  //Generate an ephemeral key pair
487  error = ecdhGenerateKeyPair(&context->ecdhContext,
488  context->prngAlgo, context->prngContext);
489  //Any error to report?
490  if(error)
491  return error;
492 
493  //Calculate the negotiated key Z
494  error = ecdhComputeSharedSecret(&context->ecdhContext,
495  context->premasterSecret, TLS_PREMASTER_SECRET_SIZE,
496  &context->premasterSecretLen);
497  //Any error to report?
498  if(error)
499  return error;
500  }
501  else if(error != NO_ERROR)
502  {
503  //Report an error
504  return error;
505  }
506 
507  //Encode the client's public key to an opaque vector
508  error = tlsWriteEcPoint(&context->ecdhContext.da.q, p, &n);
509  //Any error to report?
510  if(error)
511  return error;
512 
513  //Total number of bytes that have been written
514  *written = n;
515  }
516  else
517 #endif
518  //Invalid key exchange method?
519  {
520  //Just for sanity
521  (void) error;
522  (void) n;
523 
524  //The specified key exchange method is not supported
526  }
527 
528  //Successful processing
529  return NO_ERROR;
530 #else
531  //Not implemented
532  return ERROR_NOT_IMPLEMENTED;
533 #endif
534 }
535 
536 
537 /**
538  * @brief Parse PSK identity hint
539  * @param[in] context Pointer to the TLS context
540  * @param[in] p Input stream where to read the PSK identity hint
541  * @param[in] length Number of bytes available in the input stream
542  * @param[out] consumed Total number of bytes that have been consumed
543  * @return Error code
544  **/
545 
546 error_t tlsParsePskIdentityHint(TlsContext *context, const uint8_t *p,
547  size_t length, size_t *consumed)
548 {
549  size_t n;
550  TlsPskIdentityHint *pskIdentityHint;
551 
552  //Point to the PSK identity hint
553  pskIdentityHint = (TlsPskIdentityHint *) p;
554 
555  //Malformed ServerKeyExchange message?
556  if(length < sizeof(TlsPskIdentityHint))
557  return ERROR_DECODING_FAILED;
558  if(length < (sizeof(TlsPskIdentityHint) + ntohs(pskIdentityHint->length)))
559  return ERROR_DECODING_FAILED;
560 
561  //Retrieve the length of the PSK identity hint
562  n = ntohs(pskIdentityHint->length);
563 
564 #if (TLS_PSK_KE_SUPPORT == ENABLED || TLS_RSA_PSK_KE_SUPPORT == ENABLED || \
565  TLS_DHE_PSK_KE_SUPPORT == ENABLED || TLS_ECDHE_PSK_KE_SUPPORT == ENABLED)
566  //Any registered callback?
567  if(context->pskCallback != NULL)
568  {
569  error_t error;
570 
571  //The client selects which identity to use depending on the PSK identity
572  //hint provided by the server
573  error = context->pskCallback(context, pskIdentityHint->value, n);
574  //Any error to report?
575  if(error)
576  return ERROR_UNKNOWN_IDENTITY;
577  }
578 #endif
579 
580  //Total number of bytes that have been consumed
581  *consumed = sizeof(TlsPskIdentityHint) + n;
582 
583  //Successful processing
584  return NO_ERROR;
585 }
586 
587 
588 /**
589  * @brief Parse server's key exchange parameters
590  * @param[in] context Pointer to the TLS context
591  * @param[in] p Input stream where to read the server's key exchange parameters
592  * @param[in] length Number of bytes available in the input stream
593  * @param[out] consumed Total number of bytes that have been consumed
594  * @return Error code
595  **/
596 
597 error_t tlsParseServerKeyParams(TlsContext *context, const uint8_t *p,
598  size_t length, size_t *consumed)
599 {
600 #if (TLS_MAX_VERSION >= TLS_VERSION_1_0 && TLS_MIN_VERSION <= TLS_VERSION_1_2)
601  error_t error;
602  const uint8_t *params;
603 
604  //Initialize status code
605  error = NO_ERROR;
606 
607  //Point to the server's key exchange parameters
608  params = p;
609 
610 #if (TLS_DH_ANON_KE_SUPPORT == ENABLED || TLS_DHE_RSA_KE_SUPPORT == ENABLED || \
611  TLS_DHE_DSS_KE_SUPPORT == ENABLED || TLS_DHE_PSK_KE_SUPPORT == ENABLED)
612  //Diffie-Hellman key exchange method?
613  if(context->keyExchMethod == TLS_KEY_EXCH_DH_ANON ||
614  context->keyExchMethod == TLS_KEY_EXCH_DHE_RSA ||
615  context->keyExchMethod == TLS_KEY_EXCH_DHE_DSS ||
616  context->keyExchMethod == TLS_KEY_EXCH_DHE_PSK)
617  {
618  uint_t k;
619  size_t n;
620 
621  //Convert the prime modulus to a multiple precision integer
622  error = tlsReadMpi(&context->dhContext.params.p, p, length, &n);
623 
624  //Check status code
625  if(!error)
626  {
627  //Get the length of the prime modulus, in bits
628  k = mpiGetBitLength(&context->dhContext.params.p);
629 
630  //Make sure the prime modulus is acceptable
631  if(k < TLS_MIN_DH_MODULUS_SIZE || k > TLS_MAX_DH_MODULUS_SIZE)
632  {
633  error = ERROR_ILLEGAL_PARAMETER;
634  }
635  }
636 
637  //Check status code
638  if(!error)
639  {
640  //Advance data pointer
641  p += n;
642  //Remaining bytes to process
643  length -= n;
644 
645  //Convert the generator to a multiple precision integer
646  error = tlsReadMpi(&context->dhContext.params.g, p, length, &n);
647  }
648 
649  //Check status code
650  if(!error)
651  {
652  //Advance data pointer
653  p += n;
654  //Remaining bytes to process
655  length -= n;
656 
657  //Convert the server's public value to a multiple precision integer
658  error = tlsReadMpi(&context->dhContext.yb, p, length, &n);
659  }
660 
661  //Check status code
662  if(!error)
663  {
664  //Advance data pointer
665  p += n;
666  //Remaining bytes to process
667  length -= n;
668 
669  //Verify peer's public value
670  error = dhCheckPublicKey(&context->dhContext,
671  &context->dhContext.yb);
672  }
673 
674  //Check status code
675  if(!error)
676  {
677  //Debug message
678  TRACE_DEBUG("Diffie-Hellman parameters:\r\n");
679  TRACE_DEBUG(" Prime modulus:\r\n");
680  TRACE_DEBUG_MPI(" ", &context->dhContext.params.p);
681  TRACE_DEBUG(" Generator:\r\n");
682  TRACE_DEBUG_MPI(" ", &context->dhContext.params.g);
683  TRACE_DEBUG(" Server public value:\r\n");
684  TRACE_DEBUG_MPI(" ", &context->dhContext.yb);
685  }
686  }
687  else
688 #endif
689 #if (TLS_ECDH_ANON_KE_SUPPORT == ENABLED || TLS_ECDHE_RSA_KE_SUPPORT == ENABLED || \
690  TLS_ECDHE_ECDSA_KE_SUPPORT == ENABLED || TLS_ECDHE_PSK_KE_SUPPORT == ENABLED)
691  //ECDH key exchange method?
692  if(context->keyExchMethod == TLS_KEY_EXCH_ECDH_ANON ||
693  context->keyExchMethod == TLS_KEY_EXCH_ECDHE_RSA ||
694  context->keyExchMethod == TLS_KEY_EXCH_ECDHE_ECDSA ||
695  context->keyExchMethod == TLS_KEY_EXCH_ECDHE_PSK)
696  {
697  size_t n;
698  uint8_t curveType;
699  const EcCurve *curve;
700 
701  //Initialize curve parameters
702  curve = NULL;
703 
704  //Malformed ServerKeyExchange message?
705  if(length < sizeof(curveType))
706  {
707  error = ERROR_DECODING_FAILED;
708  }
709 
710  //Check status code
711  if(!error)
712  {
713  //Retrieve the type of the elliptic curve domain parameters
714  curveType = *p;
715 
716  //Advance data pointer
717  p += sizeof(curveType);
718  //Remaining bytes to process
719  length -= sizeof(curveType);
720 
721  //Only named curves are supported
722  if(curveType != TLS_EC_CURVE_TYPE_NAMED_CURVE)
723  {
724  error = ERROR_ILLEGAL_PARAMETER;
725  }
726  }
727 
728  //Check status code
729  if(!error)
730  {
731  //Malformed ServerKeyExchange message?
732  if(length < sizeof(uint16_t))
733  {
734  error = ERROR_DECODING_FAILED;
735  }
736  }
737 
738  //Check status code
739  if(!error)
740  {
741  //Get elliptic curve identifier
742  context->namedGroup = LOAD16BE(p);
743 
744  //Advance data pointer
745  p += sizeof(uint16_t);
746  //Remaining bytes to process
747  length -= sizeof(uint16_t);
748 
749  //TLS 1.3 group?
750  if(context->namedGroup == TLS_GROUP_BRAINPOOLP256R1_TLS13 ||
751  context->namedGroup == TLS_GROUP_BRAINPOOLP384R1_TLS13 ||
752  context->namedGroup == TLS_GROUP_BRAINPOOLP512R1_TLS13 ||
753  context->namedGroup == TLS_GROUP_CURVE_SM2)
754  {
755  //These elliptic curves do not apply to any older versions of TLS
756  error = ERROR_ILLEGAL_PARAMETER;
757  }
758  else
759  {
760  //Retrieve the corresponding EC domain parameters
761  curve = tlsGetCurve(context, context->namedGroup);
762 
763  //Make sure the elliptic curve is supported
764  if(curve == NULL)
765  {
766  //The elliptic curve is not supported
767  error = ERROR_ILLEGAL_PARAMETER;
768  }
769  }
770  }
771 
772  //Check status code
773  if(!error)
774  {
775  //Save elliptic curve parameters
776  error = ecdhSetCurve(&context->ecdhContext, curve);
777  }
778 
779  //Check status code
780  if(!error)
781  {
782  //Read server's public key
783  error = tlsReadEcPoint(&context->ecdhContext.qb, curve, p, length, &n);
784  }
785 
786  //Check status code
787  if(!error)
788  {
789  //Advance data pointer
790  p += n;
791  //Remaining bytes to process
792  length -= n;
793 
794  //Verify peer's public key
795  error = ecdhCheckPublicKey(&context->ecdhContext,
796  &context->ecdhContext.qb);
797  }
798  }
799  else
800 #endif
801  //Invalid key exchange method?
802  {
803  //It is not legal to send the ServerKeyExchange message when a key
804  //exchange method other than DHE_DSS, DHE_RSA, DH_anon, ECDHE_RSA,
805  //ECDHE_ECDSA or ECDH_anon is selected
806  error = ERROR_UNEXPECTED_MESSAGE;
807  }
808 
809  //Total number of bytes that have been consumed
810  *consumed = p - params;
811 
812  //Return status code
813  return error;
814 #else
815  //Not implemented
816  return ERROR_NOT_IMPLEMENTED;
817 #endif
818 }
819 
820 
821 /**
822  * @brief Verify server's key exchange parameters signature (TLS 1.0 and TLS 1.1)
823  * @param[in] context Pointer to the TLS context
824  * @param[in] signature Pointer to the digital signature
825  * @param[in] length Number of bytes available in the input stream
826  * @param[in] params Pointer to the server's key exchange parameters
827  * @param[in] paramsLen Length of the server's key exchange parameters
828  * @param[out] consumed Total number of bytes that have been consumed
829  * @return Error code
830  **/
831 
833  const TlsDigitalSignature *signature, size_t length,
834  const uint8_t *params, size_t paramsLen, size_t *consumed)
835 {
836  error_t error;
837 
838 #if (TLS_MAX_VERSION >= TLS_VERSION_1_0 && TLS_MIN_VERSION <= TLS_VERSION_1_1)
839  //Initialize status code
840  error = NO_ERROR;
841 
842  //Check the length of the digitally-signed element
843  if(length < sizeof(TlsDigitalSignature))
844  return ERROR_DECODING_FAILED;
845  if(length < (sizeof(TlsDigitalSignature) + ntohs(signature->length)))
846  return ERROR_DECODING_FAILED;
847 
848 #if (TLS_RSA_SIGN_SUPPORT == ENABLED)
849  //RSA signature algorithm?
850  if(context->peerCertType == TLS_CERT_RSA_SIGN)
851  {
852  Md5Context *md5Context;
853  Sha1Context *sha1Context;
854 
855  //Allocate a memory buffer to hold the MD5 context
856  md5Context = tlsAllocMem(sizeof(Md5Context));
857 
858  //Successful memory allocation?
859  if(md5Context != NULL)
860  {
861  //Compute MD5(ClientHello.random + ServerHello.random +
862  //ServerKeyExchange.params)
863  md5Init(md5Context);
864  md5Update(md5Context, context->clientRandom, TLS_RANDOM_SIZE);
865  md5Update(md5Context, context->serverRandom, TLS_RANDOM_SIZE);
866  md5Update(md5Context, params, paramsLen);
867  md5Final(md5Context, context->serverVerifyData);
868 
869  //Release previously allocated memory
870  tlsFreeMem(md5Context);
871  }
872  else
873  {
874  //Failed to allocate memory
875  error = ERROR_OUT_OF_MEMORY;
876  }
877 
878  //Check status code
879  if(!error)
880  {
881  //Allocate a memory buffer to hold the SHA-1 context
882  sha1Context = tlsAllocMem(sizeof(Sha1Context));
883 
884  //Successful memory allocation?
885  if(sha1Context != NULL)
886  {
887  //Compute SHA(ClientHello.random + ServerHello.random +
888  //ServerKeyExchange.params)
889  sha1Init(sha1Context);
890  sha1Update(sha1Context, context->clientRandom, TLS_RANDOM_SIZE);
891  sha1Update(sha1Context, context->serverRandom, TLS_RANDOM_SIZE);
892  sha1Update(sha1Context, params, paramsLen);
893  sha1Final(sha1Context, context->serverVerifyData + MD5_DIGEST_SIZE);
894 
895  //Release previously allocated memory
896  tlsFreeMem(sha1Context);
897  }
898  else
899  {
900  //Failed to allocate memory
901  error = ERROR_OUT_OF_MEMORY;
902  }
903  }
904 
905  //Check status code
906  if(!error)
907  {
908  //RSA signature verification
909  error = tlsVerifyRsaSignature(&context->peerRsaPublicKey,
910  context->serverVerifyData, signature->value, ntohs(signature->length));
911  }
912  }
913  else
914 #endif
915 #if (TLS_DSA_SIGN_SUPPORT == ENABLED)
916  //DSA signature algorithm?
917  if(context->peerCertType == TLS_CERT_DSS_SIGN)
918  {
919  Sha1Context *sha1Context;
920 
921  //Allocate a memory buffer to hold the SHA-1 context
922  sha1Context = tlsAllocMem(sizeof(Sha1Context));
923 
924  //Successful memory allocation?
925  if(sha1Context != NULL)
926  {
927  //Compute SHA(ClientHello.random + ServerHello.random +
928  //ServerKeyExchange.params)
929  sha1Init(sha1Context);
930  sha1Update(sha1Context, context->clientRandom, TLS_RANDOM_SIZE);
931  sha1Update(sha1Context, context->serverRandom, TLS_RANDOM_SIZE);
932  sha1Update(sha1Context, params, paramsLen);
933  sha1Final(sha1Context, context->serverVerifyData);
934 
935  //Release previously allocated memory
936  tlsFreeMem(sha1Context);
937  }
938  else
939  {
940  //Failed to allocate memory
941  error = ERROR_OUT_OF_MEMORY;
942  }
943 
944  //Check status code
945  if(!error)
946  {
947  //DSA signature verification
948  error = tlsVerifyDsaSignature(context, context->serverVerifyData,
949  SHA1_DIGEST_SIZE, signature->value, ntohs(signature->length));
950  }
951  }
952  else
953 #endif
954 #if (TLS_ECDSA_SIGN_SUPPORT == ENABLED)
955  //ECDSA signature algorithm?
956  if(context->peerCertType == TLS_CERT_ECDSA_SIGN)
957  {
958  Sha1Context *sha1Context;
959 
960  //Allocate a memory buffer to hold the SHA-1 context
961  sha1Context = tlsAllocMem(sizeof(Sha1Context));
962 
963  //Successful memory allocation?
964  if(sha1Context != NULL)
965  {
966  //Compute SHA(ClientHello.random + ServerHello.random +
967  //ServerKeyExchange.params)
968  sha1Init(sha1Context);
969  sha1Update(sha1Context, context->clientRandom, TLS_RANDOM_SIZE);
970  sha1Update(sha1Context, context->serverRandom, TLS_RANDOM_SIZE);
971  sha1Update(sha1Context, params, paramsLen);
972  sha1Final(sha1Context, context->serverVerifyData);
973 
974  //Release previously allocated memory
975  tlsFreeMem(sha1Context);
976  }
977 
978  //Check status code
979  if(!error)
980  {
981  //ECDSA signature verification
982  error = tlsVerifyEcdsaSignature(context, context->serverVerifyData,
983  SHA1_DIGEST_SIZE, signature->value, ntohs(signature->length));
984  }
985  }
986  else
987 #endif
988  //Invalid signature algorithm?
989  {
990  //Report an error
991  error = ERROR_INVALID_SIGNATURE;
992  }
993 
994  //Total number of bytes that have been consumed
995  *consumed = sizeof(TlsDigitalSignature) + ntohs(signature->length);
996 #else
997  //Not implemented
998  error = ERROR_NOT_IMPLEMENTED;
999 #endif
1000 
1001  //Return status code
1002  return error;
1003 }
1004 
1005 
1006 /**
1007  * @brief Verify server's key exchange parameters signature (TLS 1.2)
1008  * @param[in] context Pointer to the TLS context
1009  * @param[in] signature Pointer to the digital signature
1010  * @param[in] length Number of bytes available in the input stream
1011  * @param[in] params Pointer to the server's key exchange parameters
1012  * @param[in] paramsLen Length of the server's key exchange parameters
1013  * @param[out] consumed Total number of bytes that have been consumed
1014  * @return Error code
1015  **/
1016 
1018  const Tls12DigitalSignature *signature, size_t length,
1019  const uint8_t *params, size_t paramsLen, size_t *consumed)
1020 {
1021 #if (TLS_MAX_VERSION >= TLS_VERSION_1_2 && TLS_MIN_VERSION <= TLS_VERSION_1_2)
1022  error_t error;
1023  TlsSignatureScheme signScheme;
1024 
1025  //Initialize status code
1026  error = NO_ERROR;
1027 
1028  //Check the length of the digitally-signed element
1029  if(length < sizeof(Tls12DigitalSignature))
1030  return ERROR_DECODING_FAILED;
1031  if(length < (sizeof(Tls12DigitalSignature) + ntohs(signature->length)))
1032  return ERROR_DECODING_FAILED;
1033 
1034  //The algorithm field specifies the signature scheme
1035  signScheme = (TlsSignatureScheme) ntohs(signature->algorithm);
1036 
1037  //If the client has offered the SignatureAlgorithms extension, the signature
1038  //algorithm and hash algorithm must be a pair listed in that extension (refer
1039  //to RFC 5246, section 7.4.3)
1040  if(!tlsIsSignAlgoSupported(context, signScheme))
1041  return ERROR_ILLEGAL_PARAMETER;
1042 
1043 #if (TLS_RSA_SIGN_SUPPORT == ENABLED || TLS_RSA_PSS_SIGN_SUPPORT == ENABLED || \
1044  TLS_DSA_SIGN_SUPPORT == ENABLED || TLS_ECDSA_SIGN_SUPPORT == ENABLED)
1045  //RSA, DSA or ECDSA signature scheme?
1046  if(TLS_SIGN_ALGO(signScheme) == TLS_SIGN_ALGO_RSA ||
1047  TLS_SIGN_ALGO(signScheme) == TLS_SIGN_ALGO_DSA ||
1048  TLS_SIGN_ALGO(signScheme) == TLS_SIGN_ALGO_ECDSA ||
1049  signScheme == TLS_SIGN_SCHEME_RSA_PSS_RSAE_SHA256 ||
1050  signScheme == TLS_SIGN_SCHEME_RSA_PSS_RSAE_SHA384 ||
1051  signScheme == TLS_SIGN_SCHEME_RSA_PSS_RSAE_SHA512 ||
1052  signScheme == TLS_SIGN_SCHEME_RSA_PSS_PSS_SHA256 ||
1053  signScheme == TLS_SIGN_SCHEME_RSA_PSS_PSS_SHA384 ||
1054  signScheme == TLS_SIGN_SCHEME_RSA_PSS_PSS_SHA512)
1055  {
1056  const HashAlgo *hashAlgo;
1057  HashContext *hashContext;
1058  uint8_t digest[MAX_HASH_DIGEST_SIZE];
1059 
1060  //Check signature scheme
1061  if(signScheme == TLS_SIGN_SCHEME_RSA_PSS_RSAE_SHA256 ||
1062  signScheme == TLS_SIGN_SCHEME_RSA_PSS_PSS_SHA256)
1063  {
1064  //The hashing is intrinsic to the signature algorithm
1066  }
1067  else if(signScheme == TLS_SIGN_SCHEME_RSA_PSS_RSAE_SHA384 ||
1068  signScheme == TLS_SIGN_SCHEME_RSA_PSS_PSS_SHA384)
1069  {
1070  //The hashing is intrinsic to the signature algorithm
1072  }
1073  else if(signScheme == TLS_SIGN_SCHEME_RSA_PSS_RSAE_SHA512 ||
1074  signScheme == TLS_SIGN_SCHEME_RSA_PSS_PSS_SHA512)
1075  {
1076  //The hashing is intrinsic to the signature algorithm
1078  }
1079  else
1080  {
1081  //Retrieve the hash algorithm used for signing
1082  hashAlgo = tlsGetHashAlgo(TLS_HASH_ALGO(signScheme));
1083  }
1084 
1085  //Make sure the hash algorithm is supported
1086  if(hashAlgo != NULL)
1087  {
1088  //Allocate a memory buffer to hold the hash context
1089  hashContext = tlsAllocMem(hashAlgo->contextSize);
1090 
1091  //Successful memory allocation?
1092  if(hashContext != NULL)
1093  {
1094  //Compute hash(ClientHello.random + ServerHello.random +
1095  //ServerKeyExchange.params)
1096  hashAlgo->init(hashContext);
1097  hashAlgo->update(hashContext, context->clientRandom, TLS_RANDOM_SIZE);
1098  hashAlgo->update(hashContext, context->serverRandom, TLS_RANDOM_SIZE);
1099  hashAlgo->update(hashContext, params, paramsLen);
1100  hashAlgo->final(hashContext, digest);
1101 
1102 #if (TLS_RSA_SIGN_SUPPORT == ENABLED)
1103  //RSASSA-PKCS1-v1_5 signature scheme?
1104  if(TLS_SIGN_ALGO(signScheme) == TLS_SIGN_ALGO_RSA &&
1105  context->peerCertType == TLS_CERT_RSA_SIGN)
1106  {
1107  //Verify RSA signature (RSASSA-PKCS1-v1_5 signature scheme)
1108  error = rsassaPkcs1v15Verify(&context->peerRsaPublicKey,
1109  hashAlgo, digest, signature->value, ntohs(signature->length));
1110  }
1111  else
1112 #endif
1113 #if (TLS_RSA_PSS_SIGN_SUPPORT == ENABLED)
1114  //RSASSA-PSS signature scheme (with public key OID rsaEncryption)?
1115  if(signScheme == TLS_SIGN_SCHEME_RSA_PSS_RSAE_SHA256 ||
1116  signScheme == TLS_SIGN_SCHEME_RSA_PSS_RSAE_SHA384 ||
1118  {
1119  //The signature algorithm must be compatible with the key in the
1120  //server's end-entity certificate (refer to RFC 5246, section 7.4.3)
1121  if(context->peerCertType == TLS_CERT_RSA_SIGN)
1122  {
1123  //Verify RSA signature (RSASSA-PSS signature scheme)
1124  error = rsassaPssVerify(&context->peerRsaPublicKey, hashAlgo,
1125  hashAlgo->digestSize, digest, signature->value,
1126  ntohs(signature->length));
1127  }
1128  else
1129  {
1130  //Invalid certificate
1131  error = ERROR_INVALID_SIGNATURE;
1132  }
1133  }
1134  else
1135 #endif
1136 #if (TLS_RSA_PSS_SIGN_SUPPORT == ENABLED)
1137  //RSASSA-PSS signature scheme (with public key OID RSASSA-PSS)?
1138  if(signScheme == TLS_SIGN_SCHEME_RSA_PSS_PSS_SHA256 ||
1139  signScheme == TLS_SIGN_SCHEME_RSA_PSS_PSS_SHA384 ||
1140  signScheme == TLS_SIGN_SCHEME_RSA_PSS_PSS_SHA512)
1141  {
1142  //The signature algorithm must be compatible with the key in the
1143  //server's end-entity certificate (refer to RFC 5246, section 7.4.3)
1144  if(context->peerCertType == TLS_CERT_RSA_PSS_SIGN)
1145  {
1146  //Verify RSA signature (RSASSA-PSS signature scheme)
1147  error = rsassaPssVerify(&context->peerRsaPublicKey, hashAlgo,
1148  hashAlgo->digestSize, digest, signature->value,
1149  ntohs(signature->length));
1150  }
1151  else
1152  {
1153  //Invalid certificate
1154  error = ERROR_INVALID_SIGNATURE;
1155  }
1156  }
1157  else
1158 #endif
1159 #if (TLS_DSA_SIGN_SUPPORT == ENABLED)
1160  //DSA signature scheme?
1161  if(TLS_SIGN_ALGO(signScheme) == TLS_SIGN_ALGO_DSA &&
1162  context->peerCertType == TLS_CERT_DSS_SIGN)
1163  {
1164  //Verify DSA signature
1165  error = tlsVerifyDsaSignature(context, digest,
1166  hashAlgo->digestSize, signature->value,
1167  ntohs(signature->length));
1168  }
1169  else
1170 #endif
1171 #if (TLS_ECDSA_SIGN_SUPPORT == ENABLED)
1172  //ECDSA signature scheme?
1173  if(TLS_SIGN_ALGO(signScheme) == TLS_SIGN_ALGO_ECDSA &&
1174  context->peerCertType == TLS_CERT_ECDSA_SIGN)
1175  {
1176  //Verify ECDSA signature
1177  error = tlsVerifyEcdsaSignature(context, digest,
1178  hashAlgo->digestSize, signature->value,
1179  ntohs(signature->length));
1180  }
1181  else
1182 #endif
1183  //Invalid signature scheme?
1184  {
1185  //Report an error
1186  error = ERROR_INVALID_SIGNATURE;
1187  }
1188 
1189  //Release previously allocated memory
1190  tlsFreeMem(hashContext);
1191  }
1192  else
1193  {
1194  //Failed to allocate memory
1195  error = ERROR_OUT_OF_MEMORY;
1196  }
1197  }
1198  else
1199  {
1200  //Hash algorithm not supported
1201  error = ERROR_INVALID_SIGNATURE;
1202  }
1203  }
1204  else
1205 #endif
1206 #if (TLS_ED25519_SIGN_SUPPORT == ENABLED)
1207  //Ed25519 signature scheme?
1208  if(signScheme == TLS_SIGN_SCHEME_ED25519 &&
1209  context->peerCertType == TLS_CERT_ED25519_SIGN)
1210  {
1211  DataChunk messageChunks[3];
1212 
1213  //Data to be verified is run through the EdDSA algorithm without
1214  //pre-hashing
1215  messageChunks[0].buffer = context->clientRandom;
1216  messageChunks[0].length = TLS_RANDOM_SIZE;
1217  messageChunks[1].buffer = context->serverRandom;
1218  messageChunks[1].length = TLS_RANDOM_SIZE;
1219  messageChunks[2].buffer = params;
1220  messageChunks[2].length = paramsLen;
1221 
1222  //Verify Ed25519 signature (PureEdDSA mode)
1223  error = tlsVerifyEd25519Signature(context, messageChunks,
1224  arraysize(messageChunks), signature->value, ntohs(signature->length));
1225  }
1226  else
1227 #endif
1228 #if (TLS_ED448_SIGN_SUPPORT == ENABLED)
1229  //Ed448 signature scheme?
1230  if(signScheme == TLS_SIGN_SCHEME_ED448 &&
1231  context->peerCertType == TLS_CERT_ED448_SIGN)
1232  {
1233  DataChunk messageChunks[3];
1234 
1235  //Data to be verified is run through the EdDSA algorithm without
1236  //pre-hashing
1237  messageChunks[0].buffer = context->clientRandom;
1238  messageChunks[0].length = TLS_RANDOM_SIZE;
1239  messageChunks[1].buffer = context->serverRandom;
1240  messageChunks[1].length = TLS_RANDOM_SIZE;
1241  messageChunks[2].buffer = params;
1242  messageChunks[2].length = paramsLen;
1243 
1244  //Verify Ed448 signature (PureEdDSA mode)
1245  error = tlsVerifyEd448Signature(context, messageChunks,
1246  arraysize(messageChunks), signature->value, ntohs(signature->length));
1247  }
1248  else
1249 #endif
1250  //Invalid signature algorithm?
1251  {
1252  //Report an error
1253  error = ERROR_INVALID_SIGNATURE;
1254  }
1255 
1256  //Total number of bytes that have been consumed
1257  *consumed = sizeof(Tls12DigitalSignature) + ntohs(signature->length);
1258 
1259  //Return status code
1260  return error;
1261 #else
1262  //Not implemented
1263  return ERROR_NOT_IMPLEMENTED;
1264 #endif
1265 }
1266 
1267 
1268 /**
1269  * @brief Version selection
1270  * @param[in] context Pointer to the TLS context
1271  * @param[in] message Pointer to the received ServerHello message
1272  * @param[in] extensions ServerHello extensions offered by the server
1273  * @return Error code
1274  **/
1275 
1278 {
1279  error_t error;
1280  uint16_t selectedVersion;
1281 
1282 #if (TLS_MAX_VERSION >= TLS_VERSION_1_3 && TLS_MIN_VERSION <= TLS_VERSION_1_3)
1283  //Clients must check for the SupportedVersions extension prior to
1284  //processing the rest of the ServerHello
1285  if(extensions->selectedVersion != NULL)
1286  {
1287  //If a client receives an extension type in the ServerHello that it did
1288  //not request in the associated ClientHello, it must abort the handshake
1289  //with an unsupported_extension fatal alert
1290  if(context->versionMax <= TLS_VERSION_1_2)
1292 
1293  //The legacy_version field must be set to 0x0303, which is the version
1294  //number for TLS 1.2
1295  if(context->transportProtocol == TLS_TRANSPORT_PROTOCOL_DATAGRAM)
1296  {
1297  if(ntohs(message->serverVersion) != DTLS_VERSION_1_2)
1299  }
1300  else
1301  {
1302  if(ntohs(message->serverVersion) != TLS_VERSION_1_2)
1304  }
1305 
1306  //If this extension is present, clients must ignore the legacy_version
1307  //value and must use only the SupportedVersions extension to determine
1308  //the selected version
1309  selectedVersion = LOAD16BE(extensions->selectedVersion->value);
1310 
1311 #if (DTLS_SUPPORT == ENABLED)
1312  //DTLS protocol?
1313  if(context->transportProtocol == TLS_TRANSPORT_PROTOCOL_DATAGRAM)
1314  {
1315  //If the SupportedVersions extension contains a version prior to DTLS
1316  //1.3, the client must abort the handshake with an illegal_parameter
1317  //alert (refer to RFC 8446, section 4.2.1)
1318  if(selectedVersion >= DTLS_VERSION_1_2)
1319  return ERROR_ILLEGAL_PARAMETER;
1320 
1321  //Check whether the ServerHello message is received in response to an
1322  //updated ClientHello?
1323  if(context->state == TLS_STATE_SERVER_HELLO_2)
1324  {
1325  //The value of selected_version in the SupportedVersions extension
1326  //of the HelloRetryRequest must be retained in the ServerHello. A
1327  //client must abort the handshake with an illegal_parameter alert if
1328  //the value changes (refer to RFC 8446, section 4.1.4)
1329  if(selectedVersion != dtlsTranslateVersion(context->version))
1330  return ERROR_ILLEGAL_PARAMETER;
1331  }
1332  }
1333  else
1334 #endif
1335  //TLS protocol?
1336  {
1337  //If the SupportedVersions extension contains a version prior to TLS
1338  //1.3, the client must abort the handshake with an illegal_parameter
1339  //alert (refer to RFC 8446, section 4.2.1)
1340  if(selectedVersion <= TLS_VERSION_1_2)
1341  return ERROR_ILLEGAL_PARAMETER;
1342 
1343  //Check whether the ServerHello message is received in response to an
1344  //updated ClientHello?
1345  if(context->state == TLS_STATE_SERVER_HELLO_2)
1346  {
1347  //The value of selected_version in the SupportedVersions extension
1348  //of the HelloRetryRequest must be retained in the ServerHello. A
1349  //client must abort the handshake with an illegal_parameter alert if
1350  //the value changes (refer to RFC 8446, section 4.1.4)
1351  if(selectedVersion != context->version)
1352  return ERROR_ILLEGAL_PARAMETER;
1353  }
1354  }
1355  }
1356  else
1357 #endif
1358  {
1359  //In previous versions of TLS, this field was used for version negotiation
1360  //and represented the selected version number for the connection
1361  selectedVersion = ntohs(message->serverVersion);
1362 
1363 #if (DTLS_SUPPORT == ENABLED)
1364  //DTLS protocol?
1365  if(context->transportProtocol == TLS_TRANSPORT_PROTOCOL_DATAGRAM)
1366  {
1367  //A server which negotiates DTLS 1.3 must set the legacy_version field
1368  //to 0xFEFD (DTLS 1.2) and use the SupportedVersions extension instead
1369  if(selectedVersion < DTLS_VERSION_1_2)
1370  return ERROR_ILLEGAL_PARAMETER;
1371  }
1372  else
1373 #endif
1374  //TLS protocol?
1375  {
1376  //A server which negotiates TLS 1.3 must set the legacy_version field
1377  //to 0x0303 (TLS 1.2) and use the SupportedVersions extension instead
1378  if(selectedVersion > TLS_VERSION_1_2)
1379  return ERROR_ILLEGAL_PARAMETER;
1380  }
1381  }
1382 
1383 #if (DTLS_SUPPORT == ENABLED)
1384  //DTLS protocol?
1385  if(context->transportProtocol == TLS_TRANSPORT_PROTOCOL_DATAGRAM)
1386  {
1387  //Set the DTLS version to be used
1388  error = dtlsSelectVersion(context, selectedVersion);
1389  }
1390  else
1391 #endif
1392  //TLS protocol?
1393  {
1394  //Set the TLS version to be used
1395  error = tlsSelectVersion(context, selectedVersion);
1396  }
1397 
1398  //Specified TLS/DTLS version not supported?
1399  if(error)
1400  return error;
1401 
1402 #if (TLS_MAX_VERSION >= TLS_VERSION_1_3 && TLS_MIN_VERSION <= TLS_VERSION_1_3)
1403  //If the ServerHello indicates TLS 1.1 or below, TLS 1.3 client must and
1404  //1.2 clients should check that the last 8 bytes are not equal to the
1405  //bytes 44 4F 57 4E 47 52 44 00
1406  if(context->version <= TLS_VERSION_1_1 &&
1407  context->versionMax >= TLS_VERSION_1_2)
1408  {
1409  //If a match is found, the client must abort the handshake with an
1410  //illegal_parameter alert
1411  if(osMemcmp(message->random + 24, tls11DowngradeRandom, 8) == 0)
1412  return ERROR_ILLEGAL_PARAMETER;
1413  }
1414 
1415  //If the ServerHello indicates TLS 1.2 or below, TLS 1.3 client must check
1416  //that the last 8 bytes are not equal to the bytes 44 4F 57 4E 47 52 44 01
1417  if(context->version <= TLS_VERSION_1_2 &&
1418  context->versionMax >= TLS_VERSION_1_3 &&
1419  (context->transportProtocol == TLS_TRANSPORT_PROTOCOL_STREAM ||
1420  context->transportProtocol == TLS_TRANSPORT_PROTOCOL_EAP))
1421  {
1422  //If a match is found, the client must abort the handshake with an
1423  //illegal_parameter alert
1424  if(osMemcmp(message->random + 24, tls12DowngradeRandom, 8) == 0)
1425  return ERROR_ILLEGAL_PARAMETER;
1426  }
1427 #endif
1428 
1429  //Successful processing
1430  return NO_ERROR;
1431 }
1432 
1433 
1434 /**
1435  * @brief Resume TLS session via session ID
1436  * @param[in] context Pointer to the TLS context
1437  * @param[in] sessionId Pointer to the session ID provided by the server
1438  * @param[in] sessionIdLen Length of the session ID, in bytes
1439  * @param[in] cipherSuite Cipher suite selected by the server
1440  * @return Error code
1441  **/
1442 
1444  size_t sessionIdLen, uint16_t cipherSuite)
1445 {
1446  error_t error;
1447 
1448  //Initialize status code
1449  error = NO_ERROR;
1450 
1451 #if (TLS_SESSION_RESUME_SUPPORT == ENABLED)
1452  //Check whether the session ID matches the value that was supplied by the
1453  //client
1454  if(sessionIdLen != 0 && sessionIdLen == context->sessionIdLen &&
1455  osMemcmp(sessionId, context->sessionId, sessionIdLen) == 0)
1456  {
1457  //For resumed sessions, the selected cipher suite shall be the same as
1458  //the session being resumed
1459  if(cipherSuite != 0 && cipherSuite == context->cipherSuite.identifier)
1460  {
1461  //Perform abbreviated handshake
1462  context->resume = TRUE;
1463  }
1464  else
1465  {
1466  //The session ID is no more valid
1467  context->sessionIdLen = 0;
1468 
1469  //When renegotiating, if the server tries to use another version or
1470  //compression method than previously, abort
1471  error = ERROR_ILLEGAL_PARAMETER;
1472  }
1473  }
1474  else
1475 #endif
1476  {
1477  //Perform a full handshake
1478  context->resume = FALSE;
1479  }
1480 
1481  //Return status code
1482  return error;
1483 }
1484 
1485 
1486 /**
1487  * @brief Check whether a session ticket is valid
1488  * @param[in] context Pointer to the TLS context
1489  * @return TRUE is the session ticket is valid, else FALSE
1490  **/
1491 
1493 {
1494  bool_t valid = FALSE;
1495 
1496  //TLS 1.3 tickets cannot be used to resume a TLS 1.2 session
1497  if(context->version <= TLS_VERSION_1_2)
1498  {
1499  //Valid ticket?
1500  if(context->ticket != NULL && context->ticketLen > 0)
1501  {
1502  valid = TRUE;
1503  }
1504  }
1505 
1506  //Return TRUE is the ticket is valid, else FALSE
1507  return valid;
1508 }
1509 
1510 #endif
@ TLS_GROUP_BRAINPOOLP512R1_TLS13
Definition: tls.h:1454
#define tlsAllocMem(size)
Definition: tls.h:874
#define htons(value)
Definition: cpu_endian.h:413
Parsing and checking of TLS extensions.
@ TLS_SIGN_ALGO_DSA
Definition: tls.h:1266
TLS helper functions.
const uint8_t tls11DowngradeRandom[8]
Definition: tls13_misc.c:53
@ ERROR_UNKNOWN_IDENTITY
Definition: error.h:261
HashAlgoInit init
Definition: crypto.h:1099
@ ERROR_UNSUPPORTED_ELLIPTIC_CURVE
Definition: error.h:133
uint8_t extensions[]
Definition: ntp_common.h:207
@ TLS_GROUP_BRAINPOOLP256R1_TLS13
Definition: tls.h:1452
Generic hash algorithm context.
int bool_t
Definition: compiler_port.h:61
uint8_t sessionId[]
Definition: tls.h:1829
TLS cipher suites.
uint16_t cipherSuite
Cipher suite identifier.
Definition: tls.h:1939
error_t dtlsSelectVersion(TlsContext *context, uint16_t version)
Set the DTLS version to be used.
Definition: dtls_misc.c:53
error_t tlsVerifyEd448Signature(TlsContext *context, const DataChunk *message, uint_t messageLen, const uint8_t *signature, size_t signatureLen)
Verify Ed448 signature.
const HashAlgo * tlsGetHashAlgo(TlsHashAlgo hashAlgoId)
Get the hash algorithm that matches the specified identifier.
Definition: tls_misc.c:1186
TlsDigitalSignature
Definition: tls.h:1773
@ TLS_SIGN_SCHEME_RSA_PSS_RSAE_SHA256
Definition: tls.h:1289
#define TLS_MAX_DH_MODULUS_SIZE
Definition: tls.h:787
void sha1Update(Sha1Context *context, const void *data, size_t length)
Update the SHA-1 context with a portion of the message being hashed.
@ TLS_COMPRESSION_METHOD_NULL
Definition: tls.h:1159
error_t tlsVerifyServerKeySignature(TlsContext *context, const TlsDigitalSignature *signature, size_t length, const uint8_t *params, size_t paramsLen, size_t *consumed)
Verify server's key exchange parameters signature (TLS 1.0 and TLS 1.1)
@ ERROR_VERSION_NOT_SUPPORTED
Definition: error.h:67
@ ERROR_NOT_IMPLEMENTED
Definition: error.h:66
@ ERROR_ILLEGAL_PARAMETER
Definition: error.h:244
const EcCurve * tlsGetCurve(TlsContext *context, uint16_t namedCurve)
Get the EC domain parameters that match the specified named curve.
Definition: tls_misc.c:1253
@ ERROR_UNEXPECTED_MESSAGE
Definition: error.h:195
error_t tlsFormatCipherSuites(TlsContext *context, uint8_t *p, size_t *written)
Format the list of cipher suites supported by the client.
uint8_t p
Definition: ndp.h:300
Helper functions for TLS client.
uint8_t message[]
Definition: chap.h:154
error_t tlsSelectVersion(TlsContext *context, uint16_t version)
Set the TLS version to be used.
Definition: tls_misc.c:307
#define TRUE
Definition: os_port.h:50
@ TLS_GROUP_CURVE_SM2
Definition: tls.h:1462
size_t digestSize
Definition: crypto.h:1095
error_t tlsResumeSession(TlsContext *context, const uint8_t *sessionId, size_t sessionIdLen, uint16_t cipherSuite)
Resume TLS session via session ID.
const void * buffer
Definition: crypto.h:1025
@ TLS_TRANSPORT_PROTOCOL_DATAGRAM
Definition: tls.h:986
HashAlgoUpdate update
Definition: crypto.h:1100
void md5Final(Md5Context *context, uint8_t *digest)
Finish the MD5 message digest.
Session cache management.
TlsPskIdentity
Definition: tls.h:1751
@ TLS_SIGN_SCHEME_RSA_PSS_PSS_SHA512
Definition: tls.h:1294
error_t tlsWriteMpi(const Mpi *a, uint8_t *data, size_t *length)
Encode a multiple precision integer to an opaque vector.
Definition: tls_misc.c:962
#define osMemcmp(p1, p2, length)
Definition: os_port.h:156
@ ERROR_OUT_OF_MEMORY
Definition: error.h:63
error_t tlsFormatSessionId(TlsContext *context, uint8_t *p, size_t *written)
Format session ID.
const uint8_t tls12DowngradeRandom[8]
Definition: tls13_misc.c:59
@ TLS_CERT_DSS_SIGN
Definition: tls.h:1222
@ TLS_SIGN_SCHEME_RSA_PSS_RSAE_SHA512
Definition: tls.h:1291
@ TLS_SIGN_SCHEME_ED25519
Definition: tls.h:1303
#define osStrlen(s)
Definition: os_port.h:168
#define TLS_RANDOM_SIZE
Definition: tls.h:967
#define TLS_HASH_ALGO(signScheme)
Definition: tls_sign_misc.h:41
TlsPskIdentityHint
Definition: tls.h:1762
@ TLS_SIGN_SCHEME_RSA_PSS_PSS_SHA384
Definition: tls.h:1293
@ TLS_SIGN_SCHEME_RSA_PSS_RSAE_SHA384
Definition: tls.h:1290
error_t tlsParsePskIdentityHint(TlsContext *context, const uint8_t *p, size_t length, size_t *consumed)
Parse PSK identity hint.
size_t contextSize
Definition: crypto.h:1093
uint8_t sessionIdLen
Definition: tls.h:1828
@ TLS_KEY_EXCH_RSA
Definition: tls.h:1171
void md5Init(Md5Context *context)
Initialize MD5 message digest context.
TlsCipherSuites
Definition: tls.h:1573
#define MAX_HASH_DIGEST_SIZE
@ TLS_HASH_ALGO_SHA512
Definition: tls.h:1252
@ TLS_KEY_EXCH_ECDHE_ECDSA
Definition: tls.h:1180
@ TLS_KEY_EXCH_ECDHE_RSA
Definition: tls.h:1178
TlsHandshake
Definition: tls.h:1810
#define FALSE
Definition: os_port.h:46
error_t dhComputeSharedSecret(DhContext *context, uint8_t *output, size_t outputSize, size_t *outputLen)
Compute Diffie-Hellman shared secret.
Definition: dh.c:289
@ TLS_KEY_EXCH_ECDH_ANON
Definition: tls.h:1181
bool_t tlsIsSignAlgoSupported(TlsContext *context, uint16_t signScheme)
Check whether a signature algorithm can be used for digital signatures.
error_t tlsVerifyRsaSignature(const RsaPublicKey *key, const uint8_t *digest, const uint8_t *signature, size_t signatureLen)
Verify RSA signature (TLS 1.0 and TLS 1.1)
void sha1Init(Sha1Context *context)
Initialize SHA-1 message digest context.
#define osMemcpy(dest, src, length)
Definition: os_port.h:144
@ ERROR_UNSUPPORTED_EXTENSION
Definition: error.h:246
error_t ecdhCheckPublicKey(EcdhContext *context, const EcPublicKey *publicKey)
Check public key.
Definition: ecdh.c:301
#define TlsContext
Definition: tls.h:36
error_t
Error codes.
Definition: error.h:43
@ TLS_SIGN_SCHEME_RSA_PSS_PSS_SHA256
Definition: tls.h:1292
@ TLS_CERT_ED25519_SIGN
Definition: tls.h:1235
error_t rsaesPkcs1v15Encrypt(const PrngAlgo *prngAlgo, void *prngContext, const RsaPublicKey *key, const uint8_t *message, size_t messageLen, uint8_t *ciphertext, size_t *ciphertextLen)
RSAES-PKCS1-v1_5 encryption operation.
Definition: rsa.c:409
error_t tlsVerifyDsaSignature(TlsContext *context, const uint8_t *digest, size_t digestLen, const uint8_t *signature, size_t signatureLen)
Verify DSA signature.
#define TLS_VERSION_1_2
Definition: tls.h:96
#define TLS_PREMASTER_SECRET_SIZE
Definition: tls.h:829
error_t tlsVerifyEd25519Signature(TlsContext *context, const DataChunk *message, uint_t messageLen, const uint8_t *signature, size_t signatureLen)
Verify Ed25519 signature.
@ TLS_KEY_EXCH_DH_ANON
Definition: tls.h:1176
#define TLS_MAX_VERSION
Definition: tls.h:136
#define STORE16BE(a, p)
Definition: cpu_endian.h:262
@ TLS_TYPE_CLIENT_HELLO
Definition: tls.h:1071
error_t tlsSelectClientVersion(TlsContext *context, const TlsServerHello *message, const TlsHelloExtensions *extensions)
Version selection.
Tls12DigitalSignature
Definition: tls.h:1785
uint16_t identifier
Definition: tls.h:2073
@ TLS_CIPHER_SUITE_TYPE_UNKNOWN
#define TLS_VERSION_1_3
Definition: tls.h:97
Handshake message processing (TLS client and server)
@ TLS_HASH_ALGO_SHA384
Definition: tls.h:1251
@ TLS_CERT_RSA_PSS_SIGN
Definition: tls.h:1233
__weak_func error_t tls12VerifyServerKeySignature(TlsContext *context, const Tls12DigitalSignature *signature, size_t length, const uint8_t *params, size_t paramsLen, size_t *consumed)
Verify server's key exchange parameters signature (TLS 1.2)
@ TLS_EMPTY_RENEGOTIATION_INFO_SCSV
TLS record protocol.
MD5 algorithm context.
Definition: md5.h:62
@ TLS_TRANSPORT_PROTOCOL_EAP
Definition: tls.h:988
@ TLS_HASH_ALGO_SHA256
Definition: tls.h:1250
@ TLS_CERT_ED448_SIGN
Definition: tls.h:1236
error_t dhCheckPublicKey(DhContext *context, const Mpi *publicKey)
Check Diffie-Hellman public value.
Definition: dh.c:245
error_t tlsFormatInitialClientHello(TlsContext *context)
Format initial ClientHello message.
@ TLS_CERT_RSA_SIGN
Definition: tls.h:1221
uint8_t length
Definition: tcp.h:375
@ TLS_KEY_EXCH_DHE_PSK
Definition: tls.h:1184
TlsCompressMethods
Definition: tls.h:1584
uint16_t dtlsTranslateVersion(uint16_t version)
Translate TLS version into DTLS version.
Definition: dtls_misc.c:112
#define MD5_DIGEST_SIZE
Definition: md5.h:45
RSA/DSA/ECDSA/EdDSA signature verification.
Hello extensions.
Definition: tls.h:2154
@ TLS_FALLBACK_SCSV
uint_t mpiGetBitLength(const Mpi *a)
Get the actual length in bits.
Definition: mpi.c:254
@ TLS_GROUP_BRAINPOOLP384R1_TLS13
Definition: tls.h:1453
error_t ecdhComputeSharedSecret(EcdhContext *context, uint8_t *output, size_t outputSize, size_t *outputLen)
Compute ECDH shared secret.
Definition: ecdh.c:415
@ ERROR_UNSUPPORTED_KEY_EXCH_ALGO
Definition: error.h:131
@ TLS_KEY_EXCH_RSA_PSK
Definition: tls.h:1183
bool_t tlsIsCipherSuiteAcceptable(const TlsCipherSuiteInfo *cipherSuite, uint16_t minVersion, uint16_t maxVersion, TlsTransportProtocol transportProtocol)
Check whether a cipher suite can be used with a given protocol version.
HashAlgoFinal final
Definition: crypto.h:1101
Data chunk descriptor.
Definition: crypto.h:1024
#define ntohs(value)
Definition: cpu_endian.h:421
error_t tlsWriteEcPoint(const EcPublicKey *publicKey, uint8_t *data, size_t *length)
Encode an EC point to an opaque vector.
Definition: tls_misc.c:1038
TlsRecord
Definition: tls.h:1798
error_t tlsVerifyEcdsaSignature(TlsContext *context, const uint8_t *digest, size_t digestLen, const uint8_t *signature, size_t signatureLen)
Verify ECDSA signature.
@ TLS_EC_CURVE_TYPE_NAMED_CURVE
Definition: tls.h:1501
#define TRACE_DEBUG(...)
Definition: debug.h:119
error_t rsassaPkcs1v15Verify(const RsaPublicKey *key, const HashAlgo *hash, const uint8_t *digest, const uint8_t *signature, size_t signatureLen)
RSASSA-PKCS1-v1_5 signature verification operation.
Definition: rsa.c:1068
#define TLS_VERSION_1_1
Definition: tls.h:95
#define SHA1_DIGEST_SIZE
Definition: sha1.h:45
__weak_func error_t tlsFormatClientKeyParams(TlsContext *context, uint8_t *p, size_t *written)
Format client's key exchange parameters.
error_t tlsReadMpi(Mpi *a, const uint8_t *data, size_t size, size_t *length)
Read a multiple precision integer from an opaque vector.
Definition: tls_misc.c:996
const char_t * tlsGetCipherSuiteName(uint16_t identifier)
Convert cipher suite identifier to string representation.
TlsServerHello
Definition: tls.h:1843
#define HTONS(value)
Definition: cpu_endian.h:410
uint8_t n
error_t rsassaPssVerify(const RsaPublicKey *key, const HashAlgo *hash, size_t saltLen, const uint8_t *digest, const uint8_t *signature, size_t signatureLen)
RSASSA-PSS signature verification operation.
Definition: rsa.c:1309
@ TLS_SIGN_SCHEME_ED448
Definition: tls.h:1304
const TlsCipherSuiteInfo tlsSupportedCipherSuites[]
@ TLS_KEY_EXCH_ECDHE_PSK
Definition: tls.h:1185
TlsClientHello
Definition: tls.h:1830
Helper functions for signature generation and verification.
TLS (Transport Layer Security)
uint8_t identifier[]
@ TLS_SIGN_ALGO_RSA
Definition: tls.h:1265
error_t tlsReadEcPoint(EcPublicKey *publicKey, const EcCurve *curve, const uint8_t *data, size_t size, size_t *length)
Read an EC point from an opaque vector.
Definition: tls_misc.c:1077
#define STORE24BE(a, p)
Definition: cpu_endian.h:273
SHA-1 algorithm context.
Definition: sha1.h:62
@ TLS_CERT_ECDSA_SIGN
Definition: tls.h:1228
@ TLS_KEY_EXCH_DHE_DSS
Definition: tls.h:1175
size_t length
Definition: crypto.h:1026
@ TLS_TRANSPORT_PROTOCOL_STREAM
Definition: tls.h:985
error_t ecdhSetCurve(EcdhContext *context, const EcCurve *curve)
Specify the elliptic curve to use.
Definition: ecdh.c:83
Common interface for hash algorithms.
Definition: crypto.h:1089
#define TLS_SIGN_ALGO(signScheme)
Definition: tls_sign_misc.h:38
FFDHE key exchange.
error_t tlsParseServerKeyParams(TlsContext *context, const uint8_t *p, size_t length, size_t *consumed)
Parse server's key exchange parameters.
#define EcCurve
Definition: ec.h:346
uint_t tlsGetNumSupportedCipherSuites(void)
Determine the number of cipher suites supported.
error_t dhGenerateKeyPair(DhContext *context, const PrngAlgo *prngAlgo, void *prngContext)
Diffie-Hellman key pair generation.
Definition: dh.c:119
TlsSignatureScheme
Signature schemes.
Definition: tls.h:1280
@ ERROR_DECODING_FAILED
Definition: error.h:242
error_t tlsFormatPskIdentity(TlsContext *context, uint8_t *p, size_t *written)
Format PSK identity.
unsigned int uint_t
Definition: compiler_port.h:57
#define TRACE_DEBUG_MPI(p, a)
Definition: debug.h:122
#define LOAD16BE(p)
Definition: cpu_endian.h:186
Handshake message processing (TLS client)
void sha1Final(Sha1Context *context, uint8_t *digest)
Finish the SHA-1 message digest.
#define tlsFreeMem(p)
Definition: tls.h:879
@ TLS_STATE_SERVER_HELLO_2
Definition: tls.h:1518
@ ERROR_INVALID_SIGNATURE
Definition: error.h:228
@ TLS_SIGN_ALGO_ECDSA
Definition: tls.h:1267
@ TLS_KEY_EXCH_DHE_RSA
Definition: tls.h:1173
#define DTLS_VERSION_1_2
Definition: dtls_misc.h:36
void md5Update(Md5Context *context, const void *data, size_t length)
Update the MD5 context with a portion of the message being hashed.
@ NO_ERROR
Success.
Definition: error.h:44
Debugging facilities.
error_t tlsFormatClientHello(TlsContext *context, TlsClientHello *message, size_t *length)
Format ClientHello message.
Definition: tls_client.c:289
#define osMemmove(dest, src, length)
Definition: os_port.h:150
uint_t tlsGetCipherSuiteType(uint16_t identifier)
Retrieve the cipher suite type for a given identifier.
error_t ecdhGenerateKeyPair(EcdhContext *context, const PrngAlgo *prngAlgo, void *prngContext)
ECDH key pair generation.
Definition: ecdh.c:115
#define arraysize(a)
Definition: os_port.h:71
error_t tlsFormatCompressMethods(TlsContext *context, uint8_t *p, size_t *written)
Format the list of compression methods supported by the client.
bool_t tlsIsTicketValid(TlsContext *context)
Check whether a session ticket is valid.