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