boot: bootutil: drop flash_area_read_is_empty

Removes the current `flash_area_read_is_empty` which lacked a bit of
clarity in its naming and error handling, as well as requiring an
extra API in the flash map, and switches to using an internal function
`bootutil_buffer_is_erased`.

Code that was previously using `flash_area_read_is_empty` must now be
updated to do a `flash_area_read` followed by a call to
`bootutil_buffer_is_erased` with the read buffer.

The proposal was previously discussed here:

https://github.com/zephyrproject-rtos/zephyr/pull/28519

Signed-off-by: Fabio Utzig <fabio.utzig@nordicsemi.no>
diff --git a/boot/bootutil/src/bootutil_misc.c b/boot/bootutil/src/bootutil_misc.c
index a8b6b47..57ceff4 100644
--- a/boot/bootutil/src/bootutil_misc.c
+++ b/boot/bootutil/src/bootutil_misc.c
@@ -291,6 +291,27 @@
 }
 #endif
 
+bool bootutil_buffer_is_erased(const struct flash_area *area,
+                               const void *buffer, size_t len)
+{
+    size_t i;
+    uint8_t *u8b;
+    uint8_t erased_val;
+
+    if (buffer == NULL || len == 0) {
+        return false;
+    }
+
+    erased_val = flash_area_erased_val(area);
+    for (i = 0, u8b = (uint8_t *)buffer; i < len; i++) {
+        if (u8b[i] != erased_val) {
+            return false;
+        }
+    }
+
+    return true;
+}
+
 int
 boot_read_swap_state(const struct flash_area *fap,
                      struct boot_swap_state *state)
@@ -301,18 +322,18 @@
     int rc;
 
     off = boot_magic_off(fap);
-    rc = flash_area_read_is_empty(fap, off, magic, BOOT_MAGIC_SZ);
+    rc = flash_area_read(fap, off, magic, BOOT_MAGIC_SZ);
     if (rc < 0) {
         return BOOT_EFLASH;
     }
