From dfe0f4c2999cef10f9c8fb6115e53891f6b2c190 Mon Sep 17 00:00:00 2001 From: Justin Chadwell Date: Mon, 29 Jul 2019 17:13:45 +0100 Subject: [PATCH] Add cert_create tool support for RSA key sizes cert_tool is now able to accept a command line option for specifying the key size. It now supports the following options: 1024, 2048 (default), 3072 and 4096. This is also modifiable by TFA using the build flag KEY_SIZE. Change-Id: Ifadecf84ade3763249ee8cc7123a8178f606f0e5 Signed-off-by: Justin Chadwell --- make_helpers/tbbr/tbbr_tools.mk | 4 ++- tools/cert_create/include/key.h | 19 ++++++++--- tools/cert_create/src/key.c | 12 +++---- tools/cert_create/src/main.c | 56 +++++++++++++++++++++++++++++++-- 4 files changed, 78 insertions(+), 13 deletions(-) diff --git a/make_helpers/tbbr/tbbr_tools.mk b/make_helpers/tbbr/tbbr_tools.mk index afc007a4..9c47cc7c 100644 --- a/make_helpers/tbbr/tbbr_tools.mk +++ b/make_helpers/tbbr/tbbr_tools.mk @@ -1,5 +1,5 @@ # -# Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved. +# Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved. # # SPDX-License-Identifier: BSD-3-Clause # @@ -21,6 +21,7 @@ # Build options added by this file: # # KEY_ALG +# KEY_SIZE # ROT_KEY # TRUSTED_WORLD_KEY # NON_TRUSTED_WORLD_KEY @@ -52,6 +53,7 @@ $(eval $(call TOOL_ADD_PAYLOAD,${FWU_CERT},--fwu-cert,,FWU_)) # packed in the FIP). Developers can use their own keys by specifying the proper # build option in the command line when building the Trusted Firmware $(if ${KEY_ALG},$(eval $(call CERT_ADD_CMD_OPT,${KEY_ALG},--key-alg))) +$(if ${KEY_SIZE},$(eval $(call CERT_ADD_CMD_OPT,${KEY_SIZE},--key-size))) $(if ${HASH_ALG},$(eval $(call CERT_ADD_CMD_OPT,${HASH_ALG},--hash-alg))) $(if ${ROT_KEY},$(eval $(call CERT_ADD_CMD_OPT,${ROT_KEY},--rot-key))) $(if ${ROT_KEY},$(eval $(call CERT_ADD_CMD_OPT,${ROT_KEY},--rot-key,FWU_))) diff --git a/tools/cert_create/include/key.h b/tools/cert_create/include/key.h index 310a77f3..c08beb8b 100644 --- a/tools/cert_create/include/key.h +++ b/tools/cert_create/include/key.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2017, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -9,8 +9,6 @@ #include -#define RSA_KEY_BITS 2048 - /* Error codes */ enum { KEY_ERR_NONE, @@ -30,6 +28,9 @@ enum { KEY_ALG_MAX_NUM }; +/* Maximum number of valid key sizes per algorithm */ +#define KEY_SIZE_MAX_NUM 4 + /* Supported hash algorithms */ enum{ HASH_ALG_SHA256, @@ -37,6 +38,16 @@ enum{ HASH_ALG_SHA512, }; +/* Supported key sizes */ +/* NOTE: the first item in each array is the default key size */ +static const unsigned int KEY_SIZES[KEY_ALG_MAX_NUM][KEY_SIZE_MAX_NUM] = { + { 2048, 1024, 3072, 4096 }, /* KEY_ALG_RSA */ + { 2048, 1024, 3072, 4096 }, /* KEY_ALG_RSA_1_5 */ +#ifndef OPENSSL_NO_EC + {} /* KEY_ALG_ECDSA */ +#endif /* OPENSSL_NO_EC */ +}; + /* * This structure contains the relevant information to create the keys * required to sign the certificates. @@ -58,7 +69,7 @@ typedef struct key_s { int key_init(void); key_t *key_get_by_opt(const char *opt); int key_new(key_t *key); -int key_create(key_t *key, int type); +int key_create(key_t *key, int type, int key_bits); int key_load(key_t *key, unsigned int *err_code); int key_store(key_t *key); diff --git a/tools/cert_create/src/key.c b/tools/cert_create/src/key.c index fece7708..93d31f7c 100644 --- a/tools/cert_create/src/key.c +++ b/tools/cert_create/src/key.c @@ -41,7 +41,7 @@ int key_new(key_t *key) return 1; } -static int key_create_rsa(key_t *key) +static int key_create_rsa(key_t *key, int key_bits) { BIGNUM *e; RSA *rsa = NULL; @@ -63,7 +63,7 @@ static int key_create_rsa(key_t *key) goto err; } - if (!RSA_generate_key_ex(rsa, RSA_KEY_BITS, e, NULL)) { + if (!RSA_generate_key_ex(rsa, key_bits, e, NULL)) { printf("Cannot generate RSA key\n"); goto err; } @@ -82,7 +82,7 @@ err: } #ifndef OPENSSL_NO_EC -static int key_create_ecdsa(key_t *key) +static int key_create_ecdsa(key_t *key, int key_bits) { EC_KEY *ec; @@ -109,7 +109,7 @@ err: } #endif /* OPENSSL_NO_EC */ -typedef int (*key_create_fn_t)(key_t *key); +typedef int (*key_create_fn_t)(key_t *key, int key_bits); static const key_create_fn_t key_create_fn[KEY_ALG_MAX_NUM] = { key_create_rsa, /* KEY_ALG_RSA */ key_create_rsa, /* KEY_ALG_RSA_1_5 */ @@ -118,7 +118,7 @@ static const key_create_fn_t key_create_fn[KEY_ALG_MAX_NUM] = { #endif /* OPENSSL_NO_EC */ }; -int key_create(key_t *key, int type) +int key_create(key_t *key, int type, int key_bits) { if (type >= KEY_ALG_MAX_NUM) { printf("Invalid key type\n"); @@ -126,7 +126,7 @@ int key_create(key_t *key, int type) } if (key_create_fn[type]) { - return key_create_fn[type](key); + return key_create_fn[type](key, key_bits); } return 0; diff --git a/tools/cert_create/src/main.c b/tools/cert_create/src/main.c index 0f588cc8..44a65eb9 100644 --- a/tools/cert_create/src/main.c +++ b/tools/cert_create/src/main.c @@ -10,6 +10,7 @@ #include #include #include +#include #include #include @@ -69,6 +70,7 @@ /* Global options */ static int key_alg; static int hash_alg; +static int key_size; static int new_keys; static int save_keys; static int print_cert; @@ -155,6 +157,18 @@ static int get_key_alg(const char *key_alg_str) return -1; } +static int get_key_size(const char *key_size_str) +{ + char *end; + long key_size; + + key_size = strtol(key_size_str, &end, 10); + if (*end != '\0') + return -1; + + return key_size; +} + static int get_hash_alg(const char *hash_alg_str) { int i; @@ -174,6 +188,7 @@ static void check_cmd_params(void) ext_t *ext; key_t *key; int i, j; + bool valid_size; /* Only save new keys */ if (save_keys && !new_keys) { @@ -181,6 +196,26 @@ static void check_cmd_params(void) exit(1); } + /* Validate key-size */ + valid_size = false; + for (i = 0; i < KEY_SIZE_MAX_NUM; i++) { + if (key_size == KEY_SIZES[key_alg][i]) { + valid_size = true; + break; + } + } + if (!valid_size) { + ERROR("'%d' is not a valid key size for '%s'\n", + key_size, key_algs_str[key_alg]); + NOTICE("Valid sizes are: "); + for (i = 0; i < KEY_SIZE_MAX_NUM && + KEY_SIZES[key_alg][i] != 0; i++) { + printf("%d ", KEY_SIZES[key_alg][i]); + } + printf("\n"); + exit(1); + } + /* Check that all required options have been specified in the * command line */ for (i = 0; i < num_certs; i++) { @@ -245,6 +280,10 @@ static const cmd_opt_t common_cmd_opt[] = { "Key algorithm: 'rsa' (default) - RSAPSS scheme as per \ PKCS#1 v2.1, 'rsa_1_5' - RSA PKCS#1 v1.5, 'ecdsa'" }, + { + { "key-size", required_argument, NULL, 'b' }, + "Key size (for supported algorithms)." + }, { { "hash-alg", required_argument, NULL, 's' }, "Hash algorithm : 'sha256' (default), 'sha384', 'sha512'" @@ -286,6 +325,7 @@ int main(int argc, char *argv[]) /* Set default options */ key_alg = KEY_ALG_RSA; hash_alg = HASH_ALG_SHA256; + key_size = -1; /* Add common command line options */ for (i = 0; i < NUM_ELEM(common_cmd_opt); i++) { @@ -315,7 +355,7 @@ int main(int argc, char *argv[]) while (1) { /* getopt_long stores the option index here. */ - c = getopt_long(argc, argv, "a:hknps:", cmd_opt, &opt_idx); + c = getopt_long(argc, argv, "a:b:hknps:", cmd_opt, &opt_idx); /* Detect the end of the options. */ if (c == -1) { @@ -330,6 +370,13 @@ int main(int argc, char *argv[]) exit(1); } break; + case 'b': + key_size = get_key_size(optarg); + if (key_size <= 0) { + ERROR("Invalid key size '%s'\n", optarg); + exit(1); + } + break; case 'h': print_help(argv[0], cmd_opt); exit(0); @@ -371,6 +418,11 @@ int main(int argc, char *argv[]) } } + /* Select a reasonable default key-size */ + if (key_size == -1) { + key_size = KEY_SIZES[key_alg][0]; + } + /* Check command line arguments */ check_cmd_params(); @@ -413,7 +465,7 @@ int main(int argc, char *argv[]) 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)) { + if (!key_create(&keys[i], key_alg, key_size)) { ERROR("Error creating key '%s'\n", keys[i].desc); exit(1); } -- 2.30.2