x509_sign_generate.c
Go to the documentation of this file.
1 /**
2  * @file x509_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-2026 Oryx Embedded SARL. All rights reserved.
10  *
11  * This file is part of CycloneCRYPTO Open.
12  *
13  * This program is free software; you can redistribute it and/or
14  * modify it under the terms of the GNU General Public License
15  * as published by the Free Software Foundation; either version 2
16  * of the License, or (at your option) any later version.
17  *
18  * This program is distributed in the hope that it will be useful,
19  * but WITHOUT ANY WARRANTY; without even the implied warranty of
20  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21  * GNU General Public License for more details.
22  *
23  * You should have received a copy of the GNU General Public License
24  * along with this program; if not, write to the Free Software Foundation,
25  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
26  *
27  * @author Oryx Embedded SARL (www.oryx-embedded.com)
28  * @version 2.6.4
29  **/
30 
31 //Switch to the appropriate trace level
32 #define TRACE_LEVEL CRYPTO_TRACE_LEVEL
33 
34 //Dependencies
35 #include "core/crypto.h"
37 #include "ecc/ec_misc.h"
38 #include "debug.h"
39 
40 //Check crypto library configuration
41 #if (X509_SUPPORT == ENABLED)
42 
43 //Signature generation/verification callback functions
44 #if (X509_SIGN_CALLBACK_SUPPORT == ENABLED)
45  static X509SignGenCallback x509SignGenCallback = NULL;
46 #endif
47 
48 
49 /**
50  * @brief Register signature generation callback function
51  * @param[in] callback Signature generation callback function
52  * @return Error code
53  **/
54 
56 {
57 #if (X509_SIGN_CALLBACK_SUPPORT == ENABLED)
58  //Save callback function
59  x509SignGenCallback = callback;
60  //Successful processing
61  return NO_ERROR;
62 #else
63  //Not implemented
64  return ERROR_NOT_IMPLEMENTED;
65 #endif
66 }
67 
68 
69 /**
70  * @brief Signature generation
71  * @param[in] prngAlgo PRNG algorithm
72  * @param[in] prngContext Pointer to the PRNG context
73  * @param[in] tbsData Pointer to the data to be signed
74  * @param[in] signAlgoId Signature algorithm identifier
75  * @param[in] privateKey Signer's private key
76  * @param[out] output Resulting signature
77  * @param[out] written Length of the resulting signature
78  * @return Error code
79  **/
80 
81 error_t x509GenerateSignature(const PrngAlgo *prngAlgo, void *prngContext,
82  const X509OctetString *tbsData, const X509SignAlgoId *signAlgoId,
83  const void *privateKey, uint8_t *output, size_t *written)
84 {
85  error_t error;
86  X509SignatureAlgo signAlgo;
87  const HashAlgo *hashAlgo;
88 
89 #if (X509_SIGN_CALLBACK_SUPPORT == ENABLED)
90  //Valid signature generation callback function?
91  if(x509SignGenCallback != NULL)
92  {
93  //Invoke user-defined callback
94  error = x509SignGenCallback(prngAlgo, prngContext, tbsData,
95  signAlgoId, privateKey, output, written);
96  }
97  else
98 #endif
99  {
100  //No callback function registered
102  }
103 
104  //Check status code
105  if(error == ERROR_UNSUPPORTED_SIGNATURE_ALGO ||
106  error == ERROR_UNKOWN_KEY)
107  {
108  //Retrieve the signature algorithm that will be used to sign the
109  //certificate
110  error = x509GetSignHashAlgo(signAlgoId, &signAlgo, &hashAlgo);
111 
112  //Check status code
113  if(!error)
114  {
115 #if (X509_RSA_SUPPORT == ENABLED && RSA_SUPPORT == ENABLED)
116  //RSA signature algorithm?
117  if(signAlgo == X509_SIGN_ALGO_RSA)
118  {
119  //Generate RSA signature (RSASSA-PKCS1-v1_5 signature scheme)
120  error = x509GenerateRsaSignature(tbsData, hashAlgo, privateKey,
121  output, written);
122  }
123  else
124 #endif
125 #if (X509_RSA_PSS_SUPPORT == ENABLED && RSA_SUPPORT == ENABLED)
126  //RSA-PSS signature algorithm?
127  if(signAlgo == X509_SIGN_ALGO_RSA_PSS)
128  {
129  //Generate RSA signature (RSASSA-PSS signature scheme)
130  error = x509GenerateRsaPssSignature(prngAlgo, prngContext, tbsData,
131  hashAlgo, signAlgoId->rsaPssParams.saltLen, privateKey, output,
132  written);
133  }
134  else
135 #endif
136 #if (X509_DSA_SUPPORT == ENABLED && DSA_SUPPORT == ENABLED)
137  //DSA signature algorithm?
138  if(signAlgo == X509_SIGN_ALGO_DSA)
139  {
140  //Generate DSA signature
141  error = x509GenerateDsaSignature(prngAlgo, prngContext, tbsData,
142  hashAlgo, privateKey, output, written);
143  }
144  else
145 #endif
146 #if (X509_ECDSA_SUPPORT == ENABLED && ECDSA_SUPPORT == ENABLED)
147  //ECDSA signature algorithm?
148  if(signAlgo == X509_SIGN_ALGO_ECDSA)
149  {
150  //Generate ECDSA signature
151  error = x509GenerateEcdsaSignature(prngAlgo, prngContext, tbsData,
152  hashAlgo, privateKey, output, written);
153  }
154  else
155 #endif
156 #if (X509_SM2_SUPPORT == ENABLED && SM2_SUPPORT == ENABLED)
157  //SM2 signature algorithm?
158  if(signAlgo == X509_SIGN_ALGO_SM2)
159  {
160  //Generate SM2 signature
161  error = x509GenerateSm2Signature(prngAlgo, prngContext, tbsData,
162  hashAlgo, privateKey, output, written);
163  }
164  else
165 #endif
166 #if (X509_ED25519_SUPPORT == ENABLED && ED25519_SUPPORT == ENABLED)
167  //Ed25519 signature algorithm?
168  if(signAlgo == X509_SIGN_ALGO_ED25519)
169  {
170  //Generate Ed25519 signature (PureEdDSA mode)
171  error = x509GenerateEd25519Signature(tbsData, privateKey, output,
172  written);
173  }
174  else
175 #endif
176 #if (X509_ED448_SUPPORT == ENABLED && ED448_SUPPORT == ENABLED)
177  //Ed448 signature algorithm?
178  if(signAlgo == X509_SIGN_ALGO_ED448)
179  {
180  //Generate Ed448 signature (PureEdDSA mode)
181  error = x509GenerateEd448Signature(tbsData, privateKey, output,
182  written);
183  }
184  else
185 #endif
186 #if (X509_MLDSA44_SUPPORT == ENABLED && MLDSA44_SUPPORT == ENABLED)
187  //ML-DSA-44 signature algorithm?
188  if(signAlgo == X509_SIGN_ALGO_MLDSA44)
189  {
190  //Generate ML-DSA-44 signature
191  error = x509GenerateMldsa44Signature(tbsData, privateKey, output,
192  written);
193  }
194  else
195 #endif
196 #if (X509_MLDSA65_SUPPORT == ENABLED && MLDSA65_SUPPORT == ENABLED)
197  //ML-DSA-65 signature algorithm?
198  if(signAlgo == X509_SIGN_ALGO_MLDSA65)
199  {
200  //Generate ML-DSA-65 signature
201  error = x509GenerateMldsa65Signature(tbsData, privateKey, output,
202  written);
203  }
204  else
205 #endif
206 #if (X509_MLDSA87_SUPPORT == ENABLED && MLDSA87_SUPPORT == ENABLED)
207  //ML-DSA-87 signature algorithm?
208  if(signAlgo == X509_SIGN_ALGO_MLDSA87)
209  {
210  //Generate ML-DSA-87 signature
211  error = x509GenerateMldsa87Signature(tbsData, privateKey, output,
212  written);
213  }
214  else
215 #endif
216  //Invalid signature algorithm?
217  {
218  //Report an error
220  }
221  }
222  }
223 
224  //Return status code
225  return error;
226 }
227 
228 
229 /**
230  * @brief RSA signature generation
231  * @param[in] tbsData Pointer to the data to be signed
232  * @param[in] hashAlgo Underlying hash function
233  * @param[in] privateKey Signer's private key
234  * @param[out] output Resulting signature
235  * @param[out] written Length of the resulting signature
236  * @return Error code
237  **/
238 
240  const HashAlgo *hashAlgo, const RsaPrivateKey *privateKey, uint8_t *output,
241  size_t *written)
242 {
243 #if (X509_RSA_SUPPORT == ENABLED && RSA_SUPPORT == ENABLED)
244  error_t error;
245  uint8_t digest[MAX_HASH_DIGEST_SIZE];
246 
247  //Initialize status code
248  error = NO_ERROR;
249 
250  //If the output parameter is NULL, then the function calculates the length
251  //of the resulting signature but will not generate a signature
252  if(output != NULL)
253  {
254  //Digest the TBSCertificate structure using the specified hash algorithm
255  error = hashAlgo->compute(tbsData->value, tbsData->length, digest);
256 
257  //Check status code
258  if(!error)
259  {
260  //Generate RSA signature
261  error = rsassaPkcs1v15Sign(privateKey, hashAlgo, digest, output,
262  written);
263  }
264  }
265  else
266  {
267  //Length of the resulting RSA signature
268  *written = mpiGetByteLength(&privateKey->n);
269  }
270 
271  //Return status code
272  return error;
273 #else
274  //Not implemented
275  return ERROR_NOT_IMPLEMENTED;
276 #endif
277 }
278 
279 
280 /**
281  * @brief RSA-PSS signature generation
282  * @param[in] prngAlgo PRNG algorithm
283  * @param[in] prngContext Pointer to the PRNG context
284  * @param[in] tbsData Pointer to the data to be signed
285  * @param[in] hashAlgo Underlying hash function
286  * @param[in] saltLen Length of the salt, in bytes
287  * @param[in] privateKey Signer's private key
288  * @param[out] output Resulting signature
289  * @param[out] written Length of the resulting signature
290  * @return Error code
291  **/
292 
293 error_t x509GenerateRsaPssSignature(const PrngAlgo *prngAlgo, void *prngContext,
294  const X509OctetString *tbsData, const HashAlgo *hashAlgo, size_t saltLen,
295  const RsaPrivateKey *privateKey, uint8_t *output, size_t *written)
296 {
297 #if (X509_RSA_PSS_SUPPORT == ENABLED && RSA_SUPPORT == ENABLED)
298  error_t error;
299  uint8_t digest[MAX_HASH_DIGEST_SIZE];
300 
301  //Initialize status code
302  error = NO_ERROR;
303 
304  //If the output parameter is NULL, then the function calculates the length
305  //of the resulting signature but will not generate a signature
306  if(output != NULL)
307  {
308  //Digest the TBSCertificate structure using the specified hash algorithm
309  error = hashAlgo->compute(tbsData->value, tbsData->length, digest);
310 
311  //Check status code
312  if(!error)
313  {
314  //Generate RSA-PSS signature
315  error = rsassaPssSign(prngAlgo, prngContext, privateKey, hashAlgo,
316  saltLen, digest, output, written);
317  }
318  }
319  else
320  {
321  //Length of the resulting RSA-PSS signature
322  *written = mpiGetByteLength(&privateKey->n);
323  }
324 
325  //Return status code
326  return error;
327 #else
328  //Not implemented
329  return ERROR_NOT_IMPLEMENTED;
330 #endif
331 }
332 
333 
334 /**
335  * @brief DSA signature generation
336  * @param[in] prngAlgo PRNG algorithm
337  * @param[in] prngContext Pointer to the PRNG context
338  * @param[in] tbsData Pointer to the data to be signed
339  * @param[in] hashAlgo Underlying hash function
340  * @param[in] privateKey Signer's private key
341  * @param[out] output Resulting signature
342  * @param[out] written Length of the resulting signature
343  * @return Error code
344  **/
345 
346 error_t x509GenerateDsaSignature(const PrngAlgo *prngAlgo, void *prngContext,
347  const X509OctetString *tbsData, const HashAlgo *hashAlgo,
348  const DsaPrivateKey *privateKey, uint8_t *output, size_t *written)
349 {
350 #if (X509_DSA_SUPPORT == ENABLED && DSA_SUPPORT == ENABLED)
351  error_t error;
352  DsaSignature dsaSignature;
353  uint8_t digest[MAX_HASH_DIGEST_SIZE];
354 
355  //Initialize DSA signature
356  dsaInitSignature(&dsaSignature);
357 
358  //If the output parameter is NULL, then the function calculates the length
359  //of the resulting signature but will not generate a signature
360  if(output != NULL)
361  {
362  //Digest the TBSCertificate structure using the specified hash algorithm
363  error = hashAlgo->compute(tbsData->value, tbsData->length, digest);
364 
365  //Check status code
366  if(!error)
367  {
368  //Generate DSA signature
369  error = dsaGenerateSignature(prngAlgo, prngContext, privateKey, digest,
370  hashAlgo->digestSize, &dsaSignature);
371  }
372  }
373  else
374  {
375  //Generate a dummy (R, S) integer pair
376  error = mpiSubInt(&dsaSignature.r, &privateKey->params.q, 1);
377 
378  //Check status code
379  if(!error)
380  {
381  error = mpiSubInt(&dsaSignature.s, &privateKey->params.q, 1);
382  }
383  }
384 
385  //Check status code
386  if(!error)
387  {
388  //Encode DSA signature using ASN.1
389  error = dsaExportSignature(&dsaSignature, output, written);
390  }
391 
392  //Release previously allocated resources
393  dsaFreeSignature(&dsaSignature);
394 
395  //Return status code
396  return error;
397 #else
398  //Not implemented
399  return ERROR_NOT_IMPLEMENTED;
400 #endif
401 }
402 
403 
404 /**
405  * @brief ECDSA signature generation
406  * @param[in] prngAlgo PRNG algorithm
407  * @param[in] prngContext Pointer to the PRNG context
408  * @param[in] tbsData Pointer to the data to be signed
409  * @param[in] hashAlgo Underlying hash function
410  * @param[in] privateKey Signer's private key
411  * @param[out] output Resulting signature
412  * @param[out] written Length of the resulting signature
413  * @return Error code
414  **/
415 
416 error_t x509GenerateEcdsaSignature(const PrngAlgo *prngAlgo, void *prngContext,
417  const X509OctetString *tbsData, const HashAlgo *hashAlgo,
418  const EcPrivateKey *privateKey, uint8_t *output, size_t *written)
419 {
420 #if (X509_ECDSA_SUPPORT == ENABLED && ECDSA_SUPPORT == ENABLED)
421  error_t error;
422  EcdsaSignature ecdsaSignature;
423  uint8_t digest[MAX_HASH_DIGEST_SIZE];
424 
425  //Initialize status code
426  error = NO_ERROR;
427 
428  //Initialize ECDSA signature
429  ecdsaInitSignature(&ecdsaSignature);
430 
431  //Valid elliptic curve?
432  if(privateKey->curve != NULL)
433  {
434  //If the output parameter is NULL, then the function calculates the
435  //length of the resulting signature but will not generate a signature
436  if(output != NULL)
437  {
438  //Digest the TBSCertificate structure using the specified hash
439  //algorithm
440  error = hashAlgo->compute(tbsData->value, tbsData->length, digest);
441 
442  //Check status code
443  if(!error)
444  {
445  //Generate ECDSA signature
446  error = ecdsaGenerateSignature(prngAlgo, prngContext, privateKey,
447  digest, hashAlgo->digestSize, &ecdsaSignature);
448  }
449  }
450  else
451  {
452  //Save elliptic curve parameters
453  ecdsaSignature.curve = privateKey->curve;
454 
455  //Generate a dummy (R, S) integer pair
456  ecScalarSubInt(ecdsaSignature.r, privateKey->curve->q, 1,
458 
459  ecScalarSubInt(ecdsaSignature.s, privateKey->curve->q, 1,
461  }
462 
463  //Check status code
464  if(!error)
465  {
466  //Encode ECDSA signature using ASN.1
467  error = ecdsaExportSignature(&ecdsaSignature, output, written,
469  }
470  }
471  else
472  {
473  //Invalid elliptic curve
475  }
476 
477  //Release previously allocated resources
478  ecdsaFreeSignature(&ecdsaSignature);
479 
480  //Return status code
481  return error;
482 #else
483  //Not implemented
484  return ERROR_NOT_IMPLEMENTED;
485 #endif
486 }
487 
488 
489 /**
490  * @brief SM2 signature generation
491  * @param[in] prngAlgo PRNG algorithm
492  * @param[in] prngContext Pointer to the PRNG context
493  * @param[in] tbsData Pointer to the data to be signed
494  * @param[in] hashAlgo Underlying hash function
495  * @param[in] privateKey Signer's private key
496  * @param[out] output Resulting signature
497  * @param[out] written Length of the resulting signature
498  * @return Error code
499  **/
500 
501 error_t x509GenerateSm2Signature(const PrngAlgo *prngAlgo, void *prngContext,
502  const X509OctetString *tbsData, const HashAlgo *hashAlgo,
503  const EcPrivateKey *privateKey, uint8_t *output, size_t *written)
504 {
505 #if (X509_SM2_SUPPORT == ENABLED && SM2_SUPPORT == ENABLED)
506  error_t error;
507  EcdsaSignature sm2Signature;
508 
509  //Initialize status code
510  error = NO_ERROR;
511 
512  //Initialize SM2 signature
513  ecdsaInitSignature(&sm2Signature);
514 
515  //If the output parameter is NULL, then the function calculates the length
516  //of the resulting signature but will not generate a signature
517  if(output != NULL)
518  {
519  //Generate SM2 signature
520  error = sm2GenerateSignature(prngAlgo, prngContext, privateKey, hashAlgo,
522  tbsData->length, &sm2Signature);
523  }
524  else
525  {
526  //Generate a dummy (R, S) integer pair
527  sm2Signature.curve = SM2_CURVE;
528  ecScalarSubInt(sm2Signature.r, sm2Curve.q, 1, EC_MAX_ORDER_SIZE);
529  ecScalarSubInt(sm2Signature.s, sm2Curve.q, 1, EC_MAX_ORDER_SIZE);
530  }
531 
532  //Check status code
533  if(!error)
534  {
535  //Encode SM2 signature using ASN.1
536  error = ecdsaExportSignature(&sm2Signature, output, written,
538  }
539 
540  //Release previously allocated resources
541  ecdsaFreeSignature(&sm2Signature);
542 
543  //Return status code
544  return error;
545 #else
546  //Not implemented
547  return ERROR_NOT_IMPLEMENTED;
548 #endif
549 }
550 
551 
552 /**
553  * @brief Ed25519 signature generation
554  * @param[in] tbsData Pointer to the data to be signed
555  * @param[in] privateKey Signer's private key
556  * @param[out] output Resulting signature
557  * @param[out] written Length of the resulting signature
558  * @return Error code
559  **/
560 
562  const EddsaPrivateKey *privateKey, uint8_t *output, size_t *written)
563 {
564 #if (X509_ED25519_SUPPORT == ENABLED && ED25519_SUPPORT == ENABLED)
565  error_t error;
566  const uint8_t *q;
567 
568  //Initialize status code
569  error = NO_ERROR;
570 
571  //Check elliptic curve parameters
572  if(privateKey->curve == ED25519_CURVE)
573  {
574  //If the output parameter is NULL, then the function calculates the
575  //length of the resulting signature but will not generate a signature
576  if(output != NULL)
577  {
578  //The public key is optional
579  q = (privateKey->q.curve != NULL) ? privateKey->q.q : NULL;
580 
581  //Generate Ed25519 signature (PureEdDSA mode)
582  error = ed25519GenerateSignature(privateKey->d, q, tbsData->value,
583  tbsData->length, NULL, 0, 0, output);
584  }
585 
586  //Check status code
587  if(!error)
588  {
589  //Length of the resulting EdDSA signature
590  *written = ED25519_SIGNATURE_LEN;
591  }
592  }
593  else
594  {
595  //The private key is not valid
596  error = ERROR_INVALID_KEY;
597  }
598 
599  //Return status code
600  return error;
601 #else
602  //Not implemented
603  return ERROR_NOT_IMPLEMENTED;
604 #endif
605 }
606 
607 
608 /**
609  * @brief Ed448 signature generation
610  * @param[in] tbsData Pointer to the data to be signed
611  * @param[in] privateKey Signer's private key
612  * @param[out] output Resulting signature
613  * @param[out] written Length of the resulting signature
614  * @return Error code
615  **/
616 
618  const EddsaPrivateKey *privateKey, uint8_t *output, size_t *written)
619 {
620 #if (X509_ED448_SUPPORT == ENABLED && ED448_SUPPORT == ENABLED)
621  error_t error;
622  const uint8_t *q;
623 
624  //Initialize status code
625  error = NO_ERROR;
626 
627  //Check elliptic curve parameters
628  if(privateKey->curve == ED448_CURVE)
629  {
630  //If the output parameter is NULL, then the function calculates the
631  //length of the resulting signature but will not generate a signature
632  if(output != NULL)
633  {
634  //The public key is optional
635  q = (privateKey->q.curve != NULL) ? privateKey->q.q : NULL;
636 
637  //Generate Ed448 signature (PureEdDSA mode)
638  error = ed448GenerateSignature(privateKey->d, q, tbsData->value,
639  tbsData->length, NULL, 0, 0, output);
640  }
641 
642  //Check status code
643  if(!error)
644  {
645  //Length of the resulting EdDSA signature
646  *written = ED448_SIGNATURE_LEN;
647  }
648  }
649  else
650  {
651  //The private key is not valid
652  error = ERROR_INVALID_KEY;
653  }
654 
655  //Return status code
656  return error;
657 #else
658  //Not implemented
659  return ERROR_NOT_IMPLEMENTED;
660 #endif
661 }
662 
663 
664 /**
665  * @brief ML-DSA-44 signature generation
666  * @param[in] tbsData Pointer to the data to be signed
667  * @param[in] privateKey Signer's private key
668  * @param[out] output Resulting signature
669  * @param[out] written Length of the resulting signature
670  * @return Error code
671  **/
672 
674  const MldsaPrivateKey *privateKey, uint8_t *output, size_t *written)
675 {
676 #if (X509_MLDSA44_SUPPORT == ENABLED && MLDSA44_SUPPORT == ENABLED)
677  error_t error;
678 
679  //Initialize status code
680  error = NO_ERROR;
681 
682  //Check security level
683  if(privateKey->level == MLDSA44_SECURITY_LEVEL &&
684  privateKey->skLen == MLDSA44_PRIVATE_KEY_LEN)
685  {
686  //If the output parameter is NULL, then the function calculates the
687  //length of the resulting signature but will not generate a signature
688  if(output != NULL)
689  {
690  //Generate ML-DSA-44 signature
691  error = mldsa44GenerateSignature(privateKey->sk, tbsData->value,
692  tbsData->length, NULL, 0, output);
693  }
694 
695  //Check status code
696  if(!error)
697  {
698  //Length of the resulting ML-DSA-44 signature
699  *written = MLDSA44_SIGNATURE_LEN;
700  }
701  }
702  else
703  {
704  //The private key is not valid
705  error = ERROR_INVALID_KEY;
706  }
707 
708  //Return status code
709  return error;
710 #else
711  //Not implemented
712  return ERROR_NOT_IMPLEMENTED;
713 #endif
714 }
715 
716 
717 /**
718  * @brief ML-DSA-65 signature generation
719  * @param[in] tbsData Pointer to the data to be signed
720  * @param[in] privateKey Signer's private key
721  * @param[out] output Resulting signature
722  * @param[out] written Length of the resulting signature
723  * @return Error code
724  **/
725 
727  const MldsaPrivateKey *privateKey, uint8_t *output, size_t *written)
728 {
729 #if (X509_MLDSA65_SUPPORT == ENABLED && MLDSA65_SUPPORT == ENABLED)
730  error_t error;
731 
732  //Initialize status code
733  error = NO_ERROR;
734 
735  //Check security level
736  if(privateKey->level == MLDSA65_SECURITY_LEVEL &&
737  privateKey->skLen == MLDSA65_PRIVATE_KEY_LEN)
738  {
739  //If the output parameter is NULL, then the function calculates the
740  //length of the resulting signature but will not generate a signature
741  if(output != NULL)
742  {
743  //Generate ML-DSA-65 signature
744  error = mldsa65GenerateSignature(privateKey->sk, tbsData->value,
745  tbsData->length, NULL, 0, output);
746  }
747 
748  //Check status code
749  if(!error)
750  {
751  //Length of the resulting ML-DSA-65 signature
752  *written = MLDSA65_SIGNATURE_LEN;
753  }
754  }
755  else
756  {
757  //The private key is not valid
758  error = ERROR_INVALID_KEY;
759  }
760 
761  //Return status code
762  return error;
763 #else
764  //Not implemented
765  return ERROR_NOT_IMPLEMENTED;
766 #endif
767 }
768 
769 
770 /**
771  * @brief ML-DSA-87 signature generation
772  * @param[in] tbsData Pointer to the data to be signed
773  * @param[in] privateKey Signer's private key
774  * @param[out] output Resulting signature
775  * @param[out] written Length of the resulting signature
776  * @return Error code
777  **/
778 
780  const MldsaPrivateKey *privateKey, uint8_t *output, size_t *written)
781 {
782 #if (X509_MLDSA87_SUPPORT == ENABLED && MLDSA87_SUPPORT == ENABLED)
783  error_t error;
784 
785  //Initialize status code
786  error = NO_ERROR;
787 
788  //Check security level
789  if(privateKey->level == MLDSA87_SECURITY_LEVEL &&
790  privateKey->skLen == MLDSA87_PRIVATE_KEY_LEN)
791  {
792  //If the output parameter is NULL, then the function calculates the
793  //length of the resulting signature but will not generate a signature
794  if(output != NULL)
795  {
796  //Generate ML-DSA-87 signature
797  error = mldsa87GenerateSignature(privateKey->sk, tbsData->value,
798  tbsData->length, NULL, 0, output);
799  }
800 
801  //Check status code
802  if(!error)
803  {
804  //Length of the resulting ML-DSA-87 signature
805  *written = MLDSA87_SIGNATURE_LEN;
806  }
807  }
808  else
809  {
810  //The private key is not valid
811  error = ERROR_INVALID_KEY;
812  }
813 
814  //Return status code
815  return error;
816 #else
817  //Not implemented
818  return ERROR_NOT_IMPLEMENTED;
819 #endif
820 }
821 
822 #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:495
Mpi s
Definition: dsa.h:87
ECDSA signature.
Definition: ecdsa.h:63
#define MLDSA65_SIGNATURE_LEN
Definition: mldsa.h:58
uint8_t d[EDDSA_MAX_PRIVATE_KEY_LEN]
Private key.
Definition: eddsa.h:77
@ X509_SIGN_ALGO_MLDSA65
Definition: x509_common.h:689
error_t x509GenerateMldsa87Signature(const X509OctetString *tbsData, const MldsaPrivateKey *privateKey, uint8_t *output, size_t *written)
ML-DSA-87 signature generation.
#define PrngAlgo
Definition: crypto.h:1049
@ ERROR_NOT_IMPLEMENTED
Definition: error.h:66
const EcCurve * curve
Elliptic curve parameters.
Definition: eddsa.h:76
error_t x509RegisterSignGenCallback(X509SignGenCallback callback)
Register signature generation callback function.
const EcCurve * curve
Elliptic curve parameters.
Definition: ecdsa.h:64
const EcCurve * curve
Elliptic curve parameters.
Definition: ec.h:433
Mpi q
Group order.
Definition: dsa.h:51
size_t digestSize
Definition: crypto.h:1171
#define EC_MAX_ORDER_SIZE
Definition: ec.h:315
error_t mldsa87GenerateSignature(const uint8_t *secretKey, const void *message, size_t messageLen, const void *context, uint8_t contextLen, uint8_t *signature)
ML-DSA-87 signature generation.
Definition: mldsa.c:604
Mpi n
Modulus.
Definition: rsa.h:69
error_t sm2GenerateSignature(const PrngAlgo *prngAlgo, void *prngContext, const EcPrivateKey *privateKey, const HashAlgo *hashAlgo, const char_t *id, size_t idLen, const void *message, size_t messageLen, EcdsaSignature *signature)
SM2 signature generation.
Definition: sm2.c:62
#define ED25519_CURVE
Definition: ec_curves.h:72
error_t x509GenerateMldsa65Signature(const X509OctetString *tbsData, const MldsaPrivateKey *privateKey, uint8_t *output, size_t *written)
ML-DSA-65 signature generation.
#define ED448_SIGNATURE_LEN
Definition: ed448.h:44
Mpi r
Definition: dsa.h:86
uint_t level
Security level.
Definition: mldsa.h:95
#define ED448_CURVE
Definition: ec_curves.h:73
#define MLDSA87_SECURITY_LEVEL
Definition: mldsa.h:61
#define ED25519_SIGNATURE_LEN
Definition: ed25519.h:44
#define osStrlen(s)
Definition: os_port.h:171
#define MLDSA65_SECURITY_LEVEL
Definition: mldsa.h:50
error_t x509GenerateSignature(const PrngAlgo *prngAlgo, void *prngContext, const X509OctetString *tbsData, const X509SignAlgoId *signAlgoId, const void *privateKey, uint8_t *output, size_t *written)
Signature generation.
error_t mpiSubInt(Mpi *r, const Mpi *a, mpi_sword_t b)
Subtract an integer from a multiple precision integer.
Definition: mpi.c:1020
#define MLDSA65_PRIVATE_KEY_LEN
Definition: mldsa.h:54
@ X509_SIGN_ALGO_MLDSA44
Definition: x509_common.h:688
error_t ecdsaExportSignature(const EcdsaSignature *signature, uint8_t *output, size_t *written, EcdsaSignatureFormat format)
Export an ECDSA signature.
Definition: ecdsa.c:275
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.
error_t x509GenerateEcdsaSignature(const PrngAlgo *prngAlgo, void *prngContext, const X509OctetString *tbsData, const HashAlgo *hashAlgo, const EcPrivateKey *privateKey, uint8_t *output, size_t *written)
ECDSA signature generation.
@ ERROR_INVALID_ELLIPTIC_CURVE
Definition: error.h:134
void ecdsaFreeSignature(EcdsaSignature *signature)
Release an ECDSA signature.
Definition: ecdsa.c:90
#define MAX_HASH_DIGEST_SIZE
#define MLDSA44_SECURITY_LEVEL
Definition: mldsa.h:39
X509SignatureAlgo
Signature algorithms.
Definition: x509_common.h:679
error_t x509GenerateRsaPssSignature(const PrngAlgo *prngAlgo, void *prngContext, const X509OctetString *tbsData, const HashAlgo *hashAlgo, size_t saltLen, const RsaPrivateKey *privateKey, uint8_t *output, size_t *written)
RSA-PSS signature generation.
uint8_t q[EDDSA_MAX_PUBLIC_KEY_LEN]
Public key.
Definition: eddsa.h:66
const EcCurve * curve
Elliptic curve parameters.
Definition: eddsa.h:65
error_t
Error codes.
Definition: error.h:43
void dsaInitSignature(DsaSignature *signature)
Initialize a DSA signature.
Definition: dsa.c:168
HashAlgoCompute compute
Definition: crypto.h:1174
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.
uint8_t * sk
Secret key.
Definition: mldsa.h:98
@ X509_SIGN_ALGO_ECDSA
Definition: x509_common.h:684
Helper routines for ECC.
void ecdsaInitSignature(EcdsaSignature *signature)
Initialize an ECDSA signature.
Definition: ecdsa.c:74
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:457
uint32_t ecScalarSubInt(uint32_t *r, const uint32_t *a, uint32_t b, uint_t n)
Subtraction of two integers.
Definition: ec_misc.c:736
#define MLDSA44_SIGNATURE_LEN
Definition: mldsa.h:47
uint32_t r[EC_MAX_ORDER_SIZE]
Integer R.
Definition: ecdsa.h:65
General definitions for cryptographic algorithms.
error_t x509GetSignHashAlgo(const X509SignAlgoId *signAlgoId, X509SignatureAlgo *signAlgo, const HashAlgo **hashAlgo)
Get the signature and hash algorithms that match the specified identifier.
Definition: x509_common.c:433
EC private key.
Definition: ec.h:432
DSA private key.
Definition: dsa.h:72
#define SM2_CURVE
Definition: ec_curves.h:69
@ X509_SIGN_ALGO_MLDSA87
Definition: x509_common.h:690
error_t x509GenerateSm2Signature(const PrngAlgo *prngAlgo, void *prngContext, const X509OctetString *tbsData, const HashAlgo *hashAlgo, const EcPrivateKey *privateKey, uint8_t *output, size_t *written)
SM2 signature generation.
@ X509_SIGN_ALGO_RSA
Definition: x509_common.h:681
error_t x509GenerateRsaSignature(const X509OctetString *tbsData, const HashAlgo *hashAlgo, const RsaPrivateKey *privateKey, uint8_t *output, size_t *written)
RSA signature generation.
#define MLDSA44_PRIVATE_KEY_LEN
Definition: mldsa.h:43
EdDSA private key.
Definition: eddsa.h:75
error_t x509GenerateMldsa44Signature(const X509OctetString *tbsData, const MldsaPrivateKey *privateKey, uint8_t *output, size_t *written)
ML-DSA-44 signature generation.
error_t dsaExportSignature(const DsaSignature *signature, uint8_t *output, size_t *written)
Export a DSA signature to ASN.1 format.
Definition: dsa.c:334
@ ECDSA_SIGNATURE_FORMAT_ASN1
Definition: ecdsa.h:51
RSA/DSA/ECDSA/EdDSA signature generation.
@ X509_SIGN_ALGO_RSA_PSS
Definition: x509_common.h:682
error_t x509GenerateEd25519Signature(const X509OctetString *tbsData, const EddsaPrivateKey *privateKey, uint8_t *output, size_t *written)
Ed25519 signature generation.
RSA private key.
Definition: rsa.h:68
@ ERROR_UNKOWN_KEY
Definition: error.h:295
const EcCurve sm2Curve
SM2 elliptic curve.
Definition: ec_curves.c:1794
void dsaFreeSignature(DsaSignature *signature)
Release a DSA signature.
Definition: dsa.c:181
error_t mldsa65GenerateSignature(const uint8_t *secretKey, const void *message, size_t messageLen, const void *context, uint8_t contextLen, uint8_t *signature)
ML-DSA-65 signature generation.
Definition: mldsa.c:574
uint32_t s[EC_MAX_ORDER_SIZE]
Integer S.
Definition: ecdsa.h:66
ML-DSA private key.
Definition: mldsa.h:94
error_t(* X509SignGenCallback)(const PrngAlgo *prngAlgo, void *prngContext, const X509OctetString *tbsData, const X509SignAlgoId *signAlgoId, const void *privateKey, uint8_t *output, size_t *written)
Signature generation callback function.
error_t x509GenerateDsaSignature(const PrngAlgo *prngAlgo, void *prngContext, const X509OctetString *tbsData, const HashAlgo *hashAlgo, const DsaPrivateKey *privateKey, uint8_t *output, size_t *written)
DSA signature generation.
EddsaPublicKey q
Public key.
Definition: eddsa.h:79
__weak_func error_t ed25519GenerateSignature(const uint8_t *privateKey, const uint8_t *publicKey, const void *message, size_t messageLen, const void *context, uint8_t contextLen, uint8_t flag, uint8_t *signature)
EdDSA signature generation.
Definition: ed25519.c:234
DsaDomainParameters params
DSA domain parameters.
Definition: dsa.h:73
error_t x509GenerateEd448Signature(const X509OctetString *tbsData, const EddsaPrivateKey *privateKey, uint8_t *output, size_t *written)
Ed448 signature generation.
const uint8_t * value
Definition: x509_common.h:732
Common interface for hash algorithms.
Definition: crypto.h:1165
size_t skLen
Length of the secret key, in bytes.
Definition: mldsa.h:99
DSA signature.
Definition: dsa.h:85
@ ERROR_UNSUPPORTED_SIGNATURE_ALGO
Definition: error.h:132
@ X509_SIGN_ALGO_SM2
Definition: x509_common.h:685
Octet string.
Definition: x509_common.h:731
#define SM2_DEFAULT_ID
Definition: sm2.h:40
@ X509_SIGN_ALGO_ED25519
Definition: x509_common.h:686
error_t mldsa44GenerateSignature(const uint8_t *secretKey, const void *message, size_t messageLen, const void *context, uint8_t contextLen, uint8_t *signature)
ML-DSA-44 signature generation.
Definition: mldsa.c:542
X509RsaPssParameters rsaPssParams
Definition: x509_common.h:1136
error_t ed448GenerateSignature(const uint8_t *privateKey, const uint8_t *publicKey, const void *message, size_t messageLen, const void *context, uint8_t contextLen, uint8_t flag, uint8_t *signature)
EdDSA signature generation.
Definition: ed448.c:223
Signature algorithm identifier.
Definition: x509_common.h:1133
@ ERROR_INVALID_KEY
Definition: error.h:106
@ NO_ERROR
Success.
Definition: error.h:44
Debugging facilities.
#define MLDSA87_SIGNATURE_LEN
Definition: mldsa.h:69
@ X509_SIGN_ALGO_DSA
Definition: x509_common.h:683
@ X509_SIGN_ALGO_ED448
Definition: x509_common.h:687
#define MLDSA87_PRIVATE_KEY_LEN
Definition: mldsa.h:65
uint_t mpiGetByteLength(const Mpi *a)
Get the actual length in bytes.
Definition: mpi.c:216