-    if (rc == 1) {
+    if (bootutil_buffer_is_erased(fap, magic, BOOT_MAGIC_SZ)) {
         state->magic = BOOT_MAGIC_UNSET;
     } else {
         state->magic = boot_magic_decode(magic);
     }
 
     off = boot_swap_info_off(fap);
-    rc = flash_area_read_is_empty(fap, off, &swap_info, sizeof swap_info);
+    rc = flash_area_read(fap, off, &swap_info, sizeof swap_info);
     if (rc < 0) {
         return BOOT_EFLASH;
     }
@@ -321,30 +342,31 @@
     state->swap_type = BOOT_GET_SWAP_TYPE(swap_info);
     state->image_num = BOOT_GET_IMAGE_NUM(swap_info);
 
-    if (rc == 1 || state->swap_type > BOOT_SWAP_TYPE_REVERT) {
+    if (bootutil_buffer_is_erased(fap, &swap_info, sizeof swap_info) ||
+            state->swap_type > BOOT_SWAP_TYPE_REVERT) {
         state->swap_type = BOOT_SWAP_TYPE_NONE;
         state->image_num = 0;
     }
 
     off = boot_copy_done_off(fap);
-    rc = flash_area_read_is_empty(fap, off, &state->copy_done,
-            sizeof state->copy_done);
+    rc = flash_area_read(fap, off, &state->copy_done, sizeof state->copy_done);
     if (rc < 0) {
         return BOOT_EFLASH;
     }
-    if (rc == 1) {
+    if (bootutil_buffer_is_erased(fap, &state->copy_done,
+                sizeof state->copy_done)) {
         state->copy_done = BOOT_FLAG_UNSET;
     } else {
         state->copy_done = boot_flag_decode(state->copy_done);
     }
 
     off = boot_image_ok_off(fap);
-    rc = flash_area_read_is_empty(fap, off, &state->image_ok,
-                                  sizeof state->image_ok);
+    rc = flash_area_read(fap, off, &state->image_ok, sizeof state->image_ok);
     if (rc < 0) {
         return BOOT_EFLASH;
     }
-    if (rc == 1) {
+    if (bootutil_buffer_is_erased(fap, &state->image_ok,
+                sizeof state->image_ok)) {
         state->image_ok = BOOT_FLAG_UNSET;
     } else {
         state->image_ok = boot_flag_decode(state->image_ok);
diff --git a/boot/bootutil/src/bootutil_priv.h b/boot/bootutil/src/bootutil_priv.h
index be9de71..16ec64e 100644
--- a/boot/bootutil/src/bootutil_priv.h
+++ b/boot/bootutil/src/bootutil_priv.h
@@ -326,6 +326,16 @@
 #endif
 
 /**
+ * Checks that a buffer is erased according to what the erase value for the
+ * flash device provided in `flash_area` is.
+ *
+ * @returns true if the buffer is erased; false if any of the bytes is not
+ * erased, or when buffer is NULL, or when len == 0.
+ */
+bool bootutil_buffer_is_erased(const struct flash_area *area,
+                               const void *buffer, size_t len);
+
+/**
  * Safe (non-overflowing) uint32_t addition.  Returns true, and stores
  * the result in *dest if it can be done without overflow.  Otherwise,
  * returns false.
diff --git a/boot/bootutil/src/swap_misc.c b/boot/bootutil/src/swap_misc.c
index 995becf..940d646 100644
--- a/boot/bootutil/src/swap_misc.c
+++ b/boot/bootutil/src/swap_misc.c
@@ -164,8 +164,12 @@
     rc = swap_read_status_bytes(fap, state, bs);
     if (rc == 0) {
         off = boot_swap_info_off(fap);
-        rc = flash_area_read_is_empty(fap, off, &swap_info, sizeof swap_info);
-        if (rc == 1) {
+        rc = flash_area_read(fap, off, &swap_info, sizeof swap_info);
+        if (rc != 0) {
+            return BOOT_EFLASH;
+        }
+
+        if (bootutil_buffer_is_erased(fap, &swap_info, sizeof swap_info)) {
             BOOT_SET_SWAP_INFO(swap_info, 0, BOOT_SWAP_TYPE_NONE);
             rc = 0;
         }
diff --git a/boot/bootutil/src/swap_move.c b/boot/bootutil/src/swap_move.c
index 7332414..8c59843 100644
--- a/boot/bootutil/src/swap_move.c
+++ b/boot/bootutil/src/swap_move.c
@@ -142,12 +142,12 @@
     write_sz = BOOT_WRITE_SZ(state);
     off = boot_status_off(fap);
     for (i = max_entries; i > 0; i--) {
-        rc = flash_area_read_is_empty(fap, off + (i - 1) * write_sz, &status, 1);
+        rc = flash_area_read(fap, off + (i - 1) * write_sz, &status, 1);
         if (rc < 0) {
             return BOOT_EFLASH;
         }
 
-        if (rc == 1) {
+        if (bootutil_buffer_is_erased(fap, &status, 1)) {
             if (rc != last_rc) {
                 erased_sections++;
             }
diff --git a/boot/bootutil/src/swap_scratch.c b/boot/bootutil/src/swap_scratch.c
index 99c57f0..55fa61f 100644
--- a/boot/bootutil/src/swap_scratch.c
+++ b/boot/bootutil/src/swap_scratch.c
@@ -110,13 +110,13 @@
     found_idx = 0;
     invalid = 0;
     for (i = 0; i < max_entries; i++) {
-        rc = flash_area_read_is_empty(fap, off + i * BOOT_WRITE_SZ(state),
+        rc = flash_area_read(fap, off + i * BOOT_WRITE_SZ(state),
                 &status, 1);
         if (rc < 0) {
             return BOOT_EFLASH;
         }
 
-        if (rc == 1) {
+        if (bootutil_buffer_is_erased(fap, &status, 1)) {
             if (found && !found_idx) {
                 found_idx = i;
             }
diff --git a/boot/zephyr/include/flash_map_backend/flash_map_backend.h b/boot/zephyr/include/flash_map_backend/flash_map_backend.h
index 8b5fd0c..08deca5 100644
--- a/boot/zephyr/include/flash_map_backend/flash_map_backend.h
+++ b/boot/zephyr/include/flash_map_backend/flash_map_backend.h
@@ -82,14 +82,6 @@
  */
 uint8_t flash_area_erased_val(const struct flash_area *fap);
 
-/*
- * Reads len bytes from off, and checks if the read data is erased.
- *
- * Returns 1 if erased, 0 if non-erased, and -1 on failure.
- */
-int flash_area_read_is_empty(const struct flash_area *fa, uint32_t off,
-        void *dst, uint32_t len);
-
 #ifdef __cplusplus
 }
 #endif