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