1 /* 2 * Copyright (c) 2015-2022, ARM Limited and Contributors. All rights reserved. 3 * 4 * SPDX-License-Identifier: BSD-3-Clause 5 */ 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 16 #include "cert.h" 17 #include "cmd_opt.h" 18 #include "debug.h" 19 #include "key.h" 20 #include "sha.h" 21 22 #define MAX_FILENAME_LEN 1024 23 24 key_t *keys; 25 unsigned int num_keys; 26 27 /* 28 * Create a new key container 29 */ 30 int key_new(key_t *key) 31 { 32 /* Create key pair container */ 33 key->key = EVP_PKEY_new(); 34 if (key->key == NULL) { 35 return 0; 36 } 37 38 return 1; 39 } 40 41 static int key_create_rsa(key_t *key, int key_bits) 42 { 43 EVP_PKEY *rsa = EVP_RSA_gen(key_bits); 44 if (rsa == NULL) { 45 printf("Cannot generate RSA key\n"); 46 return 0; 47 } 48 key->key = rsa; 49 return 1; 50 } 51 52 #ifndef OPENSSL_NO_EC 53 static int key_create_ecdsa(key_t *key, int key_bits) 54 { 55 EVP_PKEY *ec = EVP_EC_gen("prime256v1"); 56 if (ec == NULL) { 57 printf("Cannot generate EC key\n"); 58 return 0; 59 } 60 key->key = ec; 61 return 1; 62 } 63 #endif /* OPENSSL_NO_EC */ 64 65 typedef int (*key_create_fn_t)(key_t *key, int key_bits); 66 static const key_create_fn_t key_create_fn[KEY_ALG_MAX_NUM] = { 67 key_create_rsa, /* KEY_ALG_RSA */ 68 #ifndef OPENSSL_NO_EC 69 key_create_ecdsa, /* KEY_ALG_ECDSA */ 70 #endif /* OPENSSL_NO_EC */ 71 }; 72 73 int key_create(key_t *key, int type, int key_bits) 74 { 75 if (type >= KEY_ALG_MAX_NUM) { 76 printf("Invalid key type\n"); 77 return 0; 78 } 79 80 if (key_create_fn[type]) { 81 return key_create_fn[type](key, key_bits); 82 } 83 84 return 0; 85 } 86 87 int key_load(key_t *key, unsigned int *err_code) 88 { 89 FILE *fp; 90 EVP_PKEY *k; 91 92 if (key->fn) { 93 /* Load key from file */ 94 fp = fopen(key->fn, "r"); 95 if (fp) { 96 k = PEM_read_PrivateKey(fp, &key->key, NULL, NULL); 97 fclose(fp); 98 if (k) { 99 *err_code = KEY_ERR_NONE; 100 return 1; 101 } else { 102 ERROR("Cannot load key from %s\n", key->fn); 103 *err_code = KEY_ERR_LOAD; 104 } 105 } else { 106 WARN("Cannot open file %s\n", key->fn); 107 *err_code = KEY_ERR_OPEN; 108 } 109 } else { 110 WARN("Key filename not specified\n"); 111 *err_code = KEY_ERR_FILENAME; 112 } 113 114 return 0; 115 } 116 117 int key_store(key_t *key) 118 { 119 FILE *fp; 120 121 if (key->fn) { 122 fp = fopen(key->fn, "w"); 123 if (fp) { 124 PEM_write_PrivateKey(fp, key->key, 125 NULL, NULL, 0, NULL, NULL); 126 fclose(fp); 127 return 1; 128 } else { 129 ERROR("Cannot create file %s\n", key->fn); 130 } 131 } else { 132 ERROR("Key filename not specified\n"); 133 } 134 135 return 0; 136 } 137 138 int key_init(void) 139 { 140 cmd_opt_t cmd_opt; 141 key_t *key; 142 unsigned int i; 143 144 keys = malloc((num_def_keys * sizeof(def_keys[0])) 145 #ifdef PDEF_KEYS 146 + (num_pdef_keys * sizeof(pdef_keys[0])) 147 #endif 148 ); 149 150 if (keys == NULL) { 151 ERROR("%s:%d Failed to allocate memory.\n", __func__, __LINE__); 152 return 1; 153 } 154 155 memcpy(&keys[0], &def_keys[0], (num_def_keys * sizeof(def_keys[0]))); 156 #ifdef PDEF_KEYS 157 memcpy(&keys[num_def_keys], &pdef_keys[0], 158 (num_pdef_keys * sizeof(pdef_keys[0]))); 159 160 num_keys = num_def_keys + num_pdef_keys; 161 #else 162 num_keys = num_def_keys; 163 #endif 164 ; 165 166 for (i = 0; i < num_keys; i++) { 167 key = &keys[i]; 168 if (key->opt != NULL) { 169 cmd_opt.long_opt.name = key->opt; 170 cmd_opt.long_opt.has_arg = required_argument; 171 cmd_opt.long_opt.flag = NULL; 172 cmd_opt.long_opt.val = CMD_OPT_KEY; 173 cmd_opt.help_msg = key->help_msg; 174 cmd_opt_add(&cmd_opt); 175 } 176 } 177 178 return 0; 179 } 180 181 key_t *key_get_by_opt(const char *opt) 182 { 183 key_t *key; 184 unsigned int i; 185 186 /* Sequential search. This is not a performance concern since the number 187 * of keys is bounded and the code runs on a host machine */ 188 for (i = 0; i < num_keys; i++) { 189 key = &keys[i]; 190 if (0 == strcmp(key->opt, opt)) { 191 return key; 192 } 193 } 194 195 return NULL; 196 } 197