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
*/
......@@ -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) \
......
/*
* 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.
......
/*
* 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_ */
......@@ -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;
}
......
......@@ -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 */
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);
}
......
/*
* 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;
}
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);
}
fclose(inFile);
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