Skip to content

Commit

Permalink
bootutil: Replace hash with SHA384 when P384 is used
Browse files Browse the repository at this point in the history
Currently all the hashing functionality is done with SHA256
but if we would like to use ECDSA-P384 that requires SHA384
as the hashing algorithm, but MCUboot is using SHA256
for image hashing and public key hashing. This commit modifies
the hashing operations to use SHA384 thus SHA256 can be omitted
which is beneficial from a code size standpoint.

Signed-off-by: Roland Mikhel <[email protected]>
Change-Id: I59230f76f88e0b42ad6383b2c9b71b73f33d7dd7
  • Loading branch information
Roland Mikhel authored and davidvincze committed Jun 29, 2023
1 parent cc92097 commit c04b187
Show file tree
Hide file tree
Showing 6 changed files with 115 additions and 93 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@
* the MCUBOOT_USE_PSA_CRYPTO will take precedence.
*/

#ifndef __BOOTUTIL_CRYPTO_SHA256_H_
#define __BOOTUTIL_CRYPTO_SHA256_H_
#ifndef __BOOTUTIL_CRYPTO_SHA_H_
#define __BOOTUTIL_CRYPTO_SHA_H_

#include "mcuboot_config/mcuboot_config.h"
#include "mcuboot_config/mcuboot_logging.h"
Expand All @@ -34,8 +34,21 @@
#error "One crypto backend must be defined: either CC310/MBED_TLS/TINYCRYPT/PSA_CRYPTO"
#endif

#if defined(MCUBOOT_SIGN_EC384) && \
!defined(MCUBOOT_USE_PSA_CRYPTO)
#error "P384 requires PSA_CRYPTO to be defined"
#endif

#if defined(MCUBOOT_SIGN_EC384)
#define IMAGE_HASH_SIZE (48)
#define EXPECTED_HASH_TLV IMAGE_TLV_SHA384
#else
#define IMAGE_HASH_SIZE (32)
#define EXPECTED_HASH_TLV IMAGE_TLV_SHA256
#endif /* MCUBOOT_SIGN_EC384 */

/* Universal defines for SHA-256 */
#define BOOTUTIL_CRYPTO_SHA256_BLOCK_SIZE (64)
#define BOOTUTIL_CRYPTO_SHA256_BLOCK_SIZE (64)
#define BOOTUTIL_CRYPTO_SHA256_DIGEST_SIZE (32)

