Add cert_create tool support for RSA key sizes
authorJustin Chadwell <justin.chadwell@arm.com>
Mon, 29 Jul 2019 16:13:45 +0000 (17:13 +0100)
committerJustin Chadwell <justin.chadwell@arm.com>
Thu, 12 Sep 2019 14:27:41 +0000 (15:27 +0100)
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 <justin.chadwell@arm.com>
make_helpers/tbbr/tbbr_tools.mk
tools/cert_create/include/key.h
tools/cert_create/src/key.c
tools/cert_create/src/main.c

index afc007a4bb2a127a2ab0d825d091a108feab29e0..9c47cc7c43941f4d27baa93882fe68bcb4e7d0f3 100644 (file)
@@ -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_)))
index 310a77f3efc2b5fbb261f792c2a05546fa83a8bb..c08beb8b25b99e36ae71c3162b23190d874b2b2f 100644 (file)
@@ -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 <openssl/ossl_typ.h>
 
-#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);
 
index fece7708538f75c3cc62808ae6611157f17a11c4..93d31f7c347c45239b00980e32550cdc836a1392 100644 (file)
@@ -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;
index 0f588cc8cfab453049368b6cf599b8db077ad560..44a65eb982e1745725b00a695f13abb929064b9a 100644 (file)
@@ -10,6 +10,7 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#include <stdbool.h>
 
 #include <openssl/conf.h>
 #include <openssl/engine.h>
@@ -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);
                        }