add option for rollback protection
Depends on 'MCUBOOT_OVERWRITE_ONLY' option since swap info is not protected by signature Signed-off-by: Håkon Øye Amundsen <haakon.amundsen@nordicsemi.no>
This commit is contained in:
parent
e2acfaede5
commit
2d1bac164f
|
@ -510,6 +510,42 @@ boot_check_header_erased(struct boot_loader_state *state, int slot)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if (BOOT_IMAGE_NUMBER > 1) || \
|
||||||
|
(defined(MCUBOOT_OVERWRITE_ONLY) && defined(MCUBOOT_DOWNGRADE_PREVENTION))
|
||||||
|
/**
|
||||||
|
* Check if the version of the image is not older than required.
|
||||||
|
*
|
||||||
|
* @param req Required minimal image version.
|
||||||
|
* @param ver Version of the image to be checked.
|
||||||
|
*
|
||||||
|
* @return 0 if the version is sufficient, nonzero otherwise.
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
boot_is_version_sufficient(struct image_version *req,
|
||||||
|
struct image_version *ver)
|
||||||
|
{
|
||||||
|
if (ver->iv_major > req->iv_major) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (ver->iv_major < req->iv_major) {
|
||||||
|
return BOOT_EBADVERSION;
|
||||||
|
}
|
||||||
|
/* The major version numbers are equal. */
|
||||||
|
if (ver->iv_minor > req->iv_minor) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (ver->iv_minor < req->iv_minor) {
|
||||||
|
return BOOT_EBADVERSION;
|
||||||
|
}
|
||||||
|
/* The minor version numbers are equal. */
|
||||||
|
if (ver->iv_revision < req->iv_revision) {
|
||||||
|
return BOOT_EBADVERSION;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Check that there is a valid image in a slot
|
* Check that there is a valid image in a slot
|
||||||
*
|
*
|
||||||
|
@ -541,6 +577,24 @@ boot_validate_slot(struct boot_loader_state *state, int slot,
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(MCUBOOT_OVERWRITE_ONLY) && defined(MCUBOOT_DOWNGRADE_PREVENTION)
|
||||||
|
if (slot != BOOT_PRIMARY_SLOT) {
|
||||||
|
/* Check if version of secondary slot is sufficient */
|
||||||
|
rc = boot_is_version_sufficient(
|
||||||
|
&boot_img_hdr(state, BOOT_PRIMARY_SLOT)->ih_ver,
|
||||||
|
&boot_img_hdr(state, BOOT_SECONDARY_SLOT)->ih_ver);
|
||||||
|
if (rc != 0 && boot_check_header_erased(state, BOOT_PRIMARY_SLOT)) {
|
||||||
|
BOOT_LOG_ERR("insufficient version in secondary slot");
|
||||||
|
flash_area_erase(fap, 0, fap->fa_size);
|
||||||
|
/* Image in the secondary slot does not satisfy version requirement.
|
||||||
|
* Erase the image and continue booting from the primary slot.
|
||||||
|
*/
|
||||||
|
rc = 1;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
if (!boot_is_header_valid(hdr, fap) || boot_image_check(state, hdr, fap, bs)) {
|
if (!boot_is_header_valid(hdr, fap) || boot_image_check(state, hdr, fap, bs)) {
|
||||||
if (slot != BOOT_PRIMARY_SLOT) {
|
if (slot != BOOT_PRIMARY_SLOT) {
|
||||||
flash_area_erase(fap, 0, fap->fa_size);
|
flash_area_erase(fap, 0, fap->fa_size);
|
||||||
|
@ -552,7 +606,7 @@ boot_validate_slot(struct boot_loader_state *state, int slot,
|
||||||
BOOT_LOG_ERR("Image in the %s slot is not valid!",
|
BOOT_LOG_ERR("Image in the %s slot is not valid!",
|
||||||
(slot == BOOT_PRIMARY_SLOT) ? "primary" : "secondary");
|
(slot == BOOT_PRIMARY_SLOT) ? "primary" : "secondary");
|
||||||
#endif
|
#endif
|
||||||
rc = -1;
|
rc = 1;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -966,39 +1020,6 @@ boot_swap_image(struct boot_loader_state *state, struct boot_status *bs)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if (BOOT_IMAGE_NUMBER > 1)
|
#if (BOOT_IMAGE_NUMBER > 1)
|
||||||
/**
|
|
||||||
* Check if the version of the image is not older than required.
|
|
||||||
*
|
|
||||||
* @param req Required minimal image version.
|
|
||||||
* @param ver Version of the image to be checked.
|
|
||||||
*
|
|
||||||
* @return 0 if the version is sufficient, nonzero otherwise.
|
|
||||||
*/
|
|
||||||
static int
|
|
||||||
boot_is_version_sufficient(struct image_version *req,
|
|
||||||
struct image_version *ver)
|
|
||||||
{
|
|
||||||
if (ver->iv_major > req->iv_major) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
if (ver->iv_major < req->iv_major) {
|
|
||||||
return BOOT_EBADVERSION;
|
|
||||||
}
|
|
||||||
/* The major version numbers are equal. */
|
|
||||||
if (ver->iv_minor > req->iv_minor) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
if (ver->iv_minor < req->iv_minor) {
|
|
||||||
return BOOT_EBADVERSION;
|
|
||||||
}
|
|
||||||
/* The minor version numbers are equal. */
|
|
||||||
if (ver->iv_revision < req->iv_revision) {
|
|
||||||
return BOOT_EBADVERSION;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check the image dependency whether it is satisfied and modify
|
* Check the image dependency whether it is satisfied and modify
|
||||||
* the swap type if necessary.
|
* the swap type if necessary.
|
||||||
|
|
|
@ -346,4 +346,14 @@ config UPDATEABLE_IMAGE_NUMBER
|
||||||
help
|
help
|
||||||
Enables support of multi image update.
|
Enables support of multi image update.
|
||||||
|
|
||||||
|
config MCUBOOT_DOWNGRADE_PREVENTION
|
||||||
|
bool "Downgrade prevention"
|
||||||
|
depends on BOOT_UPGRADE_ONLY
|
||||||
|
help
|
||||||
|
Prevent downgrades by enforcing incrementing version numbers.
|
||||||
|
When this option is set, any upgrade must have greater major version
|
||||||
|
or greater minor version with equal major version. This mechanism
|
||||||
|
only protects against some attacks against version downgrades (for
|
||||||
|
example, a JTAG could be used to write an older version).
|
||||||
|
|
||||||
source "$ZEPHYR_BASE/Kconfig.zephyr"
|
source "$ZEPHYR_BASE/Kconfig.zephyr"
|
||||||
|
|
|
@ -89,6 +89,10 @@
|
||||||
#define MCUBOOT_IMAGE_NUMBER 1
|
#define MCUBOOT_IMAGE_NUMBER 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef CONFIG_MCUBOOT_DOWNGRADE_PREVENTION
|
||||||
|
#define MCUBOOT_DOWNGRADE_PREVENTION 1
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Enabling this option uses newer flash map APIs. This saves RAM and
|
* Enabling this option uses newer flash map APIs. This saves RAM and
|
||||||
* avoids deprecated API usage.
|
* avoids deprecated API usage.
|
||||||
|
|
|
@ -942,3 +942,11 @@ state after dependency check.
|
||||||
|
|
||||||
For more information on adding dependency entries to an image,
|
For more information on adding dependency entries to an image,
|
||||||
see: [imgtool](imgtool.md).
|
see: [imgtool](imgtool.md).
|
||||||
|
|
||||||
|
## [Downgrade Prevention](#downgrade-prevention)
|
||||||
|
|
||||||
|
Downgrade prevention is a feature which enforces that the new image must have a
|
||||||
|
higher version number than the image it is replacing. This feature is enabled
|
||||||
|
with the `MCUBOOT_DOWNGRADE_PREVENTION` option. Downgrade prevention is only
|
||||||
|
available when the overwrite-based image update strategy is used
|
||||||
|
(i.e. `MCUBOOT_OVERWRITE_ONLY` is set).
|
||||||
|
|
Loading…
Reference in New Issue