Merge pull request #1165 from geesun/qx/support-sha512

Add support sha512 for hash algorithm
This commit is contained in:
davidcunado-arm 2017-11-22 22:42:12 +00:00 committed by GitHub
commit e2ff5ef861
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 154 additions and 27 deletions

View File

@ -425,11 +425,15 @@ Common build options
- ``KEY_ALG``: This build flag enables the user to select the algorithm to be - ``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. 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 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`` retained only for compatibility. The default value of this flag is ``rsa``
which is the TBBR compliant PKCS#1 RSA 2.1 scheme. 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 - ``LDFLAGS``: Extra user options appended to the linkers' command line in
addition to the one set by the build system. addition to the one set by the build system.

View File

@ -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 * SPDX-License-Identifier: BSD-3-Clause
*/ */
@ -7,6 +7,7 @@
#include <crypto_mod.h> #include <crypto_mod.h>
#include <debug.h> #include <debug.h>
#include <mbedtls_common.h> #include <mbedtls_common.h>
#include <mbedtls_config.h>
#include <stddef.h> #include <stddef.h>
#include <string.h> #include <string.h>

View File

@ -37,8 +37,29 @@ MBEDTLS_CRYPTO_SOURCES := drivers/auth/mbedtls/mbedtls_crypto.c \
pk_wrap.c \ pk_wrap.c \
pkparse.c \ pkparse.c \
pkwrite.c \ pkwrite.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 \ sha256.c \
) )
TF_MBEDTLS_HASH_ALG_ID := TF_MBEDTLS_SHA256
endif
# Key algorithm specific files # Key algorithm specific files
MBEDTLS_ECDSA_CRYPTO_SOURCES += $(addprefix ${MBEDTLS_DIR}/library/, \ MBEDTLS_ECDSA_CRYPTO_SOURCES += $(addprefix ${MBEDTLS_DIR}/library/, \
@ -67,6 +88,7 @@ endif
# Needs to be set to drive mbed TLS configuration correctly # 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_ALG_ID))
$(eval $(call add_define,TF_MBEDTLS_HASH_ALG_ID))
BL1_SOURCES += ${MBEDTLS_CRYPTO_SOURCES} BL1_SOURCES += ${MBEDTLS_CRYPTO_SOURCES}
BL2_SOURCES += ${MBEDTLS_CRYPTO_SOURCES} BL2_SOURCES += ${MBEDTLS_CRYPTO_SOURCES}

View File

@ -19,7 +19,7 @@
* Maximum key and hash sizes (in DER format) * Maximum key and hash sizes (in DER format)
*/ */
#define PK_DER_LEN 294 #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 * The platform must allocate buffers to store the authentication parameters

View File

@ -13,6 +13,13 @@
#define TF_MBEDTLS_ECDSA 2 #define TF_MBEDTLS_ECDSA 2
#define TF_MBEDTLS_RSA_AND_ECDSA 3 #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 * Configuration file to build mbed TLS with the required features for
* Trusted Boot * Trusted Boot
@ -66,6 +73,9 @@
#endif #endif
#define MBEDTLS_SHA256_C #define MBEDTLS_SHA256_C
#if (TF_MBEDTLS_HASH_ALG_ID != TF_MBEDTLS_SHA256)
#define MBEDTLS_SHA512_C
#endif
#define MBEDTLS_VERSION_C #define MBEDTLS_VERSION_C

View File

@ -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 # 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 # 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_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 CERT_ADD_CMD_OPT,${ROT_KEY},--rot-key)))
$(if ${ROT_KEY},$(eval $(call FWU_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))) $(if ${TRUSTED_WORLD_KEY},$(eval $(call CERT_ADD_CMD_OPT,${TRUSTED_WORLD_KEY},--trusted-world-key)))

View File

@ -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 * SPDX-License-Identifier: BSD-3-Clause
*/ */
@ -48,7 +48,13 @@ struct cert_s {
int cert_init(void); int cert_init(void);
cert_t *cert_get_by_opt(const char *opt); cert_t *cert_get_by_opt(const char *opt);
int cert_add_ext(X509 *issuer, X509 *subject, int nid, char *value); 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 */ /* Macro to register the certificates used in the CoT */
#define REGISTER_COT(_certs) \ #define REGISTER_COT(_certs) \

View File

@ -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 * SPDX-License-Identifier: BSD-3-Clause
*/ */
@ -30,6 +30,13 @@ enum {
KEY_ALG_MAX_NUM 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 * This structure contains the relevant information to create the keys
* required to sign the certificates. * required to sign the certificates.

View File

@ -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 * SPDX-License-Identifier: BSD-3-Clause
*/ */
@ -7,6 +7,6 @@
#ifndef SHA_H_ #ifndef SHA_H_
#define 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_ */ #endif /* SHA_H_ */

View File

@ -56,6 +56,19 @@ error:
return ret; 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) 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; 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; EVP_PKEY *pkey = keys[cert->key].key;
cert_t *issuer_cert = &certs[cert->issuer]; 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 */ /* 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); ERR_print_errors_fp(stdout);
goto END; 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; 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); ERR_print_errors_fp(stdout);
goto END; goto END;
} }

View File

@ -68,6 +68,7 @@
/* Global options */ /* Global options */
static int key_alg; static int key_alg;
static int hash_alg;
static int new_keys; static int new_keys;
static int save_keys; static int save_keys;
static int print_cert; static int print_cert;
@ -95,6 +96,12 @@ static const char *key_algs_str[] = {
#endif /* OPENSSL_NO_EC */ #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) static void print_help(const char *cmd, const struct option *long_opt)
{ {
int rem, i = 0; int rem, i = 0;
@ -150,6 +157,19 @@ static int get_key_alg(const char *key_alg_str)
return -1; 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) static void check_cmd_params(void)
{ {
cert_t *cert; cert_t *cert;
@ -227,6 +247,10 @@ static const cmd_opt_t common_cmd_opt[] = {
"Key algorithm: 'rsa' (default) - RSAPSS scheme as per \ "Key algorithm: 'rsa' (default) - RSAPSS scheme as per \
PKCS#1 v2.1, 'rsa_1_5' - RSA PKCS#1 v1.5, 'ecdsa'" 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-keys", no_argument, NULL, 'k' },
"Save key pairs into files. Filenames must be provided" "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 struct option *cmd_opt;
const char *cur_opt; const char *cur_opt;
unsigned int err_code; 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; const EVP_MD *md_info;
NOTICE("CoT Generation Tool: %s\n", build_msg); NOTICE("CoT Generation Tool: %s\n", build_msg);
@ -262,6 +287,7 @@ int main(int argc, char *argv[])
/* Set default options */ /* Set default options */
key_alg = KEY_ALG_RSA; key_alg = KEY_ALG_RSA;
hash_alg = HASH_ALG_SHA256;
/* Add common command line options */ /* Add common command line options */
for (i = 0; i < NUM_ELEM(common_cmd_opt); i++) { for (i = 0; i < NUM_ELEM(common_cmd_opt); i++) {
@ -291,7 +317,7 @@ int main(int argc, char *argv[])
while (1) { while (1) {
/* getopt_long stores the option index here. */ /* 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. */ /* Detect the end of the options. */
if (c == -1) { if (c == -1) {
@ -318,6 +344,13 @@ int main(int argc, char *argv[])
case 'p': case 'p':
print_cert = 1; print_cert = 1;
break; 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: case CMD_OPT_EXT:
cur_opt = cmd_opt_get_name(opt_idx); cur_opt = cmd_opt_get_name(opt_idx);
ext = ext_get_by_opt(cur_opt); ext = ext_get_by_opt(cur_opt);
@ -343,9 +376,18 @@ int main(int argc, char *argv[])
/* Check command line arguments */ /* Check command line arguments */
check_cmd_params(); check_cmd_params();
/* Indicate SHA256 as image hash algorithm in the certificate /* Indicate SHA as image hash algorithm in the certificate
* extension */ * extension */
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_info = EVP_sha256();
md_len = SHA256_DIGEST_LENGTH;
}
/* Load private keys from files (or generate new ones) */ /* Load private keys from files (or generate new ones) */
for (i = 0 ; i < num_keys ; i++) { for (i = 0 ; i < num_keys ; i++) {
@ -421,14 +463,14 @@ int main(int argc, char *argv[])
if (ext->arg == NULL) { if (ext->arg == NULL) {
if (ext->optional) { if (ext->optional) {
/* Include a hash filled with zeros */ /* Include a hash filled with zeros */
memset(md, 0x0, SHA256_DIGEST_LENGTH); memset(md, 0x0, SHA512_DIGEST_LENGTH);
} else { } else {
/* Do not include this hash in the certificate */ /* Do not include this hash in the certificate */
break; break;
} }
} else { } else {
/* Calculate the hash of the file */ /* 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", ERROR("Cannot calculate hash of %s\n",
ext->arg); ext->arg);
exit(1); exit(1);
@ -436,7 +478,7 @@ int main(int argc, char *argv[])
} }
CHECK_NULL(cert_ext, ext_new_hash(ext_nid, CHECK_NULL(cert_ext, ext_new_hash(ext_nid,
EXT_CRIT, md_info, md, EXT_CRIT, md_info, md,
SHA256_DIGEST_LENGTH)); md_len));
break; break;
case EXT_TYPE_PKEY: case EXT_TYPE_PKEY:
CHECK_NULL(cert_ext, ext_new_key(ext_nid, 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 */ /* 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); ERROR("Cannot create %s\n", cert->cn);
exit(1); exit(1);
} }

View File

@ -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 * SPDX-License-Identifier: BSD-3-Clause
*/ */
#include <openssl/sha.h> #include <openssl/sha.h>
#include <stdio.h> #include <stdio.h>
#include "debug.h" #include "debug.h"
#include "key.h"
#define BUFFER_SIZE 256 #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; FILE *inFile;
SHA256_CTX shaContext; SHA256_CTX shaContext;
SHA512_CTX sha512Context;
int bytes; int bytes;
unsigned char data[BUFFER_SIZE]; unsigned char data[BUFFER_SIZE];
@ -29,11 +30,25 @@ int sha_file(const char *filename, unsigned char *md)
return 0; return 0;
} }
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); SHA256_Init(&shaContext);
while ((bytes = fread(data, 1, BUFFER_SIZE, inFile)) != 0) { while ((bytes = fread(data, 1, BUFFER_SIZE, inFile)) != 0) {
SHA256_Update(&shaContext, data, bytes); SHA256_Update(&shaContext, data, bytes);
} }
SHA256_Final(md, &shaContext); SHA256_Final(md, &shaContext);
}
fclose(inFile); fclose(inFile);
return 1; return 1;