diff --git a/Makefile b/Makefile index ecff944..32918c3 100644 --- a/Makefile +++ b/Makefile @@ -695,6 +695,10 @@ $(eval $(call assert_numeric,ARM_ARCH_MINOR)) $(eval $(call assert_numeric,BRANCH_PROTECTION)) +ifdef KEY_SIZE + $(eval $(call assert_numeric,KEY_SIZE)) +endif + ifeq ($(filter $(SANITIZE_UB), on off trap),) $(error "Invalid value for SANITIZE_UB: can be one of on, off, trap") endif diff --git a/docs/design/auth-framework.rst b/docs/design/auth-framework.rst index da958b7..7de8ee1 100644 --- a/docs/design/auth-framework.rst +++ b/docs/design/auth-framework.rst @@ -704,7 +704,7 @@ In the ``tbbr_cot.c`` file, a set of buffers are allocated to store the parameters extracted from the certificates. In the case of the TBBR CoT, these parameters -are hashes and public keys. In DER format, an RSA-2048 public key requires 294 +are hashes and public keys. In DER format, an RSA-4096 public key requires 550 bytes, and a hash requires 51 bytes. Depending on the CoT and the authentication process, some of the buffers may be reused at different stages during the boot. @@ -946,12 +946,16 @@ int verify_hash(void *data_ptr, unsigned int data_len, void *digest_info_ptr, unsigned int digest_info_len); -The mbedTLS library algorithm support is configured by the -``TF_MBEDTLS_KEY_ALG`` variable which can take in 3 values: `rsa`, `ecdsa` or -`rsa+ecdsa`. This variable allows the Makefile to include the corresponding -sources in the build for the various algorithms. Setting the variable to -`rsa+ecdsa` enables support for both rsa and ecdsa algorithms in the mbedTLS -library. +The mbedTLS library algorithm support is configured by both the +``TF_MBEDTLS_KEY_ALG`` and ``TF_MBEDTLS_KEY_SIZE`` variables. + +- ``TF_MBEDTLS_KEY_ALG`` can take in 3 values: `rsa`, `ecdsa` or `rsa+ecdsa`. + This variable allows the Makefile to include the corresponding sources in + the build for the various algorithms. Setting the variable to `rsa+ecdsa` + enables support for both rsa and ecdsa algorithms in the mbedTLS library. + +- ``TF_MBEDTLS_KEY_SIZE`` sets the supported RSA key size for TFA. Valid values + include 1024, 2048, 3072 and 4096. .. note:: If code size is a concern, the build option ``MBEDTLS_SHA256_SMALLER`` can diff --git a/docs/getting_started/user-guide.rst b/docs/getting_started/user-guide.rst index 3828d0b..015de9a 100644 --- a/docs/getting_started/user-guide.rst +++ b/docs/getting_started/user-guide.rst @@ -594,10 +594,20 @@ - ``KEY_ALG``: This build flag enables the user to select the algorithm to be used for generating the PKCS keys and subsequent signing of the certificate. - It accepts 3 values: ``rsa``, ``rsa_1_5`` and ``ecdsa``. The option - ``rsa_1_5`` is the legacy PKCS#1 RSA 1.5 algorithm which is not TBBR - compliant and is retained only for compatibility. The default value of this - flag is ``rsa`` which is the TBBR compliant PKCS#1 RSA 2.1 scheme. + It accepts 2 values: ``rsa`` and ``ecdsa``. The default value of this flag + is ``rsa`` which is the TBBR compliant PKCS#1 RSA 2.1 scheme. + +- ``KEY_SIZE``: This build flag enables the user to select the key size for + the algorithm specified by ``KEY_ALG``. The valid values for ``KEY_SIZE`` + depend on the chosen algorithm. + + +-----------+------------------------------------+ + | KEY_ALG | Possible key sizes | + +===========+====================================+ + | rsa | 1024, 2048 (default), 3072, 4096 | + +-----------+------------------------------------+ + | ecdsa | unavailable | + +-----------+------------------------------------+ - ``HASH_ALG``: This build flag enables the user to select the secure hash algorithm. It accepts 3 values: ``sha256``, ``sha384`` and ``sha512``. diff --git a/drivers/auth/mbedtls/mbedtls_common.mk b/drivers/auth/mbedtls/mbedtls_common.mk index 63e65bd..4b83015 100644 --- a/drivers/auth/mbedtls/mbedtls_common.mk +++ b/drivers/auth/mbedtls/mbedtls_common.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 # @@ -48,9 +48,9 @@ ) # The platform may define the variable 'TF_MBEDTLS_KEY_ALG' to select the key -# algorithm to use. If the variable is not defined, select it based on algorithm -# used for key generation `KEY_ALG`. If `KEY_ALG` is not defined or is -# defined to `rsa`/`rsa_1_5`, then set the variable to `rsa`. +# algorithm to use. If the variable is not defined, select it based on +# algorithm used for key generation `KEY_ALG`. If `KEY_ALG` is not defined, +# then it is set to `rsa`. ifeq (${TF_MBEDTLS_KEY_ALG},) ifeq (${KEY_ALG}, ecdsa) TF_MBEDTLS_KEY_ALG := ecdsa @@ -59,6 +59,16 @@ endif endif +ifeq (${TF_MBEDTLS_KEY_SIZE},) + ifneq ($(findstring rsa,${TF_MBEDTLS_KEY_ALG}),) + ifeq (${KEY_SIZE},) + TF_MBEDTLS_KEY_SIZE := 2048 + else + TF_MBEDTLS_KEY_SIZE := ${KEY_SIZE} + endif + endif +endif + ifeq (${HASH_ALG}, sha384) TF_MBEDTLS_HASH_ALG_ID := TF_MBEDTLS_SHA384 else ifeq (${HASH_ALG}, sha512) @@ -79,6 +89,7 @@ # Needs to be set to drive mbed TLS configuration correctly $(eval $(call add_define,TF_MBEDTLS_KEY_ALG_ID)) +$(eval $(call add_define,TF_MBEDTLS_KEY_SIZE)) $(eval $(call add_define,TF_MBEDTLS_HASH_ALG_ID)) diff --git a/drivers/auth/tbbr/tbbr_cot.c b/drivers/auth/tbbr/tbbr_cot.c index da3631b..6dd4ae2 100644 --- a/drivers/auth/tbbr/tbbr_cot.c +++ b/drivers/auth/tbbr/tbbr_cot.c @@ -7,6 +7,7 @@ #include #include +#include #include #if USE_TBBR_DEFS @@ -19,7 +20,22 @@ /* * Maximum key and hash sizes (in DER format) */ +#if TF_MBEDTLS_USE_RSA +#if TF_MBEDTLS_KEY_SIZE == 1024 +#define PK_DER_LEN 162 +#elif TF_MBEDTLS_KEY_SIZE == 2048 #define PK_DER_LEN 294 +#elif TF_MBEDTLS_KEY_SIZE == 3072 +#define PK_DER_LEN 422 +#elif TF_MBEDTLS_KEY_SIZE == 4096 +#define PK_DER_LEN 550 +#else +#error "Invalid value for TF_MBEDTLS_KEY_SIZE" +#endif +#else +#define PK_DER_LEN 294 +#endif + #define HASH_DER_LEN 83 /* diff --git a/include/drivers/auth/mbedtls/mbedtls_config.h b/include/drivers/auth/mbedtls/mbedtls_config.h index f7248f9..6e179bb 100644 --- a/include/drivers/auth/mbedtls/mbedtls_config.h +++ b/include/drivers/auth/mbedtls/mbedtls_config.h @@ -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 */ @@ -13,6 +13,11 @@ #define TF_MBEDTLS_ECDSA 2 #define TF_MBEDTLS_RSA_AND_ECDSA 3 +#define TF_MBEDTLS_USE_RSA (TF_MBEDTLS_KEY_ALG_ID == TF_MBEDTLS_RSA \ + || TF_MBEDTLS_KEY_ALG_ID == TF_MBEDTLS_RSA_AND_ECDSA) +#define TF_MBEDTLS_USE_ECDSA (TF_MBEDTLS_KEY_ALG_ID == TF_MBEDTLS_ECDSA \ + || TF_MBEDTLS_KEY_ALG_ID == TF_MBEDTLS_RSA_AND_ECDSA) + /* * Hash algorithms currently supported on mbed TLS libraries */ @@ -54,19 +59,14 @@ #define MBEDTLS_PLATFORM_C -#if (TF_MBEDTLS_KEY_ALG_ID == TF_MBEDTLS_ECDSA) +#if TF_MBEDTLS_USE_ECDSA #define MBEDTLS_ECDSA_C #define MBEDTLS_ECP_C #define MBEDTLS_ECP_DP_SECP256R1_ENABLED -#elif (TF_MBEDTLS_KEY_ALG_ID == TF_MBEDTLS_RSA) +#endif +#if TF_MBEDTLS_USE_RSA #define MBEDTLS_RSA_C #define MBEDTLS_X509_RSASSA_PSS_SUPPORT -#elif (TF_MBEDTLS_KEY_ALG_ID == TF_MBEDTLS_RSA_AND_ECDSA) -#define MBEDTLS_RSA_C -#define MBEDTLS_X509_RSASSA_PSS_SUPPORT -#define MBEDTLS_ECDSA_C -#define MBEDTLS_ECP_C -#define MBEDTLS_ECP_DP_SECP256R1_ENABLED #endif #define MBEDTLS_SHA256_C @@ -80,11 +80,20 @@ #define MBEDTLS_X509_CRT_PARSE_C /* MPI / BIGNUM options */ -#define MBEDTLS_MPI_WINDOW_SIZE 2 -#define MBEDTLS_MPI_MAX_SIZE 256 +#define MBEDTLS_MPI_WINDOW_SIZE 2 + +#if TF_MBEDTLS_USE_RSA +#if TF_MBEDTLS_KEY_SIZE <= 2048 +#define MBEDTLS_MPI_MAX_SIZE 256 +#else +#define MBEDTLS_MPI_MAX_SIZE 512 +#endif +#else +#define MBEDTLS_MPI_MAX_SIZE 256 +#endif /* Memory buffer allocator options */ -#define MBEDTLS_MEMORY_ALIGN_MULTIPLE 8 +#define MBEDTLS_MEMORY_ALIGN_MULTIPLE 8 #ifndef __ASSEMBLER__ /* System headers required to build mbed TLS with the current configuration */ @@ -95,13 +104,17 @@ /* * Determine Mbed TLS heap size * 13312 = 13*1024 - * 7168 = 7*1024 + * 11264 = 11*1024 + * 7168 = 7*1024 */ -#if (TF_MBEDTLS_KEY_ALG_ID == TF_MBEDTLS_ECDSA) \ - || (TF_MBEDTLS_KEY_ALG_ID == TF_MBEDTLS_RSA_AND_ECDSA) +#if TF_MBEDTLS_USE_ECDSA #define TF_MBEDTLS_HEAP_SIZE U(13312) -#elif (TF_MBEDTLS_KEY_ALG_ID == TF_MBEDTLS_RSA) +#elif TF_MBEDTLS_USE_RSA +#if TF_MBEDTLS_KEY_SIZE <= 2048 #define TF_MBEDTLS_HEAP_SIZE U(7168) +#else +#define TF_MBEDTLS_HEAP_SIZE U(11264) +#endif #endif #endif /* MBEDTLS_CONFIG_H */ diff --git a/make_helpers/tbbr/tbbr_tools.mk b/make_helpers/tbbr/tbbr_tools.mk index afc007a..9c47cc7 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 @@ # 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/cert.h b/tools/cert_create/include/cert.h index 39b45b5..6db9b57 100644 --- a/tools/cert_create/include/cert.h +++ b/tools/cert_create/include/cert.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 */ @@ -49,7 +49,6 @@ cert_t *cert_get_by_opt(const char *opt); int cert_add_ext(X509 *issuer, X509 *subject, int nid, char *value); int cert_new( - int key_alg, int md_alg, cert_t *cert, int days, diff --git a/tools/cert_create/include/key.h b/tools/cert_create/include/key.h index 310a77f..d96d983 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, @@ -23,13 +21,15 @@ /* Supported key algorithms */ enum { KEY_ALG_RSA, /* RSA PSS as defined by PKCS#1 v2.1 (default) */ - KEY_ALG_RSA_1_5, /* RSA as defined by PKCS#1 v1.5 */ #ifndef OPENSSL_NO_EC KEY_ALG_ECDSA, #endif /* OPENSSL_NO_EC */ 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 +37,15 @@ 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 */ +#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 +67,7 @@ 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/cert.c b/tools/cert_create/src/cert.c index 8e8aee6..c68a265 100644 --- a/tools/cert_create/src/cert.c +++ b/tools/cert_create/src/cert.c @@ -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 */ @@ -93,7 +93,6 @@ } int cert_new( - int key_alg, int md_alg, cert_t *cert, int days, @@ -143,10 +142,10 @@ } /* - * Set additional parameters if algorithm is RSA PSS. This is not - * required for RSA 1.5 or ECDSA. + * Set additional parameters if issuing public key algorithm is RSA. + * This is not required for ECDSA. */ - if (key_alg == KEY_ALG_RSA) { + if (EVP_PKEY_base_id(ikey) == EVP_PKEY_RSA) { if (!EVP_PKEY_CTX_set_rsa_padding(pKeyCtx, RSA_PKCS1_PSS_PADDING)) { ERR_print_errors_fp(stdout); goto END; diff --git a/tools/cert_create/src/key.c b/tools/cert_create/src/key.c index fece770..0f80cce 100644 --- a/tools/cert_create/src/key.c +++ b/tools/cert_create/src/key.c @@ -41,7 +41,7 @@ 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 @@ 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 @@ } #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,16 +109,15 @@ } #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 */ #ifndef OPENSSL_NO_EC key_create_ecdsa, /* KEY_ALG_ECDSA */ #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 +125,7 @@ } 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 0f588cc..0cbd219 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; @@ -90,7 +92,6 @@ static const char *key_algs_str[] = { [KEY_ALG_RSA] = "rsa", - [KEY_ALG_RSA_1_5] = "rsa_1_5", #ifndef OPENSSL_NO_EC [KEY_ALG_ECDSA] = "ecdsa" #endif /* OPENSSL_NO_EC */ @@ -155,6 +156,18 @@ 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 +187,7 @@ ext_t *ext; key_t *key; int i, j; + bool valid_size; /* Only save new keys */ if (save_keys && !new_keys) { @@ -181,6 +195,26 @@ 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++) { @@ -242,8 +276,11 @@ }, { { "key-alg", required_argument, NULL, 'a' }, - "Key algorithm: 'rsa' (default) - RSAPSS scheme as per \ -PKCS#1 v2.1, 'rsa_1_5' - RSA PKCS#1 v1.5, 'ecdsa'" + "Key algorithm: 'rsa' (default)- RSAPSS scheme as per PKCS#1 v2.1, 'ecdsa'" + }, + { + { "key-size", required_argument, NULL, 'b' }, + "Key size (for supported algorithms)." }, { { "hash-alg", required_argument, NULL, 's' }, @@ -286,6 +323,7 @@ /* 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 +353,7 @@ 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 +368,13 @@ 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 +416,11 @@ } } + /* 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 +463,7 @@ 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); } @@ -493,7 +543,7 @@ } /* Create certificate. Signed with corresponding key */ - if (cert->fn && !cert_new(key_alg, hash_alg, cert, VAL_DAYS, 0, sk)) { + if (cert->fn && !cert_new(hash_alg, cert, VAL_DAYS, 0, sk)) { ERROR("Cannot create %s\n", cert->cn); exit(1); }