blob: fece7708538f75c3cc62808ae6611157f17a11c4 [file] [log] [blame]
Juan Castillo11abdcd2014-10-21 11:30:42 +01001/*
Justin Chadwellfa3ec4c2019-08-12 12:19:21 +01002 * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved.
Juan Castillo11abdcd2014-10-21 11:30:42 +01003 *
dp-armfa3cf0b2017-05-03 09:38:09 +01004 * SPDX-License-Identifier: BSD-3-Clause
Juan Castillo11abdcd2014-10-21 11:30:42 +01005 */
6
7#include <getopt.h>
8#include <stdio.h>
9#include <stdlib.h>
10#include <string.h>
11
12#include <openssl/conf.h>
13#include <openssl/evp.h>
14#include <openssl/pem.h>
15
Masahiro Yamadaa27c1662017-05-22 12:11:24 +090016#if USE_TBBR_DEFS
17#include <tbbr_oid.h>
18#else
19#include <platform_oid.h>
20#endif
21
Juan Castillo11abdcd2014-10-21 11:30:42 +010022#include "cert.h"
Juan Castillo1218dd52015-07-03 16:23:16 +010023#include "cmd_opt.h"
Juan Castillo11abdcd2014-10-21 11:30:42 +010024#include "debug.h"
25#include "key.h"
Juan Castillo11abdcd2014-10-21 11:30:42 +010026#include "sha.h"
27
28#define MAX_FILENAME_LEN 1024
29
30/*
Juan Castillof9f39c32015-06-01 16:34:23 +010031 * Create a new key container
Juan Castillo11abdcd2014-10-21 11:30:42 +010032 */
Masahiro Yamadabccb1092017-02-06 21:15:01 +090033int key_new(key_t *key)
Juan Castillo11abdcd2014-10-21 11:30:42 +010034{
Juan Castillo11abdcd2014-10-21 11:30:42 +010035 /* Create key pair container */
Juan Castillof9f39c32015-06-01 16:34:23 +010036 key->key = EVP_PKEY_new();
37 if (key->key == NULL) {
Juan Castillo11abdcd2014-10-21 11:30:42 +010038 return 0;
39 }
40
Juan Castillof9f39c32015-06-01 16:34:23 +010041 return 1;
42}
43
Juan Castilloa2224ab2015-06-30 13:36:57 +010044static int key_create_rsa(key_t *key)
Juan Castillof9f39c32015-06-01 16:34:23 +010045{
Michalis Pappas38628942017-10-06 16:11:44 +080046 BIGNUM *e;
47 RSA *rsa = NULL;
Juan Castillof9f39c32015-06-01 16:34:23 +010048
Michalis Pappas38628942017-10-06 16:11:44 +080049 e = BN_new();
50 if (e == NULL) {
51 printf("Cannot create RSA exponent\n");
52 goto err;
53 }
54
55 if (!BN_set_word(e, RSA_F4)) {
56 printf("Cannot assign RSA exponent\n");
57 goto err;
58 }
59
60 rsa = RSA_new();
Juan Castilloa2224ab2015-06-30 13:36:57 +010061 if (rsa == NULL) {
62 printf("Cannot create RSA key\n");
Juan Castillof9f39c32015-06-01 16:34:23 +010063 goto err;
64 }
Michalis Pappas38628942017-10-06 16:11:44 +080065
66 if (!RSA_generate_key_ex(rsa, RSA_KEY_BITS, e, NULL)) {
67 printf("Cannot generate RSA key\n");
68 goto err;
69 }
70
Juan Castilloa2224ab2015-06-30 13:36:57 +010071 if (!EVP_PKEY_assign_RSA(key->key, rsa)) {
72 printf("Cannot assign RSA key\n");
Juan Castillof9f39c32015-06-01 16:34:23 +010073 goto err;
Juan Castillo11abdcd2014-10-21 11:30:42 +010074 }
75
Justin Chadwellfa3ec4c2019-08-12 12:19:21 +010076 BN_free(e);
Juan Castillof9f39c32015-06-01 16:34:23 +010077 return 1;
Juan Castillof9f39c32015-06-01 16:34:23 +010078err:
79 RSA_free(rsa);
Michalis Pappas38628942017-10-06 16:11:44 +080080 BN_free(e);
Juan Castilloa2224ab2015-06-30 13:36:57 +010081 return 0;
82}
83
84#ifndef OPENSSL_NO_EC
85static int key_create_ecdsa(key_t *key)
86{
Masahiro Yamada48cb5e52017-02-06 19:47:44 +090087 EC_KEY *ec;
Juan Castilloa2224ab2015-06-30 13:36:57 +010088
89 ec = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1);
90 if (ec == NULL) {
91 printf("Cannot create EC key\n");
92 goto err;
93 }
94 if (!EC_KEY_generate_key(ec)) {
95 printf("Cannot generate EC key\n");
96 goto err;
97 }
98 EC_KEY_set_flags(ec, EC_PKEY_NO_PARAMETERS);
99 EC_KEY_set_asn1_flag(ec, OPENSSL_EC_NAMED_CURVE);
100 if (!EVP_PKEY_assign_EC_KEY(key->key, ec)) {
101 printf("Cannot assign EC key\n");
102 goto err;
103 }
104
105 return 1;
106err:
Juan Castillof9f39c32015-06-01 16:34:23 +0100107 EC_KEY_free(ec);
Juan Castilloa2224ab2015-06-30 13:36:57 +0100108 return 0;
109}
110#endif /* OPENSSL_NO_EC */
111
112typedef int (*key_create_fn_t)(key_t *key);
113static const key_create_fn_t key_create_fn[KEY_ALG_MAX_NUM] = {
Qixiang Xu31f3bb92017-09-22 16:21:41 +0800114 key_create_rsa, /* KEY_ALG_RSA */
115 key_create_rsa, /* KEY_ALG_RSA_1_5 */
Juan Castilloa2224ab2015-06-30 13:36:57 +0100116#ifndef OPENSSL_NO_EC
Qixiang Xu31f3bb92017-09-22 16:21:41 +0800117 key_create_ecdsa, /* KEY_ALG_ECDSA */
Juan Castilloa2224ab2015-06-30 13:36:57 +0100118#endif /* OPENSSL_NO_EC */
119};
120
121int key_create(key_t *key, int type)
122{
123 if (type >= KEY_ALG_MAX_NUM) {
124 printf("Invalid key type\n");
125 return 0;
126 }
127
Juan Castilloa2224ab2015-06-30 13:36:57 +0100128 if (key_create_fn[type]) {
129 return key_create_fn[type](key);
130 }
Juan Castillof9f39c32015-06-01 16:34:23 +0100131
Juan Castillo11abdcd2014-10-21 11:30:42 +0100132 return 0;
133}
134
Juan Castillof9f39c32015-06-01 16:34:23 +0100135int key_load(key_t *key, unsigned int *err_code)
Juan Castillo11abdcd2014-10-21 11:30:42 +0100136{
Masahiro Yamada48cb5e52017-02-06 19:47:44 +0900137 FILE *fp;
138 EVP_PKEY *k;
Juan Castillo11abdcd2014-10-21 11:30:42 +0100139
Juan Castillo11abdcd2014-10-21 11:30:42 +0100140 if (key->fn) {
141 /* Load key from file */
142 fp = fopen(key->fn, "r");
143 if (fp) {
Juan Castillof9f39c32015-06-01 16:34:23 +0100144 k = PEM_read_PrivateKey(fp, &key->key, NULL, NULL);
Juan Castillo11abdcd2014-10-21 11:30:42 +0100145 fclose(fp);
146 if (k) {
Juan Castillof9f39c32015-06-01 16:34:23 +0100147 *err_code = KEY_ERR_NONE;
Juan Castillo11abdcd2014-10-21 11:30:42 +0100148 return 1;
149 } else {
Juan Castillof9f39c32015-06-01 16:34:23 +0100150 ERROR("Cannot load key from %s\n", key->fn);
151 *err_code = KEY_ERR_LOAD;
Juan Castillo11abdcd2014-10-21 11:30:42 +0100152 }
153 } else {
Juan Castillof9f39c32015-06-01 16:34:23 +0100154 WARN("Cannot open file %s\n", key->fn);
155 *err_code = KEY_ERR_OPEN;
Juan Castillo11abdcd2014-10-21 11:30:42 +0100156 }
157 } else {
Juan Castillof9f39c32015-06-01 16:34:23 +0100158 WARN("Key filename not specified\n");
159 *err_code = KEY_ERR_FILENAME;
Juan Castillo11abdcd2014-10-21 11:30:42 +0100160 }
161
Juan Castillo11abdcd2014-10-21 11:30:42 +0100162 return 0;
163}
164
165int key_store(key_t *key)
166{
Masahiro Yamada48cb5e52017-02-06 19:47:44 +0900167 FILE *fp;
Juan Castillo11abdcd2014-10-21 11:30:42 +0100168
169 if (key->fn) {
170 fp = fopen(key->fn, "w");
171 if (fp) {
172 PEM_write_PrivateKey(fp, key->key,
173 NULL, NULL, 0, NULL, NULL);
174 fclose(fp);
175 return 1;
176 } else {
177 ERROR("Cannot create file %s\n", key->fn);
178 }
179 } else {
180 ERROR("Key filename not specified\n");
181 }
182
183 return 0;
184}
Juan Castillo1218dd52015-07-03 16:23:16 +0100185
186int key_init(void)
187{
Juan Castillo212f7382015-12-15 16:37:57 +0000188 cmd_opt_t cmd_opt;
Juan Castillo1218dd52015-07-03 16:23:16 +0100189 key_t *key;
Juan Castillo1218dd52015-07-03 16:23:16 +0100190 unsigned int i;
191
192 for (i = 0; i < num_keys; i++) {
193 key = &keys[i];
194 if (key->opt != NULL) {
Juan Castillo212f7382015-12-15 16:37:57 +0000195 cmd_opt.long_opt.name = key->opt;
196 cmd_opt.long_opt.has_arg = required_argument;
197 cmd_opt.long_opt.flag = NULL;
198 cmd_opt.long_opt.val = CMD_OPT_KEY;
199 cmd_opt.help_msg = key->help_msg;
200 cmd_opt_add(&cmd_opt);
Juan Castillo1218dd52015-07-03 16:23:16 +0100201 }
202 }
203
Masahiro Yamada48cb5e52017-02-06 19:47:44 +0900204 return 0;
Juan Castillo1218dd52015-07-03 16:23:16 +0100205}
206
207key_t *key_get_by_opt(const char *opt)
208{
Masahiro Yamada48cb5e52017-02-06 19:47:44 +0900209 key_t *key;
Juan Castillo1218dd52015-07-03 16:23:16 +0100210 unsigned int i;
211
212 /* Sequential search. This is not a performance concern since the number
213 * of keys is bounded and the code runs on a host machine */
214 for (i = 0; i < num_keys; i++) {
215 key = &keys[i];
216 if (0 == strcmp(key->opt, opt)) {
217 return key;
218 }
219 }
220
221 return NULL;
222}