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:
Håkon Øye Amundsen 2020-01-03 13:08:09 +00:00 committed by David Brown
parent e2acfaede5
commit 2d1bac164f
4 changed files with 77 additions and 34 deletions

View File

@ -510,6 +510,42 @@ boot_check_header_erased(struct boot_loader_state *state, int slot)
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
*
@ -541,6 +577,24 @@ boot_validate_slot(struct boot_loader_state *state, int slot,
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 (slot != BOOT_PRIMARY_SLOT) {
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!",
(slot == BOOT_PRIMARY_SLOT) ? "primary" : "secondary");
#endif
rc = -1;
rc = 1;
goto out;
}
@ -966,39 +1020,6 @@ boot_swap_image(struct boot_loader_state *state, struct boot_status *bs)
#endif
#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
* the swap type if necessary.

View File

@ -346,4 +346,14 @@ config UPDATEABLE_IMAGE_NUMBER
help
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"

View File

@ -89,6 +89,10 @@
#define MCUBOOT_IMAGE_NUMBER 1
#endif
#ifdef CONFIG_MCUBOOT_DOWNGRADE_PREVENTION
#define MCUBOOT_DOWNGRADE_PREVENTION 1
#endif
/*
* Enabling this option uses newer flash map APIs. This saves RAM and
* avoids deprecated API usage.

View File

@ -942,3 +942,11 @@ state after dependency check.
For more information on adding dependency entries to an image,
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).