x509_key_format.c
Go to the documentation of this file.
1 /**
2  * @file x509_key_format.c
3  * @brief Formatting of ASN.1 encoded keys
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"
36 #include "pkix/x509_key_format.h"
37 #include "encoding/asn1.h"
38 #include "encoding/oid.h"
39 #include "ecc/eddsa.h"
40 #include "hash/sha1.h"
41 #include "debug.h"
42 
43 //Check crypto library configuration
44 #if (X509_SUPPORT == ENABLED || PEM_SUPPORT == ENABLED)
45 
46 
47 /**
48  * @brief Format SubjectPublicKeyInfo structure
49  * @param[in] publicKeyInfo Subject's public key information
50  * @param[in] publicKey Pointer to the public key (RSA, DSA, ECDSA or EdDSA)
51  * @param[out] keyId Subject's key identifier (optional parameter)
52  * @param[out] output Buffer where to format the ASN.1 structure
53  * @param[out] written Length of the resulting ASN.1 structure
54  * @return Error code
55  **/
56 
58  const void *publicKey, uint8_t *keyId, uint8_t *output, size_t *written)
59 {
60  error_t error;
61  size_t n;
62  size_t length;
63  uint8_t *p;
64  Asn1Tag tag;
65 
66  //Point to the buffer where to write the ASN.1 structure
67  p = output;
68  //Length of the ASN.1 structure
69  length = 0;
70 
71 #if (DSA_SUPPORT == ENABLED)
72  //Valid DSA public key?
73  if(publicKey != NULL && OID_COMP(publicKeyInfo->oid.value,
74  publicKeyInfo->oid.length, DSA_OID) == 0)
75  {
76  const DsaPublicKey *dsaPublicKey;
77 
78  //Point to the DSA public key
79  dsaPublicKey = (DsaPublicKey *) publicKey;
80 
81  //Format AlgorithmIdentifier field
82  error = x509FormatAlgoId(publicKeyInfo, &dsaPublicKey->params, p, &n);
83  }
84  else
85 #endif
86  {
87  //Format AlgorithmIdentifier field
88  error = x509FormatAlgoId(publicKeyInfo, NULL, p, &n);
89  }
90 
91  //Any error to report?
92  if(error)
93  return error;
94 
95  //Advance data pointer
97  length += n;
98 
99  //Format SubjectPublicKey field
100  error = x509FormatSubjectPublicKey(publicKeyInfo, publicKey, keyId, p, &n);
101  //Any error to report?
102  if(error)
103  return error;
104 
105  //Advance data pointer
106  ASN1_INC_POINTER(p, n);
107  length += n;
108 
109  //The SubjectPublicKeyInfo structure is encapsulated within a sequence
110  tag.constructed = TRUE;
113  tag.length = length;
114 
115  //Write the corresponding ASN.1 tag
116  error = asn1InsertHeader(&tag, output, &n);
117  //Any error to report?
118  if(error)
119  return error;
120 
121  //Total number of bytes that have been written
122  *written = length + n;
123 
124  //Successful processing
125  return NO_ERROR;
126 }
127 
128 
129 /**
130  * @brief Format AlgorithmIdentifier structure
131  * @param[in] publicKeyInfo Subject's public key information
132  * @param[in] params Pointer to the domain parameters (DSA or ECDSA)
133  * @param[out] output Buffer where to format the ASN.1 structure
134  * @param[out] written Length of the resulting ASN.1 structure
135  * @return Error code
136  **/
137 
139  const void *params, uint8_t *output, size_t *written)
140 {
141  error_t error;
142  size_t n;
143  size_t length;
144  uint8_t *p;
145  size_t oidLen;
146  const uint8_t *oid;
147  Asn1Tag tag;
148 
149  //Get the public key identifier
150  oid = publicKeyInfo->oid.value;
151  oidLen = publicKeyInfo->oid.length;
152 
153  //Point to the buffer where to write the ASN.1 structure
154  p = output;
155  //Length of the ASN.1 structure
156  length = 0;
157 
158  //Format algorithm OID
159  tag.constructed = FALSE;
162  tag.length = oidLen;
163  tag.value = oid;
164 
165  //Write the corresponding ASN.1 tag
166  error = asn1WriteTag(&tag, FALSE, p, &n);
167  //Any error to report?
168  if(error)
169  return error;
170 
171  //Advance data pointer
172  ASN1_INC_POINTER(p, n);
173  length += n;
174 
175 #if (RSA_SUPPORT == ENABLED)
176  //RSA algorithm identifier?
178  {
179  //The parameters field must have ASN.1 type NULL for this algorithm
180  //identifier (refer to RFC 3279, section 2.3.1)
181  tag.constructed = FALSE;
183  tag.objType = ASN1_TYPE_NULL;
184  tag.length = 0;
185  tag.value = NULL;
186 
187  //Write the corresponding ASN.1 tag
188  error = asn1WriteTag(&tag, FALSE, p, &n);
189  }
190  //RSA-PSS algorithm identifier?
191  else if(OID_COMP(oid, oidLen, RSASSA_PSS_OID) == 0)
192  {
193  //The parameters may be either absent or present when used as subject
194  //public key information (refer to RFC 4055, section 3.1)
195  n = 0;
196  }
197  else
198 #endif
199 #if (DSA_SUPPORT == ENABLED)
200  //DSA algorithm identifier?
201  if(OID_COMP(oid, oidLen, DSA_OID) == 0)
202  {
203  //Valid DSA domain parameters?
204  if(params != NULL)
205  {
206  //Export the DSA domain parameters to ASN.1 format
207  error = x509ExportDsaParameters(params, p, &n);
208  }
209  else
210  {
211  //Format DSAParameters structure
212  error = x509FormatDsaParameters(&publicKeyInfo->dsaParams, p, &n);
213  }
214  }
215  else
216 #endif
217 #if (EC_SUPPORT == ENABLED)
218  //EC public key identifier?
220  {
221  //Format ECParameters structure
222  error = x509FormatEcParameters(&publicKeyInfo->ecParams, p, &n);
223  }
224  else
225 #endif
226 #if (ED25519_SUPPORT == ENABLED)
227  //X25519 or Ed25519 algorithm identifier?
228  if(OID_COMP(oid, oidLen, X25519_OID) == 0 ||
229  OID_COMP(oid, oidLen, ED25519_OID) == 0)
230  {
231  //For all of the OIDs, the parameters must be absent (refer to RFC 8410,
232  //section 3)
233  n = 0;
234  }
235  else
236 #endif
237 #if (ED448_SUPPORT == ENABLED)
238  //X448 or Ed448 algorithm identifier?
239  if(OID_COMP(oid, oidLen, X448_OID) == 0 ||
240  OID_COMP(oid, oidLen, ED448_OID) == 0)
241  {
242  //For all of the OIDs, the parameters must be absent (refer to RFC 8410,
243  //section 3)
244  n = 0;
245  }
246  else
247 #endif
248 #if (MLDSA44_SUPPORT == ENABLED)
249  //ML-DSA-44 algorithm identifier?
250  if(OID_COMP(oid, oidLen, MLDSA44_OID) == 0)
251  {
252  //The contents of the parameters component must be absent (refer to
253  //RFC 9881, section 2)
254  n = 0;
255  }
256  else
257 #endif
258 #if (MLDSA65_SUPPORT == ENABLED)
259  //ML-DSA-65 algorithm identifier?
260  if(OID_COMP(oid, oidLen, MLDSA65_OID) == 0)
261  {
262  //The contents of the parameters component must be absent (refer to
263  //RFC 9881, section 2)
264  n = 0;
265  }
266  else
267 #endif
268 #if (MLDSA87_SUPPORT == ENABLED)
269  //ML-DSA-87 algorithm identifier?
270  if(OID_COMP(oid, oidLen, MLDSA87_OID) == 0)
271  {
272  //The contents of the parameters component must be absent (refer to
273  //RFC 9881, section 2)
274  n = 0;
275  }
276  else
277 #endif
278  //Unknown algorithm identifier?
279  {
280  //Report an error
281  error = ERROR_INVALID_PARAMETER;
282  }
283 
284  //Any error to report?
285  if(error)
286  return error;
287 
288  //Advance data pointer
289  ASN1_INC_POINTER(p, n);
290  length += n;
291 
292  //The AlgorithmIdentifier structure is encapsulated within a sequence
293  tag.constructed = TRUE;
296  tag.length = length;
297 
298  //Write the corresponding ASN.1 tag
299  error = asn1InsertHeader(&tag, output, &n);
300  //Any error to report?
301  if(error)
302  return error;
303 
304  //Total number of bytes that have been written
305  *written = length + n;
306 
307  //Successful processing
308  return NO_ERROR;
309 }
310 
311 
312 /**
313  * @brief Format SubjectPublicKey structure
314  * @param[in] publicKeyInfo Subject's public key information
315  * @param[in] publicKey Pointer to the public key (RSA, DSA, ECDSA or EdDSA)
316  * @param[out] keyId Subject's key identifier (optional parameter)
317  * @param[out] output Buffer where to format the ASN.1 structure
318  * @param[out] written Length of the resulting ASN.1 structure
319  * @return Error code
320  **/
321 
323  const void *publicKey, uint8_t *keyId, uint8_t *output, size_t *written)
324 {
325  error_t error;
326  size_t n;
327  uint8_t *p;
328  size_t oidLen;
329  const uint8_t *oid;
330  Asn1Tag tag;
331 
332  //Get the public key identifier
333  oid = publicKeyInfo->oid.value;
334  oidLen = publicKeyInfo->oid.length;
335 
336  //Point to the buffer where to write the ASN.1 structure
337  p = output;
338 
339  //If the output parameter is NULL, then the function calculates the length
340  //of the ASN.1 structure without copying any data
341  if(p != NULL)
342  {
343  //The bit string shall contain an initial octet which encodes the number
344  //of unused bits in the final subsequent octet
345  p[0] = 0;
346 
347  //Advance data pointer
348  p++;
349  }
350 
351 #if (RSA_SUPPORT == ENABLED)
352  //RSA or RSA-PSS algorithm identifier?
353  if(OID_COMP(oid, oidLen, RSA_ENCRYPTION_OID) == 0 ||
355  {
356  //Valid RSA public key?
357  if(publicKey != NULL)
358  {
359  //Export the RSA public key to ASN.1 format
360  error = x509ExportRsaPublicKey(publicKey, p, &n);
361  }
362  else
363  {
364  //Format RSAPublicKey structure
365  error = x509FormatRsaPublicKey(&publicKeyInfo->rsaPublicKey, p, &n);
366  }
367  }
368  else
369 #endif
370 #if (DSA_SUPPORT == ENABLED)
371  //DSA algorithm identifier?
372  if(OID_COMP(oid, oidLen, DSA_OID) == 0)
373  {
374  //Valid DSA public key?
375  if(publicKey != NULL)
376  {
377  //Export the DSA public key to ASN.1 format
378  error = x509ExportDsaPublicKey(publicKey, p, &n);
379  }
380  else
381  {
382  //Format DSAPublicKey structure
383  error = x509FormatDsaPublicKey(&publicKeyInfo->dsaPublicKey, p, &n);
384  }
385  }
386  else
387 #endif
388 #if (EC_SUPPORT == ENABLED)
389  //EC public key identifier?
391  {
392  //Valid EC public key?
393  if(publicKey != NULL)
394  {
395  //Export the EC public key
396  error = ecExportPublicKey(publicKey, p, &n, EC_PUBLIC_KEY_FORMAT_X963);
397  }
398  else
399  {
400  //Format ECPublicKey structure
401  error = x509FormatEcPublicKey(&publicKeyInfo->ecPublicKey, p, &n);
402  }
403  }
404  else
405 #endif
406 #if (ED25519_SUPPORT == ENABLED)
407  //Ed25519 algorithm identifier?
408  if(OID_COMP(oid, oidLen, ED25519_OID) == 0)
409  {
410  //Valid EdDSA public key?
411  if(publicKey != NULL)
412  {
413  //Export the EdDSA public key
414  error = eddsaExportPublicKey(publicKey, p, &n);
415  }
416  else
417  {
418  //The SubjectPublicKey contains the byte stream of the public key
419  error = x509FormatEcPublicKey(&publicKeyInfo->ecPublicKey, p, &n);
420  }
421  }
422  else
423 #endif
424 #if (ED448_SUPPORT == ENABLED)
425  //Ed448 algorithm identifier?
426  if(OID_COMP(oid, oidLen, ED448_OID) == 0)
427  {
428  //Valid EdDSA public key?
429  if(publicKey != NULL)
430  {
431  //Export the EdDSA public key
432  error = eddsaExportPublicKey(publicKey, p, &n);
433  }
434  else
435  {
436  //The SubjectPublicKey contains the byte stream of the public key
437  error = x509FormatEcPublicKey(&publicKeyInfo->ecPublicKey, p, &n);
438  }
439  }
440  else
441 #endif
442 #if (MLDSA44_SUPPORT == ENABLED)
443  //ML-DSA-44 algorithm identifier?
444  if(OID_COMP(oid, oidLen, MLDSA44_OID) == 0)
445  {
446  //Valid ML-DSA public key?
447  if(publicKey != NULL)
448  {
449  //Export the ML-DSA public key
450  error = mldsaExportPublicKey(publicKey, p, &n);
451  }
452  else
453  {
454  //The SubjectPublicKey contains the byte stream of the public key
455  error = x509FormatMldsaPublicKey(&publicKeyInfo->mldsaPublicKey, p, &n);
456  }
457  }
458  else
459 #endif
460 #if (MLDSA65_SUPPORT == ENABLED)
461  //ML-DSA-65 algorithm identifier?
462  if(OID_COMP(oid, oidLen, MLDSA65_OID) == 0)
463  {
464  //Valid ML-DSA public key?
465  if(publicKey != NULL)
466  {
467  //Export the ML-DSA public key
468  error = mldsaExportPublicKey(publicKey, p, &n);
469  }
470  else
471  {
472  //The SubjectPublicKey contains the byte stream of the public key
473  error = x509FormatMldsaPublicKey(&publicKeyInfo->mldsaPublicKey, p, &n);
474  }
475  }
476  else
477 #endif
478 #if (MLDSA87_SUPPORT == ENABLED)
479  //ML-DSA-87 algorithm identifier?
480  if(OID_COMP(oid, oidLen, MLDSA87_OID) == 0)
481  {
482  //Valid ML-DSA public key?
483  if(publicKey != NULL)
484  {
485  //Export the ML-DSA public key
486  error = mldsaExportPublicKey(publicKey, p, &n);
487  }
488  else
489  {
490  //The SubjectPublicKey contains the byte stream of the public key
491  error = x509FormatMldsaPublicKey(&publicKeyInfo->mldsaPublicKey, p, &n);
492  }
493  }
494  else
495 #endif
496  //Unknown algorithm identifier?
497  {
498  //Report an error
499  error = ERROR_INVALID_PARAMETER;
500  }
501 
502  //Any error to report?
503  if(error)
504  return error;
505 
506  //The keyIdentifier parameter is optional
507  if(keyId != NULL && p != NULL)
508  {
509  //The keyIdentifier is composed of the 160-bit SHA-1 hash of the value
510  //of the bit string subjectPublicKey (excluding the tag, length, and
511  //number of unused bits)
512  error = sha1Compute(p, n, keyId);
513  //Any error to report?
514  if(error)
515  return error;
516  }
517 
518  //The public key is encapsulated within a bit string
519  tag.constructed = FALSE;
522  tag.length = n + 1;
523 
524  //Write the corresponding ASN.1 tag
525  error = asn1InsertHeader(&tag, output, &n);
526  //Any error to report?
527  if(error)
528  return error;
529 
530  //Total number of bytes that have been written
531  *written = tag.totalLength;;
532 
533  //Successful processing
534  return NO_ERROR;
535 }
536 
537 
538 /**
539  * @brief Format RSAPublicKey structure
540  * @param[in] rsaPublicKey Pointer to the RSA public key
541  * @param[out] output Buffer where to format the ASN.1 structure
542  * @param[out] written Length of the resulting ASN.1 structure
543  * @return Error code
544  **/
545 
547  uint8_t *output, size_t *written)
548 {
549  error_t error;
550  size_t n;
551  size_t length;
552  uint8_t *p;
553  Asn1Tag tag;
554 
555  //Point to the buffer where to write the ASN.1 structure
556  p = output;
557  //Length of the ASN.1 structure
558  length = 0;
559 
560  //Write Modulus field
561  tag.constructed = FALSE;
564  tag.length = rsaPublicKey->n.length;
565  tag.value = rsaPublicKey->n.value;
566 
567  //Write the corresponding ASN.1 tag
568  error = asn1WriteTag(&tag, FALSE, p, &n);
569  //Any error to report?
570  if(error)
571  return error;
572 
573  //Advance data pointer
574  ASN1_INC_POINTER(p, n);
575  length += n;
576 
577  //Write PublicExponent field
578  tag.constructed = FALSE;
581  tag.length = rsaPublicKey->e.length;
582  tag.value = rsaPublicKey->e.value;
583 
584  //Write the corresponding ASN.1 tag
585  error = asn1WriteTag(&tag, FALSE, p, &n);
586  //Any error to report?
587  if(error)
588  return error;
589 
590  //Advance data pointer
591  ASN1_INC_POINTER(p, n);
592  length += n;
593 
594  //The public key is encapsulated within a sequence
595  tag.constructed = TRUE;
598  tag.length = length;
599 
600  //Write RSAPublicKey structure
601  error = asn1InsertHeader(&tag, output, &n);
602  //Any error to report?
603  if(error)
604  return error;
605 
606  //Total number of bytes that have been written
607  *written = tag.totalLength;;
608 
609  //Successful processing
610  return NO_ERROR;
611 }
612 
613 
614 /**
615  * @brief Format DSAPublicKey structure
616  * @param[in] dsaPublicKey Pointer to the DSA public key
617  * @param[out] output Buffer where to format the DSAPublicKey structure
618  * @param[out] written Length of the DSAPublicKey structure
619  * @return Error code
620  **/
621 
623  uint8_t *output, size_t *written)
624 {
625  error_t error;
626  size_t n;
627  Asn1Tag tag;
628 
629  //Write public key
630  tag.constructed = FALSE;
633  tag.length = dsaPublicKey->y.length;
634  tag.value = dsaPublicKey->y.value;
635 
636  //Write the corresponding ASN.1 tag
637  error = asn1WriteTag(&tag, FALSE, output, &n);
638  //Any error to report?
639  if(error)
640  return error;
641 
642  //Total number of bytes that have been written
643  *written = n;
644 
645  //Successful processing
646  return NO_ERROR;
647 }
648 
649 
650 /**
651  * @brief Format DSA domain parameters
652  * @param[in] dsaParams Pointer to the DSA domain parameters
653  * @param[out] output Buffer where to format the ASN.1 structure
654  * @param[out] written Length of the resulting ASN.1 structure
655  * @return Error code
656  **/
657 
659  uint8_t *output, size_t *written)
660 {
661  error_t error;
662  size_t n;
663  size_t length;
664  uint8_t *p;
665  Asn1Tag tag;
666 
667  //Point to the buffer where to write the ASN.1 structure
668  p = output;
669  //Length of the ASN.1 structure
670  length = 0;
671 
672  //Write parameter p
673  tag.constructed = FALSE;
676  tag.length = dsaParams->p.length;
677  tag.value = dsaParams->p.value;
678 
679  //Write the corresponding ASN.1 tag
680  error = asn1WriteTag(&tag, FALSE, p, &n);
681  //Any error to report?
682  if(error)
683  return error;
684 
685  //Advance data pointer
686  ASN1_INC_POINTER(p, n);
687  length += n;
688 
689  //Write parameter q
690  tag.constructed = FALSE;
693  tag.length = dsaParams->q.length;
694  tag.value = dsaParams->q.value;
695 
696  //Write the corresponding ASN.1 tag
697  error = asn1WriteTag(&tag, FALSE, p, &n);
698  //Any error to report?
699  if(error)
700  return error;
701 
702  //Advance data pointer
703  ASN1_INC_POINTER(p, n);
704  length += n;
705 
706  //Write parameter g
707  tag.constructed = FALSE;
710  tag.length = dsaParams->g.length;
711  tag.value = dsaParams->g.value;
712 
713  //Write the corresponding ASN.1 tag
714  error = asn1WriteTag(&tag, FALSE, p, &n);
715  //Any error to report?
716  if(error)
717  return error;
718 
719  //Advance data pointer
720  ASN1_INC_POINTER(p, n);
721  length += n;
722 
723  //The DSA domain parameters are encapsulated within a sequence
724  tag.constructed = TRUE;
727  tag.length = length;
728 
729  //Write DSAParameters structure
730  error = asn1InsertHeader(&tag, output, &n);
731  //Any error to report?
732  if(error)
733  return error;
734 
735  //Total number of bytes that have been written
736  *written = tag.totalLength;
737 
738  //Successful processing
739  return NO_ERROR;
740 }
741 
742 
743 /**
744  * @brief Format ECPublicKey structure
745  * @param[in] ecPublicKey Pointer to the EC public key
746  * @param[out] output Buffer where to format the ASN.1 structure
747  * @param[out] written Length of the resulting ASN.1 structure
748  * @return Error code
749  **/
750 
752  uint8_t *output, size_t *written)
753 {
754  //If the output parameter is NULL, then the function calculates the length
755  //of the octet string without copying any data
756  if(output != NULL)
757  {
758  //Copy the EC public key
759  osMemcpy(output, ecPublicKey->q.value, ecPublicKey->q.length);
760  }
761 
762  //Total number of bytes that have been written
763  *written = ecPublicKey->q.length;
764 
765  //Successful processing
766  return NO_ERROR;
767 }
768 
769 
770 /**
771  * @brief Format ECParameters structure
772  * @param[in] ecParams Pointer to the EC parameters
773  * @param[out] output Buffer where to format the ECParameters structure
774  * @param[out] written Length of the ECParameters structure
775  * @return Error code
776  **/
777 
779  uint8_t *output, size_t *written)
780 {
781  error_t error;
782  size_t n;
783  Asn1Tag tag;
784 
785  //The namedCurve field identifies all the required values for a particular
786  //set of elliptic curve domain parameters to be represented by an object
787  //identifier
788  tag.constructed = FALSE;
791  tag.length = ecParams->namedCurve.length;
792  tag.value = ecParams->namedCurve.value;
793 
794  //Write the corresponding ASN.1 tag
795  error = asn1WriteTag(&tag, FALSE, output, &n);
796  //Any error to report?
797  if(error)
798  return error;
799 
800  //Total number of bytes that have been written
801  *written = n;
802 
803  //Successful processing
804  return NO_ERROR;
805 }
806 
807 
808 /**
809  * @brief Format ML-DSA-PublicKey structure
810  * @param[in] mldsaPublicKey Pointer to the ML-DSA public key
811  * @param[out] output Buffer where to format the ASN.1 structure
812  * @param[out] written Length of the resulting ASN.1 structure
813  * @return Error code
814  **/
815 
816 
818  uint8_t *output, size_t *written)
819 {
820  //If the output parameter is NULL, then the function calculates the length
821  //of the octet string without copying any data
822  if(output != NULL)
823  {
824  //Copy the ML-DSA public key
825  osMemcpy(output, mldsaPublicKey->pk.value, mldsaPublicKey->pk.length);
826  }
827 
828  //Total number of bytes that have been written
829  *written = mldsaPublicKey->pk.length;
830 
831  //Successful processing
832  return NO_ERROR;
833 }
834 
835 
836 /**
837  * @brief Export an RSA public key to ASN.1 format
838  * @param[in] publicKey Pointer to the RSA public key
839  * @param[out] output Buffer where to store the ASN.1 structure
840  * @param[out] written Length of the resulting ASN.1 structure
841  * @return Error code
842  **/
843 
845  uint8_t *output, size_t *written)
846 {
847  error_t error;
848  size_t n;
849  size_t length;
850  uint8_t *p;
851  Asn1Tag tag;
852 
853  //Point to the buffer where to write the ASN.1 structure
854  p = output;
855  //Length of the ASN.1 structure
856  length = 0;
857 
858  //Write Modulus field
859  error = asn1WriteMpi(&publicKey->n, FALSE, p, &n);
860  //Any error to report?
861  if(error)
862  return error;
863 
864  //Advance data pointer
865  ASN1_INC_POINTER(p, n);
866  length += n;
867 
868  //Write PublicExponent field
869  error = asn1WriteMpi(&publicKey->e, FALSE, p, &n);
870  //Any error to report?
871  if(error)
872  return error;
873 
874  //Advance data pointer
875  ASN1_INC_POINTER(p, n);
876  length += n;
877 
878  //The public key is encapsulated within a sequence
879  tag.constructed = TRUE;
882  tag.length = length;
883 
884  //Write RSAPublicKey structure
885  error = asn1InsertHeader(&tag, output, &n);
886  //Any error to report?
887  if(error)
888  return error;
889 
890  //Total number of bytes that have been written
891  *written = tag.totalLength;
892 
893  //Successful processing
894  return NO_ERROR;
895 }
896 
897 
898 /**
899  * @brief Export an RSA private key to ASN.1 format
900  * @param[in] privateKey Pointer to the RSA private key
901  * @param[out] output Buffer where to store the ASN.1 structure
902  * @param[out] written Length of the resulting ASN.1 structure
903  * @return Error code
904  **/
905 
907  uint8_t *output, size_t *written)
908 {
909  error_t error;
910  size_t n;
911  size_t length;
912  uint8_t *p;
913  Asn1Tag tag;
914 
915  //Point to the buffer where to write the ASN.1 structure
916  p = output;
917  //Length of the ASN.1 structure
918  length = 0;
919 
920  //Write Version field
921  error = asn1WriteInt32(PKCS1_VERSION_1, FALSE, p, &n);
922  //Any error to report?
923  if(error)
924  return error;
925 
926  //Advance data pointer
927  ASN1_INC_POINTER(p, n);
928  length += n;
929 
930  //Write Modulus field
931  error = asn1WriteMpi(&privateKey->n, FALSE, p, &n);
932  //Any error to report?
933  if(error)
934  return error;
935 
936  //Advance data pointer
937  ASN1_INC_POINTER(p, n);
938  length += n;
939 
940  //Write PublicExponent field
941  error = asn1WriteMpi(&privateKey->e, FALSE, p, &n);
942  //Any error to report?
943  if(error)
944  return error;
945 
946  //Advance data pointer
947  ASN1_INC_POINTER(p, n);
948  length += n;
949 
950  //Write PrivateExponent field
951  error = asn1WriteMpi(&privateKey->d, FALSE, p, &n);
952  //Any error to report?
953  if(error)
954  return error;
955 
956  //Advance data pointer
957  ASN1_INC_POINTER(p, n);
958  length += n;
959 
960  //Write Prime1 field
961  error = asn1WriteMpi(&privateKey->p, FALSE, p, &n);
962  //Any error to report?
963  if(error)
964  return error;
965 
966  //Advance data pointer
967  ASN1_INC_POINTER(p, n);
968  length += n;
969 
970  //Write Prime2 field
971  error = asn1WriteMpi(&privateKey->q, FALSE, p, &n);
972  //Any error to report?
973  if(error)
974  return error;
975 
976  //Advance data pointer
977  ASN1_INC_POINTER(p, n);
978  length += n;
979 
980  //Write Exponent1 field
981  error = asn1WriteMpi(&privateKey->dp, FALSE, p, &n);
982  //Any error to report?
983  if(error)
984  return error;
985 
986  //Advance data pointer
987  ASN1_INC_POINTER(p, n);
988  length += n;
989 
990  //Write Exponent2 field
991  error = asn1WriteMpi(&privateKey->dq, FALSE, p, &n);
992  //Any error to report?
993  if(error)
994  return error;
995 
996  //Advance data pointer
997  ASN1_INC_POINTER(p, n);
998  length += n;
999 
1000  //Write Coefficient field
1001  error = asn1WriteMpi(&privateKey->qinv, FALSE, p, &n);
1002  //Any error to report?
1003  if(error)
1004  return error;
1005 
1006  //Advance data pointer
1007  ASN1_INC_POINTER(p, n);
1008  length += n;
1009 
1010  //The private key is encapsulated within a sequence
1011  tag.constructed = TRUE;
1014  tag.length = length;
1015 
1016  //Write RSAPrivateKey structure
1017  error = asn1InsertHeader(&tag, output, &n);
1018  //Any error to report?
1019  if(error)
1020  return error;
1021 
1022  //Total number of bytes that have been written
1023  *written = tag.totalLength;
1024 
1025  //Successful processing
1026  return NO_ERROR;
1027 }
1028 
1029 
1030 /**
1031  * @brief Export a DSA public key to ASN.1 format
1032  * @param[in] publicKey Pointer to the DSA public key
1033  * @param[out] output Buffer where to store the ASN.1 structure
1034  * @param[out] written Length of the resulting ASN.1 structure
1035  * @return Error code
1036  **/
1037 
1039  uint8_t *output, size_t *written)
1040 {
1041  error_t error;
1042  size_t n;
1043 
1044  //Write public key
1045  error = asn1WriteMpi(&publicKey->y, FALSE, output, &n);
1046  //Any error to report?
1047  if(error)
1048  return error;
1049 
1050  //Total number of bytes that have been written
1051  *written = n;
1052 
1053  //Successful processing
1054  return NO_ERROR;
1055 }
1056 
1057 
1058 /**
1059  * @brief Export a DSA private key to ASN.1 format
1060  * @param[in] privateKey Pointer to the DSA private key
1061  * @param[out] output Buffer where to store the ASN.1 structure
1062  * @param[out] written Length of the resulting ASN.1 structure
1063  * @return Error code
1064  **/
1065 
1067  uint8_t *output, size_t *written)
1068 {
1069  error_t error;
1070  size_t n;
1071 
1072  //Write private key
1073  error = asn1WriteMpi(&privateKey->x, FALSE, output, &n);
1074  //Any error to report?
1075  if(error)
1076  return error;
1077 
1078  //Total number of bytes that have been written
1079  *written = n;
1080 
1081  //Successful processing
1082  return NO_ERROR;
1083 }
1084 
1085 
1086 /**
1087  * @brief Export DSA domain parameters to ASN.1 format
1088  * @param[in] params Pointer to the DSA domain parameters
1089  * @param[out] output Buffer where to store the ASN.1 structure
1090  * @param[out] written Length of the resulting ASN.1 structure
1091  * @return Error code
1092  **/
1093 
1095  uint8_t *output, size_t *written)
1096 {
1097  error_t error;
1098  size_t n;
1099  size_t length;
1100  uint8_t *p;
1101  Asn1Tag tag;
1102 
1103  //Point to the buffer where to write the ASN.1 structure
1104  p = output;
1105  //Length of the ASN.1 structure
1106  length = 0;
1107 
1108  //Write parameter p
1109  error = asn1WriteMpi(&params->p, FALSE, p, &n);
1110  //Any error to report?
1111  if(error)
1112  return error;
1113 
1114  //Advance data pointer
1115  ASN1_INC_POINTER(p, n);
1116  length += n;
1117 
1118  //Write parameter q
1119  error = asn1WriteMpi(&params->q, FALSE, p, &n);
1120  //Any error to report?
1121  if(error)
1122  return error;
1123 
1124  //Advance data pointer
1125  ASN1_INC_POINTER(p, n);
1126  length += n;
1127 
1128  //Write parameter g
1129  error = asn1WriteMpi(&params->g, FALSE, p, &n);
1130  //Any error to report?
1131  if(error)
1132  return error;
1133 
1134  //Advance data pointer
1135  ASN1_INC_POINTER(p, n);
1136  length += n;
1137 
1138  //The DSA domain parameters are encapsulated within a sequence
1139  tag.constructed = TRUE;
1142  tag.length = length;
1143 
1144  //Write DSAParameters structure
1145  error = asn1InsertHeader(&tag, output, &n);
1146  //Any error to report?
1147  if(error)
1148  return error;
1149 
1150  //Total number of bytes that have been written
1151  *written = tag.totalLength;
1152 
1153  //Successful processing
1154  return NO_ERROR;
1155 }
1156 
1157 
1158 /**
1159  * @brief Export an EC public key to ASN.1 format
1160  * @param[in] publicKey EC public key
1161  * @param[out] output Buffer where to format the ASN.1 structure
1162  * @param[out] written Length of the resulting ASN.1 structure
1163  * @return Error code
1164  **/
1165 
1167  uint8_t *output, size_t *written)
1168 {
1169 #if (EC_SUPPORT == ENABLED)
1170  error_t error;
1171  size_t n;
1172  uint8_t *p;
1173  Asn1Tag tag;
1174 
1175  //Point to the buffer where to write the ASN.1 structure
1176  p = output;
1177 
1178  //If the output parameter is NULL, then the function calculates the length
1179  //of the ASN.1 structure without copying any data
1180  if(p != NULL)
1181  {
1182  //The bit string shall contain an initial octet which encodes the number
1183  //of unused bits in the final subsequent octet
1184  p[0] = 0;
1185 
1186  //Advance data pointer
1187  p++;
1188  }
1189 
1190  //Format ECPublicKey structure
1191  error = ecExportPublicKey(publicKey, p, &n, EC_PUBLIC_KEY_FORMAT_X963);
1192 
1193  //Check status code
1194  if(!error)
1195  {
1196  //The public key is encapsulated within a bit string
1197  tag.constructed = FALSE;
1200  tag.length = n + 1;
1201 
1202  //Write the corresponding ASN.1 tag
1203  error = asn1InsertHeader(&tag, output, &n);
1204  }
1205 
1206  //Check status code
1207  if(!error)
1208  {
1209  //Get the length of the ECPublicKey structure
1210  n = tag.totalLength;
1211 
1212  //Explicit tagging shall be used to encode the public key
1213  tag.constructed = TRUE;
1215  tag.objType = 1;
1216  tag.length = n;
1217 
1218  //Write the corresponding ASN.1 tag
1219  error = asn1InsertHeader(&tag, output, &n);
1220  }
1221 
1222  //Check status code
1223  if(!error)
1224  {
1225  //Total number of bytes that have been written
1226  *written = tag.totalLength;
1227  }
1228 
1229  //Return status code
1230  return error;
1231 #else
1232  //Not implemented
1233  return ERROR_NOT_IMPLEMENTED;
1234 #endif
1235 }
1236 
1237 
1238 /**
1239  * @brief Export an EC private key to ASN.1 format
1240  * @param[in] curve Elliptic curve parameters (optional parameter)
1241  * @param[in] privateKey Pointer to the EC private key
1242  * @param[in] publicKey Pointer to the EC public key (optional parameter)
1243  * @param[out] output Buffer where to store the ASN.1 structure
1244  * @param[out] written Length of the resulting ASN.1 structure
1245  * @return Error code
1246  **/
1247 
1249  const EcPrivateKey *privateKey, const EcPublicKey *publicKey,
1250  uint8_t *output, size_t *written)
1251 {
1252 #if (EC_SUPPORT == ENABLED)
1253  error_t error;
1254  size_t n;
1255  size_t length;
1256  uint8_t *p;
1257  Asn1Tag tag;
1258 
1259  //Point to the buffer where to write the ASN.1 structure
1260  p = output;
1261  //Length of the ASN.1 structure
1262  length = 0;
1263 
1264  //Format Version field (refer to RFC 5915, section 3)
1265  error = asn1WriteInt32(1, FALSE, p, &n);
1266  //Any error to report?
1267  if(error)
1268  return error;
1269 
1270  //Advance data pointer
1271  ASN1_INC_POINTER(p, n);
1272  length += n;
1273 
1274  //The PrivateKey field is an octet string of length ceiling (log2(n)/8)
1275  //(refer to RFC 5915, section 3)
1276  error = ecExportPrivateKey(privateKey, p, &n);
1277  //Any error to report?
1278  if(error)
1279  return error;
1280 
1281  //Format PrivateKey field
1282  tag.constructed = FALSE;
1285  tag.length = n;
1286 
1287  //Write the corresponding ASN.1 tag
1288  error = asn1InsertHeader(&tag, p, &n);
1289  //Any error to report?
1290  if(error)
1291  return error;
1292 
1293  //Get the length of the PrivateKey structure
1294  n = tag.totalLength;
1295 
1296  //Advance data pointer
1297  ASN1_INC_POINTER(p, n);
1298  length += n;
1299 
1300  //The parameters field is optional
1301  if(curve != NULL)
1302  {
1303  //Format ECParameters field
1304  error = x509ExportEcParameters(curve, p, &n);
1305  //Any error to report?
1306  if(error)
1307  return error;
1308 
1309  //Advance data pointer
1310  ASN1_INC_POINTER(p, n);
1311  length += n;
1312  }
1313 
1314  //The publicKey field is optional
1315  if(publicKey != NULL && publicKey->curve != NULL)
1316  {
1317  //Format publicKey field
1318  error = x509ExportEcPublicKey(publicKey, p, &n);
1319  //Any error to report?
1320  if(error)
1321  return error;
1322 
1323  //Advance data pointer
1324  ASN1_INC_POINTER(p, n);
1325  length += n;
1326  }
1327 
1328  //Format ECPrivateKey field
1329  tag.constructed = TRUE;
1332  tag.length = length;
1333 
1334  //Write the corresponding ASN.1 tag
1335  error = asn1InsertHeader(&tag, output, &n);
1336  //Any error to report?
1337  if(error)
1338  return error;
1339 
1340  //Total number of bytes that have been written
1341  *written = tag.totalLength;
1342 
1343  //Successful processing
1344  return NO_ERROR;
1345 #else
1346  //Not implemented
1347  return ERROR_NOT_IMPLEMENTED;
1348 #endif
1349 }
1350 
1351 
1352 /**
1353  * @brief Export EC domain parameters to ASN.1 format
1354  * @param[in] curve Elliptic curve parameters
1355  * @param[out] output Buffer where to store the ASN.1 structure
1356  * @param[out] written Length of the resulting ASN.1 structure
1357  * @return Error code
1358  **/
1359 
1360 error_t x509ExportEcParameters(const EcCurve *curve, uint8_t *output,
1361  size_t *written)
1362 {
1363 #if (EC_SUPPORT == ENABLED)
1364  error_t error;
1365  size_t n;
1366  Asn1Tag tag;
1367 
1368  //Format ECParameters field
1369  tag.constructed = FALSE;
1372  tag.length = curve->oidSize;
1373  tag.value = curve->oid;
1374 
1375  //Write the corresponding ASN.1 tag
1376  error = asn1WriteTag(&tag, FALSE, output, &n);
1377 
1378  //Check status code
1379  if(!error)
1380  {
1381  //Explicit tagging shall be used to encode the parameters
1382  tag.constructed = TRUE;
1384  tag.objType = 0;
1385  tag.length = n;
1386 
1387  //Write the corresponding ASN.1 tag
1388  error = asn1InsertHeader(&tag, output, &n);
1389  }
1390 
1391  //Check status code
1392  if(!error)
1393  {
1394  //Total number of bytes that have been written
1395  *written = tag.totalLength;
1396  }
1397 
1398  //Return status code
1399  return error;
1400 #else
1401  //Not implemented
1402  return ERROR_NOT_IMPLEMENTED;
1403 #endif
1404 }
1405 
1406 
1407 /**
1408  * @brief Export an EdDSA private key to ASN.1 format
1409  * @param[in] privateKey Pointer to the EdDSA private key
1410  * @param[out] output Buffer where to store the ASN.1 structure
1411  * @param[out] written Length of the resulting ASN.1 structure
1412  * @return Error code
1413  **/
1414 
1416  uint8_t *output, size_t *written)
1417 {
1418 #if (ED25519_SUPPORT == ENABLED || ED448_SUPPORT == ENABLED)
1419  error_t error;
1420  size_t n;
1421  Asn1Tag tag;
1422 
1423  //The private key is always an opaque byte sequence
1424  error = eddsaExportPrivateKey(privateKey, output, &n);
1425 
1426  //Check status code
1427  if(!error)
1428  {
1429  //The private key is encapsulated within an octet string
1430  tag.constructed = FALSE;
1433  tag.length = n;
1434 
1435  //Write CurvePrivateKey structure
1436  error = asn1InsertHeader(&tag, output, &n);
1437  }
1438 
1439  //Check status code
1440  if(!error)
1441  {
1442  //Total number of bytes that have been written
1443  *written = tag.totalLength;
1444  }
1445 
1446  //Return status code
1447  return error;
1448 #else
1449  //Not implemented
1450  return ERROR_NOT_IMPLEMENTED;
1451 #endif
1452 }
1453 
1454 
1455 /**
1456  * @brief Export an ML-DSA private key to ASN.1 format
1457  * @param[in] privateKey Pointer to the ML-DSA private key
1458  * @param[out] output Buffer where to store the ASN.1 structure
1459  * @param[out] written Length of the resulting ASN.1 structure
1460  * @return Error code
1461  **/
1462 
1464  uint8_t *output, size_t *written)
1465 {
1466 #if (MLDSA44_SUPPORT == ENABLED || MLDSA65_SUPPORT == ENABLED || \
1467  MLDSA87_SUPPORT == ENABLED)
1468  error_t error;
1469  size_t n;
1470  size_t length;
1471  uint8_t *p;
1472  Asn1Tag tag;
1473 
1474  //The CHOICE allows three representations of the private key
1475  if(privateKey->seed != NULL &&
1476  privateKey->sk == NULL)
1477  {
1478  //The seed format contains just the 32-byte seed value from which both
1479  //the expanded private key and public key can be derived
1480  error = mldsaExportSeed(privateKey, output, &n);
1481  //Any error to report?
1482  if(error)
1483  return error;
1484 
1485  //Implicit tagging shall be used to encode the seed
1486  tag.constructed = FALSE;
1488  tag.objType = 0;
1489  tag.length = n;
1490 
1491  //Write the corresponding ASN.1 tag
1492  error = asn1InsertHeader(&tag, output, &n);
1493  //Any error to report?
1494  if(error)
1495  return error;
1496  }
1497  else if(privateKey->seed == NULL &&
1498  privateKey->sk != NULL)
1499  {
1500  //The expandedKey format contains the expanded private key that was
1501  //derived from the seed
1502  error = mldsaExportPrivateKey(privateKey, output, &n);
1503  //Any error to report?
1504  if(error)
1505  return error;
1506 
1507  //The private key is encapsulated within an octet string
1508  tag.constructed = FALSE;
1511  tag.length = n;
1512 
1513  //Write the corresponding ASN.1 tag
1514  error = asn1InsertHeader(&tag, output, &n);
1515  //Any error to report?
1516  if(error)
1517  return error;
1518  }
1519  else if(privateKey->seed != NULL &&
1520  privateKey->sk != NULL)
1521  {
1522  //Point to the buffer where to write the ASN.1 structure
1523  p = output;
1524  //Length of the ASN.1 structure
1525  length = 0;
1526 
1527  //The both format contains both the seed and expanded private key
1528  error = mldsaExportSeed(privateKey, p, &n);
1529  //Any error to report?
1530  if(error)
1531  return error;
1532 
1533  //The seed is encapsulated within an octet string
1534  tag.constructed = FALSE;
1537  tag.length = n;
1538 
1539  //Write the corresponding ASN.1 tag
1540  error = asn1InsertHeader(&tag, p, &n);
1541  //Any error to report?
1542  if(error)
1543  return error;
1544 
1545  //Get the length of the seed field
1546  n = tag.totalLength;
1547 
1548  //Advance data pointer
1549  ASN1_INC_POINTER(p, n);
1550  length += n;
1551 
1552  //Write the private key
1553  error = mldsaExportPrivateKey(privateKey, p, &n);
1554  //Any error to report?
1555  if(error)
1556  return error;
1557 
1558  //The private key is encapsulated within an octet string
1559  tag.constructed = FALSE;
1562  tag.length = n;
1563 
1564  //Write the corresponding ASN.1 tag
1565  error = asn1InsertHeader(&tag, p, &n);
1566  //Any error to report?
1567  if(error)
1568  return error;
1569 
1570  //Get the length of the expandedKey field
1571  n = tag.totalLength;
1572 
1573  //Advance data pointer
1574  ASN1_INC_POINTER(p, n);
1575  length += n;
1576 
1577  //Format both structure
1578  tag.constructed = TRUE;
1581  tag.length = length;
1582 
1583  //Write the corresponding ASN.1 tag
1584  error = asn1InsertHeader(&tag, output, &n);
1585  //Any error to report?
1586  if(error)
1587  return error;
1588  }
1589  else
1590  {
1591  //Malformed private key
1592  return ERROR_INVALID_KEY;
1593  }
1594 
1595  //Total number of bytes that have been written
1596  *written = tag.totalLength;
1597 
1598  //Successful processing
1599  return NO_ERROR;
1600 #else
1601  //Not implemented
1602  return ERROR_NOT_IMPLEMENTED;
1603 #endif
1604 }
1605 
1606 #endif
const uint8_t MLDSA44_OID[9]
Definition: mldsa.c:47
error_t mldsaExportPrivateKey(const MldsaPrivateKey *key, uint8_t *output, size_t *written)
Export an ML-DSA private key.
Definition: mldsa.c:357
error_t x509FormatEcParameters(const X509EcParameters *ecParams, uint8_t *output, size_t *written)
Format ECParameters structure.
error_t x509ExportEddsaPrivateKey(const EddsaPrivateKey *privateKey, uint8_t *output, size_t *written)
Export an EdDSA private key to ASN.1 format.
Mpi p
First factor.
Definition: rsa.h:72
const uint8_t X25519_OID[3]
Definition: ec_curves.c:108
X509OctetString g
Definition: x509_common.h:829
const uint8_t MLDSA65_OID[9]
Definition: mldsa.c:49
X509OctetString p
Definition: x509_common.h:827
@ ERROR_NOT_IMPLEMENTED
Definition: error.h:66
X509DsaPublicKey dsaPublicKey
Definition: x509_common.h:887
uint8_t * seed
Seed.
Definition: mldsa.h:96
OID (Object Identifier)
SHA-1 (Secure Hash Algorithm 1)
uint8_t p
Definition: ndp.h:300
Mpi q
Group order.
Definition: dsa.h:51
X509OctetString oid
Definition: x509_common.h:880
#define TRUE
Definition: os_port.h:50
error_t x509ExportEcPrivateKey(const EcCurve *curve, const EcPrivateKey *privateKey, const EcPublicKey *publicKey, uint8_t *output, size_t *written)
Export an EC private key to ASN.1 format.
error_t asn1InsertHeader(Asn1Tag *tag, uint8_t *data, size_t *written)
Insert an ASN.1 tag header.
Definition: asn1.c:643
const uint8_t EC_PUBLIC_KEY_OID[7]
Definition: ec.c:44
Mpi n
Modulus.
Definition: rsa.h:69
X509EcParameters ecParams
Definition: x509_common.h:891
error_t mldsaExportSeed(const MldsaPrivateKey *key, uint8_t *output, size_t *written)
Export an ML-DSA seed.
Definition: mldsa.c:489
@ EC_PUBLIC_KEY_FORMAT_X963
Definition: ec.h:386
error_t ecExportPublicKey(const EcPublicKey *key, uint8_t *output, size_t *written, EcPublicKeyFormat format)
Export an EC public key.
Definition: ec.c:378
Mpi e
Public exponent.
Definition: rsa.h:59
Mpi p
Prime modulus.
Definition: dsa.h:50
const uint8_t RSASSA_PSS_OID[9]
Definition: rsa.c:85
uint8_t oid[]
Definition: lldp_tlv.h:300
Mpi d
Private exponent.
Definition: rsa.h:71
Mpi n
Modulus.
Definition: rsa.h:58
X509OctetString q
Definition: x509_common.h:828
EC public key.
Definition: x509_common.h:858
error_t x509FormatMldsaPublicKey(const X509MldsaPublicKey *mldsaPublicKey, uint8_t *output, size_t *written)
Format ML-DSA-PublicKey structure.
error_t x509FormatSubjectPublicKeyInfo(const X509SubjectPublicKeyInfo *publicKeyInfo, const void *publicKey, uint8_t *keyId, uint8_t *output, size_t *written)
Format SubjectPublicKeyInfo structure.
const uint8_t DSA_OID[7]
Definition: dsa.c:51
@ PKCS1_VERSION_1
Definition: x509_common.h:515
error_t sha1Compute(const void *data, size_t length, uint8_t *digest)
Digest a message using SHA-1.
size_t totalLength
Definition: asn1.h:111
error_t x509ExportMldsaPrivateKey(const MldsaPrivateKey *privateKey, uint8_t *output, size_t *written)
Export an ML-DSA private key to ASN.1 format.
error_t eddsaExportPublicKey(const EddsaPublicKey *key, uint8_t *output, size_t *written)
Export an EdDSA public key.
Definition: eddsa.c:328
size_t length
Definition: asn1.h:109
X509OctetString y
Definition: x509_common.h:839
#define FALSE
Definition: os_port.h:46
DSA public key.
Definition: dsa.h:61
@ ERROR_INVALID_PARAMETER
Invalid parameter.
Definition: error.h:47
#define osMemcpy(dest, src, length)
Definition: os_port.h:147
error_t x509FormatDsaPublicKey(const X509DsaPublicKey *dsaPublicKey, uint8_t *output, size_t *written)
Format DSAPublicKey structure.
error_t
Error codes.
Definition: error.h:43
error_t ecExportPrivateKey(const EcPrivateKey *key, uint8_t *output, size_t *written)
Export an EC private key.
Definition: ec.c:578
Mpi g
Group generator.
Definition: dsa.h:52
error_t x509ExportDsaPublicKey(const DsaPublicKey *publicKey, uint8_t *output, size_t *written)
Export a DSA public key to ASN.1 format.
EC parameters.
Definition: x509_common.h:848
error_t x509ExportDsaPrivateKey(const DsaPrivateKey *privateKey, uint8_t *output, size_t *written)
Export a DSA private key to ASN.1 format.
#define ASN1_CLASS_UNIVERSAL
Definition: asn1.h:52
RSA public key.
Definition: x509_common.h:815
uint8_t * sk
Secret key.
Definition: mldsa.h:98
error_t x509FormatAlgoId(const X509SubjectPublicKeyInfo *publicKeyInfo, const void *params, uint8_t *output, size_t *written)
Format AlgorithmIdentifier structure.
ASN.1 tag.
Definition: asn1.h:105
Mpi q
Second factor.
Definition: rsa.h:73
#define ASN1_INC_POINTER(p, n)
Definition: asn1.h:58
error_t x509ExportRsaPublicKey(const RsaPublicKey *publicKey, uint8_t *output, size_t *written)
Export an RSA public key to ASN.1 format.
RSA public key.
Definition: rsa.h:57
X509RsaPublicKey rsaPublicKey
Definition: x509_common.h:883
DSA domain parameters.
Definition: dsa.h:49
X509MldsaPublicKey mldsaPublicKey
Definition: x509_common.h:896
error_t mldsaExportPublicKey(const MldsaPublicKey *key, uint8_t *output, size_t *written)
Export an ML-DSA public key.
Definition: mldsa.c:225
EdDSA (Edwards-Curve Digital Signature Algorithm)
General definitions for cryptographic algorithms.
error_t asn1WriteMpi(const Mpi *value, bool_t reverse, uint8_t *data, size_t *written)
Write a multiple-precision integer from the output stream.
Definition: asn1.c:880
error_t asn1WriteTag(Asn1Tag *tag, bool_t reverse, uint8_t *data, size_t *written)
Write an ASN.1 tag.
Definition: asn1.c:334
EC private key.
Definition: ec.h:432
error_t eddsaExportPrivateKey(const EddsaPrivateKey *key, uint8_t *output, size_t *written)
Export an EdDSA private key.
Definition: eddsa.c:436
DsaDomainParameters params
DSA domain parameters.
Definition: dsa.h:62
DSA private key.
Definition: dsa.h:72
X509DsaParameters dsaParams
Definition: x509_common.h:886
uint_t objClass
Definition: asn1.h:107
uint8_t length
Definition: tcp.h:375
Mpi e
Public exponent.
Definition: rsa.h:70
error_t x509FormatRsaPublicKey(const X509RsaPublicKey *rsaPublicKey, uint8_t *output, size_t *written)
Format RSAPublicKey structure.
error_t x509ExportRsaPrivateKey(const RsaPrivateKey *privateKey, uint8_t *output, size_t *written)
Export an RSA private key to ASN.1 format.
X509OctetString namedCurve
Definition: x509_common.h:849
error_t x509ExportEcPublicKey(const EcPublicKey *publicKey, uint8_t *output, size_t *written)
Export an EC public key to ASN.1 format.
const uint8_t ED448_OID[3]
Definition: ec_curves.c:114
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
const uint8_t ED25519_OID[3]
Definition: ec_curves.c:112
const uint8_t RSA_ENCRYPTION_OID[9]
Definition: rsa.c:54
const uint8_t X448_OID[3]
Definition: ec_curves.c:110
EC public key.
Definition: ec.h:421
@ ASN1_TYPE_OCTET_STRING
Definition: asn1.h:75
@ ASN1_TYPE_INTEGER
Definition: asn1.h:73
Formatting of ASN.1 encoded keys.
error_t x509FormatEcPublicKey(const X509EcPublicKey *ecPublicKey, uint8_t *output, size_t *written)
Format ECPublicKey structure.
error_t x509ExportEcParameters(const EcCurve *curve, uint8_t *output, size_t *written)
Export EC domain parameters to ASN.1 format.
X509OctetString q
Definition: x509_common.h:859
#define OID_COMP(oid1, oidLen1, oid2)
Definition: oid.h:42
uint8_t n
RSA private key.
Definition: rsa.h:68
X509OctetString n
Definition: x509_common.h:816
X509OctetString e
Definition: x509_common.h:817
Subject Public Key Information extension.
Definition: x509_common.h:878
DSA domain parameters.
Definition: x509_common.h:826
#define ASN1_CLASS_CONTEXT_SPECIFIC
Definition: asn1.h:54
error_t x509FormatDsaParameters(const X509DsaParameters *dsaParams, uint8_t *output, size_t *written)
Format DSA domain parameters.
error_t x509ExportDsaParameters(const DsaDomainParameters *params, uint8_t *output, size_t *written)
Export DSA domain parameters to ASN.1 format.
Mpi x
Secret exponent.
Definition: dsa.h:74
uint8_t oidLen
Definition: lldp_tlv.h:299
bool_t constructed
Definition: asn1.h:106
Mpi y
Public key value.
Definition: dsa.h:63
ML-DSA private key.
Definition: mldsa.h:94
@ ASN1_TYPE_OBJECT_IDENTIFIER
Definition: asn1.h:77
@ ASN1_TYPE_SEQUENCE
Definition: asn1.h:83
const uint8_t * value
Definition: x509_common.h:732
#define EcCurve
Definition: ec.h:346
Mpi dp
First factor's CRT exponent.
Definition: rsa.h:74
@ ASN1_TYPE_BIT_STRING
Definition: asn1.h:74
const uint8_t MLDSA87_OID[9]
Definition: mldsa.c:51
X509EcPublicKey ecPublicKey
Definition: x509_common.h:892
error_t asn1WriteInt32(int32_t value, bool_t reverse, uint8_t *data, size_t *written)
Write a 32-bit integer to the output stream.
Definition: asn1.c:781
DSA public key.
Definition: x509_common.h:838
ML-DSA public key.
Definition: x509_common.h:868
const EcCurve * curve
Elliptic curve parameters.
Definition: ec.h:422
error_t x509FormatSubjectPublicKey(const X509SubjectPublicKeyInfo *publicKeyInfo, const void *publicKey, uint8_t *keyId, uint8_t *output, size_t *written)
Format SubjectPublicKey structure.
const uint8_t * value
Definition: asn1.h:110
@ ERROR_INVALID_KEY
Definition: error.h:106
@ NO_ERROR
Success.
Definition: error.h:44
Debugging facilities.
uint_t objType
Definition: asn1.h:108
ASN.1 (Abstract Syntax Notation One)
X509OctetString pk
Definition: x509_common.h:869
@ ASN1_TYPE_NULL
Definition: asn1.h:76