tls_sign_generate.c
Go to the documentation of this file.
1 /**
2  * @file tls_sign_generate.c
3  * @brief RSA/DSA/ECDSA/EdDSA signature generation
4  *
5  * @section License
6  *
7  * SPDX-License-Identifier: GPL-2.0-or-later
8  *
9  * Copyright (C) 2010-2024 Oryx Embedded SARL. All rights reserved.
10  *
11  * This file is part of CycloneSSL Open.
12  *
13  * This program is free software; you can redistribute it and/or
14  * modify it under the terms of the GNU General Public License
15  * as published by the Free Software Foundation; either version 2
16  * of the License, or (at your option) any later version.
17  *
18  * This program is distributed in the hope that it will be useful,
19  * but WITHOUT ANY WARRANTY; without even the implied warranty of
20  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21  * GNU General Public License for more details.
22  *
23  * You should have received a copy of the GNU General Public License
24  * along with this program; if not, write to the Free Software Foundation,
25  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
26  *
27  * @author Oryx Embedded SARL (www.oryx-embedded.com)
28  * @version 2.4.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_sign_generate.h"
37 #include "tls_sign_misc.h"
38 #include "tls_transcript_hash.h"
39 #include "tls_misc.h"
40 #include "pkix/pem_import.h"
41 #include "pkc/rsa.h"
42 #include "pkc/dsa.h"
43 #include "ecc/ecdsa.h"
44 #include "ecc/eddsa.h"
45 #include "debug.h"
46 
47 //Check TLS library configuration
48 #if (TLS_SUPPORT == ENABLED)
49 
50 
51 /**
52  * @brief Digital signature generation (TLS 1.0 or TLS 1.1)
53  * @param[in] context Pointer to the TLS context
54  * @param[out] p Buffer where to store the digitally-signed element
55  * @param[out] length Length of the digitally-signed element
56  * @return Error code
57  **/
58 
60  size_t *length)
61 {
62 #if (TLS_MAX_VERSION >= TLS_VERSION_1_0 && TLS_MIN_VERSION <= TLS_VERSION_1_1)
63  error_t error;
64  size_t n;
65  TlsDigitalSignature *signature;
66 
67  //The digitally-signed element does not convey the signature algorithm
68  //to use, and hence implementations need to inspect the certificate to
69  //find out the signature algorithm to use
70  signature = (TlsDigitalSignature *) p;
71 
72 #if (TLS_RSA_SIGN_SUPPORT == ENABLED)
73  //RSA certificate?
74  if(context->cert->type == TLS_CERT_RSA_SIGN)
75  {
76  RsaPrivateKey privateKey;
77 
78  //Initialize RSA private key
79  rsaInitPrivateKey(&privateKey);
80 
81  //Digest all the handshake messages starting at ClientHello using MD5
83  context->transcriptMd5Context, "", context->clientVerifyData);
84 
85  //Check status code
86  if(!error)
87  {
88  //Digest all the handshake messages starting at ClientHello using SHA-1
90  context->transcriptSha1Context, "",
91  context->clientVerifyData + MD5_DIGEST_SIZE);
92  }
93 
94  //Check status code
95  if(!error)
96  {
97  //Decode the PEM structure that holds the RSA private key
98  error = pemImportRsaPrivateKey(context->cert->privateKey,
99  context->cert->privateKeyLen, context->cert->password, &privateKey);
100  }
101 
102  //Check status code
103  if(!error)
104  {
105  //Generate an RSA signature using the client's private key
106  error = tlsGenerateRsaSignature(&privateKey,
107  context->clientVerifyData, signature->value, &n);
108  }
109 
110  //Release previously allocated resources
111  rsaFreePrivateKey(&privateKey);
112  }
113  else
114 #endif
115 #if (TLS_DSA_SIGN_SUPPORT == ENABLED)
116  //DSA certificate?
117  if(context->cert->type == TLS_CERT_DSS_SIGN)
118  {
119  //Digest all the handshake messages starting at ClientHello
120  error = tlsFinalizeTranscriptHash(context, SHA1_HASH_ALGO,
121  context->transcriptSha1Context, "", context->clientVerifyData);
122 
123  //Check status code
124  if(!error)
125  {
126  //Generate a DSA signature using the client's private key
127  error = tlsGenerateDsaSignature(context, context->clientVerifyData,
128  SHA1_DIGEST_SIZE, signature->value, &n);
129  }
130  }
131  else
132 #endif
133 #if (TLS_ECDSA_SIGN_SUPPORT == ENABLED)
134  //ECDSA certificate?
135  if(context->cert->type == TLS_CERT_ECDSA_SIGN)
136  {
137  //Digest all the handshake messages starting at ClientHello
138  error = tlsFinalizeTranscriptHash(context, SHA1_HASH_ALGO,
139  context->transcriptSha1Context, "", context->clientVerifyData);
140 
141  //Check status code
142  if(!error)
143  {
144  //Generate an ECDSA signature using the client's private key
145  error = tlsGenerateEcdsaSignature(context, context->clientVerifyData,
146  SHA1_DIGEST_SIZE, signature->value, &n);
147  }
148  }
149  else
150 #endif
151  //Invalid certificate?
152  {
153  //Report an error
155  }
156 
157  //Check status code
158  if(!error)
159  {
160  //The signature is preceded by a 2-byte length field
161  signature->length = htons(n);
162  //Total length of the digitally-signed element
163  *length = sizeof(TlsDigitalSignature) + n;
164  }
165 
166  //Return status code
167  return error;
168 #else
169  //Not implemented
170  return ERROR_NOT_IMPLEMENTED;
171 #endif
172 }
173 
174 
175 /**
176  * @brief Digital signature generation (TLS 1.2)
177  * @param[in] context Pointer to the TLS context
178  * @param[out] p Buffer where to store the digitally-signed element
179  * @param[out] length Length of the digitally-signed element
180  * @return Error code
181  **/
182 
184  size_t *length)
185 {
186 #if (TLS_MAX_VERSION >= TLS_VERSION_1_2 && TLS_MIN_VERSION <= TLS_VERSION_1_2)
187  error_t error;
188  size_t n;
189  Tls12DigitalSignature *signature;
190  const HashAlgo *hashAlgo;
191 
192  //Point to the digitally-signed element
193  signature = (Tls12DigitalSignature *) p;
194  //The algorithm field specifies the signature scheme
195  signature->algorithm = htons(context->signScheme);
196 
197  //Check signature scheme
198  if(TLS_SIGN_ALGO(context->signScheme) == TLS_SIGN_ALGO_RSA ||
199  TLS_SIGN_ALGO(context->signScheme) == TLS_SIGN_ALGO_DSA ||
200  TLS_SIGN_ALGO(context->signScheme) == TLS_SIGN_ALGO_ECDSA)
201  {
202  //Retrieve the hash algorithm used for signing
203  hashAlgo = tlsGetHashAlgo(TLS_HASH_ALGO(context->signScheme));
204  }
205  else if(context->signScheme == TLS_SIGN_SCHEME_RSA_PSS_RSAE_SHA256 ||
206  context->signScheme == TLS_SIGN_SCHEME_RSA_PSS_PSS_SHA256)
207  {
208  //The hashing is intrinsic to the signature algorithm
210  }
211  else if(context->signScheme == TLS_SIGN_SCHEME_RSA_PSS_RSAE_SHA384 ||
212  context->signScheme == TLS_SIGN_SCHEME_RSA_PSS_PSS_SHA384)
213  {
214  //The hashing is intrinsic to the signature algorithm
216  }
217  else if(context->signScheme == TLS_SIGN_SCHEME_RSA_PSS_RSAE_SHA512 ||
218  context->signScheme == TLS_SIGN_SCHEME_RSA_PSS_PSS_SHA512)
219  {
220  //The hashing is intrinsic to the signature algorithm
222  }
223  else
224  {
225  //Unknown signature scheme
226  hashAlgo = NULL;
227  }
228 
229  //Digest all the handshake messages starting at ClientHello
230  if(hashAlgo == SHA1_HASH_ALGO)
231  {
232  //Use SHA-1 hash algorithm
233  error = tlsFinalizeTranscriptHash(context, SHA1_HASH_ALGO,
234  context->transcriptSha1Context, "", context->clientVerifyData);
235  }
236  else if(hashAlgo == context->cipherSuite.prfHashAlgo)
237  {
238  //Use PRF hash algorithm (SHA-256 or SHA-384)
239  error = tlsFinalizeTranscriptHash(context, hashAlgo,
240  context->transcriptHashContext, "", context->clientVerifyData);
241  }
242  else
243  {
244  //The specified hash algorithm is not supported
246  }
247 
248  //Handshake message hash successfully computed?
249  if(!error)
250  {
251 #if (TLS_RSA_SIGN_SUPPORT == ENABLED)
252  //RSASSA-PKCS1-v1_5 signature scheme?
253  if(TLS_SIGN_ALGO(context->signScheme) == TLS_SIGN_ALGO_RSA)
254  {
255  //Generate RSA signature (RSASSA-PKCS1-v1_5 signature scheme)
256  error = tlsGenerateRsaPkcs1Signature(context, hashAlgo,
257  context->clientVerifyData, signature->value, &n);
258  }
259  else
260 #endif
261 #if (TLS_RSA_PSS_SIGN_SUPPORT == ENABLED)
262  //RSASSA-PSS signature scheme?
263  if(context->signScheme == TLS_SIGN_SCHEME_RSA_PSS_RSAE_SHA256 ||
264  context->signScheme == TLS_SIGN_SCHEME_RSA_PSS_RSAE_SHA384 ||
265  context->signScheme == TLS_SIGN_SCHEME_RSA_PSS_RSAE_SHA512 ||
266  context->signScheme == TLS_SIGN_SCHEME_RSA_PSS_PSS_SHA256 ||
267  context->signScheme == TLS_SIGN_SCHEME_RSA_PSS_PSS_SHA384 ||
268  context->signScheme == TLS_SIGN_SCHEME_RSA_PSS_PSS_SHA512)
269  {
270  //Generate RSA signature (RSASSA-PSS signature scheme)
271  error = tlsGenerateRsaPssSignature(context, hashAlgo,
272  context->clientVerifyData, signature->value, &n);
273  }
274  else
275 #endif
276 #if (TLS_DSA_SIGN_SUPPORT == ENABLED)
277  //DSA signature scheme?
278  if(TLS_SIGN_ALGO(context->signScheme) == TLS_SIGN_ALGO_DSA)
279  {
280  //Generate a DSA signature using the client's private key
281  error = tlsGenerateDsaSignature(context, context->clientVerifyData,
282  hashAlgo->digestSize, signature->value, &n);
283  }
284  else
285 #endif
286 #if (TLS_ECDSA_SIGN_SUPPORT == ENABLED)
287  //ECDSA signature scheme?
288  if(TLS_SIGN_ALGO(context->signScheme) == TLS_SIGN_ALGO_ECDSA)
289  {
290  //Generate an ECDSA signature using the client's private key
291  error = tlsGenerateEcdsaSignature(context, context->clientVerifyData,
292  hashAlgo->digestSize, signature->value, &n);
293  }
294  else
295 #endif
296  //Invalid signature scheme?
297  {
298  //Report an error
300  }
301  }
302 
303  //Check status code
304  if(!error)
305  {
306  //The signature is preceded by a 2-byte length field
307  signature->length = htons(n);
308  //Total length of the digitally-signed element
309  *length = sizeof(Tls12DigitalSignature) + n;
310  }
311 
312  //Return status code
313  return error;
314 #else
315  //Not implemented
316  return ERROR_NOT_IMPLEMENTED;
317 #endif
318 }
319 
320 
321 /**
322  * @brief Generate RSA signature (TLS 1.0 and TLS 1.1)
323  * @param[in] key Signer's RSA private key
324  * @param[in] digest Digest of the message to be signed
325  * @param[out] signature Resulting signature
326  * @param[out] signatureLen Length of the resulting signature
327  * @return Error code
328  **/
329 
331  const uint8_t *digest, uint8_t *signature, size_t *signatureLen)
332 {
333 #if (TLS_MAX_VERSION >= TLS_VERSION_1_0 && TLS_MIN_VERSION <= TLS_VERSION_1_1 && \
334  TLS_RSA_SIGN_SUPPORT == ENABLED)
335  error_t error;
336  size_t k;
337  size_t paddingLen;
338  uint8_t *em;
339  Mpi m;
340  Mpi s;
341 
342  //Debug message
343  TRACE_DEBUG("RSA signature generation...\r\n");
344  TRACE_DEBUG(" Modulus:\r\n");
345  TRACE_DEBUG_MPI(" ", &key->n);
346  TRACE_DEBUG(" Public exponent:\r\n");
347  TRACE_DEBUG_MPI(" ", &key->e);
348  TRACE_DEBUG(" Private exponent:\r\n");
349  TRACE_DEBUG_MPI(" ", &key->d);
350  TRACE_DEBUG(" Prime 1:\r\n");
351  TRACE_DEBUG_MPI(" ", &key->p);
352  TRACE_DEBUG(" Prime 2:\r\n");
353  TRACE_DEBUG_MPI(" ", &key->q);
354  TRACE_DEBUG(" Prime exponent 1:\r\n");
355  TRACE_DEBUG_MPI(" ", &key->dp);
356  TRACE_DEBUG(" Prime exponent 2:\r\n");
357  TRACE_DEBUG_MPI(" ", &key->dq);
358  TRACE_DEBUG(" Coefficient:\r\n");
359  TRACE_DEBUG_MPI(" ", &key->qinv);
360  TRACE_DEBUG(" Message digest:\r\n");
362 
363  //Initialize multiple-precision integers
364  mpiInit(&m);
365  mpiInit(&s);
366 
367  //Get the length in octets of the modulus n
368  k = mpiGetByteLength(&key->n);
369 
370  //Check the length of the modulus
371  if(k < (MD5_DIGEST_SIZE + SHA1_DIGEST_SIZE + 11))
372  return ERROR_INVALID_KEY;
373 
374  //Point to the buffer where the encoded message EM will be generated
375  em = signature;
376 
377  //The leading 0x00 octet ensures that the encoded message,
378  //converted to an integer, is less than the modulus
379  em[0] = 0x00;
380  //Block type 0x01 is used for private-key operations
381  em[1] = 0x01;
382 
383  //Compute the length of the padding string PS
384  paddingLen = k - (MD5_DIGEST_SIZE + SHA1_DIGEST_SIZE + 3);
385  //Fill the padding string with 0xFF
386  osMemset(em + 2, 0xFF, paddingLen);
387  //Append a 0x00 octet to PS
388  em[paddingLen + 2] = 0x00;
389 
390  //Append the digest value
391  osMemcpy(em + paddingLen + 3, digest, MD5_DIGEST_SIZE + SHA1_DIGEST_SIZE);
392 
393  //Debug message
394  TRACE_DEBUG(" Encoded message\r\n");
395  TRACE_DEBUG_ARRAY(" ", em, k);
396 
397  //Start of exception handling block
398  do
399  {
400  //Convert the encoded message EM to an integer message representative m
401  error = mpiImport(&m, em, k, MPI_FORMAT_BIG_ENDIAN);
402  //Conversion failed?
403  if(error)
404  break;
405 
406  //Apply the RSASP1 signature primitive
407  error = rsasp1(key, &m, &s);
408  //Any error to report?
409  if(error)
410  break;
411 
412  //Convert the signature representative s to a signature of length k octets
413  error = mpiExport(&s, signature, k, MPI_FORMAT_BIG_ENDIAN);
414  //Conversion failed?
415  if(error)
416  break;
417 
418  //Length of the resulting signature
419  *signatureLen = k;
420 
421  //Debug message
422  TRACE_DEBUG(" Signature:\r\n");
423  TRACE_DEBUG_ARRAY(" ", signature, *signatureLen);
424 
425  //End of exception handling block
426  } while(0);
427 
428  //Free previously allocated memory
429  mpiFree(&m);
430  mpiFree(&s);
431 
432  //Return status code
433  return error;
434 #else
435  //RSA signature algorithm is not supported
436  return ERROR_NOT_IMPLEMENTED;
437 #endif
438 }
439 
440 
441 /**
442  * @brief Generate RSA signature (TLS 1.2)
443  * @param[in] context Pointer to the TLS context
444  * @param[in] hashAlgo Hash function used to digest the message
445  * @param[in] digest Digest of the message to be signed
446  * @param[out] signature Resulting signature
447  * @param[out] signatureLen Length of the resulting signature
448  * @return Error code
449  **/
450 
452  const HashAlgo *hashAlgo, const uint8_t *digest, uint8_t *signature,
453  size_t *signatureLen)
454 {
455 #if (TLS_RSA_SIGN_SUPPORT == ENABLED)
456  error_t error;
457  RsaPrivateKey privateKey;
458 
459  //Initialize RSA private key
460  rsaInitPrivateKey(&privateKey);
461 
462  //Decode the PEM structure that holds the RSA private key
463  error = pemImportRsaPrivateKey(context->cert->privateKey,
464  context->cert->privateKeyLen, context->cert->password, &privateKey);
465 
466  //Check status code
467  if(!error)
468  {
469  //Generate RSA signature (RSASSA-PKCS1-v1_5 signature scheme)
470  error = rsassaPkcs1v15Sign(&privateKey, hashAlgo, digest, signature,
471  signatureLen);
472  }
473 
474  //Release previously allocated resources
475  rsaFreePrivateKey(&privateKey);
476 
477  //Return status code
478  return error;
479 #else
480  //RSA signature algorithm is not supported
481  return ERROR_NOT_IMPLEMENTED;
482 #endif
483 }
484 
485 
486 /**
487  * @brief Generate RSA-PSS signature
488  * @param[in] context Pointer to the TLS context
489  * @param[in] hashAlgo Hash function used to digest the message
490  * @param[in] digest Digest of the message to be signed
491  * @param[out] signature Resulting signature
492  * @param[out] signatureLen Length of the resulting signature
493  * @return Error code
494  **/
495 
497  const HashAlgo *hashAlgo, const uint8_t *digest, uint8_t *signature,
498  size_t *signatureLen)
499 {
500 #if (TLS_RSA_PSS_SIGN_SUPPORT == ENABLED)
501  error_t error;
502  RsaPrivateKey privateKey;
503 
504  //Initialize RSA private key
505  rsaInitPrivateKey(&privateKey);
506 
507  //Decode the PEM structure that holds the RSA private key
508  error = pemImportRsaPrivateKey(context->cert->privateKey,
509  context->cert->privateKeyLen, context->cert->password, &privateKey);
510 
511  //Check status code
512  if(!error)
513  {
514  //Generate RSA signature (RSASSA-PSS signature scheme)
515  error = rsassaPssSign(context->prngAlgo, context->prngContext,
516  &privateKey, hashAlgo, hashAlgo->digestSize, digest, signature,
517  signatureLen);
518  }
519 
520  //Release previously allocated resources
521  rsaFreePrivateKey(&privateKey);
522 
523  //Return status code
524  return error;
525 #else
526  //RSA signature algorithm is not supported
527  return ERROR_NOT_IMPLEMENTED;
528 #endif
529 }
530 
531 
532 /**
533  * @brief Generate DSA signature
534  * @param[in] context Pointer to the TLS context
535  * @param[in] digest Digest of the message to be signed
536  * @param[in] digestLen Length in octets of the digest
537  * @param[out] signature Resulting signature
538  * @param[out] signatureLen Length of the resulting signature
539  * @return Error code
540  **/
541 
542 error_t tlsGenerateDsaSignature(TlsContext *context, const uint8_t *digest,
543  size_t digestLen, uint8_t *signature, size_t *signatureLen)
544 {
545 #if (TLS_DSA_SIGN_SUPPORT == ENABLED)
546  error_t error;
547  DsaPrivateKey privateKey;
548  DsaSignature dsaSignature;
549 
550  //Initialize DSA private key
551  dsaInitPrivateKey(&privateKey);
552  //Initialize DSA signature
553  dsaInitSignature(&dsaSignature);
554 
555  //Decode the PEM structure that holds the DSA private key
556  error = pemImportDsaPrivateKey(context->cert->privateKey,
557  context->cert->privateKeyLen, context->cert->password, &privateKey);
558 
559  //Check status code
560  if(!error)
561  {
562  //Generate DSA signature
563  error = dsaGenerateSignature(context->prngAlgo, context->prngContext,
564  &privateKey, digest, digestLen, &dsaSignature);
565  }
566 
567  //Check status code
568  if(!error)
569  {
570  //Encode the resulting (R, S) integer pair using ASN.1
571  error = dsaWriteSignature(&dsaSignature, signature, signatureLen);
572  }
573 
574  //Free previously allocated resources
575  dsaFreePrivateKey(&privateKey);
576  dsaFreeSignature(&dsaSignature);
577 
578  //Return status code
579  return error;
580 #else
581  //DSA signature algorithm is not supported
582  return ERROR_NOT_IMPLEMENTED;
583 #endif
584 }
585 
586 
587 /**
588  * @brief Generate ECDSA signature
589  * @param[in] context Pointer to the TLS context
590  * @param[in] digest Digest of the message to be signed
591  * @param[in] digestLen Length in octets of the digest
592  * @param[out] signature Resulting signature
593  * @param[out] signatureLen Length of the resulting signature
594  * @return Error code
595  **/
596 
597 error_t tlsGenerateEcdsaSignature(TlsContext *context, const uint8_t *digest,
598  size_t digestLen, uint8_t *signature, size_t *signatureLen)
599 {
600 #if (TLS_ECDSA_SIGN_SUPPORT == ENABLED)
601  error_t error;
602  EcDomainParameters params;
603  EcPrivateKey privateKey;
604  EcdsaSignature ecdsaSignature;
605 
606  //Initialize ECDSA signature
607  ecdsaInitSignature(&ecdsaSignature);
608 
609 #if (TLS_ECC_CALLBACK_SUPPORT == ENABLED)
610  //Any registered callback?
611  if(context->ecdsaSignCallback != NULL)
612  {
613  //Invoke user callback function
614  error = context->ecdsaSignCallback(context, digest, digestLen,
615  &ecdsaSignature);
616  }
617  else
618 #endif
619  {
620  //Initialize EC domain parameters
621  ecInitDomainParameters(&params);
622  //Initialize EC private key
623  ecInitPrivateKey(&privateKey);
624 
625  //Decode the PEM structure that holds the EC domain parameters
626  error = pemImportEcParameters(context->cert->privateKey,
627  context->cert->privateKeyLen, &params);
628 
629  //Check status code
630  if(!error)
631  {
632  //Decode the PEM structure that holds the EC private key
633  error = pemImportEcPrivateKey(context->cert->privateKey,
634  context->cert->privateKeyLen, context->cert->password, &privateKey);
635  }
636 
637  //Check status code
638  if(!error)
639  {
640  //Generate ECDSA signature
641  error = ecdsaGenerateSignature(context->prngAlgo, context->prngContext,
642  &params, &privateKey, digest, digestLen, &ecdsaSignature);
643  }
644 
645  //Release previously allocated resources
646  ecFreeDomainParameters(&params);
647  ecFreePrivateKey(&privateKey);
648  }
649 
650  //Check status code
651  if(!error)
652  {
653  //Encode the resulting (R, S) integer pair using ASN.1
654  error = ecdsaWriteSignature(&ecdsaSignature, signature, signatureLen);
655  }
656 
657  //Release previously allocated resources
658  ecdsaFreeSignature(&ecdsaSignature);
659 
660  //Return status code
661  return error;
662 #else
663  //ECDSA signature algorithm is not supported
664  return ERROR_NOT_IMPLEMENTED;
665 #endif
666 }
667 
668 
669 /**
670  * @brief Generate Ed25519 signature
671  * @param[in] context Pointer to the TLS context
672  * @param[in] messageChunks Array of data chunks representing the message
673  * to be signed
674  * @param[out] signature Resulting signature
675  * @param[out] signatureLen Length of the resulting signature
676  * @return Error code
677  **/
678 
680  const DataChunk *messageChunks, uint8_t *signature,
681  size_t *signatureLen)
682 {
683 #if (TLS_ED25519_SIGN_SUPPORT == ENABLED)
684  error_t error;
685  EddsaPrivateKey privateKey;
686  uint8_t d[ED25519_PRIVATE_KEY_LEN];
687 
688  //Initialize EdDSA private key
689  eddsaInitPrivateKey(&privateKey);
690 
691  //Decode the PEM structure that holds the EdDSA private key
692  error = pemImportEddsaPrivateKey(context->cert->privateKey,
693  context->cert->privateKeyLen, context->cert->password, &privateKey);
694 
695  //Check the length of the EdDSA private key
696  if(mpiGetByteLength(&privateKey.d) == ED25519_PRIVATE_KEY_LEN)
697  {
698  //Retrieve private key
699  error = mpiExport(&privateKey.d, d, ED25519_PRIVATE_KEY_LEN,
701 
702  //Check status code
703  if(!error)
704  {
705  //Generate Ed25519 signature (PureEdDSA mode)
706  error = ed25519GenerateSignatureEx(d, NULL, messageChunks, NULL, 0, 0,
707  signature);
708  }
709 
710  //Length of the resulting EdDSA signature
711  *signatureLen = ED25519_SIGNATURE_LEN;
712  }
713  else
714  {
715  //The length of the EdDSA private key is not valid
716  error = ERROR_INVALID_KEY;
717  }
718 
719  //Free previously allocated resources
720  eddsaFreePrivateKey(&privateKey);
721 
722  //Return status code
723  return error;
724 #else
725  //EdDSA signature algorithm is not supported
726  return ERROR_NOT_IMPLEMENTED;
727 #endif
728 }
729 
730 
731 /**
732  * @brief Generate Ed448 signature
733  * @param[in] context Pointer to the TLS context
734  * @param[in] messageChunks Array of data chunks representing the message
735  * to be signed
736  * @param[out] signature Resulting signature
737  * @param[out] signatureLen Length of the resulting signature
738  * @return Error code
739  **/
740 
742  const DataChunk *messageChunks, uint8_t *signature,
743  size_t *signatureLen)
744 {
745 #if (TLS_ED448_SIGN_SUPPORT == ENABLED)
746  error_t error;
747  EddsaPrivateKey privateKey;
748  uint8_t d[ED448_PRIVATE_KEY_LEN];
749 
750  //Initialize EdDSA private key
751  eddsaInitPrivateKey(&privateKey);
752 
753  //Decode the PEM structure that holds the EdDSA private key
754  error = pemImportEddsaPrivateKey(context->cert->privateKey,
755  context->cert->privateKeyLen, context->cert->password, &privateKey);
756 
757  //Check the length of the EdDSA private key
758  if(mpiGetByteLength(&privateKey.d) == ED448_PRIVATE_KEY_LEN)
759  {
760  //Retrieve private key
761  error = mpiExport(&privateKey.d, d, ED448_PRIVATE_KEY_LEN,
763 
764  //Check status code
765  if(!error)
766  {
767  //Generate Ed448 signature (PureEdDSA mode)
768  error = ed448GenerateSignatureEx(d, NULL, messageChunks, NULL, 0, 0,
769  signature);
770  }
771 
772  //Length of the resulting EdDSA signature
773  *signatureLen = ED448_SIGNATURE_LEN;
774  }
775  else
776  {
777  //The length of the EdDSA private key is not valid
778  error = ERROR_INVALID_KEY;
779  }
780 
781  //Free previously allocated resources
782  eddsaFreePrivateKey(&privateKey);
783 
784  //Return status code
785  return error;
786 #else
787  //Ed448 signature algorithm is not supported
788  return ERROR_NOT_IMPLEMENTED;
789 #endif
790 }
791 
792 #endif
#define htons(value)
Definition: cpu_endian.h:413
ECDSA signature.
Definition: ecdsa.h:49
@ TLS_SIGN_ALGO_DSA
Definition: tls.h:1233
TLS helper functions.
#define SHA1_HASH_ALGO
Definition: sha1.h:49
const HashAlgo * tlsGetHashAlgo(TlsHashAlgo hashAlgoId)
Get the hash algorithm that matches the specified identifier.
Definition: tls_misc.c:1173
Mpi p
First factor.
Definition: rsa.h:72
TlsDigitalSignature
Definition: tls.h:1717
Arbitrary precision integer.
Definition: mpi.h:80
@ TLS_SIGN_SCHEME_RSA_PSS_RSAE_SHA256
Definition: tls.h:1253
error_t ed25519GenerateSignatureEx(const uint8_t *privateKey, const uint8_t *publicKey, const DataChunk *messageChunks, const void *context, uint8_t contextLen, uint8_t flag, uint8_t *signature)
EdDSA signature generation.
Definition: ed25519.c:271
error_t rsasp1(const RsaPrivateKey *key, const Mpi *m, Mpi *s)
RSA signature primitive.
Definition: rsa.c:1302
@ ERROR_NOT_IMPLEMENTED
Definition: error.h:66
void ecInitDomainParameters(EcDomainParameters *params)
Initialize EC domain parameters.
Definition: ec.c:51
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.
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
ECDSA (Elliptic Curve Digital Signature Algorithm)
uint8_t p
Definition: ndp.h:300
error_t tlsGenerateEd25519Signature(TlsContext *context, const DataChunk *messageChunks, uint8_t *signature, size_t *signatureLen)
Generate Ed25519 signature.
void dsaFreePrivateKey(DsaPrivateKey *key)
Release a DSA private key.
Definition: dsa.c:150
size_t digestSize
Definition: crypto.h:1052
Mpi n
Modulus.
Definition: rsa.h:69
@ TLS_SIGN_SCHEME_RSA_PSS_PSS_SHA512
Definition: tls.h:1258
#define ED448_SIGNATURE_LEN
Definition: ed448.h:44
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:676
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:389
@ TLS_CERT_DSS_SIGN
Definition: tls.h:1189
@ TLS_SIGN_SCHEME_RSA_PSS_RSAE_SHA512
Definition: tls.h:1255
#define ED25519_SIGNATURE_LEN
Definition: ed25519.h:44
error_t tlsGenerateRsaPkcs1Signature(TlsContext *context, const HashAlgo *hashAlgo, const uint8_t *digest, uint8_t *signature, size_t *signatureLen)
Generate RSA signature (TLS 1.2)
error_t mpiImport(Mpi *r, const uint8_t *data, uint_t length, MpiFormat format)
Octet string to integer conversion.
Definition: mpi.c:624
EC domain parameters.
Definition: ec.h:76
void ecFreeDomainParameters(EcDomainParameters *params)
Release EC domain parameters.
Definition: ec.c:72
void mpiInit(Mpi *r)
Initialize a multiple precision integer.
Definition: mpi.c:48
#define ED25519_PRIVATE_KEY_LEN
Definition: ed25519.h:40
#define TLS_HASH_ALGO(signScheme)
Definition: tls_sign_misc.h:41
void rsaInitPrivateKey(RsaPrivateKey *key)
Initialize an RSA private key.
Definition: rsa.c:131
Mpi d
Private exponent.
Definition: rsa.h:71
@ TLS_SIGN_SCHEME_RSA_PSS_PSS_SHA384
Definition: tls.h:1257
@ TLS_SIGN_SCHEME_RSA_PSS_RSAE_SHA384
Definition: tls.h:1254
error_t tlsGenerateEcdsaSignature(TlsContext *context, const uint8_t *digest, size_t digestLen, uint8_t *signature, size_t *signatureLen)
Generate ECDSA signature.
void ecdsaFreeSignature(EcdsaSignature *signature)
Release an ECDSA signature.
Definition: ecdsa.c:82
error_t ed448GenerateSignatureEx(const uint8_t *privateKey, const uint8_t *publicKey, const DataChunk *messageChunks, const void *context, uint8_t contextLen, uint8_t flag, uint8_t *signature)
EdDSA signature generation.
Definition: ed448.c:258
@ TLS_HASH_ALGO_SHA512
Definition: tls.h:1219
error_t mpiExport(const Mpi *a, uint8_t *data, uint_t length, MpiFormat format)
Integer to octet string conversion.
Definition: mpi.c:709
PEM file import functions.
__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
#define osMemcpy(dest, src, length)
Definition: os_port.h:141
#define TlsContext
Definition: tls.h:36
@ MPI_FORMAT_LITTLE_ENDIAN
Definition: mpi.h:70
error_t
Error codes.
Definition: error.h:43
error_t tls12GenerateSignature(TlsContext *context, uint8_t *p, size_t *length)
Digital signature generation (TLS 1.2)
void dsaInitSignature(DsaSignature *signature)
Initialize a DSA signature.
Definition: dsa.c:164
@ TLS_SIGN_SCHEME_RSA_PSS_PSS_SHA256
Definition: tls.h:1256
void rsaFreePrivateKey(RsaPrivateKey *key)
Release an RSA private key.
Definition: rsa.c:153
error_t tlsGenerateEd448Signature(TlsContext *context, const DataChunk *messageChunks, uint8_t *signature, size_t *signatureLen)
Generate Ed448 signature.
Mpi q
Second factor.
Definition: rsa.h:73
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
void ecdsaInitSignature(EcdsaSignature *signature)
Initialize an ECDSA signature.
Definition: ecdsa.c:69
#define MD5_HASH_ALGO
Definition: md5.h:49
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
Tls12DigitalSignature
Definition: tls.h:1729
@ TLS_HASH_ALGO_SHA384
Definition: tls.h:1218
EdDSA (Edwards-Curve Digital Signature Algorithm)
void dsaInitPrivateKey(DsaPrivateKey *key)
Initialize a DSA private key.
Definition: dsa.c:133
RSA public-key cryptography standard.
DSA (Digital Signature Algorithm)
EC private key.
Definition: ec.h:104
@ TLS_HASH_ALGO_SHA256
Definition: tls.h:1217
DSA private key.
Definition: dsa.h:72
@ TLS_CERT_RSA_SIGN
Definition: tls.h:1188
void ecFreePrivateKey(EcPrivateKey *key)
Release an EdDSA private key.
Definition: ec.c:192
uint8_t length
Definition: tcp.h:368
Mpi e
Public exponent.
Definition: rsa.h:70
#define MD5_DIGEST_SIZE
Definition: md5.h:45
error_t pemImportEcParameters(const char_t *input, size_t length, EcDomainParameters *params)
Decode a PEM file containing EC domain parameters.
Definition: pem_import.c:881
error_t dsaWriteSignature(const DsaSignature *signature, uint8_t *data, size_t *length)
Encode DSA signature using ASN.1.
Definition: dsa.c:193
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:1450
Mpi qinv
CRT coefficient.
Definition: rsa.h:76
EdDSA private key.
Definition: eddsa.h:59
Mpi dq
Second factor's CRT exponent.
Definition: rsa.h:75
Transcript hash calculation.
error_t tlsGenerateDsaSignature(TlsContext *context, const uint8_t *digest, size_t digestLen, uint8_t *signature, size_t *signatureLen)
Generate DSA signature.
Data chunk descriptor.
Definition: crypto.h:981
#define ED448_PRIVATE_KEY_LEN
Definition: ed448.h:40
error_t ecdsaWriteSignature(const EcdsaSignature *signature, uint8_t *data, size_t *length)
Encode ECDSA signature using ASN.1.
Definition: ecdsa.c:98
#define TRACE_DEBUG(...)
Definition: debug.h:107
#define SHA1_DIGEST_SIZE
Definition: sha1.h:45
#define TRACE_DEBUG_ARRAY(p, a, n)
Definition: debug.h:108
Mpi d
Private key.
Definition: eddsa.h:60
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:1163
uint8_t m
Definition: ndp.h:304
uint8_t n
RSA private key.
Definition: rsa.h:68
error_t tlsGenerateSignature(TlsContext *context, uint8_t *p, size_t *length)
Digital signature generation (TLS 1.0 or TLS 1.1)
void dsaFreeSignature(DsaSignature *signature)
Release a DSA signature.
Definition: dsa.c:177
error_t tlsGenerateRsaSignature(const RsaPrivateKey *key, const uint8_t *digest, uint8_t *signature, size_t *signatureLen)
Generate RSA signature (TLS 1.0 and TLS 1.1)
void ecInitPrivateKey(EcPrivateKey *key)
Initialize an EC private key.
Definition: ec.c:177
Helper functions for signature generation and verification.
@ MPI_FORMAT_BIG_ENDIAN
Definition: mpi.h:71
TLS (Transport Layer Security)
@ TLS_SIGN_ALGO_RSA
Definition: tls.h:1232
uint8_t s
Definition: igmp_common.h:234
@ TLS_CERT_ECDSA_SIGN
Definition: tls.h:1195
Common interface for hash algorithms.
Definition: crypto.h:1046
#define TLS_SIGN_ALGO(signScheme)
Definition: tls_sign_misc.h:38
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
DSA signature.
Definition: dsa.h:84
Mpi dp
First factor's CRT exponent.
Definition: rsa.h:74
@ ERROR_UNSUPPORTED_SIGNATURE_ALGO
Definition: error.h:132
#define TRACE_DEBUG_MPI(p, a)
Definition: debug.h:110
#define osMemset(p, value, length)
Definition: os_port.h:135
@ TLS_SIGN_ALGO_ECDSA
Definition: tls.h:1234
error_t tlsGenerateRsaPssSignature(TlsContext *context, const HashAlgo *hashAlgo, const uint8_t *digest, uint8_t *signature, size_t *signatureLen)
Generate RSA-PSS signature.
RSA/DSA/ECDSA/EdDSA signature generation.
@ ERROR_INVALID_KEY
Definition: error.h:106
Debugging facilities.
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