Commit 2972247c authored by Qixiang Xu's avatar Qixiang Xu
Browse files

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: default avatarQixiang Xu <qixiang.xu@arm.com>
parent 203444c5
/* /*
* 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 { ...@@ -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) \
......
/* /*
* 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 { ...@@ -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.
......
/* /*
* 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 @@ ...@@ -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_ */
...@@ -56,6 +56,19 @@ error: ...@@ -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) ...@@ -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 ...@@ -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 ...@@ -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;
} }
......
...@@ -68,6 +68,7 @@ ...@@ -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[] = { ...@@ -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) ...@@ -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[] = { ...@@ -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[]) ...@@ -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[]) ...@@ -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[]) ...@@ -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[]) ...@@ -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[]) ...@@ -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[]) ...@@ -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[]) ...@@ -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[]) ...@@ -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);
} }
......
/* /*
* 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) ...@@ -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;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment