From da2e2ab4e3d77819f2c477ee8b66242d240cdb7a Mon Sep 17 00:00:00 2001 From: David Brown Date: Wed, 10 Apr 2024 14:59:00 -0600 Subject: [PATCH] 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 054e8e45..a697676b 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)) {