2 * Public Key layer for writing key files and structures
4 * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
5 * SPDX-License-Identifier: GPL-2.0
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License along
18 * with this program; if not, write to the Free Software Foundation, Inc.,
19 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21 * This file is part of mbed TLS (https://tls.mbed.org)
24 #if !defined(MBEDTLS_CONFIG_FILE)
25 #include "mbedtls/config.h"
27 #include MBEDTLS_CONFIG_FILE
30 #if defined(MBEDTLS_PK_WRITE_C)
32 #include "mbedtls/pk.h"
33 #include "mbedtls/asn1write.h"
34 #include "mbedtls/oid.h"
38 #if defined(MBEDTLS_RSA_C)
39 #include "mbedtls/rsa.h"
41 #if defined(MBEDTLS_ECP_C)
42 #include "mbedtls/ecp.h"
44 #if defined(MBEDTLS_ECDSA_C)
45 #include "mbedtls/ecdsa.h"
47 #if defined(MBEDTLS_PEM_WRITE_C)
48 #include "mbedtls/pem.h"
51 #if defined(MBEDTLS_PLATFORM_C)
52 #include "mbedtls/platform.h"
55 #define mbedtls_calloc calloc
56 #define mbedtls_free free
59 #if defined(MBEDTLS_RSA_C)
61 * RSAPublicKey ::= SEQUENCE {
62 * modulus INTEGER, -- n
63 * publicExponent INTEGER -- e
66 static int pk_write_rsa_pubkey( unsigned char **p
, unsigned char *start
,
67 mbedtls_rsa_context
*rsa
)
72 MBEDTLS_ASN1_CHK_ADD( len
, mbedtls_asn1_write_mpi( p
, start
, &rsa
->E
) );
73 MBEDTLS_ASN1_CHK_ADD( len
, mbedtls_asn1_write_mpi( p
, start
, &rsa
->N
) );
75 MBEDTLS_ASN1_CHK_ADD( len
, mbedtls_asn1_write_len( p
, start
, len
) );
76 MBEDTLS_ASN1_CHK_ADD( len
, mbedtls_asn1_write_tag( p
, start
, MBEDTLS_ASN1_CONSTRUCTED
|
77 MBEDTLS_ASN1_SEQUENCE
) );
81 #endif /* MBEDTLS_RSA_C */
83 #if defined(MBEDTLS_ECP_C)
85 * EC public key is an EC point
87 static int pk_write_ec_pubkey( unsigned char **p
, unsigned char *start
,
88 mbedtls_ecp_keypair
*ec
)
92 unsigned char buf
[MBEDTLS_ECP_MAX_PT_LEN
];
94 if( ( ret
= mbedtls_ecp_point_write_binary( &ec
->grp
, &ec
->Q
,
95 MBEDTLS_ECP_PF_UNCOMPRESSED
,
96 &len
, buf
, sizeof( buf
) ) ) != 0 )
101 if( *p
< start
|| (size_t)( *p
- start
) < len
)
102 return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL
);
105 memcpy( *p
, buf
, len
);
111 * ECParameters ::= CHOICE {
112 * namedCurve OBJECT IDENTIFIER
115 static int pk_write_ec_param( unsigned char **p
, unsigned char *start
,
116 mbedtls_ecp_keypair
*ec
)
123 if( ( ret
= mbedtls_oid_get_oid_by_ec_grp( ec
->grp
.id
, &oid
, &oid_len
) ) != 0 )
126 MBEDTLS_ASN1_CHK_ADD( len
, mbedtls_asn1_write_oid( p
, start
, oid
, oid_len
) );
130 #endif /* MBEDTLS_ECP_C */
132 int mbedtls_pk_write_pubkey( unsigned char **p
, unsigned char *start
,
133 const mbedtls_pk_context
*key
)
138 #if defined(MBEDTLS_RSA_C)
139 if( mbedtls_pk_get_type( key
) == MBEDTLS_PK_RSA
)
140 MBEDTLS_ASN1_CHK_ADD( len
, pk_write_rsa_pubkey( p
, start
, mbedtls_pk_rsa( *key
) ) );
143 #if defined(MBEDTLS_ECP_C)
144 if( mbedtls_pk_get_type( key
) == MBEDTLS_PK_ECKEY
)
145 MBEDTLS_ASN1_CHK_ADD( len
, pk_write_ec_pubkey( p
, start
, mbedtls_pk_ec( *key
) ) );
148 return( MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE
);
153 int mbedtls_pk_write_pubkey_der( mbedtls_pk_context
*key
, unsigned char *buf
, size_t size
)
157 size_t len
= 0, par_len
= 0, oid_len
;
162 MBEDTLS_ASN1_CHK_ADD( len
, mbedtls_pk_write_pubkey( &c
, buf
, key
) );
165 return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL
);
168 * SubjectPublicKeyInfo ::= SEQUENCE {
169 * algorithm AlgorithmIdentifier,
170 * subjectPublicKey BIT STRING }
175 MBEDTLS_ASN1_CHK_ADD( len
, mbedtls_asn1_write_len( &c
, buf
, len
) );
176 MBEDTLS_ASN1_CHK_ADD( len
, mbedtls_asn1_write_tag( &c
, buf
, MBEDTLS_ASN1_BIT_STRING
) );
178 if( ( ret
= mbedtls_oid_get_oid_by_pk_alg( mbedtls_pk_get_type( key
),
179 &oid
, &oid_len
) ) != 0 )
184 #if defined(MBEDTLS_ECP_C)
185 if( mbedtls_pk_get_type( key
) == MBEDTLS_PK_ECKEY
)
187 MBEDTLS_ASN1_CHK_ADD( par_len
, pk_write_ec_param( &c
, buf
, mbedtls_pk_ec( *key
) ) );
191 MBEDTLS_ASN1_CHK_ADD( len
, mbedtls_asn1_write_algorithm_identifier( &c
, buf
, oid
, oid_len
,
194 MBEDTLS_ASN1_CHK_ADD( len
, mbedtls_asn1_write_len( &c
, buf
, len
) );
195 MBEDTLS_ASN1_CHK_ADD( len
, mbedtls_asn1_write_tag( &c
, buf
, MBEDTLS_ASN1_CONSTRUCTED
|
196 MBEDTLS_ASN1_SEQUENCE
) );
201 int mbedtls_pk_write_key_der( mbedtls_pk_context
*key
, unsigned char *buf
, size_t size
)
204 unsigned char *c
= buf
+ size
;
207 #if defined(MBEDTLS_RSA_C)
208 if( mbedtls_pk_get_type( key
) == MBEDTLS_PK_RSA
)
210 mbedtls_rsa_context
*rsa
= mbedtls_pk_rsa( *key
);
212 MBEDTLS_ASN1_CHK_ADD( len
, mbedtls_asn1_write_mpi( &c
, buf
, &rsa
->QP
) );
213 MBEDTLS_ASN1_CHK_ADD( len
, mbedtls_asn1_write_mpi( &c
, buf
, &rsa
->DQ
) );
214 MBEDTLS_ASN1_CHK_ADD( len
, mbedtls_asn1_write_mpi( &c
, buf
, &rsa
->DP
) );
215 MBEDTLS_ASN1_CHK_ADD( len
, mbedtls_asn1_write_mpi( &c
, buf
, &rsa
->Q
) );
216 MBEDTLS_ASN1_CHK_ADD( len
, mbedtls_asn1_write_mpi( &c
, buf
, &rsa
->P
) );
217 MBEDTLS_ASN1_CHK_ADD( len
, mbedtls_asn1_write_mpi( &c
, buf
, &rsa
->D
) );
218 MBEDTLS_ASN1_CHK_ADD( len
, mbedtls_asn1_write_mpi( &c
, buf
, &rsa
->E
) );
219 MBEDTLS_ASN1_CHK_ADD( len
, mbedtls_asn1_write_mpi( &c
, buf
, &rsa
->N
) );
220 MBEDTLS_ASN1_CHK_ADD( len
, mbedtls_asn1_write_int( &c
, buf
, 0 ) );
222 MBEDTLS_ASN1_CHK_ADD( len
, mbedtls_asn1_write_len( &c
, buf
, len
) );
223 MBEDTLS_ASN1_CHK_ADD( len
, mbedtls_asn1_write_tag( &c
, buf
, MBEDTLS_ASN1_CONSTRUCTED
|
224 MBEDTLS_ASN1_SEQUENCE
) );
227 #endif /* MBEDTLS_RSA_C */
228 #if defined(MBEDTLS_ECP_C)
229 if( mbedtls_pk_get_type( key
) == MBEDTLS_PK_ECKEY
)
231 mbedtls_ecp_keypair
*ec
= mbedtls_pk_ec( *key
);
232 size_t pub_len
= 0, par_len
= 0;
235 * RFC 5915, or SEC1 Appendix C.4
237 * ECPrivateKey ::= SEQUENCE {
238 * version INTEGER { ecPrivkeyVer1(1) } (ecPrivkeyVer1),
239 * privateKey OCTET STRING,
240 * parameters [0] ECParameters {{ NamedCurve }} OPTIONAL,
241 * publicKey [1] BIT STRING OPTIONAL
246 MBEDTLS_ASN1_CHK_ADD( pub_len
, pk_write_ec_pubkey( &c
, buf
, ec
) );
249 return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL
);
253 MBEDTLS_ASN1_CHK_ADD( pub_len
, mbedtls_asn1_write_len( &c
, buf
, pub_len
) );
254 MBEDTLS_ASN1_CHK_ADD( pub_len
, mbedtls_asn1_write_tag( &c
, buf
, MBEDTLS_ASN1_BIT_STRING
) );
256 MBEDTLS_ASN1_CHK_ADD( pub_len
, mbedtls_asn1_write_len( &c
, buf
, pub_len
) );
257 MBEDTLS_ASN1_CHK_ADD( pub_len
, mbedtls_asn1_write_tag( &c
, buf
,
258 MBEDTLS_ASN1_CONTEXT_SPECIFIC
| MBEDTLS_ASN1_CONSTRUCTED
| 1 ) );
262 MBEDTLS_ASN1_CHK_ADD( par_len
, pk_write_ec_param( &c
, buf
, ec
) );
264 MBEDTLS_ASN1_CHK_ADD( par_len
, mbedtls_asn1_write_len( &c
, buf
, par_len
) );
265 MBEDTLS_ASN1_CHK_ADD( par_len
, mbedtls_asn1_write_tag( &c
, buf
,
266 MBEDTLS_ASN1_CONTEXT_SPECIFIC
| MBEDTLS_ASN1_CONSTRUCTED
| 0 ) );
269 /* privateKey: write as MPI then fix tag */
270 MBEDTLS_ASN1_CHK_ADD( len
, mbedtls_asn1_write_mpi( &c
, buf
, &ec
->d
) );
271 *c
= MBEDTLS_ASN1_OCTET_STRING
;
274 MBEDTLS_ASN1_CHK_ADD( len
, mbedtls_asn1_write_int( &c
, buf
, 1 ) );
276 MBEDTLS_ASN1_CHK_ADD( len
, mbedtls_asn1_write_len( &c
, buf
, len
) );
277 MBEDTLS_ASN1_CHK_ADD( len
, mbedtls_asn1_write_tag( &c
, buf
, MBEDTLS_ASN1_CONSTRUCTED
|
278 MBEDTLS_ASN1_SEQUENCE
) );
281 #endif /* MBEDTLS_ECP_C */
282 return( MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE
);
287 #if defined(MBEDTLS_PEM_WRITE_C)
289 #define PEM_BEGIN_PUBLIC_KEY "-----BEGIN PUBLIC KEY-----\n"
290 #define PEM_END_PUBLIC_KEY "-----END PUBLIC KEY-----\n"
292 #define PEM_BEGIN_PRIVATE_KEY_RSA "-----BEGIN RSA PRIVATE KEY-----\n"
293 #define PEM_END_PRIVATE_KEY_RSA "-----END RSA PRIVATE KEY-----\n"
294 #define PEM_BEGIN_PRIVATE_KEY_EC "-----BEGIN EC PRIVATE KEY-----\n"
295 #define PEM_END_PRIVATE_KEY_EC "-----END EC PRIVATE KEY-----\n"
298 * Max sizes of key per types. Shown as tag + len (+ content).
301 #if defined(MBEDTLS_RSA_C)
304 * SubjectPublicKeyInfo ::= SEQUENCE { 1 + 3
305 * algorithm AlgorithmIdentifier, 1 + 1 (sequence)
306 * + 1 + 1 + 9 (rsa oid)
307 * + 1 + 1 (params null)
308 * subjectPublicKey BIT STRING } 1 + 3 + (1 + below)
309 * RSAPublicKey ::= SEQUENCE { 1 + 3
310 * modulus INTEGER, -- n 1 + 3 + MPI_MAX + 1
311 * publicExponent INTEGER -- e 1 + 3 + MPI_MAX + 1
314 #define RSA_PUB_DER_MAX_BYTES 38 + 2 * MBEDTLS_MPI_MAX_SIZE
318 * RSAPrivateKey ::= SEQUENCE { 1 + 3
319 * version Version, 1 + 1 + 1
320 * modulus INTEGER, 1 + 3 + MPI_MAX + 1
321 * publicExponent INTEGER, 1 + 3 + MPI_MAX + 1
322 * privateExponent INTEGER, 1 + 3 + MPI_MAX + 1
323 * prime1 INTEGER, 1 + 3 + MPI_MAX / 2 + 1
324 * prime2 INTEGER, 1 + 3 + MPI_MAX / 2 + 1
325 * exponent1 INTEGER, 1 + 3 + MPI_MAX / 2 + 1
326 * exponent2 INTEGER, 1 + 3 + MPI_MAX / 2 + 1
327 * coefficient INTEGER, 1 + 3 + MPI_MAX / 2 + 1
328 * otherPrimeInfos OtherPrimeInfos OPTIONAL 0 (not supported)
331 #define MPI_MAX_SIZE_2 MBEDTLS_MPI_MAX_SIZE / 2 + \
332 MBEDTLS_MPI_MAX_SIZE % 2
333 #define RSA_PRV_DER_MAX_BYTES 47 + 3 * MBEDTLS_MPI_MAX_SIZE \
336 #else /* MBEDTLS_RSA_C */
338 #define RSA_PUB_DER_MAX_BYTES 0
339 #define RSA_PRV_DER_MAX_BYTES 0
341 #endif /* MBEDTLS_RSA_C */
343 #if defined(MBEDTLS_ECP_C)
346 * SubjectPublicKeyInfo ::= SEQUENCE { 1 + 2
347 * algorithm AlgorithmIdentifier, 1 + 1 (sequence)
348 * + 1 + 1 + 7 (ec oid)
349 * + 1 + 1 + 9 (namedCurve oid)
350 * subjectPublicKey BIT STRING 1 + 2 + 1 [1]
351 * + 1 (point format) [1]
352 * + 2 * ECP_MAX (coords) [1]
355 #define ECP_PUB_DER_MAX_BYTES 30 + 2 * MBEDTLS_ECP_MAX_BYTES
359 * ECPrivateKey ::= SEQUENCE { 1 + 2
360 * version INTEGER , 1 + 1 + 1
361 * privateKey OCTET STRING, 1 + 1 + ECP_MAX
362 * parameters [0] ECParameters OPTIONAL, 1 + 1 + (1 + 1 + 9)
363 * publicKey [1] BIT STRING OPTIONAL 1 + 2 + [1] above
366 #define ECP_PRV_DER_MAX_BYTES 29 + 3 * MBEDTLS_ECP_MAX_BYTES
368 #else /* MBEDTLS_ECP_C */
370 #define ECP_PUB_DER_MAX_BYTES 0
371 #define ECP_PRV_DER_MAX_BYTES 0
373 #endif /* MBEDTLS_ECP_C */
375 #define PUB_DER_MAX_BYTES RSA_PUB_DER_MAX_BYTES > ECP_PUB_DER_MAX_BYTES ? \
376 RSA_PUB_DER_MAX_BYTES : ECP_PUB_DER_MAX_BYTES
377 #define PRV_DER_MAX_BYTES RSA_PRV_DER_MAX_BYTES > ECP_PRV_DER_MAX_BYTES ? \
378 RSA_PRV_DER_MAX_BYTES : ECP_PRV_DER_MAX_BYTES
380 int mbedtls_pk_write_pubkey_pem( mbedtls_pk_context
*key
, unsigned char *buf
, size_t size
)
383 unsigned char output_buf
[PUB_DER_MAX_BYTES
];
386 if( ( ret
= mbedtls_pk_write_pubkey_der( key
, output_buf
,
387 sizeof(output_buf
) ) ) < 0 )
392 if( ( ret
= mbedtls_pem_write_buffer( PEM_BEGIN_PUBLIC_KEY
, PEM_END_PUBLIC_KEY
,
393 output_buf
+ sizeof(output_buf
) - ret
,
394 ret
, buf
, size
, &olen
) ) != 0 )
402 int mbedtls_pk_write_key_pem( mbedtls_pk_context
*key
, unsigned char *buf
, size_t size
)
405 unsigned char output_buf
[PRV_DER_MAX_BYTES
];
406 const char *begin
, *end
;
409 if( ( ret
= mbedtls_pk_write_key_der( key
, output_buf
, sizeof(output_buf
) ) ) < 0 )
412 #if defined(MBEDTLS_RSA_C)
413 if( mbedtls_pk_get_type( key
) == MBEDTLS_PK_RSA
)
415 begin
= PEM_BEGIN_PRIVATE_KEY_RSA
;
416 end
= PEM_END_PRIVATE_KEY_RSA
;
420 #if defined(MBEDTLS_ECP_C)
421 if( mbedtls_pk_get_type( key
) == MBEDTLS_PK_ECKEY
)
423 begin
= PEM_BEGIN_PRIVATE_KEY_EC
;
424 end
= PEM_END_PRIVATE_KEY_EC
;
428 return( MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE
);
430 if( ( ret
= mbedtls_pem_write_buffer( begin
, end
,
431 output_buf
+ sizeof(output_buf
) - ret
,
432 ret
, buf
, size
, &olen
) ) != 0 )
439 #endif /* MBEDTLS_PEM_WRITE_C */
441 #endif /* MBEDTLS_PK_WRITE_C */