aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile1
-rw-r--r--tools/cert_create/Makefile5
-rw-r--r--tools/cert_create/include/key.h19
-rw-r--r--tools/cert_create/src/key.c96
-rw-r--r--tools/cert_create/src/main.c83
5 files changed, 161 insertions, 43 deletions
diff --git a/Makefile b/Makefile
index 7f7ca8e7..faa6554a 100644
--- a/Makefile
+++ b/Makefile
@@ -337,6 +337,7 @@ ifneq (${GENERATE_COT},0)
$(eval CRT_ARGS += $(if ${TRUSTED_WORLD_KEY}, --trusted-world-key ${TRUSTED_WORLD_KEY}))
$(eval CRT_ARGS += $(if ${NON_TRUSTED_WORLD_KEY}, --non-trusted-world-key ${NON_TRUSTED_WORLD_KEY}))
$(eval CRT_ARGS += --trusted-key-cert ${TRUSTED_KEY_CERT})
+ $(eval CRT_ARGS += $(if ${KEY_ALG}, --key-alg ${KEY_ALG}))
endif
# Check Trusted Board Boot options
diff --git a/tools/cert_create/Makefile b/tools/cert_create/Makefile
index eac8cec8..a4bd76fb 100644
--- a/tools/cert_create/Makefile
+++ b/tools/cert_create/Makefile
@@ -33,6 +33,7 @@ PLAT := none
V := 0
DEBUG := 0
BINARY := ${PROJECT}
+OPENSSL_DIR := /usr
OBJECTS := src/cert.o \
src/ext.o \
@@ -69,8 +70,8 @@ endif
# Make soft links and include from local directory otherwise wrong headers
# could get pulled in from firmware tree.
-INC_DIR := -I ./include -I ${PLAT_INCLUDE}
-LIB_DIR :=
+INC_DIR := -I ./include -I ${PLAT_INCLUDE} -I ${OPENSSL_DIR}/include
+LIB_DIR := -L ${OPENSSL_DIR}/lib
LIB := -lssl -lcrypto
CC := gcc
diff --git a/tools/cert_create/include/key.h b/tools/cert_create/include/key.h
index 88197500..dfb31508 100644
--- a/tools/cert_create/include/key.h
+++ b/tools/cert_create/include/key.h
@@ -35,6 +35,21 @@
#define RSA_KEY_BITS 2048
+/* Error codes */
+enum {
+ KEY_ERR_NONE,
+ KEY_ERR_MALLOC,
+ KEY_ERR_FILENAME,
+ KEY_ERR_OPEN,
+ KEY_ERR_LOAD
+};
+
+/* Supported key algorithms */
+enum {
+ KEY_ALG_RSA,
+ KEY_ALG_ECDSA
+};
+
/*
* This structure contains the relevant information to create the keys
* required to sign the certificates.
@@ -50,8 +65,8 @@ typedef struct key_s {
EVP_PKEY *key; /* Key container */
} key_t;
-int key_new(key_t *key);
-int key_load(key_t *key);
+int key_create(key_t *key, int type);
+int key_load(key_t *key, unsigned int *err_code);
int key_store(key_t *key);
#endif /* KEY_H_ */
diff --git a/tools/cert_create/src/key.c b/tools/cert_create/src/key.c
index b5737d93..2137bf7d 100644
--- a/tools/cert_create/src/key.c
+++ b/tools/cert_create/src/key.c
@@ -46,41 +46,81 @@
#define MAX_FILENAME_LEN 1024
/*
- * Create a new key
+ * Create a new key container
*/
-int key_new(key_t *key)
+static int key_new(key_t *key)
{
- RSA *rsa = NULL;
- EVP_PKEY *k = NULL;
-
/* Create key pair container */
- k = EVP_PKEY_new();
- if (k == NULL) {
+ key->key = EVP_PKEY_new();
+ if (key->key == NULL) {
return 0;
}
- /* Generate a new RSA key */
- rsa = RSA_generate_key(RSA_KEY_BITS, RSA_F4, NULL, NULL);
- if (EVP_PKEY_assign_RSA(k, rsa)) {
- key->key = k;
- return 1;
- } else {
- printf("Cannot assign RSA key\n");
+ return 1;
+}
+
+int key_create(key_t *key, int type)
+{
+ RSA *rsa = NULL;
+ EC_KEY *ec = NULL;
+
+ /* Create OpenSSL key container */
+ if (!key_new(key)) {
+ goto err;
}
- if (k)
- EVP_PKEY_free(k);
+ switch (type) {
+ case KEY_ALG_RSA:
+ /* Generate a new RSA key */
+ rsa = RSA_generate_key(RSA_KEY_BITS, RSA_F4, NULL, NULL);
+ if (rsa == NULL) {
+ printf("Cannot create RSA key\n");
+ goto err;
+ }
+ if (!EVP_PKEY_assign_RSA(key->key, rsa)) {
+ printf("Cannot assign RSA key\n");
+ goto err;
+ }
+ break;
+ case KEY_ALG_ECDSA:
+ /* Generate a new ECDSA key */
+ ec = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1);
+ if (ec == NULL) {
+ printf("Cannot create EC key\n");
+ goto err;
+ }
+ if (!EC_KEY_generate_key(ec)) {
+ printf("Cannot generate EC key\n");
+ goto err;
+ }
+ EC_KEY_set_flags(ec, EC_PKEY_NO_PARAMETERS);
+ EC_KEY_set_asn1_flag(ec, OPENSSL_EC_NAMED_CURVE);
+ if (!EVP_PKEY_assign_EC_KEY(key->key, ec)) {
+ printf("Cannot assign EC key\n");
+ goto err;
+ }
+ break;
+ default:
+ goto err;
+ }
+
+ return 1;
+
+err:
+ RSA_free(rsa);
+ EC_KEY_free(ec);
+
return 0;
}
-int key_load(key_t *key)
+int key_load(key_t *key, unsigned int *err_code)
{
FILE *fp = NULL;
EVP_PKEY *k = NULL;
- /* Create key pair container */
- k = EVP_PKEY_new();
- if (k == NULL) {
+ /* Create OpenSSL key container */
+ if (!key_new(key)) {
+ *err_code = KEY_ERR_MALLOC;
return 0;
}
@@ -88,24 +128,24 @@ int key_load(key_t *key)
/* Load key from file */
fp = fopen(key->fn, "r");
if (fp) {
- k = PEM_read_PrivateKey(fp, &k, NULL, NULL);
+ k = PEM_read_PrivateKey(fp, &key->key, NULL, NULL);
fclose(fp);
if (k) {
- key->key = k;
+ *err_code = KEY_ERR_NONE;
return 1;
} else {
- ERROR("Cannot read key from %s\n", key->fn);
+ ERROR("Cannot load key from %s\n", key->fn);
+ *err_code = KEY_ERR_LOAD;
}
} else {
- ERROR("Cannot open file %s\n", key->fn);
+ WARN("Cannot open file %s\n", key->fn);
+ *err_code = KEY_ERR_OPEN;
}
} else {
- ERROR("Key filename not specified\n");
+ WARN("Key filename not specified\n");
+ *err_code = KEY_ERR_FILENAME;
}
- if (k)
- EVP_PKEY_free(k);
-
return 0;
}
diff --git a/tools/cert_create/src/main.c b/tools/cert_create/src/main.c
index 2af5247f..77faf42e 100644
--- a/tools/cert_create/src/main.c
+++ b/tools/cert_create/src/main.c
@@ -80,6 +80,7 @@
#define VAL_DAYS 7300
#define ID_TO_BIT_MASK(id) (1 << id)
#define NVCOUNTER_VALUE 0
+#define NUM_ELEM(x) ((sizeof(x)) / (sizeof(x[0])))
/* Files */
enum {
@@ -112,6 +113,7 @@ enum {
};
/* Global options */
+static int key_alg;
static int new_keys;
static int save_keys;
static int print_cert;
@@ -138,6 +140,11 @@ static char *strdup(const char *str)
return dup;
}
+static const char *key_algs_str[] = {
+ [KEY_ALG_RSA] = "rsa",
+ [KEY_ALG_ECDSA] = "ecdsa"
+};
+
/* Command line options */
static const struct option long_opt[] = {
/* Binary images */
@@ -166,6 +173,7 @@ static const struct option long_opt[] = {
{"bl32-key", required_argument, 0, BL32_KEY_ID},
{"bl33-key", required_argument, 0, BL33_KEY_ID},
/* Common options */
+ {"key-alg", required_argument, 0, 'a'},
{"help", no_argument, 0, 'h'},
{"save-keys", no_argument, 0, 'k'},
{"new-chain", no_argument, 0, 'n'},
@@ -189,6 +197,7 @@ static void print_help(const char *cmd)
printf(" --%s <file> \\\n", long_opt[i].name);
}
printf("\n");
+ printf("-a Key algorithm: rsa (default), ecdsa\n");
printf("-h Print help and exit\n");
printf("-k Save key pairs into files. Filenames must be provided\n");
printf("-n Generate new key pairs if no key files are provided\n");
@@ -198,8 +207,27 @@ static void print_help(const char *cmd)
exit(0);
}
+static int get_key_alg(const char *key_alg_str)
+{
+ int i;
+
+ for (i = 0 ; i < NUM_ELEM(key_algs_str) ; i++) {
+ if (0 == strcmp(key_alg_str, key_algs_str[i])) {
+ return i;
+ }
+ }
+
+ return -1;
+}
+
static void check_cmd_params(void)
{
+ /* Only save new keys */
+ if (save_keys && !new_keys) {
+ ERROR("Only new keys can be saved to disk\n");
+ exit(1);
+ }
+
/* BL2, BL31 and BL33 are mandatory */
if (certs[BL2_CERT].bin == NULL) {
ERROR("BL2 image not specified\n");
@@ -276,15 +304,19 @@ int main(int argc, char *argv[])
FILE *file = NULL;
int i, tz_nvctr_nid, ntz_nvctr_nid, hash_nid, pk_nid;
int c, opt_idx = 0;
+ unsigned int err_code;
unsigned char md[SHA256_DIGEST_LENGTH];
const EVP_MD *md_info;
NOTICE("CoT Generation Tool: %s\n", build_msg);
NOTICE("Target platform: %s\n", platform_msg);
+ /* Set default options */
+ key_alg = KEY_ALG_RSA;
+
while (1) {
/* getopt_long stores the option index here. */
- c = getopt_long(argc, argv, "hknp", long_opt, &opt_idx);
+ c = getopt_long(argc, argv, "ahknp", long_opt, &opt_idx);
/* Detect the end of the options. */
if (c == -1) {
@@ -292,6 +324,13 @@ int main(int argc, char *argv[])
}
switch (c) {
+ case 'a':
+ key_alg = get_key_alg(optarg);
+ if (key_alg < 0) {
+ ERROR("Invalid key algorithm '%s'\n", optarg);
+ exit(1);
+ }
+ break;
case 'h':
print_help(argv[0]);
break;
@@ -399,19 +438,41 @@ int main(int argc, char *argv[])
CHECK_OID(ntz_nvctr_nid, NTZ_FW_NVCOUNTER_OID);
/* Load private keys from files (or generate new ones) */
- if (new_keys) {
- for (i = 0 ; i < NUM_KEYS ; i++) {
- if (!key_new(&keys[i])) {
- ERROR("Error creating %s\n", keys[i].desc);
- exit(1);
- }
+ for (i = 0 ; i < NUM_KEYS ; i++) {
+ /* First try to load the key from disk */
+ if (key_load(&keys[i], &err_code)) {
+ /* Key loaded successfully */
+ continue;
}
- } else {
- for (i = 0 ; i < NUM_KEYS ; i++) {
- if (!key_load(&keys[i])) {
- ERROR("Error loading %s\n", keys[i].desc);
+
+ /* Key not loaded. Check the error code */
+ if (err_code == KEY_ERR_MALLOC) {
+ /* Cannot allocate memory. Abort. */
+ ERROR("Malloc error while loading '%s'\n", keys[i].fn);
+ exit(1);
+ } else if (err_code == KEY_ERR_LOAD) {
+ /* File exists, but it does not contain a valid private
+ * key. Abort. */
+ ERROR("Error loading '%s'\n", keys[i].fn);
+ exit(1);
+ }
+
+ /* File does not exist, could not be opened or no filename was
+ * given */
+ if (new_keys) {
+ /* Try to create a new key */
+ NOTICE("Creating new key for '%s'\n", keys[i].desc);
+ if (!key_create(&keys[i], key_alg)) {
+ ERROR("Error creating key '%s'\n", keys[i].desc);
exit(1);
}
+ } else {
+ if (err_code == KEY_ERR_OPEN) {
+ ERROR("Error opening '%s'\n", keys[i].fn);
+ } else {
+ ERROR("Key '%s' not specified\n", keys[i].desc);
+ }
+ exit(1);
}
}