Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 27 additions & 0 deletions boot/bootutil/include/bootutil/sign_key.h
Original file line number Diff line number Diff line change
Expand Up @@ -57,9 +57,36 @@ extern struct bootutil_key bootutil_keys[];
*
* @return 0 on success; nonzero on failure.
*/
#if defined(MCUBOOT_HW_KEY_MULTI)
/**
* Special return code for boot_retrieve_public_key_hash().
*
* Returned when the requested key index is out of range (no more keys).
*/
#define BOOTUTIL_HW_KEY_NO_MORE 1

/**
* Retrieve a HW key hash by index (multi-key support).
*
* @param[in] image_index Index of the image to be authenticated.
* @param[in] key_index Index of the HW key hash to retrieve.
* @param[out] public_key_hash Buffer to store the key-hash in.
* @param[in,out] key_hash_size As input the size of the buffer. As output
* the actual key-hash length.
*
* @return 0 on success; BOOTUTIL_HW_KEY_NO_MORE when
* key_index is out of range; other nonzero on
* failure.
*/
int boot_retrieve_public_key_hash(uint8_t image_index,
uint8_t key_index,
uint8_t *public_key_hash,
size_t *key_hash_size);
#else
int boot_retrieve_public_key_hash(uint8_t image_index,
uint8_t *public_key_hash,
size_t *key_hash_size);
#endif /* MCUBOOT_HW_KEY_MULTI */
#endif /* !MCUBOOT_HW_KEY */

extern const int bootutil_key_cnt;
Expand Down
27 changes: 27 additions & 0 deletions boot/bootutil/src/bootutil_find_key.c
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,32 @@ int bootutil_find_key(uint8_t image_index, uint8_t *key, uint16_t key_len)
bootutil_sha_finish(&sha_ctx, hash);
bootutil_sha_drop(&sha_ctx);

#if defined(MCUBOOT_HW_KEY_MULTI)
for (uint8_t key_index = 0;; key_index++) {
key_hash_size = sizeof(key_hash);
rc = boot_retrieve_public_key_hash(image_index, key_index, key_hash,
&key_hash_size);
if (rc == BOOTUTIL_HW_KEY_NO_MORE) {
break;
}
if (rc) {
return -1;
}

/* Adding hardening to avoid this potential attack:
* - Image is signed with an arbitrary key and the corresponding public
* key is added as a TLV field.
* - During public key validation (comparing against key-hash read from
* HW) a fault is injected to accept the public key as valid one.
*/
FIH_CALL(boot_fih_memequal, fih_rc, hash, key_hash, key_hash_size);
if (FIH_EQ(fih_rc, FIH_SUCCESS)) {
bootutil_keys[0].key = key;
pub_key_len = key_len;
return 0;
}
}
#else
rc = boot_retrieve_public_key_hash(image_index, key_hash, &key_hash_size);
if (rc) {
return -1;
Expand All @@ -113,6 +139,7 @@ int bootutil_find_key(uint8_t image_index, uint8_t *key, uint16_t key_len)
pub_key_len = key_len;
return 0;
}
#endif /* MCUBOOT_HW_KEY_MULTI */

return -1;
}
Expand Down
7 changes: 7 additions & 0 deletions boot/zephyr/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -541,6 +541,13 @@ config BOOT_BUILTIN_KEY
help
Use built-in key for image verification, otherwise the public key is embedded in MCUBoot.

config BOOT_HW_KEY_MULTI
bool "Allow multiple HW key hashes"
depends on BOOT_HW_KEY
help
Enable the multi-key HW key interface so MCUboot can iterate over
multiple provisioned key hashes when matching a public key.

config BOOT_VALIDATE_SLOT0
bool "Validate image in the primary slot on every boot"
default y
Expand Down
4 changes: 4 additions & 0 deletions boot/zephyr/include/mcuboot_config/mcuboot_config.h
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,10 @@
#define MCUBOOT_BUILTIN_KEY
#endif

#ifdef CONFIG_BOOT_HW_KEY_MULTI
#define MCUBOOT_HW_KEY_MULTI
#endif

#ifdef CONFIG_BOOT_VALIDATE_SLOT0
#define MCUBOOT_VALIDATE_PRIMARY_SLOT
#endif
Expand Down
15 changes: 10 additions & 5 deletions docs/design.md
Original file line number Diff line number Diff line change
Expand Up @@ -1314,16 +1314,21 @@ Using any of these options makes MCUboot independent from the public key(s).
The key(s) can be provisioned any time and by different parties.

Hardware KEYs support options details:
- `MCUBOOT_HW_KEY`: In this case the hash of the public key must be
- `MCUBOOT_HW_KEY`: In this case the hash(es) of the public key(s) must be
provisioned to the target device and MCUboot must be able to retrieve the
key-hash from there. For this reason the target must provide a definition
for the `boot_retrieve_public_key_hash()` function which is declared in
`boot/bootutil/include/bootutil/sign_key.h`. It is also required to use
`boot/bootutil/include/bootutil/sign_key.h`. If `MCUBOOT_HW_KEY_MULTI` is
enabled, the function takes a key index and must return
`BOOTUTIL_HW_KEY_NO_MORE` when the index is out of range, so MCUboot can
iterate over all provisioned key hashes. If `MCUBOOT_HW_KEY_MULTI` is not
enabled, the legacy single-key interface is used. It is also required to use
the `full` option for the `--public-key-format` imgtool argument in order to
add the whole public key (PUBKEY TLV) to the image manifest instead of its
hash (KEYHASH TLV). During boot the public key is validated before using it for
signature verification, MCUboot calculates the hash of the public key from the
TLV area and compares it with the key-hash that was retrieved from the device.
hash (KEYHASH TLV). During boot the public key is validated before using it
for signature verification, MCUboot calculates the hash of the public key from
the TLV area and compares it with the key-hash that was retrieved from the
device.
- `MCUBOOT_BUILTIN_KEY`: With this option the whole public key(s) used for
signature verification must be provisioned to the target device and the used
[cryptographic library](PORTING.md) must support the usage of builtin keys based
Expand Down