Boot: Use TLV iterator everywhere

With a partial code synchronization the TLV iterator API was introduced
(change-id: I817b199f4923433010253c4a201ada250f743aa8). This patch
extends its usage everywhere the bootloader searches TLVs in the image
manifest, thus the boot_find_tlv_offs() function can finally be removed.

Change-Id: Iff5b3e596199b6593958816694555aef50c19aef
Signed-off-by: David Vincze <david.vincze@arm.com>
diff --git a/bl2/ext/mcuboot/bootutil/src/bootutil_priv.h b/bl2/ext/mcuboot/bootutil/src/bootutil_priv.h
index 72efd1b..b577e41 100644
--- a/bl2/ext/mcuboot/bootutil/src/bootutil_priv.h
+++ b/bl2/ext/mcuboot/bootutil/src/bootutil_priv.h
@@ -233,9 +233,6 @@
                          uint8_t image_num);
 int boot_write_swap_size(const struct flash_area *fap, uint32_t swap_size);
 int boot_read_swap_size(int image_index, uint32_t *swap_size);
-int boot_find_tlv_offs(const struct image_header *hdr,
-                       const struct flash_area *fap,
-                       uint32_t *off, uint32_t *end);
 bool boot_add_uint32_overflow_check(uint32_t a, uint32_t b);
 bool boot_add_uint16_overflow_check(uint16_t a, uint16_t b);
 
diff --git a/bl2/ext/mcuboot/bootutil/src/image_validate.c b/bl2/ext/mcuboot/bootutil/src/image_validate.c
index 8c554ee..83bf50e 100644
--- a/bl2/ext/mcuboot/bootutil/src/image_validate.c
+++ b/bl2/ext/mcuboot/bootutil/src/image_validate.c
@@ -194,9 +194,9 @@
                               const struct flash_area *fap,
                               uint32_t *img_security_cnt)
 {
-    struct image_tlv tlv;
+    struct image_tlv_iter it;
     uint32_t off;
-    uint32_t end;
+    uint16_t len;
     uint32_t found = 0;
     int32_t rc;
 
@@ -212,50 +212,35 @@
         return BOOT_EBADIMAGE;
     }
 
-    rc = boot_find_tlv_offs(hdr, fap, &off, &end);
+    rc = bootutil_tlv_iter_begin(&it, hdr, fap, IMAGE_TLV_SEC_CNT, true);
     if (rc) {
         return rc;
     }
 
-    /* Calculate the end of the protected TLV area. */
-    end = off - sizeof(struct image_tlv_info) +
-          (uint32_t)hdr->ih_protect_tlv_size;
-
     /* Traverse through the protected TLV area to find
      * the security counter TLV.
      */
