Skip to content

Commit

Permalink
[nrf noup] PureEdDSA using ED25519
Browse files Browse the repository at this point in the history
The commit adds support for PureEdDSA, which validates signature
of image rather than hash. This is most secure, available, ED25519
usage in MCUboot, but due to requirement of PureEdDSA to be able
to calculate signature at whole message at once, here image,
it only works on setups where entire image can be mapped to
device address space, so that PSA functions calculating the
signature can see the whole image at once.
This option is enabled with Kconfig option:
 CONFIG_BOOT_SIGNATURE_TYPE_ED25519_PURE
and enables MCUBOOT_SIGN_ED25519_PURE in MCUboot configuraiton.

Note that the option will enable SHA512 for calculating public
key hash.

Signed-off-by: Dominik Ermel <dominik.ermel@nordicsemi.no>
  • Loading branch information
de-nordic committed Sep 6, 2024
1 parent 8c7f38c commit cd55052
Show file tree
Hide file tree
Showing 5 changed files with 100 additions and 7 deletions.
3 changes: 3 additions & 0 deletions boot/bootutil/src/bootutil_priv.h
Original file line number Diff line number Diff line change
Expand Up @@ -262,6 +262,9 @@ struct boot_loader_state {
fih_ret bootutil_verify_sig(uint8_t *hash, uint32_t hlen, uint8_t *sig,
size_t slen, uint8_t key_id);

fih_ret bootutil_verify_img(const uint8_t *img, uint32_t size,
uint8_t *sig, size_t slen, uint8_t key_id);

fih_ret boot_fih_memequal(const void *s1, const void *s2, size_t n);

int boot_find_status(int image_index, const struct flash_area **fap);
Expand Down
37 changes: 37 additions & 0 deletions boot/bootutil/src/image_ed25519.c
Original file line number Diff line number Diff line change
Expand Up @@ -107,4 +107,41 @@ bootutil_verify_sig(uint8_t *hash, uint32_t hlen, uint8_t *sig, size_t slen,
FIH_RET(fih_rc);
}

fih_ret
bootutil_verify_img(const uint8_t *img, uint32_t size,
uint8_t *sig, size_t slen, uint8_t key_id)
{
int rc;
FIH_DECLARE(fih_rc, FIH_FAILURE);
uint8_t *pubkey;
uint8_t *end;

if (slen != 64) {
FIH_SET(fih_rc, FIH_FAILURE);
goto out;
}

pubkey = (uint8_t *)bootutil_keys[key_id].key;
end = pubkey + *bootutil_keys[key_id].len;

rc = bootutil_import_key(&pubkey, end);
if (rc) {
FIH_SET(fih_rc, FIH_FAILURE);
goto out;
}

rc = ED25519_verify(img, size, sig, pubkey);

if (rc == 0) {
/* if verify returns 0, there was an error. */
FIH_SET(fih_rc, FIH_FAILURE);
goto out;
}

FIH_SET(fih_rc, FIH_SUCCESS);
out:

FIH_RET(fih_rc);
}

#endif /* MCUBOOT_SIGN_ED25519 */
47 changes: 41 additions & 6 deletions boot/bootutil/src/image_validate.c
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@

#include "bootutil_priv.h"

#ifndef MCUBOOT_SIGN_ED25519_PURE
/*
* Compute SHA hash over the image.
* (SHA384 if ECDSA-P384 is being used,
Expand Down Expand Up @@ -178,6 +179,7 @@ bootutil_img_hash(struct enc_key_data *enc_state, int image_index,

return 0;
}
#endif

/*
* Currently, we only support being able to verify one type of
Expand Down Expand Up @@ -402,7 +404,6 @@ bootutil_img_validate(struct enc_key_data *enc_state, int image_index,
uint32_t off;
uint16_t len;
uint16_t type;
int image_hash_valid = 0;
#ifdef EXPECTED_SIG_TLV
FIH_DECLARE(valid_signature, FIH_FAILURE);
#ifndef MCUBOOT_BUILTIN_KEY
Expand All @@ -419,7 +420,10 @@ bootutil_img_validate(struct enc_key_data *enc_state, int image_index,
#endif /* EXPECTED_SIG_TLV */
struct image_tlv_iter it;
uint8_t buf[SIG_BUF_SIZE];
#if defined(EXPECTED_HASH_TLV) && !defined(MCUBOOT_SIGN_ED25519_PURE)
int image_hash_valid = 0;
uint8_t hash[IMAGE_HASH_SIZE];
#endif
int rc = 0;
FIH_DECLARE(fih_rc, FIH_FAILURE);
#ifdef MCUBOOT_HW_ROLLBACK_PROT
Expand All @@ -428,6 +432,7 @@ bootutil_img_validate(struct enc_key_data *enc_state, int image_index,
FIH_DECLARE(security_counter_valid, FIH_FAILURE);
#endif

#if defined(EXPECTED_HASH_TLV) && !defined(MCUBOOT_SIGN_ED25519_PURE)
rc = bootutil_img_hash(enc_state, image_index, hdr, fap, tmp_buf,
tmp_buf_sz, hash, seed, seed_len);
if (rc) {
Expand All @@ -437,6 +442,7 @@ bootutil_img_validate(struct enc_key_data *enc_state, int image_index,
if (out_hash) {
memcpy(out_hash, hash, IMAGE_HASH_SIZE);
}
#endif

rc = bootutil_tlv_iter_begin(&it, hdr, fap, IMAGE_TLV_ANY, false);
if (rc) {
Expand Down Expand Up @@ -480,8 +486,10 @@ bootutil_img_validate(struct enc_key_data *enc_state, int image_index,
}
}
#endif

if (type == EXPECTED_HASH_TLV) {
switch(type) {
#if defined(EXPECTED_HASH_TLV) && !defined(MCUBOOT_SIGN_ED25519_PURE)
case EXPECTED_HASH_TLV:
{
/* Verify the image hash. This must always be present. */
if (len != sizeof(hash)) {
rc = -1;
Expand All @@ -499,8 +507,12 @@ bootutil_img_validate(struct enc_key_data *enc_state, int image_index,
}

image_hash_valid = 1;
break;
}
#endif /*def EXPECTED_HASH_TLV */
#ifdef EXPECTED_KEY_TLV
} else if (type == EXPECTED_KEY_TLV) {
case EXPECTED_KEY_TLV:
{
/*
* Determine which key we should be checking.
*/
Expand All @@ -525,9 +537,12 @@ bootutil_img_validate(struct enc_key_data *enc_state, int image_index,
* The key may not be found, which is acceptable. There
* can be multiple signatures, each preceded by a key.
*/
break;
}
#endif /* EXPECTED_KEY_TLV */
#ifdef EXPECTED_SIG_TLV
} else if (type == EXPECTED_SIG_TLV) {
case EXPECTED_SIG_TLV:
{
/* Ignore this signature if it is out of bounds. */
if (key_id < 0 || key_id >= bootutil_key_cnt) {
key_id = -1;
Expand All @@ -541,12 +556,25 @@ bootutil_img_validate(struct enc_key_data *enc_state, int image_index,
if (rc) {
goto out;
}
#ifndef MCUBOOT_SIGN_ED25519_PURE
FIH_CALL(bootutil_verify_sig, valid_signature, hash, sizeof(hash),
buf, len, key_id);
#else
/* Directly check signature on the image, by using the mapping of
* a device to memory. The pointer is beginning of image in flash,
* so offset of area, the range is header + image + protected tlvs.
*/
FIH_CALL(bootutil_verify_img, valid_signature, (void *)flash_area_get_off(fap),
hdr->ih_hdr_size + hdr->ih_img_size + hdr->ih_protect_tlv_size,
buf, len, key_id);
#endif
key_id = -1;
break;
}
#endif /* EXPECTED_SIG_TLV */
#ifdef MCUBOOT_HW_ROLLBACK_PROT
} else if (type == IMAGE_TLV_SEC_CNT) {
case IMAGE_TLV_SEC_CNT:
{
/*
* Verify the image's security counter.
* This must always be present.
Expand Down Expand Up @@ -581,14 +609,21 @@ bootutil_img_validate(struct enc_key_data *enc_state, int image_index,

/* The image's security counter has been successfully verified. */
security_counter_valid = fih_rc;
break;
}
#endif /* MCUBOOT_HW_ROLLBACK_PROT */
}
}

#if defined(EXPECTED_HASH_TLV) && !defined(MCUBOOT_SIGN_ED25519_PURE)
rc = !image_hash_valid;
if (rc) {
goto out;
}
#elif defined(MCUBOOT_SIGN_ED25519_PURE)
/* This returns true on EQ, rc is err on non-0 */
rc = !FIH_EQ(valid_signature, FIH_SUCCESS);
#endif
#ifdef EXPECTED_SIG_TLV
FIH_SET(fih_rc, valid_signature);
#endif
Expand Down
15 changes: 14 additions & 1 deletion boot/zephyr/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -259,10 +259,23 @@ config BOOT_SIGNATURE_TYPE_ED25519
image; that is not completely correct approach as the SHA512 should be
rather directly calculated over an image.
select BOOT_ENCRYPTION_SUPPORT
select BOOT_IMG_HASH_ALG_SHA256_ALLOW
select BOOT_IMG_HASH_ALG_SHA256_ALLOW if !BOOT_SIGNATURE_TYPE_ED25519_PURE
# The SHA is used only for key hashing, not for images.
select BOOT_IMG_HASH_ALG_SHA512_ALLOW

if BOOT_SIGNATURE_TYPE_ED25519

config BOOT_SIGNATURE_TYPE_ED25519_PURE
bool "PureEdDSA ed255129 signature of image"
help
PureEdDSA where signature is directly calculated on image as a message.
This is more secure signature then the ed25519 over sha the
BOOT_SIGNATURE_TYPE_ED25519 offers, but it is only possible on devices
that can hold all slots on internal storage with mapping to device
address space, as this type of signature is calculated on entire
message at once.
select BOOT_ENCRYPTION_SUPPORT

choice BOOT_ED25519_IMPLEMENTATION
prompt "Ecdsa implementation"
default BOOT_ED25519_PSA if NRF_SECURITY
Expand Down
5 changes: 5 additions & 0 deletions boot/zephyr/include/mcuboot_config/mcuboot_config.h
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,11 @@
#define MCUBOOT_HASH_STORAGE_DIRECTLY
#endif

#ifdef CONFIG_BOOT_SIGNATURE_TYPE_ED25519_PURE
#define MCUBOOT_SIGN_ED25519
#define MCUBOOT_SIGN_ED25519_PURE
#endif

#ifdef CONFIG_BOOT_BOOTSTRAP
#define MCUBOOT_BOOTSTRAP 1
#endif
Expand Down

0 comments on commit cd55052

Please sign in to comment.