Boot: Add hardware key support to MCUBoot
PSA Trusted Boot and Firmware Update specification requires
the support of at least one immutable root of trust public key
(ROTPK) for firmware verification. This key is provisioned to
the SoC during manufacturing. This change enables MCUBoot to
get the ROTPK hash from the SoC and compare with calculated
hash of public key from image manifest to validate the key
which is used for firmware authentication before usage.
Change-Id: I68cf4104bc2984fa8ad4c902d2a9a36064939f1e
Signed-off-by: Tamas Ban <tamas.ban@arm.com>
diff --git a/bl2/ext/mcuboot/bootutil/include/bootutil/image.h b/bl2/ext/mcuboot/bootutil/include/bootutil/image.h
index 6afcc48..46fdbfc 100644
--- a/bl2/ext/mcuboot/bootutil/include/bootutil/image.h
+++ b/bl2/ext/mcuboot/bootutil/include/bootutil/image.h
@@ -65,6 +65,7 @@
* 2nd one is the actual signature.
*/
#define IMAGE_TLV_KEYHASH 0x01 /* hash of the public key */
+#define IMAGE_TLV_KEY 0x02 /* public key */
#define IMAGE_TLV_SHA256 0x10 /* SHA256 of image hdr and body */
#define IMAGE_TLV_RSA2048_PSS 0x20 /* RSA2048 of hash output */
#define IMAGE_TLV_RSA3072_PSS 0x23 /* RSA3072 of hash output */
diff --git a/bl2/ext/mcuboot/bootutil/include/bootutil/sign_key.h b/bl2/ext/mcuboot/bootutil/include/bootutil/sign_key.h
index 47b2570..b0c1f21 100644
--- a/bl2/ext/mcuboot/bootutil/include/bootutil/sign_key.h
+++ b/bl2/ext/mcuboot/bootutil/include/bootutil/sign_key.h
@@ -26,12 +26,22 @@
extern "C" {
#endif
+#ifdef MCUBOOT_HW_KEY
+struct bootutil_key {
+ uint8_t *key;
+ unsigned int *len;
+};
+
+extern struct bootutil_key bootutil_keys[];
+#else
struct bootutil_key {
const uint8_t *key;
const unsigned int *len;
};
extern const struct bootutil_key bootutil_keys[];
+#endif
+
extern const int bootutil_key_cnt;
#ifdef __cplusplus
diff --git a/bl2/ext/mcuboot/bootutil/src/image_validate.c b/bl2/ext/mcuboot/bootutil/src/image_validate.c
index 561d1d0..fee67a2 100644
--- a/bl2/ext/mcuboot/bootutil/src/image_validate.c
+++ b/bl2/ext/mcuboot/bootutil/src/image_validate.c
@@ -43,6 +43,10 @@
#include "bootutil_priv.h"
+#ifdef MCUBOOT_HW_KEY
+#include "platform/include/tfm_plat_crypto_keys.h"
+#endif
+
/*
* Compute SHA256 over the image.
*/
@@ -122,6 +126,33 @@
#endif
#ifdef EXPECTED_SIG_TLV
+#ifdef MCUBOOT_HW_KEY
+extern unsigned int pub_key_len;
+static int
+bootutil_find_key(uint8_t *key, uint16_t key_len)
+{
+ bootutil_sha256_context sha256_ctx;
+ uint8_t hash[32];
+ uint8_t key_hash[32];
+ uint32_t key_hash_size= sizeof(key_hash);
+ enum tfm_plat_err_t plat_err;
+
+ bootutil_sha256_init(&sha256_ctx);
+ bootutil_sha256_update(&sha256_ctx, key, key_len);
+ bootutil_sha256_finish(&sha256_ctx, hash);
+
+ plat_err = tfm_plat_get_rotpk_hash(0, key_hash, &key_hash_size);
+ if (plat_err != TFM_PLAT_ERR_SUCCESS) {
+ return -1;
+ }
+ if (!memcmp(hash, key_hash, key_hash_size)) {
+ bootutil_keys[0].key = key;
+ pub_key_len = key_len;
+ return 0;
+ }
+ return -1;
+}
+#else
static int
bootutil_find_key(uint8_t *keyhash, uint8_t keyhash_len)
{
@@ -144,6 +175,7 @@
return -1;
}
#endif
+#endif
#ifdef MCUBOOT_RAM_LOADING
/* Check the hash of an image after it has been copied to SRAM */
@@ -328,6 +360,10 @@
#ifdef EXPECTED_SIG_TLV
int valid_signature = 0;
int key_id = -1;
+#ifdef MCUBOOT_HW_KEY
+ /* Few extra bytes for encoding and for public exponent */
+ uint8_t key_buf[SIG_BUF_SIZE + 24];
+#endif
#endif
struct image_tlv tlv;
uint8_t buf[SIG_BUF_SIZE];
@@ -388,6 +424,7 @@
sha256_valid = 1;
#ifdef EXPECTED_SIG_TLV
+#ifndef MCUBOOT_HW_KEY
} else if (tlv.it_type == IMAGE_TLV_KEYHASH) {
/*
* Determine which key we should be checking.
@@ -404,6 +441,24 @@
* The key may not be found, which is acceptable. There
* can be multiple signatures, each preceded by a key.
*/
+#else
+ } else if (tlv.it_type == IMAGE_TLV_KEY) {
+ /*
+ * Determine which key we should be checking.
+ */
+ if (tlv.it_len > sizeof(key_buf)) {
+ return -1;
+ }
+ rc = flash_area_read(fap, off + sizeof(tlv), key_buf, tlv.it_len);
+ if (rc) {
+ return rc;
+ }
+ key_id = bootutil_find_key(key_buf, tlv.it_len);
+ /*
+ * The key may not be found, which is acceptable. There
+ * can be multiple signatures, each preceded by a key.
+ */
+#endif /* MCUBOOT_HW_KEY */
} else if (tlv.it_type == EXPECTED_SIG_TLV) {
/* Ignore this signature if it is out of bounds. */
if (key_id >= 0 && key_id < bootutil_key_cnt) {