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