Place TLV size into TLV itself
To allow the signatures to be replaced, move the size of the TLV into a
small "info" header at the start of the TLV.
Note that this causes image swapping to lose robustness. This is fixed
by a later commit.
Based on work by Marko Kiiskila <marko@runtime.io>
Signed-off-by: Marko Kiiskila <marko@runtime.io>
Signed-off-by: David Brown <david.brown@linaro.org>
JIRA: MCUB-65
diff --git a/boot/bootutil/src/loader.c b/boot/bootutil/src/loader.c
index 1923fbc..82d39f8 100644
--- a/boot/bootutil/src/loader.c
+++ b/boot/bootutil/src/loader.c
@@ -228,6 +228,43 @@
}
#endif /* !MCUBOOT_OVERWRITE_ONLY */
+/*
+ * Compute the total size of the given image. Includes the size of
+ * the TLVs.
+ */
+static int
+boot_read_image_size(int slot, struct image_header *hdr, uint32_t *size)
+{
+ const struct flash_area *fap;
+ struct image_tlv_info info;
+ int area_id;
+ int rc;
+
+ area_id = flash_area_id_from_image_slot(slot);
+ rc = flash_area_open(area_id, &fap);
+ if (rc != 0) {
+ rc = BOOT_EFLASH;
+ goto done;
+ }
+
+ rc = flash_area_read(fap, hdr->ih_hdr_size + hdr->ih_img_size,
+ &info, sizeof(info));
+ if (rc != 0) {
+ rc = BOOT_EFLASH;
+ goto done;
+ }
+ if (info.it_magic != IMAGE_TLV_INFO_MAGIC) {
+ rc = BOOT_EBADIMAGE;
+ goto done;
+ }
+ *size = hdr->ih_hdr_size + hdr->ih_img_size + info.it_tlv_tot;
+ rc = 0;
+
+done:
+ flash_area_close(fap);
+ return 0;
+}
+
static int
boot_read_image_header(int slot, struct image_header *out_hdr)
{
@@ -1029,12 +1066,14 @@
hdr = boot_img_hdr(&boot_data, 0);
if (hdr->ih_magic == IMAGE_MAGIC) {
- copy_size = hdr->ih_hdr_size + hdr->ih_img_size + hdr->ih_tlv_size;
+ rc = boot_read_image_size(0, hdr, ©_size);
+ assert(rc == 0);
}
hdr = boot_img_hdr(&boot_data, 1);
if (hdr->ih_magic == IMAGE_MAGIC) {
- size = hdr->ih_hdr_size + hdr->ih_img_size + hdr->ih_tlv_size;
+ rc = boot_read_image_size(1, hdr, &size);
+ assert(rc == 0);
}
if (!size || !copy_size || size == copy_size) {
@@ -1044,10 +1083,11 @@
hdr = &tmp_hdr;
if (hdr->ih_magic == IMAGE_MAGIC) {
if (!size) {
- size = hdr->ih_hdr_size + hdr->ih_img_size + hdr->ih_tlv_size;
+ rc = boot_read_image_size(2, hdr, &size);
} else {
- copy_size = hdr->ih_hdr_size + hdr->ih_img_size + hdr->ih_tlv_size;
+ rc = boot_read_image_size(2, hdr, &size);
}
+ assert(rc == 0);
}
}