Commit dfe0f4c2 authored by Justin Chadwell's avatar Justin Chadwell
Browse files

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: default avatarJustin Chadwell <justin.chadwell@arm.com>
parent aacff749
# #
# 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 # SPDX-License-Identifier: BSD-3-Clause
# #
...@@ -21,6 +21,7 @@ ...@@ -21,6 +21,7 @@
# Build options added by this file: # Build options added by this file:
# #
# KEY_ALG # KEY_ALG
# KEY_SIZE
# ROT_KEY # ROT_KEY
# TRUSTED_WORLD_KEY # TRUSTED_WORLD_KEY
# NON_TRUSTED_WORLD_KEY # NON_TRUSTED_WORLD_KEY
...@@ -52,6 +53,7 @@ $(eval $(call TOOL_ADD_PAYLOAD,${FWU_CERT},--fwu-cert,,FWU_)) ...@@ -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 # 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 # 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_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 ${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)))
$(if ${ROT_KEY},$(eval $(call CERT_ADD_CMD_OPT,${ROT_KEY},--rot-key,FWU_))) $(if ${ROT_KEY},$(eval $(call CERT_ADD_CMD_OPT,${ROT_KEY},--rot-key,FWU_)))
......
/* /*
* 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 * SPDX-License-Identifier: BSD-3-Clause
*/ */
...@@ -9,8 +9,6 @@ ...@@ -9,8 +9,6 @@
#include <openssl/ossl_typ.h> #include <openssl/ossl_typ.h>
#define RSA_KEY_BITS 2048
/* Error codes */ /* Error codes */
enum { enum {
KEY_ERR_NONE, KEY_ERR_NONE,
...@@ -30,6 +28,9 @@ enum { ...@@ -30,6 +28,9 @@ enum {
KEY_ALG_MAX_NUM KEY_ALG_MAX_NUM
}; };
/* Maximum number of valid key sizes per algorithm */
#define KEY_SIZE_MAX_NUM 4
/* Supported hash algorithms */ /* Supported hash algorithms */
enum{ enum{
HASH_ALG_SHA256, HASH_ALG_SHA256,
...@@ -37,6 +38,16 @@ enum{ ...@@ -37,6 +38,16 @@ enum{
HASH_ALG_SHA512, 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 * This structure contains the relevant information to create the keys
* required to sign the certificates. * required to sign the certificates.
...@@ -58,7 +69,7 @@ typedef struct key_s { ...@@ -58,7 +69,7 @@ typedef struct key_s {
int key_init(void); int key_init(void);
key_t *key_get_by_opt(const char *opt); key_t *key_get_by_opt(const char *opt);
int key_new(key_t *key); 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_load(key_t *key, unsigned int *err_code);
int key_store(key_t *key); int key_store(key_t *key);
......
...@@ -41,7 +41,7 @@ int key_new(key_t *key) ...@@ -41,7 +41,7 @@ int key_new(key_t *key)
return 1; return 1;
} }
static int key_create_rsa(key_t *key) static int key_create_rsa(key_t *key, int key_bits)
{ {
BIGNUM *e; BIGNUM *e;
RSA *rsa = NULL; RSA *rsa = NULL;
...@@ -63,7 +63,7 @@ static int key_create_rsa(key_t *key) ...@@ -63,7 +63,7 @@ static int key_create_rsa(key_t *key)
goto err; 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"); printf("Cannot generate RSA key\n");
goto err; goto err;
} }
...@@ -82,7 +82,7 @@ err: ...@@ -82,7 +82,7 @@ err:
} }
#ifndef OPENSSL_NO_EC #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; EC_KEY *ec;
...@@ -109,7 +109,7 @@ err: ...@@ -109,7 +109,7 @@ err:
} }
#endif /* OPENSSL_NO_EC */ #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] = { 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 */
key_create_rsa, /* KEY_ALG_RSA_1_5 */ 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] = { ...@@ -118,7 +118,7 @@ static const key_create_fn_t key_create_fn[KEY_ALG_MAX_NUM] = {
#endif /* OPENSSL_NO_EC */ #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) { if (type >= KEY_ALG_MAX_NUM) {
printf("Invalid key type\n"); printf("Invalid key type\n");
...@@ -126,7 +126,7 @@ int key_create(key_t *key, int type) ...@@ -126,7 +126,7 @@ int key_create(key_t *key, int type)
} }
if (key_create_fn[type]) { if (key_create_fn[type]) {
return key_create_fn[type](key); return key_create_fn[type](key, key_bits);
} }
return 0; return 0;
......
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <stdbool.h>
#include <openssl/conf.h> #include <openssl/conf.h>
#include <openssl/engine.h> #include <openssl/engine.h>
...@@ -69,6 +70,7 @@ ...@@ -69,6 +70,7 @@
/* Global options */ /* Global options */
static int key_alg; static int key_alg;
static int hash_alg; static int hash_alg;
static int key_size;
static int new_keys; static int new_keys;
static int save_keys; static int save_keys;
static int print_cert; static int print_cert;
...@@ -155,6 +157,18 @@ static int get_key_alg(const char *key_alg_str) ...@@ -155,6 +157,18 @@ static int get_key_alg(const char *key_alg_str)
return -1; 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) static int get_hash_alg(const char *hash_alg_str)
{ {
int i; int i;
...@@ -174,6 +188,7 @@ static void check_cmd_params(void) ...@@ -174,6 +188,7 @@ static void check_cmd_params(void)
ext_t *ext; ext_t *ext;
key_t *key; key_t *key;
int i, j; int i, j;
bool valid_size;
/* Only save new keys */ /* Only save new keys */
if (save_keys && !new_keys) { if (save_keys && !new_keys) {
...@@ -181,6 +196,26 @@ static void check_cmd_params(void) ...@@ -181,6 +196,26 @@ static void check_cmd_params(void)
exit(1); 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 /* Check that all required options have been specified in the
* command line */ * command line */
for (i = 0; i < num_certs; i++) { for (i = 0; i < num_certs; i++) {
...@@ -245,6 +280,10 @@ static const cmd_opt_t common_cmd_opt[] = { ...@@ -245,6 +280,10 @@ static const cmd_opt_t common_cmd_opt[] = {
"Key algorithm: 'rsa' (default) - RSAPSS scheme as per \ "Key algorithm: 'rsa' (default) - RSAPSS scheme as per \
PKCS#1 v2.1, 'rsa_1_5' - RSA PKCS#1 v1.5, 'ecdsa'" 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-alg", required_argument, NULL, 's' },
"Hash algorithm : 'sha256' (default), 'sha384', 'sha512'" "Hash algorithm : 'sha256' (default), 'sha384', 'sha512'"
...@@ -286,6 +325,7 @@ int main(int argc, char *argv[]) ...@@ -286,6 +325,7 @@ int main(int argc, char *argv[])
/* Set default options */ /* Set default options */
key_alg = KEY_ALG_RSA; key_alg = KEY_ALG_RSA;
hash_alg = HASH_ALG_SHA256; hash_alg = HASH_ALG_SHA256;
key_size = -1;
/* Add common command line options */ /* Add common command line options */
for (i = 0; i < NUM_ELEM(common_cmd_opt); i++) { for (i = 0; i < NUM_ELEM(common_cmd_opt); i++) {
...@@ -315,7 +355,7 @@ int main(int argc, char *argv[]) ...@@ -315,7 +355,7 @@ int main(int argc, char *argv[])
while (1) { while (1) {
/* getopt_long stores the option index here. */ /* 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. */ /* Detect the end of the options. */
if (c == -1) { if (c == -1) {
...@@ -330,6 +370,13 @@ int main(int argc, char *argv[]) ...@@ -330,6 +370,13 @@ int main(int argc, char *argv[])
exit(1); exit(1);
} }
break; 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': case 'h':
print_help(argv[0], cmd_opt); print_help(argv[0], cmd_opt);
exit(0); exit(0);
...@@ -371,6 +418,11 @@ int main(int argc, char *argv[]) ...@@ -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 command line arguments */
check_cmd_params(); check_cmd_params();
...@@ -413,7 +465,7 @@ int main(int argc, char *argv[]) ...@@ -413,7 +465,7 @@ int main(int argc, char *argv[])
if (new_keys) { if (new_keys) {
/* Try to create a new key */ /* Try to create a new key */
NOTICE("Creating new key for '%s'\n", keys[i].desc); 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); ERROR("Error creating key '%s'\n", keys[i].desc);
exit(1); exit(1);
} }
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment