Add TLV iterator API

This introduces an API which allows for iteration over an image's TLVs
without resorting to low-level implementation details. All previous TLV
low-level handling was updated to comply with this new interface, and it
also makes it easier for external code to handle TLVs.

The API provides two functions:

1) To start a new iterator:

```
int bootutil_tlv_iter_begin(struct image_tlv_iter *it,
                            const struct image_header *hdr,
                            const struct flash_area *fap, uint8_t type,
                            bool prot);
```

2) To iterate over existing TLVs of given type:

```
int bootutil_tlv_iter_next(struct image_tlv_iter *it, uint32_t *off,
                           uint16_t *len, uint8_t *type);
```

A type of IMAGE_TLV_ANY was added to allow for iteration over all TLVs.

Low-level TLV access functions were removed from API, but low-level
structs are still visible in the namespace.

Signed-off-by: Fabio Utzig <utzig@apache.org>
diff --git a/boot/bootutil/src/loader.c b/boot/bootutil/src/loader.c
index 1634312..045be52 100644
--- a/boot/bootutil/src/loader.c
+++ b/boot/bootutil/src/loader.c
@@ -243,38 +243,6 @@
 }
 
 /*
- * 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 (flash_area_read(fap, off_, &info, sizeof(info))) {
-        return BOOT_EFLASH;
-    }
-
-    if (info.it_magic != IMAGE_TLV_INFO_MAGIC) {
-        return BOOT_EBADIMAGE;
-    }
-
-    *end = off_ + info.it_tlv_tot;
-    *off = off_ + sizeof(info);
-    return 0;
-}
-
-/*
  * Compute the total size of the given image.  Includes the size of
  * the TLVs.
  */
@@ -283,6 +251,7 @@
 boot_read_image_size(struct boot_loader_state *state, int slot, uint32_t *size)
 {
     const struct flash_area *fap;
+    struct image_tlv_info info;
     uint32_t off;
     int area_id;
     int rc;
@@ -298,10 +267,19 @@
         goto done;
     }
 
-    rc = boot_find_tlv_offs(boot_img_hdr(state, slot), fap, &off, size);
-    if (rc != 0) {
+    off = BOOT_TLV_OFF(boot_img_hdr(state, slot));
+
+    if (flash_area_read(fap, off, &info, sizeof(info))) {
+        rc = BOOT_EFLASH;
         goto done;
     }
+
+    if (info.it_magic != IMAGE_TLV_INFO_MAGIC) {
+        rc = BOOT_EBADIMAGE;
+        goto done;
+    }
+
+    *size = off + info.it_tlv_tot;
     rc = 0;
 
 done:
@@ -1884,11 +1862,10 @@
 boot_verify_slot_dependencies(struct boot_loader_state *state, uint32_t slot)
 {
     const struct flash_area *fap;
-    struct image_tlv tlv;
+    struct image_tlv_iter it;
     struct image_dependency dep;
     uint32_t off;
-    uint32_t end;
-    bool dep_tlvs_found = false;
+    uint16_t len;
     int area_id;
     int rc;
 
@@ -1899,56 +1876,43 @@
         goto done;
     }
 
-    rc = boot_find_tlv_offs(boot_img_hdr(state, slot), fap, &off, &end);
+    rc = bootutil_tlv_iter_begin(&it, boot_img_hdr(state, slot), fap,
+            IMAGE_TLV_DEPENDENCY, true);
     if (rc != 0) {
         goto done;
     }
 
-    /* Traverse through all of the TLVs to find the dependency TLVs. */
-    for (; off < end; off += sizeof(tlv) + tlv.it_len) {
-        rc = flash_area_read(fap, off, &tlv, sizeof(tlv));
-        if (rc != 0) {
-             rc = BOOT_EFLASH;
-             goto done;
-         }
-
-        if (tlv.it_type == IMAGE_TLV_DEPENDENCY) {
-            dep_tlvs_found = true;
-
-            if (tlv.it_len != sizeof(dep)) {
-                rc = BOOT_EBADIMAGE;
-                goto done;
-            }
-
-            rc = flash_area_read(fap, off + sizeof(tlv), &dep, tlv.it_len);
-            if (rc != 0) {
-                rc = BOOT_EFLASH;
-                goto done;
-            }
-
-            if (dep.image_id >= BOOT_IMAGE_NUMBER) {
-                rc = BOOT_EBADARGS;
-                goto done;
-            }
-
-            /* Verify dependency and modify the swap type if not satisfied. */
-            rc = boot_verify_slot_dependency(state, &dep);
-            if (rc != 0) {
-                /* Dependency not satisfied. */
-                goto done;
-            }
-
-            /* Dependency satisfied, no action needed.
-             * Continue with the next TLV entry.
-             */
-        } else if (dep_tlvs_found) {
-            /* The dependency TLVs are contiguous in the TLV area. If a
-             * dependency had already been found and the last read TLV
-             * has a different type then there are no more dependency TLVs.
-             * The search can be finished.
-             */
+    while (true) {
+        rc = bootutil_tlv_iter_next(&it, &off, &len, NULL);
+        if (rc < 0) {
+            return -1;
+        } else if (rc > 0) {
+            rc = 0;
             break;
         }
+
+        if (len != sizeof(dep)) {
+            rc = BOOT_EBADIMAGE;
+            goto done;
+        }
+
+        rc = flash_area_read(fap, off, &dep, len);
+        if (rc != 0) {
+            rc = BOOT_EFLASH;
+            goto done;
+        }
+
+        if (dep.image_id >= BOOT_IMAGE_NUMBER) {
+            rc = BOOT_EBADARGS;
+            goto done;
+        }
+
+        /* Verify dependency and modify the swap type if not satisfied. */
+        rc = boot_verify_slot_dependency(state, &dep);
+        if (rc != 0) {
+            /* Dependency not satisfied. */
+            goto done;
+        }
     }
 
 done: