diff --git a/boot/bootutil/include/bootutil/security_cnt.h b/boot/bootutil/include/bootutil/security_cnt.h index 7e1389618..ff3a7371c 100644 --- a/boot/bootutil/include/bootutil/security_cnt.h +++ b/boot/bootutil/include/bootutil/security_cnt.h @@ -72,6 +72,19 @@ fih_ret boot_nv_security_counter_get(uint32_t image_id, fih_int *security_cnt); int32_t boot_nv_security_counter_update(uint32_t image_id, uint32_t img_security_cnt); +/** + * This function verifies whether the security counter update to a given value is possible. + * The update might not be possible if the maximum amount of security counter updates + * was reached. + * + * @param image_id Index of the image (from 0). + * @param img_security_cnt New security counter value. + * + * @return FIH_SUCCESS if update is possible; FIH_FAILURE otherwise + */ +fih_ret boot_nv_security_counter_is_update_possible(uint32_t image_id, + uint32_t img_security_cnt); + #ifdef __cplusplus } #endif diff --git a/boot/bootutil/src/image_validate.c b/boot/bootutil/src/image_validate.c index 522e5da2d..ba31ddbf3 100644 --- a/boot/bootutil/src/image_validate.c +++ b/boot/bootutil/src/image_validate.c @@ -839,6 +839,19 @@ bootutil_img_validate(struct boot_loader_state *state, goto out; } +#ifdef MCUBOOT_HW_ROLLBACK_PROT_COUNTER_LIMITED + if (img_security_cnt > (uint32_t)fih_int_decode(security_cnt)) { + FIH_CALL(boot_nv_security_counter_is_update_possible, fih_rc, image_index, + img_security_cnt); + if (FIH_NOT_EQ(fih_rc, FIH_SUCCESS)) { + FIH_SET(fih_rc, FIH_FAILURE); + BOOT_LOG_ERR("Security counter update is not possible, possibly the maximum " + "number of security updates has been reached."); + goto out; + } + } +#endif + /* The image's security counter has been successfully verified. */ security_counter_valid = fih_rc; skip_security_counter_read: diff --git a/boot/zephyr/Kconfig b/boot/zephyr/Kconfig index cdb4d29cc..f1707759e 100644 --- a/boot/zephyr/Kconfig +++ b/boot/zephyr/Kconfig @@ -1076,6 +1076,18 @@ config MCUBOOT_HW_DOWNGRADE_PREVENTION Because of the acceptance of equal values it allows for software downgrade to some extent. +config MCUBOOT_HW_DOWNGRADE_PREVENTION_COUNTER_LIMITED + bool "HW based downgrade prevention counter has limited number of updates" + depends on MCUBOOT_HW_DOWNGRADE_PREVENTION + default y if SOC_NRF5340_CPUAPP || SOC_SERIES_NRF91X || SOC_SERIES_NRF54LX + help + When this option is set, the hardware downgrade prevention counter + has limited number of updates. This option will enable checking + if it is possible to update the counter before performing + the upgrade. If an update package contains a security counter + value as a TLV but it is not possible to update the counter, + the update will be rejected. + endchoice config BOOT_WATCHDOG_FEED diff --git a/boot/zephyr/include/mcuboot_config/mcuboot_config.h b/boot/zephyr/include/mcuboot_config/mcuboot_config.h index 8ba030738..0c02f62bc 100644 --- a/boot/zephyr/include/mcuboot_config/mcuboot_config.h +++ b/boot/zephyr/include/mcuboot_config/mcuboot_config.h @@ -209,6 +209,10 @@ #define MCUBOOT_HW_ROLLBACK_PROT #endif +#ifdef CONFIG_MCUBOOT_HW_DOWNGRADE_PREVENTION_COUNTER_LIMITED +#define MCUBOOT_HW_ROLLBACK_PROT_COUNTER_LIMITED +#endif + #ifdef CONFIG_MEASURED_BOOT #define MCUBOOT_MEASURED_BOOT #endif