Merge changes from topic "jc/rsa-pkcs" into integration

* changes:
  Remove RSA PKCS#1 v1.5 support from cert_tool
  Add documentation for new KEY_SIZE option
  Add cert_create tool support for RSA key sizes
  Support larger RSA key sizes when using MBEDTLS
This commit is contained in:
Soby Mathew 2019-09-13 12:00:59 +00:00 committed by TrustedFirmware Code Review
commit c428fbaeab
12 changed files with 173 additions and 57 deletions

View File

@ -695,6 +695,10 @@ $(eval $(call assert_numeric,ARM_ARCH_MAJOR))
$(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

View File

@ -704,7 +704,7 @@ Each image descriptor must specify:
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 @@ three functions:
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

View File

@ -594,10 +594,20 @@ Common build options
- ``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``.

View 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
#
@ -48,9 +48,9 @@ LIBMBEDTLS_SRCS := $(addprefix ${MBEDTLS_DIR}/library/, \
)
# 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 @@ ifeq (${TF_MBEDTLS_KEY_ALG},)
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 @@ endif
# 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))

View File

@ -7,6 +7,7 @@
#include <stddef.h>
#include <platform_def.h>
#include <drivers/auth/mbedtls/mbedtls_config.h>
#include <drivers/auth/auth_mod.h>
#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
/*

View 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
*/
@ -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 */

View 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_)))

View 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
*/
@ -49,7 +49,6 @@ int cert_init(void);
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,

View 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,
@ -23,13 +21,15 @@ enum {
/* 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 @@ 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 */
#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 @@ 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);

View 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
*/
@ -93,7 +93,6 @@ 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,
@ -143,10 +142,10 @@ int cert_new(
}
/*
* 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;

View 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,16 +109,15 @@ 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 */
#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 @@ 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;

View 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;
@ -90,7 +92,6 @@ static char *strdup(const char *str)
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 @@ 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 +187,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 +195,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++) {
@ -242,8 +276,11 @@ static const cmd_opt_t common_cmd_opt[] = {
},
{
{ "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 @@ 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 +353,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 +368,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 +416,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 +463,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);
}
@ -493,7 +543,7 @@ int main(int argc, char *argv[])
}
/* 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);
}