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-2026 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.6.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_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 "pkix/pem_import.h"
48 #include "pkix/x509_cert_parse.h"
49 #include "debug.h"
50 
51 //Check TLS library configuration
52 #if (TLS_SUPPORT == ENABLED && TLS_CLIENT_SUPPORT == ENABLED)
53 
54 
55 /**
56  * @brief Format initial ClientHello message
57  * @param[in] context Pointer to the TLS context
58  * @return Error code
59  **/
60 
62 {
63  error_t error;
64  size_t length;
65  TlsRecord *record;
67 
68  //Point to the buffer where to format the TLS record
69  record = (TlsRecord *) context->txBuffer;
70  //Point to the buffer where to format the handshake message
71  message = (TlsHandshake *) record->data;
72 
73  //Format ClientHello message
74  error = tlsFormatClientHello(context, (TlsClientHello *) message->data,
75  &length);
76 
77  //Check status code
78  if(!error)
79  {
80  //Set the type of the handshake message
81  message->msgType = TLS_TYPE_CLIENT_HELLO;
82  //Fix the length of the handshake message
83  STORE24BE(length, message->length);
84 
85  //Total length of the handshake message
86  length += sizeof(TlsHandshake);
87 
88  //Fix the length of the TLS record
89  record->length = htons(length);
90  }
91 
92  //Return status code
93  return error;
94 }
95 
96 
97 /**
98  * @brief Format session ID
99  * @param[in] context Pointer to the TLS context
100  * @param[in] p Output stream where to write session ID
101  * @param[out] written Total number of bytes that have been written
102  * @return Error code
103  **/
104 
106  size_t *written)
107 {
108  size_t n;
109 
110  //TLS 1.3 supported by the client?
111  if(context->versionMax >= TLS_VERSION_1_3)
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 the list of trusted authorities
315  * @param[in] context Pointer to the TLS context
316  * @param[in] p Output stream where to write the list of trusted authorities
317  * @param[out] written Total number of bytes that have been written
318  * @return Error code
319  **/
320 
322  size_t *written)
323 {
324 #if (TLS_TRUSTED_CA_KEYS_SUPPORT == ENABLED)
325  error_t error;
326  size_t n;
327  size_t pemCertLen;
328  const char_t *trustedCaList;
329  size_t trustedCaListLen;
330  uint8_t *derCert;
331  size_t derCertLen;
332  X509CertInfo *certInfo;
333  TlsTrustedAuthority *trustedAuthority;
334  TlsTrustedAuthorities *trustedAuthorities;
335 
336  //Initialize status code
337  error = NO_ERROR;
338 
339  //"TrustedAuthorities" provides a list of CA root key identifiers that the
340  //client possesses (refer to RFC 6066, section 6)
341  trustedAuthorities = (TlsTrustedAuthorities *) p;
342 
343  //Point to the first certificate authority
344  p = trustedAuthorities->value;
345  //Length of the list in bytes
346  n = 0;
347 
348  //Point to the first trusted CA certificate
349  trustedCaList = context->trustedCaList;
350  //Get the total length, in bytes, of the trusted CA list
351  trustedCaListLen = context->trustedCaListLen;
352 
353  //Allocate a memory buffer to store X.509 certificate info
354  certInfo = tlsAllocMem(sizeof(X509CertInfo));
355 
356  //Successful memory allocation?
357  if(certInfo != NULL)
358  {
359  //Loop through the list of trusted CA certificates
360  while(trustedCaListLen > 0 && error == NO_ERROR)
361  {
362  //The first pass calculates the length of the DER-encoded certificate
363  error = pemImportCertificate(trustedCaList, trustedCaListLen, NULL,
364  &derCertLen, &pemCertLen);
365 
366  //Check status code
367  if(!error)
368  {
369  //Allocate a memory buffer to hold the DER-encoded certificate
370  derCert = tlsAllocMem(derCertLen);
371 
372  //Successful memory allocation?
373  if(derCert != NULL)
374  {
375  //The second pass decodes the PEM certificate
376  error = pemImportCertificate(trustedCaList, trustedCaListLen,
377  derCert, &derCertLen, NULL);
378 
379  //Check status code
380  if(!error)
381  {
382  //Parse X.509 certificate
383  error = x509ParseCertificate(derCert, derCertLen, certInfo);
384  }
385 
386  //Valid CA certificate?
387  if(!error)
388  {
389  //Point to the CA root key identifier
390  trustedAuthority = (TlsTrustedAuthority *) p;
391 
392  //The CA root key is identified via a distinguished name
393  trustedAuthority->type = TLS_CA_ROOT_KEY_ID_TYPE_X509_NAME;
394 
395  //Each distinguished name is preceded by a 2-byte length field
396  STORE16BE(certInfo->tbsCert.subject.raw.length,
397  trustedAuthority->identifier);
398 
399  //The distinguished name shall be DER-encoded
400  osMemcpy(trustedAuthority->identifier + 2,
401  certInfo->tbsCert.subject.raw.value,
402  certInfo->tbsCert.subject.raw.length);
403 
404  //Advance write pointer
405  p += sizeof(TlsTrustedAuthority) + 2 + certInfo->tbsCert.subject.raw.length;
406  n += sizeof(TlsTrustedAuthority) + 2 + certInfo->tbsCert.subject.raw.length;
407  }
408  else
409  {
410  //Discard current CA certificate
411  error = NO_ERROR;
412  }
413 
414  //Free previously allocated memory
415  tlsFreeMem(derCert);
416  }
417  else
418  {
419  //Failed to allocate memory
420  error = ERROR_OUT_OF_MEMORY;
421  }
422 
423  //Advance read pointer
424  trustedCaList += pemCertLen;
425  trustedCaListLen -= pemCertLen;
426  }
427  else
428  {
429  //End of file detected
430  trustedCaListLen = 0;
431  error = NO_ERROR;
432  }
433  }
434 
435  //Fix the length of the list
436  trustedAuthorities->length = htons(n);
437 
438  //Free previously allocated memory
439  tlsFreeMem(certInfo);
440  }
441  else
442  {
443  //Failed to allocate memory
444  error = ERROR_OUT_OF_MEMORY;
445  }
446 
447  //Check status code
448  if(!error)
449  {
450  //Total number of bytes that have been written
451  *written = sizeof(TlsTrustedAuthorities) + n;
452  }
453 
454  //Return status code
455  return error;
456 #else
457  //Not implemented
458  return ERROR_NOT_IMPLEMENTED;
459 #endif
460 }
461 
462 
463 /**
464  * @brief Format PSK identity
465  * @param[in] context Pointer to the TLS context
466  * @param[in] p Output stream where to write the PSK identity hint
467  * @param[out] written Total number of bytes that have been written
468  * @return Error code
469  **/
470 
472  size_t *written)
473 {
474  size_t n;
475  TlsPskIdentity *pskIdentity;
476 
477  //Point to the PSK identity
478  pskIdentity = (TlsPskIdentity *) p;
479 
480 #if (TLS_PSK_KE_SUPPORT == ENABLED || TLS_RSA_PSK_KE_SUPPORT == ENABLED || \
481  TLS_DHE_PSK_KE_SUPPORT == ENABLED || TLS_ECDHE_PSK_KE_SUPPORT == ENABLED)
482  //Any PSK identity defined?
483  if(context->pskIdentity != NULL)
484  {
485  //Determine the length of the PSK identity
486  n = osStrlen(context->pskIdentity);
487  //Copy PSK identity
488  osMemcpy(pskIdentity->value, context->pskIdentity, n);
489  }
490  else
491 #endif
492  {
493  //No PSK identity is provided
494  n = 0;
495  }
496 
497  //The PSK identity is preceded by a 2-byte length field
498  pskIdentity->length = htons(n);
499 
500  //Total number of bytes that have been written
501  *written = sizeof(TlsPskIdentity) + n;
502 
503  //Successful processing
504  return NO_ERROR;
505 }
506 
507 
508 /**
509  * @brief Format client's key exchange parameters
510  * @param[in] context Pointer to the TLS context
511  * @param[in] p Output stream where to write the client's key exchange parameters
512  * @param[out] written Total number of bytes that have been written
513  * @return Error code
514  **/
515 
516 __weak_func error_t tlsFormatClientKeyParams(TlsContext *context, uint8_t *p,
517  size_t *written)
518 {
519 #if (TLS_MAX_VERSION >= TLS_VERSION_1_0 && TLS_MIN_VERSION <= TLS_VERSION_1_2)
520  error_t error;
521  size_t n;
522 
523 #if (TLS_RSA_KE_SUPPORT == ENABLED || TLS_RSA_PSK_KE_SUPPORT == ENABLED)
524  //RSA key exchange method?
525  if(context->keyExchMethod == TLS_KEY_EXCH_RSA ||
526  context->keyExchMethod == TLS_KEY_EXCH_RSA_PSK)
527  {
528  //If RSA is being used for key agreement and authentication, the
529  //client generates a 48-byte premaster secret
530  context->premasterSecretLen = 48;
531 
532  //The first 2 bytes code the latest version supported by the client
533  STORE16BE(context->clientVersion, context->premasterSecret);
534 
535  //The last 46 bytes contain securely-generated random bytes
536  error = context->prngAlgo->generate(context->prngContext,
537  context->premasterSecret + 2, 46);
538  //Any error to report?
539  if(error)
540  return error;
541 
542  //Encrypt the premaster secret using the server public key
543  error = rsaesPkcs1v15Encrypt(context->prngAlgo, context->prngContext,
544  &context->peerRsaPublicKey, context->premasterSecret, 48, p + 2, &n);
545  //RSA encryption failed?
546  if(error)
547  return error;
548 
549  //The RSA-encrypted premaster secret in a ClientKeyExchange is preceded by
550  //two length bytes
551  STORE16BE(n, p);
552 
553  //Total number of bytes that have been written
554  *written = n + 2;
555  }
556  else
557 #endif
558 #if (TLS_DH_ANON_KE_SUPPORT == ENABLED || TLS_DHE_RSA_KE_SUPPORT == ENABLED || \
559  TLS_DHE_DSS_KE_SUPPORT == ENABLED || TLS_DHE_PSK_KE_SUPPORT == ENABLED)
560  //Diffie-Hellman key exchange method?
561  if(context->keyExchMethod == TLS_KEY_EXCH_DH_ANON ||
562  context->keyExchMethod == TLS_KEY_EXCH_DHE_RSA ||
563  context->keyExchMethod == TLS_KEY_EXCH_DHE_DSS ||
564  context->keyExchMethod == TLS_KEY_EXCH_DHE_PSK)
565  {
566  //Generate an ephemeral key pair
567  error = dhGenerateKeyPair(&context->dhContext,
568  context->prngAlgo, context->prngContext);
569  //Any error to report?
570  if(error)
571  return error;
572 
573  //Encode the client's public value to an opaque vector
574  error = tlsWriteMpi(&context->dhContext.ya, p, &n);
575  //Any error to report?
576  if(error)
577  return error;
578 
579  //Total number of bytes that have been written
580  *written = n;
581 
582  //Calculate the negotiated key Z
583  error = dhComputeSharedSecret(&context->dhContext,
584  context->premasterSecret, TLS_PREMASTER_SECRET_SIZE,
585  &context->premasterSecretLen);
586  //Any error to report?
587  if(error)
588  return error;
589 
590  //Leading bytes of Z that contain all zero bits are stripped before
591  //it is used as the premaster secret (RFC 4346, section 8.2.1)
592  for(n = 0; n < context->premasterSecretLen; n++)
593  {
594  if(context->premasterSecret[n] != 0x00)
595  break;
596  }
597 
598  //Any leading zero bytes?
599  if(n > 0)
600  {
601  //Strip leading zero bytes from the negotiated key
602  osMemmove(context->premasterSecret, context->premasterSecret + n,
603  context->premasterSecretLen - n);
604 
605  //Adjust the length of the premaster secret
606  context->premasterSecretLen -= n;
607  }
608  }
609  else
610 #endif
611 #if (TLS_ECDH_ANON_KE_SUPPORT == ENABLED || TLS_ECDHE_RSA_KE_SUPPORT == ENABLED || \
612  TLS_ECDHE_ECDSA_KE_SUPPORT == ENABLED || TLS_ECDHE_PSK_KE_SUPPORT == ENABLED)
613  //ECDH key exchange method?
614  if(context->keyExchMethod == TLS_KEY_EXCH_ECDH_ANON ||
615  context->keyExchMethod == TLS_KEY_EXCH_ECDHE_RSA ||
616  context->keyExchMethod == TLS_KEY_EXCH_ECDHE_ECDSA ||
617  context->keyExchMethod == TLS_KEY_EXCH_ECDHE_PSK)
618  {
619 #if (TLS_ECC_CALLBACK_SUPPORT == ENABLED)
620  //Any registered callback?
621  if(context->ecdhCallback != NULL)
622  {
623  //Invoke user callback function
624  error = context->ecdhCallback(context);
625  }
626  else
627 #endif
628  {
629  //No callback function defined
631  }
632 
633  //Check status code
635  {
636  //Generate an ephemeral key pair
637  error = ecdhGenerateKeyPair(&context->ecdhContext,
638  context->prngAlgo, context->prngContext);
639  //Any error to report?
640  if(error)
641  return error;
642 
643  //Calculate the negotiated key Z
644  error = ecdhComputeSharedSecret(&context->ecdhContext,
645  context->premasterSecret, TLS_PREMASTER_SECRET_SIZE,
646  &context->premasterSecretLen);
647  //Any error to report?
648  if(error)
649  return error;
650  }
651  else if(error != NO_ERROR)
652  {
653  //Report an error
654  return error;
655  }
656 
657  //Encode the client's public key to an opaque vector
658  error = tlsWriteEcPoint(&context->ecdhContext.da.q, p, &n);
659  //Any error to report?
660  if(error)
661  return error;
662 
663  //Total number of bytes that have been written
664  *written = n;
665  }
666  else
667 #endif
668  //Invalid key exchange method?
669  {
670  //Just for sanity
671  (void) error;
672  (void) n;
673 
674  //The specified key exchange method is not supported
676  }
677 
678  //Successful processing
679  return NO_ERROR;
680 #else
681  //Not implemented
682  return ERROR_NOT_IMPLEMENTED;
683 #endif
684 }
685 
686 
687 /**
688  * @brief Parse PSK identity hint
689  * @param[in] context Pointer to the TLS context
690  * @param[in] p Input stream where to read the PSK identity hint
691  * @param[in] length Number of bytes available in the input stream
692  * @param[out] consumed Total number of bytes that have been consumed
693  * @return Error code
694  **/
695 
696 error_t tlsParsePskIdentityHint(TlsContext *context, const uint8_t *p,
697  size_t length, size_t *consumed)
698 {
699  size_t n;
700  TlsPskIdentityHint *pskIdentityHint;
701 
702  //Point to the PSK identity hint
703  pskIdentityHint = (TlsPskIdentityHint *) p;
704 
705  //Malformed ServerKeyExchange message?
706  if(length < sizeof(TlsPskIdentityHint))
707  return ERROR_DECODING_FAILED;
708  if(length < (sizeof(TlsPskIdentityHint) + ntohs(pskIdentityHint->length)))
709  return ERROR_DECODING_FAILED;
710 
711  //Retrieve the length of the PSK identity hint
712  n = ntohs(pskIdentityHint->length);
713 
714 #if (TLS_PSK_KE_SUPPORT == ENABLED || TLS_RSA_PSK_KE_SUPPORT == ENABLED || \
715  TLS_DHE_PSK_KE_SUPPORT == ENABLED || TLS_ECDHE_PSK_KE_SUPPORT == ENABLED)
716  //Any registered callback?
717  if(context->pskCallback != NULL)
718  {
719  error_t error;
720 
721  //The client selects which identity to use depending on the PSK identity
722  //hint provided by the server
723  error = context->pskCallback(context, pskIdentityHint->value, n);
724  //Any error to report?
725  if(error)
726  return ERROR_UNKNOWN_IDENTITY;
727  }
728 #endif
729 
730  //Total number of bytes that have been consumed
731  *consumed = sizeof(TlsPskIdentityHint) + n;
732 
733  //Successful processing
734  return NO_ERROR;
735 }
736 
737 
738 /**
739  * @brief Parse server's key exchange parameters
740  * @param[in] context Pointer to the TLS context
741  * @param[in] p Input stream where to read the server's key exchange parameters
742  * @param[in] length Number of bytes available in the input stream
743  * @param[out] consumed Total number of bytes that have been consumed
744  * @return Error code
745  **/
746 
747 error_t tlsParseServerKeyParams(TlsContext *context, const uint8_t *p,
748  size_t length, size_t *consumed)
749 {
750 #if (TLS_MAX_VERSION >= TLS_VERSION_1_0 && TLS_MIN_VERSION <= TLS_VERSION_1_2)
751  error_t error;
752  const uint8_t *params;
753 
754  //Initialize status code
755  error = NO_ERROR;
756 
757  //Point to the server's key exchange parameters
758  params = p;
759 
760 #if (TLS_DH_ANON_KE_SUPPORT == ENABLED || TLS_DHE_RSA_KE_SUPPORT == ENABLED || \
761  TLS_DHE_DSS_KE_SUPPORT == ENABLED || TLS_DHE_PSK_KE_SUPPORT == ENABLED)
762  //Diffie-Hellman key exchange method?
763  if(context->keyExchMethod == TLS_KEY_EXCH_DH_ANON ||
764  context->keyExchMethod == TLS_KEY_EXCH_DHE_RSA ||
765  context->keyExchMethod == TLS_KEY_EXCH_DHE_DSS ||
766  context->keyExchMethod == TLS_KEY_EXCH_DHE_PSK)
767  {
768  uint_t k;
769  size_t n;
770 
771  //Convert the prime modulus to a multiple precision integer
772  error = tlsReadMpi(&context->dhContext.params.p, p, length, &n);
773 
774  //Check status code
775  if(!error)
776  {
777  //Get the length of the prime modulus, in bits
778  k = mpiGetBitLength(&context->dhContext.params.p);
779 
780  //Make sure the prime modulus is acceptable
781  if(k < TLS_MIN_DH_MODULUS_SIZE || k > TLS_MAX_DH_MODULUS_SIZE)
782  {
783  error = ERROR_ILLEGAL_PARAMETER;
784  }
785  }
786 
787  //Check status code
788  if(!error)
789  {
790  //Advance data pointer
791  p += n;
792  //Remaining bytes to process
793  length -= n;
794 
795  //Convert the generator to a multiple precision integer
796  error = tlsReadMpi(&context->dhContext.params.g, p, length, &n);
797  }
798 
799  //Check status code
800  if(!error)
801  {
802  //Advance data pointer
803  p += n;
804  //Remaining bytes to process
805  length -= n;
806 
807  //Convert the server's public value to a multiple precision integer
808  error = tlsReadMpi(&context->dhContext.yb, p, length, &n);
809  }
810 
811  //Check status code
812  if(!error)
813  {
814  //Advance data pointer
815  p += n;
816  //Remaining bytes to process
817  length -= n;
818 
819  //Verify peer's public value
820  error = dhCheckPublicKey(&context->dhContext,
821  &context->dhContext.yb);
822  }
823 
824  //Check status code
825  if(!error)
826  {
827  //Debug message
828  TRACE_DEBUG("Diffie-Hellman parameters:\r\n");
829  TRACE_DEBUG(" Prime modulus:\r\n");
830  TRACE_DEBUG_MPI(" ", &context->dhContext.params.p);
831  TRACE_DEBUG(" Generator:\r\n");
832  TRACE_DEBUG_MPI(" ", &context->dhContext.params.g);
833  TRACE_DEBUG(" Server public value:\r\n");
834  TRACE_DEBUG_MPI(" ", &context->dhContext.yb);
835  }
836  }
837  else
838 #endif
839 #if (TLS_ECDH_ANON_KE_SUPPORT == ENABLED || TLS_ECDHE_RSA_KE_SUPPORT == ENABLED || \
840  TLS_ECDHE_ECDSA_KE_SUPPORT == ENABLED || TLS_ECDHE_PSK_KE_SUPPORT == ENABLED)
841  //ECDH key exchange method?
842  if(context->keyExchMethod == TLS_KEY_EXCH_ECDH_ANON ||
843  context->keyExchMethod == TLS_KEY_EXCH_ECDHE_RSA ||
844  context->keyExchMethod == TLS_KEY_EXCH_ECDHE_ECDSA ||
845  context->keyExchMethod == TLS_KEY_EXCH_ECDHE_PSK)
846  {
847  size_t n;
848  uint8_t curveType;
849  const EcCurve *curve;
850 
851  //Initialize curve parameters
852  curve = NULL;
853 
854  //Malformed ServerKeyExchange message?
855  if(length < sizeof(curveType))
856  {
857  error = ERROR_DECODING_FAILED;
858  }
859 
860  //Check status code
861  if(!error)
862  {
863  //Retrieve the type of the elliptic curve domain parameters
864  curveType = *p;
865 
866  //Advance data pointer
867  p += sizeof(curveType);
868  //Remaining bytes to process
869  length -= sizeof(curveType);
870 
871  //Only named curves are supported
872  if(curveType != TLS_EC_CURVE_TYPE_NAMED_CURVE)
873  {
874  error = ERROR_ILLEGAL_PARAMETER;
875  }
876  }
877 
878  //Check status code
879  if(!error)
880  {
881  //Malformed ServerKeyExchange message?
882  if(length < sizeof(uint16_t))
883  {
884  error = ERROR_DECODING_FAILED;
885  }
886  }
887 
888  //Check status code
889  if(!error)
890  {
891  //Get elliptic curve identifier
892  context->namedGroup = LOAD16BE(p);
893 
894  //Advance data pointer
895  p += sizeof(uint16_t);
896  //Remaining bytes to process
897  length -= sizeof(uint16_t);
898 
899  //TLS 1.3 group?
900  if(context->namedGroup == TLS_GROUP_BRAINPOOLP256R1_TLS13 ||
901  context->namedGroup == TLS_GROUP_BRAINPOOLP384R1_TLS13 ||
902  context->namedGroup == TLS_GROUP_BRAINPOOLP512R1_TLS13 ||
903  context->namedGroup == TLS_GROUP_CURVE_SM2)
904  {
905  //These elliptic curves do not apply to any older versions of TLS
906  error = ERROR_ILLEGAL_PARAMETER;
907  }
908  else
909  {
910  //Retrieve the corresponding EC domain parameters
911  curve = tlsGetCurve(context, context->namedGroup);
912 
913  //Make sure the elliptic curve is supported
914  if(curve == NULL)
915  {
916  //The elliptic curve is not supported
917  error = ERROR_ILLEGAL_PARAMETER;
918  }
919  }
920  }
921 
922  //Check status code
923  if(!error)
924  {
925  //Save elliptic curve parameters
926  error = ecdhSetCurve(&context->ecdhContext, curve);
927  }
928 
929  //Check status code
930  if(!error)
931  {
932  //Read server's public key
933  error = tlsReadEcPoint(&context->ecdhContext.qb, curve, p, length, &n);
934  }
935 
936  //Check status code
937  if(!error)
938  {
939  //Advance data pointer
940  p += n;
941  //Remaining bytes to process
942  length -= n;
943 
944  //Verify peer's public key
945  error = ecdhCheckPublicKey(&context->ecdhContext,
946  &context->ecdhContext.qb);
947  }
948  }
949  else
950 #endif
951  //Invalid key exchange method?
952  {
953  //It is not legal to send the ServerKeyExchange message when a key
954  //exchange method other than DHE_DSS, DHE_RSA, DH_anon, ECDHE_RSA,
955  //ECDHE_ECDSA or ECDH_anon is selected
956  error = ERROR_UNEXPECTED_MESSAGE;
957  }
958 
959  //Total number of bytes that have been consumed
960  *consumed = p - params;
961 
962  //Return status code
963  return error;
964 #else
965  //Not implemented
966  return ERROR_NOT_IMPLEMENTED;
967 #endif
968 }
969 
970 
971 /**
972  * @brief Verify server's key exchange parameters signature (TLS 1.0 and TLS 1.1)
973  * @param[in] context Pointer to the TLS context
974  * @param[in] signature Pointer to the digital signature
975  * @param[in] length Number of bytes available in the input stream
976  * @param[in] params Pointer to the server's key exchange parameters
977  * @param[in] paramsLen Length of the server's key exchange parameters
978  * @param[out] consumed Total number of bytes that have been consumed
979  * @return Error code
980  **/
981 
983  const TlsDigitalSignature *signature, size_t length,
984  const uint8_t *params, size_t paramsLen, size_t *consumed)
985 {
986  error_t error;
987 
988 #if (TLS_MAX_VERSION >= TLS_VERSION_1_0 && TLS_MIN_VERSION <= TLS_VERSION_1_1)
989  //Initialize status code
990  error = NO_ERROR;
991 
992  //Check the length of the digitally-signed element
993  if(length < sizeof(TlsDigitalSignature))
994  return ERROR_DECODING_FAILED;
995  if(length < (sizeof(TlsDigitalSignature) + ntohs(signature->length)))
996  return ERROR_DECODING_FAILED;
997 
998 #if (TLS_RSA_SIGN_SUPPORT == ENABLED)
999  //RSA signature algorithm?
1000  if(context->peerCertType == TLS_CERT_RSA_SIGN)
1001  {
1002  Md5Context *md5Context;
1003  Sha1Context *sha1Context;
1004 
1005  //Allocate a memory buffer to hold the MD5 context
1006  md5Context = tlsAllocMem(sizeof(Md5Context));
1007 
1008  //Successful memory allocation?
1009  if(md5Context != NULL)
1010  {
1011  //Compute MD5(ClientHello.random + ServerHello.random +
1012  //ServerKeyExchange.params)
1013  md5Init(md5Context);
1014  md5Update(md5Context, context->clientRandom, TLS_RANDOM_SIZE);
1015  md5Update(md5Context, context->serverRandom, TLS_RANDOM_SIZE);
1016  md5Update(md5Context, params, paramsLen);
1017  md5Final(md5Context, context->serverVerifyData);
1018 
1019  //Release previously allocated memory
1020  tlsFreeMem(md5Context);
1021  }
1022  else
1023  {
1024  //Failed to allocate memory
1025  error = ERROR_OUT_OF_MEMORY;
1026  }
1027 
1028  //Check status code
1029  if(!error)
1030  {
1031  //Allocate a memory buffer to hold the SHA-1 context
1032  sha1Context = tlsAllocMem(sizeof(Sha1Context));
1033 
1034  //Successful memory allocation?
1035  if(sha1Context != NULL)
1036  {
1037  //Compute SHA(ClientHello.random + ServerHello.random +
1038  //ServerKeyExchange.params)
1039  sha1Init(sha1Context);
1040  sha1Update(sha1Context, context->clientRandom, TLS_RANDOM_SIZE);
1041  sha1Update(sha1Context, context->serverRandom, TLS_RANDOM_SIZE);
1042  sha1Update(sha1Context, params, paramsLen);
1043  sha1Final(sha1Context, context->serverVerifyData + MD5_DIGEST_SIZE);
1044 
1045  //Release previously allocated memory
1046  tlsFreeMem(sha1Context);
1047  }
1048  else
1049  {
1050  //Failed to allocate memory
1051  error = ERROR_OUT_OF_MEMORY;
1052  }
1053  }
1054 
1055  //Check status code
1056  if(!error)
1057  {
1058  //RSA signature verification
1059  error = tlsVerifyRsaSignature(&context->peerRsaPublicKey,
1060  context->serverVerifyData, signature->value, ntohs(signature->length));
1061  }
1062  }
1063  else
1064 #endif
1065 #if (TLS_DSA_SIGN_SUPPORT == ENABLED)
1066  //DSA signature algorithm?
1067  if(context->peerCertType == TLS_CERT_DSS_SIGN)
1068  {
1069  Sha1Context *sha1Context;
1070 
1071  //Allocate a memory buffer to hold the SHA-1 context
1072  sha1Context = tlsAllocMem(sizeof(Sha1Context));
1073 
1074  //Successful memory allocation?
1075  if(sha1Context != NULL)
1076  {
1077  //Compute SHA(ClientHello.random + ServerHello.random +
1078  //ServerKeyExchange.params)
1079  sha1Init(sha1Context);
1080  sha1Update(sha1Context, context->clientRandom, TLS_RANDOM_SIZE);
1081  sha1Update(sha1Context, context->serverRandom, TLS_RANDOM_SIZE);
1082  sha1Update(sha1Context, params, paramsLen);
1083  sha1Final(sha1Context, context->serverVerifyData);
1084 
1085  //Release previously allocated memory
1086  tlsFreeMem(sha1Context);
1087  }
1088  else
1089  {
1090  //Failed to allocate memory
1091  error = ERROR_OUT_OF_MEMORY;
1092  }
1093 
1094  //Check status code
1095  if(!error)
1096  {
1097  //DSA signature verification
1098  error = tlsVerifyDsaSignature(context, context->serverVerifyData,
1099  SHA1_DIGEST_SIZE, signature->value, ntohs(signature->length));
1100  }
1101  }
1102  else
1103 #endif
1104 #if (TLS_ECDSA_SIGN_SUPPORT == ENABLED)
1105  //ECDSA signature algorithm?
1106  if(context->peerCertType == TLS_CERT_ECDSA_SIGN)
1107  {
1108  Sha1Context *sha1Context;
1109 
1110  //Allocate a memory buffer to hold the SHA-1 context
1111  sha1Context = tlsAllocMem(sizeof(Sha1Context));
1112 
1113  //Successful memory allocation?
1114  if(sha1Context != NULL)
1115  {
1116  //Compute SHA(ClientHello.random + ServerHello.random +
1117  //ServerKeyExchange.params)
1118  sha1Init(sha1Context);
1119  sha1Update(sha1Context, context->clientRandom, TLS_RANDOM_SIZE);
1120  sha1Update(sha1Context, context->serverRandom, TLS_RANDOM_SIZE);
1121  sha1Update(sha1Context, params, paramsLen);
1122  sha1Final(sha1Context, context->serverVerifyData);
1123 
1124  //Release previously allocated memory
1125  tlsFreeMem(sha1Context);
1126  }
1127 
1128  //Check status code
1129  if(!error)
1130  {
1131  //ECDSA signature verification
1132  error = tlsVerifyEcdsaSignature(context, context->serverVerifyData,
1133  SHA1_DIGEST_SIZE, signature->value, ntohs(signature->length));
1134  }
1135  }
1136  else
1137 #endif
1138  //Invalid signature algorithm?
1139  {
1140  //Report an error
1141  error = ERROR_INVALID_SIGNATURE;
1142  }
1143 
1144  //Total number of bytes that have been consumed
1145  *consumed = sizeof(TlsDigitalSignature) + ntohs(signature->length);
1146 #else
1147  //Not implemented
1148  error = ERROR_NOT_IMPLEMENTED;
1149 #endif
1150 
1151  //Return status code
1152  return error;
1153 }
1154 
1155 
1156 /**
1157  * @brief Verify server's key exchange parameters signature (TLS 1.2)
1158  * @param[in] context Pointer to the TLS context
1159  * @param[in] signature Pointer to the digital signature
1160  * @param[in] length Number of bytes available in the input stream
1161  * @param[in] params Pointer to the server's key exchange parameters
1162  * @param[in] paramsLen Length of the server's key exchange parameters
1163  * @param[out] consumed Total number of bytes that have been consumed
1164  * @return Error code
1165  **/
1166 
1168  const Tls12DigitalSignature *signature, size_t length,
1169  const uint8_t *params, size_t paramsLen, size_t *consumed)
1170 {
1171 #if (TLS_MAX_VERSION >= TLS_VERSION_1_2 && TLS_MIN_VERSION <= TLS_VERSION_1_2)
1172  error_t error;
1173  TlsSignatureScheme signScheme;
1174 
1175  //Initialize status code
1176  error = NO_ERROR;
1177 
1178  //Check the length of the digitally-signed element
1179  if(length < sizeof(Tls12DigitalSignature))
1180  return ERROR_DECODING_FAILED;
1181  if(length < (sizeof(Tls12DigitalSignature) + ntohs(signature->length)))
1182  return ERROR_DECODING_FAILED;
1183 
1184  //The algorithm field specifies the signature scheme
1185  signScheme = (TlsSignatureScheme) ntohs(signature->algorithm);
1186 
1187  //If the client has offered the SignatureAlgorithms extension, the signature
1188  //algorithm and hash algorithm must be a pair listed in that extension (refer
1189  //to RFC 5246, section 7.4.3)
1190  if(!tlsIsSignAlgoSupported(context, signScheme))
1191  return ERROR_ILLEGAL_PARAMETER;
1192 
1193 #if (TLS_RSA_SIGN_SUPPORT == ENABLED || TLS_RSA_PSS_SIGN_SUPPORT == ENABLED || \
1194  TLS_DSA_SIGN_SUPPORT == ENABLED || TLS_ECDSA_SIGN_SUPPORT == ENABLED)
1195  //RSA, DSA or ECDSA signature scheme?
1196  if(TLS_SIGN_ALGO(signScheme) == TLS_SIGN_ALGO_RSA ||
1197  TLS_SIGN_ALGO(signScheme) == TLS_SIGN_ALGO_DSA ||
1198  TLS_SIGN_ALGO(signScheme) == TLS_SIGN_ALGO_ECDSA ||
1199  signScheme == TLS_SIGN_SCHEME_RSA_PSS_RSAE_SHA256 ||
1200  signScheme == TLS_SIGN_SCHEME_RSA_PSS_RSAE_SHA384 ||
1201  signScheme == TLS_SIGN_SCHEME_RSA_PSS_RSAE_SHA512 ||
1202  signScheme == TLS_SIGN_SCHEME_RSA_PSS_PSS_SHA256 ||
1203  signScheme == TLS_SIGN_SCHEME_RSA_PSS_PSS_SHA384 ||
1204  signScheme == TLS_SIGN_SCHEME_RSA_PSS_PSS_SHA512)
1205  {
1206  const HashAlgo *hashAlgo;
1207  HashContext *hashContext;
1208  uint8_t digest[MAX_HASH_DIGEST_SIZE];
1209 
1210  //Check signature scheme
1211  if(signScheme == TLS_SIGN_SCHEME_RSA_PSS_RSAE_SHA256 ||
1212  signScheme == TLS_SIGN_SCHEME_RSA_PSS_PSS_SHA256)
1213  {
1214  //The hashing is intrinsic to the signature algorithm
1216  }
1217  else if(signScheme == TLS_SIGN_SCHEME_RSA_PSS_RSAE_SHA384 ||
1218  signScheme == TLS_SIGN_SCHEME_RSA_PSS_PSS_SHA384)
1219  {
1220  //The hashing is intrinsic to the signature algorithm
1222  }
1223  else if(signScheme == TLS_SIGN_SCHEME_RSA_PSS_RSAE_SHA512 ||
1224  signScheme == TLS_SIGN_SCHEME_RSA_PSS_PSS_SHA512)
1225  {
1226  //The hashing is intrinsic to the signature algorithm
1228  }
1229  else
1230  {
1231  //Retrieve the hash algorithm used for signing
1232  hashAlgo = tlsGetHashAlgo(TLS_HASH_ALGO(signScheme));
1233  }
1234 
1235  //Make sure the hash algorithm is supported
1236  if(hashAlgo != NULL)
1237  {
1238  //Allocate a memory buffer to hold the hash context
1239  hashContext = tlsAllocMem(hashAlgo->contextSize);
1240 
1241  //Successful memory allocation?
1242  if(hashContext != NULL)
1243  {
1244  //Compute hash(ClientHello.random + ServerHello.random +
1245  //ServerKeyExchange.params)
1246  hashAlgo->init(hashContext);
1247  hashAlgo->update(hashContext, context->clientRandom, TLS_RANDOM_SIZE);
1248  hashAlgo->update(hashContext, context->serverRandom, TLS_RANDOM_SIZE);
1249  hashAlgo->update(hashContext, params, paramsLen);
1250  hashAlgo->final(hashContext, digest);
1251 
1252 #if (TLS_RSA_SIGN_SUPPORT == ENABLED)
1253  //RSASSA-PKCS1-v1_5 signature scheme?
1254  if(TLS_SIGN_ALGO(signScheme) == TLS_SIGN_ALGO_RSA &&
1255  context->peerCertType == TLS_CERT_RSA_SIGN)
1256  {
1257  //Verify RSA signature (RSASSA-PKCS1-v1_5 signature scheme)
1258  error = rsassaPkcs1v15Verify(&context->peerRsaPublicKey,
1259  hashAlgo, digest, signature->value, ntohs(signature->length));
1260  }
1261  else
1262 #endif
1263 #if (TLS_RSA_PSS_SIGN_SUPPORT == ENABLED)
1264  //RSASSA-PSS signature scheme (with public key OID rsaEncryption)?
1265  if(signScheme == TLS_SIGN_SCHEME_RSA_PSS_RSAE_SHA256 ||
1266  signScheme == TLS_SIGN_SCHEME_RSA_PSS_RSAE_SHA384 ||
1268  {
1269  //The signature algorithm must be compatible with the key in the
1270  //server's end-entity certificate (refer to RFC 5246, section 7.4.3)
1271  if(context->peerCertType == TLS_CERT_RSA_SIGN)
1272  {
1273  //Verify RSA signature (RSASSA-PSS signature scheme)
1274  error = rsassaPssVerify(&context->peerRsaPublicKey, hashAlgo,
1275  hashAlgo->digestSize, digest, signature->value,
1276  ntohs(signature->length));
1277  }
1278  else
1279  {
1280  //Invalid certificate
1281  error = ERROR_INVALID_SIGNATURE;
1282  }
1283  }
1284  else
1285 #endif
1286 #if (TLS_RSA_PSS_SIGN_SUPPORT == ENABLED)
1287  //RSASSA-PSS signature scheme (with public key OID RSASSA-PSS)?
1288  if(signScheme == TLS_SIGN_SCHEME_RSA_PSS_PSS_SHA256 ||
1289  signScheme == TLS_SIGN_SCHEME_RSA_PSS_PSS_SHA384 ||
1290  signScheme == TLS_SIGN_SCHEME_RSA_PSS_PSS_SHA512)
1291  {
1292  //The signature algorithm must be compatible with the key in the
1293  //server's end-entity certificate (refer to RFC 5246, section 7.4.3)
1294  if(context->peerCertType == TLS_CERT_RSA_PSS_SIGN)
1295  {
1296  //Verify RSA signature (RSASSA-PSS signature scheme)
1297  error = rsassaPssVerify(&context->peerRsaPublicKey, hashAlgo,
1298  hashAlgo->digestSize, digest, signature->value,
1299  ntohs(signature->length));
1300  }
1301  else
1302  {
1303  //Invalid certificate
1304  error = ERROR_INVALID_SIGNATURE;
1305  }
1306  }
1307  else
1308 #endif
1309 #if (TLS_DSA_SIGN_SUPPORT == ENABLED)
1310  //DSA signature scheme?
1311  if(TLS_SIGN_ALGO(signScheme) == TLS_SIGN_ALGO_DSA &&
1312  context->peerCertType == TLS_CERT_DSS_SIGN)
1313  {
1314  //Verify DSA signature
1315  error = tlsVerifyDsaSignature(context, digest,
1316  hashAlgo->digestSize, signature->value,
1317  ntohs(signature->length));
1318  }
1319  else
1320 #endif
1321 #if (TLS_ECDSA_SIGN_SUPPORT == ENABLED)
1322  //ECDSA signature scheme?
1323  if(TLS_SIGN_ALGO(signScheme) == TLS_SIGN_ALGO_ECDSA &&
1324  context->peerCertType == TLS_CERT_ECDSA_SIGN)
1325  {
1326  //Verify ECDSA signature
1327  error = tlsVerifyEcdsaSignature(context, digest,
1328  hashAlgo->digestSize, signature->value,
1329  ntohs(signature->length));
1330  }
1331  else
1332 #endif
1333  //Invalid signature scheme?
1334  {
1335  //Report an error
1336  error = ERROR_INVALID_SIGNATURE;
1337  }
1338 
1339  //Release previously allocated memory
1340  tlsFreeMem(hashContext);
1341  }
1342  else
1343  {
1344  //Failed to allocate memory
1345  error = ERROR_OUT_OF_MEMORY;
1346  }
1347  }
1348  else
1349  {
1350  //Hash algorithm not supported
1351  error = ERROR_INVALID_SIGNATURE;
1352  }
1353  }
1354  else
1355 #endif
1356 #if (TLS_ED25519_SIGN_SUPPORT == ENABLED)
1357  //Ed25519 signature scheme?
1358  if(signScheme == TLS_SIGN_SCHEME_ED25519 &&
1359  context->peerCertType == TLS_CERT_ED25519_SIGN)
1360  {
1361  DataChunk messageChunks[3];
1362 
1363  //Data to be verified is run through the EdDSA algorithm without
1364  //pre-hashing
1365  messageChunks[0].buffer = context->clientRandom;
1366  messageChunks[0].length = TLS_RANDOM_SIZE;
1367  messageChunks[1].buffer = context->serverRandom;
1368  messageChunks[1].length = TLS_RANDOM_SIZE;
1369  messageChunks[2].buffer = params;
1370  messageChunks[2].length = paramsLen;
1371 
1372  //Verify Ed25519 signature (PureEdDSA mode)
1373  error = tlsVerifyEd25519Signature(context, messageChunks,
1374  arraysize(messageChunks), signature->value, ntohs(signature->length));
1375  }
1376  else
1377 #endif
1378 #if (TLS_ED448_SIGN_SUPPORT == ENABLED)
1379  //Ed448 signature scheme?
1380  if(signScheme == TLS_SIGN_SCHEME_ED448 &&
1381  context->peerCertType == TLS_CERT_ED448_SIGN)
1382  {
1383  DataChunk messageChunks[3];
1384 
1385  //Data to be verified is run through the EdDSA algorithm without
1386  //pre-hashing
1387  messageChunks[0].buffer = context->clientRandom;
1388  messageChunks[0].length = TLS_RANDOM_SIZE;
1389  messageChunks[1].buffer = context->serverRandom;
1390  messageChunks[1].length = TLS_RANDOM_SIZE;
1391  messageChunks[2].buffer = params;
1392  messageChunks[2].length = paramsLen;
1393 
1394  //Verify Ed448 signature (PureEdDSA mode)
1395  error = tlsVerifyEd448Signature(context, messageChunks,
1396  arraysize(messageChunks), signature->value, ntohs(signature->length));
1397  }
1398  else
1399 #endif
1400  //Invalid signature algorithm?
1401  {
1402  //Report an error
1403  error = ERROR_INVALID_SIGNATURE;
1404  }
1405 
1406  //Total number of bytes that have been consumed
1407  *consumed = sizeof(Tls12DigitalSignature) + ntohs(signature->length);
1408 
1409  //Return status code
1410  return error;
1411 #else
1412  //Not implemented
1413  return ERROR_NOT_IMPLEMENTED;
1414 #endif
1415 }
1416 
1417 
1418 /**
1419  * @brief Version selection
1420  * @param[in] context Pointer to the TLS context
1421  * @param[in] message Pointer to the received ServerHello message
1422  * @param[in] extensions ServerHello extensions offered by the server
1423  * @return Error code
1424  **/
1425 
1428 {
1429  error_t error;
1430  uint16_t selectedVersion;
1431 
1432 #if (TLS_MAX_VERSION >= TLS_VERSION_1_3 && TLS_MIN_VERSION <= TLS_VERSION_1_3)
1433  //Clients must check for the SupportedVersions extension prior to
1434  //processing the rest of the ServerHello
1435  if(extensions->selectedVersion != NULL)
1436  {
1437  //If a client receives an extension type in the ServerHello that it did
1438  //not request in the associated ClientHello, it must abort the handshake
1439  //with an unsupported_extension fatal alert
1440  if(context->versionMax <= TLS_VERSION_1_2)
1442 
1443  //DTLS protocol?
1444  if(context->transportProtocol == TLS_TRANSPORT_PROTOCOL_DATAGRAM)
1445  {
1446  //The legacy_version field must be set to {254, 253}, which is the
1447  //version number for DTLS 1.2
1448  if(ntohs(message->serverVersion) != DTLS_VERSION_1_2)
1450  }
1451  else
1452  {
1453  //The legacy_version field must be set to 0x0303, which is the version
1454  //number for TLS 1.2
1455  if(ntohs(message->serverVersion) != TLS_VERSION_1_2)
1457  }
1458 
1459  //If this extension is present, clients must ignore the legacy_version
1460  //value and must use only the SupportedVersions extension to determine
1461  //the selected version
1462  selectedVersion = LOAD16BE(extensions->selectedVersion->value);
1463 
1464 #if (DTLS_SUPPORT == ENABLED)
1465  //DTLS protocol?
1466  if(context->transportProtocol == TLS_TRANSPORT_PROTOCOL_DATAGRAM)
1467  {
1468  //If the SupportedVersions extension contains a version prior to DTLS
1469  //1.3, the client must abort the handshake with an illegal_parameter
1470  //alert (refer to RFC 8446, section 4.2.1)
1471  if(selectedVersion >= DTLS_VERSION_1_2)
1472  return ERROR_ILLEGAL_PARAMETER;
1473 
1474  //Check whether the ServerHello message is received in response to an
1475  //updated ClientHello?
1476  if(context->state == TLS_STATE_SERVER_HELLO_2)
1477  {
1478  //The value of selected_version in the SupportedVersions extension
1479  //of the HelloRetryRequest must be retained in the ServerHello. A
1480  //client must abort the handshake with an illegal_parameter alert if
1481  //the value changes (refer to RFC 8446, section 4.1.4)
1482  if(selectedVersion != dtlsTranslateVersion(context->version))
1483  return ERROR_ILLEGAL_PARAMETER;
1484  }
1485  }
1486  else
1487 #endif
1488  //TLS protocol?
1489  {
1490  //If the SupportedVersions extension contains a version prior to TLS
1491  //1.3, the client must abort the handshake with an illegal_parameter
1492  //alert (refer to RFC 8446, section 4.2.1)
1493  if(selectedVersion <= TLS_VERSION_1_2)
1494  return ERROR_ILLEGAL_PARAMETER;
1495 
1496  //Check whether the ServerHello message is received in response to an
1497  //updated ClientHello?
1498  if(context->state == TLS_STATE_SERVER_HELLO_2)
1499  {
1500  //The value of selected_version in the SupportedVersions extension
1501  //of the HelloRetryRequest must be retained in the ServerHello. A
1502  //client must abort the handshake with an illegal_parameter alert if
1503  //the value changes (refer to RFC 8446, section 4.1.4)
1504  if(selectedVersion != context->version)
1505  return ERROR_ILLEGAL_PARAMETER;
1506  }
1507  }
1508  }
1509  else
1510 #endif
1511  {
1512  //In previous versions of TLS, this field was used for version negotiation
1513  //and represented the selected version number for the connection
1514  selectedVersion = ntohs(message->serverVersion);
1515 
1516 #if (DTLS_SUPPORT == ENABLED)
1517  //DTLS protocol?
1518  if(context->transportProtocol == TLS_TRANSPORT_PROTOCOL_DATAGRAM)
1519  {
1520  //A server which negotiates DTLS 1.3 must set the legacy_version field
1521  //to 0xfefd (DTLS 1.2) and use the SupportedVersions extension instead
1522  if(selectedVersion < DTLS_VERSION_1_2)
1523  return ERROR_ILLEGAL_PARAMETER;
1524  }
1525  else
1526 #endif
1527  //TLS protocol?
1528  {
1529  //A server which negotiates TLS 1.3 must set the legacy_version field
1530  //to 0x0303 (TLS 1.2) and use the SupportedVersions extension instead
1531  if(selectedVersion > TLS_VERSION_1_2)
1532  return ERROR_ILLEGAL_PARAMETER;
1533  }
1534  }
1535 
1536 #if (DTLS_SUPPORT == ENABLED)
1537  //DTLS protocol?
1538  if(context->transportProtocol == TLS_TRANSPORT_PROTOCOL_DATAGRAM)
1539  {
1540  //Set the DTLS version to be used
1541  error = dtlsSelectVersion(context, selectedVersion);
1542  }
1543  else
1544 #endif
1545  //TLS protocol?
1546  {
1547  //Set the TLS version to be used
1548  error = tlsSelectVersion(context, selectedVersion);
1549  }
1550 
1551  //Specified TLS/DTLS version not supported?
1552  if(error)
1553  return error;
1554 
1555 #if (TLS_MAX_VERSION >= TLS_VERSION_1_3 && TLS_MIN_VERSION <= TLS_VERSION_1_3)
1556  //If the ServerHello indicates TLS 1.1 or below, TLS 1.3 client must and
1557  //1.2 clients should check that the last 8 bytes are not equal to the
1558  //bytes 44 4F 57 4E 47 52 44 00
1559  if(context->version <= TLS_VERSION_1_1 &&
1560  context->versionMax >= TLS_VERSION_1_2)
1561  {
1562  //If a match is found, the client must abort the handshake with an
1563  //illegal_parameter alert
1564  if(osMemcmp(message->random + 24, tls11DowngradeRandom, 8) == 0)
1565  return ERROR_ILLEGAL_PARAMETER;
1566  }
1567 
1568  //If the ServerHello indicates TLS 1.2 or below, TLS 1.3 client must check
1569  //that the last 8 bytes are not equal to the bytes 44 4F 57 4E 47 52 44 01
1570  if(context->version <= TLS_VERSION_1_2 &&
1571  context->versionMax >= TLS_VERSION_1_3)
1572  {
1573  //If a match is found, the client must abort the handshake with an
1574  //illegal_parameter alert
1575  if(osMemcmp(message->random + 24, tls12DowngradeRandom, 8) == 0)
1576  return ERROR_ILLEGAL_PARAMETER;
1577  }
1578 #endif
1579 
1580  //Successful processing
1581  return NO_ERROR;
1582 }
1583 
1584 
1585 /**
1586  * @brief Resume TLS session via session ID
1587  * @param[in] context Pointer to the TLS context
1588  * @param[in] sessionId Pointer to the session ID provided by the server
1589  * @param[in] sessionIdLen Length of the session ID, in bytes
1590  * @param[in] cipherSuite Cipher suite selected by the server
1591  * @return Error code
1592  **/
1593 
1595  size_t sessionIdLen, uint16_t cipherSuite)
1596 {
1597  error_t error;
1598 
1599  //Initialize status code
1600  error = NO_ERROR;
1601 
1602 #if (TLS_SESSION_RESUME_SUPPORT == ENABLED)
1603  //Check whether the session ID matches the value that was supplied by the
1604  //client
1605  if(sessionIdLen != 0 && sessionIdLen == context->sessionIdLen &&
1606  osMemcmp(sessionId, context->sessionId, sessionIdLen) == 0)
1607  {
1608  //For resumed sessions, the selected cipher suite shall be the same as
1609  //the session being resumed
1610  if(cipherSuite != 0 && cipherSuite == context->cipherSuite.identifier)
1611  {
1612  //Perform abbreviated handshake
1613  context->resume = TRUE;
1614  }
1615  else
1616  {
1617  //The session ID is no more valid
1618  context->sessionIdLen = 0;
1619 
1620  //When renegotiating, if the server tries to use another version or
1621  //compression method than previously, abort
1622  error = ERROR_ILLEGAL_PARAMETER;
1623  }
1624  }
1625  else
1626 #endif
1627  {
1628  //Perform a full handshake
1629  context->resume = FALSE;
1630  }
1631 
1632  //Return status code
1633  return error;
1634 }
1635 
1636 
1637 /**
1638  * @brief Check whether a session ticket is valid
1639  * @param[in] context Pointer to the TLS context
1640  * @return TRUE is the session ticket is valid, else FALSE
1641  **/
1642 
1644 {
1645  bool_t valid = FALSE;
1646 
1647  //TLS 1.3 tickets cannot be used to resume a TLS 1.2 session
1648  if(context->version <= TLS_VERSION_1_2)
1649  {
1650  //Valid ticket?
1651  if(context->ticket != NULL && context->ticketLen > 0)
1652  {
1653  valid = TRUE;
1654  }
1655  }
1656 
1657  //Return TRUE is the ticket is valid, else FALSE
1658  return valid;
1659 }
1660 
1661 #endif
@ TLS_GROUP_BRAINPOOLP512R1_TLS13
Definition: tls.h:1484
#define tlsAllocMem(size)
Definition: tls.h:888
#define htons(value)
Definition: cpu_endian.h:413
Parsing and checking of TLS extensions.
@ TLS_SIGN_ALGO_DSA
Definition: tls.h:1280
TLS helper functions.
const uint8_t tls11DowngradeRandom[8]
Definition: tls13_misc.c:53
X.509 certificate parsing.
@ ERROR_UNKNOWN_IDENTITY
Definition: error.h:261
HashAlgoInit init
Definition: crypto.h:1161
@ ERROR_UNSUPPORTED_ELLIPTIC_CURVE
Definition: error.h:133
uint8_t extensions[]
Definition: ntp_common.h:213
@ TLS_GROUP_BRAINPOOLP256R1_TLS13
Definition: tls.h:1482
Generic hash algorithm context.
int bool_t
Definition: compiler_port.h:63
uint8_t sessionId[]
Definition: tls.h:1895
TLS cipher suites.
uint16_t cipherSuite
Cipher suite identifier.
Definition: tls.h:2005
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:1325
X509TbsCertificate tbsCert
Definition: x509_common.h:1123
TlsDigitalSignature
Definition: tls.h:1839
@ TLS_SIGN_SCHEME_RSA_PSS_RSAE_SHA256
Definition: tls.h:1303
#define TLS_MAX_DH_MODULUS_SIZE
Definition: tls.h:801
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:1173
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:1392
@ 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:305
#define TRUE
Definition: os_port.h:50
error_t x509ParseCertificate(const uint8_t *data, size_t length, X509CertInfo *certInfo)
Parse a X.509 certificate.
@ TLS_GROUP_CURVE_SM2
Definition: tls.h:1492
size_t digestSize
Definition: crypto.h:1157
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:1080
@ TLS_TRANSPORT_PROTOCOL_DATAGRAM
Definition: tls.h:1000
HashAlgoUpdate update
Definition: crypto.h:1162
void md5Final(Md5Context *context, uint8_t *digest)
Finish the MD5 message digest.
Session cache management.
TlsPskIdentity
Definition: tls.h:1817
@ TLS_SIGN_SCHEME_RSA_PSS_PSS_SHA512
Definition: tls.h:1308
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:1101
#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.
error_t tlsFormatTrustedAuthorities(TlsContext *context, uint8_t *p, size_t *written)
Format the list of trusted authorities.
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.
const uint8_t tls12DowngradeRandom[8]
Definition: tls13_misc.c:59
@ TLS_CERT_DSS_SIGN
Definition: tls.h:1236
@ TLS_SIGN_SCHEME_RSA_PSS_RSAE_SHA512
Definition: tls.h:1305
@ TLS_SIGN_SCHEME_ED25519
Definition: tls.h:1317
#define osStrlen(s)
Definition: os_port.h:168
#define TLS_RANDOM_SIZE
Definition: tls.h:981
#define TLS_HASH_ALGO(signScheme)
Definition: tls_sign_misc.h:41
TlsPskIdentityHint
Definition: tls.h:1828
@ TLS_SIGN_SCHEME_RSA_PSS_PSS_SHA384
Definition: tls.h:1307
@ TLS_SIGN_SCHEME_RSA_PSS_RSAE_SHA384
Definition: tls.h:1304
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:1155
uint8_t sessionIdLen
Definition: tls.h:1894
@ TLS_KEY_EXCH_RSA
Definition: tls.h:1185
void md5Init(Md5Context *context)
Initialize MD5 message digest context.
TlsCipherSuites
Definition: tls.h:1617
#define MAX_HASH_DIGEST_SIZE
@ TLS_HASH_ALGO_SHA512
Definition: tls.h:1266
@ TLS_KEY_EXCH_ECDHE_ECDSA
Definition: tls.h:1194
@ TLS_KEY_EXCH_ECDHE_RSA
Definition: tls.h:1192
TlsHandshake
Definition: tls.h:1876
#define FALSE
Definition: os_port.h:46
error_t pemImportCertificate(const char_t *input, size_t inputLen, uint8_t *output, size_t *outputLen, size_t *consumed)
Decode a PEM file containing a certificate.
Definition: pem_import.c:55
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:1195
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)
PEM file import functions.
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
X.509 certificate.
Definition: x509_common.h:1121
#define TlsContext
Definition: tls.h:36
error_t
Error codes.
Definition: error.h:43
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.
@ TLS_SIGN_SCHEME_RSA_PSS_PSS_SHA256
Definition: tls.h:1306
@ TLS_CERT_ED25519_SIGN
Definition: tls.h:1249
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:843
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:1190
#define TLS_MAX_VERSION
Definition: tls.h:136
#define STORE16BE(a, p)
Definition: cpu_endian.h:262
@ TLS_TYPE_CLIENT_HELLO
Definition: tls.h:1085
error_t tlsSelectClientVersion(TlsContext *context, const TlsServerHello *message, const TlsHelloExtensions *extensions)
Version selection.
Tls12DigitalSignature
Definition: tls.h:1851
uint16_t identifier
Definition: tls.h:2176
@ 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:1265
@ TLS_CERT_RSA_PSS_SIGN
Definition: tls.h:1247
__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_HASH_ALGO_SHA256
Definition: tls.h:1264
@ TLS_CERT_ED448_SIGN
Definition: tls.h:1250
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:1235
uint8_t length
Definition: tcp.h:375
@ TLS_KEY_EXCH_DHE_PSK
Definition: tls.h:1198
TlsCompressMethods
Definition: tls.h:1628
uint16_t dtlsTranslateVersion(uint16_t version)
Translate TLS version into DTLS version.
Definition: dtls_misc.c:124
#define MD5_DIGEST_SIZE
Definition: md5.h:45
RSA/DSA/ECDSA/EdDSA signature verification.
Hello extensions.
Definition: tls.h:2257
@ TLS_FALLBACK_SCSV
uint_t mpiGetBitLength(const Mpi *a)
Get the actual length in bits.
Definition: mpi.c:255
@ TLS_GROUP_BRAINPOOLP384R1_TLS13
Definition: tls.h:1483
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:1197
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:1163
Data chunk descriptor.
Definition: crypto.h:1079
#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:1177
TlsRecord
Definition: tls.h:1864
error_t tlsVerifyEcdsaSignature(TlsContext *context, const uint8_t *digest, size_t digestLen, const uint8_t *signature, size_t signatureLen)
Verify ECDSA signature.
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.
@ TLS_EC_CURVE_TYPE_NAMED_CURVE
Definition: tls.h:1531
#define TRACE_DEBUG(...)
Definition: debug.h:119
char char_t
Definition: compiler_port.h:55
#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:1135
@ TLS_CA_ROOT_KEY_ID_TYPE_X509_NAME
Definition: tls.h:1440
const char_t * tlsGetCipherSuiteName(uint16_t identifier)
Convert cipher suite identifier to string representation.
TlsServerHello
Definition: tls.h:1909
#define HTONS(value)
Definition: cpu_endian.h:410
uint8_t n
@ TLS_SIGN_SCHEME_ED448
Definition: tls.h:1318
const TlsCipherSuiteInfo tlsSupportedCipherSuites[]
@ TLS_KEY_EXCH_ECDHE_PSK
Definition: tls.h:1199
TlsClientHello
Definition: tls.h:1896
Helper functions for signature generation and verification.
TLS (Transport Layer Security)
uint8_t identifier[]
@ TLS_SIGN_ALGO_RSA
Definition: tls.h:1279
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:1216
#define STORE24BE(a, p)
Definition: cpu_endian.h:273
SHA-1 algorithm context.
Definition: sha1.h:62
TlsTrustedAuthorities
Definition: tls.h:1683
@ TLS_CERT_ECDSA_SIGN
Definition: tls.h:1242
@ TLS_KEY_EXCH_DHE_DSS
Definition: tls.h:1189
size_t length
Definition: crypto.h:1081
error_t ecdhSetCurve(EcdhContext *context, const EcCurve *curve)
Specify the elliptic curve to use.
Definition: ecdh.c:83
const uint8_t * value
Definition: x509_common.h:704
Common interface for hash algorithms.
Definition: crypto.h:1151
#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:1294
@ 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:893
@ TLS_STATE_SERVER_HELLO_2
Definition: tls.h:1549
@ ERROR_INVALID_SIGNATURE
Definition: error.h:228
@ TLS_SIGN_ALGO_ECDSA
Definition: tls.h:1281
@ TLS_KEY_EXCH_DHE_RSA
Definition: tls.h:1187
#define DTLS_VERSION_1_2
Definition: dtls_misc.h:36
X509OctetString raw
Definition: x509_common.h:726
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
TlsTrustedAuthority
Definition: tls.h:1672
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.