xref: /aosp_15_r20/external/arm-trusted-firmware/tools/cert_create/src/key.c (revision 54fd6939e177f8ff529b10183254802c76df6d08)
1*54fd6939SJiyong Park /*
2*54fd6939SJiyong Park  * Copyright (c) 2015-2021, ARM Limited and Contributors. All rights reserved.
3*54fd6939SJiyong Park  *
4*54fd6939SJiyong Park  * SPDX-License-Identifier: BSD-3-Clause
5*54fd6939SJiyong Park  */
6*54fd6939SJiyong Park 
7*54fd6939SJiyong Park #include <getopt.h>
8*54fd6939SJiyong Park #include <stdio.h>
9*54fd6939SJiyong Park #include <stdlib.h>
10*54fd6939SJiyong Park #include <string.h>
11*54fd6939SJiyong Park 
12*54fd6939SJiyong Park #include <openssl/conf.h>
13*54fd6939SJiyong Park #include <openssl/evp.h>
14*54fd6939SJiyong Park #include <openssl/pem.h>
15*54fd6939SJiyong Park 
16*54fd6939SJiyong Park #include "cert.h"
17*54fd6939SJiyong Park #include "cmd_opt.h"
18*54fd6939SJiyong Park #include "debug.h"
19*54fd6939SJiyong Park #include "key.h"
20*54fd6939SJiyong Park #include "sha.h"
21*54fd6939SJiyong Park 
22*54fd6939SJiyong Park #define MAX_FILENAME_LEN		1024
23*54fd6939SJiyong Park 
24*54fd6939SJiyong Park key_t *keys;
25*54fd6939SJiyong Park unsigned int num_keys;
26*54fd6939SJiyong Park 
27*54fd6939SJiyong Park /*
28*54fd6939SJiyong Park  * Create a new key container
29*54fd6939SJiyong Park  */
key_new(key_t * key)30*54fd6939SJiyong Park int key_new(key_t *key)
31*54fd6939SJiyong Park {
32*54fd6939SJiyong Park 	/* Create key pair container */
33*54fd6939SJiyong Park 	key->key = EVP_PKEY_new();
34*54fd6939SJiyong Park 	if (key->key == NULL) {
35*54fd6939SJiyong Park 		return 0;
36*54fd6939SJiyong Park 	}
37*54fd6939SJiyong Park 
38*54fd6939SJiyong Park 	return 1;
39*54fd6939SJiyong Park }
40*54fd6939SJiyong Park 
key_create_rsa(key_t * key,int key_bits)41*54fd6939SJiyong Park static int key_create_rsa(key_t *key, int key_bits)
42*54fd6939SJiyong Park {
43*54fd6939SJiyong Park 	BIGNUM *e;
44*54fd6939SJiyong Park 	RSA *rsa = NULL;
45*54fd6939SJiyong Park 
46*54fd6939SJiyong Park 	e = BN_new();
47*54fd6939SJiyong Park 	if (e == NULL) {
48*54fd6939SJiyong Park 		printf("Cannot create RSA exponent\n");
49*54fd6939SJiyong Park 		goto err;
50*54fd6939SJiyong Park 	}
51*54fd6939SJiyong Park 
52*54fd6939SJiyong Park 	if (!BN_set_word(e, RSA_F4)) {
53*54fd6939SJiyong Park 		printf("Cannot assign RSA exponent\n");
54*54fd6939SJiyong Park 		goto err;
55*54fd6939SJiyong Park 	}
56*54fd6939SJiyong Park 
57*54fd6939SJiyong Park 	rsa = RSA_new();
58*54fd6939SJiyong Park 	if (rsa == NULL) {
59*54fd6939SJiyong Park 		printf("Cannot create RSA key\n");
60*54fd6939SJiyong Park 		goto err;
61*54fd6939SJiyong Park 	}
62*54fd6939SJiyong Park 
63*54fd6939SJiyong Park 	if (!RSA_generate_key_ex(rsa, key_bits, e, NULL)) {
64*54fd6939SJiyong Park 		printf("Cannot generate RSA key\n");
65*54fd6939SJiyong Park 		goto err;
66*54fd6939SJiyong Park 	}
67*54fd6939SJiyong Park 
68*54fd6939SJiyong Park 	if (!EVP_PKEY_assign_RSA(key->key, rsa)) {
69*54fd6939SJiyong Park 		printf("Cannot assign RSA key\n");
70*54fd6939SJiyong Park 		goto err;
71*54fd6939SJiyong Park 	}
72*54fd6939SJiyong Park 
73*54fd6939SJiyong Park 	BN_free(e);
74*54fd6939SJiyong Park 	return 1;
75*54fd6939SJiyong Park err:
76*54fd6939SJiyong Park 	RSA_free(rsa);
77*54fd6939SJiyong Park 	BN_free(e);
78*54fd6939SJiyong Park 	return 0;
79*54fd6939SJiyong Park }
80*54fd6939SJiyong Park 
81*54fd6939SJiyong Park #ifndef OPENSSL_NO_EC
key_create_ecdsa(key_t * key,int key_bits)82*54fd6939SJiyong Park static int key_create_ecdsa(key_t *key, int key_bits)
83*54fd6939SJiyong Park {
84*54fd6939SJiyong Park 	EC_KEY *ec;
85*54fd6939SJiyong Park 
86*54fd6939SJiyong Park 	ec = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1);
87*54fd6939SJiyong Park 	if (ec == NULL) {
88*54fd6939SJiyong Park 		printf("Cannot create EC key\n");
89*54fd6939SJiyong Park 		goto err;
90*54fd6939SJiyong Park 	}
91*54fd6939SJiyong Park 	if (!EC_KEY_generate_key(ec)) {
92*54fd6939SJiyong Park 		printf("Cannot generate EC key\n");
93*54fd6939SJiyong Park 		goto err;
94*54fd6939SJiyong Park 	}
95*54fd6939SJiyong Park 	EC_KEY_set_flags(ec, EC_PKEY_NO_PARAMETERS);
96*54fd6939SJiyong Park 	EC_KEY_set_asn1_flag(ec, OPENSSL_EC_NAMED_CURVE);
97*54fd6939SJiyong Park 	if (!EVP_PKEY_assign_EC_KEY(key->key, ec)) {
98*54fd6939SJiyong Park 		printf("Cannot assign EC key\n");
99*54fd6939SJiyong Park 		goto err;
100*54fd6939SJiyong Park 	}
101*54fd6939SJiyong Park 
102*54fd6939SJiyong Park 	return 1;
103*54fd6939SJiyong Park err:
104*54fd6939SJiyong Park 	EC_KEY_free(ec);
105*54fd6939SJiyong Park 	return 0;
106*54fd6939SJiyong Park }
107*54fd6939SJiyong Park #endif /* OPENSSL_NO_EC */
108*54fd6939SJiyong Park 
109*54fd6939SJiyong Park typedef int (*key_create_fn_t)(key_t *key, int key_bits);
110*54fd6939SJiyong Park static const key_create_fn_t key_create_fn[KEY_ALG_MAX_NUM] = {
111*54fd6939SJiyong Park 	key_create_rsa, 	/* KEY_ALG_RSA */
112*54fd6939SJiyong Park #ifndef OPENSSL_NO_EC
113*54fd6939SJiyong Park 	key_create_ecdsa, 	/* KEY_ALG_ECDSA */
114*54fd6939SJiyong Park #endif /* OPENSSL_NO_EC */
115*54fd6939SJiyong Park };
116*54fd6939SJiyong Park 
key_create(key_t * key,int type,int key_bits)117*54fd6939SJiyong Park int key_create(key_t *key, int type, int key_bits)
118*54fd6939SJiyong Park {
119*54fd6939SJiyong Park 	if (type >= KEY_ALG_MAX_NUM) {
120*54fd6939SJiyong Park 		printf("Invalid key type\n");
121*54fd6939SJiyong Park 		return 0;
122*54fd6939SJiyong Park 	}
123*54fd6939SJiyong Park 
124*54fd6939SJiyong Park 	if (key_create_fn[type]) {
125*54fd6939SJiyong Park 		return key_create_fn[type](key, key_bits);
126*54fd6939SJiyong Park 	}
127*54fd6939SJiyong Park 
128*54fd6939SJiyong Park 	return 0;
129*54fd6939SJiyong Park }
130*54fd6939SJiyong Park 
key_load(key_t * key,unsigned int * err_code)131*54fd6939SJiyong Park int key_load(key_t *key, unsigned int *err_code)
132*54fd6939SJiyong Park {
133*54fd6939SJiyong Park 	FILE *fp;
134*54fd6939SJiyong Park 	EVP_PKEY *k;
135*54fd6939SJiyong Park 
136*54fd6939SJiyong Park 	if (key->fn) {
137*54fd6939SJiyong Park 		/* Load key from file */
138*54fd6939SJiyong Park 		fp = fopen(key->fn, "r");
139*54fd6939SJiyong Park 		if (fp) {
140*54fd6939SJiyong Park 			k = PEM_read_PrivateKey(fp, &key->key, NULL, NULL);
141*54fd6939SJiyong Park 			fclose(fp);
142*54fd6939SJiyong Park 			if (k) {
143*54fd6939SJiyong Park 				*err_code = KEY_ERR_NONE;
144*54fd6939SJiyong Park 				return 1;
145*54fd6939SJiyong Park 			} else {
146*54fd6939SJiyong Park 				ERROR("Cannot load key from %s\n", key->fn);
147*54fd6939SJiyong Park 				*err_code = KEY_ERR_LOAD;
148*54fd6939SJiyong Park 			}
149*54fd6939SJiyong Park 		} else {
150*54fd6939SJiyong Park 			WARN("Cannot open file %s\n", key->fn);
151*54fd6939SJiyong Park 			*err_code = KEY_ERR_OPEN;
152*54fd6939SJiyong Park 		}
153*54fd6939SJiyong Park 	} else {
154*54fd6939SJiyong Park 		WARN("Key filename not specified\n");
155*54fd6939SJiyong Park 		*err_code = KEY_ERR_FILENAME;
156*54fd6939SJiyong Park 	}
157*54fd6939SJiyong Park 
158*54fd6939SJiyong Park 	return 0;
159*54fd6939SJiyong Park }
160*54fd6939SJiyong Park 
key_store(key_t * key)161*54fd6939SJiyong Park int key_store(key_t *key)
162*54fd6939SJiyong Park {
163*54fd6939SJiyong Park 	FILE *fp;
164*54fd6939SJiyong Park 
165*54fd6939SJiyong Park 	if (key->fn) {
166*54fd6939SJiyong Park 		fp = fopen(key->fn, "w");
167*54fd6939SJiyong Park 		if (fp) {
168*54fd6939SJiyong Park 			PEM_write_PrivateKey(fp, key->key,
169*54fd6939SJiyong Park 					NULL, NULL, 0, NULL, NULL);
170*54fd6939SJiyong Park 			fclose(fp);
171*54fd6939SJiyong Park 			return 1;
172*54fd6939SJiyong Park 		} else {
173*54fd6939SJiyong Park 			ERROR("Cannot create file %s\n", key->fn);
174*54fd6939SJiyong Park 		}
175*54fd6939SJiyong Park 	} else {
176*54fd6939SJiyong Park 		ERROR("Key filename not specified\n");
177*54fd6939SJiyong Park 	}
178*54fd6939SJiyong Park 
179*54fd6939SJiyong Park 	return 0;
180*54fd6939SJiyong Park }
181*54fd6939SJiyong Park 
key_init(void)182*54fd6939SJiyong Park int key_init(void)
183*54fd6939SJiyong Park {
184*54fd6939SJiyong Park 	cmd_opt_t cmd_opt;
185*54fd6939SJiyong Park 	key_t *key;
186*54fd6939SJiyong Park 	unsigned int i;
187*54fd6939SJiyong Park 
188*54fd6939SJiyong Park 	keys = malloc((num_def_keys * sizeof(def_keys[0]))
189*54fd6939SJiyong Park #ifdef PDEF_KEYS
190*54fd6939SJiyong Park 		      + (num_pdef_keys * sizeof(pdef_keys[0]))
191*54fd6939SJiyong Park #endif
192*54fd6939SJiyong Park 		      );
193*54fd6939SJiyong Park 
194*54fd6939SJiyong Park 	if (keys == NULL) {
195*54fd6939SJiyong Park 		ERROR("%s:%d Failed to allocate memory.\n", __func__, __LINE__);
196*54fd6939SJiyong Park 		return 1;
197*54fd6939SJiyong Park 	}
198*54fd6939SJiyong Park 
199*54fd6939SJiyong Park 	memcpy(&keys[0], &def_keys[0], (num_def_keys * sizeof(def_keys[0])));
200*54fd6939SJiyong Park #ifdef PDEF_KEYS
201*54fd6939SJiyong Park 	memcpy(&keys[num_def_keys], &pdef_keys[0],
202*54fd6939SJiyong Park 		(num_pdef_keys * sizeof(pdef_keys[0])));
203*54fd6939SJiyong Park 
204*54fd6939SJiyong Park 	num_keys = num_def_keys + num_pdef_keys;
205*54fd6939SJiyong Park #else
206*54fd6939SJiyong Park 	num_keys = num_def_keys;
207*54fd6939SJiyong Park #endif
208*54fd6939SJiyong Park 		   ;
209*54fd6939SJiyong Park 
210*54fd6939SJiyong Park 	for (i = 0; i < num_keys; i++) {
211*54fd6939SJiyong Park 		key = &keys[i];
212*54fd6939SJiyong Park 		if (key->opt != NULL) {
213*54fd6939SJiyong Park 			cmd_opt.long_opt.name = key->opt;
214*54fd6939SJiyong Park 			cmd_opt.long_opt.has_arg = required_argument;
215*54fd6939SJiyong Park 			cmd_opt.long_opt.flag = NULL;
216*54fd6939SJiyong Park 			cmd_opt.long_opt.val = CMD_OPT_KEY;
217*54fd6939SJiyong Park 			cmd_opt.help_msg = key->help_msg;
218*54fd6939SJiyong Park 			cmd_opt_add(&cmd_opt);
219*54fd6939SJiyong Park 		}
220*54fd6939SJiyong Park 	}
221*54fd6939SJiyong Park 
222*54fd6939SJiyong Park 	return 0;
223*54fd6939SJiyong Park }
224*54fd6939SJiyong Park 
key_get_by_opt(const char * opt)225*54fd6939SJiyong Park key_t *key_get_by_opt(const char *opt)
226*54fd6939SJiyong Park {
227*54fd6939SJiyong Park 	key_t *key;
228*54fd6939SJiyong Park 	unsigned int i;
229*54fd6939SJiyong Park 
230*54fd6939SJiyong Park 	/* Sequential search. This is not a performance concern since the number
231*54fd6939SJiyong Park 	 * of keys is bounded and the code runs on a host machine */
232*54fd6939SJiyong Park 	for (i = 0; i < num_keys; i++) {
233*54fd6939SJiyong Park 		key = &keys[i];
234*54fd6939SJiyong Park 		if (0 == strcmp(key->opt, opt)) {
235*54fd6939SJiyong Park 			return key;
236*54fd6939SJiyong Park 		}
237*54fd6939SJiyong Park 	}
238*54fd6939SJiyong Park 
239*54fd6939SJiyong Park 	return NULL;
240*54fd6939SJiyong Park }
241