xref: /rk3399_ARM-atf/tools/cert_create/src/key.c (revision ccbfd01d95b9b35acb3e2ca5f25379ce8fa0ed1c)
16f971622SJuan Castillo /*
2*ccbfd01dSManish V Badarkhe  * Copyright (c) 2015-2024, Arm Limited and Contributors. All rights reserved.
36f971622SJuan Castillo  *
482cb2c1aSdp-arm  * SPDX-License-Identifier: BSD-3-Clause
56f971622SJuan Castillo  */
66f971622SJuan Castillo 
7c512c89cSlaurenw-arm #include <assert.h>
86f971622SJuan Castillo #include <getopt.h>
96f971622SJuan Castillo #include <stdio.h>
106f971622SJuan Castillo #include <stdlib.h>
116f971622SJuan Castillo #include <string.h>
126f971622SJuan Castillo 
13616b3ce2SRobin van der Gracht /* Suppress OpenSSL engine deprecation warnings */
14616b3ce2SRobin van der Gracht #define OPENSSL_SUPPRESS_DEPRECATED
15616b3ce2SRobin van der Gracht 
166f971622SJuan Castillo #include <openssl/conf.h>
17616b3ce2SRobin van der Gracht #include <openssl/engine.h>
186f971622SJuan Castillo #include <openssl/evp.h>
196f971622SJuan Castillo #include <openssl/pem.h>
206f971622SJuan Castillo 
216f971622SJuan Castillo #include "cert.h"
22ad2c1a9aSJuan Castillo #include "cmd_opt.h"
236f971622SJuan Castillo #include "debug.h"
246f971622SJuan Castillo #include "key.h"
256f971622SJuan Castillo #include "sha.h"
266f971622SJuan Castillo 
276f971622SJuan Castillo #define MAX_FILENAME_LEN		1024
286f971622SJuan Castillo 
29*ccbfd01dSManish V Badarkhe cert_key_t *keys;
30b94bf967SPankaj Gupta unsigned int num_keys;
31b94bf967SPankaj Gupta 
32cf2dd17dSJuan Pablo Conde #if !USING_OPENSSL3
336f971622SJuan Castillo /*
34ccbf890eSJuan Castillo  * Create a new key container
356f971622SJuan Castillo  */
36*ccbfd01dSManish V Badarkhe int key_new(cert_key_t *key)
37ccbf890eSJuan Castillo {
38ccbf890eSJuan Castillo 	/* Create key pair container */
39ccbf890eSJuan Castillo 	key->key = EVP_PKEY_new();
40ccbf890eSJuan Castillo 	if (key->key == NULL) {
41ccbf890eSJuan Castillo 		return 0;
42ccbf890eSJuan Castillo 	}
43ccbf890eSJuan Castillo 
44ccbf890eSJuan Castillo 	return 1;
45ccbf890eSJuan Castillo }
46cf2dd17dSJuan Pablo Conde #endif
47ccbf890eSJuan Castillo 
48*ccbfd01dSManish V Badarkhe static int key_create_rsa(cert_key_t *key, int key_bits)
496f971622SJuan Castillo {
50cf2dd17dSJuan Pablo Conde #if USING_OPENSSL3
519bc52d33SJuan Pablo Conde 	EVP_PKEY *rsa = EVP_RSA_gen(key_bits);
52ccbf890eSJuan Castillo 	if (rsa == NULL) {
53742c4e14SMichalis Pappas 		printf("Cannot generate RSA key\n");
54ed2a76eaSJuan Castillo 		return 0;
55ed2a76eaSJuan Castillo 	}
569bc52d33SJuan Pablo Conde 	key->key = rsa;
579bc52d33SJuan Pablo Conde 	return 1;
58cf2dd17dSJuan Pablo Conde #else
59cf2dd17dSJuan Pablo Conde 	BIGNUM *e;
60cf2dd17dSJuan Pablo Conde 	RSA *rsa = NULL;
61cf2dd17dSJuan Pablo Conde 
62cf2dd17dSJuan Pablo Conde 	e = BN_new();
63cf2dd17dSJuan Pablo Conde 	if (e == NULL) {
64cf2dd17dSJuan Pablo Conde 		printf("Cannot create RSA exponent\n");
65cf2dd17dSJuan Pablo Conde 		return 0;
66cf2dd17dSJuan Pablo Conde 	}
67cf2dd17dSJuan Pablo Conde 
68cf2dd17dSJuan Pablo Conde 	if (!BN_set_word(e, RSA_F4)) {
69cf2dd17dSJuan Pablo Conde 		printf("Cannot assign RSA exponent\n");
70cf2dd17dSJuan Pablo Conde 		goto err2;
71cf2dd17dSJuan Pablo Conde 	}
72cf2dd17dSJuan Pablo Conde 
73cf2dd17dSJuan Pablo Conde 	rsa = RSA_new();
74cf2dd17dSJuan Pablo Conde 	if (rsa == NULL) {
75cf2dd17dSJuan Pablo Conde 		printf("Cannot create RSA key\n");
76cf2dd17dSJuan Pablo Conde 		goto err2;
77cf2dd17dSJuan Pablo Conde 	}
78cf2dd17dSJuan Pablo Conde 
79cf2dd17dSJuan Pablo Conde 	if (!RSA_generate_key_ex(rsa, key_bits, e, NULL)) {
80cf2dd17dSJuan Pablo Conde 		printf("Cannot generate RSA key\n");
81cf2dd17dSJuan Pablo Conde 		goto err;
82cf2dd17dSJuan Pablo Conde 	}
83cf2dd17dSJuan Pablo Conde 
84cf2dd17dSJuan Pablo Conde 	if (!EVP_PKEY_assign_RSA(key->key, rsa)) {
85cf2dd17dSJuan Pablo Conde 		printf("Cannot assign RSA key\n");
86cf2dd17dSJuan Pablo Conde 		goto err;
87cf2dd17dSJuan Pablo Conde 	}
88cf2dd17dSJuan Pablo Conde 
89cf2dd17dSJuan Pablo Conde 	BN_free(e);
90cf2dd17dSJuan Pablo Conde 	return 1;
91cf2dd17dSJuan Pablo Conde 
92cf2dd17dSJuan Pablo Conde err:
93cf2dd17dSJuan Pablo Conde 	RSA_free(rsa);
94cf2dd17dSJuan Pablo Conde err2:
95cf2dd17dSJuan Pablo Conde 	BN_free(e);
96cf2dd17dSJuan Pablo Conde 	return 0;
97cf2dd17dSJuan Pablo Conde #endif
989bc52d33SJuan Pablo Conde }
99ed2a76eaSJuan Castillo 
100ed2a76eaSJuan Castillo #ifndef OPENSSL_NO_EC
101cf2dd17dSJuan Pablo Conde #if USING_OPENSSL3
102*ccbfd01dSManish V Badarkhe static int key_create_ecdsa(cert_key_t *key, int key_bits, const char *curve)
103e78ba69eSLionel Debieve {
104e78ba69eSLionel Debieve 	EVP_PKEY *ec = EVP_EC_gen(curve);
105ccbf890eSJuan Castillo 	if (ec == NULL) {
106ccbf890eSJuan Castillo 		printf("Cannot generate EC key\n");
107ed2a76eaSJuan Castillo 		return 0;
108ed2a76eaSJuan Castillo 	}
109e78ba69eSLionel Debieve 
1109bc52d33SJuan Pablo Conde 	key->key = ec;
1119bc52d33SJuan Pablo Conde 	return 1;
112e78ba69eSLionel Debieve }
113e78ba69eSLionel Debieve 
114*ccbfd01dSManish V Badarkhe static int key_create_ecdsa_nist(cert_key_t *key, int key_bits)
115e78ba69eSLionel Debieve {
116c512c89cSlaurenw-arm 	if (key_bits == 384) {
117c512c89cSlaurenw-arm 		return key_create_ecdsa(key, key_bits, "secp384r1");
118c512c89cSlaurenw-arm 	} else {
119c512c89cSlaurenw-arm 		assert(key_bits == 256);
120e78ba69eSLionel Debieve 		return key_create_ecdsa(key, key_bits, "prime256v1");
121e78ba69eSLionel Debieve 	}
122c512c89cSlaurenw-arm }
123e78ba69eSLionel Debieve 
124*ccbfd01dSManish V Badarkhe static int key_create_ecdsa_brainpool_r(cert_key_t *key, int key_bits)
125e78ba69eSLionel Debieve {
126e78ba69eSLionel Debieve 	return key_create_ecdsa(key, key_bits, "brainpoolP256r1");
127e78ba69eSLionel Debieve }
128e78ba69eSLionel Debieve 
129*ccbfd01dSManish V Badarkhe static int key_create_ecdsa_brainpool_t(cert_key_t *key, int key_bits)
130e78ba69eSLionel Debieve {
131e78ba69eSLionel Debieve 	return key_create_ecdsa(key, key_bits, "brainpoolP256t1");
132e78ba69eSLionel Debieve }
133cf2dd17dSJuan Pablo Conde #else
134*ccbfd01dSManish V Badarkhe static int key_create_ecdsa(cert_key_t *key, int key_bits, const int curve_id)
135e78ba69eSLionel Debieve {
136cf2dd17dSJuan Pablo Conde 	EC_KEY *ec;
137cf2dd17dSJuan Pablo Conde 
138e78ba69eSLionel Debieve 	ec = EC_KEY_new_by_curve_name(curve_id);
139cf2dd17dSJuan Pablo Conde 	if (ec == NULL) {
140cf2dd17dSJuan Pablo Conde 		printf("Cannot create EC key\n");
141cf2dd17dSJuan Pablo Conde 		return 0;
142cf2dd17dSJuan Pablo Conde 	}
143cf2dd17dSJuan Pablo Conde 	if (!EC_KEY_generate_key(ec)) {
144cf2dd17dSJuan Pablo Conde 		printf("Cannot generate EC key\n");
145cf2dd17dSJuan Pablo Conde 		goto err;
146cf2dd17dSJuan Pablo Conde 	}
147cf2dd17dSJuan Pablo Conde 	EC_KEY_set_flags(ec, EC_PKEY_NO_PARAMETERS);
148cf2dd17dSJuan Pablo Conde 	EC_KEY_set_asn1_flag(ec, OPENSSL_EC_NAMED_CURVE);
149cf2dd17dSJuan Pablo Conde 	if (!EVP_PKEY_assign_EC_KEY(key->key, ec)) {
150cf2dd17dSJuan Pablo Conde 		printf("Cannot assign EC key\n");
151cf2dd17dSJuan Pablo Conde 		goto err;
152cf2dd17dSJuan Pablo Conde 	}
153cf2dd17dSJuan Pablo Conde 
154cf2dd17dSJuan Pablo Conde 	return 1;
155cf2dd17dSJuan Pablo Conde 
156cf2dd17dSJuan Pablo Conde err:
157cf2dd17dSJuan Pablo Conde 	EC_KEY_free(ec);
158cf2dd17dSJuan Pablo Conde 	return 0;
1599bc52d33SJuan Pablo Conde }
160e78ba69eSLionel Debieve 
161*ccbfd01dSManish V Badarkhe static int key_create_ecdsa_nist(cert_key_t *key, int key_bits)
162e78ba69eSLionel Debieve {
163c512c89cSlaurenw-arm 	if (key_bits == 384) {
164c512c89cSlaurenw-arm 		return key_create_ecdsa(key, key_bits, NID_secp384r1);
165c512c89cSlaurenw-arm 	} else {
166c512c89cSlaurenw-arm 		assert(key_bits == 256);
167e78ba69eSLionel Debieve 		return key_create_ecdsa(key, key_bits, NID_X9_62_prime256v1);
168e78ba69eSLionel Debieve 	}
169c512c89cSlaurenw-arm }
170e78ba69eSLionel Debieve 
171c0c280dfSDonald Chan #if OPENSSL_VERSION_NUMBER >= 0x10100000L
172*ccbfd01dSManish V Badarkhe static int key_create_ecdsa_brainpool_r(cert_key_t *key, int key_bits)
173e78ba69eSLionel Debieve {
174e78ba69eSLionel Debieve 	return key_create_ecdsa(key, key_bits, NID_brainpoolP256r1);
175e78ba69eSLionel Debieve }
176e78ba69eSLionel Debieve 
177*ccbfd01dSManish V Badarkhe static int key_create_ecdsa_brainpool_t(cert_key_t *key, int key_bits)
178e78ba69eSLionel Debieve {
179e78ba69eSLionel Debieve 	return key_create_ecdsa(key, key_bits, NID_brainpoolP256t1);
180e78ba69eSLionel Debieve }
181c0c280dfSDonald Chan #endif
182e78ba69eSLionel Debieve #endif /* USING_OPENSSL3 */
183ed2a76eaSJuan Castillo #endif /* OPENSSL_NO_EC */
184ed2a76eaSJuan Castillo 
185*ccbfd01dSManish V Badarkhe typedef int (*key_create_fn_t)(cert_key_t *key, int key_bits);
186ed2a76eaSJuan Castillo static const key_create_fn_t key_create_fn[KEY_ALG_MAX_NUM] = {
187e78ba69eSLionel Debieve 	[KEY_ALG_RSA] = key_create_rsa,
188ed2a76eaSJuan Castillo #ifndef OPENSSL_NO_EC
189e78ba69eSLionel Debieve 	[KEY_ALG_ECDSA_NIST] = key_create_ecdsa_nist,
190c0c280dfSDonald Chan #if OPENSSL_VERSION_NUMBER >= 0x10100000L
191e78ba69eSLionel Debieve 	[KEY_ALG_ECDSA_BRAINPOOL_R] = key_create_ecdsa_brainpool_r,
192e78ba69eSLionel Debieve 	[KEY_ALG_ECDSA_BRAINPOOL_T] = key_create_ecdsa_brainpool_t,
193c0c280dfSDonald Chan #endif
194ed2a76eaSJuan Castillo #endif /* OPENSSL_NO_EC */
195ed2a76eaSJuan Castillo };
196ed2a76eaSJuan Castillo 
197*ccbfd01dSManish V Badarkhe int key_create(cert_key_t *key, int type, int key_bits)
198ed2a76eaSJuan Castillo {
199ed2a76eaSJuan Castillo 	if (type >= KEY_ALG_MAX_NUM) {
200ed2a76eaSJuan Castillo 		printf("Invalid key type\n");
201ed2a76eaSJuan Castillo 		return 0;
202ed2a76eaSJuan Castillo 	}
203ed2a76eaSJuan Castillo 
204ed2a76eaSJuan Castillo 	if (key_create_fn[type]) {
205dfe0f4c2SJustin Chadwell 		return key_create_fn[type](key, key_bits);
206ed2a76eaSJuan Castillo 	}
207ccbf890eSJuan Castillo 
2086f971622SJuan Castillo 	return 0;
2096f971622SJuan Castillo }
2106f971622SJuan Castillo 
211616b3ce2SRobin van der Gracht static EVP_PKEY *key_load_pkcs11(const char *uri)
212616b3ce2SRobin van der Gracht {
213616b3ce2SRobin van der Gracht 	char *key_pass;
214616b3ce2SRobin van der Gracht 	EVP_PKEY *pkey;
215616b3ce2SRobin van der Gracht 	ENGINE *e;
216616b3ce2SRobin van der Gracht 
217616b3ce2SRobin van der Gracht 	ENGINE_load_builtin_engines();
218616b3ce2SRobin van der Gracht 	e = ENGINE_by_id("pkcs11");
219616b3ce2SRobin van der Gracht 	if (!e) {
220616b3ce2SRobin van der Gracht 		fprintf(stderr, "Cannot Load PKCS#11 ENGINE\n");
221616b3ce2SRobin van der Gracht 		return NULL;
222616b3ce2SRobin van der Gracht 	}
223616b3ce2SRobin van der Gracht 
224616b3ce2SRobin van der Gracht 	if (!ENGINE_init(e)) {
225616b3ce2SRobin van der Gracht 		fprintf(stderr, "Cannot ENGINE_init\n");
226616b3ce2SRobin van der Gracht 		goto err;
227616b3ce2SRobin van der Gracht 	}
228616b3ce2SRobin van der Gracht 
229616b3ce2SRobin van der Gracht 	key_pass = getenv("PKCS11_PIN");
230616b3ce2SRobin van der Gracht 	if (key_pass) {
231616b3ce2SRobin van der Gracht 		if (!ENGINE_ctrl_cmd_string(e, "PIN", key_pass, 0)) {
232616b3ce2SRobin van der Gracht 			fprintf(stderr, "Cannot Set PKCS#11 PIN\n");
233616b3ce2SRobin van der Gracht 			goto err;
234616b3ce2SRobin van der Gracht 		}
235616b3ce2SRobin van der Gracht 	}
236616b3ce2SRobin van der Gracht 
237616b3ce2SRobin van der Gracht 	pkey = ENGINE_load_private_key(e, uri, NULL, NULL);
238616b3ce2SRobin van der Gracht 	if (pkey)
239616b3ce2SRobin van der Gracht 		return pkey;
240616b3ce2SRobin van der Gracht err:
241616b3ce2SRobin van der Gracht 	ENGINE_free(e);
242616b3ce2SRobin van der Gracht 	return NULL;
243616b3ce2SRobin van der Gracht 
244616b3ce2SRobin van der Gracht }
245616b3ce2SRobin van der Gracht 
246*ccbfd01dSManish V Badarkhe unsigned int key_load(cert_key_t *key)
2476f971622SJuan Castillo {
248bb3b0c0bSSandrine Bailleux 	if (key->fn == NULL) {
249bb3b0c0bSSandrine Bailleux 		VERBOSE("Key not specified\n");
250bb3b0c0bSSandrine Bailleux 		return KEY_ERR_FILENAME;
251bb3b0c0bSSandrine Bailleux 	}
2526f971622SJuan Castillo 
253bb3b0c0bSSandrine Bailleux 	if (strncmp(key->fn, "pkcs11:", 7) == 0) {
254616b3ce2SRobin van der Gracht 		/* Load key through pkcs11 */
255616b3ce2SRobin van der Gracht 		key->key = key_load_pkcs11(key->fn);
256616b3ce2SRobin van der Gracht 	} else {
2576f971622SJuan Castillo 		/* Load key from file */
258bb3b0c0bSSandrine Bailleux 		FILE *fp = fopen(key->fn, "r");
259bb3b0c0bSSandrine Bailleux 		if (fp == NULL) {
260616b3ce2SRobin van der Gracht 			WARN("Cannot open file %s\n", key->fn);
261bb3b0c0bSSandrine Bailleux 			return KEY_ERR_OPEN;
2626f971622SJuan Castillo 		}
2636f971622SJuan Castillo 
264bb3b0c0bSSandrine Bailleux 		key->key = PEM_read_PrivateKey(fp, NULL, NULL, NULL);
265bb3b0c0bSSandrine Bailleux 		fclose(fp);
266bb3b0c0bSSandrine Bailleux 	}
267bb3b0c0bSSandrine Bailleux 
268bb3b0c0bSSandrine Bailleux 	if (key->key == NULL) {
269bb3b0c0bSSandrine Bailleux 		ERROR("Cannot load key from %s\n", key->fn);
270bb3b0c0bSSandrine Bailleux 		return KEY_ERR_LOAD;
271bb3b0c0bSSandrine Bailleux 	}
272bb3b0c0bSSandrine Bailleux 
273bb3b0c0bSSandrine Bailleux 	return KEY_ERR_NONE;
2746f971622SJuan Castillo }
2756f971622SJuan Castillo 
276*ccbfd01dSManish V Badarkhe int key_store(cert_key_t *key)
2776f971622SJuan Castillo {
278c893c733SMasahiro Yamada 	FILE *fp;
2796f971622SJuan Castillo 
2806f971622SJuan Castillo 	if (key->fn) {
281616b3ce2SRobin van der Gracht 		if (!strncmp(key->fn, "pkcs11:", 7)) {
282616b3ce2SRobin van der Gracht 			ERROR("PKCS11 URI provided instead of a file");
283616b3ce2SRobin van der Gracht 			return 0;
284616b3ce2SRobin van der Gracht 		}
2856f971622SJuan Castillo 		fp = fopen(key->fn, "w");
2866f971622SJuan Castillo 		if (fp) {
2876f971622SJuan Castillo 			PEM_write_PrivateKey(fp, key->key,
2886f971622SJuan Castillo 					NULL, NULL, 0, NULL, NULL);
2896f971622SJuan Castillo 			fclose(fp);
2906f971622SJuan Castillo 			return 1;
2916f971622SJuan Castillo 		} else {
2926f971622SJuan Castillo 			ERROR("Cannot create file %s\n", key->fn);
2936f971622SJuan Castillo 		}
2946f971622SJuan Castillo 	} else {
2956f971622SJuan Castillo 		ERROR("Key filename not specified\n");
2966f971622SJuan Castillo 	}
2976f971622SJuan Castillo 
2986f971622SJuan Castillo 	return 0;
2996f971622SJuan Castillo }
300ad2c1a9aSJuan Castillo 
301ad2c1a9aSJuan Castillo int key_init(void)
302ad2c1a9aSJuan Castillo {
303159807e2SJuan Castillo 	cmd_opt_t cmd_opt;
304*ccbfd01dSManish V Badarkhe 	cert_key_t *key;
305ad2c1a9aSJuan Castillo 	unsigned int i;
306ad2c1a9aSJuan Castillo 
307b94bf967SPankaj Gupta 	keys = malloc((num_def_keys * sizeof(def_keys[0]))
308b94bf967SPankaj Gupta #ifdef PDEF_KEYS
309b94bf967SPankaj Gupta 		      + (num_pdef_keys * sizeof(pdef_keys[0]))
310b94bf967SPankaj Gupta #endif
311b94bf967SPankaj Gupta 		      );
312b94bf967SPankaj Gupta 
313b94bf967SPankaj Gupta 	if (keys == NULL) {
314b94bf967SPankaj Gupta 		ERROR("%s:%d Failed to allocate memory.\n", __func__, __LINE__);
315b94bf967SPankaj Gupta 		return 1;
316b94bf967SPankaj Gupta 	}
317b94bf967SPankaj Gupta 
318b94bf967SPankaj Gupta 	memcpy(&keys[0], &def_keys[0], (num_def_keys * sizeof(def_keys[0])));
319b94bf967SPankaj Gupta #ifdef PDEF_KEYS
320b94bf967SPankaj Gupta 	memcpy(&keys[num_def_keys], &pdef_keys[0],
321b94bf967SPankaj Gupta 		(num_pdef_keys * sizeof(pdef_keys[0])));
322b94bf967SPankaj Gupta 
323b94bf967SPankaj Gupta 	num_keys = num_def_keys + num_pdef_keys;
324b94bf967SPankaj Gupta #else
325b94bf967SPankaj Gupta 	num_keys = num_def_keys;
326b94bf967SPankaj Gupta #endif
327b94bf967SPankaj Gupta 		   ;
328b94bf967SPankaj Gupta 
329ad2c1a9aSJuan Castillo 	for (i = 0; i < num_keys; i++) {
330ad2c1a9aSJuan Castillo 		key = &keys[i];
331ad2c1a9aSJuan Castillo 		if (key->opt != NULL) {
332159807e2SJuan Castillo 			cmd_opt.long_opt.name = key->opt;
333159807e2SJuan Castillo 			cmd_opt.long_opt.has_arg = required_argument;
334159807e2SJuan Castillo 			cmd_opt.long_opt.flag = NULL;
335159807e2SJuan Castillo 			cmd_opt.long_opt.val = CMD_OPT_KEY;
336159807e2SJuan Castillo 			cmd_opt.help_msg = key->help_msg;
337159807e2SJuan Castillo 			cmd_opt_add(&cmd_opt);
338ad2c1a9aSJuan Castillo 		}
339ad2c1a9aSJuan Castillo 	}
340ad2c1a9aSJuan Castillo 
341c893c733SMasahiro Yamada 	return 0;
342ad2c1a9aSJuan Castillo }
343ad2c1a9aSJuan Castillo 
344*ccbfd01dSManish V Badarkhe cert_key_t *key_get_by_opt(const char *opt)
345ad2c1a9aSJuan Castillo {
346*ccbfd01dSManish V Badarkhe 	cert_key_t *key;
347ad2c1a9aSJuan Castillo 	unsigned int i;
348ad2c1a9aSJuan Castillo 
349ad2c1a9aSJuan Castillo 	/* Sequential search. This is not a performance concern since the number
350ad2c1a9aSJuan Castillo 	 * of keys is bounded and the code runs on a host machine */
351ad2c1a9aSJuan Castillo 	for (i = 0; i < num_keys; i++) {
352ad2c1a9aSJuan Castillo 		key = &keys[i];
353ad2c1a9aSJuan Castillo 		if (0 == strcmp(key->opt, opt)) {
354ad2c1a9aSJuan Castillo 			return key;
355ad2c1a9aSJuan Castillo 		}
356ad2c1a9aSJuan Castillo 	}
357ad2c1a9aSJuan Castillo 
358ad2c1a9aSJuan Castillo 	return NULL;
359ad2c1a9aSJuan Castillo }
360cf2dd17dSJuan Pablo Conde 
361cf2dd17dSJuan Pablo Conde void key_cleanup(void)
362cf2dd17dSJuan Pablo Conde {
363cf2dd17dSJuan Pablo Conde 	unsigned int i;
364cf2dd17dSJuan Pablo Conde 
365cf2dd17dSJuan Pablo Conde 	for (i = 0; i < num_keys; i++) {
366cf2dd17dSJuan Pablo Conde 		EVP_PKEY_free(keys[i].key);
367cf2dd17dSJuan Pablo Conde 		if (keys[i].fn != NULL) {
368cf2dd17dSJuan Pablo Conde 			void *ptr = keys[i].fn;
369cf2dd17dSJuan Pablo Conde 
370cf2dd17dSJuan Pablo Conde 			free(ptr);
371cf2dd17dSJuan Pablo Conde 			keys[i].fn = NULL;
372cf2dd17dSJuan Pablo Conde 		}
373cf2dd17dSJuan Pablo Conde 	}
374cf2dd17dSJuan Pablo Conde 	free(keys);
375cf2dd17dSJuan Pablo Conde }
376cf2dd17dSJuan Pablo Conde 
377