boot: bootutil: Only update the security counter for confirmed images
When an upgrade is performed, the security counter must only be updated
after the upgrade has been confirmed, to make possible to rollback if
needed. To that end, the security counter was only updated for a given
image if the swap type is BOOT_SWAP_TYPE_NONE, meaning in most cases
that no update has been performed by MCUboot at this run.
However, the swap type is also set to BOOT_SWAP_TYPE_NONE after an
interrupted upgrade is completed, so at the time
boot_update_hw_rollback_protection is called, having a "none" swap type
doesn't guarantee that no upgrade is waiting for confirmation. This
means MCUboot was wrongly updating the security counter immediately
after the completion of a resumed upgrade, preventing any rollback in
that case.
Instead, the boot_update_hw_rollback_protection now checks the trailer
of the primary image to determine if the security counter has to be
updated. The update occurs only if the trailer is empty (no update has
ever been made) or if the "image-ok" flag is set (the image has been
confirmed).
Signed-off-by: Thomas Altenbach <thomas.altenbach@legrand.com>
diff --git a/boot/bootutil/src/loader.c b/boot/bootutil/src/loader.c
index f47ec4e..ffd2456 100644
--- a/boot/bootutil/src/loader.c
+++ b/boot/bootutil/src/loader.c
@@ -2246,18 +2246,26 @@
{
#ifdef MCUBOOT_HW_ROLLBACK_PROT
int rc;
+ uint8_t image_index;
+ struct boot_swap_state swap_state;
+
+ image_index = BOOT_CURR_IMG(state);
+
+ rc = boot_read_swap_state_by_id(FLASH_AREA_IMAGE_PRIMARY(image_index), &swap_state);
+ if (rc != 0) {
+ return rc;
+ }
/* Update the stored security counter with the active image's security
- * counter value. It will only be updated if the new security counter is
- * greater than the stored value.
- *
- * In case of a successful image swapping when the swap type is TEST the
- * security counter can be increased only after a reset, when the swap
- * type is NONE and the image has marked itself "OK" (the image_ok flag
- * has been set). This way a "revert" can be performed when it's
- * necessary.
- */
- if (BOOT_SWAP_TYPE(state) == BOOT_SWAP_TYPE_NONE) {
+ * counter value. It will only be updated if the new security counter is
+ * greater than the stored value.
+ *
+ * In case of a successful image swapping when the swap type is TEST the
+ * security counter can be increased only after a reset, when the image has
+ * marked itself "OK" (the image_ok flag has been set). This way a "revert"
+ * can be performed when it's necessary.
+ */
+ if (swap_state.magic != BOOT_MAGIC_GOOD || swap_state.image_ok == BOOT_FLAG_SET) {
rc = boot_update_security_counter(state, BOOT_PRIMARY_SLOT, BOOT_PRIMARY_SLOT);
if (rc != 0) {
BOOT_LOG_ERR("Security counter update failed after image "