mirror of https://github.com/wolfSSL/wolfBoot.git
parent
91e0b16788
commit
1359aac80d
|
|
@ -1395,6 +1395,15 @@ int wolfBoot_dualboot_candidate(void)
|
|||
(wolfBoot_get_partition_state(candidate, &p_state) == 0) &&
|
||||
(p_state == IMG_STATE_TESTING))
|
||||
{
|
||||
#ifndef ALLOW_DOWNGRADE
|
||||
uint32_t candidate_v = (candidate == PART_BOOT) ? boot_v : update_v;
|
||||
uint32_t fallback_v = (candidate == PART_BOOT) ? update_v : boot_v;
|
||||
|
||||
if (fallback_v < candidate_v) {
|
||||
wolfBoot_printf("Rollback to lower version not allowed\n");
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
wolfBoot_erase_partition(candidate);
|
||||
candidate ^= 1; /* switch to other partition if available */
|
||||
}
|
||||
|
|
|
|||
|
|
@ -259,6 +259,7 @@ void RAMFUNCTION wolfBoot_start(void)
|
|||
uint32_t *load_address;
|
||||
int failures = 0;
|
||||
uint32_t load_off;
|
||||
uint32_t max_ver;
|
||||
const uint8_t *hdr_ptr = NULL;
|
||||
#ifdef MMU
|
||||
uint8_t *dts_addr = NULL;
|
||||
|
|
@ -346,6 +347,7 @@ void RAMFUNCTION wolfBoot_start(void)
|
|||
}
|
||||
|
||||
wolfBoot_printf("Versions, A:%u B:%u\r\n", pA_ver, pB_ver);
|
||||
max_ver = (pB_ver > pA_ver) ? (uint32_t)pB_ver : (uint32_t)pA_ver;
|
||||
|
||||
/* Choose partition with higher version */
|
||||
selected = (pB_ver > pA_ver) ? 1: 0;
|
||||
|
|
@ -368,6 +370,15 @@ void RAMFUNCTION wolfBoot_start(void)
|
|||
cur_part = BOOT_PART_B;
|
||||
else
|
||||
cur_part = BOOT_PART_A;
|
||||
#ifndef ALLOW_DOWNGRADE
|
||||
{
|
||||
uint32_t cur_ver = selected ? (uint32_t)pB_ver : (uint32_t)pA_ver;
|
||||
if ((max_ver > 0U) && (cur_ver < max_ver)) {
|
||||
wolfBoot_printf("Rollback to lower version not allowed\r\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
part_name[2] = 'A' + selected;
|
||||
|
||||
|
|
|
|||
|
|
@ -45,12 +45,24 @@ void RAMFUNCTION wolfBoot_start(void)
|
|||
int active;
|
||||
struct wolfBoot_image fw_image;
|
||||
uint8_t p_state;
|
||||
#ifndef ALLOW_DOWNGRADE
|
||||
uint32_t boot_v = wolfBoot_current_firmware_version();
|
||||
uint32_t update_v = wolfBoot_update_firmware_version();
|
||||
uint32_t max_v = (boot_v > update_v) ? boot_v : update_v;
|
||||
#endif
|
||||
active = wolfBoot_dualboot_candidate();
|
||||
|
||||
if (active < 0) /* panic if no images available */
|
||||
boot_panic();
|
||||
|
||||
for (;;) {
|
||||
#ifndef ALLOW_DOWNGRADE
|
||||
uint32_t active_v = (active == PART_UPDATE) ? update_v : boot_v;
|
||||
if ((max_v > 0U) && (active_v < max_v)) {
|
||||
wolfBoot_printf("Rollback to lower version not allowed\n");
|
||||
boot_panic();
|
||||
}
|
||||
#endif
|
||||
if ((wolfBoot_open_image(&fw_image, active) < 0)
|
||||
#ifndef WOLFBOOT_SKIP_BOOT_VERIFY
|
||||
|| (wolfBoot_verify_integrity(&fw_image) < 0)
|
||||
|
|
|
|||
|
|
@ -138,6 +138,11 @@ void RAMFUNCTION wolfBoot_start(void)
|
|||
uint8_t *dts_addr = NULL;
|
||||
uint32_t dts_size = 0;
|
||||
#endif
|
||||
#ifndef ALLOW_DOWNGRADE
|
||||
uint32_t boot_v = wolfBoot_current_firmware_version();
|
||||
uint32_t update_v = wolfBoot_update_firmware_version();
|
||||
uint32_t max_v = (boot_v > update_v) ? boot_v : update_v;
|
||||
#endif
|
||||
|
||||
memset(&os_image, 0, sizeof(struct wolfBoot_image));
|
||||
|
||||
|
|
@ -162,6 +167,16 @@ void RAMFUNCTION wolfBoot_start(void)
|
|||
wolfBoot_panic();
|
||||
break;
|
||||
}
|
||||
#ifndef ALLOW_DOWNGRADE
|
||||
{
|
||||
uint32_t active_v = (active == PART_UPDATE) ? update_v : boot_v;
|
||||
if ((max_v > 0U) && (active_v < max_v)) {
|
||||
wolfBoot_printf("Rollback to lower version not allowed\n");
|
||||
wolfBoot_panic();
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(WOLFBOOT_DUALBOOT) && defined(WOLFBOOT_FIXED_PARTITIONS)
|
||||
wolfBoot_printf("Trying %s partition at %p\n",
|
||||
|
|
|
|||
|
|
@ -33,6 +33,7 @@ static int mock_disk_init_ret;
|
|||
static int mock_disk_close_called;
|
||||
static int mock_do_boot_called;
|
||||
static const uint32_t *mock_boot_address;
|
||||
static int mock_fail_payload_part;
|
||||
|
||||
ChaCha chacha;
|
||||
|
||||
|
|
@ -72,6 +73,7 @@ static void reset_mocks(void)
|
|||
mock_disk_close_called = 0;
|
||||
mock_do_boot_called = 0;
|
||||
mock_boot_address = NULL;
|
||||
mock_fail_payload_part = -1;
|
||||
wolfBoot_panicked = 0;
|
||||
}
|
||||
|
||||
|
|
@ -140,6 +142,8 @@ int disk_part_read(int drv, int part, uint64_t off, uint64_t sz, uint8_t *buf)
|
|||
|
||||
(void)drv;
|
||||
image = (part == BOOT_PART_B) ? part_b_image : part_a_image;
|
||||
if ((mock_fail_payload_part == part) && (off >= IMAGE_HEADER_SIZE))
|
||||
return -1;
|
||||
if ((off > max) || (sz > (max - off)))
|
||||
return -1;
|
||||
memcpy(buf, image + off, (size_t)sz);
|
||||
|
|
@ -288,6 +292,19 @@ START_TEST(test_get_decrypted_blob_version_rejects_truncated_version_tlv)
|
|||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(test_update_disk_rejects_rollback_after_higher_image_failure)
|
||||
{
|
||||
reset_mocks();
|
||||
build_image(part_a_image, 7, 0xA1);
|
||||
build_image(part_b_image, 5, 0xB2);
|
||||
mock_fail_payload_part = BOOT_PART_A;
|
||||
|
||||
wolfBoot_start();
|
||||
|
||||
ck_assert_int_eq(wolfBoot_panicked, 1);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
Suite *wolfboot_suite(void)
|
||||
{
|
||||
Suite *s = suite_create("wolfBoot");
|
||||
|
|
@ -297,6 +314,7 @@ Suite *wolfboot_suite(void)
|
|||
tcase_add_test(tc, test_update_disk_zeroizes_key_material_before_boot);
|
||||
tcase_add_test(tc, test_update_disk_prefers_primary_partition_when_versions_equal);
|
||||
tcase_add_test(tc, test_get_decrypted_blob_version_rejects_truncated_version_tlv);
|
||||
tcase_add_test(tc, test_update_disk_rejects_rollback_after_higher_image_failure);
|
||||
suite_add_tcase(s, tc);
|
||||
|
||||
return s;
|
||||
|
|
|
|||
|
|
@ -191,7 +191,7 @@ static int add_payload(uint8_t part, uint32_t version, uint32_t size)
|
|||
return 0;
|
||||
}
|
||||
|
||||
START_TEST(test_invalid_update_falls_back_to_boot_without_reselect_loop)
|
||||
START_TEST(test_invalid_update_rollback_to_older_boot_is_denied)
|
||||
{
|
||||
uint8_t bad_digest[SHA256_DIGEST_SIZE];
|
||||
|
||||
|
|
@ -208,8 +208,8 @@ START_TEST(test_invalid_update_falls_back_to_boot_without_reselect_loop)
|
|||
|
||||
wolfBoot_start();
|
||||
|
||||
ck_assert_int_eq(wolfBoot_staged_ok, 1);
|
||||
ck_assert_ptr_eq(wolfBoot_stage_address, (const uint32_t *)WOLFBOOT_LOAD_ADDRESS);
|
||||
ck_assert_int_eq(wolfBoot_staged_ok, 0);
|
||||
ck_assert_int_eq(wolfBoot_panicked, 1);
|
||||
cleanup_flash();
|
||||
}
|
||||
END_TEST
|
||||
|
|
@ -219,7 +219,7 @@ static Suite *wolfboot_suite(void)
|
|||
Suite *s = suite_create("wolfboot-update-ram-nofixed");
|
||||
TCase *tc = tcase_create("fallback");
|
||||
|
||||
tcase_add_test(tc, test_invalid_update_falls_back_to_boot_without_reselect_loop);
|
||||
tcase_add_test(tc, test_invalid_update_rollback_to_older_boot_is_denied);
|
||||
tcase_set_timeout(tc, 5);
|
||||
suite_add_tcase(s, tc);
|
||||
|
||||
|
|
|
|||
|
|
@ -378,8 +378,8 @@ START_TEST (test_invalid_update_type) {
|
|||
ext_flash_lock();
|
||||
wolfBoot_update_trigger();
|
||||
wolfBoot_start();
|
||||
ck_assert(wolfBoot_staged_ok);
|
||||
ck_assert(get_version_ramloaded() == 1);
|
||||
ck_assert(!wolfBoot_staged_ok);
|
||||
ck_assert_int_eq(wolfBoot_panicked, 1);
|
||||
cleanup_flash();
|
||||
}
|
||||
|
||||
|
|
@ -396,8 +396,8 @@ START_TEST (test_update_toolarge) {
|
|||
|
||||
wolfBoot_update_trigger();
|
||||
wolfBoot_start();
|
||||
ck_assert(wolfBoot_staged_ok);
|
||||
ck_assert(get_version_ramloaded() == 1);
|
||||
ck_assert(!wolfBoot_staged_ok);
|
||||
ck_assert_int_eq(wolfBoot_panicked, 1);
|
||||
cleanup_flash();
|
||||
}
|
||||
|
||||
|
|
@ -414,12 +414,12 @@ START_TEST (test_invalid_sha) {
|
|||
ext_flash_lock();
|
||||
wolfBoot_update_trigger();
|
||||
wolfBoot_start();
|
||||
ck_assert(wolfBoot_staged_ok);
|
||||
ck_assert(get_version_ramloaded() == 1);
|
||||
ck_assert(!wolfBoot_staged_ok);
|
||||
ck_assert_int_eq(wolfBoot_panicked, 1);
|
||||
cleanup_flash();
|
||||
}
|
||||
|
||||
START_TEST (test_emergency_rollback) {
|
||||
START_TEST (test_emergency_rollback_to_older_version_denied) {
|
||||
uint8_t testing_flags[5] = { IMG_STATE_TESTING, 'B', 'O', 'O', 'T' };
|
||||
reset_mock_stats();
|
||||
prepare_flash();
|
||||
|
|
@ -432,8 +432,8 @@ START_TEST (test_emergency_rollback) {
|
|||
ext_flash_lock();
|
||||
|
||||
wolfBoot_start();
|
||||
ck_assert(wolfBoot_staged_ok);
|
||||
ck_assert(get_version_ramloaded() == 1);
|
||||
ck_assert(!wolfBoot_staged_ok);
|
||||
ck_assert_int_eq(wolfBoot_panicked, 1);
|
||||
cleanup_flash();
|
||||
}
|
||||
|
||||
|
|
@ -532,7 +532,7 @@ Suite *wolfboot_suite(void)
|
|||
tcase_add_test(invalid_update_type, test_invalid_update_type);
|
||||
tcase_add_test(update_toolarge, test_update_toolarge);
|
||||
tcase_add_test(invalid_sha, test_invalid_sha);
|
||||
tcase_add_test(emergency_rollback, test_emergency_rollback);
|
||||
tcase_add_test(emergency_rollback, test_emergency_rollback_to_older_version_denied);
|
||||
tcase_add_test(emergency_rollback_failure_due_to_bad_update, test_emergency_rollback_failure_due_to_bad_update);
|
||||
tcase_add_test(empty_boot_partition_update, test_empty_boot_partition_update);
|
||||
tcase_add_test(empty_boot_but_update_sha_corrupted_denied, test_empty_boot_but_update_sha_corrupted_denied);
|
||||
|
|
|
|||
Loading…
Reference in New Issue