#if defined(MCUBOOT_USE_PSA_CRYPTO)
Expand Down Expand Up @@ -69,119 +82,129 @@ extern "C" {

#if defined(MCUBOOT_USE_PSA_CRYPTO)

typedef psa_hash_operation_t bootutil_sha256_context;
typedef psa_hash_operation_t bootutil_sha_context;

static inline int bootutil_sha256_init(bootutil_sha256_context *ctx)
static inline int bootutil_sha_init(bootutil_sha_context *ctx)
{
*ctx = psa_hash_operation_init();
return (int)psa_hash_setup(ctx, PSA_ALG_SHA_256);
#if defined(MCUBOOT_SIGN_EC384)
psa_status_t status = psa_hash_setup(ctx, PSA_ALG_SHA_384);
#else
psa_status_t status = psa_hash_setup(ctx, PSA_ALG_SHA_256);
#endif
return (int)status;
}

static inline int bootutil_sha256_drop(bootutil_sha256_context *ctx)
static inline int bootutil_sha_drop(bootutil_sha_context *ctx)
{
return (int)psa_hash_abort(ctx);
}

static inline int bootutil_sha256_update(bootutil_sha256_context *ctx,
const void *data,
uint32_t data_len)
static inline int bootutil_sha_update(bootutil_sha_context *ctx,
const void *data,
uint32_t data_len)
{
return (int)psa_hash_update(ctx, data, data_len);
}

static inline int bootutil_sha256_finish(bootutil_sha256_context *ctx,
uint8_t *output)
static inline int bootutil_sha_finish(bootutil_sha_context *ctx,
uint8_t *output)
{
size_t hash_length = 0;
/* Assumes the output buffer is at least the expected size of the hash */
#if defined(MCUBOOT_SIGN_EC384)
return (int)psa_hash_finish(ctx, output, PSA_HASH_LENGTH(PSA_ALG_SHA_384), &hash_length);
#else
return (int)psa_hash_finish(ctx, output, PSA_HASH_LENGTH(PSA_ALG_SHA_256), &hash_length);
#endif
}

#elif defined(MCUBOOT_USE_MBED_TLS)

typedef mbedtls_sha256_context bootutil_sha256_context;
typedef mbedtls_sha256_context bootutil_sha_context;

static inline int bootutil_sha256_init(bootutil_sha256_context *ctx)
static inline int bootutil_sha_init(bootutil_sha_context *ctx)
{
mbedtls_sha256_init(ctx);
return mbedtls_sha256_starts_ret(ctx, 0);
}

static inline int bootutil_sha256_drop(bootutil_sha256_context *ctx)
static inline int bootutil_sha_drop(bootutil_sha_context *ctx)
{
/* XXX: config defines MBEDTLS_PLATFORM_NO_STD_FUNCTIONS so no need to free */
/* (void)mbedtls_sha256_free(ctx); */
(void)ctx;
return 0;
}

static inline int bootutil_sha256_update(bootutil_sha256_context *ctx,
const void *data,
uint32_t data_len)
static inline int bootutil_sha_update(bootutil_sha_context *ctx,
const void *data,
uint32_t data_len)
{
return mbedtls_sha256_update_ret(ctx, data, data_len);
}

static inline int bootutil_sha256_finish(bootutil_sha256_context *ctx,
uint8_t *output)
static inline int bootutil_sha_finish(bootutil_sha_context *ctx,
uint8_t *output)
{
return mbedtls_sha256_finish_ret(ctx, output);
}

#endif /* MCUBOOT_USE_MBED_TLS */

#if defined(MCUBOOT_USE_TINYCRYPT)
typedef struct tc_sha256_state_struct bootutil_sha256_context;
static inline int bootutil_sha256_init(bootutil_sha256_context *ctx)
typedef struct tc_sha256_state_struct bootutil_sha_context;

static inline int bootutil_sha_init(bootutil_sha_context *ctx)
{
tc_sha256_init(ctx);
return 0;
}

static inline int bootutil_sha256_drop(bootutil_sha256_context *ctx)
static inline int bootutil_sha_drop(bootutil_sha_context *ctx)
{
(void)ctx;
return 0;
}

static inline int bootutil_sha256_update(bootutil_sha256_context *ctx,
const void *data,
uint32_t data_len)
static inline int bootutil_sha_update(bootutil_sha_context *ctx,
const void *data,
uint32_t data_len)
{
return tc_sha256_update(ctx, data, data_len);
}

static inline int bootutil_sha256_finish(bootutil_sha256_context *ctx,
uint8_t *output)
static inline int bootutil_sha_finish(bootutil_sha_context *ctx,
uint8_t *output)
{
return tc_sha256_final(output, ctx);
}
#endif /* MCUBOOT_USE_TINYCRYPT */

#if defined(MCUBOOT_USE_CC310)
static inline int bootutil_sha256_init(bootutil_sha256_context *ctx)
static inline int bootutil_sha_init(bootutil_sha_context *ctx)
{
cc310_sha256_init(ctx);
return 0;
}

static inline int bootutil_sha256_drop(bootutil_sha256_context *ctx)
static inline int bootutil_sha_drop(bootutil_sha_context *ctx)
{
(void)ctx;
nrf_cc310_disable();
return 0;
}

static inline int bootutil_sha256_update(bootutil_sha256_context *ctx,
const void *data,
uint32_t data_len)
static inline int bootutil_sha_update(bootutil_sha_context *ctx,
const void *data,
uint32_t data_len)
{
cc310_sha256_update(ctx, data, data_len);
return 0;
}

static inline int bootutil_sha256_finish(bootutil_sha256_context *ctx,
uint8_t *output)
static inline int bootutil_sha_finish(bootutil_sha_context *ctx,
uint8_t *output)
{
cc310_sha256_finalize(ctx, output);
return 0;
Expand All @@ -192,4 +215,4 @@ static inline int bootutil_sha256_finish(bootutil_sha256_context *ctx,
}
#endif

#endif /* __BOOTUTIL_CRYPTO_SHA256_H_ */
#endif /* __BOOTUTIL_CRYPTO_SHA_H_ */
2 changes: 1 addition & 1 deletion boot/bootutil/include/bootutil/image.h
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,6 @@ struct flash_area;
* Image trailer TLV types.
*
* Signature is generated by computing signature over the image hash.
* Currently the only image hash type is SHA256.
*
* Signature comes in the form of 2 TLVs.
* 1st on identifies the public key which should be used to verify it.
Expand All @@ -84,6 +83,7 @@ struct flash_area;
#define IMAGE_TLV_KEYHASH 0x01 /* hash of the public key */
#define IMAGE_TLV_PUBKEY 0x02 /* public key */
#define IMAGE_TLV_SHA256 0x10 /* SHA256 of image hdr and body */
#define IMAGE_TLV_SHA384 0x11 /* SHA384 of image hdr and body */
#define IMAGE_TLV_RSA2048_PSS 0x20 /* RSA2048 of hash output */
#define IMAGE_TLV_ECDSA224 0x21 /* ECDSA of hash output - Not supported anymore */
#define IMAGE_TLV_ECDSA_SIG 0x22 /* ECDSA of hash output */
Expand Down
7 changes: 4 additions & 3 deletions boot/bootutil/src/boot_record.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2018-2021 Arm Limited
* Copyright (c) 2018-2023 Arm Limited
* Copyright (c) 2020 Linaro Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
Expand All @@ -22,6 +22,7 @@
#include <string.h>

#include "mcuboot_config/mcuboot_config.h"
#include "bootutil/crypto/sha.h"

#if defined(MCUBOOT_MEASURED_BOOT) || defined(MCUBOOT_DATA_SHARING)
#include "bootutil/boot_record.h"
Expand Down Expand Up @@ -132,7 +133,7 @@ boot_save_boot_status(uint8_t sw_module,
uint16_t type;
uint16_t ias_minor;
size_t record_len = 0;
uint8_t image_hash[32]; /* SHA256 - 32 Bytes */
uint8_t image_hash[IMAGE_HASH_SIZE];
uint8_t buf[MAX_BOOT_RECORD_SZ];
bool boot_record_found = false;
bool hash_found = false;
Expand Down Expand Up @@ -170,7 +171,7 @@ boot_save_boot_status(uint8_t sw_module,
record_len = len;
boot_record_found = true;

} else if (type == IMAGE_TLV_SHA256) {
} else if (type == EXPECTED_HASH_TLV) {
/* Get the image's hash value from the manifest section. */
if (len > sizeof(image_hash)) {
return -1;
Expand Down
2 changes: 1 addition & 1 deletion boot/bootutil/src/encrypted.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
#endif

#if defined(MCUBOOT_ENCRYPT_EC256) || defined(MCUBOOT_ENCRYPT_X25519)
#include "bootutil/crypto/sha256.h"
#include "bootutil/crypto/sha.h"
#include "bootutil/crypto/hmac_sha256.h"
#include "mbedtls/oid.h"
#include "mbedtls/asn1.h"
Expand Down
28 changes: 14 additions & 14 deletions boot/bootutil/src/image_rsa.c
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@
*/
#if !defined(MCUBOOT_USE_PSA_CRYPTO)

#include "bootutil/crypto/sha256.h"
#include "bootutil/crypto/sha.h"

/*
* Constants for this particular constrained implementation of
Expand Down Expand Up @@ -86,17 +86,17 @@ static const uint8_t pss_zeros[8] = {0};
static void
pss_mgf1(uint8_t *mask, const uint8_t *hash)
{
bootutil_sha256_context ctx;
bootutil_sha_context ctx;
uint8_t counter[4] = { 0, 0, 0, 0 };
uint8_t htmp[PSS_HLEN];
int count = PSS_MASK_LEN;
int bytes;

while (count > 0) {
bootutil_sha256_init(&ctx);
bootutil_sha256_update(&ctx, hash, PSS_HLEN);
bootutil_sha256_update(&ctx, counter, 4);
bootutil_sha256_finish(&ctx, htmp);
bootutil_sha_init(&ctx);
bootutil_sha_update(&ctx, hash, PSS_HLEN);
bootutil_sha_update(&ctx, counter, 4);
bootutil_sha_finish(&ctx, htmp);

counter[3]++;

Expand All @@ -109,7 +109,7 @@ pss_mgf1(uint8_t *mask, const uint8_t *hash)
count -= bytes;
}

bootutil_sha256_drop(&ctx);
bootutil_sha_drop(&ctx);
}

/*
Expand All @@ -121,7 +121,7 @@ static fih_ret
bootutil_cmp_rsasig(bootutil_rsa_context *ctx, uint8_t *hash, uint32_t hlen,
uint8_t *sig, size_t slen)
{
bootutil_sha256_context shactx;
bootutil_sha_context shactx;
uint8_t em[MBEDTLS_MPI_MAX_SIZE];
uint8_t db_mask[PSS_MASK_LEN];
uint8_t h2[PSS_HLEN];
Expand Down Expand Up @@ -221,12 +221,12 @@ bootutil_cmp_rsasig(bootutil_rsa_context *ctx, uint8_t *hash, uint32_t hlen,
/* Step 12. Let M' = 0x00 00 00 00 00 00 00 00 || mHash || salt; */

/* Step 13. Let H' = Hash(M') */
bootutil_sha256_init(&shactx);
bootutil_sha256_update(&shactx, pss_zeros, 8);
bootutil_sha256_update(&shactx, hash, PSS_HLEN);
bootutil_sha256_update(&shactx, &db_mask[PSS_MASK_SALT_POS], PSS_SLEN);
bootutil_sha256_finish(&shactx, h2);
bootutil_sha256_drop(&shactx);
bootutil_sha_init(&shactx);
bootutil_sha_update(&shactx, pss_zeros, 8);
bootutil_sha_update(&shactx, hash, PSS_HLEN);
bootutil_sha_update(&shactx, &db_mask[PSS_MASK_SALT_POS], PSS_SLEN);
bootutil_sha_finish(&shactx, h2);
bootutil_sha_drop(&shactx);

/* Step 14. If H = H', output "consistent". Otherwise, output
* "inconsistent". */
Expand Down
Loading

0 comments on commit c04b187

Please sign in to comment.