xref: /rk3399_ARM-atf/tools/cert_create/src/key.c (revision 138ddcbf4d330d13a11576d973513014055f98c1)
1 /*
2  * Copyright (c) 2015-2022, Arm Limited and Contributors. All rights reserved.
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  */
6 
7 #include <getopt.h>
8 #include <stdio.h>
9 #include <stdlib.h>
10 #include <string.h>
11 
12 /* Suppress OpenSSL engine deprecation warnings */
13 #define OPENSSL_SUPPRESS_DEPRECATED
14 
15 #include <openssl/conf.h>
16 #include <openssl/engine.h>
17 #include <openssl/evp.h>
18 #include <openssl/pem.h>
19 
20 #include "cert.h"
21 #include "cmd_opt.h"
22 #include "debug.h"
23 #include "key.h"
24 #include "sha.h"
25 
26 #define MAX_FILENAME_LEN		1024
27 
28 key_t *keys;
29 unsigned int num_keys;
30 
31 #if !USING_OPENSSL3
32 /*
33  * Create a new key container
34  */
35 int key_new(key_t *key)
36 {
37 	/* Create key pair container */
38 	key->key = EVP_PKEY_new();
39 	if (key->key == NULL) {
40 		return 0;
41 	}
42 
43 	return 1;
44 }
45 #endif
46 
47 static int key_create_rsa(key_t *key, int key_bits)
48 {
49 #if USING_OPENSSL3
50 	EVP_PKEY *rsa = EVP_RSA_gen(key_bits);
51 	if (rsa == NULL) {
52 		printf("Cannot generate RSA key\n");
53 		return 0;
54 	}
55 	key->key = rsa;
56 	return 1;
57 #else
58 	BIGNUM *e;
59 	RSA *rsa = NULL;
60 
61 	e = BN_new();
62 	if (e == NULL) {
63 		printf("Cannot create RSA exponent\n");
64 		return 0;
65 	}
66 
67 	if (!BN_set_word(e, RSA_F4)) {
68 		printf("Cannot assign RSA exponent\n");
69 		goto err2;
70 	}
71 
72 	rsa = RSA_new();
73 	if (rsa == NULL) {
74 		printf("Cannot create RSA key\n");
75 		goto err2;
76 	}
77 
78 	if (!RSA_generate_key_ex(rsa, key_bits, e, NULL)) {
79 		printf("Cannot generate RSA key\n");
80 		goto err;
81 	}
82 
83 	if (!EVP_PKEY_assign_RSA(key->key, rsa)) {
84 		printf("Cannot assign RSA key\n");
85 		goto err;
86 	}
87 
88 	BN_free(e);
89 	return 1;
90 
91 err:
92 	RSA_free(rsa);
93 err2:
94 	BN_free(e);
95 	return 0;
96 #endif
97 }
98 
99 #ifndef OPENSSL_NO_EC
100 #if USING_OPENSSL3
101 static int key_create_ecdsa(key_t *key, int key_bits, const char *curve)
102 {
103 	EVP_PKEY *ec = EVP_EC_gen(curve);
104 	if (ec == NULL) {
105 		printf("Cannot generate EC key\n");
106 		return 0;
107 	}
108 
109 	key->key = ec;
110 	return 1;
111 }
112 
113 static int key_create_ecdsa_nist(key_t *key, int key_bits)
114 {
115 	return key_create_ecdsa(key, key_bits, "prime256v1");
116 }
117 
118 static int key_create_ecdsa_brainpool_r(key_t *key, int key_bits)
119 {
120 	return key_create_ecdsa(key, key_bits, "brainpoolP256r1");
121 }
122 
123 static int key_create_ecdsa_brainpool_t(key_t *key, int key_bits)
124 {
125 	return key_create_ecdsa(key, key_bits, "brainpoolP256t1");
126 }
127 #else
128 static int key_create_ecdsa(key_t *key, int key_bits, const int curve_id)
129 {
130 	EC_KEY *ec;
131 
132 	ec = EC_KEY_new_by_curve_name(curve_id);
133 	if (ec == NULL) {
134 		printf("Cannot create EC key\n");
135 		return 0;
136 	}
137 	if (!EC_KEY_generate_key(ec)) {
138 		printf("Cannot generate EC key\n");
139 		goto err;
140 	}
141 	EC_KEY_set_flags(ec, EC_PKEY_NO_PARAMETERS);
142 	EC_KEY_set_asn1_flag(ec, OPENSSL_EC_NAMED_CURVE);
143 	if (!EVP_PKEY_assign_EC_KEY(key->key, ec)) {
144 		printf("Cannot assign EC key\n");
145 		goto err;
146 	}
147 
148 	return 1;
149 
150 err:
151 	EC_KEY_free(ec);
152 	return 0;
153 }
154 
155 static int key_create_ecdsa_nist(key_t *key, int key_bits)
156 {
157 	return key_create_ecdsa(key, key_bits, NID_X9_62_prime256v1);
158 }
159 
160 static int key_create_ecdsa_brainpool_r(key_t *key, int key_bits)
161 {
162 	return key_create_ecdsa(key, key_bits, NID_brainpoolP256r1);
163 }
164 
165 static int key_create_ecdsa_brainpool_t(key_t *key, int key_bits)
166 {
167 	return key_create_ecdsa(key, key_bits, NID_brainpoolP256t1);
168 }
169 #endif /* USING_OPENSSL3 */
170 #endif /* OPENSSL_NO_EC */
171 
172 typedef int (*key_create_fn_t)(key_t *key, int key_bits);
173 static const key_create_fn_t key_create_fn[KEY_ALG_MAX_NUM] = {
174 	[KEY_ALG_RSA] = key_create_rsa,
175 #ifndef OPENSSL_NO_EC
176 	[KEY_ALG_ECDSA_NIST] = key_create_ecdsa_nist,
177 	[KEY_ALG_ECDSA_BRAINPOOL_R] = key_create_ecdsa_brainpool_r,
178 	[KEY_ALG_ECDSA_BRAINPOOL_T] = key_create_ecdsa_brainpool_t,
179 #endif /* OPENSSL_NO_EC */
180 };
181 
182 int key_create(key_t *key, int type, int key_bits)
183 {
184 	if (type >= KEY_ALG_MAX_NUM) {
185 		printf("Invalid key type\n");
186 		return 0;
187 	}
188 
189 	if (key_create_fn[type]) {
190 		return key_create_fn[type](key, key_bits);
191 	}
192 
193 	return 0;
194 }
195 
196 static EVP_PKEY *key_load_pkcs11(const char *uri)
197 {
198 	char *key_pass;
199 	EVP_PKEY *pkey;
200 	ENGINE *e;
201 
202 	ENGINE_load_builtin_engines();
203 	e = ENGINE_by_id("pkcs11");
204 	if (!e) {
205 		fprintf(stderr, "Cannot Load PKCS#11 ENGINE\n");
206 		return NULL;
207 	}
208 
209 	if (!ENGINE_init(e)) {
210 		fprintf(stderr, "Cannot ENGINE_init\n");
211 		goto err;
212 	}
213 
214 	key_pass = getenv("PKCS11_PIN");
215 	if (key_pass) {
216 		if (!ENGINE_ctrl_cmd_string(e, "PIN", key_pass, 0)) {
217 			fprintf(stderr, "Cannot Set PKCS#11 PIN\n");
218 			goto err;
219 		}
220 	}
221 
222 	pkey = ENGINE_load_private_key(e, uri, NULL, NULL);
223 	if (pkey)
224 		return pkey;
225 err:
226 	ENGINE_free(e);
227 	return NULL;
228 
229 }
230 
231 int key_load(key_t *key, unsigned int *err_code)
232 {
233 	FILE *fp;
234 
235 	if (key->fn) {
236 		if (!strncmp(key->fn, "pkcs11:", 7)) {
237 			/* Load key through pkcs11 */
238 			key->key = key_load_pkcs11(key->fn);
239 		} else {
240 			/* Load key from file */
241 			fp = fopen(key->fn, "r");
242 			if (fp) {
243 				key->key = PEM_read_PrivateKey(fp, NULL, NULL, NULL);
244 				fclose(fp);
245 			} else {
246 				WARN("Cannot open file %s\n", key->fn);
247 				*err_code = KEY_ERR_OPEN;
248 			}
249 		}
250 		if (key->key) {
251 			*err_code = KEY_ERR_NONE;
252 			return 1;
253 		} else {
254 			ERROR("Cannot load key from %s\n", key->fn);
255 			*err_code = KEY_ERR_LOAD;
256 		}
257 	} else {
258 		VERBOSE("Key not specified\n");
259 		*err_code = KEY_ERR_FILENAME;
260 	}
261 
262 	return 0;
263 }
264 
265 int key_store(key_t *key)
266 {
267 	FILE *fp;
268 
269 	if (key->fn) {
270 		if (!strncmp(key->fn, "pkcs11:", 7)) {
271 			ERROR("PKCS11 URI provided instead of a file");
272 			return 0;
273 		}
274 		fp = fopen(key->fn, "w");
275 		if (fp) {
276 			PEM_write_PrivateKey(fp, key->key,
277 					NULL, NULL, 0, NULL, NULL);
278 			fclose(fp);
279 			return 1;
280 		} else {
281 			ERROR("Cannot create file %s\n", key->fn);
282 		}
283 	} else {
284 		ERROR("Key filename not specified\n");
285 	}
286 
287 	return 0;
288 }
289 
290 int key_init(void)
291 {
292 	cmd_opt_t cmd_opt;
293 	key_t *key;
294 	unsigned int i;
295 
296 	keys = malloc((num_def_keys * sizeof(def_keys[0]))
297 #ifdef PDEF_KEYS
298 		      + (num_pdef_keys * sizeof(pdef_keys[0]))
299 #endif
300 		      );
301 
302 	if (keys == NULL) {
303 		ERROR("%s:%d Failed to allocate memory.\n", __func__, __LINE__);
304 		return 1;
305 	}
306 
307 	memcpy(&keys[0], &def_keys[0], (num_def_keys * sizeof(def_keys[0])));
308 #ifdef PDEF_KEYS
309 	memcpy(&keys[num_def_keys], &pdef_keys[0],
310 		(num_pdef_keys * sizeof(pdef_keys[0])));
311 
312 	num_keys = num_def_keys + num_pdef_keys;
313 #else
314 	num_keys = num_def_keys;
315 #endif
316 		   ;
317 
318 	for (i = 0; i < num_keys; i++) {
319 		key = &keys[i];
320 		if (key->opt != NULL) {
321 			cmd_opt.long_opt.name = key->opt;
322 			cmd_opt.long_opt.has_arg = required_argument;
323 			cmd_opt.long_opt.flag = NULL;
324 			cmd_opt.long_opt.val = CMD_OPT_KEY;
325 			cmd_opt.help_msg = key->help_msg;
326 			cmd_opt_add(&cmd_opt);
327 		}
328 	}
329 
330 	return 0;
331 }
332 
333 key_t *key_get_by_opt(const char *opt)
334 {
335 	key_t *key;
336 	unsigned int i;
337 
338 	/* Sequential search. This is not a performance concern since the number
339 	 * of keys is bounded and the code runs on a host machine */
340 	for (i = 0; i < num_keys; i++) {
341 		key = &keys[i];
342 		if (0 == strcmp(key->opt, opt)) {
343 			return key;
344 		}
345 	}
346 
347 	return NULL;
348 }
349 
350 void key_cleanup(void)
351 {
352 	unsigned int i;
353 
354 	for (i = 0; i < num_keys; i++) {
355 		EVP_PKEY_free(keys[i].key);
356 		if (keys[i].fn != NULL) {
357 			void *ptr = keys[i].fn;
358 
359 			free(ptr);
360 			keys[i].fn = NULL;
361 		}
362 	}
363 	free(keys);
364 }
365 
366