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.4
29  **/
30 
31 //Switch to the appropriate trace level
32 #define TRACE_LEVEL TLS_TRACE_LEVEL
33 
34 //Dependencies
35 #include "tls.h"
36 #include "tls_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  (context->transportProtocol == TLS_TRANSPORT_PROTOCOL_STREAM ||
113  context->transportProtocol == TLS_TRANSPORT_PROTOCOL_QUIC ||
114  context->transportProtocol == TLS_TRANSPORT_PROTOCOL_EAP))
115  {
116  //A client which has a cached session ID set by a pre-TLS 1.3 server
117  //should set this field to that value
118  osMemcpy(p, context->sessionId, context->sessionIdLen);
119  n = context->sessionIdLen;
120  }
121  else
122  {
123 #if (TLS_SESSION_RESUME_SUPPORT == ENABLED)
124  //The session ID value identifies a session the client wishes to reuse
125  //for this connection
126  osMemcpy(p, context->sessionId, context->sessionIdLen);
127  n = context->sessionIdLen;
128 #else
129  //Session resumption is not supported
130  n = 0;
131 #endif
132  }
133 
134 #if (TLS_SECURE_RENEGOTIATION_SUPPORT == ENABLED)
135  //Secure renegotiation?
136  if(context->secureRenegoEnabled && context->secureRenegoFlag)
137  {
138  //Do not offer a session ID when renegotiating
139  n = 0;
140  }
141 #endif
142 
143  //Total number of bytes that have been written
144  *written = n;
145 
146  //Successful processing
147  return NO_ERROR;
148 }
149 
150 
151 /**
152  * @brief Format the list of cipher suites supported by the client
153  * @param[in] context Pointer to the TLS context
154  * @param[in] p Output stream where to write the list of cipher suites
155  * @param[out] written Total number of bytes that have been written
156  * @return Error code
157  **/
158 
160  size_t *written)
161 {
162  uint_t i;
163  uint_t j;
164  uint_t k;
165  uint_t n;
166  uint16_t identifier;
167  TlsCipherSuites *cipherSuites;
168 
169  //Types of cipher suites proposed by the client
170  context->cipherSuiteTypes = TLS_CIPHER_SUITE_TYPE_UNKNOWN;
171 
172  //Point to the list of cryptographic algorithms supported by the client
173  cipherSuites = (TlsCipherSuites *) p;
174  //Number of cipher suites in the array
175  n = 0;
176 
177  //Determine the number of supported cipher suites
179 
180  //Debug message
181  TRACE_DEBUG("Cipher suites:\r\n");
182 
183  //Any preferred cipher suites?
184  if(context->numCipherSuites > 0)
185  {
186  //Loop through the list of preferred cipher suites
187  for(i = 0; i < context->numCipherSuites; i++)
188  {
189  //Loop through the list of supported cipher suites
190  for(j = 0; j < k; j++)
191  {
192  //Retrieve cipher suite identifier
194 
195  //Supported cipher suite?
196  if(identifier == context->cipherSuites[i])
197  {
198  //Check whether the cipher suite can be negotiated with the
199  //current protocol version
201  context->versionMin, context->versionMax,
202  context->transportProtocol))
203  {
204  //Copy cipher suite identifier
205  cipherSuites->value[n++] = htons(identifier);
206 
207  //Debug message
208  TRACE_DEBUG(" 0x%04" PRIX16 " (%s)\r\n", identifier,
210 
211  //Check whether the identifier matches an ECC or FFDHE cipher
212  //suite
213  context->cipherSuiteTypes |= tlsGetCipherSuiteType(identifier);
214  }
215  }
216  }
217  }
218  }
219  else
220  {
221  //Loop through the list of supported cipher suites
222  for(j = 0; j < k; j++)
223  {
224  //Retrieve cipher suite identifier
226 
227  //Check whether the cipher suite can be negotiated with the
228  //current protocol version
230  context->versionMin, context->versionMax,
231  context->transportProtocol))
232  {
233  //Copy cipher suite identifier
234  cipherSuites->value[n++] = htons(identifier);
235 
236  //Debug message
237  TRACE_DEBUG(" 0x%04" PRIX16 " (%s)\r\n", identifier,
239 
240  //Check whether the identifier matches an ECC or FFDHE cipher
241  //suite
242  context->cipherSuiteTypes |= tlsGetCipherSuiteType(identifier);
243  }
244  }
245  }
246 
247 #if (TLS_SECURE_RENEGOTIATION_SUPPORT == ENABLED)
248  //Check whether secure renegotiation is enabled
249  if(context->secureRenegoEnabled)
250  {
251  //Initial handshake?
252  if(context->clientVerifyDataLen == 0)
253  {
254  //The client includes the TLS_EMPTY_RENEGOTIATION_INFO_SCSV signaling
255  //cipher suite value in its ClientHello
256  cipherSuites->value[n++] = HTONS(TLS_EMPTY_RENEGOTIATION_INFO_SCSV);
257  }
258  }
259 #endif
260 
261 #if (TLS_FALLBACK_SCSV_SUPPORT == ENABLED)
262  //Check whether support for FALLBACK_SCSV is enabled
263  if(context->fallbackScsvEnabled)
264  {
265  //The TLS_FALLBACK_SCSV cipher suite value is meant for use by clients
266  //that repeat a connection attempt with a downgraded protocol
267  if(context->versionMax != TLS_MAX_VERSION)
268  {
269  //The client should put TLS_FALLBACK_SCSV after all cipher suites
270  //that it actually intends to negotiate
271  cipherSuites->value[n++] = HTONS(TLS_FALLBACK_SCSV);
272  }
273  }
274 #endif
275 
276  //Length of the array, in bytes
277  cipherSuites->length = htons(n * 2);
278 
279  //Total number of bytes that have been written
280  *written = sizeof(TlsCipherSuites) + n * 2;
281 
282  //Successful processing
283  return NO_ERROR;
284 }
285 
286 
287 /**
288  * @brief Format the list of compression methods supported by the client
289  * @param[in] context Pointer to the TLS context
290  * @param[in] p Output stream where to write the list of compression methods
291  * @param[out] written Total number of bytes that have been written
292  * @return Error code
293  **/
294 
296  size_t *written)
297 {
298  TlsCompressMethods *compressMethods;
299 
300  //List of compression algorithms supported by the client
301  compressMethods = (TlsCompressMethods *) p;
302 
303  //The CRIME exploit takes advantage of TLS compression, so conservative
304  //implementations do not enable compression at the TLS level
305  compressMethods->length = 1;
306  compressMethods->value[0] = TLS_COMPRESSION_METHOD_NULL;
307 
308  //Total number of bytes that have been written
309  *written = sizeof(TlsCompressMethods) + compressMethods->length;
310 
311  //Successful processing
312  return NO_ERROR;
313 }
314 
315 
316 /**
317  * @brief Format the list of trusted authorities
318  * @param[in] context Pointer to the TLS context
319  * @param[in] p Output stream where to write the list of trusted authorities
320  * @param[out] written Total number of bytes that have been written
321  * @return Error code
322  **/
323 
325  size_t *written)
326 {
327 #if (TLS_TRUSTED_CA_KEYS_SUPPORT == ENABLED)
328  error_t error;
329  size_t n;
330  size_t pemCertLen;
331  const char_t *trustedCaList;
332  size_t trustedCaListLen;
333  uint8_t *derCert;
334  size_t derCertLen;
335  X509CertInfo *certInfo;
336  TlsTrustedAuthority *trustedAuthority;
337  TlsTrustedAuthorities *trustedAuthorities;
338 
339  //Initialize status code
340  error = NO_ERROR;
341 
342  //"TrustedAuthorities" provides a list of CA root key identifiers that the
343  //client possesses (refer to RFC 6066, section 6)
344  trustedAuthorities = (TlsTrustedAuthorities *) p;
345 
346  //Point to the first certificate authority
347  p = trustedAuthorities->value;
348  //Length of the list in bytes
349  n = 0;
350 
351  //Point to the first trusted CA certificate
352  trustedCaList = context->trustedCaList;
353  //Get the total length, in bytes, of the trusted CA list
354  trustedCaListLen = context->trustedCaListLen;
355 
356  //Allocate a memory buffer to store X.509 certificate info
357  certInfo = tlsAllocMem(sizeof(X509CertInfo));
358 
359  //Successful memory allocation?
360  if(certInfo != NULL)
361  {
362  //Loop through the list of trusted CA certificates
363  while(trustedCaListLen > 0 && error == NO_ERROR)
364  {
365  //The first pass calculates the length of the DER-encoded certificate
366  error = pemImportCertificate(trustedCaList, trustedCaListLen, NULL,
367  &derCertLen, &pemCertLen);
368 
369  //Check status code
370  if(!error)
371  {
372  //Allocate a memory buffer to hold the DER-encoded certificate
373  derCert = tlsAllocMem(derCertLen);
374 
375  //Successful memory allocation?
376  if(derCert != NULL)
377  {
378  //The second pass decodes the PEM certificate
379  error = pemImportCertificate(trustedCaList, trustedCaListLen,
380  derCert, &derCertLen, NULL);
381 
382  //Check status code
383  if(!error)
384  {
385  //Parse X.509 certificate
386  error = x509ParseCertificate(derCert, derCertLen, certInfo);
387  }
388 
389  //Valid CA certificate?
390  if(!error)
391  {
392  //Point to the CA root key identifier
393  trustedAuthority = (TlsTrustedAuthority *) p;
394 
395  //The CA root key is identified via a distinguished name
396  trustedAuthority->type = TLS_CA_ROOT_KEY_ID_TYPE_X509_NAME;
397 
398  //Each distinguished name is preceded by a 2-byte length field
399  STORE16BE(certInfo->tbsCert.subject.raw.length,
400  trustedAuthority->identifier);
401 
402  //The distinguished name shall be DER-encoded
403  osMemcpy(trustedAuthority->identifier + 2,
404  certInfo->tbsCert.subject.raw.value,
405  certInfo->tbsCert.subject.raw.length);
406 
407  //Advance write pointer
408  p += sizeof(TlsTrustedAuthority) + 2 + certInfo->tbsCert.subject.raw.length;
409  n += sizeof(TlsTrustedAuthority) + 2 + certInfo->tbsCert.subject.raw.length;
410  }
411  else
412  {
413  //Discard current CA certificate
414  error = NO_ERROR;
415  }
416 
417  //Free previously allocated memory
418  tlsFreeMem(derCert);
419  }
420  else
421  {
422  //Failed to allocate memory
423  error = ERROR_OUT_OF_MEMORY;
424  }
425 
426  //Advance read pointer
427  trustedCaList += pemCertLen;
428  trustedCaListLen -= pemCertLen;
429  }
430  else
431  {
432  //End of file detected
433  trustedCaListLen = 0;
434  error = NO_ERROR;
435  }
436  }
437 
438  //Fix the length of the list
439  trustedAuthorities->length = htons(n);
440 
441  //Free previously allocated memory
442  tlsFreeMem(certInfo);
443  }
444  else
445  {
446  //Failed to allocate memory
447  error = ERROR_OUT_OF_MEMORY;
448  }
449 
450  //Check status code
451  if(!error)
452  {
453  //Total number of bytes that have been written
454  *written = sizeof(TlsTrustedAuthorities) + n;
455  }
456 
457  //Return status code
458  return error;
459 #else
460  //Not implemented
461  return ERROR_NOT_IMPLEMENTED;
462 #endif
463 }
464 
465 
466 /**
467  * @brief Format PSK identity
468  * @param[in] context Pointer to the TLS context
469  * @param[in] p Output stream where to write the PSK identity hint
470  * @param[out] written Total number of bytes that have been written
471  * @return Error code
472  **/
473 
475  size_t *written)
476 {
477  size_t n;
478  TlsPskIdentity *pskIdentity;
479 
480  //Point to the PSK identity
481  pskIdentity = (TlsPskIdentity *) p;
482 
483 #if (TLS_PSK_KE_SUPPORT == ENABLED || TLS_RSA_PSK_KE_SUPPORT == ENABLED || \
484  TLS_DHE_PSK_KE_SUPPORT == ENABLED || TLS_ECDHE_PSK_KE_SUPPORT == ENABLED)
485  //Any PSK identity defined?
486  if(context->pskIdentity != NULL)
487  {
488  //Determine the length of the PSK identity
489  n = osStrlen(context->pskIdentity);
490  //Copy PSK identity
491  osMemcpy(pskIdentity->value, context->pskIdentity, n);
492  }
493  else
494 #endif
495  {
496  //No PSK identity is provided
497  n = 0;
498  }
499 
500  //The PSK identity is preceded by a 2-byte length field
501  pskIdentity->length = htons(n);
502 
503  //Total number of bytes that have been written
504  *written = sizeof(TlsPskIdentity) + n;
505 
506  //Successful processing
507  return NO_ERROR;
508 }
509 
510 
511 /**
512  * @brief Format client's key exchange parameters
513  * @param[in] context Pointer to the TLS context
514  * @param[in] p Output stream where to write the client's key exchange parameters
515  * @param[out] written Total number of bytes that have been written
516  * @return Error code
517  **/
518 
519 __weak_func error_t tlsFormatClientKeyParams(TlsContext *context, uint8_t *p,
520  size_t *written)
521 {
522 #if (TLS_MAX_VERSION >= TLS_VERSION_1_0 && TLS_MIN_VERSION <= TLS_VERSION_1_2)
523  error_t error;
524  size_t n;
525 
526 #if (TLS_RSA_KE_SUPPORT == ENABLED || TLS_RSA_PSK_KE_SUPPORT == ENABLED)
527  //RSA key exchange method?
528  if(context->keyExchMethod == TLS_KEY_EXCH_RSA ||
529  context->keyExchMethod == TLS_KEY_EXCH_RSA_PSK)
530  {
531  //If RSA is being used for key agreement and authentication, the
532  //client generates a 48-byte premaster secret
533  context->premasterSecretLen = 48;
534 
535  //The first 2 bytes code the latest version supported by the client
536  STORE16BE(context->clientVersion, context->premasterSecret);
537 
538  //The last 46 bytes contain securely-generated random bytes
539  error = context->prngAlgo->generate(context->prngContext,
540  context->premasterSecret + 2, 46);
541  //Any error to report?
542  if(error)
543  return error;
544 
545  //Encrypt the premaster secret using the server public key
546  error = rsaesPkcs1v15Encrypt(context->prngAlgo, context->prngContext,
547  &context->peerRsaPublicKey, context->premasterSecret, 48, p + 2, &n);
548  //RSA encryption failed?
549  if(error)
550  return error;
551 
552  //The RSA-encrypted premaster secret in a ClientKeyExchange is preceded by
553  //two length bytes
554  STORE16BE(n, p);
555 
556  //Total number of bytes that have been written
557  *written = n + 2;
558  }
559  else
560 #endif
561 #if (TLS_DH_ANON_KE_SUPPORT == ENABLED || TLS_DHE_RSA_KE_SUPPORT == ENABLED || \
562  TLS_DHE_DSS_KE_SUPPORT == ENABLED || TLS_DHE_PSK_KE_SUPPORT == ENABLED)
563  //Diffie-Hellman key exchange method?
564  if(context->keyExchMethod == TLS_KEY_EXCH_DH_ANON ||
565  context->keyExchMethod == TLS_KEY_EXCH_DHE_RSA ||
566  context->keyExchMethod == TLS_KEY_EXCH_DHE_DSS ||
567  context->keyExchMethod == TLS_KEY_EXCH_DHE_PSK)
568  {
569  //Generate an ephemeral key pair
570  error = dhGenerateKeyPair(&context->dhContext,
571  context->prngAlgo, context->prngContext);
572  //Any error to report?
573  if(error)
574  return error;
575 
576  //Encode the client's public value to an opaque vector
577  error = tlsWriteMpi(&context->dhContext.ya, p, &n);
578  //Any error to report?
579  if(error)
580  return error;
581 
582  //Total number of bytes that have been written
583  *written = n;
584 
585  //Calculate the negotiated key Z
586  error = dhComputeSharedSecret(&context->dhContext,
587  context->premasterSecret, TLS_PREMASTER_SECRET_SIZE,
588  &context->premasterSecretLen);
589  //Any error to report?
590  if(error)
591  return error;
592 
593  //Leading bytes of Z that contain all zero bits are stripped before
594  //it is used as the premaster secret (RFC 4346, section 8.2.1)
595  for(n = 0; n < context->premasterSecretLen; n++)
596  {
597  if(context->premasterSecret[n] != 0x00)
598  break;
599  }
600 
601  //Any leading zero bytes?
602  if(n > 0)
603  {
604  //Strip leading zero bytes from the negotiated key
605  osMemmove(context->premasterSecret, context->premasterSecret + n,
606  context->premasterSecretLen - n);
607 
608  //Adjust the length of the premaster secret
609  context->premasterSecretLen -= n;
610  }
611  }
612  else
613 #endif
614 #if (TLS_ECDH_ANON_KE_SUPPORT == ENABLED || TLS_ECDHE_RSA_KE_SUPPORT == ENABLED || \
615  TLS_ECDHE_ECDSA_KE_SUPPORT == ENABLED || TLS_ECDHE_PSK_KE_SUPPORT == ENABLED)
616  //ECDH key exchange method?
617  if(context->keyExchMethod == TLS_KEY_EXCH_ECDH_ANON ||
618  context->keyExchMethod == TLS_KEY_EXCH_ECDHE_RSA ||
619  context->keyExchMethod == TLS_KEY_EXCH_ECDHE_ECDSA ||
620  context->keyExchMethod == TLS_KEY_EXCH_ECDHE_PSK)
621  {
622 #if (TLS_ECC_CALLBACK_SUPPORT == ENABLED)
623  //Any registered callback?
624  if(context->ecdhCallback != NULL)
625  {
626  //Invoke user callback function
627  error = context->ecdhCallback(context);
628  }
629  else
630 #endif
631  {
632  //No callback function defined
634  }
635 
636  //Check status code
638  {
639  //Generate an ephemeral key pair
640  error = ecdhGenerateKeyPair(&context->ecdhContext,
641  context->prngAlgo, context->prngContext);
642  //Any error to report?
643  if(error)
644  return error;
645 
646  //Calculate the negotiated key Z
647  error = ecdhComputeSharedSecret(&context->ecdhContext,
648  context->premasterSecret, TLS_PREMASTER_SECRET_SIZE,
649  &context->premasterSecretLen);
650  //Any error to report?
651  if(error)
652  return error;
653  }
654  else if(error != NO_ERROR)
655  {
656  //Report an error
657  return error;
658  }
659 
660  //Encode the client's public key to an opaque vector
661  error = tlsWriteEcPoint(&context->ecdhContext.da.q, p, &n);
662  //Any error to report?
663  if(error)
664  return error;
665 
666  //Total number of bytes that have been written
667  *written = n;
668  }
669  else
670 #endif
671  //Invalid key exchange method?
672  {
673  //Just for sanity
674  (void) error;
675  (void) n;
676 
677  //The specified key exchange method is not supported
679  }
680 
681  //Successful processing
682  return NO_ERROR;
683 #else
684  //Not implemented
685  return ERROR_NOT_IMPLEMENTED;
686 #endif
687 }
688 
689 
690 /**
691  * @brief Parse PSK identity hint
692  * @param[in] context Pointer to the TLS context
693  * @param[in] p Input stream where to read the PSK identity hint
694  * @param[in] length Number of bytes available in the input stream
695  * @param[out] consumed Total number of bytes that have been consumed
696  * @return Error code
697  **/
698 
699 error_t tlsParsePskIdentityHint(TlsContext *context, const uint8_t *p,
700  size_t length, size_t *consumed)
701 {
702  size_t n;
703  TlsPskIdentityHint *pskIdentityHint;
704 
705  //Point to the PSK identity hint
706  pskIdentityHint = (TlsPskIdentityHint *) p;
707 
708  //Malformed ServerKeyExchange message?
709  if(length < sizeof(TlsPskIdentityHint))
710  return ERROR_DECODING_FAILED;
711  if(length < (sizeof(TlsPskIdentityHint) + ntohs(pskIdentityHint->length)))
712  return ERROR_DECODING_FAILED;
713 
714  //Retrieve the length of the PSK identity hint
715  n = ntohs(pskIdentityHint->length);
716 
717 #if (TLS_PSK_KE_SUPPORT == ENABLED || TLS_RSA_PSK_KE_SUPPORT == ENABLED || \
718  TLS_DHE_PSK_KE_SUPPORT == ENABLED || TLS_ECDHE_PSK_KE_SUPPORT == ENABLED)
719  //Any registered callback?
720  if(context->pskCallback != NULL)
721  {
722  error_t error;
723 
724  //The client selects which identity to use depending on the PSK identity
725  //hint provided by the server
726  error = context->pskCallback(context, pskIdentityHint->value, n);
727  //Any error to report?
728  if(error)
729  return ERROR_UNKNOWN_IDENTITY;
730  }
731 #endif
732 
733  //Total number of bytes that have been consumed
734  *consumed = sizeof(TlsPskIdentityHint) + n;
735 
736  //Successful processing
737  return NO_ERROR;
738 }
739 
740 
741 /**
742  * @brief Parse server's key exchange parameters
743  * @param[in] context Pointer to the TLS context
744  * @param[in] p Input stream where to read the server's key exchange parameters
745  * @param[in] length Number of bytes available in the input stream
746  * @param[out] consumed Total number of bytes that have been consumed
747  * @return Error code
748  **/
749 
750 error_t tlsParseServerKeyParams(TlsContext *context, const uint8_t *p,
751  size_t length, size_t *consumed)
752 {
753 #if (TLS_MAX_VERSION >= TLS_VERSION_1_0 && TLS_MIN_VERSION <= TLS_VERSION_1_2)
754  error_t error;
755  const uint8_t *params;
756 
757  //Initialize status code
758  error = NO_ERROR;
759 
760  //Point to the server's key exchange parameters
761  params = p;
762 
763 #if (TLS_DH_ANON_KE_SUPPORT == ENABLED || TLS_DHE_RSA_KE_SUPPORT == ENABLED || \
764  TLS_DHE_DSS_KE_SUPPORT == ENABLED || TLS_DHE_PSK_KE_SUPPORT == ENABLED)
765  //Diffie-Hellman key exchange method?
766  if(context->keyExchMethod == TLS_KEY_EXCH_DH_ANON ||
767  context->keyExchMethod == TLS_KEY_EXCH_DHE_RSA ||
768  context->keyExchMethod == TLS_KEY_EXCH_DHE_DSS ||
769  context->keyExchMethod == TLS_KEY_EXCH_DHE_PSK)
770  {
771  uint_t k;
772  size_t n;
773 
774  //Convert the prime modulus to a multiple precision integer
775  error = tlsReadMpi(&context->dhContext.params.p, p, length, &n);
776 
777  //Check status code
778  if(!error)
779  {
780  //Get the length of the prime modulus, in bits
781  k = mpiGetBitLength(&context->dhContext.params.p);
782 
783  //Make sure the prime modulus is acceptable
784  if(k < TLS_MIN_DH_MODULUS_SIZE || k > TLS_MAX_DH_MODULUS_SIZE)
785  {
786  error = ERROR_ILLEGAL_PARAMETER;
787  }
788  }
789 
790  //Check status code
791  if(!error)
792  {
793  //Advance data pointer
794  p += n;
795  //Remaining bytes to process
796  length -= n;
797 
798  //Convert the generator to a multiple precision integer
799  error = tlsReadMpi(&context->dhContext.params.g, p, length, &n);
800  }
801 
802  //Check status code
803  if(!error)
804  {
805  //Advance data pointer
806  p += n;
807  //Remaining bytes to process
808  length -= n;
809 
810  //Convert the server's public value to a multiple precision integer
811  error = tlsReadMpi(&context->dhContext.yb, p, length, &n);
812  }
813 
814  //Check status code
815  if(!error)
816  {
817  //Advance data pointer
818  p += n;
819  //Remaining bytes to process
820  length -= n;
821 
822  //Verify peer's public value
823  error = dhCheckPublicKey(&context->dhContext,
824  &context->dhContext.yb);
825  }
826 
827  //Check status code
828  if(!error)
829  {
830  //Debug message
831  TRACE_DEBUG("Diffie-Hellman parameters:\r\n");
832  TRACE_DEBUG(" Prime modulus:\r\n");
833  TRACE_DEBUG_MPI(" ", &context->dhContext.params.p);
834  TRACE_DEBUG(" Generator:\r\n");
835  TRACE_DEBUG_MPI(" ", &context->dhContext.params.g);
836  TRACE_DEBUG(" Server public value:\r\n");
837  TRACE_DEBUG_MPI(" ", &context->dhContext.yb);
838  }
839  }
840  else
841 #endif
842 #if (TLS_ECDH_ANON_KE_SUPPORT == ENABLED || TLS_ECDHE_RSA_KE_SUPPORT == ENABLED || \
843  TLS_ECDHE_ECDSA_KE_SUPPORT == ENABLED || TLS_ECDHE_PSK_KE_SUPPORT == ENABLED)
844  //ECDH key exchange method?
845  if(context->keyExchMethod == TLS_KEY_EXCH_ECDH_ANON ||
846  context->keyExchMethod == TLS_KEY_EXCH_ECDHE_RSA ||
847  context->keyExchMethod == TLS_KEY_EXCH_ECDHE_ECDSA ||
848  context->keyExchMethod == TLS_KEY_EXCH_ECDHE_PSK)
849  {
850  size_t n;
851  uint8_t curveType;
852  const EcCurve *curve;
853 
854  //Initialize curve parameters
855  curve = NULL;
856 
857  //Malformed ServerKeyExchange message?
858  if(length < sizeof(curveType))
859  {
860  error = ERROR_DECODING_FAILED;
861  }
862 
863  //Check status code
864  if(!error)
865  {
866  //Retrieve the type of the elliptic curve domain parameters
867  curveType = *p;
868 
869  //Advance data pointer
870  p += sizeof(curveType);
871  //Remaining bytes to process
872  length -= sizeof(curveType);
873 
874  //Only named curves are supported
875  if(curveType != TLS_EC_CURVE_TYPE_NAMED_CURVE)
876  {
877  error = ERROR_ILLEGAL_PARAMETER;
878  }
879  }
880 
881  //Check status code
882  if(!error)
883  {
884  //Malformed ServerKeyExchange message?
885  if(length < sizeof(uint16_t))
886  {
887  error = ERROR_DECODING_FAILED;
888  }
889  }
890 
891  //Check status code
892  if(!error)
893  {
894  //Get elliptic curve identifier
895  context->namedGroup = LOAD16BE(p);
896 
897  //Advance data pointer
898  p += sizeof(uint16_t);
899  //Remaining bytes to process
900  length -= sizeof(uint16_t);
901 
902  //TLS 1.3 group?
903  if(context->namedGroup == TLS_GROUP_BRAINPOOLP256R1_TLS13 ||
904  context->namedGroup == TLS_GROUP_BRAINPOOLP384R1_TLS13 ||
905  context->namedGroup == TLS_GROUP_BRAINPOOLP512R1_TLS13 ||
906  context->namedGroup == TLS_GROUP_CURVE_SM2)
907  {
908  //These elliptic curves do not apply to any older versions of TLS
909  error = ERROR_ILLEGAL_PARAMETER;
910  }
911  else
912  {
913  //Retrieve the corresponding EC domain parameters
914  curve = tlsGetCurve(context, context->namedGroup);
915 
916  //Make sure the elliptic curve is supported
917  if(curve == NULL)
918  {
919  //The elliptic curve is not supported
920  error = ERROR_ILLEGAL_PARAMETER;
921  }
922  }
923  }
924 
925  //Check status code
926  if(!error)
927  {
928  //Save elliptic curve parameters
929  error = ecdhSetCurve(&context->ecdhContext, curve);
930  }
931 
932  //Check status code
933  if(!error)
934  {
935  //Read server's public key
936  error = tlsReadEcPoint(&context->ecdhContext.qb, curve, p, length, &n);
937  }
938 
939  //Check status code
940  if(!error)
941  {
942  //Advance data pointer
943  p += n;
944  //Remaining bytes to process
945  length -= n;
946 
947  //Verify peer's public key
948  error = ecdhCheckPublicKey(&context->ecdhContext,
949  &context->ecdhContext.qb);
950  }
951  }
952  else
953 #endif
954  //Invalid key exchange method?
955  {
956  //It is not legal to send the ServerKeyExchange message when a key
957  //exchange method other than DHE_DSS, DHE_RSA, DH_anon, ECDHE_RSA,
958  //ECDHE_ECDSA or ECDH_anon is selected
959  error = ERROR_UNEXPECTED_MESSAGE;
960  }
961 
962  //Total number of bytes that have been consumed
963  *consumed = p - params;
964 
965  //Return status code
966  return error;
967 #else
968  //Not implemented
969  return ERROR_NOT_IMPLEMENTED;
970 #endif
971 }
972 
973 
974 /**
975  * @brief Verify server's key exchange parameters signature (TLS 1.0 and TLS 1.1)
976  * @param[in] context Pointer to the TLS context
977  * @param[in] signature Pointer to the digital signature
978  * @param[in] length Number of bytes available in the input stream
979  * @param[in] params Pointer to the server's key exchange parameters
980  * @param[in] paramsLen Length of the server's key exchange parameters
981  * @param[out] consumed Total number of bytes that have been consumed
982  * @return Error code
983  **/
984 
986  const TlsDigitalSignature *signature, size_t length,
987  const uint8_t *params, size_t paramsLen, size_t *consumed)
988 {
989  error_t error;
990 
991 #if (TLS_MAX_VERSION >= TLS_VERSION_1_0 && TLS_MIN_VERSION <= TLS_VERSION_1_1)
992  //Initialize status code
993  error = NO_ERROR;
994 
995  //Check the length of the digitally-signed element
996  if(length < sizeof(TlsDigitalSignature))
997  return ERROR_DECODING_FAILED;
998  if(length < (sizeof(TlsDigitalSignature) + ntohs(signature->length)))
999  return ERROR_DECODING_FAILED;
1000 
1001 #if (TLS_RSA_SIGN_SUPPORT == ENABLED)
1002  //RSA signature algorithm?
1003  if(context->peerCertType == TLS_CERT_RSA_SIGN)
1004  {
1005  Md5Context *md5Context;
1006  Sha1Context *sha1Context;
1007 
1008  //Allocate a memory buffer to hold the MD5 context
1009  md5Context = tlsAllocMem(sizeof(Md5Context));
1010 
1011  //Successful memory allocation?
1012  if(md5Context != NULL)
1013  {
1014  //Compute MD5(ClientHello.random + ServerHello.random +
1015  //ServerKeyExchange.params)
1016  md5Init(md5Context);
1017  md5Update(md5Context, context->clientRandom, TLS_RANDOM_SIZE);
1018  md5Update(md5Context, context->serverRandom, TLS_RANDOM_SIZE);
1019  md5Update(md5Context, params, paramsLen);
1020  md5Final(md5Context, context->serverVerifyData);
1021 
1022  //Release previously allocated memory
1023  tlsFreeMem(md5Context);
1024  }
1025  else
1026  {
1027  //Failed to allocate memory
1028  error = ERROR_OUT_OF_MEMORY;
1029  }
1030 
1031  //Check status code
1032  if(!error)
1033  {
1034  //Allocate a memory buffer to hold the SHA-1 context
1035  sha1Context = tlsAllocMem(sizeof(Sha1Context));
1036 
1037  //Successful memory allocation?
1038  if(sha1Context != NULL)
1039  {
1040  //Compute SHA(ClientHello.random + ServerHello.random +
1041  //ServerKeyExchange.params)
1042  sha1Init(sha1Context);
1043  sha1Update(sha1Context, context->clientRandom, TLS_RANDOM_SIZE);
1044  sha1Update(sha1Context, context->serverRandom, TLS_RANDOM_SIZE);
1045  sha1Update(sha1Context, params, paramsLen);
1046  sha1Final(sha1Context, context->serverVerifyData + MD5_DIGEST_SIZE);
1047 
1048  //Release previously allocated memory
1049  tlsFreeMem(sha1Context);
1050  }
1051  else
1052  {
1053  //Failed to allocate memory
1054  error = ERROR_OUT_OF_MEMORY;
1055  }
1056  }
1057 
1058  //Check status code
1059  if(!error)
1060  {
1061  //RSA signature verification
1062  error = tlsVerifyRsaSignature(&context->peerRsaPublicKey,
1063  context->serverVerifyData, signature->value, ntohs(signature->length));
1064  }
1065  }
1066  else
1067 #endif
1068 #if (TLS_DSA_SIGN_SUPPORT == ENABLED)
1069  //DSA signature algorithm?
1070  if(context->peerCertType == TLS_CERT_DSS_SIGN)
1071  {
1072  Sha1Context *sha1Context;
1073 
1074  //Allocate a memory buffer to hold the SHA-1 context
1075  sha1Context = tlsAllocMem(sizeof(Sha1Context));
1076 
1077  //Successful memory allocation?
1078  if(sha1Context != NULL)
1079  {
1080  //Compute SHA(ClientHello.random + ServerHello.random +
1081  //ServerKeyExchange.params)
1082  sha1Init(sha1Context);
1083  sha1Update(sha1Context, context->clientRandom, TLS_RANDOM_SIZE);
1084  sha1Update(sha1Context, context->serverRandom, TLS_RANDOM_SIZE);
1085  sha1Update(sha1Context, params, paramsLen);
1086  sha1Final(sha1Context, context->serverVerifyData);
1087 
1088  //Release previously allocated memory
1089  tlsFreeMem(sha1Context);
1090  }
1091  else
1092  {
1093  //Failed to allocate memory
1094  error = ERROR_OUT_OF_MEMORY;
1095  }
1096 
1097  //Check status code
1098  if(!error)
1099  {
1100  //DSA signature verification
1101  error = tlsVerifyDsaSignature(context, context->serverVerifyData,
1102  SHA1_DIGEST_SIZE, signature->value, ntohs(signature->length));
1103  }
1104  }
1105  else
1106 #endif
1107 #if (TLS_ECDSA_SIGN_SUPPORT == ENABLED)
1108  //ECDSA signature algorithm?
1109  if(context->peerCertType == TLS_CERT_ECDSA_SIGN)
1110  {
1111  Sha1Context *sha1Context;
1112 
1113  //Allocate a memory buffer to hold the SHA-1 context
1114  sha1Context = tlsAllocMem(sizeof(Sha1Context));
1115 
1116  //Successful memory allocation?
1117  if(sha1Context != NULL)
1118  {
1119  //Compute SHA(ClientHello.random + ServerHello.random +
1120  //ServerKeyExchange.params)
1121  sha1Init(sha1Context);
1122  sha1Update(sha1Context, context->clientRandom, TLS_RANDOM_SIZE);
1123  sha1Update(sha1Context, context->serverRandom, TLS_RANDOM_SIZE);
1124  sha1Update(sha1Context, params, paramsLen);
1125  sha1Final(sha1Context, context->serverVerifyData);
1126 
1127  //Release previously allocated memory
1128  tlsFreeMem(sha1Context);
1129  }
1130 
1131  //Check status code
1132  if(!error)
1133  {
1134  //ECDSA signature verification
1135  error = tlsVerifyEcdsaSignature(context, context->serverVerifyData,
1136  SHA1_DIGEST_SIZE, signature->value, ntohs(signature->length));
1137  }
1138  }
1139  else
1140 #endif
1141  //Invalid signature algorithm?
1142  {
1143  //Report an error
1144  error = ERROR_INVALID_SIGNATURE;
1145  }
1146 
1147  //Total number of bytes that have been consumed
1148  *consumed = sizeof(TlsDigitalSignature) + ntohs(signature->length);
1149 #else
1150  //Not implemented
1151  error = ERROR_NOT_IMPLEMENTED;
1152 #endif
1153 
1154  //Return status code
1155  return error;
1156 }
1157 
1158 
1159 /**
1160  * @brief Verify server's key exchange parameters signature (TLS 1.2)
1161  * @param[in] context Pointer to the TLS context
1162  * @param[in] signature Pointer to the digital signature
1163  * @param[in] length Number of bytes available in the input stream
1164  * @param[in] params Pointer to the server's key exchange parameters
1165  * @param[in] paramsLen Length of the server's key exchange parameters
1166  * @param[out] consumed Total number of bytes that have been consumed
1167  * @return Error code
1168  **/
1169 
1171  const Tls12DigitalSignature *signature, size_t length,
1172  const uint8_t *params, size_t paramsLen, size_t *consumed)
1173 {
1174 #if (TLS_MAX_VERSION >= TLS_VERSION_1_2 && TLS_MIN_VERSION <= TLS_VERSION_1_2)
1175  error_t error;
1176  TlsSignatureScheme signScheme;
1177 
1178  //Initialize status code
1179  error = NO_ERROR;
1180 
1181  //Check the length of the digitally-signed element
1182  if(length < sizeof(Tls12DigitalSignature))
1183  return ERROR_DECODING_FAILED;
1184  if(length < (sizeof(Tls12DigitalSignature) + ntohs(signature->length)))
1185  return ERROR_DECODING_FAILED;
1186 
1187  //The algorithm field specifies the signature scheme
1188  signScheme = (TlsSignatureScheme) ntohs(signature->algorithm);
1189 
1190  //If the client has offered the SignatureAlgorithms extension, the signature
1191  //algorithm and hash algorithm must be a pair listed in that extension (refer
1192  //to RFC 5246, section 7.4.3)
1193  if(!tlsIsSignAlgoSupported(context, signScheme))
1194  return ERROR_ILLEGAL_PARAMETER;
1195 
1196 #if (TLS_RSA_SIGN_SUPPORT == ENABLED || TLS_RSA_PSS_SIGN_SUPPORT == ENABLED || \
1197  TLS_DSA_SIGN_SUPPORT == ENABLED || TLS_ECDSA_SIGN_SUPPORT == ENABLED)
1198  //RSA, DSA or ECDSA signature scheme?
1199  if(TLS_SIGN_ALGO(signScheme) == TLS_SIGN_ALGO_RSA ||
1200  TLS_SIGN_ALGO(signScheme) == TLS_SIGN_ALGO_DSA ||
1201  TLS_SIGN_ALGO(signScheme) == TLS_SIGN_ALGO_ECDSA ||
1202  signScheme == TLS_SIGN_SCHEME_RSA_PSS_RSAE_SHA256 ||
1203  signScheme == TLS_SIGN_SCHEME_RSA_PSS_RSAE_SHA384 ||
1204  signScheme == TLS_SIGN_SCHEME_RSA_PSS_RSAE_SHA512 ||
1205  signScheme == TLS_SIGN_SCHEME_RSA_PSS_PSS_SHA256 ||
1206  signScheme == TLS_SIGN_SCHEME_RSA_PSS_PSS_SHA384 ||
1207  signScheme == TLS_SIGN_SCHEME_RSA_PSS_PSS_SHA512)
1208  {
1209  const HashAlgo *hashAlgo;
1210  HashContext *hashContext;
1211  uint8_t digest[MAX_HASH_DIGEST_SIZE];
1212 
1213  //Check signature scheme
1214  if(signScheme == TLS_SIGN_SCHEME_RSA_PSS_RSAE_SHA256 ||
1215  signScheme == TLS_SIGN_SCHEME_RSA_PSS_PSS_SHA256)
1216  {
1217  //The hashing is intrinsic to the signature algorithm
1219  }
1220  else if(signScheme == TLS_SIGN_SCHEME_RSA_PSS_RSAE_SHA384 ||
1221  signScheme == TLS_SIGN_SCHEME_RSA_PSS_PSS_SHA384)
1222  {
1223  //The hashing is intrinsic to the signature algorithm
1225  }
1226  else if(signScheme == TLS_SIGN_SCHEME_RSA_PSS_RSAE_SHA512 ||
1227  signScheme == TLS_SIGN_SCHEME_RSA_PSS_PSS_SHA512)
1228  {
1229  //The hashing is intrinsic to the signature algorithm
1231  }
1232  else
1233  {
1234  //Retrieve the hash algorithm used for signing
1235  hashAlgo = tlsGetHashAlgo(TLS_HASH_ALGO(signScheme));
1236  }
1237 
1238  //Make sure the hash algorithm is supported
1239  if(hashAlgo != NULL)
1240  {
1241  //Allocate a memory buffer to hold the hash context
1242  hashContext = tlsAllocMem(hashAlgo->contextSize);
1243 
1244  //Successful memory allocation?
1245  if(hashContext != NULL)
1246  {
1247  //Compute hash(ClientHello.random + ServerHello.random +
1248  //ServerKeyExchange.params)
1249  hashAlgo->init(hashContext);
1250  hashAlgo->update(hashContext, context->clientRandom, TLS_RANDOM_SIZE);
1251  hashAlgo->update(hashContext, context->serverRandom, TLS_RANDOM_SIZE);
1252  hashAlgo->update(hashContext, params, paramsLen);
1253  hashAlgo->final(hashContext, digest);
1254 
1255 #if (TLS_RSA_SIGN_SUPPORT == ENABLED)
1256  //RSASSA-PKCS1-v1_5 signature scheme?
1257  if(TLS_SIGN_ALGO(signScheme) == TLS_SIGN_ALGO_RSA &&
1258  context->peerCertType == TLS_CERT_RSA_SIGN)
1259  {
1260  //Verify RSA signature (RSASSA-PKCS1-v1_5 signature scheme)
1261  error = rsassaPkcs1v15Verify(&context->peerRsaPublicKey,
1262  hashAlgo, digest, signature->value, ntohs(signature->length));
1263  }
1264  else
1265 #endif
1266 #if (TLS_RSA_PSS_SIGN_SUPPORT == ENABLED)
1267  //RSASSA-PSS signature scheme (with public key OID rsaEncryption)?
1268  if(signScheme == TLS_SIGN_SCHEME_RSA_PSS_RSAE_SHA256 ||
1269  signScheme == TLS_SIGN_SCHEME_RSA_PSS_RSAE_SHA384 ||
1271  {
1272  //The signature algorithm must be compatible with the key in the
1273  //server's end-entity certificate (refer to RFC 5246, section 7.4.3)
1274  if(context->peerCertType == TLS_CERT_RSA_SIGN)
1275  {
1276  //Verify RSA signature (RSASSA-PSS signature scheme)
1277  error = rsassaPssVerify(&context->peerRsaPublicKey, hashAlgo,
1278  hashAlgo->digestSize, digest, signature->value,
1279  ntohs(signature->length));
1280  }
1281  else
1282  {
1283  //Invalid certificate
1284  error = ERROR_INVALID_SIGNATURE;
1285  }
1286  }
1287  else
1288 #endif
1289 #if (TLS_RSA_PSS_SIGN_SUPPORT == ENABLED)
1290  //RSASSA-PSS signature scheme (with public key OID RSASSA-PSS)?
1291  if(signScheme == TLS_SIGN_SCHEME_RSA_PSS_PSS_SHA256 ||
1292  signScheme == TLS_SIGN_SCHEME_RSA_PSS_PSS_SHA384 ||
1293  signScheme == TLS_SIGN_SCHEME_RSA_PSS_PSS_SHA512)
1294  {
1295  //The signature algorithm must be compatible with the key in the
1296  //server's end-entity certificate (refer to RFC 5246, section 7.4.3)
1297  if(context->peerCertType == TLS_CERT_RSA_PSS_SIGN)
1298  {
1299  //Verify RSA signature (RSASSA-PSS signature scheme)
1300  error = rsassaPssVerify(&context->peerRsaPublicKey, hashAlgo,
1301  hashAlgo->digestSize, digest, signature->value,
1302  ntohs(signature->length));
1303  }
1304  else
1305  {
1306  //Invalid certificate
1307  error = ERROR_INVALID_SIGNATURE;
1308  }
1309  }
1310  else
1311 #endif
1312 #if (TLS_DSA_SIGN_SUPPORT == ENABLED)
1313  //DSA signature scheme?
1314  if(TLS_SIGN_ALGO(signScheme) == TLS_SIGN_ALGO_DSA &&
1315  context->peerCertType == TLS_CERT_DSS_SIGN)
1316  {
1317  //Verify DSA signature
1318  error = tlsVerifyDsaSignature(context, digest,
1319  hashAlgo->digestSize, signature->value,
1320  ntohs(signature->length));
1321  }
1322  else
1323 #endif
1324 #if (TLS_ECDSA_SIGN_SUPPORT == ENABLED)
1325  //ECDSA signature scheme?
1326  if(TLS_SIGN_ALGO(signScheme) == TLS_SIGN_ALGO_ECDSA &&
1327  context->peerCertType == TLS_CERT_ECDSA_SIGN)
1328  {
1329  //Verify ECDSA signature
1330  error = tlsVerifyEcdsaSignature(context, digest,
1331  hashAlgo->digestSize, signature->value,
1332  ntohs(signature->length));
1333  }
1334  else
1335 #endif
1336  //Invalid signature scheme?
1337  {
1338  //Report an error
1339  error = ERROR_INVALID_SIGNATURE;
1340  }
1341 
1342  //Release previously allocated memory
1343  tlsFreeMem(hashContext);
1344  }
1345  else
1346  {
1347  //Failed to allocate memory
1348  error = ERROR_OUT_OF_MEMORY;
1349  }
1350  }
1351  else
1352  {
1353  //Hash algorithm not supported
1354  error = ERROR_INVALID_SIGNATURE;
1355  }
1356  }
1357  else
1358 #endif
1359 #if (TLS_ED25519_SIGN_SUPPORT == ENABLED)
1360  //Ed25519 signature scheme?
1361  if(signScheme == TLS_SIGN_SCHEME_ED25519 &&
1362  context->peerCertType == TLS_CERT_ED25519_SIGN)
1363  {
1364  DataChunk messageChunks[3];
1365 
1366  //Data to be verified is run through the EdDSA algorithm without
1367  //pre-hashing
1368  messageChunks[0].buffer = context->clientRandom;
1369  messageChunks[0].length = TLS_RANDOM_SIZE;
1370  messageChunks[1].buffer = context->serverRandom;
1371  messageChunks[1].length = TLS_RANDOM_SIZE;
1372  messageChunks[2].buffer = params;
1373  messageChunks[2].length = paramsLen;
1374 
1375  //Verify Ed25519 signature (PureEdDSA mode)
1376  error = tlsVerifyEd25519Signature(context, messageChunks,
1377  arraysize(messageChunks), signature->value, ntohs(signature->length));
1378  }
1379  else
1380 #endif
1381 #if (TLS_ED448_SIGN_SUPPORT == ENABLED)
1382  //Ed448 signature scheme?
1383  if(signScheme == TLS_SIGN_SCHEME_ED448 &&
1384  context->peerCertType == TLS_CERT_ED448_SIGN)
1385  {
1386  DataChunk messageChunks[3];
1387 
1388  //Data to be verified is run through the EdDSA algorithm without
1389  //pre-hashing
1390  messageChunks[0].buffer = context->clientRandom;
1391  messageChunks[0].length = TLS_RANDOM_SIZE;
1392  messageChunks[1].buffer = context->serverRandom;
1393  messageChunks[1].length = TLS_RANDOM_SIZE;
1394  messageChunks[2].buffer = params;
1395  messageChunks[2].length = paramsLen;
1396 
1397  //Verify Ed448 signature (PureEdDSA mode)
1398  error = tlsVerifyEd448Signature(context, messageChunks,
1399  arraysize(messageChunks), signature->value, ntohs(signature->length));
1400  }
1401  else
1402 #endif
1403  //Invalid signature algorithm?
1404  {
1405  //Report an error
1406  error = ERROR_INVALID_SIGNATURE;
1407  }
1408 
1409  //Total number of bytes that have been consumed
1410  *consumed = sizeof(Tls12DigitalSignature) + ntohs(signature->length);
1411 
1412  //Return status code
1413  return error;
1414 #else
1415  //Not implemented
1416  return ERROR_NOT_IMPLEMENTED;
1417 #endif
1418 }
1419 
1420 
1421 /**
1422  * @brief Version selection
1423  * @param[in] context Pointer to the TLS context
1424  * @param[in] message Pointer to the received ServerHello message
1425  * @param[in] extensions ServerHello extensions offered by the server
1426  * @return Error code
1427  **/
1428 
1431 {
1432  error_t error;
1433  uint16_t selectedVersion;
1434 
1435 #if (TLS_MAX_VERSION >= TLS_VERSION_1_3 && TLS_MIN_VERSION <= TLS_VERSION_1_3)
1436  //Clients must check for the SupportedVersions extension prior to
1437  //processing the rest of the ServerHello
1438  if(extensions->selectedVersion != NULL)
1439  {
1440  //If a client receives an extension type in the ServerHello that it did
1441  //not request in the associated ClientHello, it must abort the handshake
1442  //with an unsupported_extension fatal alert
1443  if(context->versionMax <= TLS_VERSION_1_2)
1445 
1446  //The legacy_version field must be set to 0x0303, which is the version
1447  //number for TLS 1.2
1448  if(context->transportProtocol == TLS_TRANSPORT_PROTOCOL_DATAGRAM)
1449  {
1450  if(ntohs(message->serverVersion) != DTLS_VERSION_1_2)
1452  }
1453  else
1454  {
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  (context->transportProtocol == TLS_TRANSPORT_PROTOCOL_STREAM ||
1573  context->transportProtocol == TLS_TRANSPORT_PROTOCOL_EAP))
1574  {
1575  //If a match is found, the client must abort the handshake with an
1576  //illegal_parameter alert
1577  if(osMemcmp(message->random + 24, tls12DowngradeRandom, 8) == 0)
1578  return ERROR_ILLEGAL_PARAMETER;
1579  }
1580 #endif
1581 
1582  //Successful processing
1583  return NO_ERROR;
1584 }
1585 
1586 
1587 /**
1588  * @brief Resume TLS session via session ID
1589  * @param[in] context Pointer to the TLS context
1590  * @param[in] sessionId Pointer to the session ID provided by the server
1591  * @param[in] sessionIdLen Length of the session ID, in bytes
1592  * @param[in] cipherSuite Cipher suite selected by the server
1593  * @return Error code
1594  **/
1595 
1597  size_t sessionIdLen, uint16_t cipherSuite)
1598 {
1599  error_t error;
1600 
1601  //Initialize status code
1602  error = NO_ERROR;
1603 
1604 #if (TLS_SESSION_RESUME_SUPPORT == ENABLED)
1605  //Check whether the session ID matches the value that was supplied by the
1606  //client
1607  if(sessionIdLen != 0 && sessionIdLen == context->sessionIdLen &&
1608  osMemcmp(sessionId, context->sessionId, sessionIdLen) == 0)
1609  {
1610  //For resumed sessions, the selected cipher suite shall be the same as
1611  //the session being resumed
1612  if(cipherSuite != 0 && cipherSuite == context->cipherSuite.identifier)
1613  {
1614  //Perform abbreviated handshake
1615  context->resume = TRUE;
1616  }
1617  else
1618  {
1619  //The session ID is no more valid
1620  context->sessionIdLen = 0;
1621 
1622  //When renegotiating, if the server tries to use another version or
1623  //compression method than previously, abort
1624  error = ERROR_ILLEGAL_PARAMETER;
1625  }
1626  }
1627  else
1628 #endif
1629  {
1630  //Perform a full handshake
1631  context->resume = FALSE;
1632  }
1633 
1634  //Return status code
1635  return error;
1636 }
1637 
1638 
1639 /**
1640  * @brief Check whether a session ticket is valid
1641  * @param[in] context Pointer to the TLS context
1642  * @return TRUE is the session ticket is valid, else FALSE
1643  **/
1644 
1646 {
1647  bool_t valid = FALSE;
1648 
1649  //TLS 1.3 tickets cannot be used to resume a TLS 1.2 session
1650  if(context->version <= TLS_VERSION_1_2)
1651  {
1652  //Valid ticket?
1653  if(context->ticket != NULL && context->ticketLen > 0)
1654  {
1655  valid = TRUE;
1656  }
1657  }
1658 
1659  //Return TRUE is the ticket is valid, else FALSE
1660  return valid;
1661 }
1662 
1663 #endif
@ TLS_GROUP_BRAINPOOLP512R1_TLS13
Definition: tls.h:1481
#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:1134
@ ERROR_UNSUPPORTED_ELLIPTIC_CURVE
Definition: error.h:133
uint8_t extensions[]
Definition: ntp_common.h:213
@ TLS_GROUP_BRAINPOOLP256R1_TLS13
Definition: tls.h:1479
Generic hash algorithm context.
@ TLS_TRANSPORT_PROTOCOL_QUIC
Definition: tls.h:1001
int bool_t
Definition: compiler_port.h:61
uint8_t sessionId[]
Definition: tls.h:1891
TLS cipher suites.
uint16_t cipherSuite
Cipher suite identifier.
Definition: tls.h:2001
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:1193
X509TbsCertificate tbsCert
Definition: x509_common.h:1123
TlsDigitalSignature
Definition: tls.h:1835
@ 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:1260
@ 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
error_t x509ParseCertificate(const uint8_t *data, size_t length, X509CertInfo *certInfo)
Parse a X.509 certificate.
@ TLS_GROUP_CURVE_SM2
Definition: tls.h:1489
size_t digestSize
Definition: crypto.h:1130
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:1053
@ TLS_TRANSPORT_PROTOCOL_DATAGRAM
Definition: tls.h:1000
HashAlgoUpdate update
Definition: crypto.h:1135
void md5Final(Md5Context *context, uint8_t *digest)
Finish the MD5 message digest.
Session cache management.
TlsPskIdentity
Definition: tls.h:1813
@ 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:969
#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:1824
@ 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:1128
uint8_t sessionIdLen
Definition: tls.h:1890
@ TLS_KEY_EXCH_RSA
Definition: tls.h:1185
void md5Init(Md5Context *context)
Initialize MD5 message digest context.
TlsCipherSuites
Definition: tls.h:1613
#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:1872
#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:1847
uint16_t identifier
Definition: tls.h:2172
@ 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_TRANSPORT_PROTOCOL_EAP
Definition: tls.h:1002
@ 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:1624
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:2253
@ 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:1480
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:1136
Data chunk descriptor.
Definition: crypto.h:1052
#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:1045
TlsRecord
Definition: tls.h:1860
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:1528
#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:1003
@ TLS_CA_ROOT_KEY_ID_TYPE_X509_NAME
Definition: tls.h:1437
const char_t * tlsGetCipherSuiteName(uint16_t identifier)
Convert cipher suite identifier to string representation.
TlsServerHello
Definition: tls.h:1905
#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:1892
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:1084
#define STORE24BE(a, p)
Definition: cpu_endian.h:273
SHA-1 algorithm context.
Definition: sha1.h:62
TlsTrustedAuthorities
Definition: tls.h:1679
@ TLS_CERT_ECDSA_SIGN
Definition: tls.h:1242
@ TLS_KEY_EXCH_DHE_DSS
Definition: tls.h:1189
size_t length
Definition: crypto.h:1054
@ TLS_TRANSPORT_PROTOCOL_STREAM
Definition: tls.h:999
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:1124
#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:1545
@ 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:1668
Debugging facilities.
error_t tlsFormatClientHello(TlsContext *context, TlsClientHello *message, size_t *length)
Format ClientHello message.
Definition: tls_client.c:292
#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.