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
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.

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
*/
@ -7,6 +7,7 @@
#include <crypto_mod.h>
#include <debug.h>
#include <mbedtls_common.h>
#include <mbedtls_config.h>
#include <stddef.h>
#include <string.h>

View File

@ -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}

View File

@ -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

View File

@ -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

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
# 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)))

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
*/
@ -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) \

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

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

View File

@ -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;
}

View File

@ -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);
}

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
*/
#include <openssl/sha.h>
#include <stdio.h>
#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;