Added SHA2-384 support for integrity checks

pull/190/head
Daniele Lacamera 2022-04-06 09:41:37 +02:00
parent cbf7214c9c
commit f04889ee29
10 changed files with 202 additions and 17 deletions

View File

@ -163,6 +163,11 @@
# define NO_SHA256
#endif
#ifdef WOLFBOOT_HASH_SHA384
# define WOLFSSL_SHA384
# define NO_SHA256
#endif
#ifdef EXT_ENCRYPTED
# define HAVE_PWDBASED
#else

View File

@ -60,6 +60,7 @@
#define HDR_IMG_DELTA_SIZE 0x06
#define HDR_PUBKEY 0x10
#define HDR_SHA3_384 0x13
#define HDR_SHA384 0x14
#define HDR_IMG_DELTA_INVERSE 0x15
#define HDR_IMG_DELTA_INVERSE_SIZE 0x16
#define HDR_SIGNATURE 0x20
@ -143,6 +144,12 @@ int wolfBoot_dualboot_candidate(void);
# define WOLFBOOT_SHA_DIGEST_SIZE (32)
# define image_hash image_sha256
# define key_hash key_sha256
#elif defined(WOLFBOOT_HASH_SHA384)
# define WOLFBOOT_SHA_BLOCK_SIZE (256)
# define WOLFBOOT_SHA_HDR HDR_SHA384
# define WOLFBOOT_SHA_DIGEST_SIZE (48)
# define image_hash image_sha384
# define key_hash key_sha384
#elif defined(WOLFBOOT_HASH_SHA3_384)
# define WOLFBOOT_SHA_BLOCK_SIZE (128)
# define WOLFBOOT_SHA_HDR HDR_SHA3_384

View File

@ -367,6 +367,14 @@ ifeq ($(HASH),SHA256)
CFLAGS+=-D"WOLFBOOT_HASH_SHA256"
endif
ifeq ($(HASH),SHA384)
CFLAGS+=-D"WOLFBOOT_HASH_SHA384"
SIGN_OPTIONS+=--sha384
ifneq ($(SIGN),ED25519)
WOLFCRYPT_OBJS+=./lib/wolfssl/wolfcrypt/src/sha512.o
endif
endif
ifeq ($(HASH),SHA3)
WOLFCRYPT_OBJS+=./lib/wolfssl/wolfcrypt/src/sha3.o
CFLAGS+=-D"WOLFBOOT_HASH_SHA3_384"

View File

@ -511,6 +511,67 @@ static void key_sha256(uint8_t *hash)
#endif /* WOLFBOOT_NO_SIGN */
#endif /* SHA2-256 */
#if defined(WOLFBOOT_HASH_SHA384)
#include <wolfssl/wolfcrypt/sha512.h>
static int image_sha384(struct wolfBoot_image *img, uint8_t *hash)
{
uint8_t *stored_sha, *end_sha;
uint16_t stored_sha_len;
uint8_t *p;
int blksz;
uint32_t position = 0;
wc_Sha384 sha384_ctx;
if (!img)
return -1;
p = get_img_hdr(img);
stored_sha_len = get_header(img, HDR_SHA384, &stored_sha);
if (stored_sha_len != WOLFBOOT_SHA_DIGEST_SIZE)
return -1;
wc_InitSha384(&sha384_ctx);
end_sha = stored_sha - (2 * sizeof(uint16_t)); /* Subtract 2 Type + 2 Len */
while (p < end_sha) {
blksz = WOLFBOOT_SHA_BLOCK_SIZE;
if (end_sha - p < blksz)
blksz = end_sha - p;
wc_Sha384Update(&sha384_ctx, p, blksz);
p += blksz;
}
do {
p = get_sha_block(img, position);
if (p == NULL)
break;
blksz = WOLFBOOT_SHA_BLOCK_SIZE;
if (position + blksz > img->fw_size)
blksz = img->fw_size - position;
wc_Sha384Update(&sha384_ctx, p, blksz);
position += blksz;
} while(position < img->fw_size);
wc_Sha384Final(&sha384_ctx, hash);
return 0;
}
#ifndef WOLFBOOT_NO_SIGN
static void key_sha384(uint8_t *hash)
{
int blksz;
unsigned int i = 0;
wc_Sha384 sha384_ctx;
wc_InitSha384(&sha384_ctx);
while(i < KEY_LEN)
{
blksz = WOLFBOOT_SHA_BLOCK_SIZE;
if ((i + blksz) > KEY_LEN)
blksz = KEY_LEN - i;
wc_Sha384Update(&sha384_ctx, (KEY_BUFFER + i), blksz);
i += blksz;
}
wc_Sha384Final(&sha384_ctx, hash);
}
#endif /* WOLFBOOT_NO_SIGN */
#endif /* WOLFBOOT_HASH_SHA384 */
#if defined(WOLFBOOT_HASH_SHA3_384)
#include <wolfssl/wolfcrypt/sha3.h>

