From 2091755c5e3b8d94333b9aad742e61db9d754cc5 Mon Sep 17 00:00:00 2001 From: Soby Mathew Date: Thu, 31 Aug 2017 11:49:32 +0100 Subject: [PATCH 1/2] Export KEY_ALG as a user build option The `KEY_ALG` variable is used to select the algorithm for key generation by `cert_create` tool for signing the certificates. This variable was previously undocumented and did not have a global default value. This patch corrects this and also adds changes to derive the value of `TF_MBEDTLS_KEY_ALG` based on `KEY_ALG` if it not set by the platform. The corresponding assignment of these variables are also now removed from the `arm_common.mk` makefile. Signed-off-by: Soby Mathew Change-Id: I78e2d6f4fc04ed5ad35ce2266118afb63127a5a4 --- docs/user-guide.rst | 5 +++++ drivers/auth/mbedtls/mbedtls_crypto.mk | 10 ++++++++-- make_helpers/defaults.mk | 3 +++ plat/arm/common/arm_common.mk | 5 ----- 4 files changed, 16 insertions(+), 7 deletions(-) diff --git a/docs/user-guide.rst b/docs/user-guide.rst index 043af63ed1..1502c8c105 100644 --- a/docs/user-guide.rst +++ b/docs/user-guide.rst @@ -405,6 +405,11 @@ Common build options AArch64 and facilitates the loading of ``SP_MIN`` and BL33 as AArch32 executable images. +- ``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 2 values viz ``rsa``, ``ecdsa``. The default value of this flag + is ``rsa``. + - ``LDFLAGS``: Extra user options appended to the linkers' command line in addition to the one set by the build system. diff --git a/drivers/auth/mbedtls/mbedtls_crypto.mk b/drivers/auth/mbedtls/mbedtls_crypto.mk index cb81d4d674..38197164c9 100644 --- a/drivers/auth/mbedtls/mbedtls_crypto.mk +++ b/drivers/auth/mbedtls/mbedtls_crypto.mk @@ -7,9 +7,15 @@ include drivers/auth/mbedtls/mbedtls_common.mk # The platform may define the variable 'TF_MBEDTLS_KEY_ALG' to select the key -# algorithm to use. Default algorithm is 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 or is +# defined to `rsa`, then set the variable to `rsa`. ifeq (${TF_MBEDTLS_KEY_ALG},) - TF_MBEDTLS_KEY_ALG := rsa + ifeq (${KEY_ALG}, ecdsa) + TF_MBEDTLS_KEY_ALG := ecdsa + else + TF_MBEDTLS_KEY_ALG := rsa + endif endif # If MBEDTLS_KEY_ALG build flag is defined use it to set TF_MBEDTLS_KEY_ALG for diff --git a/make_helpers/defaults.mk b/make_helpers/defaults.mk index 302d937f30..860104605c 100644 --- a/make_helpers/defaults.mk +++ b/make_helpers/defaults.mk @@ -81,6 +81,9 @@ GENERATE_COT := 0 # operations. HW_ASSISTED_COHERENCY := 0 +# Set the default algorithm for the generation of Trusted Board Boot keys +KEY_ALG := rsa + # Flag to enable new version of image loading LOAD_IMAGE_V2 := 0 diff --git a/plat/arm/common/arm_common.mk b/plat/arm/common/arm_common.mk index 20372c2036..af94ac2acd 100644 --- a/plat/arm/common/arm_common.mk +++ b/plat/arm/common/arm_common.mk @@ -174,9 +174,6 @@ endif ifneq (${TRUSTED_BOARD_BOOT},0) - # By default, ARM platforms use RSA keys - KEY_ALG := rsa - # Include common TBB sources AUTH_SOURCES := drivers/auth/auth_mod.c \ drivers/auth/crypto_mod.c \ @@ -195,8 +192,6 @@ ifneq (${TRUSTED_BOARD_BOOT},0) $(eval $(call FWU_FIP_ADD_IMG,NS_BL2U,--fwu)) - TF_MBEDTLS_KEY_ALG := ${KEY_ALG} - # We expect to locate the *.mk files under the directories specified below ifeq (${ARM_CRYPTOCELL_INTEG},0) CRYPTO_LIB_MK := drivers/auth/mbedtls/mbedtls_crypto.mk From a8eb286adaa73e86305317b9cae15d41c57de8e7 Mon Sep 17 00:00:00 2001 From: Soby Mathew Date: Thu, 31 Aug 2017 11:50:29 +0100 Subject: [PATCH 2/2] cert_tool: Support for legacy RSA PKCS#1 v1.5 This patch enables choice of RSA version at run time to be used for generating signatures by the cert_tool. The RSA PSS as defined in PKCS#1 v2.1 becomes the default version and this patch enables to specify the RSA PKCS#1 v1.5 algorithm to `cert_create` through the command line -a option. Also, the build option `KEY_ALG` can be used to pass this option from the build system. Please note that RSA PSS is mandated by Trusted Board Boot requirements (TBBR) and legacy RSA support is being added for compatibility reasons. Fixes ARM-Software/tf-issues#499 Change-Id: Ifaa3f2f7c9b43f3d7b3effe2cde76bf6745a5d73 Co-Authored-By: Eleanor Bonnici Signed-off-by: Soby Mathew --- docs/user-guide.rst | 6 +++-- drivers/auth/mbedtls/mbedtls_crypto.mk | 2 +- tools/cert_create/include/cert.h | 2 +- tools/cert_create/include/key.h | 3 ++- tools/cert_create/src/cert.c | 34 ++++++++++++++++---------- tools/cert_create/src/main.c | 8 +++--- 6 files changed, 34 insertions(+), 21 deletions(-) diff --git a/docs/user-guide.rst b/docs/user-guide.rst index 1502c8c105..1181495cfc 100644 --- a/docs/user-guide.rst +++ b/docs/user-guide.rst @@ -407,8 +407,10 @@ 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 2 values viz ``rsa``, ``ecdsa``. The default value of this flag - is ``rsa``. + It accepts 3 values viz ``rsa``, ``rsa_1_5``, ``ecdsa``. The ``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. - ``LDFLAGS``: Extra user options appended to the linkers' command line in addition to the one set by the build system. diff --git a/drivers/auth/mbedtls/mbedtls_crypto.mk b/drivers/auth/mbedtls/mbedtls_crypto.mk index 38197164c9..21b857bffe 100644 --- a/drivers/auth/mbedtls/mbedtls_crypto.mk +++ b/drivers/auth/mbedtls/mbedtls_crypto.mk @@ -9,7 +9,7 @@ include drivers/auth/mbedtls/mbedtls_common.mk # 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`, then set the variable to `rsa`. +# defined to `rsa`/`rsa_1_5`, then set the variable to `rsa`. ifeq (${TF_MBEDTLS_KEY_ALG},) ifeq (${KEY_ALG}, ecdsa) TF_MBEDTLS_KEY_ALG := ecdsa diff --git a/tools/cert_create/include/cert.h b/tools/cert_create/include/cert.h index 543f12233a..256e7afd25 100644 --- a/tools/cert_create/include/cert.h +++ b/tools/cert_create/include/cert.h @@ -48,7 +48,7 @@ struct cert_s { 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(cert_t *cert, int days, int ca, STACK_OF(X509_EXTENSION) * sk); +int cert_new(int key_alg, cert_t *cert, int days, int ca, STACK_OF(X509_EXTENSION) * sk); /* Macro to register the certificates used in the CoT */ #define REGISTER_COT(_certs) \ diff --git a/tools/cert_create/include/key.h b/tools/cert_create/include/key.h index 4b9e88258c..304fa6154f 100644 --- a/tools/cert_create/include/key.h +++ b/tools/cert_create/include/key.h @@ -22,7 +22,8 @@ enum { /* Supported key algorithms */ enum { - KEY_ALG_RSA, + 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 */ diff --git a/tools/cert_create/src/cert.c b/tools/cert_create/src/cert.c index 9775664a38..1b84e36d35 100644 --- a/tools/cert_create/src/cert.c +++ b/tools/cert_create/src/cert.c @@ -79,7 +79,7 @@ int cert_add_ext(X509 *issuer, X509 *subject, int nid, char *value) return 1; } -int cert_new(cert_t *cert, int days, int ca, STACK_OF(X509_EXTENSION) * sk) +int cert_new(int key_alg, cert_t *cert, int days, int ca, STACK_OF(X509_EXTENSION) * sk) { EVP_PKEY *pkey = keys[cert->key].key; cert_t *issuer_cert = &certs[cert->issuer]; @@ -90,7 +90,7 @@ int cert_new(cert_t *cert, int days, int ca, STACK_OF(X509_EXTENSION) * sk) X509_NAME *name; ASN1_INTEGER *sno; int i, num, rc = 0; - EVP_MD_CTX mdCtx; + EVP_MD_CTX mdCtx; EVP_PKEY_CTX *pKeyCtx = NULL; /* Create the certificate structure */ @@ -112,24 +112,32 @@ int cert_new(cert_t *cert, int days, int ca, STACK_OF(X509_EXTENSION) * sk) } EVP_MD_CTX_init(&mdCtx); + + /* Sign the certificate with the issuer key */ if (!EVP_DigestSignInit(&mdCtx, &pKeyCtx, EVP_sha256(), NULL, ikey)) { ERR_print_errors_fp(stdout); goto END; } - if (!EVP_PKEY_CTX_set_rsa_padding(pKeyCtx, RSA_PKCS1_PSS_PADDING)) { - ERR_print_errors_fp(stdout); - goto END; - } + /* + * Set additional parameters if algorithm is RSA PSS. This is not + * required for RSA 1.5 or ECDSA. + */ + if (key_alg == KEY_ALG_RSA) { + if (!EVP_PKEY_CTX_set_rsa_padding(pKeyCtx, RSA_PKCS1_PSS_PADDING)) { + ERR_print_errors_fp(stdout); + goto END; + } - if (!EVP_PKEY_CTX_set_rsa_pss_saltlen(pKeyCtx, RSA_SALT_LEN)) { - ERR_print_errors_fp(stdout); - goto END; - } + if (!EVP_PKEY_CTX_set_rsa_pss_saltlen(pKeyCtx, RSA_SALT_LEN)) { + ERR_print_errors_fp(stdout); + goto END; + } - if (!EVP_PKEY_CTX_set_rsa_mgf1_md(pKeyCtx, EVP_sha256())) { - ERR_print_errors_fp(stdout); - goto END; + if (!EVP_PKEY_CTX_set_rsa_mgf1_md(pKeyCtx, EVP_sha256())) { + ERR_print_errors_fp(stdout); + goto END; + } } /* x509.v3 */ diff --git a/tools/cert_create/src/main.c b/tools/cert_create/src/main.c index f14601c8bc..df59961b0a 100644 --- a/tools/cert_create/src/main.c +++ b/tools/cert_create/src/main.c @@ -89,6 +89,7 @@ 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 */ @@ -223,7 +224,8 @@ static const cmd_opt_t common_cmd_opt[] = { }, { { "key-alg", required_argument, NULL, 'a' }, - "Key algorithm: 'rsa' (default), 'ecdsa'" + "Key algorithm: 'rsa' (default) - RSAPSS scheme as per \ +PKCS#1 v2.1, 'rsa_1_5' - RSA PKCS#1 v1.5, 'ecdsa'" }, { { "save-keys", no_argument, NULL, 'k' }, @@ -450,8 +452,8 @@ int main(int argc, char *argv[]) sk_X509_EXTENSION_push(sk, cert_ext); } - /* Create certificate. Signed with ROT key */ - if (cert->fn && !cert_new(cert, VAL_DAYS, 0, sk)) { + /* Create certificate. Signed with corresponding key */ + if (cert->fn && !cert_new(key_alg, cert, VAL_DAYS, 0, sk)) { ERROR("Cannot create %s\n", cert->cn); exit(1); }