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