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