From 0faf395d33811b4d7dafc73bca99ebc423ea23cf Mon Sep 17 00:00:00 2001 From: David Brown Date: Wed, 10 Apr 2024 14:40:08 -0600 Subject: [PATCH 1/3] boot: Add tlv query for protected region Add a query to the TLV iterator that will indicate if the currently iterated TLV entry was found in the protected region or not. Signed-off-by: David Brown --- boot/bootutil/include/bootutil/image.h | 1 + boot/bootutil/src/tlv.c | 20 ++++++++++++++++++++ 2 files changed, 21 insertions(+) diff --git a/boot/bootutil/include/bootutil/image.h b/boot/bootutil/include/bootutil/image.h index d3e5f93af..1f12d9512 100644 --- a/boot/bootutil/include/bootutil/image.h +++ b/boot/bootutil/include/bootutil/image.h @@ -186,6 +186,7 @@ int bootutil_tlv_iter_begin(struct image_tlv_iter *it, bool prot); int bootutil_tlv_iter_next(struct image_tlv_iter *it, uint32_t *off, uint16_t *len, uint16_t *type); +int bootutil_tlv_iter_is_prot(struct image_tlv_iter *it, uint32_t off); int32_t bootutil_get_img_security_cnt(struct image_header *hdr, const struct flash_area *fap, diff --git a/boot/bootutil/src/tlv.c b/boot/bootutil/src/tlv.c index 37d12a31d..a763c9685 100644 --- a/boot/bootutil/src/tlv.c +++ b/boot/bootutil/src/tlv.c @@ -132,3 +132,23 @@ bootutil_tlv_iter_next(struct image_tlv_iter *it, uint32_t *off, uint16_t *len, return 1; } + +/* + * Return if a TLV entry is in the protected area. + * + * @param it The image TLV iterator struct + * @param off The offset of the entry to check. + * + * @return 0 if this TLV iterator entry is not protected. + * 1 if this TLV iterator entry is in the protected region + * -1 if the iterator is invalid. + */ +int +bootutil_tlv_iter_is_prot(struct image_tlv_iter *it, uint32_t off) +{ + if (it == NULL || it->hdr == NULL || it->fap == NULL) { + return -1; + } + + return off < it->prot_end; +} From 74e0fcd27e0dfefffe46c52c62fb4bb8aa579b78 Mon Sep 17 00:00:00 2001 From: David Brown Date: Wed, 10 Apr 2024 14:59:00 -0600 Subject: [PATCH 2/3] boot: Enforce TLV entries to be protected Only allow TLV entries that are needed for signature verification to be placed in the unprotected area of the TLV. Signed-off-by: David Brown --- boot/bootutil/src/image_validate.c | 45 ++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/boot/bootutil/src/image_validate.c b/boot/bootutil/src/image_validate.c index 054e8e45b..a697676b6 100644 --- a/boot/bootutil/src/image_validate.c +++ b/boot/bootutil/src/image_validate.c @@ -349,6 +349,30 @@ bootutil_get_img_security_cnt(struct image_header *hdr, return 0; } +#ifndef ALLOW_ROGUE_TLVS +/* + * The following list of TLVs are the only entries allowed in the unprotected + * TLV section. All other TLV entries must be in the protected section. + */ +static const uint16_t allowed_unprot_tlvs[] = { + IMAGE_TLV_KEYHASH, + IMAGE_TLV_PUBKEY, + IMAGE_TLV_SHA256, + IMAGE_TLV_SHA384, + IMAGE_TLV_RSA2048_PSS, + IMAGE_TLV_ECDSA224, + IMAGE_TLV_ECDSA_SIG, + IMAGE_TLV_RSA3072_PSS, + IMAGE_TLV_ED25519, + IMAGE_TLV_ENC_RSA2048, + IMAGE_TLV_ENC_KW, + IMAGE_TLV_ENC_EC256, + IMAGE_TLV_ENC_X25519, + /* Mark end with ANY. */ + IMAGE_TLV_ANY, +}; +#endif + /* * Verify the integrity of the image. * Return non-zero if image could not be validated/does not validate. @@ -420,6 +444,27 @@ bootutil_img_validate(struct enc_key_data *enc_state, int image_index, break; } +#ifndef ALLOW_ROGUE_TLVS + /* + * Ensure that the non-protected TLV only has entries necessary to hold + * the signature. We also allow encryption related keys to be in the + * unprotected area. + */ + if (!bootutil_tlv_iter_is_prot(&it, off)) { + bool found = false; + for (const uint16_t *p = allowed_unprot_tlvs; *p != IMAGE_TLV_ANY; p++) { + if (type == *p) { + found = true; + break; + } + } + if (!found) { + FIH_SET(fih_rc, FIH_FAILURE); + goto out; + } + } +#endif + if (type == EXPECTED_HASH_TLV) { /* Verify the image hash. This must always be present. */ if (len != sizeof(hash)) { From 91cfa52fa3e6c829d13d8e93055b1b9668426aa3 Mon Sep 17 00:00:00 2001 From: David Brown Date: Wed, 10 Apr 2024 15:17:53 -0600 Subject: [PATCH 3/3] doc: Release notes for TLV check Add a release not stub for the TLV check. Signed-off-by: David Brown --- docs/release-notes.d/bootutil-check-tlv.md | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 docs/release-notes.d/bootutil-check-tlv.md diff --git a/docs/release-notes.d/bootutil-check-tlv.md b/docs/release-notes.d/bootutil-check-tlv.md new file mode 100644 index 000000000..1cfdb9876 --- /dev/null +++ b/docs/release-notes.d/bootutil-check-tlv.md @@ -0,0 +1,2 @@ +- Enforce that TLV entries that should be protected are. + This can be disabled by defining `ALLOW_ROGUE_TLVS`