blob: 0f80cce9b7a7ae0ee32cd6300af8f845994ae8bc [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
Justin Chadwellfebe86c2019-07-29 17:13:45 +010044static int key_create_rsa(key_t *key, int key_bits)
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
Justin Chadwellfebe86c2019-07-29 17:13:45 +010066 if (!RSA_generate_key_ex(rsa, key_bits, e, NULL)) {
Michalis Pappas38628942017-10-06 16:11:44 +080067 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
Justin Chadwellfebe86c2019-07-29 17:13:45 +010085static int key_create_ecdsa(key_t *key, int key_bits)
Juan Castilloa2224ab2015-06-30 13:36:57 +010086{
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
Justin Chadwellfebe86c2019-07-29 17:13:45 +0100112typedef int (*key_create_fn_t)(key_t *key, int key_bits);
Juan Castilloa2224ab2015-06-30 13:36:57 +0100113static 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 */
Juan Castilloa2224ab2015-06-30 13:36:57 +0100115#ifndef OPENSSL_NO_EC
Qixiang Xu31f3bb92017-09-22 16:21:41 +0800116 key_create_ecdsa, /* KEY_ALG_ECDSA */
Juan Castilloa2224ab2015-06-30 13:36:57 +0100117#endif /* OPENSSL_NO_EC */
118};
119
Justin Chadwellfebe86c2019-07-29 17:13:45 +0100120int key_create(key_t *key, int type, int key_bits)
Juan Castilloa2224ab2015-06-30 13:36:57 +0100121{
122 if (type >= KEY_ALG_MAX_NUM) {
123 printf("Invalid key type\n");
124 return 0;
125 }
126
Juan Castilloa2224ab2015-06-30 13:36:57 +0100127 if (key_create_fn[type]) {
Justin Chadwellfebe86c2019-07-29 17:13:45 +0100128 return key_create_fn[type](key, key_bits);
Juan Castilloa2224ab2015-06-30 13:36:57 +0100129 }
Juan Castillof9f39c32015-06-01 16:34:23 +0100130
Juan Castillo11abdcd2014-10-21 11:30:42 +0100131 return 0;
132}
133
Juan Castillof9f39c32015-06-01 16:34:23 +0100134int key_load(key_t *key, unsigned int *err_code)
Juan Castillo11abdcd2014-10-21 11:30:42 +0100135{
Masahiro Yamada48cb5e52017-02-06 19:47:44 +0900136 FILE *fp;
137 EVP_PKEY *k;
Juan Castillo11abdcd2014-10-21 11:30:42 +0100138
Juan Castillo11abdcd2014-10-21 11:30:42 +0100139 if (key->fn) {
140 /* Load key from file */
141 fp = fopen(key->fn, "r");
142 if (fp) {
Juan Castillof9f39c32015-06-01 16:34:23 +0100143 k = PEM_read_PrivateKey(fp, &key->key, NULL, NULL);
Juan Castillo11abdcd2014-10-21 11:30:42 +0100144 fclose(fp);
145 if (k) {
Juan Castillof9f39c32015-06-01 16:34:23 +0100146 *err_code = KEY_ERR_NONE;
Juan Castillo11abdcd2014-10-21 11:30:42 +0100147 return 1;
148 } else {
Juan Castillof9f39c32015-06-01 16:34:23 +0100149 ERROR("Cannot load key from %s\n", key->fn);
150 *err_code = KEY_ERR_LOAD;
Juan Castillo11abdcd2014-10-21 11:30:42 +0100151 }
152 } else {
Juan Castillof9f39c32015-06-01 16:34:23 +0100153 WARN("Cannot open file %s\n", key->fn);
154 *err_code = KEY_ERR_OPEN;
Juan Castillo11abdcd2014-10-21 11:30:42 +0100155 }
156 } else {
Juan Castillof9f39c32015-06-01 16:34:23 +0100157 WARN("Key filename not specified\n");
158 *err_code = KEY_ERR_FILENAME;
Juan Castillo11abdcd2014-10-21 11:30:42 +0100159 }
160
Juan Castillo11abdcd2014-10-21 11:30:42 +0100161 return 0;
162}
163
164int key_store(key_t *key)
165{
Masahiro Yamada48cb5e52017-02-06 19:47:44 +0900166 FILE *fp;
Juan Castillo11abdcd2014-10-21 11:30:42 +0100167
168 if (key->fn) {
169 fp = fopen(key->fn, "w");
170 if (fp) {
171 PEM_write_PrivateKey(fp, key->key,
172 NULL, NULL, 0, NULL, NULL);
173 fclose(fp);
174 return 1;
175 } else {
176 ERROR("Cannot create file %s\n", key->fn);
177 }
178 } else {
179 ERROR("Key filename not specified\n");
180 }
181
182 return 0;
183}
Juan Castillo1218dd52015-07-03 16:23:16 +0100184
185int key_init(void)
186{
Juan Castillo212f7382015-12-15 16:37:57 +0000187 cmd_opt_t cmd_opt;
Juan Castillo1218dd52015-07-03 16:23:16 +0100188 key_t *key;
Juan Castillo1218dd52015-07-03 16:23:16 +0100189 unsigned int i;
190
191 for (i = 0; i < num_keys; i++) {
192 key = &keys[i];
193 if (key->opt != NULL) {
Juan Castillo212f7382015-12-15 16:37:57 +0000194 cmd_opt.long_opt.name = key->opt;
195 cmd_opt.long_opt.has_arg = required_argument;
196 cmd_opt.long_opt.flag = NULL;
197 cmd_opt.long_opt.val = CMD_OPT_KEY;
198 cmd_opt.help_msg = key->help_msg;
199 cmd_opt_add(&cmd_opt);
Juan Castillo1218dd52015-07-03 16:23:16 +0100200 }
201 }
202
Masahiro Yamada48cb5e52017-02-06 19:47:44 +0900203 return 0;
Juan Castillo1218dd52015-07-03 16:23:16 +0100204}
205
206key_t *key_get_by_opt(const char *opt)
207{
Masahiro Yamada48cb5e52017-02-06 19:47:44 +0900208 key_t *key;
Juan Castillo1218dd52015-07-03 16:23:16 +0100209 unsigned int i;
210
211 /* Sequential search. This is not a performance concern since the number
212 * of keys is bounded and the code runs on a host machine */
213 for (i = 0; i < num_keys; i++) {
214 key = &keys[i];
215 if (0 == strcmp(key->opt, opt)) {
216 return key;
217 }
218 }
219
220 return NULL;
221}