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.6
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 "encoding/oid.h"
38 #include "ecc/ec_misc.h"
39 #include "debug.h"
40 
41 //Check crypto library configuration
42 #if (X509_SUPPORT == ENABLED)
43 
44 //Signature generation/verification callback functions
45 #if (X509_SIGN_CALLBACK_SUPPORT == ENABLED)
46  static X509SignGenCallback x509SignGenCallback = NULL;
47 #endif
48 
49 
50 /**
51  * @brief Register signature generation callback function
52  * @param[in] callback Signature generation callback function
53  * @return Error code
54  **/
55 
57 {
58 #if (X509_SIGN_CALLBACK_SUPPORT == ENABLED)
59  //Save callback function
60  x509SignGenCallback = callback;
61  //Successful processing
62  return NO_ERROR;
63 #else
64  //Not implemented
65  return ERROR_NOT_IMPLEMENTED;
66 #endif
67 }
68 
69 
70 /**
71  * @brief Signature generation
72  * @param[in] prngAlgo PRNG algorithm
73  * @param[in] prngContext Pointer to the PRNG context
74  * @param[in] tbsData Pointer to the data to be signed
75  * @param[in] signAlgoId Signature algorithm identifier
76  * @param[in] privateKey Signer's private key
77  * @param[out] output Resulting signature
78  * @param[out] written Length of the resulting signature
79  * @return Error code
80  **/
81 
82 error_t x509GenerateSignature(const PrngAlgo *prngAlgo, void *prngContext,
83  const X509OctetString *tbsData, const X509SignAlgoId *signAlgoId,
84  const void *privateKey, uint8_t *output, size_t *written)
85 {
86  error_t error;
87  X509SignatureAlgo signAlgo;
88  const HashAlgo *hashAlgo;
89 
90 #if (X509_SIGN_CALLBACK_SUPPORT == ENABLED)
91  //Valid signature generation callback function?
92  if(x509SignGenCallback != NULL)
93  {
94  //Invoke user-defined callback
95  error = x509SignGenCallback(prngAlgo, prngContext, tbsData,
96  signAlgoId, privateKey, output, written);
97  }
98  else
99 #endif
100  {
101  //No callback function registered
103  }
104 
105  //Check status code
106  if(error == ERROR_UNSUPPORTED_SIGNATURE_ALGO ||
107  error == ERROR_UNKOWN_KEY)
108  {
109  //Retrieve the signature algorithm that will be used to sign the
110  //certificate
111  error = x509GetSignHashAlgo(signAlgoId, &signAlgo, &hashAlgo);
112 
113  //Check status code
114  if(!error)
115  {
116 #if (X509_RSA_SUPPORT == ENABLED && RSA_SUPPORT == ENABLED)
117  //RSA signature algorithm?
118  if(signAlgo == X509_SIGN_ALGO_RSA)
119  {
120  //Generate RSA signature (RSASSA-PKCS1-v1_5 signature scheme)
121  error = x509GenerateRsaSignature(tbsData, hashAlgo, privateKey,
122  output, written);
123  }
124  else
125 #endif
126 #if (X509_RSA_PSS_SUPPORT == ENABLED && RSA_SUPPORT == ENABLED)
127  //RSA-PSS signature algorithm?
128  if(signAlgo == X509_SIGN_ALGO_RSA_PSS)
129  {
130  size_t oidLen;
131  const uint8_t *oid;
132  const HashAlgo *mgfHashAlgo;
133 
134  //Get the OID of the signature algorithm
135  oid = signAlgoId->oid.value;
136  oidLen = signAlgoId->oid.length;
137 
138  //Check signature algorithm
140  {
141  //The saltLength must be 32 bytes for id-RSASSA-PSS-SHAKE128
142  //(refer to RFC 8692, section 4.1.1)
143  error = x509GenerateRsaPssSignature(prngAlgo, prngContext,
144  tbsData, hashAlgo, hashAlgo, 32, privateKey, output, written);
145  }
146  else if(OID_COMP(oid, oidLen, RSASSA_PSS_SHAKE256_OID) == 0)
147  {
148  //The saltLength must be 64 bytes for id-RSASSA-PSS-SHAKE256
149  //(refer to RFC 8692, section 4.1.1)
150  error = x509GenerateRsaPssSignature(prngAlgo, prngContext,
151  tbsData, hashAlgo, hashAlgo, 64, privateKey, output, written);
152  }
153  else
154  {
155  //Get the OID of the MGF algorithm
156  oid = signAlgoId->rsaPssParams.maskGenAlgo.value;
157  oidLen = signAlgoId->rsaPssParams.maskGenAlgo.length;
158 
159  //MGF1 mask generation function?
160  if(OID_COMP(oid, oidLen, MGF1_OID) == 0)
161  {
162  //Get the OID of the MGF hash algorithm
163  oid = signAlgoId->rsaPssParams.maskGenHashAlgo.value;
165 
166  //Select the MGF hash algorithm
167  mgfHashAlgo = x509GetHashAlgo(oid, oidLen);
168 
169  //Valid MGF hash algorithm?
170  if(mgfHashAlgo != NULL)
171  {
172  //The saltLength field of the RSASSA-PSS-params is the
173  //octet length of the salt
174  error = x509GenerateRsaPssSignature(prngAlgo, prngContext,
175  tbsData, hashAlgo, mgfHashAlgo,
176  signAlgoId->rsaPssParams.saltLen, privateKey, output,
177  written);
178  }
179  else
180  {
181  //The MGF hash algorithm is not supported
183  }
184  }
185  else
186  {
187  //The MGF algorithm is not supported
189  }
190  }
191  }
192  else
193 #endif
194 #if (X509_DSA_SUPPORT == ENABLED && DSA_SUPPORT == ENABLED)
195  //DSA signature algorithm?
196  if(signAlgo == X509_SIGN_ALGO_DSA)
197  {
198  //Generate DSA signature
199  error = x509GenerateDsaSignature(prngAlgo, prngContext, tbsData,
200  hashAlgo, privateKey, output, written);
201  }
202  else
203 #endif
204 #if (X509_ECDSA_SUPPORT == ENABLED && ECDSA_SUPPORT == ENABLED)
205  //ECDSA signature algorithm?
206  if(signAlgo == X509_SIGN_ALGO_ECDSA)
207  {
208  //Generate ECDSA signature
209  error = x509GenerateEcdsaSignature(prngAlgo, prngContext, tbsData,
210  hashAlgo, privateKey, output, written);
211  }
212  else
213 #endif
214 #if (X509_SM2_SUPPORT == ENABLED && SM2_SUPPORT == ENABLED)
215  //SM2 signature algorithm?
216  if(signAlgo == X509_SIGN_ALGO_SM2)
217  {
218  //Generate SM2 signature
219  error = x509GenerateSm2Signature(prngAlgo, prngContext, tbsData,
220  hashAlgo, privateKey, output, written);
221  }
222  else
223 #endif
224 #if (X509_ED25519_SUPPORT == ENABLED && ED25519_SUPPORT == ENABLED)
225  //Ed25519 signature algorithm?
226  if(signAlgo == X509_SIGN_ALGO_ED25519)
227  {
228  //Generate Ed25519 signature (PureEdDSA mode)
229  error = x509GenerateEd25519Signature(tbsData, privateKey, output,
230  written);
231  }
232  else
233 #endif
234 #if (X509_ED448_SUPPORT == ENABLED && ED448_SUPPORT == ENABLED)
235  //Ed448 signature algorithm?
236  if(signAlgo == X509_SIGN_ALGO_ED448)
237  {
238  //Generate Ed448 signature (PureEdDSA mode)
239  error = x509GenerateEd448Signature(tbsData, privateKey, output,
240  written);
241  }
242  else
243 #endif
244 #if (X509_MLDSA44_SUPPORT == ENABLED && MLDSA44_SUPPORT == ENABLED)
245  //ML-DSA-44 signature algorithm?
246  if(signAlgo == X509_SIGN_ALGO_MLDSA44)
247  {
248  //Generate ML-DSA-44 signature
249  error = x509GenerateMldsa44Signature(tbsData, privateKey, output,
250  written);
251  }
252  else
253 #endif
254 #if (X509_MLDSA65_SUPPORT == ENABLED && MLDSA65_SUPPORT == ENABLED)
255  //ML-DSA-65 signature algorithm?
256  if(signAlgo == X509_SIGN_ALGO_MLDSA65)
257  {
258  //Generate ML-DSA-65 signature
259  error = x509GenerateMldsa65Signature(tbsData, privateKey, output,
260  written);
261  }
262  else
263 #endif
264 #if (X509_MLDSA87_SUPPORT == ENABLED && MLDSA87_SUPPORT == ENABLED)
265  //ML-DSA-87 signature algorithm?
266  if(signAlgo == X509_SIGN_ALGO_MLDSA87)
267  {
268  //Generate ML-DSA-87 signature
269  error = x509GenerateMldsa87Signature(tbsData, privateKey, output,
270  written);
271  }
272  else
273 #endif
274  //Invalid signature algorithm?
275  {
276  //Report an error
278  }
279  }
280  }
281 
282  //Return status code
283  return error;
284 }
285 
286 
287 /**
288  * @brief RSA signature generation
289  * @param[in] tbsData Pointer to the data to be signed
290  * @param[in] hashAlgo Underlying hash function
291  * @param[in] privateKey Signer's private key
292  * @param[out] output Resulting signature
293  * @param[out] written Length of the resulting signature
294  * @return Error code
295  **/
296 
298  const HashAlgo *hashAlgo, const RsaPrivateKey *privateKey, uint8_t *output,
299  size_t *written)
300 {
301 #if (X509_RSA_SUPPORT == ENABLED && RSA_SUPPORT == ENABLED)
302  error_t error;
303  uint8_t digest[MAX_HASH_DIGEST_SIZE];
304 
305  //Initialize status code
306  error = NO_ERROR;
307 
308  //If the output parameter is NULL, then the function calculates the length
309  //of the resulting signature but will not generate a signature
310  if(output != NULL)
311  {
312  //Digest the TBSCertificate structure using the specified hash algorithm
313  error = hashAlgo->compute(tbsData->value, tbsData->length, digest);
314 
315  //Check status code
316  if(!error)
317  {
318  //Generate RSA signature
319  error = rsassaPkcs1v15Sign(privateKey, hashAlgo, digest, output,
320  written);
321  }
322  }
323  else
324  {
325  //Length of the resulting RSA signature
326  *written = mpiGetByteLength(&privateKey->n);
327  }
328 
329  //Return status code
330  return error;
331 #else
332  //Not implemented
333  return ERROR_NOT_IMPLEMENTED;
334 #endif
335 }
336 
337 
338 /**
339  * @brief RSA-PSS signature generation
340  * @param[in] prngAlgo PRNG algorithm
341  * @param[in] prngContext Pointer to the PRNG context
342  * @param[in] tbsData Pointer to the data to be signed
343  * @param[in] hashAlgo Hash function
344  * @param[in] mgfHashAlgo MGF hash function
345  * @param[in] saltLen Length of the salt, in bytes
346  * @param[in] privateKey Signer's private key
347  * @param[out] output Resulting signature
348  * @param[out] written Length of the resulting signature
349  * @return Error code
350  **/
351 
352 error_t x509GenerateRsaPssSignature(const PrngAlgo *prngAlgo, void *prngContext,
353  const X509OctetString *tbsData, const HashAlgo *hashAlgo,
354  const HashAlgo *mgfHashAlgo, size_t saltLen, const RsaPrivateKey *privateKey,
355  uint8_t *output, size_t *written)
356 {
357 #if (X509_RSA_PSS_SUPPORT == ENABLED && RSA_SUPPORT == ENABLED)
358  error_t error;
359  uint8_t digest[MAX_HASH_DIGEST_SIZE];
360 
361  //Initialize status code
362  error = NO_ERROR;
363 
364  //If the output parameter is NULL, then the function calculates the length
365  //of the resulting signature but will not generate a signature
366  if(output != NULL)
367  {
368  //Digest the TBSCertificate structure using the specified hash algorithm
369  error = hashAlgo->compute(tbsData->value, tbsData->length, digest);
370 
371  //Check status code
372  if(!error)
373  {
374  //Generate RSA-PSS signature
375  error = rsassaPssSign(prngAlgo, prngContext, privateKey, hashAlgo,
376  mgfHashAlgo, saltLen, digest, output, written);
377  }
378  }
379  else
380  {
381  //Length of the resulting RSA-PSS signature
382  *written = mpiGetByteLength(&privateKey->n);
383  }
384 
385  //Return status code
386  return error;
387 #else
388  //Not implemented
389  return ERROR_NOT_IMPLEMENTED;
390 #endif
391 }
392 
393 
394 /**
395  * @brief DSA signature generation
396  * @param[in] prngAlgo PRNG algorithm
397  * @param[in] prngContext Pointer to the PRNG context
398  * @param[in] tbsData Pointer to the data to be signed
399  * @param[in] hashAlgo Underlying hash function
400  * @param[in] privateKey Signer's private key
401  * @param[out] output Resulting signature
402  * @param[out] written Length of the resulting signature
403  * @return Error code
404  **/
405 
406 error_t x509GenerateDsaSignature(const PrngAlgo *prngAlgo, void *prngContext,
407  const X509OctetString *tbsData, const HashAlgo *hashAlgo,
408  const DsaPrivateKey *privateKey, uint8_t *output, size_t *written)
409 {
410 #if (X509_DSA_SUPPORT == ENABLED && DSA_SUPPORT == ENABLED)
411  error_t error;
412  DsaSignature dsaSignature;
413  uint8_t digest[MAX_HASH_DIGEST_SIZE];
414 
415  //Initialize DSA signature
416  dsaInitSignature(&dsaSignature);
417 
418  //If the output parameter is NULL, then the function calculates the length
419  //of the resulting signature but will not generate a signature
420  if(output != NULL)
421  {
422  //Digest the TBSCertificate structure using the specified hash algorithm
423  error = hashAlgo->compute(tbsData->value, tbsData->length, digest);
424 
425  //Check status code
426  if(!error)
427  {
428  //Generate DSA signature
429  error = dsaGenerateSignature(prngAlgo, prngContext, privateKey, digest,
430  hashAlgo->digestSize, &dsaSignature);
431  }
432  }
433  else
434  {
435  //Generate a dummy (R, S) integer pair
436  error = mpiSubInt(&dsaSignature.r, &privateKey->params.q, 1);
437 
438  //Check status code
439  if(!error)
440  {
441  error = mpiSubInt(&dsaSignature.s, &privateKey->params.q, 1);
442  }
443  }
444 
445  //Check status code
446  if(!error)
447  {
448  //Encode DSA signature using ASN.1
449  error = dsaExportSignature(&dsaSignature, output, written);
450  }
451 
452  //Release previously allocated resources
453  dsaFreeSignature(&dsaSignature);
454 
455  //Return status code
456  return error;
457 #else
458  //Not implemented
459  return ERROR_NOT_IMPLEMENTED;
460 #endif
461 }
462 
463 
464 /**
465  * @brief ECDSA signature generation
466  * @param[in] prngAlgo PRNG algorithm
467  * @param[in] prngContext Pointer to the PRNG context
468  * @param[in] tbsData Pointer to the data to be signed
469  * @param[in] hashAlgo Underlying hash function
470  * @param[in] privateKey Signer's private key
471  * @param[out] output Resulting signature
472  * @param[out] written Length of the resulting signature
473  * @return Error code
474  **/
475 
476 error_t x509GenerateEcdsaSignature(const PrngAlgo *prngAlgo, void *prngContext,
477  const X509OctetString *tbsData, const HashAlgo *hashAlgo,
478  const EcPrivateKey *privateKey, uint8_t *output, size_t *written)
479 {
480 #if (X509_ECDSA_SUPPORT == ENABLED && ECDSA_SUPPORT == ENABLED)
481  error_t error;
482  EcdsaSignature ecdsaSignature;
483  uint8_t digest[MAX_HASH_DIGEST_SIZE];
484 
485  //Initialize status code
486  error = NO_ERROR;
487 
488  //Initialize ECDSA signature
489  ecdsaInitSignature(&ecdsaSignature);
490 
491  //Valid elliptic curve?
492  if(privateKey->curve != NULL)
493  {
494  //If the output parameter is NULL, then the function calculates the
495  //length of the resulting signature but will not generate a signature
496  if(output != NULL)
497  {
498  //Digest the TBSCertificate structure using the specified hash
499  //algorithm
500  error = hashAlgo->compute(tbsData->value, tbsData->length, digest);
501 
502  //Check status code
503  if(!error)
504  {
505  //Generate ECDSA signature
506  error = ecdsaGenerateSignature(prngAlgo, prngContext, privateKey,
507  digest, hashAlgo->digestSize, &ecdsaSignature);
508  }
509  }
510  else
511  {
512  //Save elliptic curve parameters
513  ecdsaSignature.curve = privateKey->curve;
514 
515  //Generate a dummy (R, S) integer pair
516  ecScalarSubInt(ecdsaSignature.r, privateKey->curve->q, 1,
518 
519  ecScalarSubInt(ecdsaSignature.s, privateKey->curve->q, 1,
521  }
522 
523  //Check status code
524  if(!error)
525  {
526  //Encode ECDSA signature using ASN.1
527  error = ecdsaExportSignature(&ecdsaSignature, output, written,
529  }
530  }
531  else
532  {
533  //Invalid elliptic curve
535  }
536 
537  //Release previously allocated resources
538  ecdsaFreeSignature(&ecdsaSignature);
539 
540  //Return status code
541  return error;
542 #else
543  //Not implemented
544  return ERROR_NOT_IMPLEMENTED;
545 #endif
546 }
547 
548 
549 /**
550  * @brief SM2 signature generation
551  * @param[in] prngAlgo PRNG algorithm
552  * @param[in] prngContext Pointer to the PRNG context
553  * @param[in] tbsData Pointer to the data to be signed
554  * @param[in] hashAlgo Underlying hash function
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 
561 error_t x509GenerateSm2Signature(const PrngAlgo *prngAlgo, void *prngContext,
562  const X509OctetString *tbsData, const HashAlgo *hashAlgo,
563  const EcPrivateKey *privateKey, uint8_t *output, size_t *written)
564 {
565 #if (X509_SM2_SUPPORT == ENABLED && SM2_SUPPORT == ENABLED)
566  error_t error;
567  EcdsaSignature sm2Signature;
568 
569  //Initialize status code
570  error = NO_ERROR;
571 
572  //Initialize SM2 signature
573  ecdsaInitSignature(&sm2Signature);
574 
575  //If the output parameter is NULL, then the function calculates the length
576  //of the resulting signature but will not generate a signature
577  if(output != NULL)
578  {
579  //Generate SM2 signature
580  error = sm2GenerateSignature(prngAlgo, prngContext, privateKey, hashAlgo,
582  tbsData->length, &sm2Signature);
583  }
584  else
585  {
586  //Generate a dummy (R, S) integer pair
587  sm2Signature.curve = SM2_CURVE;
588  ecScalarSubInt(sm2Signature.r, sm2Curve.q, 1, EC_MAX_ORDER_SIZE);
589  ecScalarSubInt(sm2Signature.s, sm2Curve.q, 1, EC_MAX_ORDER_SIZE);
590  }
591 
592  //Check status code
593  if(!error)
594  {
595  //Encode SM2 signature using ASN.1
596  error = ecdsaExportSignature(&sm2Signature, output, written,
598  }
599 
600  //Release previously allocated resources
601  ecdsaFreeSignature(&sm2Signature);
602 
603  //Return status code
604  return error;
605 #else
606  //Not implemented
607  return ERROR_NOT_IMPLEMENTED;
608 #endif
609 }
610 
611 
612 /**
613  * @brief Ed25519 signature generation
614  * @param[in] tbsData Pointer to the data to be signed
615  * @param[in] privateKey Signer's private key
616  * @param[out] output Resulting signature
617  * @param[out] written Length of the resulting signature
618  * @return Error code
619  **/
620 
622  const EddsaPrivateKey *privateKey, uint8_t *output, size_t *written)
623 {
624 #if (X509_ED25519_SUPPORT == ENABLED && ED25519_SUPPORT == ENABLED)
625  error_t error;
626  const uint8_t *q;
627 
628  //Initialize status code
629  error = NO_ERROR;
630 
631  //Check elliptic curve parameters
632  if(privateKey->curve == ED25519_CURVE)
633  {
634  //If the output parameter is NULL, then the function calculates the
635  //length of the resulting signature but will not generate a signature
636  if(output != NULL)
637  {
638  //The public key is optional
639  q = (privateKey->q.curve != NULL) ? privateKey->q.q : NULL;
640 
641  //Generate Ed25519 signature (PureEdDSA mode)
642  error = ed25519GenerateSignature(privateKey->d, q, tbsData->value,
643  tbsData->length, NULL, 0, 0, output);
644  }
645 
646  //Check status code
647  if(!error)
648  {
649  //Length of the resulting EdDSA signature
650  *written = ED25519_SIGNATURE_LEN;
651  }
652  }
653  else
654  {
655  //The private key is not valid
656  error = ERROR_INVALID_KEY;
657  }
658 
659  //Return status code
660  return error;
661 #else
662  //Not implemented
663  return ERROR_NOT_IMPLEMENTED;
664 #endif
665 }
666 
667 
668 /**
669  * @brief Ed448 signature generation
670  * @param[in] tbsData Pointer to the data to be signed
671  * @param[in] privateKey Signer's private key
672  * @param[out] output Resulting signature
673  * @param[out] written Length of the resulting signature
674  * @return Error code
675  **/
676 
678  const EddsaPrivateKey *privateKey, uint8_t *output, size_t *written)
679 {
680 #if (X509_ED448_SUPPORT == ENABLED && ED448_SUPPORT == ENABLED)
681  error_t error;
682  const uint8_t *q;
683 
684  //Initialize status code
685  error = NO_ERROR;
686 
687  //Check elliptic curve parameters
688  if(privateKey->curve == ED448_CURVE)
689  {
690  //If the output parameter is NULL, then the function calculates the
691  //length of the resulting signature but will not generate a signature
692  if(output != NULL)
693  {
694  //The public key is optional
695  q = (privateKey->q.curve != NULL) ? privateKey->q.q : NULL;
696 
697  //Generate Ed448 signature (PureEdDSA mode)
698  error = ed448GenerateSignature(privateKey->d, q, tbsData->value,
699  tbsData->length, NULL, 0, 0, output);
700  }
701 
702  //Check status code
703  if(!error)
704  {
705  //Length of the resulting EdDSA signature
706  *written = ED448_SIGNATURE_LEN;
707  }
708  }
709  else
710  {
711  //The private key is not valid
712  error = ERROR_INVALID_KEY;
713  }
714 
715  //Return status code
716  return error;
717 #else
718  //Not implemented
719  return ERROR_NOT_IMPLEMENTED;
720 #endif
721 }
722 
723 
724 /**
725  * @brief ML-DSA-44 signature generation
726  * @param[in] tbsData Pointer to the data to be signed
727  * @param[in] privateKey Signer's private key
728  * @param[out] output Resulting signature
729  * @param[out] written Length of the resulting signature
730  * @return Error code
731  **/
732 
734  const MldsaPrivateKey *privateKey, uint8_t *output, size_t *written)
735 {
736 #if (X509_MLDSA44_SUPPORT == ENABLED && MLDSA44_SUPPORT == ENABLED)
737  error_t error;
738 
739  //Initialize status code
740  error = NO_ERROR;
741 
742  //Check security level
743  if(privateKey->level == MLDSA44_SECURITY_LEVEL &&
744  privateKey->skLen == MLDSA44_PRIVATE_KEY_LEN)
745  {
746  //If the output parameter is NULL, then the function calculates the
747  //length of the resulting signature but will not generate a signature
748  if(output != NULL)
749  {
750  //Generate ML-DSA-44 signature
751  error = mldsa44GenerateSignature(privateKey->sk, tbsData->value,
752  tbsData->length, NULL, 0, output);
753  }
754 
755  //Check status code
756  if(!error)
757  {
758  //Length of the resulting ML-DSA-44 signature
759  *written = MLDSA44_SIGNATURE_LEN;
760  }
761  }
762  else
763  {
764  //The private key is not valid
765  error = ERROR_INVALID_KEY;
766  }
767 
768  //Return status code
769  return error;
770 #else
771  //Not implemented
772  return ERROR_NOT_IMPLEMENTED;
773 #endif
774 }
775 
776 
777 /**
778  * @brief ML-DSA-65 signature generation
779  * @param[in] tbsData Pointer to the data to be signed
780  * @param[in] privateKey Signer's private key
781  * @param[out] output Resulting signature
782  * @param[out] written Length of the resulting signature
783  * @return Error code
784  **/
785 
787  const MldsaPrivateKey *privateKey, uint8_t *output, size_t *written)
788 {
789 #if (X509_MLDSA65_SUPPORT == ENABLED && MLDSA65_SUPPORT == ENABLED)
790  error_t error;
791 
792  //Initialize status code
793  error = NO_ERROR;
794 
795  //Check security level
796  if(privateKey->level == MLDSA65_SECURITY_LEVEL &&
797  privateKey->skLen == MLDSA65_PRIVATE_KEY_LEN)
798  {
799  //If the output parameter is NULL, then the function calculates the
800  //length of the resulting signature but will not generate a signature
801  if(output != NULL)
802  {
803  //Generate ML-DSA-65 signature
804  error = mldsa65GenerateSignature(privateKey->sk, tbsData->value,
805  tbsData->length, NULL, 0, output);
806  }
807 
808  //Check status code
809  if(!error)
810  {
811  //Length of the resulting ML-DSA-65 signature
812  *written = MLDSA65_SIGNATURE_LEN;
813  }
814  }
815  else
816  {
817  //The private key is not valid
818  error = ERROR_INVALID_KEY;
819  }
820 
821  //Return status code
822  return error;
823 #else
824  //Not implemented
825  return ERROR_NOT_IMPLEMENTED;
826 #endif
827 }
828 
829 
830 /**
831  * @brief ML-DSA-87 signature generation
832  * @param[in] tbsData Pointer to the data to be signed
833  * @param[in] privateKey Signer's private key
834  * @param[out] output Resulting signature
835  * @param[out] written Length of the resulting signature
836  * @return Error code
837  **/
838 
840  const MldsaPrivateKey *privateKey, uint8_t *output, size_t *written)
841 {
842 #if (X509_MLDSA87_SUPPORT == ENABLED && MLDSA87_SUPPORT == ENABLED)
843  error_t error;
844 
845  //Initialize status code
846  error = NO_ERROR;
847 
848  //Check security level
849  if(privateKey->level == MLDSA87_SECURITY_LEVEL &&
850  privateKey->skLen == MLDSA87_PRIVATE_KEY_LEN)
851  {
852  //If the output parameter is NULL, then the function calculates the
853  //length of the resulting signature but will not generate a signature
854  if(output != NULL)
855  {
856  //Generate ML-DSA-87 signature
857  error = mldsa87GenerateSignature(privateKey->sk, tbsData->value,
858  tbsData->length, NULL, 0, output);
859  }
860 
861  //Check status code
862  if(!error)
863  {
864  //Length of the resulting ML-DSA-87 signature
865  *written = MLDSA87_SIGNATURE_LEN;
866  }
867  }
868  else
869  {
870  //The private key is not valid
871  error = ERROR_INVALID_KEY;
872  }
873 
874  //Return status code
875  return error;
876 #else
877  //Not implemented
878  return ERROR_NOT_IMPLEMENTED;
879 #endif
880 }
881 
882 #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:717
error_t x509GenerateMldsa87Signature(const X509OctetString *tbsData, const MldsaPrivateKey *privateKey, uint8_t *output, size_t *written)
ML-DSA-87 signature generation.
const uint8_t RSASSA_PSS_SHAKE256_OID[8]
Definition: rsa.c:89
#define PrngAlgo
Definition: crypto.h:1140
@ ERROR_NOT_IMPLEMENTED
Definition: error.h:66
const EcCurve * curve
Elliptic curve parameters.
Definition: eddsa.h:76
OID (Object Identifier)
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:1249
#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:606
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
X509OctetString maskGenHashAlgo
Definition: x509_common.h:1153
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
uint8_t oid[]
Definition: lldp_tlv.h:300
const uint8_t MGF1_OID[9]
Definition: rsa.c:92
const HashAlgo * x509GetHashAlgo(const uint8_t *oid, size_t length)
Get the hash algorithms that match the specified identifier.
Definition: x509_common.c:971
#define MLDSA65_PRIVATE_KEY_LEN
Definition: mldsa.h:54
@ X509_SIGN_ALGO_MLDSA44
Definition: x509_common.h:716
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:707
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:1252
uint8_t * sk
Secret key.
Definition: mldsa.h:98
@ X509_SIGN_ALGO_ECDSA
Definition: x509_common.h:712
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:447
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:718
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.
X509OctetString oid
Definition: x509_common.h:1164
X509OctetString maskGenAlgo
Definition: x509_common.h:1152
@ X509_SIGN_ALGO_RSA
Definition: x509_common.h:709
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:710
error_t x509GenerateEd25519Signature(const X509OctetString *tbsData, const EddsaPrivateKey *privateKey, uint8_t *output, size_t *written)
Ed25519 signature generation.
#define OID_COMP(oid1, oidLen1, oid2)
Definition: oid.h:42
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
uint8_t oidLen
Definition: lldp_tlv.h:299
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.
error_t x509GenerateRsaPssSignature(const PrngAlgo *prngAlgo, void *prngContext, const X509OctetString *tbsData, const HashAlgo *hashAlgo, const HashAlgo *mgfHashAlgo, size_t saltLen, const RsaPrivateKey *privateKey, uint8_t *output, size_t *written)
RSA-PSS 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:254
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:762
Common interface for hash algorithms.
Definition: crypto.h:1243
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:713
Octet string.
Definition: x509_common.h:761
#define SM2_DEFAULT_ID
Definition: sm2.h:40
@ X509_SIGN_ALGO_ED25519
Definition: x509_common.h:714
const uint8_t RSASSA_PSS_SHAKE128_OID[8]
Definition: rsa.c:87
error_t rsassaPssSign(const PrngAlgo *prngAlgo, void *prngContext, const RsaPrivateKey *key, const HashAlgo *hash, const HashAlgo *mgfHash, size_t saltLen, const uint8_t *digest, uint8_t *signature, size_t *signatureLen)
RSASSA-PSS signature generation operation.
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:1166
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:243
Signature algorithm identifier.
Definition: x509_common.h:1163
@ 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:711
@ X509_SIGN_ALGO_ED448
Definition: x509_common.h:715
#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