tls_signature.c
Go to the documentation of this file.
1 /**
2  * @file tls_signature.c
3  * @brief RSA/DSA/ECDSA/EdDSA signature generation and verification (TLS 1.3)
4  *
5  * @section License
6  *
7  * SPDX-License-Identifier: GPL-2.0-or-later
8  *
9  * Copyright (C) 2010-2023 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.3.2
29  **/
30 
31 //Switch to the appropriate trace level
32 #define TRACE_LEVEL TLS_TRACE_LEVEL
33 
34 //Dependencies
35 #include "tls.h"
36 #include "tls_signature.h"
37 #include "tls_transcript_hash.h"
38 #include "tls_misc.h"
39 #include "pkix/pem_import.h"
40 #include "pkc/rsa.h"
41 #include "pkc/dsa.h"
42 #include "ecc/ecdsa.h"
43 #include "ecc/eddsa.h"
44 #include "debug.h"
45 
46 //Check TLS library configuration
47 #if (TLS_SUPPORT == ENABLED)
48 
49 
50 /**
51  * @brief Select the algorithm to be used when generating digital signatures
52  * @param[in] context Pointer to the TLS context
53  * @param[in] cert End entity certificate
54  * @param[in] supportedSignAlgos List of supported signature/hash algorithm pairs
55  * @return Error code
56  **/
57 
59  const TlsSignHashAlgos *supportedSignAlgos)
60 {
61  error_t error;
62  uint_t i;
63  uint_t n;
64  const HashAlgo *hashAlgo;
65  const TlsSignHashAlgo *p;
66 
67  //Initialize status code
68  error = ERROR_HANDSHAKE_FAILED;
69 
70  //Default signature algorithm
71  context->signAlgo = TLS_SIGN_ALGO_ANONYMOUS;
72  context->signHashAlgo = TLS_HASH_ALGO_NONE;
73 
74 #if (TLS_RSA_SIGN_SUPPORT == ENABLED || TLS_RSA_PSS_SIGN_SUPPORT == ENABLED || \
75  TLS_DSA_SIGN_SUPPORT == ENABLED || TLS_ECDSA_SIGN_SUPPORT == ENABLED)
76  //RSA, DSA or ECDSA certificate?
77  if(cert->type == TLS_CERT_RSA_SIGN ||
78  cert->type == TLS_CERT_DSS_SIGN ||
79  cert->type == TLS_CERT_ECDSA_SIGN)
80  {
81  //Check whether the peer has provided a list of supported hash/signature
82  //algorithm pairs
83  if(supportedSignAlgos != NULL)
84  {
85  TlsHashAlgo hashAlgoId;
86 
87  //Process the list and select the relevant signature algorithm
88  p = supportedSignAlgos->value;
89  //Get the number of hash/signature algorithm pairs present in the list
90  n = ntohs(supportedSignAlgos->length) / sizeof(TlsSignHashAlgo);
91 
92  //The hash algorithm to be used when generating signatures must be
93  //one of those present in the list
94  for(i = 0; i < n; i++)
95  {
96  //Reset the hash algorithm identifier to its default value
97  hashAlgoId = TLS_HASH_ALGO_NONE;
98 
99 #if (TLS_RSA_SIGN_SUPPORT == ENABLED)
100  //RSA signature scheme?
101  if(cert->type == TLS_CERT_RSA_SIGN &&
102  p[i].signature == TLS_SIGN_ALGO_RSA)
103  {
104  //In TLS 1.3, RSASSA-PKCS1-v1_5 signature algorithms refer
105  //solely to signatures which appear in certificates and are
106  //not defined for use in signed TLS handshake messages
107  if(context->version <= TLS_VERSION_1_2)
108  {
109  //Select current hash algorithm
110  hashAlgoId = (TlsHashAlgo) p[i].hash;
111  }
112  }
113  else
114 #endif
115 #if (TLS_RSA_PSS_SIGN_SUPPORT == ENABLED)
116  //RSA-PSS signature scheme?
117  if(cert->type == TLS_CERT_RSA_SIGN &&
118  p[i].hash == TLS_HASH_ALGO_INTRINSIC)
119  {
120  //TLS 1.2 and TLS 1.3 support RSASSA-PSS signature schemes
121  if(context->version >= TLS_VERSION_1_2)
122  {
123  //Check RSA-PSS signature scheme
125  {
126  //RSASSA-PSS RSAE signature scheme with SHA-256
127  hashAlgoId = TLS_HASH_ALGO_SHA256;
128  }
130  {
131  //RSASSA-PSS RSAE signature scheme with SHA-384
132  hashAlgoId = TLS_HASH_ALGO_SHA384;
133  }
135  {
136  //RSASSA-PSS RSAE signature scheme with SHA-512
137  hashAlgoId = TLS_HASH_ALGO_SHA512;
138  }
139  else
140  {
141  //Just for sanity
142  }
143  }
144  }
145  else
146 #endif
147 #if (TLS_DSA_SIGN_SUPPORT == ENABLED)
148  //DSA signature scheme?
149  if(cert->type == TLS_CERT_DSS_SIGN &&
150  p[i].signature == TLS_SIGN_ALGO_DSA)
151  {
152  //TLS 1.3 removes support for DSA certificates
153  if(context->version <= TLS_VERSION_1_2)
154  {
155  //Select current hash algorithm
156  hashAlgoId = (TlsHashAlgo) p[i].hash;
157  }
158  }
159  else
160 #endif
161 #if (TLS_ECDSA_SIGN_SUPPORT == ENABLED)
162  //ECDSA signature scheme?
163  if(cert->type == TLS_CERT_ECDSA_SIGN &&
164  p[i].signature == TLS_SIGN_ALGO_ECDSA)
165  {
166  //Version of TLS prior to TLS 1.3?
167  if(context->version <= TLS_VERSION_1_2)
168  {
169  //Select current hash algorithm
170  hashAlgoId = (TlsHashAlgo) p[i].hash;
171  }
172  else
173  {
174  //Check elliptic curve and hash algorithm
175  if(cert->namedCurve == TLS_GROUP_SECP256R1 &&
176  p[i].hash == TLS_HASH_ALGO_SHA256)
177  {
178  //Select SHA-256 hash algorithm
179  hashAlgoId = TLS_HASH_ALGO_SHA256;
180  }
181  else if(cert->namedCurve == TLS_GROUP_SECP384R1 &&
182  p[i].hash == TLS_HASH_ALGO_SHA384)
183  {
184  //Select SHA-384 hash algorithm
185  hashAlgoId = TLS_HASH_ALGO_SHA384;
186  }
187  else if(cert->namedCurve == TLS_GROUP_SECP521R1 &&
188  p[i].hash == TLS_HASH_ALGO_SHA512)
189  {
190  //Select SHA-512 hash algorithm
191  hashAlgoId = TLS_HASH_ALGO_SHA512;
192  }
193  else
194  {
195  //Just for sanity
196  }
197  }
198  }
199  else
200 #endif
201  //Unknown signature scheme?
202  {
203  //Just for sanity
204  }
205 
206  //Get the hash algorithm that matches the specified identifier
207  hashAlgo = tlsGetHashAlgo(hashAlgoId);
208 
209  //Check whether the hash algorithm is supported
210  if(hashAlgo != NULL)
211  {
212  //In TLS versions prior to 1.3, the client implementation can only
213  //generate a CertificateVerify using SHA-1 or the hash used by
214  //the PRF. Supporting all hash algorithms would require the client
215  //to maintain hashes for every possible signature algorithm that
216  //the server may request...
217  if(context->version == TLS_VERSION_1_3 ||
218  context->entity == TLS_CONNECTION_END_SERVER ||
219  hashAlgoId == TLS_HASH_ALGO_SHA1 ||
220  hashAlgo == context->cipherSuite.prfHashAlgo)
221  {
222  //The signature algorithm is acceptable
223  context->signAlgo = (TlsSignatureAlgo) p[i].signature;
224  context->signHashAlgo = (TlsHashAlgo) hashAlgoId;
225  break;
226  }
227  }
228  }
229  }
230  else
231  {
232  //Version of TLS prior to TLS 1.3?
233  if(context->version <= TLS_VERSION_1_2)
234  {
235  //Check certificate type
236  if(cert->type == TLS_CERT_RSA_SIGN)
237  {
238  //Select RSA signature algorithm
239  context->signAlgo = TLS_SIGN_ALGO_RSA;
240  }
241  else if(cert->type == TLS_CERT_DSS_SIGN)
242  {
243  //Select DSA signature algorithm
244  context->signAlgo = TLS_SIGN_ALGO_DSA;
245  }
246  else if(cert->type == TLS_CERT_ECDSA_SIGN)
247  {
248  //Select ECDSA signature algorithm
249  context->signAlgo = TLS_SIGN_ALGO_ECDSA;
250  }
251  else
252  {
253  //Just for sanity
254  }
255 
256  //Select the default hash algorithm to be used when generating
257  //RSA, DSA or ECDSA signatures
259  {
260  //Select SHA-1 hash algorithm
261  context->signHashAlgo = TLS_HASH_ALGO_SHA1;
262  }
263  else if(tlsGetHashAlgo(TLS_HASH_ALGO_SHA256) != NULL)
264  {
265  //Select SHA-256 hash algorithm
266  context->signHashAlgo = TLS_HASH_ALGO_SHA256;
267  }
268  else if(tlsGetHashAlgo(TLS_HASH_ALGO_SHA384) != NULL)
269  {
270  //Select SHA-384 hash algorithm
271  context->signHashAlgo = TLS_HASH_ALGO_SHA384;
272  }
273  else if(tlsGetHashAlgo(TLS_HASH_ALGO_SHA512) != NULL)
274  {
275  //Select SHA-512 hash algorithm
276  context->signHashAlgo = TLS_HASH_ALGO_SHA512;
277  }
278  else
279  {
280  //Just for sanity
281  }
282  }
283  }
284  }
285  else
286 #endif
287 #if (TLS_RSA_PSS_SIGN_SUPPORT == ENABLED)
288  //RSA-PSS certificate?
289  if(cert->type == TLS_CERT_RSA_PSS_SIGN)
290  {
291  //TLS 1.2 and TLS 1.3 support RSASSA-PSS signature schemes
292  if(context->version >= TLS_VERSION_1_2)
293  {
294  //Check whether the peer has provided a list of supported hash/signature
295  //algorithm pairs
296  if(supportedSignAlgos != NULL)
297  {
298  TlsHashAlgo hashAlgoId;
299 
300  //Process the list and select the relevant signature algorithm
301  p = supportedSignAlgos->value;
302  //Get the number of hash/signature algorithm pairs present in the list
303  n = ntohs(supportedSignAlgos->length) / sizeof(TlsSignHashAlgo);
304 
305  //The hash algorithm to be used when generating signatures must be
306  //one of those present in the list
307  for(i = 0; i < n; i++)
308  {
309  //The hashing is intrinsic to the signature algorithm
310  if(p[i].hash == TLS_HASH_ALGO_INTRINSIC)
311  {
312  //Check signature scheme
314  {
315  //Select SHA-256 hash algorithm
316  hashAlgoId = TLS_HASH_ALGO_SHA256;
317  }
319  {
320  //Select SHA-384 hash algorithm
321  hashAlgoId = TLS_HASH_ALGO_SHA384;
322  }
324  {
325  //Select SHA-512 hash algorithm
326  hashAlgoId = TLS_HASH_ALGO_SHA512;
327  }
328  else
329  {
330  //Invalid signature scheme
331  hashAlgoId = TLS_HASH_ALGO_NONE;
332  }
333 
334  //Check whether the hash algorithm is supported
335  if(tlsGetHashAlgo(hashAlgoId) != NULL)
336  {
337  //Acceptable hash algorithm found
338  context->signAlgo = (TlsSignatureAlgo) p[i].signature;
339  context->signHashAlgo = (TlsHashAlgo) p[i].hash;
340  break;
341  }
342  }
343  }
344  }
345  }
346  }
347  else
348 #endif
349 #if (TLS_EDDSA_SIGN_SUPPORT == ENABLED)
350  //EdDSA certificate?
351  if(cert->type == TLS_CERT_ED25519_SIGN ||
352  cert->type == TLS_CERT_ED448_SIGN)
353  {
354  //TLS 1.2 or TLS 1.3 currently selected?
355  if((context->version >= TLS_VERSION_1_2 &&
356  context->entity == TLS_CONNECTION_END_SERVER) ||
357  (context->version >= TLS_VERSION_1_3 &&
358  context->entity == TLS_CONNECTION_END_CLIENT))
359  {
360  //Check certificate type
361  if(cert->type == TLS_CERT_ED25519_SIGN)
362  {
363  //Ed25519 is used in PureEdDSA mode, without pre-hashing
364  context->signAlgo = TLS_SIGN_ALGO_ED25519;
365  context->signHashAlgo = TLS_HASH_ALGO_INTRINSIC;
366  }
367  else if(cert->type == TLS_CERT_ED448_SIGN)
368  {
369  //Ed448 is used in PureEdDSA mode, without pre-hashing
370  context->signAlgo = TLS_SIGN_ALGO_ED448;
371  context->signHashAlgo = TLS_HASH_ALGO_INTRINSIC;
372  }
373  else
374  {
375  //Just for sanity
376  }
377  }
378  }
379  else
380 #endif
381  //Unsupported signature algorithm?
382  {
383  //Just for sanity
384  }
385 
386  //If no acceptable choices are presented, return an error
387  if(context->signAlgo != TLS_SIGN_ALGO_ANONYMOUS &&
388  context->signHashAlgo != TLS_HASH_ALGO_NONE)
389  {
390  error = NO_ERROR;
391  }
392 
393  //Return status code
394  return error;
395 }
396 
397 
398 #if (TLS_MAX_VERSION >= TLS_VERSION_1_0 && TLS_MIN_VERSION <= TLS_VERSION_1_1)
399 
400 /**
401  * @brief Digital signature generation(TLS 1.0 or TLS 1.1)
402  * @param[in] context Pointer to the TLS context
403  * @param[out] p Buffer where to store the digitally-signed element
404  * @param[out] length Length of the digitally-signed element
405  * @return Error code
406  **/
407 
408 error_t tlsGenerateSignature(TlsContext *context, uint8_t *p,
409  size_t *length)
410 {
411  error_t error;
412  size_t n;
414 
415  //The digitally-signed element does not convey the signature algorithm
416  //to use, and hence implementations need to inspect the certificate to
417  //find out the signature algorithm to use
419 
420 #if (TLS_RSA_SIGN_SUPPORT == ENABLED)
421  //RSA certificate?
422  if(context->cert->type == TLS_CERT_RSA_SIGN)
423  {
424  RsaPrivateKey privateKey;
425 
426  //Initialize RSA private key
427  rsaInitPrivateKey(&privateKey);
428 
429  //Digest all the handshake messages starting at ClientHello using MD5
430  error = tlsFinalizeTranscriptHash(context, MD5_HASH_ALGO,
431  context->transcriptMd5Context, "", context->clientVerifyData);
432 
433  //Check status code
434  if(!error)
435  {
436  //Digest all the handshake messages starting at ClientHello using SHA-1
437  error = tlsFinalizeTranscriptHash(context, SHA1_HASH_ALGO,
438  context->transcriptSha1Context, "",
439  context->clientVerifyData + MD5_DIGEST_SIZE);
440  }
441 
442  //Check status code
443  if(!error)
444  {
445  //Decode the PEM structure that holds the RSA private key
446  error = pemImportRsaPrivateKey(context->cert->privateKey,
447  context->cert->privateKeyLen, context->cert->password, &privateKey);
448  }
449 
450  //Check status code
451  if(!error)
452  {
453  //Generate an RSA signature using the client's private key
454  error = tlsGenerateRsaSignature(&privateKey,
455  context->clientVerifyData, signature->value, &n);
456  }
457 
458  //Release previously allocated resources
459  rsaFreePrivateKey(&privateKey);
460  }
461  else
462 #endif
463 #if (TLS_DSA_SIGN_SUPPORT == ENABLED)
464  //DSA certificate?
465  if(context->cert->type == TLS_CERT_DSS_SIGN)
466  {
467  //Digest all the handshake messages starting at ClientHello
468  error = tlsFinalizeTranscriptHash(context, SHA1_HASH_ALGO,
469  context->transcriptSha1Context, "", context->clientVerifyData);
470 
471  //Check status code
472  if(!error)
473  {
474  //Generate a DSA signature using the client's private key
475  error = tlsGenerateDsaSignature(context, context->clientVerifyData,
476  SHA1_DIGEST_SIZE, signature->value, &n);
477  }
478  }
479  else
480 #endif
481 #if (TLS_ECDSA_SIGN_SUPPORT == ENABLED)
482  //ECDSA certificate?
483  if(context->cert->type == TLS_CERT_ECDSA_SIGN)
484  {
485  //Digest all the handshake messages starting at ClientHello
486  error = tlsFinalizeTranscriptHash(context, SHA1_HASH_ALGO,
487  context->transcriptSha1Context, "", context->clientVerifyData);
488 
489  //Check status code
490  if(!error)
491  {
492  //Generate an ECDSA signature using the client's private key
493  error = tlsGenerateEcdsaSignature(context, context->clientVerifyData,
494  SHA1_DIGEST_SIZE, signature->value, &n);
495  }
496  }
497  else
498 #endif
499  //Invalid certificate?
500  {
501  //Report an error
503  }
504 
505  //Check status code
506  if(!error)
507  {
508  //The signature is preceded by a 2-byte length field
509  signature->length = htons(n);
510  //Total length of the digitally-signed element
511  *length = sizeof(TlsDigitalSignature) + n;
512  }
513 
514  //Return status code
515  return error;
516 }
517 
518 
519 /**
520  * @brief Digital signature verification (TLS 1.0 and TLS 1.1)
521  * @param[in] context Pointer to the TLS context
522  * @param[in] p Pointer to the digitally-signed element to be verified
523  * @param[in] length Length of the digitally-signed element
524  * @return Error code
525  **/
526 
527 error_t tlsVerifySignature(TlsContext *context, const uint8_t *p,
528  size_t length)
529 {
530  error_t error;
532 
533  //The digitally-signed element does not convey the signature algorithm
534  //to use, and hence implementations need to inspect the certificate to
535  //find out the signature algorithm to use
537 
538  //Check the length of the digitally-signed element
539  if(length < sizeof(TlsDigitalSignature))
540  return ERROR_DECODING_FAILED;
541  if(length != (sizeof(TlsDigitalSignature) + ntohs(signature->length)))
542  return ERROR_DECODING_FAILED;
543 
544 #if (TLS_RSA_SIGN_SUPPORT == ENABLED)
545  //RSA certificate?
546  if(context->peerCertType == TLS_CERT_RSA_SIGN)
547  {
548  //Digest all the handshake messages starting at ClientHello using MD5
549  error = tlsFinalizeTranscriptHash(context, MD5_HASH_ALGO,
550  context->transcriptMd5Context, "", context->clientVerifyData);
551 
552  //Check status code
553  if(!error)
554  {
555  //Digest all the handshake messages starting at ClientHello using SHA-1
556  error = tlsFinalizeTranscriptHash(context, SHA1_HASH_ALGO,
557  context->transcriptSha1Context, "",
558  context->clientVerifyData + MD5_DIGEST_SIZE);
559  }
560 
561  //Check status code
562  if(!error)
563  {
564  //Verify RSA signature using client's public key
565  error = tlsVerifyRsaSignature(&context->peerRsaPublicKey,
566  context->clientVerifyData, signature->value,
567  ntohs(signature->length));
568  }
569  }
570  else
571 #endif
572 #if (TLS_DSA_SIGN_SUPPORT == ENABLED)
573  //DSA certificate?
574  if(context->peerCertType == TLS_CERT_DSS_SIGN)
575  {
576  //Digest all the handshake messages starting at ClientHello
577  error = tlsFinalizeTranscriptHash(context, SHA1_HASH_ALGO,
578  context->transcriptSha1Context, "", context->clientVerifyData);
579 
580  //Check status code
581  if(!error)
582  {
583  //Verify DSA signature using client's public key
584  error = tlsVerifyDsaSignature(context, context->clientVerifyData,
585  SHA1_DIGEST_SIZE, signature->value, ntohs(signature->length));
586  }
587  }
588  else
589 #endif
590 #if (TLS_ECDSA_SIGN_SUPPORT == ENABLED)
591  //ECDSA certificate?
592  if(context->peerCertType == TLS_CERT_ECDSA_SIGN)
593  {
594  //Digest all the handshake messages starting at ClientHello
595  error = tlsFinalizeTranscriptHash(context, SHA1_HASH_ALGO,
596  context->transcriptSha1Context, "", context->clientVerifyData);
597 
598  //Check status code
599  if(!error)
600  {
601  //Verify ECDSA signature using client's public key
602  error = tlsVerifyEcdsaSignature(context, context->clientVerifyData,
603  SHA1_DIGEST_SIZE, signature->value, ntohs(signature->length));
604  }
605  }
606  else
607 #endif
608  //Invalid signature algorithm?
609  {
610  //Report an error
611  error = ERROR_INVALID_SIGNATURE;
612  }
613 
614  //Return status code
615  return error;
616 }
617 
618 #endif
619 #if (TLS_MAX_VERSION >= TLS_VERSION_1_2 && TLS_MIN_VERSION <= TLS_VERSION_1_2)
620 
621 /**
622  * @brief Digital signature generation(TLS 1.2)
623  * @param[in] context Pointer to the TLS context
624  * @param[out] p Buffer where to store the digitally-signed element
625  * @param[out] length Length of the digitally-signed element
626  * @return Error code
627  **/
628 
630  size_t *length)
631 {
632  error_t error;
633  size_t n;
635  const HashAlgo *hashAlgo;
636 
637  //Point to the digitally-signed element
639 
640  //Retrieve the hash algorithm used for signing
641  if(context->signAlgo == TLS_SIGN_ALGO_RSA_PSS_RSAE_SHA256 ||
642  context->signAlgo == TLS_SIGN_ALGO_RSA_PSS_PSS_SHA256)
643  {
644  //The hashing is intrinsic to the signature algorithm
646  }
647  else if(context->signAlgo == TLS_SIGN_ALGO_RSA_PSS_RSAE_SHA384 ||
648  context->signAlgo == TLS_SIGN_ALGO_RSA_PSS_PSS_SHA384)
649  {
650  //The hashing is intrinsic to the signature algorithm
652  }
653  else if(context->signAlgo == TLS_SIGN_ALGO_RSA_PSS_RSAE_SHA512 ||
654  context->signAlgo == TLS_SIGN_ALGO_RSA_PSS_PSS_SHA512)
655  {
656  //The hashing is intrinsic to the signature algorithm
658  }
659  else
660  {
661  //Select the relevant hash algorithm
662  hashAlgo = tlsGetHashAlgo(context->signHashAlgo);
663  }
664 
665  //Digest all the handshake messages starting at ClientHello
666  if(hashAlgo == SHA1_HASH_ALGO)
667  {
668  //Use SHA-1 hash algorithm
669  error = tlsFinalizeTranscriptHash(context, SHA1_HASH_ALGO,
670  context->transcriptSha1Context, "", context->clientVerifyData);
671  }
672  else if(hashAlgo == context->cipherSuite.prfHashAlgo)
673  {
674  //Use PRF hash algorithm (SHA-256 or SHA-384)
675  error = tlsFinalizeTranscriptHash(context, hashAlgo,
676  context->transcriptHashContext, "", context->clientVerifyData);
677  }
678  else
679  {
680  //The specified hash algorithm is not supported
682  }
683 
684  //Handshake message hash successfully computed?
685  if(!error)
686  {
687 #if (TLS_RSA_SIGN_SUPPORT == ENABLED)
688  //RSASSA-PKCS1-v1_5 signature scheme?
689  if(context->signAlgo == TLS_SIGN_ALGO_RSA)
690  {
691  RsaPrivateKey privateKey;
692 
693  //Initialize RSA private key
694  rsaInitPrivateKey(&privateKey);
695 
696  //Set the relevant signature algorithm
697  signature->algorithm.signature = TLS_SIGN_ALGO_RSA;
698  signature->algorithm.hash = context->signHashAlgo;
699 
700  //Decode the PEM structure that holds the RSA private key
701  error = pemImportRsaPrivateKey(context->cert->privateKey,
702  context->cert->privateKeyLen, context->cert->password, &privateKey);
703 
704  //Check status code
705  if(!error)
706  {
707  //Generate RSA signature (RSASSA-PKCS1-v1_5 signature scheme)
708  error = rsassaPkcs1v15Sign(&privateKey, hashAlgo,
709  context->clientVerifyData, signature->value, &n);
710  }
711 
712  //Release previously allocated resources
713  rsaFreePrivateKey(&privateKey);
714  }
715  else
716 #endif
717 #if (TLS_RSA_PSS_SIGN_SUPPORT == ENABLED)
718  //RSASSA-PSS signature scheme?
719  if(context->signAlgo == TLS_SIGN_ALGO_RSA_PSS_RSAE_SHA256 ||
720  context->signAlgo == TLS_SIGN_ALGO_RSA_PSS_RSAE_SHA384 ||
721  context->signAlgo == TLS_SIGN_ALGO_RSA_PSS_RSAE_SHA512 ||
722  context->signAlgo == TLS_SIGN_ALGO_RSA_PSS_PSS_SHA256 ||
723  context->signAlgo == TLS_SIGN_ALGO_RSA_PSS_PSS_SHA384 ||
724  context->signAlgo == TLS_SIGN_ALGO_RSA_PSS_PSS_SHA512)
725  {
726  RsaPrivateKey privateKey;
727 
728  //Initialize RSA private key
729  rsaInitPrivateKey(&privateKey);
730 
731  //Set the relevant signature algorithm
732  signature->algorithm.signature = context->signAlgo;
733  signature->algorithm.hash = TLS_HASH_ALGO_INTRINSIC;
734 
735  //Decode the PEM structure that holds the RSA private key
736  error = pemImportRsaPrivateKey(context->cert->privateKey,
737  context->cert->privateKeyLen, context->cert->password, &privateKey);
738 
739  //Check status code
740  if(!error)
741  {
742  //Generate RSA signature (RSASSA-PSS signature scheme)
743  error = rsassaPssSign(context->prngAlgo, context->prngContext,
744  &privateKey, hashAlgo, hashAlgo->digestSize,
745  context->clientVerifyData, signature->value, &n);
746  }
747 
748  //Release previously allocated resources
749  rsaFreePrivateKey(&privateKey);
750  }
751  else
752 #endif
753 #if (TLS_DSA_SIGN_SUPPORT == ENABLED)
754  //DSA signature scheme?
755  if(context->signAlgo == TLS_SIGN_ALGO_DSA)
756  {
757  //Set the relevant signature algorithm
758  signature->algorithm.signature = TLS_SIGN_ALGO_DSA;
759  signature->algorithm.hash = context->signHashAlgo;
760 
761  //Generate a DSA signature using the client's private key
762  error = tlsGenerateDsaSignature(context, context->clientVerifyData,
763  hashAlgo->digestSize, signature->value, &n);
764  }
765  else
766 #endif
767 #if (TLS_ECDSA_SIGN_SUPPORT == ENABLED)
768  //ECDSA signature scheme?
769  if(context->signAlgo == TLS_SIGN_ALGO_ECDSA)
770  {
771  //Set the relevant signature algorithm
772  signature->algorithm.signature = TLS_SIGN_ALGO_ECDSA;
773  signature->algorithm.hash = context->signHashAlgo;
774 
775  //Generate an ECDSA signature using the client's private key
776  error = tlsGenerateEcdsaSignature(context, context->clientVerifyData,
777  hashAlgo->digestSize, signature->value, &n);
778  }
779  else
780 #endif
781  //Invalid signature scheme?
782  {
783  //Report an error
785  }
786  }
787 
788  //Check status code
789  if(!error)
790  {
791  //The signature is preceded by a 2-byte length field
792  signature->length = htons(n);
793  //Total length of the digitally-signed element
794  *length = sizeof(Tls12DigitalSignature) + n;
795  }
796 
797  //Return status code
798  return error;
799 }
800 
801 
802 /**
803  * @brief Digital signature verification (TLS 1.2)
804  * @param[in] context Pointer to the TLS context
805  * @param[in] p Pointer to the digitally-signed element to be verified
806  * @param[in] length Length of the digitally-signed element
807  * @return Error code
808  **/
809 
810 error_t tls12VerifySignature(TlsContext *context, const uint8_t *p,
811  size_t length)
812 {
813  error_t error;
815  const HashAlgo *hashAlgo;
816 
817  //Point to the digitally-signed element
819 
820  //Check the length of the digitally-signed element
821  if(length < sizeof(Tls12DigitalSignature))
822  return ERROR_DECODING_FAILED;
823  if(length != (sizeof(Tls12DigitalSignature) + ntohs(signature->length)))
824  return ERROR_DECODING_FAILED;
825 
826  //Retrieve the hash algorithm used for signing
827  if(signature->algorithm.signature == TLS_SIGN_ALGO_RSA_PSS_RSAE_SHA256 ||
828  signature->algorithm.signature == TLS_SIGN_ALGO_RSA_PSS_PSS_SHA256)
829  {
830  //The hashing is intrinsic to the signature algorithm
831  if(signature->algorithm.hash == TLS_HASH_ALGO_INTRINSIC)
832  {
834  }
835  else
836  {
837  hashAlgo = NULL;
838  }
839  }
840  else if(signature->algorithm.signature == TLS_SIGN_ALGO_RSA_PSS_RSAE_SHA384 ||
841  signature->algorithm.signature == TLS_SIGN_ALGO_RSA_PSS_PSS_SHA384)
842  {
843  //The hashing is intrinsic to the signature algorithm
844  if(signature->algorithm.hash == TLS_HASH_ALGO_INTRINSIC)
845  {
847  }
848  else
849  {
850  hashAlgo = NULL;
851  }
852  }
853  else if(signature->algorithm.signature == TLS_SIGN_ALGO_RSA_PSS_RSAE_SHA512 ||
854  signature->algorithm.signature == TLS_SIGN_ALGO_RSA_PSS_PSS_SHA512)
855  {
856  //The hashing is intrinsic to the signature algorithm
857  if(signature->algorithm.hash == TLS_HASH_ALGO_INTRINSIC)
858  {
860  }
861  else
862  {
863  hashAlgo = NULL;
864  }
865  }
866  else
867  {
868  //This field indicates the hash algorithm that is used
869  hashAlgo = tlsGetHashAlgo(signature->algorithm.hash);
870  }
871 
872  //Digest all the handshake messages starting at ClientHello
873  if(hashAlgo == SHA1_HASH_ALGO)
874  {
875  //Use SHA-1 hash algorithm
876  error = tlsFinalizeTranscriptHash(context, SHA1_HASH_ALGO,
877  context->transcriptSha1Context, "", context->clientVerifyData);
878  }
879  else if(hashAlgo == context->cipherSuite.prfHashAlgo)
880  {
881  //Use PRF hash algorithm (SHA-256 or SHA-384)
882  error = tlsFinalizeTranscriptHash(context, hashAlgo,
883  context->transcriptHashContext, "", context->clientVerifyData);
884  }
885  else
886  {
887  //The specified hash algorithm is not supported
888  error = ERROR_INVALID_SIGNATURE;
889  }
890 
891  //Check status code
892  if(!error)
893  {
894 #if (TLS_RSA_SIGN_SUPPORT == ENABLED)
895  //RSASSA-PKCS1-v1_5 signature scheme?
896  if(signature->algorithm.signature == TLS_SIGN_ALGO_RSA &&
897  context->peerCertType == TLS_CERT_RSA_SIGN)
898  {
899  //Verify RSA signature (RSASSA-PKCS1-v1_5 signature scheme)
900  error = rsassaPkcs1v15Verify(&context->peerRsaPublicKey,
901  hashAlgo, context->clientVerifyData, signature->value,
902  ntohs(signature->length));
903  }
904  else
905 #endif
906 #if (TLS_RSA_PSS_SIGN_SUPPORT == ENABLED)
907  //RSASSA-PSS signature scheme (with public key OID rsaEncryption)?
908  if(signature->algorithm.signature == TLS_SIGN_ALGO_RSA_PSS_RSAE_SHA256 ||
909  signature->algorithm.signature == TLS_SIGN_ALGO_RSA_PSS_RSAE_SHA384 ||
910  signature->algorithm.signature == TLS_SIGN_ALGO_RSA_PSS_RSAE_SHA512)
911  {
912  //Enforce the type of the certificate provided by the peer
913  if(context->peerCertType == TLS_CERT_RSA_SIGN)
914  {
915  //Verify RSA signature (RSASSA-PSS signature scheme)
916  error = rsassaPssVerify(&context->peerRsaPublicKey, hashAlgo,
917  hashAlgo->digestSize, context->clientVerifyData,
918  signature->value, ntohs(signature->length));
919  }
920  else
921  {
922  //Invalid certificate
923  error = ERROR_INVALID_SIGNATURE;
924  }
925  }
926  else
927 #endif
928 #if (TLS_RSA_PSS_SIGN_SUPPORT == ENABLED)
929  //RSASSA-PSS signature scheme (with public key OID RSASSA-PSS)?
930  if(signature->algorithm.signature == TLS_SIGN_ALGO_RSA_PSS_PSS_SHA256 ||
931  signature->algorithm.signature == TLS_SIGN_ALGO_RSA_PSS_PSS_SHA384 ||
932  signature->algorithm.signature == TLS_SIGN_ALGO_RSA_PSS_PSS_SHA512)
933  {
934  //Enforce the type of the certificate provided by the peer
935  if(context->peerCertType == TLS_CERT_RSA_PSS_SIGN)
936  {
937  //Verify RSA signature (RSASSA-PSS signature scheme)
938  error = rsassaPssVerify(&context->peerRsaPublicKey, hashAlgo,
939  hashAlgo->digestSize, context->clientVerifyData,
940  signature->value, ntohs(signature->length));
941  }
942  else
943  {
944  //Invalid certificate
945  error = ERROR_INVALID_SIGNATURE;
946  }
947  }
948  else
949 #endif
950 #if (TLS_DSA_SIGN_SUPPORT == ENABLED)
951  //DSA signature scheme?
952  if(signature->algorithm.signature == TLS_SIGN_ALGO_DSA &&
953  context->peerCertType == TLS_CERT_DSS_SIGN)
954  {
955  //Verify DSA signature using client's public key
956  error = tlsVerifyDsaSignature(context, context->clientVerifyData,
957  hashAlgo->digestSize, signature->value, ntohs(signature->length));
958  }
959  else
960 #endif
961 #if (TLS_ECDSA_SIGN_SUPPORT == ENABLED)
962  //ECDSA signature scheme?
963  if(signature->algorithm.signature == TLS_SIGN_ALGO_ECDSA &&
964  context->peerCertType == TLS_CERT_ECDSA_SIGN)
965  {
966  //Verify ECDSA signature using client's public key
967  error = tlsVerifyEcdsaSignature(context, context->clientVerifyData,
968  hashAlgo->digestSize, signature->value, ntohs(signature->length));
969  }
970  else
971 #endif
972  //Invalid signature scheme?
973  {
974  //Report an error
975  error = ERROR_INVALID_SIGNATURE;
976  }
977  }
978 
979  //Return status code
980  return error;
981 }
982 
983 #endif
984 #if (TLS_MAX_VERSION >= TLS_VERSION_1_0 && TLS_MIN_VERSION <= TLS_VERSION_1_1)
985 
986 /**
987  * @brief Generate RSA signature (TLS 1.0 and TLS 1.1)
988  * @param[in] key Signer's RSA private key
989  * @param[in] digest Digest of the message to be signed
990  * @param[out] signature Resulting signature
991  * @param[out] signatureLen Length of the resulting signature
992  * @return Error code
993  **/
994 
996  const uint8_t *digest, uint8_t *signature, size_t *signatureLen)
997 {
998 #if (TLS_RSA_SIGN_SUPPORT == ENABLED)
999  error_t error;
1000  size_t k;
1001  size_t paddingLen;
1002  uint8_t *em;
1003  Mpi m;
1004  Mpi s;
1005 
1006  //Debug message
1007  TRACE_DEBUG("RSA signature generation...\r\n");
1008  TRACE_DEBUG(" Modulus:\r\n");
1009  TRACE_DEBUG_MPI(" ", &key->n);
1010  TRACE_DEBUG(" Public exponent:\r\n");
1011  TRACE_DEBUG_MPI(" ", &key->e);
1012  TRACE_DEBUG(" Private exponent:\r\n");
1013  TRACE_DEBUG_MPI(" ", &key->d);
1014  TRACE_DEBUG(" Prime 1:\r\n");
1015  TRACE_DEBUG_MPI(" ", &key->p);
1016  TRACE_DEBUG(" Prime 2:\r\n");
1017  TRACE_DEBUG_MPI(" ", &key->q);
1018  TRACE_DEBUG(" Prime exponent 1:\r\n");
1019  TRACE_DEBUG_MPI(" ", &key->dp);
1020  TRACE_DEBUG(" Prime exponent 2:\r\n");
1021  TRACE_DEBUG_MPI(" ", &key->dq);
1022  TRACE_DEBUG(" Coefficient:\r\n");
1023  TRACE_DEBUG_MPI(" ", &key->qinv);
1024  TRACE_DEBUG(" Message digest:\r\n");
1026 
1027  //Initialize multiple-precision integers
1028  mpiInit(&m);
1029  mpiInit(&s);
1030 
1031  //Get the length in octets of the modulus n
1032  k = mpiGetByteLength(&key->n);
1033 
1034  //Check the length of the modulus
1035  if(k < (MD5_DIGEST_SIZE + SHA1_DIGEST_SIZE + 11))
1036  return ERROR_INVALID_KEY;
1037 
1038  //Point to the buffer where the encoded message EM will be generated
1039  em = signature;
1040 
1041  //The leading 0x00 octet ensures that the encoded message,
1042  //converted to an integer, is less than the modulus
1043  em[0] = 0x00;
1044  //Block type 0x01 is used for private-key operations
1045  em[1] = 0x01;
1046 
1047  //Compute the length of the padding string PS
1048  paddingLen = k - (MD5_DIGEST_SIZE + SHA1_DIGEST_SIZE + 3);
1049  //Fill the padding string with 0xFF
1050  osMemset(em + 2, 0xFF, paddingLen);
1051  //Append a 0x00 octet to PS
1052  em[paddingLen + 2] = 0x00;
1053 
1054  //Append the digest value
1055  osMemcpy(em + paddingLen + 3, digest, MD5_DIGEST_SIZE + SHA1_DIGEST_SIZE);
1056 
1057  //Debug message
1058  TRACE_DEBUG(" Encoded message\r\n");
1059  TRACE_DEBUG_ARRAY(" ", em, k);
1060 
1061  //Start of exception handling block
1062  do
1063  {
1064  //Convert the encoded message EM to an integer message representative m
1065  error = mpiImport(&m, em, k, MPI_FORMAT_BIG_ENDIAN);
1066  //Conversion failed?
1067  if(error)
1068  break;
1069 
1070  //Apply the RSASP1 signature primitive
1071  error = rsasp1(key, &m, &s);
1072  //Any error to report?
1073  if(error)
1074  break;
1075 
1076  //Convert the signature representative s to a signature of length k octets
1077  error = mpiExport(&s, signature, k, MPI_FORMAT_BIG_ENDIAN);
1078  //Conversion failed?
1079  if(error)
1080  break;
1081 
1082  //Length of the resulting signature
1083  *signatureLen = k;
1084 
1085  //Debug message
1086  TRACE_DEBUG(" Signature:\r\n");
1087  TRACE_DEBUG_ARRAY(" ", signature, *signatureLen);
1088 
1089  //End of exception handling block
1090  } while(0);
1091 
1092  //Free previously allocated memory
1093  mpiFree(&m);
1094  mpiFree(&s);
1095 
1096  //Return status code
1097  return error;
1098 #else
1099  //RSA signature generation is not supported
1100  return ERROR_NOT_IMPLEMENTED;
1101 #endif
1102 }
1103 
1104 
1105 /**
1106  * @brief Verify RSA signature (TLS 1.0 and TLS 1.1)
1107  * @param[in] key Signer's RSA public key
1108  * @param[in] digest Digest of the message whose signature is to be verified
1109  * @param[in] signature Signature to be verified
1110  * @param[in] signatureLen Length of the signature to be verified
1111  * @return Error code
1112  **/
1113 
1115  const uint8_t *digest, const uint8_t *signature, size_t signatureLen)
1116 {
1117 #if (TLS_RSA_SIGN_SUPPORT == ENABLED)
1118  error_t error;
1119  uint_t k;
1120  uint8_t *em;
1121  Mpi s;
1122  Mpi m;
1123 
1124  //Debug message
1125  TRACE_DEBUG("RSA signature verification...\r\n");
1126  TRACE_DEBUG(" Modulus:\r\n");
1127  TRACE_DEBUG_MPI(" ", &key->n);
1128  TRACE_DEBUG(" Public exponent:\r\n");
1129  TRACE_DEBUG_MPI(" ", &key->e);
1130  TRACE_DEBUG(" Message digest:\r\n");
1132  TRACE_DEBUG(" Signature:\r\n");
1133  TRACE_DEBUG_ARRAY(" ", signature, signatureLen);
1134 
1135  //Get the length in octets of the modulus n
1136  k = mpiGetByteLength(&key->n);
1137 
1138  //Check the length of the signature
1139  if(signatureLen != k)
1140  return ERROR_INVALID_SIGNATURE;
1141 
1142  //Initialize multiple-precision integers
1143  mpiInit(&s);
1144  mpiInit(&m);
1145 
1146  //Allocate a memory buffer to hold the encoded message
1147  em = tlsAllocMem(k);
1148  //Failed to allocate memory?
1149  if(em == NULL)
1150  return ERROR_OUT_OF_MEMORY;
1151 
1152  //Start of exception handling block
1153  do
1154  {
1155  //Convert the signature to an integer signature representative s
1156  error = mpiImport(&s, signature, signatureLen, MPI_FORMAT_BIG_ENDIAN);
1157  //Conversion failed?
1158  if(error)
1159  break;
1160 
1161  //Apply the RSAVP1 verification primitive
1162  error = rsavp1(key, &s, &m);
1163  //Any error to report?
1164  if(error)
1165  break;
1166 
1167  //Convert the message representative m to an encoded message EM of
1168  //length k octets
1169  error = mpiExport(&m, em, k, MPI_FORMAT_BIG_ENDIAN);
1170  //Conversion failed?
1171  if(error)
1172  break;
1173 
1174  //Debug message
1175  TRACE_DEBUG(" Encoded message\r\n");
1176  TRACE_DEBUG_ARRAY(" ", em, k);
1177 
1178  //Verify the encoded message EM
1179  error = tlsVerifyRsaEm(digest, em, k);
1180 
1181  //End of exception handling block
1182  } while(0);
1183 
1184  //Release multiple precision integers
1185  mpiFree(&s);
1186  mpiFree(&m);
1187  //Release previously allocated memory
1188  tlsFreeMem(em);
1189 
1190  //Return status code
1191  return error;
1192 #else
1193  //RSA signature verification is not supported
1194  return ERROR_NOT_IMPLEMENTED;
1195 #endif
1196 }
1197 
1198 
1199 /**
1200  * @brief Verify RSA encoded message
1201  * @param[in] digest Digest value
1202  * @param[in] em Encoded message
1203  * @param[in] emLen Length of the encoded message
1204  * @return Error code
1205  **/
1206 
1207 error_t tlsVerifyRsaEm(const uint8_t *digest, const uint8_t *em, size_t emLen)
1208 {
1209  size_t i;
1210  size_t j;
1211  size_t n;
1212  uint8_t bad;
1213 
1214  //Check the length of the encoded message
1215  if(emLen < (MD5_DIGEST_SIZE + SHA1_DIGEST_SIZE + 11))
1216  return ERROR_INVALID_LENGTH;
1217 
1218  //Point to the first byte of the encoded message
1219  i = 0;
1220 
1221  //The first octet of EM must have hexadecimal value 0x00
1222  bad = em[i++];
1223  //The second octet of EM must have hexadecimal value 0x01
1224  bad |= em[i++] ^ 0x01;
1225 
1226  //Determine the length of the padding string PS
1227  n = emLen - MD5_DIGEST_SIZE - SHA1_DIGEST_SIZE - 3;
1228 
1229  //Each byte of PS must be set to 0xFF when the block type is 0x01
1230  for(j = 0; j < n; j++)
1231  {
1232  bad |= em[i++] ^ 0xFF;
1233  }
1234 
1235  //The padding string must be followed by a 0x00 octet
1236  bad |= em[i++];
1237 
1238  //Recover the underlying hash value, and then compare it to the newly
1239  //computed hash value
1240  for(j = 0; j < (MD5_DIGEST_SIZE + SHA1_DIGEST_SIZE); j++)
1241  {
1242  bad |= em[i++] ^ digest[j];
1243  }
1244 
1245  //Verification result
1246  return (bad != 0) ? ERROR_INVALID_SIGNATURE : NO_ERROR;
1247 }
1248 
1249 #endif
1250 
1251 
1252 /**
1253  * @brief Generate DSA signature
1254  * @param[in] context Pointer to the TLS context
1255  * @param[in] digest Digest of the message to be signed
1256  * @param[in] digestLen Length in octets of the digest
1257  * @param[out] signature Resulting signature
1258  * @param[out] signatureLen Length of the resulting signature
1259  * @return Error code
1260  **/
1261 
1262 error_t tlsGenerateDsaSignature(TlsContext *context, const uint8_t *digest,
1263  size_t digestLen, uint8_t *signature, size_t *signatureLen)
1264 {
1265 #if (TLS_DSA_SIGN_SUPPORT == ENABLED)
1266  error_t error;
1267  DsaPrivateKey privateKey;
1268  DsaSignature dsaSignature;
1269 
1270  //Initialize DSA private key
1271  dsaInitPrivateKey(&privateKey);
1272  //Initialize DSA signature
1273  dsaInitSignature(&dsaSignature);
1274 
1275  //Decode the PEM structure that holds the DSA private key
1276  error = pemImportDsaPrivateKey(context->cert->privateKey,
1277  context->cert->privateKeyLen, context->cert->password, &privateKey);
1278 
1279  //Check status code
1280  if(!error)
1281  {
1282  //Generate DSA signature
1283  error = dsaGenerateSignature(context->prngAlgo, context->prngContext,
1284  &privateKey, digest, digestLen, &dsaSignature);
1285  }
1286 
1287  //Check status code
1288  if(!error)
1289  {
1290  //Encode the resulting (R, S) integer pair using ASN.1
1291  error = dsaWriteSignature(&dsaSignature, signature, signatureLen);
1292  }
1293 
1294  //Free previously allocated resources
1295  dsaFreePrivateKey(&privateKey);
1296  dsaFreeSignature(&dsaSignature);
1297 
1298  //Return status code
1299  return error;
1300 #else
1301  //DSA signature generation is not supported
1302  return ERROR_NOT_IMPLEMENTED;
1303 #endif
1304 }
1305 
1306 
1307 /**
1308  * @brief Verify DSA signature
1309  * @param[in] context Pointer to the TLS context
1310  * @param[in] digest Digest of the message whose signature is to be verified
1311  * @param[in] digestLen Length in octets of the digest
1312  * @param[in] signature Signature to be verified
1313  * @param[in] signatureLen Length of the signature to be verified
1314  * @return Error code
1315  **/
1316 
1317 error_t tlsVerifyDsaSignature(TlsContext *context, const uint8_t *digest,
1318  size_t digestLen, const uint8_t *signature, size_t signatureLen)
1319 {
1320 #if (TLS_DSA_SIGN_SUPPORT == ENABLED)
1321  error_t error;
1322  DsaSignature dsaSignature;
1323 
1324  //Initialize DSA signature
1325  dsaInitSignature(&dsaSignature);
1326 
1327  //Read the ASN.1 encoded DSA signature
1328  error = dsaReadSignature(signature, signatureLen, &dsaSignature);
1329 
1330  //Check status code
1331  if(!error)
1332  {
1333  //DSA signature verification
1334  error = dsaVerifySignature(&context->peerDsaPublicKey,
1335  digest, digestLen, &dsaSignature);
1336  }
1337  else
1338  {
1339  //Malformed DSA signature
1340  error = ERROR_INVALID_SIGNATURE;
1341  }
1342 
1343  //Free previously allocated resources
1344  dsaFreeSignature(&dsaSignature);
1345 
1346  //Return status code
1347  return error;
1348 #else
1349  //DSA signature verification is not supported
1350  return ERROR_NOT_IMPLEMENTED;
1351 #endif
1352 }
1353 
1354 
1355 /**
1356  * @brief Generate ECDSA signature
1357  * @param[in] context Pointer to the TLS context
1358  * @param[in] digest Digest of the message to be signed
1359  * @param[in] digestLen Length in octets of the digest
1360  * @param[out] signature Resulting signature
1361  * @param[out] signatureLen Length of the resulting signature
1362  * @return Error code
1363  **/
1364 
1365 error_t tlsGenerateEcdsaSignature(TlsContext *context, const uint8_t *digest,
1366  size_t digestLen, uint8_t *signature, size_t *signatureLen)
1367 {
1368 #if (TLS_ECDSA_SIGN_SUPPORT == ENABLED)
1369  error_t error;
1370  EcdsaSignature ecdsaSignature;
1371 
1372  //Initialize ECDSA signature
1373  ecdsaInitSignature(&ecdsaSignature);
1374 
1375 #if (TLS_ECC_CALLBACK_SUPPORT == ENABLED)
1376  //Any registered callback?
1377  if(context->ecdsaSignCallback != NULL)
1378  {
1379  //Invoke user callback function
1380  error = context->ecdsaSignCallback(context, digest, digestLen,
1381  &ecdsaSignature);
1382  }
1383  else
1384 #endif
1385  {
1386  EcDomainParameters params;
1387  EcPrivateKey privateKey;
1388 
1389  //Initialize EC domain parameters
1390  ecInitDomainParameters(&params);
1391  //Initialize EC private key
1392  ecInitPrivateKey(&privateKey);
1393 
1394  //Decode the PEM structure that holds the EC domain parameters
1395  error = pemImportEcParameters(context->cert->privateKey,
1396  context->cert->privateKeyLen, &params);
1397 
1398  //Check status code
1399  if(!error)
1400  {
1401  //Decode the PEM structure that holds the EC private key
1402  error = pemImportEcPrivateKey(context->cert->privateKey,
1403  context->cert->privateKeyLen, context->cert->password, &privateKey);
1404  }
1405 
1406  //Check status code
1407  if(!error)
1408  {
1409  //Generate ECDSA signature
1410  error = ecdsaGenerateSignature(context->prngAlgo, context->prngContext,
1411  &params, &privateKey, digest, digestLen, &ecdsaSignature);
1412  }
1413 
1414  //Release previously allocated resources
1415  ecFreeDomainParameters(&params);
1416  ecFreePrivateKey(&privateKey);
1417  }
1418 
1419  //Check status code
1420  if(!error)
1421  {
1422  //Encode the resulting (R, S) integer pair using ASN.1
1423  error = ecdsaWriteSignature(&ecdsaSignature, signature, signatureLen);
1424  }
1425 
1426  //Release previously allocated resources
1427  ecdsaFreeSignature(&ecdsaSignature);
1428 
1429  //Return status code
1430  return error;
1431 #else
1432  //ECDSA signature generation is not supported
1433  return ERROR_NOT_IMPLEMENTED;
1434 #endif
1435 }
1436 
1437 
1438 /**
1439  * @brief Verify ECDSA signature
1440  * @param[in] context Pointer to the TLS context
1441  * @param[in] digest Digest of the message whose signature is to be verified
1442  * @param[in] digestLen Length in octets of the digest
1443  * @param[in] signature Signature to be verified
1444  * @param[in] signatureLen Length of the signature to be verified
1445  * @return Error code
1446  **/
1447 
1448 error_t tlsVerifyEcdsaSignature(TlsContext *context, const uint8_t *digest,
1449  size_t digestLen, const uint8_t *signature, size_t signatureLen)
1450 {
1451 #if (TLS_ECDSA_SIGN_SUPPORT == ENABLED)
1452  error_t error;
1453  EcdsaSignature ecdsaSignature;
1454 
1455  //Initialize ECDSA signature
1456  ecdsaInitSignature(&ecdsaSignature);
1457 
1458  //Read the ASN.1 encoded ECDSA signature
1459  error = ecdsaReadSignature(signature, signatureLen, &ecdsaSignature);
1460 
1461  //Check status code
1462  if(!error)
1463  {
1464 #if (TLS_ECC_CALLBACK_SUPPORT == ENABLED)
1465  //Any registered callback?
1466  if(context->ecdsaVerifyCallback != NULL)
1467  {
1468  //Invoke user callback function
1469  error = context->ecdsaVerifyCallback(context, digest, digestLen,
1470  &ecdsaSignature);
1471  }
1472  else
1473 #endif
1474  {
1475  //No callback function defined
1477  }
1478 
1479  //Check status code
1480  if(error == ERROR_UNSUPPORTED_ELLIPTIC_CURVE ||
1481  error == ERROR_UNSUPPORTED_HASH_ALGO)
1482  {
1483  //ECDSA signature verification
1484  error = ecdsaVerifySignature(&context->peerEcParams,
1485  &context->peerEcPublicKey, digest, digestLen, &ecdsaSignature);
1486  }
1487  }
1488  else
1489  {
1490  //Malformed ECDSA signature
1491  error = ERROR_INVALID_SIGNATURE;
1492  }
1493 
1494  //Free previously allocated resources
1495  ecdsaFreeSignature(&ecdsaSignature);
1496 
1497  //Return status code
1498  return error;
1499 #else
1500  //ECDSA signature verification is not supported
1501  return ERROR_NOT_IMPLEMENTED;
1502 #endif
1503 }
1504 
1505 
1506 /**
1507  * @brief Generate EdDSA signature
1508  * @param[in] context Pointer to the TLS context
1509  * @param[in] messageChunks Collection of chunks representing the message to
1510  * be signed
1511  * @param[out] signature Resulting signature
1512  * @param[out] signatureLen Length of the resulting signature
1513  * @return Error code
1514  **/
1515 
1517  const EddsaMessageChunk *messageChunks, uint8_t *signature,
1518  size_t *signatureLen)
1519 {
1520 #if (TLS_EDDSA_SIGN_SUPPORT == ENABLED)
1521  error_t error;
1522 
1523 #if (TLS_ED25519_SUPPORT == ENABLED)
1524  //Ed25519 elliptic curve?
1525  if(context->cert->type == TLS_CERT_ED25519_SIGN)
1526  {
1527  EddsaPrivateKey privateKey;
1528 
1529  //Initialize EdDSA private key
1530  eddsaInitPrivateKey(&privateKey);
1531 
1532  //Decode the PEM structure that holds the EdDSA private key
1533  error = pemImportEddsaPrivateKey(context->cert->privateKey,
1534  context->cert->privateKeyLen, context->cert->password, &privateKey);
1535 
1536  //Check the length of the EdDSA private key
1537  if(mpiGetByteLength(&privateKey.d) == ED25519_PRIVATE_KEY_LEN)
1538  {
1539  uint8_t d[ED25519_PRIVATE_KEY_LEN];
1540 
1541  //Retrieve private key
1542  error = mpiExport(&privateKey.d, d, ED25519_PRIVATE_KEY_LEN,
1544 
1545  //Check status code
1546  if(!error)
1547  {
1548  //Generate Ed25519 signature (PureEdDSA mode)
1549  error = ed25519GenerateSignatureEx(d, NULL, messageChunks, NULL,
1550  0, 0, signature);
1551  }
1552 
1553  //Length of the resulting EdDSA signature
1554  *signatureLen = ED25519_SIGNATURE_LEN;
1555  }
1556  else
1557  {
1558  //The length of the EdDSA private key is not valid
1559  error = ERROR_INVALID_KEY;
1560  }
1561 
1562  //Free previously allocated resources
1563  eddsaFreePrivateKey(&privateKey);
1564  }
1565  else
1566 #endif
1567 #if (TLS_ED448_SUPPORT == ENABLED)
1568  //Ed448 elliptic curve?
1569  if(context->cert->type == TLS_CERT_ED448_SIGN)
1570  {
1571  EddsaPrivateKey privateKey;
1572 
1573  //Initialize EdDSA private key
1574  eddsaInitPrivateKey(&privateKey);
1575 
1576  //Decode the PEM structure that holds the EdDSA private key
1577  error = pemImportEddsaPrivateKey(context->cert->privateKey,
1578  context->cert->privateKeyLen, context->cert->password, &privateKey);
1579 
1580  //Check the length of the EdDSA private key
1581  if(mpiGetByteLength(&privateKey.d) == ED448_PRIVATE_KEY_LEN)
1582  {
1583  uint8_t d[ED448_PRIVATE_KEY_LEN];
1584 
1585  //Retrieve private key
1586  error = mpiExport(&privateKey.d, d, ED448_PRIVATE_KEY_LEN,
1588 
1589  //Check status code
1590  if(!error)
1591  {
1592  //Generate Ed448 signature (PureEdDSA mode)
1593  error = ed448GenerateSignatureEx(d, NULL, messageChunks, NULL,
1594  0, 0, signature);
1595  }
1596 
1597  //Length of the resulting EdDSA signature
1598  *signatureLen = ED448_SIGNATURE_LEN;
1599  }
1600  else
1601  {
1602  //The length of the EdDSA private key is not valid
1603  error = ERROR_INVALID_KEY;
1604  }
1605 
1606  //Free previously allocated resources
1607  eddsaFreePrivateKey(&privateKey);
1608  }
1609  else
1610 #endif
1611  //Invalid signature algorithm?
1612  {
1613  //Report an error
1615  }
1616 
1617  //Return status code
1618  return error;
1619 #else
1620  //EdDSA signature generation is not supported
1621  return ERROR_NOT_IMPLEMENTED;
1622 #endif
1623 }
1624 
1625 
1626 /**
1627  * @brief Verify EdDSA signature
1628  * @param[in] context Pointer to the TLS context
1629  * @param[in] messageChunks Collection of chunks representing the message
1630  * whose signature is to be verified
1631  * @param[in] signature Signature to be verified
1632  * @param[in] signatureLen Length of the signature to be verified
1633  * @return Error code
1634  **/
1635 
1637  const EddsaMessageChunk *messageChunks, const uint8_t *signature,
1638  size_t signatureLen)
1639 {
1640 #if (TLS_EDDSA_SIGN_SUPPORT == ENABLED)
1641  error_t error;
1642 
1643 #if (TLS_ED25519_SUPPORT == ENABLED)
1644  //Ed25519 elliptic curve?
1645  if(context->peerEcParams.type == EC_CURVE_TYPE_ED25519)
1646  {
1647  //Check the length of the EdDSA signature
1648  if(signatureLen == ED25519_SIGNATURE_LEN)
1649  {
1650  uint8_t publicKey[ED25519_PUBLIC_KEY_LEN];
1651 
1652  //Get peer's public key
1653  error = mpiExport(&context->peerEcPublicKey.q.x, publicKey,
1655 
1656  //Check status code
1657  if(!error)
1658  {
1659  //Verify Ed25519 signature (PureEdDSA mode)
1660  error = ed25519VerifySignatureEx(publicKey, messageChunks, NULL,
1661  0, 0, signature);
1662  }
1663  }
1664  else
1665  {
1666  //The length of the EdDSA signature is not valid
1667  error = ERROR_INVALID_SIGNATURE;
1668  }
1669  }
1670  else
1671 #endif
1672 #if (TLS_ED448_SUPPORT == ENABLED)
1673  //Ed448 elliptic curve?
1674  if(context->peerEcParams.type == EC_CURVE_TYPE_ED448)
1675  {
1676  //Check the length of the EdDSA signature
1677  if(signatureLen == ED448_SIGNATURE_LEN)
1678  {
1679  uint8_t publicKey[ED448_PUBLIC_KEY_LEN];
1680 
1681  //Get peer's public key
1682  error = mpiExport(&context->peerEcPublicKey.q.x, publicKey,
1684 
1685  //Check status code
1686  if(!error)
1687  {
1688  //Verify Ed448 signature (PureEdDSA mode)
1689  error = ed448VerifySignatureEx(publicKey, messageChunks, NULL,
1690  0, 0, signature);
1691  }
1692  }
1693  else
1694  {
1695  //The length of the EdDSA signature is not valid
1696  error = ERROR_INVALID_SIGNATURE;
1697  }
1698  }
1699  else
1700 #endif
1701  //Invalid signature algorithm?
1702  {
1703  //Report an error
1705  }
1706 
1707  //Return status code
1708  return error;
1709 #else
1710  //EdDSA signature verification is not supported
1711  return ERROR_NOT_IMPLEMENTED;
1712 #endif
1713 }
1714 
1715 #endif
unsigned int uint_t
Definition: compiler_port.h:50
#define htons(value)
Definition: cpu_endian.h:413
#define ntohs(value)
Definition: cpu_endian.h:421
Debugging facilities.
#define TRACE_DEBUG_ARRAY(p, a, n)
Definition: debug.h:108
#define TRACE_DEBUG(...)
Definition: debug.h:107
#define TRACE_DEBUG_MPI(p, a)
Definition: debug.h:110
uint8_t n
void dsaFreePrivateKey(DsaPrivateKey *key)
Release a DSA private key.
Definition: dsa.c:150
error_t dsaReadSignature(const uint8_t *data, size_t length, DsaSignature *signature)
Read an ASN.1 encoded DSA signature.
Definition: dsa.c:349
error_t dsaVerifySignature(const DsaPublicKey *key, const uint8_t *digest, size_t digestLen, const DsaSignature *signature)
DSA signature verification.
Definition: dsa.c:585
void dsaInitSignature(DsaSignature *signature)
Initialize a DSA signature.
Definition: dsa.c:164
void dsaFreeSignature(DsaSignature *signature)
Release a DSA signature.
Definition: dsa.c:177
error_t dsaGenerateSignature(const PrngAlgo *prngAlgo, void *prngContext, const DsaPrivateKey *key, const uint8_t *digest, size_t digestLen, DsaSignature *signature)
DSA signature generation.
Definition: dsa.c:484
void dsaInitPrivateKey(DsaPrivateKey *key)
Initialize a DSA private key.
Definition: dsa.c:133
error_t dsaWriteSignature(const DsaSignature *signature, uint8_t *data, size_t *length)
Encode DSA signature using ASN.1.
Definition: dsa.c:193
DSA (Digital Signature Algorithm)
void ecFreeDomainParameters(EcDomainParameters *params)
Release EC domain parameters.
Definition: ec.c:72
void ecInitDomainParameters(EcDomainParameters *params)
Initialize EC domain parameters.
Definition: ec.c:51
void ecFreePrivateKey(EcPrivateKey *key)
Release an EdDSA private key.
Definition: ec.c:192
void ecInitPrivateKey(EcPrivateKey *key)
Initialize an EC private key.
Definition: ec.c:177
@ EC_CURVE_TYPE_ED25519
Definition: ec_curves.h:283
@ EC_CURVE_TYPE_ED448
Definition: ec_curves.h:284
error_t ecdsaWriteSignature(const EcdsaSignature *signature, uint8_t *data, size_t *length)
Encode ECDSA signature using ASN.1.
Definition: ecdsa.c:98
error_t ecdsaReadSignature(const uint8_t *data, size_t length, EcdsaSignature *signature)
Read an ASN.1 encoded ECDSA signature.
Definition: ecdsa.c:260
__weak_func error_t ecdsaVerifySignature(const EcDomainParameters *params, const EcPublicKey *publicKey, const uint8_t *digest, size_t digestLen, const EcdsaSignature *signature)
ECDSA signature verification.
Definition: ecdsa.c:507
void ecdsaFreeSignature(EcdsaSignature *signature)
Release an ECDSA signature.
Definition: ecdsa.c:82
__weak_func error_t ecdsaGenerateSignature(const PrngAlgo *prngAlgo, void *prngContext, const EcDomainParameters *params, const EcPrivateKey *privateKey, const uint8_t *digest, size_t digestLen, EcdsaSignature *signature)
ECDSA signature generation.
Definition: ecdsa.c:397
void ecdsaInitSignature(EcdsaSignature *signature)
Initialize an ECDSA signature.
Definition: ecdsa.c:69
ECDSA (Elliptic Curve Digital Signature Algorithm)
error_t ed25519GenerateSignatureEx(const uint8_t *privateKey, const uint8_t *publicKey, const EddsaMessageChunk *messageChunks, const void *context, uint8_t contextLen, uint8_t flag, uint8_t *signature)
EdDSA signature generation.
Definition: ed25519.c:271
error_t ed25519VerifySignatureEx(const uint8_t *publicKey, const EddsaMessageChunk *messageChunks, const void *context, uint8_t contextLen, uint8_t flag, const uint8_t *signature)
EdDSA signature verification.
Definition: ed25519.c:463
#define ED25519_PUBLIC_KEY_LEN
Definition: ed25519.h:42
#define ED25519_SIGNATURE_LEN
Definition: ed25519.h:44
#define ED25519_PRIVATE_KEY_LEN
Definition: ed25519.h:40
error_t ed448VerifySignatureEx(const uint8_t *publicKey, const EddsaMessageChunk *messageChunks, const void *context, uint8_t contextLen, uint8_t flag, const uint8_t *signature)
EdDSA signature verification.
Definition: ed448.c:438
error_t ed448GenerateSignatureEx(const uint8_t *privateKey, const uint8_t *publicKey, const EddsaMessageChunk *messageChunks, const void *context, uint8_t contextLen, uint8_t flag, uint8_t *signature)
EdDSA signature generation.
Definition: ed448.c:258
#define ED448_PRIVATE_KEY_LEN
Definition: ed448.h:40
#define ED448_PUBLIC_KEY_LEN
Definition: ed448.h:42
#define ED448_SIGNATURE_LEN
Definition: ed448.h:44
void eddsaFreePrivateKey(EddsaPrivateKey *key)
Release an EdDSA private key.
Definition: eddsa.c:89
void eddsaInitPrivateKey(EddsaPrivateKey *key)
Initialize an EdDSA private key.
Definition: eddsa.c:73
EdDSA (Edwards-Curve Digital Signature Algorithm)
error_t
Error codes.
Definition: error.h:43
@ ERROR_INVALID_KEY
Definition: error.h:106
@ ERROR_UNSUPPORTED_SIGNATURE_ALGO
Definition: error.h:132
@ ERROR_UNSUPPORTED_HASH_ALGO
Definition: error.h:130
@ ERROR_INVALID_SIGNATURE
Definition: error.h:226
@ ERROR_HANDSHAKE_FAILED
Definition: error.h:232
@ ERROR_DECODING_FAILED
Definition: error.h:240
@ ERROR_UNSUPPORTED_ELLIPTIC_CURVE
Definition: error.h:133
@ ERROR_NOT_IMPLEMENTED
Definition: error.h:66
@ NO_ERROR
Success.
Definition: error.h:44
@ ERROR_OUT_OF_MEMORY
Definition: error.h:63
@ ERROR_INVALID_LENGTH
Definition: error.h:111
#define MD5_DIGEST_SIZE
Definition: md5.h:45
#define MD5_HASH_ALGO
Definition: md5.h:51
void mpiInit(Mpi *r)
Initialize a multiple precision integer.
Definition: mpi.c:48
error_t mpiImport(Mpi *r, const uint8_t *data, uint_t length, MpiFormat format)
Octet string to integer conversion.
Definition: mpi.c:624
uint_t mpiGetByteLength(const Mpi *a)
Get the actual length in bytes.
Definition: mpi.c:195
void mpiFree(Mpi *r)
Release a multiple precision integer.
Definition: mpi.c:64
error_t mpiExport(const Mpi *a, uint8_t *data, uint_t length, MpiFormat format)
Integer to octet string conversion.
Definition: mpi.c:709
@ MPI_FORMAT_BIG_ENDIAN
Definition: mpi.h:71
@ MPI_FORMAT_LITTLE_ENDIAN
Definition: mpi.h:70
uint8_t s
Definition: ndp.h:343
uint8_t p
Definition: ndp.h:298
uint8_t m
Definition: ndp.h:302
#define osMemset(p, value, length)
Definition: os_port.h:137
#define osMemcpy(dest, src, length)
Definition: os_port.h:143
error_t pemImportEcPrivateKey(const char_t *input, size_t length, const char_t *password, EcPrivateKey *privateKey)
Decode a PEM file containing an EC private key.
Definition: pem_import.c:1162
error_t pemImportEcParameters(const char_t *input, size_t length, EcDomainParameters *params)
Decode a PEM file containing EC domain parameters.
Definition: pem_import.c:880
error_t pemImportEddsaPrivateKey(const char_t *input, size_t length, const char_t *password, EddsaPrivateKey *privateKey)
Decode a PEM file containing a EdDSA private key.
Definition: pem_import.c:1449
error_t pemImportDsaPrivateKey(const char_t *input, size_t length, const char_t *password, DsaPrivateKey *privateKey)
Decode a PEM file containing a DSA private key.
Definition: pem_import.c:675
error_t pemImportRsaPrivateKey(const char_t *input, size_t length, const char_t *password, RsaPrivateKey *privateKey)
Decode a PEM file containing an RSA private key.
Definition: pem_import.c:388
PEM file import functions.
void rsaFreePrivateKey(RsaPrivateKey *key)
Release an RSA private key.
Definition: rsa.c:153
error_t rsassaPssSign(const PrngAlgo *prngAlgo, void *prngContext, const RsaPrivateKey *key, const HashAlgo *hash, size_t saltLen, const uint8_t *digest, uint8_t *signature, size_t *signatureLen)
RSASSA-PSS signature generation operation.
Definition: rsa.c:959
error_t rsassaPssVerify(const RsaPublicKey *key, const HashAlgo *hash, size_t saltLen, const uint8_t *digest, const uint8_t *signature, size_t signatureLen)
RSASSA-PSS signature verification operation.
Definition: rsa.c:1079
error_t rsasp1(const RsaPrivateKey *key, const Mpi *m, Mpi *s)
RSA signature primitive.
Definition: rsa.c:1300
error_t rsassaPkcs1v15Sign(const RsaPrivateKey *key, const HashAlgo *hash, const uint8_t *digest, uint8_t *signature, size_t *signatureLen)
RSASSA-PKCS1-v1_5 signature generation operation.
Definition: rsa.c:705
error_t rsassaPkcs1v15Verify(const RsaPublicKey *key, const HashAlgo *hash, const uint8_t *digest, const uint8_t *signature, size_t signatureLen)
RSASSA-PKCS1-v1_5 signature verification operation.
Definition: rsa.c:838
void rsaInitPrivateKey(RsaPrivateKey *key)
Initialize an RSA private key.
Definition: rsa.c:131
error_t rsavp1(const RsaPublicKey *key, const Mpi *s, Mpi *m)
RSA verification primitive.
Definition: rsa.c:1321
RSA public-key cryptography standard.
#define SHA1_HASH_ALGO
Definition: sha1.h:51
#define SHA1_DIGEST_SIZE
Definition: sha1.h:45
DSA private key.
Definition: dsa.h:72
DSA signature.
Definition: dsa.h:84
EC domain parameters.
Definition: ec.h:76
EC private key.
Definition: ec.h:104
ECDSA signature.
Definition: ecdsa.h:49
Message chunk descriptor.
Definition: eddsa.h:71
EdDSA private key.
Definition: eddsa.h:59
Mpi d
Private key.
Definition: eddsa.h:60
Common interface for hash algorithms.
Definition: crypto.h:1007
size_t digestSize
Definition: crypto.h:1013
Arbitrary precision integer.
Definition: mpi.h:80
RSA private key.
Definition: rsa.h:68
Mpi p
First factor.
Definition: rsa.h:72
Mpi dq
Second factor's CRT exponent.
Definition: rsa.h:75
Mpi e
Public exponent.
Definition: rsa.h:70
Mpi q
Second factor.
Definition: rsa.h:73
Mpi d
Private exponent.
Definition: rsa.h:71
Mpi dp
First factor's CRT exponent.
Definition: rsa.h:74
Mpi qinv
CRT coefficient.
Definition: rsa.h:76
Mpi n
Modulus.
Definition: rsa.h:69
RSA public key.
Definition: rsa.h:57
Mpi e
Public exponent.
Definition: rsa.h:59
Mpi n
Modulus.
Definition: rsa.h:58
Certificate descriptor.
Definition: tls.h:2033
TlsNamedGroup namedCurve
Named curve used to generate the EC public key.
Definition: tls.h:2042
TlsCertificateType type
End entity certificate type.
Definition: tls.h:2039
uint8_t length
Definition: tcp.h:366
TLS (Transport Layer Security)
#define tlsAllocMem(size)
Definition: tls.h:840
#define tlsFreeMem(p)
Definition: tls.h:845
Tls12DigitalSignature
Definition: tls.h:1683
TlsDigitalSignature
Definition: tls.h:1671
TlsHashAlgo
Hash algorithms.
Definition: tls.h:1184
@ TLS_HASH_ALGO_SHA384
Definition: tls.h:1190
@ TLS_HASH_ALGO_NONE
Definition: tls.h:1185
@ TLS_HASH_ALGO_SHA256
Definition: tls.h:1189
@ TLS_HASH_ALGO_SHA512
Definition: tls.h:1191
@ TLS_HASH_ALGO_INTRINSIC
Definition: tls.h:1192
@ TLS_HASH_ALGO_SHA1
Definition: tls.h:1187
TlsSignHashAlgo
Definition: tls.h:1482
@ TLS_CERT_ED448_SIGN
Definition: tls.h:1175
@ TLS_CERT_RSA_SIGN
Definition: tls.h:1161
@ TLS_CERT_DSS_SIGN
Definition: tls.h:1162
@ TLS_CERT_ED25519_SIGN
Definition: tls.h:1174
@ TLS_CERT_RSA_PSS_SIGN
Definition: tls.h:1173
@ TLS_CERT_ECDSA_SIGN
Definition: tls.h:1168
TlsSignHashAlgos
Definition: tls.h:1493
#define TLS_VERSION_1_3
Definition: tls.h:98
TlsSignatureAlgo
Signature algorithms.
Definition: tls.h:1201
@ TLS_SIGN_ALGO_RSA_PSS_PSS_SHA512
Definition: tls.h:1213
@ TLS_SIGN_ALGO_ECDSA
Definition: tls.h:1205
@ TLS_SIGN_ALGO_RSA_PSS_RSAE_SHA512
Definition: tls.h:1208
@ TLS_SIGN_ALGO_ED448
Definition: tls.h:1210
@ TLS_SIGN_ALGO_RSA
Definition: tls.h:1203
@ TLS_SIGN_ALGO_DSA
Definition: tls.h:1204
@ TLS_SIGN_ALGO_RSA_PSS_PSS_SHA256
Definition: tls.h:1211
@ TLS_SIGN_ALGO_ANONYMOUS
Definition: tls.h:1202
@ TLS_SIGN_ALGO_ED25519
Definition: tls.h:1209
@ TLS_SIGN_ALGO_RSA_PSS_RSAE_SHA256
Definition: tls.h:1206
@ TLS_SIGN_ALGO_RSA_PSS_PSS_SHA384
Definition: tls.h:1212
@ TLS_SIGN_ALGO_RSA_PSS_RSAE_SHA384
Definition: tls.h:1207
#define TlsContext
Definition: tls.h:36
@ TLS_CONNECTION_END_SERVER
Definition: tls.h:944
@ TLS_CONNECTION_END_CLIENT
Definition: tls.h:943
@ TLS_GROUP_SECP521R1
Definition: tls.h:1338
@ TLS_GROUP_SECP256R1
Definition: tls.h:1336
@ TLS_GROUP_SECP384R1
Definition: tls.h:1337
uint8_t signature
Definition: tls.h:1481
#define TLS_VERSION_1_2
Definition: tls.h:97
const HashAlgo * tlsGetHashAlgo(uint8_t hashAlgoId)
Get the hash algorithm that matches the specified identifier.
Definition: tls_misc.c:1166
TLS helper functions.
error_t tlsVerifyEddsaSignature(TlsContext *context, const EddsaMessageChunk *messageChunks, const uint8_t *signature, size_t signatureLen)
Verify EdDSA signature.
error_t tlsVerifyEcdsaSignature(TlsContext *context, const uint8_t *digest, size_t digestLen, const uint8_t *signature, size_t signatureLen)
Verify ECDSA signature.
error_t tlsGenerateDsaSignature(TlsContext *context, const uint8_t *digest, size_t digestLen, uint8_t *signature, size_t *signatureLen)
Generate DSA signature.
error_t tlsVerifyDsaSignature(TlsContext *context, const uint8_t *digest, size_t digestLen, const uint8_t *signature, size_t signatureLen)
Verify DSA signature.
error_t tlsGenerateEddsaSignature(TlsContext *context, const EddsaMessageChunk *messageChunks, uint8_t *signature, size_t *signatureLen)
Generate EdDSA signature.
error_t tls12GenerateSignature(TlsContext *context, uint8_t *p, size_t *length)
Digital signature generation(TLS 1.2)
error_t tls12VerifySignature(TlsContext *context, const uint8_t *p, size_t length)
Digital signature verification (TLS 1.2)
error_t tlsGenerateEcdsaSignature(TlsContext *context, const uint8_t *digest, size_t digestLen, uint8_t *signature, size_t *signatureLen)
Generate ECDSA signature.
error_t tlsSelectSignatureScheme(TlsContext *context, const TlsCertDesc *cert, const TlsSignHashAlgos *supportedSignAlgos)
Select the algorithm to be used when generating digital signatures.
Definition: tls_signature.c:58
RSA/DSA/ECDSA/EdDSA signature generation and verification (TLS 1.3)
error_t tlsGenerateSignature(TlsContext *context, uint8_t *p, size_t *length)
error_t tlsVerifySignature(TlsContext *context, const uint8_t *p, size_t length)
error_t tlsVerifyRsaSignature(const RsaPublicKey *key, const uint8_t *digest, const uint8_t *signature, size_t signatureLen)
error_t tlsVerifyRsaEm(const uint8_t *digest, const uint8_t *em, size_t emLen)
error_t tlsGenerateRsaSignature(const RsaPrivateKey *key, const uint8_t *digest, uint8_t *signature, size_t *signatureLen)
error_t tlsFinalizeTranscriptHash(TlsContext *context, const HashAlgo *hash, const void *hashContext, const char_t *label, uint8_t *output)
Finalize hash calculation from previous handshake messages.
Transcript hash calculation.