From 2972247cb4ae84ed660532cac426259a4f17c816 Mon Sep 17 00:00:00 2001 From: Qixiang Xu Date: Thu, 9 Nov 2017 13:51:58 +0800 Subject: [PATCH 1/2] tools: add an option -hash-alg for cert_create This option enables the user to select the secure hash algorithm to be used for generating the hash. It supports the following options: - sha256 (default) - sha384 - sha512 Change-Id: Icb093cec1b5715e248c3d1c3749a2479a7ab4b89 Signed-off-by: Qixiang Xu --- tools/cert_create/include/cert.h | 10 ++++-- tools/cert_create/include/key.h | 9 ++++- tools/cert_create/include/sha.h | 4 +-- tools/cert_create/src/cert.c | 25 ++++++++++++-- tools/cert_create/src/main.c | 58 +++++++++++++++++++++++++++----- tools/cert_create/src/sha.c | 29 ++++++++++++---- 6 files changed, 112 insertions(+), 23 deletions(-) diff --git a/tools/cert_create/include/cert.h b/tools/cert_create/include/cert.h index 256e7afd2..9b4ef5af6 100644 --- a/tools/cert_create/include/cert.h +++ b/tools/cert_create/include/cert.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2015-2017, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -48,7 +48,13 @@ 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(int key_alg, cert_t *cert, int days, int ca, STACK_OF(X509_EXTENSION) * sk); +int cert_new( + int key_alg, + int md_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 304fa6154..1a253cc71 100644 --- a/tools/cert_create/include/key.h +++ b/tools/cert_create/include/key.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2015-2017, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -30,6 +30,13 @@ enum { KEY_ALG_MAX_NUM }; +/* Supported hash algorithms */ +enum{ + HASH_ALG_SHA256, + HASH_ALG_SHA384, + HASH_ALG_SHA512, +}; + /* * This structure contains the relevant information to create the keys * required to sign the certificates. diff --git a/tools/cert_create/include/sha.h b/tools/cert_create/include/sha.h index 6907fa196..4d07a1e72 100644 --- a/tools/cert_create/include/sha.h +++ b/tools/cert_create/include/sha.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2015-2017, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -7,6 +7,6 @@ #ifndef SHA_H_ #define SHA_H_ -int sha_file(const char *filename, unsigned char *md); +int sha_file(int md_alg, const char *filename, unsigned char *md); #endif /* SHA_H_ */ diff --git a/tools/cert_create/src/cert.c b/tools/cert_create/src/cert.c index 3f0b4d363..8e8aee699 100644 --- a/tools/cert_create/src/cert.c +++ b/tools/cert_create/src/cert.c @@ -56,6 +56,19 @@ error: return ret; } +const EVP_MD *get_digest(int alg) +{ + switch (alg) { + case HASH_ALG_SHA256: + return EVP_sha256(); + case HASH_ALG_SHA384: + return EVP_sha384(); + case HASH_ALG_SHA512: + return EVP_sha512(); + default: + return NULL; + } +} int cert_add_ext(X509 *issuer, X509 *subject, int nid, char *value) { @@ -79,7 +92,13 @@ int cert_add_ext(X509 *issuer, X509 *subject, int nid, char *value) return 1; } -int cert_new(int key_alg, cert_t *cert, int days, int ca, STACK_OF(X509_EXTENSION) * sk) +int cert_new( + int key_alg, + int md_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]; @@ -118,7 +137,7 @@ int cert_new(int key_alg, cert_t *cert, int days, int ca, STACK_OF(X509_EXTENSIO } /* Sign the certificate with the issuer key */ - if (!EVP_DigestSignInit(mdCtx, &pKeyCtx, EVP_sha256(), NULL, ikey)) { + if (!EVP_DigestSignInit(mdCtx, &pKeyCtx, get_digest(md_alg), NULL, ikey)) { ERR_print_errors_fp(stdout); goto END; } @@ -138,7 +157,7 @@ int cert_new(int key_alg, cert_t *cert, int days, int ca, STACK_OF(X509_EXTENSIO goto END; } - if (!EVP_PKEY_CTX_set_rsa_mgf1_md(pKeyCtx, EVP_sha256())) { + if (!EVP_PKEY_CTX_set_rsa_mgf1_md(pKeyCtx, get_digest(md_alg))) { ERR_print_errors_fp(stdout); goto END; } diff --git a/tools/cert_create/src/main.c b/tools/cert_create/src/main.c index 741242f59..4abfe6dd7 100644 --- a/tools/cert_create/src/main.c +++ b/tools/cert_create/src/main.c @@ -68,6 +68,7 @@ /* Global options */ static int key_alg; +static int hash_alg; static int new_keys; static int save_keys; static int print_cert; @@ -95,6 +96,12 @@ static const char *key_algs_str[] = { #endif /* OPENSSL_NO_EC */ }; +static const char *hash_algs_str[] = { + [HASH_ALG_SHA256] = "sha256", + [HASH_ALG_SHA384] = "sha384", + [HASH_ALG_SHA512] = "sha512", +}; + static void print_help(const char *cmd, const struct option *long_opt) { int rem, i = 0; @@ -150,6 +157,19 @@ static int get_key_alg(const char *key_alg_str) return -1; } +static int get_hash_alg(const char *hash_alg_str) +{ + int i; + + for (i = 0 ; i < NUM_ELEM(hash_algs_str) ; i++) { + if (0 == strcmp(hash_alg_str, hash_algs_str[i])) { + return i; + } + } + + return -1; +} + static void check_cmd_params(void) { cert_t *cert; @@ -227,6 +247,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'" }, + { + { "hash-alg", required_argument, NULL, 's' }, + "Hash algorithm : 'sha256' (default), 'sha384', 'sha512'" + }, { { "save-keys", no_argument, NULL, 'k' }, "Save key pairs into files. Filenames must be provided" @@ -254,7 +278,8 @@ int main(int argc, char *argv[]) const struct option *cmd_opt; const char *cur_opt; unsigned int err_code; - unsigned char md[SHA256_DIGEST_LENGTH]; + unsigned char md[SHA512_DIGEST_LENGTH]; + unsigned int md_len; const EVP_MD *md_info; NOTICE("CoT Generation Tool: %s\n", build_msg); @@ -262,6 +287,7 @@ int main(int argc, char *argv[]) /* Set default options */ key_alg = KEY_ALG_RSA; + hash_alg = HASH_ALG_SHA256; /* Add common command line options */ for (i = 0; i < NUM_ELEM(common_cmd_opt); i++) { @@ -291,7 +317,7 @@ int main(int argc, char *argv[]) while (1) { /* getopt_long stores the option index here. */ - c = getopt_long(argc, argv, "a:hknp", cmd_opt, &opt_idx); + c = getopt_long(argc, argv, "a:hknps:", cmd_opt, &opt_idx); /* Detect the end of the options. */ if (c == -1) { @@ -318,6 +344,13 @@ int main(int argc, char *argv[]) case 'p': print_cert = 1; break; + case 's': + hash_alg = get_hash_alg(optarg); + if (hash_alg < 0) { + ERROR("Invalid hash algorithm '%s'\n", optarg); + exit(1); + } + break; case CMD_OPT_EXT: cur_opt = cmd_opt_get_name(opt_idx); ext = ext_get_by_opt(cur_opt); @@ -343,9 +376,18 @@ int main(int argc, char *argv[]) /* Check command line arguments */ check_cmd_params(); - /* Indicate SHA256 as image hash algorithm in the certificate + /* Indicate SHA as image hash algorithm in the certificate * extension */ - md_info = EVP_sha256(); + if (hash_alg == HASH_ALG_SHA384) { + md_info = EVP_sha384(); + md_len = SHA384_DIGEST_LENGTH; + } else if (hash_alg == HASH_ALG_SHA512) { + md_info = EVP_sha512(); + md_len = SHA512_DIGEST_LENGTH; + } else { + md_info = EVP_sha256(); + md_len = SHA256_DIGEST_LENGTH; + } /* Load private keys from files (or generate new ones) */ for (i = 0 ; i < num_keys ; i++) { @@ -421,14 +463,14 @@ int main(int argc, char *argv[]) if (ext->arg == NULL) { if (ext->optional) { /* Include a hash filled with zeros */ - memset(md, 0x0, SHA256_DIGEST_LENGTH); + memset(md, 0x0, SHA512_DIGEST_LENGTH); } else { /* Do not include this hash in the certificate */ break; } } else { /* Calculate the hash of the file */ - if (!sha_file(ext->arg, md)) { + if (!sha_file(hash_alg, ext->arg, md)) { ERROR("Cannot calculate hash of %s\n", ext->arg); exit(1); @@ -436,7 +478,7 @@ int main(int argc, char *argv[]) } CHECK_NULL(cert_ext, ext_new_hash(ext_nid, EXT_CRIT, md_info, md, - SHA256_DIGEST_LENGTH)); + md_len)); break; case EXT_TYPE_PKEY: CHECK_NULL(cert_ext, ext_new_key(ext_nid, @@ -453,7 +495,7 @@ int main(int argc, char *argv[]) } /* Create certificate. Signed with corresponding key */ - if (cert->fn && !cert_new(key_alg, cert, VAL_DAYS, 0, sk)) { + if (cert->fn && !cert_new(key_alg, hash_alg, cert, VAL_DAYS, 0, sk)) { ERROR("Cannot create %s\n", cert->cn); exit(1); } diff --git a/tools/cert_create/src/sha.c b/tools/cert_create/src/sha.c index 297159302..3d977fbfe 100644 --- a/tools/cert_create/src/sha.c +++ b/tools/cert_create/src/sha.c @@ -1,20 +1,21 @@ /* - * Copyright (c) 2015, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2015-2017, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ #include #include - #include "debug.h" +#include "key.h" #define BUFFER_SIZE 256 -int sha_file(const char *filename, unsigned char *md) +int sha_file(int md_alg, const char *filename, unsigned char *md) { FILE *inFile; SHA256_CTX shaContext; + SHA512_CTX sha512Context; int bytes; unsigned char data[BUFFER_SIZE]; @@ -29,11 +30,25 @@ int sha_file(const char *filename, unsigned char *md) return 0; } - SHA256_Init(&shaContext); - while ((bytes = fread(data, 1, BUFFER_SIZE, inFile)) != 0) { - SHA256_Update(&shaContext, data, bytes); + if (md_alg == HASH_ALG_SHA384) { + SHA384_Init(&sha512Context); + while ((bytes = fread(data, 1, BUFFER_SIZE, inFile)) != 0) { + SHA384_Update(&sha512Context, data, bytes); + } + SHA384_Final(md, &sha512Context); + } else if (md_alg == HASH_ALG_SHA512) { + SHA512_Init(&sha512Context); + while ((bytes = fread(data, 1, BUFFER_SIZE, inFile)) != 0) { + SHA512_Update(&sha512Context, data, bytes); + } + SHA512_Final(md, &sha512Context); + } else { + SHA256_Init(&shaContext); + while ((bytes = fread(data, 1, BUFFER_SIZE, inFile)) != 0) { + SHA256_Update(&shaContext, data, bytes); + } + SHA256_Final(md, &shaContext); } - SHA256_Final(md, &shaContext); fclose(inFile); return 1; From 9a3088a5f509084e60d9c55bf53985c5ec4ca821 Mon Sep 17 00:00:00 2001 From: Qixiang Xu Date: Thu, 9 Nov 2017 13:56:29 +0800 Subject: [PATCH 2/2] tbbr: Add build flag HASH_ALG to let the user to select the SHA The flag support the following values: - sha256 (default) - sha384 - sha512 Change-Id: I7a49d858c361e993949cf6ada0a86575c3291066 Signed-off-by: Qixiang Xu --- docs/user-guide.rst | 6 ++++- drivers/auth/mbedtls/mbedtls_crypto.c | 3 ++- drivers/auth/mbedtls/mbedtls_crypto.mk | 24 ++++++++++++++++++- drivers/auth/tbbr/tbbr_cot.c | 2 +- include/drivers/auth/mbedtls/mbedtls_config.h | 10 ++++++++ make_helpers/tbbr/tbbr_tools.mk | 1 + 6 files changed, 42 insertions(+), 4 deletions(-) diff --git a/docs/user-guide.rst b/docs/user-guide.rst index 172e7932c..0eecde90a 100644 --- a/docs/user-guide.rst +++ b/docs/user-guide.rst @@ -425,11 +425,15 @@ 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 viz ``rsa``, ``rsa_1_5``, ``ecdsa``. The ``rsa_1_5`` is + 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. +- ``HASH_ALG``: This build flag enables the user to select the secure hash + algorithm. It accepts 3 values viz. ``sha256``, ``sha384``, ``sha512``. + The default value of this flag is ``sha256``. + - ``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.c b/drivers/auth/mbedtls/mbedtls_crypto.c index d8810d6db..bc9ed3a85 100644 --- a/drivers/auth/mbedtls/mbedtls_crypto.c +++ b/drivers/auth/mbedtls/mbedtls_crypto.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2015-2017, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -7,6 +7,7 @@ #include #include #include +#include #include #include diff --git a/drivers/auth/mbedtls/mbedtls_crypto.mk b/drivers/auth/mbedtls/mbedtls_crypto.mk index d6fc7eb53..8eb4873d9 100644 --- a/drivers/auth/mbedtls/mbedtls_crypto.mk +++ b/drivers/auth/mbedtls/mbedtls_crypto.mk @@ -37,9 +37,30 @@ MBEDTLS_CRYPTO_SOURCES := drivers/auth/mbedtls/mbedtls_crypto.c \ pk_wrap.c \ pkparse.c \ pkwrite.c \ - sha256.c \ ) +ifeq (${HASH_ALG}, sha384) + MBEDTLS_CRYPTO_SOURCES += \ + $(addprefix ${MBEDTLS_DIR}/library/, \ + sha256.c \ + sha512.c \ + ) + TF_MBEDTLS_HASH_ALG_ID := TF_MBEDTLS_SHA384 +else ifeq (${HASH_ALG}, sha512) + MBEDTLS_CRYPTO_SOURCES += \ + $(addprefix ${MBEDTLS_DIR}/library/, \ + sha256.c \ + sha512.c \ + ) + TF_MBEDTLS_HASH_ALG_ID := TF_MBEDTLS_SHA512 +else + MBEDTLS_CRYPTO_SOURCES += \ + $(addprefix ${MBEDTLS_DIR}/library/, \ + sha256.c \ + ) + TF_MBEDTLS_HASH_ALG_ID := TF_MBEDTLS_SHA256 +endif + # Key algorithm specific files MBEDTLS_ECDSA_CRYPTO_SOURCES += $(addprefix ${MBEDTLS_DIR}/library/, \ ecdsa.c \ @@ -67,6 +88,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_HASH_ALG_ID)) BL1_SOURCES += ${MBEDTLS_CRYPTO_SOURCES} BL2_SOURCES += ${MBEDTLS_CRYPTO_SOURCES} diff --git a/drivers/auth/tbbr/tbbr_cot.c b/drivers/auth/tbbr/tbbr_cot.c index 4aaab390f..01d6fb5a3 100644 --- a/drivers/auth/tbbr/tbbr_cot.c +++ b/drivers/auth/tbbr/tbbr_cot.c @@ -19,7 +19,7 @@ * Maximum key and hash sizes (in DER format) */ #define PK_DER_LEN 294 -#define HASH_DER_LEN 51 +#define HASH_DER_LEN 83 /* * The platform must allocate buffers to store the authentication parameters diff --git a/include/drivers/auth/mbedtls/mbedtls_config.h b/include/drivers/auth/mbedtls/mbedtls_config.h index 96587acae..f8f260808 100644 --- a/include/drivers/auth/mbedtls/mbedtls_config.h +++ b/include/drivers/auth/mbedtls/mbedtls_config.h @@ -13,6 +13,13 @@ #define TF_MBEDTLS_ECDSA 2 #define TF_MBEDTLS_RSA_AND_ECDSA 3 +/* + * Hash algorithms currently supported on mbed TLS libraries + */ +#define TF_MBEDTLS_SHA256 1 +#define TF_MBEDTLS_SHA384 2 +#define TF_MBEDTLS_SHA512 3 + /* * Configuration file to build mbed TLS with the required features for * Trusted Boot @@ -66,6 +73,9 @@ #endif #define MBEDTLS_SHA256_C +#if (TF_MBEDTLS_HASH_ALG_ID != TF_MBEDTLS_SHA256) +#define MBEDTLS_SHA512_C +#endif #define MBEDTLS_VERSION_C diff --git a/make_helpers/tbbr/tbbr_tools.mk b/make_helpers/tbbr/tbbr_tools.mk index 712fa6f61..b13afe488 100644 --- a/make_helpers/tbbr/tbbr_tools.mk +++ b/make_helpers/tbbr/tbbr_tools.mk @@ -54,6 +54,7 @@ $(eval $(call FWU_CERT_ADD_CMD_OPT,${FWU_CERT},--fwu-cert)) # 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 ${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 FWU_CERT_ADD_CMD_OPT,${ROT_KEY},--rot-key))) $(if ${TRUSTED_WORLD_KEY},$(eval $(call CERT_ADD_CMD_OPT,${TRUSTED_WORLD_KEY},--trusted-world-key)))