pkcs8_key_format.c
Go to the documentation of this file.
1 /**
2  * @file pkcs8_key_format.c
3  * @brief PKCS #8 key formatting
4  *
5  * @section License
6  *
7  * SPDX-License-Identifier: GPL-2.0-or-later
8  *
9  * Copyright (C) 2010-2025 Oryx Embedded SARL. All rights reserved.
10  *
11  * This file is part of 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.5.2
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/pkcs8_key_format.h"
37 #include "pkix/x509_key_format.h"
38 #include "encoding/asn1.h"
39 #include "encoding/oid.h"
40 #include "ecc/ec_misc.h"
41 #include "debug.h"
42 
43 //Check crypto library configuration
44 #if (PEM_SUPPORT == ENABLED)
45 
46 
47 /**
48  * @brief Format an RSA private key
49  * @param[in] privateKey Pointer to the RSA private key
50  * @param[out] output Buffer where to store the ASN.1 structure
51  * @param[out] written Length of the resulting ASN.1 structure
52  * @return Error code
53  **/
54 
56  uint8_t *output, size_t *written)
57 {
58  error_t error;
59  size_t n;
60  Asn1Tag tag;
61 
62  //Export the RSA private key to ASN.1 format
63  error = x509ExportRsaPrivateKey(privateKey, output, &n);
64 
65  //Check status code
66  if(!error)
67  {
68  //The RSAPrivateKey structure is encapsulated within an octet string
69  tag.constructed = FALSE;
72  tag.length = n;
73 
74  //Write PrivateKey structure
75  error = asn1InsertHeader(&tag, output, &n);
76  }
77 
78  //Check status code
79  if(!error)
80  {
81  //Total number of bytes that have been written
82  *written = tag.totalLength;
83  }
84 
85  //Return status code
86  return error;
87 }
88 
89 
90 /**
91  * @brief Format a DSA private key
92  * @param[in] privateKey Pointer to the RSA private key
93  * @param[out] output Buffer where to store the ASN.1 structure
94  * @param[out] written Length of the resulting ASN.1 structure
95  * @return Error code
96  **/
97 
99  uint8_t *output, size_t *written)
100 {
101  error_t error;
102  size_t n;
103  Asn1Tag tag;
104 
105  //Export the DSA private key to ASN.1 format
106  error = x509ExportDsaPrivateKey(privateKey, output, &n);
107 
108  //Check status code
109  if(!error)
110  {
111  //The DSAPrivateKey structure is encapsulated within an octet string
112  tag.constructed = FALSE;
115  tag.length = n;
116 
117  //Write PrivateKey structure
118  error = asn1InsertHeader(&tag, output, &n);
119  }
120 
121  //Check status code
122  if(!error)
123  {
124  //Total number of bytes that have been written
125  *written = tag.totalLength;
126  }
127 
128  //Return status code
129  return error;
130 }
131 
132 
133 /**
134  * @brief Format an EC private key
135  * @param[in] privateKey EC private key
136  * @param[out] output Buffer where to format the ASN.1 structure
137  * @param[out] written Length of the resulting ASN.1 structure
138  * @return Error code
139  **/
140 
142  uint8_t *output, size_t *written)
143 {
144 #if (EC_SUPPORT == ENABLED)
145  error_t error;
146  size_t n;
147  Asn1Tag tag;
148 
149  //Export the EC private key to ASN.1 format
150  error = x509ExportEcPrivateKey(NULL, privateKey, &privateKey->q, output, &n);
151 
152  //Check status code
153  if(!error)
154  {
155  //The ECPrivateKey structure is encapsulated within an octet string
156  tag.constructed = FALSE;
159  tag.length = n;
160 
161  //Write PrivateKey structure
162  error = asn1InsertHeader(&tag, output, &n);
163  }
164 
165  //Check status code
166  if(!error)
167  {
168  //Total number of bytes that have been written
169  *written = tag.totalLength;
170  }
171 
172  //Return status code
173  return error;
174 #else
175  //Not implemented
176  return ERROR_NOT_IMPLEMENTED;
177 #endif
178 }
179 
180 
181 /**
182  * @brief Format an EdDSA private key
183  * @param[in] privateKey EdDSA private key
184  * @param[out] output Buffer where to format the ASN.1 structure
185  * @param[out] written Length of the resulting ASN.1 structure
186  * @return Error code
187  **/
188 
190  uint8_t *output, size_t *written)
191 {
192 #if (ED25519_SUPPORT == ENABLED || ED448_SUPPORT == ENABLED)
193  error_t error;
194  size_t n;
195  Asn1Tag tag;
196 
197  //Export the EdDSA private key to ASN.1 format
198  error = x509ExportEddsaPrivateKey(privateKey, output, &n);
199 
200  //Check status code
201  if(!error)
202  {
203  //The CurvePrivateKey structure is encapsulated within an octet string
204  tag.constructed = FALSE;
207  tag.length = n;
208 
209  //Write PrivateKey structure
210  error = asn1InsertHeader(&tag, output, &n);
211  }
212 
213  //Check status code
214  if(!error)
215  {
216  //Total number of bytes that have been written
217  *written = tag.totalLength;
218  }
219 
220  //Return status code
221  return error;
222 #else
223  //Not implemented
224  return ERROR_NOT_IMPLEMENTED;
225 #endif
226 }
227 
228 
229 /**
230  * @brief Format an EdDSA public key
231  * @param[in] publicKey EdDSA public key
232  * @param[out] output Buffer where to format the ASN.1 structure
233  * @param[out] written Length of the resulting ASN.1 structure
234  * @return Error code
235  **/
236 
238  uint8_t *output, size_t *written)
239 {
240 #if (ED25519_SUPPORT == ENABLED || ED448_SUPPORT == ENABLED)
241  error_t error;
242  size_t n;
243  uint8_t *p;
244  Asn1Tag tag;
245 
246  //Point to the buffer where to write the ASN.1 structure
247  p = output;
248 
249  //If the output parameter is NULL, then the function calculates the length
250  //of the ASN.1 structure without copying any data
251  if(p != NULL)
252  {
253  //The bit string shall contain an initial octet which encodes the number
254  //of unused bits in the final subsequent octet
255  p[0] = 0;
256 
257  //Advance data pointer
258  p++;
259  }
260 
261  //Format EdDSA public key
262  error = eddsaExportPublicKey(publicKey, p, &n);
263 
264  //Check status code
265  if(!error)
266  {
267  //Implicit tagging shall be used to encode the public key
268  tag.constructed = TRUE;
270  tag.objType = 1;
271  tag.length = n + 1;
272 
273  //Write the corresponding ASN.1 tag
274  error = asn1InsertHeader(&tag, output, &n);
275  }
276 
277  //Check status code
278  if(!error)
279  {
280  //Total number of bytes that have been written
281  *written = tag.totalLength;
282  }
283 
284  //Return status code
285  return error;
286 #else
287  //Not implemented
288  return ERROR_NOT_IMPLEMENTED;
289 #endif
290 }
291 
292 #endif
PKCS #8 key formatting.
error_t x509ExportEddsaPrivateKey(const EddsaPrivateKey *privateKey, uint8_t *output, size_t *written)
Export an EdDSA private key to ASN.1 format.
@ ERROR_NOT_IMPLEMENTED
Definition: error.h:66
OID (Object Identifier)
uint8_t p
Definition: ndp.h:300
#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
error_t pkcs8FormatEddsaPrivateKey(const EddsaPrivateKey *privateKey, uint8_t *output, size_t *written)
Format an EdDSA private key.
error_t pkcs8FormatRsaPrivateKey(const RsaPrivateKey *privateKey, uint8_t *output, size_t *written)
Format an RSA private key.
error_t pkcs8FormatDsaPrivateKey(const DsaPrivateKey *privateKey, uint8_t *output, size_t *written)
Format a DSA private key.
size_t totalLength
Definition: asn1.h:111
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
#define FALSE
Definition: os_port.h:46
error_t
Error codes.
Definition: error.h:43
error_t x509ExportDsaPrivateKey(const DsaPrivateKey *privateKey, uint8_t *output, size_t *written)
Export a DSA private key to ASN.1 format.
EdDSA public key.
Definition: eddsa.h:64
#define ASN1_CLASS_UNIVERSAL
Definition: asn1.h:52
error_t pkcs8FormatEcPrivateKey(const EcPrivateKey *privateKey, uint8_t *output, size_t *written)
Format an EC private key.
ASN.1 tag.
Definition: asn1.h:105
Helper routines for ECC.
General definitions for cryptographic algorithms.
EcPublicKey q
Public key.
Definition: ec.h:436
EC private key.
Definition: ec.h:432
DSA private key.
Definition: dsa.h:72
uint_t objClass
Definition: asn1.h:107
error_t x509ExportRsaPrivateKey(const RsaPrivateKey *privateKey, uint8_t *output, size_t *written)
Export an RSA private key to ASN.1 format.
EdDSA private key.
Definition: eddsa.h:75
@ ASN1_TYPE_OCTET_STRING
Definition: asn1.h:75
Formatting of ASN.1 encoded keys.
uint8_t n
RSA private key.
Definition: rsa.h:68
#define ASN1_CLASS_CONTEXT_SPECIFIC
Definition: asn1.h:54
bool_t constructed
Definition: asn1.h:106
error_t pkcs8FormatEddsaPublicKey(const EddsaPublicKey *publicKey, uint8_t *output, size_t *written)
Format an EdDSA public key.
Debugging facilities.
uint_t objType
Definition: asn1.h:108
ASN.1 (Abstract Syntax Notation One)