diff --git a/boot/bootutil/src/bootutil_priv.h b/boot/bootutil/src/bootutil_priv.h index 32f996e78..68e0595cf 100644 --- a/boot/bootutil/src/bootutil_priv.h +++ b/boot/bootutil/src/bootutil_priv.h @@ -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); diff --git a/boot/bootutil/src/image_ed25519.c b/boot/bootutil/src/image_ed25519.c index c060b9a32..6351567a6 100644 --- a/boot/bootutil/src/image_ed25519.c +++ b/boot/bootutil/src/image_ed25519.c @@ -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 */ diff --git a/boot/bootutil/src/image_validate.c b/boot/bootutil/src/image_validate.c index 59d35d714..65c1b378a 100644 --- a/boot/bootutil/src/image_validate.c +++ b/boot/bootutil/src/image_validate.c @@ -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, @@ -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 @@ -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 @@ -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 @@ -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) { @@ -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) { @@ -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; @@ -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. */ @@ -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; @@ -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. @@ -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 diff --git a/boot/zephyr/Kconfig b/boot/zephyr/Kconfig index bb0c1762b..8e0c6cfa4 100644 --- a/boot/zephyr/Kconfig +++ b/boot/zephyr/Kconfig @@ -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 diff --git a/boot/zephyr/include/mcuboot_config/mcuboot_config.h b/boot/zephyr/include/mcuboot_config/mcuboot_config.h index 184e944da..05654d0b4 100644 --- a/boot/zephyr/include/mcuboot_config/mcuboot_config.h +++ b/boot/zephyr/include/mcuboot_config/mcuboot_config.h @@ -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