View File

@ -47,6 +47,9 @@ struct xmalloc_slot {
#ifdef WOLFBOOT_HASH_SHA256
# include <wolfssl/wolfcrypt/sha256.h>
# define HASH_BLOCK_SIZE WC_SHA256_BLOCK_SIZE
#elif defined WOLFBOOT_HASH_SHA384
# include <wolfssl/wolfcrypt/sha512.h>
# define HASH_BLOCK_SIZE (WC_SHA384_BLOCK_SIZE / sizeof(uint32_t))
#elif defined WOLFBOOT_HASH_SHA3_384
# include <wolfssl/wolfcrypt/sha3.h>
# define HASH_BLOCK_SIZE WC_SHA3_384_BLOCK_SIZE
@ -148,7 +151,7 @@ static uint8_t mp_curve_specs[MP_CURVE_SPECS_SIZE];
static uint32_t sha_block[HASH_BLOCK_SIZE];
static struct xmalloc_slot xmalloc_pool[] = {
#ifdef WOLFBOOT_HASH_SHA256
#if defined(WOLFBOOT_HASH_SHA256) || defined(WOLFBOOT_HASH_SHA384)
{ (uint8_t *)sha_block, HASH_BLOCK_SIZE * sizeof(uint32_t), 0 },
#endif
{ (uint8_t *)mp_curve_specs, MP_CURVE_SPECS_SIZE, 0 },
@ -201,7 +204,7 @@ static uint32_t sha_block[HASH_BLOCK_SIZE];
static uint32_t sha512_block[sizeof(word64) * 16];
static struct xmalloc_slot xmalloc_pool[] = {
#ifdef WOLFBOOT_HASH_SHA256
#if defined(WOLFBOOT_HASH_SHA256) || defined(WOLFBOOT_HASH_SHA384)
{ (uint8_t *)sha_block, HASH_BLOCK_SIZE * sizeof(uint32_t), 0 },
#endif
{ (uint8_t *)sha512_block, sizeof(word64) * 16, 0 },
@ -221,7 +224,7 @@ static ge448_p2 pi, p2;
static uint32_t sha_block[HASH_BLOCK_SIZE];
static struct xmalloc_slot xmalloc_pool[] = {
#ifdef WOLFBOOT_HASH_SHA256
#if defined(WOLFBOOT_HASH_SHA256) || defined(WOLFBOOT_HASH_SHA384)
{ (uint8_t *)sha_block, HASH_BLOCK_SIZE * sizeof(uint32_t), 0 },
#endif
{ (uint8_t *)aslide, GE448_WINDOW_BUF_SIZE, 0 },
@ -257,8 +260,8 @@ static uint32_t sha_block[HASH_BLOCK_SIZE];
#endif
static uint8_t mp_digit_buf0[MPDIGIT_BUF0_SIZE];
static struct xmalloc_slot xmalloc_pool[] = {
#ifdef WOLFBOOT_HASH_SHA256
{ (uint8_t *)sha_block, WC_SHA256_BLOCK_SIZE * sizeof(uint32_t), 0 },
#if defined(WOLFBOOT_HASH_SHA256) || defined(WOLFBOOT_HASH_SHA384)
{ (uint8_t *)sha_block, HASH_BLOCK_SIZE * sizeof(uint32_t), 0 },
#endif
{ mp_digit_buf0, MPDIGIT_BUF0_SIZE, 0},
#ifndef WOLFSSL_SP_ARM_CORTEX_M_ASM
@ -276,8 +279,8 @@ static uint32_t sha_block[HASH_BLOCK_SIZE];
static uint8_t mp_int_buffer4[MP_INT_SIZE * 5];
static uint8_t mp_mont_reduce_buffer[MP_MONT_REDUCE_BUF_SIZE];
static struct xmalloc_slot xmalloc_pool[] = {
#ifdef WOLFBOOT_HASH_SHA256
{ (uint8_t *)sha_block, WC_SHA256_BLOCK_SIZE * sizeof(uint32_t), 0 },
#if defined(WOLFBOOT_HASH_SHA256) || defined(WOLFBOOT_HASH_SHA384)
{ (uint8_t *)sha_block, HASH_BLOCK_SIZE * sizeof(uint32_t), 0 },
#endif
{ mp_int_buffer0, MP_INT_SIZE, 0},
{ mp_int_buffer1, MP_INT_SIZE * 3, 0},
@ -293,8 +296,8 @@ static uint32_t sha_block[HASH_BLOCK_SIZE];
static uint32_t sha_block[HASH_BLOCK_SIZE];
static struct xmalloc_slot xmalloc_pool[] = {
#ifdef WOLFBOOT_HASH_SHA256
{ (uint8_t *)sha_block, WC_SHA256_BLOCK_SIZE * sizeof(uint32_t), 0 },
#if defined(WOLFBOOT_HASH_SHA256) || defined(WOLFBOOT_HASH_SHA384)
{ (uint8_t *)sha_block, HASH_BLOCK_SIZE * sizeof(uint32_t), 0 },
#endif
{ NULL, 0, 0}
};

View File

@ -78,6 +78,9 @@
#ifndef NO_SHA256
#include <wolfssl/wolfcrypt/sha256.h>
#endif
#ifndef NO_SHA384
#include <wolfssl/wolfcrypt/sha512.h>
#endif
#ifdef WOLFSSL_SHA3
#include <wolfssl/wolfcrypt/sha3.h>
#endif
@ -105,8 +108,11 @@
#define HDR_SHA256 0x03
#define HDR_SHA3_384 0x13
#define HDR_SHA384 0x14
#define HDR_SHA256_LEN 32
#define HDR_SHA384_LEN 48
#define HDR_SHA3_384_LEN 48
#define HDR_VERSION_LEN 4
#define HDR_TIMESTAMP_LEN 8
@ -130,6 +136,7 @@
#define HDR_IMG_TYPE_DIFF 0x00D0
#define HASH_SHA256 HDR_SHA256
#define HASH_SHA384 HDR_SHA384
#define HASH_SHA3 HDR_SHA3_384
#define SIGN_AUTO 0
@ -561,6 +568,50 @@ static int make_header_ex(int is_diff, uint8_t *pubkey, uint32_t pubkey_sz,
digest_sz = HDR_SHA256_LEN;
#endif
}
else if (CMD.hash_algo == HASH_SHA384)
{
#ifndef NO_SHA384
wc_Sha384 sha;
printf("Calculating SHA384 digest...\n");
ret = wc_InitSha384_ex(&sha, NULL, INVALID_DEVID);
if (ret == 0) {
/* Hash Header */
ret = wc_Sha384Update(&sha, header, header_idx);
/* Hash image file */
f = fopen(image_file, "rb");
pos = 0;
while (ret == 0 && pos < image_sz) {
read_sz = image_sz - pos;
if (read_sz > 32)
read_sz = 32;
io_sz = fread(buf, 1, read_sz, f);
if ((io_sz < 0) && !feof(f)) {
ret = -1;
break;
}
ret = wc_Sha384Update(&sha, buf, read_sz);
pos += read_sz;
}
fclose(f);
if (ret == 0)
wc_Sha384Final(&sha, digest);
wc_Sha384Free(&sha);
}
/* pubkey hash calculation */
if (ret == 0) {
ret = wc_InitSha384_ex(&sha, NULL, INVALID_DEVID);
if (ret == 0) {
ret = wc_Sha384Update(&sha, pubkey, pubkey_sz);
if (ret == 0)
wc_Sha384Final(&sha, buf);
wc_Sha384Free(&sha);
}
}
if (ret == 0)
digest_sz = HDR_SHA384_LEN;
#endif
}
else if (CMD.hash_algo == HASH_SHA3)
{
#ifdef WOLFSSL_SHA3
@ -1104,6 +1155,10 @@ cleanup:
}
static const char Hashes_str[] = "[--sha256 | --sha384 | --sha3]";
static const char Enc_str[] = "[--chacha | --aes128 | --aes256]";
static const char Sign_algo_str[] = "[--ed25519 | --ed447 | --ecc256 | --ecc384 | --ecc521 | --rsa2048 | --rsa2048enc | --rsa4096 | --rsa4096enc | --no-CMD.sign]";
int main(int argc, char** argv)
@ -1125,11 +1180,16 @@ int main(int argc, char** argv)
/* Check arguments and print usage */
if (argc < 4 || argc > 10) {
printf("Usage: %s [--ed25519 | --ed447 | --ecc256 | --ecc384 | --ecc521 | --rsa2048 | --rsa2048enc | --rsa4096 | --rsa4096enc | --no-CMD.sign] [--sha256 | --sha3] [--wolfboot-update] [--encrypt enc_key.bin] [--chacha | --aes128 | --aes256] [--delta image_vX_signed.bin] image key.der fw_version\n", argv[0]);
printf(" - or - ");
printf(" %s [--sha256 | --sha3] [--sha-only] [--wolfboot-update] image pub_key.der fw_version\n", argv[0]);
printf(" - or - ");
printf(" %s [--ed25519 | --ed448 | --ecc256 | --ecc384 | --ecc521 | --rsa2048 | --rsa4096 ] [--sha256 | --sha3] [--manual-CMD.sign] image pub_key.der fw_version signature.sig\n", argv[0]);
printf("Usage: %s %s %s [--wolfboot-update] [--encrypt enc_key.bin] %s"
" [--delta image_vX_signed.bin] image key.der fw_version\n",
argv[0], Hashes_str, Sign_algo_str, Enc_str);
printf(" - or - \n");
printf(" %s %s [--wolfboot-update] image pub_key.der fw_version\n",
argv[0], Hashes_str);
printf(" - or - \n");
printf(" %s %s %s [--manual-CMD.sign] image pub_key.der"
"fw_version signature.sig\n",
argv[0], Hashes_str, Sign_algo_str);
return 0;
}
@ -1179,6 +1239,10 @@ int main(int argc, char** argv)
CMD.hash_algo = HASH_SHA256;
hash_str = "SHA256";
}
else if (strcmp(argv[i], "--sha384") == 0) {
CMD.hash_algo = HASH_SHA384;
hash_str = "SHA384";
}
else if (strcmp(argv[i], "--sha3") == 0) {
CMD.hash_algo = HASH_SHA3;
hash_str = "SHA3";

View File

@ -33,6 +33,7 @@ HDR_SHA256 = 0x03
HDR_IMG_DELTA_BASE = 0x05
HDR_IMG_DELTA_SIZE = 0x06
HDR_SHA3_384 = 0x13
HDR_SHA384 = 0x14
HDR_IMG_DELTA_INVERSE = 0x15
HDR_IMG_DELTA_INVERSE_SIZE = 0x16
HDR_IMG_TYPE = 0x04
@ -44,6 +45,7 @@ HDR_PADDING = 0xFF
HDR_VERSION_LEN = 4
HDR_TIMESTAMP_LEN = 8
HDR_SHA256_LEN = 32
HDR_SHA384_LEN = 48
HDR_SHA3_384_LEN = 48
HDR_IMG_TYPE_LEN = 2
HDR_SIGNATURE_LEN = 64
@ -175,6 +177,32 @@ def make_header(image_file, fw_version, extra_fields=[]):
header += struct.pack('<HH', HDR_PUBKEY, HDR_SHA256_LEN)
header += key_digest
elif hash_algo == 'sha384':
sha = hashes.Sha384.new()
# Sha calculation
sha.update(header)
img_bin = open(image_file, 'rb')
while True:
buf = img_bin.read(48)
if (len(buf) == 0):
img_bin.close()
break
sha.update(buf)
digest = sha.digest()
# Add SHA to the header
header += struct.pack('<HH', HDR_SHA384, HDR_SHA384_LEN)
header += digest
if sign != 'none':
# pubkey SHA calculation
keysha = hashes.Sha384.new()
keysha.update(pubkey)
key_digest = keysha.digest()
header += struct.pack('<HH', HDR_PUBKEY, HDR_SHA384_LEN)
header += key_digest
elif hash_algo == 'sha3':
sha = hashes.Sha3.new()
# Sha calculation
@ -254,11 +282,11 @@ def make_header(image_file, fw_version, extra_fields=[]):
#### MAIN ####
if (argc < 4) or (argc > 10):
print("Usage: %s [--ed25519 | --ed448 | --ecc256 | --rsa2048 | --rsa4096 | --no-sign] [--sha256 | --sha3] [--wolfboot-update] [--encrypt key.bin] [--delta base_file.bin] image key.der fw_version\n" % sys.argv[0])
print("Usage: %s [--ed25519 | --ed448 | --ecc256 | --rsa2048 | --rsa4096 | --no-sign] [--sha256 | --sha384 | --sha3] [--wolfboot-update] [--encrypt key.bin] [--delta base_file.bin] image key.der fw_version\n" % sys.argv[0])
print(" - or - ")
print(" %s [--sha256 | --sha3] [--sha-only] [--wolfboot-update] [--encrypt key.bin] [--delta base_file.bin] image pub_key.der fw_version\n" % sys.argv[0])
print(" %s [--sha256 | --sha384 | --sha3] [--sha-only] [--wolfboot-update] [--encrypt key.bin] [--delta base_file.bin] image pub_key.der fw_version\n" % sys.argv[0])
print(" - or - ")
print(" %s [--ed25519 | --ed448 | --ecc256 | --rsa2048 | --rsa4096 ] [--sha256 | --sha3] [--manual-sign] [--chacha | --aes128 | --aes256 ] [--encrypt key.bin] [--delta base_file.bin] image pub_key.der fw_version signature.sig\n" % sys.argv[0])
print(" %s [--ed25519 | --ed448 | --ecc256 | --rsa2048 | --rsa4096 ] [--sha256 | --sha384 | --sha3] [--manual-sign] [--chacha | --aes128 | --aes256 ] [--encrypt key.bin] [--delta base_file.bin] image pub_key.der fw_version signature.sig\n" % sys.argv[0])
sys.exit(1)
i = 1
@ -281,6 +309,8 @@ while (i < len(argv)):
sign='rsa4096'
elif (argv[i] == '--sha256'):
hash_algo='sha256'
elif (argv[i] == '--sha384'):
hash_algo='sha384'
elif (argv[i] == '--sha3'):
hash_algo='sha3'
elif (argv[i] == '--wolfboot-update'):

View File

@ -64,6 +64,7 @@
/* Hashing */
#define WOLFSSL_SHA512 /* Required for ED25519 */
#define WOLFSSL_SHA384 /* Required for ED25519 */
#define WOLFSSL_SHA3
#undef NO_SHA256

View File

@ -89,6 +89,9 @@ endif
ifeq ($(HASH),SHA256)
SIGN_ARGS+= --sha256
endif
ifeq ($(HASH),SHA384)
SIGN_ARGS+= --sha384
endif
ifeq ($(HASH),SHA3)
SIGN_ARGS+= --sha3
endif

View File

@ -53,6 +53,9 @@ endif
ifeq ($(HASH),SHA256)
SIGN_ARGS+= --sha256
endif
ifeq ($(HASH),SHA384)
SIGN_ARGS+= --sha384
endif
ifeq ($(HASH),SHA3)
SIGN_ARGS+= --sha3
endif