-    while (off < end) {
-        rc = LOAD_IMAGE_DATA(hdr, fap, off, &tlv, sizeof(tlv));
+    while (true) {
+        rc = bootutil_tlv_iter_next(&it, &off, &len, NULL);
+        if (rc < 0) {
+            return -1;
+        } else if (rc > 0) {
+            break;
+        }
+
+        if (len != sizeof(*img_security_cnt)) {
+            /* Security counter is not valid. */
+            return BOOT_EBADIMAGE;
+        }
+
+        rc = LOAD_IMAGE_DATA(hdr, fap, off, img_security_cnt, len);
         if (rc != 0) {
             return BOOT_EFLASH;
         }
 
-        if (tlv.it_type == IMAGE_TLV_SEC_CNT) {
-
-            if (tlv.it_len != sizeof(*img_security_cnt)) {
-                /* Security counter is not valid. */
-                break;
-            }
-
-            rc = LOAD_IMAGE_DATA(hdr, fap, off + sizeof(tlv),
-                                 img_security_cnt, tlv.it_len);
-            if (rc != 0) {
-                return BOOT_EFLASH;
-            }
-
-            /* Security counter has been found. */
-            found = 1;
-            break;
-        }
-
-        /* Avoid integer overflow. */
-        if (boot_add_uint32_overflow_check(off, (sizeof(tlv) + tlv.it_len)))
-        {
-            /* Potential overflow. */
-            break;
-        } else {
-            off += sizeof(tlv) + tlv.it_len;
-        }
+        /* Security counter has been found. */
+        found = 1;
+        break;
     }
 
     if (found) {
diff --git a/bl2/ext/mcuboot/bootutil/src/loader.c b/bl2/ext/mcuboot/bootutil/src/loader.c
index 9b5b935..c2b1b5f 100644
--- a/bl2/ext/mcuboot/bootutil/src/loader.c
+++ b/bl2/ext/mcuboot/bootutil/src/loader.c
@@ -159,43 +159,6 @@
 #endif /* !MCUBOOT_NO_SWAP && !MCUBOOT_RAM_LOADING */
 
 /*
- * Locate the TLVs in an image.
- *
- * @param hdr The image_header struct of the image being checked
- * @param fap flash_area struct of the slot storing the image being checked
- * @param off Address of the first TLV (after TLV info)
- * @param end Address where TLV area ends
- *
- * Returns 0 on success.
- */
-int
-boot_find_tlv_offs(const struct image_header *hdr, const struct flash_area *fap,
-                   uint32_t *off, uint32_t *end)
-{
-    struct image_tlv_info info;
-    uint32_t off_;
-
-    off_ = BOOT_TLV_OFF(hdr);
-
-    if (LOAD_IMAGE_DATA(hdr, fap, off_, &info, sizeof(info))) {
-        return BOOT_EFLASH;
-    }
-
-    if (info.it_magic != IMAGE_TLV_INFO_MAGIC) {
-        return BOOT_EBADIMAGE;
-    }
-
-    if (boot_add_uint32_overflow_check(off_, info.it_tlv_tot))
-    {
-        return -1;
-    }
-
-    *end = off_ + info.it_tlv_tot;
-    *off = off_ + sizeof(info);
-    return 0;
-}
-
-/*
  * \brief Verifies the image header: magic value, flags, integer overflow.
  *
  * \retval 0
diff --git a/bl2/src/boot_record.c b/bl2/src/boot_record.c
index ba98eba..63c6181 100644
--- a/bl2/src/boot_record.c
+++ b/bl2/src/boot_record.c
@@ -90,8 +90,10 @@
                           const struct image_header *hdr,
                           const struct flash_area *fap)
 {
-    struct image_tlv tlv_entry;
-    uintptr_t tlv_end, offset;
+    struct image_tlv_iter it;
+    uint32_t offset;
+    uint16_t len;
+    uint8_t type;
     uint8_t buf[32];
     int32_t res;
     uint16_t ias_minor;
@@ -106,7 +108,8 @@
     /* Manifest data is concatenated to the end of the image. It is encoded in
      * TLV format.
      */
-    res = boot_find_tlv_offs(hdr, fap, &offset, &tlv_end);
+
+    res = bootutil_tlv_iter_begin(&it, hdr, fap, IMAGE_TLV_ANY, false);
     if (res) {
         return BOOT_STATUS_ERROR;
     }
@@ -116,20 +119,21 @@
      *  - image hash:      SW component measurement value
      *  - public key hash: Signer ID
      */
-    for (; offset < tlv_end; offset += sizeof(tlv_entry) + tlv_entry.it_len) {
-        res = LOAD_IMAGE_DATA(hdr, fap, offset, &tlv_entry, sizeof(tlv_entry));
-        if (res) {
+    while (true) {
+        res = bootutil_tlv_iter_next(&it, &offset, &len, &type);
+        if (res < 0) {
             return BOOT_STATUS_ERROR;
+        } else if (res > 0) {
+            break;
         }
 
-        if (tlv_entry.it_type == IMAGE_TLV_SHA256) {
+        if (type == IMAGE_TLV_SHA256) {
             /* Get the image's hash value from the manifest section */
-            if (tlv_entry.it_len != sizeof(buf)) { /* SHA256 - 32 bytes */
+            if (len != sizeof(buf)) { /* SHA256 - 32 bytes */
                 return BOOT_STATUS_ERROR;
             }
 
-            res = LOAD_IMAGE_DATA(hdr, fap, offset + sizeof(tlv_entry),
-                                  buf, tlv_entry.it_len);
+            res = LOAD_IMAGE_DATA(hdr, fap, offset, buf, len);
             if (res) {
                 return BOOT_STATUS_ERROR;
             }
@@ -138,7 +142,7 @@
             ias_minor = SET_IAS_MINOR(sw_module, SW_MEASURE_VALUE);
             res2 = boot_add_data_to_shared_area(TLV_MAJOR_IAS,
                                                 ias_minor,
-                                                tlv_entry.it_len,
+                                                len,
                                                 buf);
             if (res2) {
                 return BOOT_STATUS_ERROR;
@@ -156,32 +160,30 @@
 
 #ifdef MCUBOOT_SIGN_RSA
 #ifndef MCUBOOT_HW_KEY
-        } else if (tlv_entry.it_type == IMAGE_TLV_KEYHASH) {
+        } else if (type == IMAGE_TLV_KEYHASH) {
             /* Get the hash of the public key from the manifest section */
-            if (tlv_entry.it_len != sizeof(buf)) { /* SHA256 - 32 bytes */
+            if (len != sizeof(buf)) { /* SHA256 - 32 bytes */
                 return BOOT_STATUS_ERROR;
             }
 
-            res = LOAD_IMAGE_DATA(hdr, fap, offset + sizeof(tlv_entry),
-                                  buf, tlv_entry.it_len);
+            res = LOAD_IMAGE_DATA(hdr, fap, offset, buf, len);
             if (res) {
                 return BOOT_STATUS_ERROR;
             }
 #else /* MCUBOOT_HW_KEY */
-        } else if (tlv_entry.it_type == IMAGE_TLV_KEY) {
+        } else if (type == IMAGE_TLV_KEY) {
             /* Get the public key from the manifest section. */
-            if (tlv_entry.it_len > sizeof(key_buf)) {
+            if (len > sizeof(key_buf)) {
                 return BOOT_STATUS_ERROR;
             }
-            res = LOAD_IMAGE_DATA(hdr, fap, offset + sizeof(tlv_entry),
-                                  key_buf, tlv_entry.it_len);
+            res = LOAD_IMAGE_DATA(hdr, fap, offset, key_buf, len);
             if (res) {
                 return BOOT_STATUS_ERROR;
             }
 
             /* Calculate the hash of the public key. */
             bootutil_sha256_init(&sha256_ctx);
-            bootutil_sha256_update(&sha256_ctx, key_buf, tlv_entry.it_len);
+            bootutil_sha256_update(&sha256_ctx, key_buf, len);
             bootutil_sha256_finish(&sha256_ctx, buf);
 #endif /* MCUBOOT_HW_KEY */
 
@@ -387,8 +389,10 @@
 
 #else /* MCUBOOT_INDIVIDUAL_CLAIMS */
 
-    struct image_tlv tlv_entry;
-    uint32_t tlv_end, offset;
+    struct image_tlv_iter it;
+    uint32_t offset;
+    uint16_t len;
+    uint8_t type;
     size_t record_len = 0;
     uint8_t image_hash[32]; /* SHA256 - 32 Bytes */
     uint8_t buf[MAX_BOOT_RECORD_SZ];
@@ -402,7 +406,7 @@
      * It is encoded in TLV format.
      */
 
-    res = boot_find_tlv_offs(hdr, fap, &offset, &tlv_end);
+    res = bootutil_tlv_iter_begin(&it, hdr, fap, IMAGE_TLV_ANY, false);
     if (res) {
         return BOOT_STATUS_ERROR;
     }
@@ -410,32 +414,32 @@
     /* Traverse through the TLV area to find the boot record
      * and image hash TLVs.
      */
-    while (offset < tlv_end) {
-        res = LOAD_IMAGE_DATA(hdr, fap, offset, &tlv_entry, sizeof(tlv_entry));
-        if (res) {
+    while (true) {
+        res = bootutil_tlv_iter_next(&it, &offset, &len, &type);
+        if (res < 0) {
             return BOOT_STATUS_ERROR;
+        } else if (res > 0) {
+            break;
         }
 
-        if (tlv_entry.it_type == IMAGE_TLV_BOOT_RECORD) {
-            if (tlv_entry.it_len > sizeof(buf)) {
+        if (type == IMAGE_TLV_BOOT_RECORD) {
+            if (len > sizeof(buf)) {
                 return BOOT_STATUS_ERROR;
             }
-            res = LOAD_IMAGE_DATA(hdr, fap, offset + sizeof(tlv_entry),
-                                  buf, tlv_entry.it_len);
+            res = LOAD_IMAGE_DATA(hdr, fap, offset, buf, len);
             if (res) {
                 return BOOT_STATUS_ERROR;
             }
 
-            record_len = tlv_entry.it_len;
+            record_len = len;
             boot_record_found = 1;
 
-        } else if (tlv_entry.it_type == IMAGE_TLV_SHA256) {
+        } else if (type == IMAGE_TLV_SHA256) {
             /* Get the image's hash value from the manifest section. */
-            if (tlv_entry.it_len > sizeof(image_hash)) {
+            if (len > sizeof(image_hash)) {
                 return BOOT_STATUS_ERROR;
             }
-            res = LOAD_IMAGE_DATA(hdr, fap, offset + sizeof(tlv_entry),
-                                  image_hash, tlv_entry.it_len);
+            res = LOAD_IMAGE_DATA(hdr, fap, offset, image_hash, len);
             if (res) {
                 return BOOT_STATUS_ERROR;
             }
@@ -449,15 +453,6 @@
              */
             break;
         }
-
-        /* Avoid integer overflow. */
-        if ((UINTPTR_MAX - offset) <
-            (sizeof(tlv_entry) + tlv_entry.it_len)) {
-            /* Potential overflow. */
-            break;
-        } else {
-            offset += sizeof(tlv_entry) + tlv_entry.it_len;
-        }
     }