x509_key_parse.c
Go to the documentation of this file.
1 /**
2  * @file x509_key_parse.c
3  * @brief Parsing 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_parse.h"
37 #include "encoding/asn1.h"
38 #include "encoding/oid.h"
39 #include "ecc/eddsa.h"
40 #include "ecc/ec_misc.h"
41 #include "debug.h"
42 
43 //Check crypto library configuration
44 #if (X509_SUPPORT == ENABLED || PEM_SUPPORT == ENABLED)
45 
46 
47 /**
48  * @brief Parse SubjectPublicKeyInfo structure
49  * @param[in] data Pointer to the ASN.1 structure to parse
50  * @param[in] length Length of the ASN.1 structure
51  * @param[out] totalLength Number of bytes that have been parsed
52  * @param[out] publicKeyInfo Information resulting from the parsing process
53  * @return Error code
54  **/
55 
57  size_t *totalLength, X509SubjectPublicKeyInfo *publicKeyInfo)
58 {
59  error_t error;
60  size_t n;
61  size_t oidLen;
62  const uint8_t *oid;
63  Asn1Tag tag;
64 
65  //Debug message
66  TRACE_DEBUG(" Parsing SubjectPublicKeyInfo...\r\n");
67 
68  //Clear the SubjectPublicKeyInfo structure
69  osMemset(publicKeyInfo, 0, sizeof(X509SubjectPublicKeyInfo));
70 
71  //The public key information is encapsulated within a sequence
72  error = asn1ReadSequence(data, length, &tag);
73  //Failed to decode ASN.1 tag?
74  if(error)
75  return error;
76 
77  //Save the total length of the field
78  *totalLength = tag.totalLength;
79 
80  //Raw contents of the ASN.1 sequence
81  publicKeyInfo->raw.value = data;
82  publicKeyInfo->raw.length = tag.totalLength;
83 
84  //Point to the first field of the sequence
85  data = tag.value;
86  length = tag.length;
87 
88  //Read AlgorithmIdentifier field
89  error = x509ParseAlgoId(data, length, &n, publicKeyInfo);
90  //Any error to report?
91  if(error)
92  return error;
93 
94  //Point to the next field
95  data += n;
96  length -= n;
97 
98  //The SubjectPublicKey is encapsulated within a bit string
99  error = asn1ReadTag(data, length, &tag);
100  //Failed to decode ASN.1 tag?
101  if(error)
102  return error;
103 
104  //Enforce encoding, class and type
105  error = asn1CheckTag(&tag, FALSE, ASN1_CLASS_UNIVERSAL,
107  //Invalid tag?
108  if(error)
109  return error;
110 
111  //The bit string shall contain an initial octet which encodes the number
112  //of unused bits in the final subsequent octet
113  if(tag.length < 1 || tag.value[0] != 0x00)
114  return ERROR_FAILURE;
115 
116  //Point to the public key
117  data = tag.value + 1;
118  length = tag.length - 1;
119 
120  //Raw contents of the SubjectPublicKey (excluding the tag, length, and
121  //number of unused bits)
122  publicKeyInfo->rawSubjectPublicKey.value = data;
123  publicKeyInfo->rawSubjectPublicKey.length = length;
124 
125  //Get the public key algorithm identifier
126  oid = publicKeyInfo->oid.value;
127  oidLen = publicKeyInfo->oid.length;
128 
129 #if (RSA_SUPPORT == ENABLED)
130  //RSA or RSA-PSS algorithm identifier?
131  if(OID_COMP(oid, oidLen, RSA_ENCRYPTION_OID) == 0 ||
133  {
134  //Read RSAPublicKey structure
136  &publicKeyInfo->rsaPublicKey);
137  }
138  else
139 #endif
140 #if (DSA_SUPPORT == ENABLED)
141  //DSA algorithm identifier?
142  if(OID_COMP(oid, oidLen, DSA_OID) == 0)
143  {
144  //Read DSAPublicKey structure
146  &publicKeyInfo->dsaPublicKey);
147  }
148  else
149 #endif
150 #if (EC_SUPPORT == ENABLED)
151  //EC public key identifier?
153  {
154  //Read ECPublicKey structure
156  &publicKeyInfo->ecPublicKey);
157  }
158  else
159 #endif
160 #if (ED25519_SUPPORT == ENABLED)
161  //X25519 or Ed25519 algorithm identifier?
162  if(OID_COMP(oid, oidLen, X25519_OID) == 0 ||
163  OID_COMP(oid, oidLen, ED25519_OID) == 0)
164  {
165  //Read ECPublicKey structure
167  &publicKeyInfo->ecPublicKey);
168  }
169  else
170 #endif
171 #if (ED448_SUPPORT == ENABLED)
172  //X448 or Ed448 algorithm identifier?
173  if(OID_COMP(oid, oidLen, X448_OID) == 0 ||
174  OID_COMP(oid, oidLen, ED448_OID) == 0)
175  {
176  //Read ECPublicKey structure
178  &publicKeyInfo->ecPublicKey);
179  }
180  else
181 #endif
182 #if (MLDSA44_SUPPORT == ENABLED)
183  //ML-DSA-44 algorithm identifier?
184  if(OID_COMP(oid, oidLen, MLDSA44_OID) == 0)
185  {
186  //Read ML-DSA-44-PublicKey structure
188  &publicKeyInfo->mldsaPublicKey);
189  }
190  else
191 #endif
192 #if (MLDSA65_SUPPORT == ENABLED)
193  //ML-DSA-65 algorithm identifier?
194  if(OID_COMP(oid, oidLen, MLDSA65_OID) == 0)
195  {
196  //Read ML-DSA-65-PublicKey structure
198  &publicKeyInfo->mldsaPublicKey);
199  }
200  else
201 #endif
202 #if (MLDSA87_SUPPORT == ENABLED)
203  //ML-DSA-87 algorithm identifier?
204  if(OID_COMP(oid, oidLen, MLDSA87_OID) == 0)
205  {
206  //Read ML-DSA-87-PublicKey structure
208  &publicKeyInfo->mldsaPublicKey);
209  }
210  else
211 #endif
212  //Unknown algorithm identifier?
213  {
214  //Report an error
215  error = ERROR_WRONG_IDENTIFIER;
216  }
217 
218  //Return status code
219  return error;
220 }
221 
222 
223 /**
224  * @brief Parse AlgorithmIdentifier structure
225  * @param[in] data Pointer to the ASN.1 structure to parse
226  * @param[in] length Length of the ASN.1 structure
227  * @param[out] totalLength Number of bytes that have been parsed
228  * @param[out] publicKeyInfo Information resulting from the parsing process
229  * @return Error code
230  **/
231 
232 error_t x509ParseAlgoId(const uint8_t *data, size_t length,
233  size_t *totalLength, X509SubjectPublicKeyInfo *publicKeyInfo)
234 {
235  error_t error;
236  Asn1Tag tag;
237 
238  //Debug message
239  TRACE_DEBUG(" Parsing AlgorithmIdentifier...\r\n");
240 
241  //Read AlgorithmIdentifier field
242  error = asn1ReadSequence(data, length, &tag);
243  //Failed to decode ASN.1 tag?
244  if(error)
245  return error;
246 
247  //Save the total length of the field
248  *totalLength = tag.totalLength;
249 
250  //Point to the first field
251  data = tag.value;
252  length = tag.length;
253 
254  //Read algorithm identifier (OID)
255  error = asn1ReadOid(data, length, &tag);
256  //Failed to decode ASN.1 tag?
257  if(error)
258  return error;
259 
260  //Save the algorithm identifier
261  publicKeyInfo->oid.value = tag.value;
262  publicKeyInfo->oid.length = tag.length;
263 
264  //Point to the next field (if any)
265  data += tag.totalLength;
266  length -= tag.totalLength;
267 
268 #if (RSA_SUPPORT == ENABLED)
269  //RSA algorithm identifier?
271  {
272  //The parameters field must have ASN.1 type NULL for this algorithm
273  //identifier (refer to RFC 3279, section 2.3.1)
274  error = NO_ERROR;
275  }
276  //RSA-PSS algorithm identifier?
277  else if(!asn1CheckOid(&tag, RSASSA_PSS_OID, sizeof(RSASSA_PSS_OID)))
278  {
279  //The parameters may be either absent or present when used as subject
280  //public key information (refer to RFC 4055, section 3.1)
281  error = NO_ERROR;
282  }
283  else
284 #endif
285 #if (DSA_SUPPORT == ENABLED)
286  //DSA algorithm identifier?
287  if(!asn1CheckOid(&tag, DSA_OID, sizeof(DSA_OID)))
288  {
289  //Read DsaParameters structure
290  error = x509ParseDsaParameters(data, length, &publicKeyInfo->dsaParams);
291  }
292  else
293 #endif
294 #if (EC_SUPPORT == ENABLED)
295  //EC public key identifier?
297  {
298  //Read ECParameters structure
299  error = x509ParseEcParameters(data, length, &publicKeyInfo->ecParams);
300  }
301  else
302 #endif
303 #if (ED25519_SUPPORT == ENABLED)
304  //X25519 or Ed25519 algorithm identifier?
305  if(!asn1CheckOid(&tag, X25519_OID, sizeof(X25519_OID)) ||
306  !asn1CheckOid(&tag, ED25519_OID, sizeof(ED25519_OID)))
307  {
308  //For all of the OIDs, the parameters must be absent (refer to RFC 8410,
309  //section 3)
310  error = NO_ERROR;
311  }
312  else
313 #endif
314 #if (ED448_SUPPORT == ENABLED)
315  //X448 or Ed448 algorithm identifier?
316  if(!asn1CheckOid(&tag, X448_OID, sizeof(X448_OID)) ||
317  !asn1CheckOid(&tag, ED448_OID, sizeof(ED448_OID)))
318  {
319  //For all of the OIDs, the parameters must be absent (refer to RFC 8410,
320  //section 3)
321  error = NO_ERROR;
322  }
323  else
324 #endif
325 #if (MLDSA44_SUPPORT == ENABLED)
326  //ML-DSA-44 algorithm identifier?
327  if(!asn1CheckOid(&tag, MLDSA44_OID, sizeof(MLDSA44_OID)))
328  {
329  //The contents of the parameters component must be absent (refer to
330  //RFC 9881, section 2)
331  error = NO_ERROR;
332  }
333  else
334 #endif
335 #if (MLDSA65_SUPPORT == ENABLED)
336  //ML-DSA-65 algorithm identifier?
337  if(!asn1CheckOid(&tag, MLDSA65_OID, sizeof(MLDSA65_OID)))
338  {
339  //The contents of the parameters component must be absent (refer to
340  //RFC 9881, section 2)
341  error = NO_ERROR;
342  }
343  else
344 #endif
345 #if (MLDSA87_SUPPORT == ENABLED)
346  //ML-DSA-87 algorithm identifier?
347  if(!asn1CheckOid(&tag, MLDSA87_OID, sizeof(MLDSA87_OID)))
348  {
349  //The contents of the parameters component must be absent (refer to
350  //RFC 9881, section 2)
351  error = NO_ERROR;
352  }
353  else
354 #endif
355  //Unknown algorithm identifier?
356  {
357  //Report an error
358  error = ERROR_WRONG_IDENTIFIER;
359  }
360 
361  //Return status code
362  return error;
363 }
364 
365 
366 /**
367  * @brief Parse RSAPublicKey structure
368  * @param[in] data Pointer to the ASN.1 structure to parse
369  * @param[in] length Length of the ASN.1 structure
370  * @param[out] rsaPublicKey Information resulting from the parsing process
371  * @return Error code
372  **/
373 
374 error_t x509ParseRsaPublicKey(const uint8_t *data, size_t length,
375  X509RsaPublicKey *rsaPublicKey)
376 {
377  error_t error;
378  Asn1Tag tag;
379 
380  //Debug message
381  TRACE_DEBUG(" Parsing RSAPublicKey...\r\n");
382 
383  //Read RSAPublicKey structure
384  error = asn1ReadSequence(data, length, &tag);
385  //Failed to decode ASN.1 tag?
386  if(error)
387  return error;
388 
389  //Point to the first field
390  data = tag.value;
391  length = tag.length;
392 
393  //Read Modulus field
394  error = asn1ReadTag(data, length, &tag);
395  //Failed to decode ASN.1 tag?
396  if(error)
397  return error;
398 
399  //Enforce encoding, class and type
401  //Invalid tag?
402  if(error)
403  return error;
404 
405  //Save the modulus
406  rsaPublicKey->n.value = tag.value;
407  rsaPublicKey->n.length = tag.length;
408 
409  //Point to the next field
410  data += tag.totalLength;
411  length -= tag.totalLength;
412 
413  //Read PublicExponent field
414  error = asn1ReadTag(data, length, &tag);
415  //Failed to decode ASN.1 tag?
416  if(error)
417  return error;
418 
419  //Enforce encoding, class and type
421  //Invalid tag?
422  if(error)
423  return error;
424 
425  //Save the public exponent
426  rsaPublicKey->e.value = tag.value;
427  rsaPublicKey->e.length = tag.length;
428 
429  //Successful processing
430  return NO_ERROR;
431 }
432 
433 
434 /**
435  * @brief Parse DSAPublicKey structure
436  * @param[in] data Pointer to the ASN.1 structure to parse
437  * @param[in] length Length of the ASN.1 structure
438  * @param[out] dsaPublicKey Information resulting from the parsing process
439  * @return Error code
440  **/
441 
442 error_t x509ParseDsaPublicKey(const uint8_t *data, size_t length,
443  X509DsaPublicKey *dsaPublicKey)
444 {
445  error_t error;
446  Asn1Tag tag;
447 
448  //Debug message
449  TRACE_DEBUG(" Parsing DSAPublicKey...\r\n");
450 
451  //Read DSAPublicKey structure
452  error = asn1ReadTag(data, length, &tag);
453  //Failed to decode ASN.1 tag?
454  if(error)
455  return error;
456 
457  //Enforce encoding, class and type
459  //Invalid tag?
460  if(error)
461  return error;
462 
463  //Save the DSA public value
464  dsaPublicKey->y.value = tag.value;
465  dsaPublicKey->y.length = tag.length;
466 
467  //Successful processing
468  return NO_ERROR;
469 }
470 
471 
472 /**
473  * @brief Parse DSA domain parameters
474  * @param[in] data Pointer to the ASN.1 structure to parse
475  * @param[in] length Length of the ASN.1 structure
476  * @param[out] dsaParams Information resulting from the parsing process
477  * @return Error code
478  **/
479 
480 error_t x509ParseDsaParameters(const uint8_t *data, size_t length,
481  X509DsaParameters *dsaParams)
482 {
483  error_t error;
484  Asn1Tag tag;
485 
486  //Debug message
487  TRACE_DEBUG(" Parsing DSAParameters...\r\n");
488 
489  //Read DSAParameters structure
490  error = asn1ReadSequence(data, length, &tag);
491  //Failed to decode ASN.1 tag?
492  if(error)
493  return error;
494 
495  //Point to the first field
496  data = tag.value;
497  length = tag.length;
498 
499  //Read the parameter p
500  error = asn1ReadTag(data, length, &tag);
501  //Failed to decode ASN.1 tag?
502  if(error)
503  return error;
504 
505  //Enforce encoding, class and type
507  //Invalid tag?
508  if(error)
509  return error;
510 
511  //Save the parameter p
512  dsaParams->p.value = tag.value;
513  dsaParams->p.length = tag.length;
514 
515  //Point to the next field
516  data += tag.totalLength;
517  length -= tag.totalLength;
518 
519  //Read the parameter q
520  error = asn1ReadTag(data, length, &tag);
521  //Failed to decode ASN.1 tag?
522  if(error)
523  return error;
524 
525  //Enforce encoding, class and type
527  //Invalid tag?
528  if(error)
529  return error;
530 
531  //Save the parameter q
532  dsaParams->q.value = tag.value;
533  dsaParams->q.length = tag.length;
534 
535  //Point to the next field
536  data += tag.totalLength;
537  length -= tag.totalLength;
538 
539  //Read the parameter g
540  error = asn1ReadTag(data, length, &tag);
541  //Failed to decode ASN.1 tag?
542  if(error)
543  return error;
544 
545  //Enforce encoding, class and type
547  //Invalid tag?
548  if(error)
549  return error;
550 
551  //Save the parameter g
552  dsaParams->g.value = tag.value;
553  dsaParams->g.length = tag.length;
554 
555  //Successful processing
556  return NO_ERROR;
557 }
558 
559 
560 /**
561  * @brief Parse ECPublicKey structure
562  * @param[in] data Pointer to the ASN.1 structure to parse
563  * @param[in] length Length of the ASN.1 structure
564  * @param[out] ecPublicKey Information resulting from the parsing process
565  * @return Error code
566  **/
567 
568 error_t x509ParseEcPublicKey(const uint8_t *data, size_t length,
569  X509EcPublicKey *ecPublicKey)
570 {
571  //Debug message
572  TRACE_DEBUG(" Parsing ECPublicKey...\r\n");
573 
574  //Make sure the EC public key is valid
575  if(length == 0)
576  return ERROR_BAD_CERTIFICATE;
577 
578  //Save the EC public key
579  ecPublicKey->q.value = data;
580  ecPublicKey->q.length = length;
581 
582  //Successful processing
583  return NO_ERROR;
584 }
585 
586 
587 /**
588  * @brief Parse ECParameters structure
589  * @param[in] data Pointer to the ASN.1 structure to parse
590  * @param[in] length Length of the ASN.1 structure
591  * @param[out] ecParams Information resulting from the parsing process
592  * @return Error code
593  **/
594 
595 error_t x509ParseEcParameters(const uint8_t *data, size_t length,
596  X509EcParameters *ecParams)
597 {
598  error_t error;
599  Asn1Tag tag;
600 
601  //Debug message
602  TRACE_DEBUG(" Parsing ECParameters...\r\n");
603 
604  //Read namedCurve field
605  error = asn1ReadOid(data, length, &tag);
606  //Failed to decode ASN.1 tag?
607  if(error)
608  return error;
609 
610  //The namedCurve field identifies all the required values for a particular
611  //set of elliptic curve domain parameters to be represented by an object
612  //identifier
613  ecParams->namedCurve.value = tag.value;
614  ecParams->namedCurve.length = tag.length;
615 
616  //Successful processing
617  return NO_ERROR;
618 }
619 
620 
621 /**
622  * @brief Parse ML-DSA-PublicKey structure
623  * @param[in] data Pointer to the ASN.1 structure to parse
624  * @param[in] length Length of the ASN.1 structure
625  * @param[out] mldsaPublicKey Information resulting from the parsing process
626  * @return Error code
627  **/
628 
629 
631  X509MldsaPublicKey *mldsaPublicKey)
632 {
633  //Debug message
634  TRACE_DEBUG(" Parsing ML-DSA-PublicKey...\r\n");
635 
636  //Make sure the ML-DSA public key is valid
640  {
641  return ERROR_BAD_CERTIFICATE;
642  }
643 
644  //Save the ML-DSA public key
645  mldsaPublicKey->pk.value = data;
646  mldsaPublicKey->pk.length = length;
647 
648  //Successful processing
649  return NO_ERROR;
650 }
651 
652 
653 /**
654  * @brief Import an RSA public key
655  * @param[out] publicKey RSA public key
656  * @param[in] publicKeyInfo Public key information
657  * @return Error code
658  **/
659 
661  const X509SubjectPublicKeyInfo *publicKeyInfo)
662 {
663  error_t error;
664 
665 #if (RSA_SUPPORT == ENABLED)
666  const uint8_t *oid;
667  size_t oidLen;
668 
669  //Get the public key algorithm identifier
670  oid = publicKeyInfo->oid.value;
671  oidLen = publicKeyInfo->oid.length;
672 
673  //RSA algorithm identifier?
674  if(OID_COMP(oid, oidLen, RSA_ENCRYPTION_OID) == 0 ||
676  {
677  //Sanity check
678  if(publicKeyInfo->rsaPublicKey.n.value != NULL &&
679  publicKeyInfo->rsaPublicKey.e.value != NULL)
680  {
681  //Read modulus
682  error = mpiImport(&publicKey->n, publicKeyInfo->rsaPublicKey.n.value,
683  publicKeyInfo->rsaPublicKey.n.length, MPI_FORMAT_BIG_ENDIAN);
684 
685  //Check status code
686  if(!error)
687  {
688  //Read public exponent
689  error = mpiImport(&publicKey->e, publicKeyInfo->rsaPublicKey.e.value,
690  publicKeyInfo->rsaPublicKey.e.length, MPI_FORMAT_BIG_ENDIAN);
691  }
692 
693  //Check status code
694  if(!error)
695  {
696  //Debug message
697  TRACE_DEBUG("RSA public key:\r\n");
698  TRACE_DEBUG(" Modulus:\r\n");
699  TRACE_DEBUG_MPI(" ", &publicKey->n);
700  TRACE_DEBUG(" Public exponent:\r\n");
701  TRACE_DEBUG_MPI(" ", &publicKey->e);
702  }
703  }
704  else
705  {
706  //The public key is not valid
707  error = ERROR_INVALID_KEY;
708  }
709  }
710  else
711 #endif
712  //Invalid algorithm identifier?
713  {
714  //Report an error
715  error = ERROR_WRONG_IDENTIFIER;
716  }
717 
718  //Return status code
719  return error;
720 }
721 
722 
723 /**
724  * @brief Import a DSA public key
725  * @param[out] publicKey DSA public key
726  * @param[in] publicKeyInfo Public key information
727  * @return Error code
728  **/
729 
731  const X509SubjectPublicKeyInfo *publicKeyInfo)
732 {
733  error_t error;
734 
735 #if (DSA_SUPPORT == ENABLED)
736  //DSA algorithm identifier?
737  if(OID_COMP(publicKeyInfo->oid.value, publicKeyInfo->oid.length,
738  DSA_OID) == 0)
739  {
740  //Sanity check
741  if(publicKeyInfo->dsaParams.p.value != NULL &&
742  publicKeyInfo->dsaParams.q.value != NULL &&
743  publicKeyInfo->dsaParams.g.value != NULL &&
744  publicKeyInfo->dsaPublicKey.y.value != NULL)
745  {
746  //Read parameter p
747  error = mpiImport(&publicKey->params.p,
748  publicKeyInfo->dsaParams.p.value,
749  publicKeyInfo->dsaParams.p.length, MPI_FORMAT_BIG_ENDIAN);
750 
751  //Check status code
752  if(!error)
753  {
754  //Read parameter q
755  error = mpiImport(&publicKey->params.q,
756  publicKeyInfo->dsaParams.q.value,
757  publicKeyInfo->dsaParams.q.length, MPI_FORMAT_BIG_ENDIAN);
758  }
759 
760  //Check status code
761  if(!error)
762  {
763  //Read parameter g
764  error = mpiImport(&publicKey->params.g,
765  publicKeyInfo->dsaParams.g.value,
766  publicKeyInfo->dsaParams.g.length, MPI_FORMAT_BIG_ENDIAN);
767  }
768 
769  //Check status code
770  if(!error)
771  {
772  //Read public value
773  error = mpiImport(&publicKey->y,
774  publicKeyInfo->dsaPublicKey.y.value,
775  publicKeyInfo->dsaPublicKey.y.length, MPI_FORMAT_BIG_ENDIAN);
776  }
777 
778  //Check status code
779  if(!error)
780  {
781  //Debug message
782  TRACE_DEBUG("DSA public key:\r\n");
783  TRACE_DEBUG(" Parameter p:\r\n");
784  TRACE_DEBUG_MPI(" ", &publicKey->params.p);
785  TRACE_DEBUG(" Parameter q:\r\n");
786  TRACE_DEBUG_MPI(" ", &publicKey->params.q);
787  TRACE_DEBUG(" Parameter g:\r\n");
788  TRACE_DEBUG_MPI(" ", &publicKey->params.g);
789  TRACE_DEBUG(" Public value y:\r\n");
790  TRACE_DEBUG_MPI(" ", &publicKey->y);
791  }
792  }
793  else
794  {
795  //The public key is not valid
796  error = ERROR_INVALID_KEY;
797  }
798  }
799  else
800 #endif
801  //Invalid algorithm identifier?
802  {
803  //Report an error
804  error = ERROR_WRONG_IDENTIFIER;
805  }
806 
807  //Return status code
808  return error;
809 }
810 
811 
812 /**
813  * @brief Import an EC public key
814  * @param[out] publicKey EC public key
815  * @param[in] publicKeyInfo Public key information
816  * @return Error code
817  **/
818 
820  const X509SubjectPublicKeyInfo *publicKeyInfo)
821 {
822  error_t error;
823 
824 #if (EC_SUPPORT == ENABLED)
825  //EC public key identifier?
826  if(OID_COMP(publicKeyInfo->oid.value, publicKeyInfo->oid.length,
827  EC_PUBLIC_KEY_OID) == 0)
828  {
829  //Sanity check
830  if(publicKeyInfo->ecParams.namedCurve.value != NULL &&
831  publicKeyInfo->ecPublicKey.q.value != NULL)
832  {
833  const EcCurve *curve;
834 
835  //Get the elliptic curve that matches the OID
836  curve = ecGetCurve(publicKeyInfo->ecParams.namedCurve.value,
837  publicKeyInfo->ecParams.namedCurve.length);
838 
839  //Make sure the specified elliptic curve is supported
840  if(curve != NULL)
841  {
842  //Read the EC public key
843  error = ecImportPublicKey(publicKey, curve,
844  publicKeyInfo->ecPublicKey.q.value,
846  }
847  else
848  {
849  //Invalid elliptic curve
850  error = ERROR_WRONG_IDENTIFIER;
851  }
852 
853  //Check status code
854  if(!error)
855  {
856  //Dump EC public key
857  TRACE_DEBUG("EC public key X:\r\n");
858  TRACE_DEBUG_EC_SCALAR(" ", publicKey->q.x, (curve->fieldSize + 31) / 32);
859  TRACE_DEBUG("EC public key Y:\r\n");
860  TRACE_DEBUG_EC_SCALAR(" ", publicKey->q.y, (curve->fieldSize + 31) / 32);
861  }
862  }
863  else
864  {
865  //The public key is not valid
866  error = ERROR_INVALID_KEY;
867  }
868  }
869  else
870 #endif
871  //Invalid algorithm identifier?
872  {
873  //Report an error
874  error = ERROR_WRONG_IDENTIFIER;
875  }
876 
877  //Return status code
878  return error;
879 }
880 
881 
882 /**
883  * @brief Import an EdDSA public key
884  * @param[out] publicKey EdDSA public key
885  * @param[in] publicKeyInfo Public key information
886  * @return Error code
887  **/
888 
890  const X509SubjectPublicKeyInfo *publicKeyInfo)
891 {
892 #if (ED25519_SUPPORT == ENABLED || ED448_SUPPORT == ENABLED)
893  error_t error;
894  const EcCurve *curve;
895 
896  //Get the elliptic curve that matches the OID
897  curve = ecGetCurve(publicKeyInfo->oid.value, publicKeyInfo->oid.length);
898 
899  //Edwards elliptic curve?
900  if(curve != NULL && curve->type == EC_CURVE_TYPE_EDWARDS)
901  {
902  //Read the EdDSA public key
903  error = eddsaImportPublicKey(publicKey, curve,
904  publicKeyInfo->ecPublicKey.q.value,
905  publicKeyInfo->ecPublicKey.q.length);
906  }
907  else
908  {
909  //Report an error
910  error = ERROR_WRONG_IDENTIFIER;
911  }
912 
913  //Check status code
914  if(!error)
915  {
916  //Dump EdDSA public key
917  TRACE_DEBUG("EdDSA public key:\r\n");
918  TRACE_DEBUG_ARRAY(" ", publicKey->q, publicKeyInfo->ecPublicKey.q.length);
919  }
920 
921  //Return status code
922  return error;
923 #else
924  //Not implemented
925  return ERROR_NOT_IMPLEMENTED;
926 #endif
927 }
928 
929 
930 /**
931  * @brief Import an ML-DSA public key
932  * @param[out] publicKey ML-DSA public key
933  * @param[in] publicKeyInfo Public key information
934  * @return Error code
935  **/
936 
938  const X509SubjectPublicKeyInfo *publicKeyInfo)
939 {
940 #if (MLDSA44_SUPPORT == ENABLED || MLDSA65_SUPPORT == ENABLED || \
941  MLDSA87_SUPPORT == ENABLED)
942  error_t error;
943  uint_t level;
944 
945  //Initialize status code
946  error = NO_ERROR;
947 
948  //Check algorithm identifier
949  if(OID_COMP(publicKeyInfo->oid.value, publicKeyInfo->oid.length,
950  MLDSA44_OID) == 0)
951  {
952  //ML-DSA-44
953  level = MLDSA44_SECURITY_LEVEL;
954  }
955  else if(OID_COMP(publicKeyInfo->oid.value, publicKeyInfo->oid.length,
956  MLDSA65_OID) == 0)
957  {
958  //ML-DSA-65
959  level = MLDSA65_SECURITY_LEVEL;
960  }
961  else if(OID_COMP(publicKeyInfo->oid.value, publicKeyInfo->oid.length,
962  MLDSA87_OID) == 0)
963  {
964  //ML-DSA-87
965  level = MLDSA87_SECURITY_LEVEL;
966  }
967  else
968  {
969  //Invalid algorithm identifier
970  error = ERROR_WRONG_IDENTIFIER;
971  }
972 
973  //Check status code
974  if(!error)
975  {
976  //Read the ML-DSA public key
977  error = mldsaImportPublicKey(publicKey, level,
978  publicKeyInfo->mldsaPublicKey.pk.value,
979  publicKeyInfo->mldsaPublicKey.pk.length);
980  }
981 
982  //Check status code
983  if(!error)
984  {
985  //Dump ML-DSA public key
986  TRACE_DEBUG("ML-DSA public key:\r\n");
987  TRACE_DEBUG_ARRAY(" ", publicKey->pk, publicKeyInfo->mldsaPublicKey.pk.length);
988  }
989 
990  //Return status code
991  return error;
992 #else
993  //Not implemented
994  return ERROR_NOT_IMPLEMENTED;
995 #endif
996 }
997 
998 #endif
const uint8_t MLDSA44_OID[9]
Definition: mldsa.c:47
@ EC_CURVE_TYPE_EDWARDS
Definition: ec.h:364
error_t x509ImportEcPublicKey(EcPublicKey *publicKey, const X509SubjectPublicKeyInfo *publicKeyInfo)
Import an EC public key.
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
error_t x509ParseSubjectPublicKeyInfo(const uint8_t *data, size_t length, size_t *totalLength, X509SubjectPublicKeyInfo *publicKeyInfo)
Parse SubjectPublicKeyInfo structure.
OID (Object Identifier)
Mpi q
Group order.
Definition: dsa.h:51
X509OctetString oid
Definition: x509_common.h:880
uint8_t data[]
Definition: ethernet.h:224
const uint8_t EC_PUBLIC_KEY_OID[7]
Definition: ec.c:44
error_t ecImportPublicKey(EcPublicKey *key, const EcCurve *curve, const uint8_t *input, size_t length, EcPublicKeyFormat format)
Import an EC public key.
Definition: ec.c:263
X509EcParameters ecParams
Definition: x509_common.h:891
error_t x509ParseRsaPublicKey(const uint8_t *data, size_t length, X509RsaPublicKey *rsaPublicKey)
Parse RSAPublicKey structure.
#define TRACE_DEBUG_EC_SCALAR(p, a, n)
Definition: debug.h:123
#define MLDSA87_SECURITY_LEVEL
Definition: mldsa.h:61
@ EC_PUBLIC_KEY_FORMAT_X963
Definition: ec.h:386
uint16_t totalLength
Definition: ipv4.h:348
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
error_t asn1ReadTag(const uint8_t *data, size_t length, Asn1Tag *tag)
Read an ASN.1 tag from the input stream.
Definition: asn1.c:52
error_t x509ImportDsaPublicKey(DsaPublicKey *publicKey, const X509SubjectPublicKeyInfo *publicKeyInfo)
Import a DSA public key.
uint32_t y[EC_MAX_MODULUS_SIZE]
y-coordinate
Definition: ec.h:400
#define MLDSA65_SECURITY_LEVEL
Definition: mldsa.h:50
error_t x509ParseDsaParameters(const uint8_t *data, size_t length, X509DsaParameters *dsaParams)
Parse DSA domain parameters.
uint8_t oid[]
Definition: lldp_tlv.h:300
Mpi n
Modulus.
Definition: rsa.h:58
X509OctetString q
Definition: x509_common.h:828
error_t asn1ReadOid(const uint8_t *data, size_t length, Asn1Tag *tag)
Read an object identifier from the input stream.
Definition: asn1.c:218
EC public key.
Definition: x509_common.h:858
const uint8_t DSA_OID[7]
Definition: dsa.c:51
size_t totalLength
Definition: asn1.h:111
size_t length
Definition: asn1.h:109
X509OctetString y
Definition: x509_common.h:839
#define MLDSA44_SECURITY_LEVEL
Definition: mldsa.h:39
#define FALSE
Definition: os_port.h:46
ML-DSA public key.
Definition: mldsa.h:82
uint8_t q[EDDSA_MAX_PUBLIC_KEY_LEN]
Public key.
Definition: eddsa.h:66
DSA public key.
Definition: dsa.h:61
error_t
Error codes.
Definition: error.h:43
Mpi g
Group generator.
Definition: dsa.h:52
EC parameters.
Definition: x509_common.h:848
error_t x509ParseMldsaPublicKey(const uint8_t *data, size_t length, X509MldsaPublicKey *mldsaPublicKey)
Parse ML-DSA-PublicKey structure.
EdDSA public key.
Definition: eddsa.h:64
#define ASN1_CLASS_UNIVERSAL
Definition: asn1.h:52
RSA public key.
Definition: x509_common.h:815
@ ERROR_FAILURE
Generic error code.
Definition: error.h:45
ASN.1 tag.
Definition: asn1.h:105
Helper routines for ECC.
RSA public key.
Definition: rsa.h:57
error_t mpiImport(Mpi *r, const uint8_t *input, size_t length, MpiFormat format)
Octet string to integer conversion.
Definition: mpi.c:714
X509RsaPublicKey rsaPublicKey
Definition: x509_common.h:883
X509MldsaPublicKey mldsaPublicKey
Definition: x509_common.h:896
EdDSA (Edwards-Curve Digital Signature Algorithm)
error_t x509ImportEddsaPublicKey(EddsaPublicKey *publicKey, const X509SubjectPublicKeyInfo *publicKeyInfo)
Import an EdDSA public key.
General definitions for cryptographic algorithms.
X509OctetString raw
Definition: x509_common.h:879
@ ERROR_BAD_CERTIFICATE
Definition: error.h:236
error_t x509ParseAlgoId(const uint8_t *data, size_t length, size_t *totalLength, X509SubjectPublicKeyInfo *publicKeyInfo)
Parse AlgorithmIdentifier structure.
DsaDomainParameters params
DSA domain parameters.
Definition: dsa.h:62
#define MLDSA44_PUBLIC_KEY_LEN
Definition: mldsa.h:45
X509DsaParameters dsaParams
Definition: x509_common.h:886
uint8_t length
Definition: tcp.h:375
error_t asn1CheckOid(const Asn1Tag *tag, const uint8_t *oid, size_t length)
Check ASN.1 tag against a specified OID.
Definition: asn1.c:972
X509OctetString namedCurve
Definition: x509_common.h:849
const uint8_t ED448_OID[3]
Definition: ec_curves.c:114
error_t x509ImportMldsaPublicKey(MldsaPublicKey *publicKey, const X509SubjectPublicKeyInfo *publicKeyInfo)
Import an ML-DSA public key.
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_INTEGER
Definition: asn1.h:73
#define TRACE_DEBUG(...)
Definition: debug.h:119
#define TRACE_DEBUG_ARRAY(p, a, n)
Definition: debug.h:120
X509OctetString q
Definition: x509_common.h:859
#define OID_COMP(oid1, oidLen1, oid2)
Definition: oid.h:42
error_t x509ImportRsaPublicKey(RsaPublicKey *publicKey, const X509SubjectPublicKeyInfo *publicKeyInfo)
Import an RSA public key.
uint8_t n
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 MLDSA65_PUBLIC_KEY_LEN
Definition: mldsa.h:56
EcPoint q
Public key.
Definition: ec.h:423
uint8_t oidLen
Definition: lldp_tlv.h:299
@ MPI_FORMAT_BIG_ENDIAN
Definition: mpi.h:93
Mpi y
Public key value.
Definition: dsa.h:63
@ ERROR_WRONG_IDENTIFIER
Definition: error.h:89
X509OctetString rawSubjectPublicKey
Definition: x509_common.h:881
error_t x509ParseEcParameters(const uint8_t *data, size_t length, X509EcParameters *ecParams)
Parse ECParameters structure.
const EcCurve * ecGetCurve(const uint8_t *oid, size_t length)
Get the elliptic curve that matches the specified OID.
Definition: ec_curves.c:5888
uint8_t * pk
Public key.
Definition: mldsa.h:84
const uint8_t * value
Definition: x509_common.h:732
error_t eddsaImportPublicKey(EddsaPublicKey *key, const EcCurve *curve, const uint8_t *input, size_t length)
Import an EdDSA public key.
Definition: eddsa.c:275
#define EcCurve
Definition: ec.h:346
Parsing of ASN.1 encoded keys.
@ ASN1_TYPE_BIT_STRING
Definition: asn1.h:74
error_t x509ParseDsaPublicKey(const uint8_t *data, size_t length, X509DsaPublicKey *dsaPublicKey)
Parse DSAPublicKey structure.
unsigned int uint_t
Definition: compiler_port.h:57
uint32_t x[EC_MAX_MODULUS_SIZE]
x-coordinate
Definition: ec.h:399
#define TRACE_DEBUG_MPI(p, a)
Definition: debug.h:122
const uint8_t MLDSA87_OID[9]
Definition: mldsa.c:51
#define osMemset(p, value, length)
Definition: os_port.h:141
error_t asn1ReadSequence(const uint8_t *data, size_t length, Asn1Tag *tag)
Read an ASN.1 sequence from the input stream.
Definition: asn1.c:163
X509EcPublicKey ecPublicKey
Definition: x509_common.h:892
DSA public key.
Definition: x509_common.h:838
ML-DSA public key.
Definition: x509_common.h:868
error_t mldsaImportPublicKey(MldsaPublicKey *key, uint_t level, const uint8_t *input, size_t length)
Import an ML-DSA public key.
Definition: mldsa.c:144
const uint8_t * value
Definition: asn1.h:110
#define MLDSA87_PUBLIC_KEY_LEN
Definition: mldsa.h:67
error_t asn1CheckTag(const Asn1Tag *tag, bool_t constructed, uint_t objClass, uint_t objType)
Enforce the type of a specified tag.
Definition: asn1.c:944
@ ERROR_INVALID_KEY
Definition: error.h:106
@ NO_ERROR
Success.
Definition: error.h:44
Debugging facilities.
ASN.1 (Abstract Syntax Notation One)
X509OctetString pk
Definition: x509_common.h:869
error_t x509ParseEcPublicKey(const uint8_t *data, size_t length, X509EcPublicKey *ecPublicKey)
Parse ECPublicKey structure.