Skip to content

Commit

Permalink
Merge pull request wolfSSL#463 from jpbland1/bad-image-recovery
Browse files Browse the repository at this point in the history
add emergency fallback test, currently fails due to
  • Loading branch information
dgarske authored Jul 10, 2024
2 parents eedd86f + 6c3940f commit b9dc7ee
Show file tree
Hide file tree
Showing 10 changed files with 362 additions and 151 deletions.
70 changes: 68 additions & 2 deletions .github/workflows/test-powerfail-simulator.yml
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,14 @@ jobs:
run: |
tools/scripts/sim-update-powerfail-resume.sh
- name: Rebuild wolfboot.elf
run: |
make clean && make test-sim-internal-flash-with-update
- name: Run emergency fallback test
run: |
tools/scripts/sim-update-emergency-fallback.sh
# TEST with NVM_WRITEONCE enabled
- name: make clean
Expand Down Expand Up @@ -89,6 +97,14 @@ jobs:
run: |
tools/scripts/sim-update-powerfail-resume.sh
- name: Rebuild wolfboot.elf
run: |
make clean && make test-sim-internal-flash-with-update
- name: Run emergency fallback test
run: |
tools/scripts/sim-update-emergency-fallback.sh
# TEST with NVM_WRITEONCE AND FLAGS_HOME enabled
- name: make clean
Expand Down Expand Up @@ -127,6 +143,14 @@ jobs:
run: |
tools/scripts/sim-update-powerfail-resume.sh
- name: Rebuild wolfboot.elf
run: |
make clean && make test-sim-internal-flash-with-update
- name: Run emergency fallback test
run: |
tools/scripts/sim-update-emergency-fallback.sh
# TEST with NVM_WRITEONCE AND FLAGS_HOME AND FLAGS_INVERT enabled
- name: make clean
Expand Down Expand Up @@ -165,6 +189,14 @@ jobs:
run: |
tools/scripts/sim-update-powerfail-resume.sh
- name: Rebuild wolfboot.elf
run: |
make clean && make test-sim-external-flash-with-update
- name: Run emergency fallback test
run: |
tools/scripts/sim-update-emergency-fallback.sh
# TEST with DELTA updates
- name: make clean
Expand All @@ -189,15 +221,15 @@ jobs:
- name: Rebuild wolfboot.elf
run: |
make test-sim-internal-flash-with-delta-update
make clean && make test-sim-internal-flash-with-delta-update
- name: Run update-revert test (DELTA)
run: |
tools/scripts/sim-update-fallback.sh
- name: Rebuild wolfboot.elf
run: |
make test-sim-internal-flash-with-delta-update
make clean && make test-sim-internal-flash-with-delta-update
- name: Run update-revert test with power failures (DELTA)
run: |
Expand Down Expand Up @@ -248,6 +280,14 @@ jobs:
run: |
tools/scripts/sim-update-powerfail-resume.sh
- name: Rebuild wolfboot.elf
run: |
make clean && make test-sim-external-flash-with-enc-update
- name: Run emergency fallback test
run: |
tools/scripts/sim-update-emergency-fallback.sh
# TEST with encryption (aes128) and delta updates
- name: make clean
run: |
Expand Down Expand Up @@ -322,6 +362,14 @@ jobs:
run: |
tools/scripts/sim-update-powerfail-resume.sh
- name: Rebuild wolfboot.elf
run: |
make clean && make test-sim-external-flash-with-enc-update
- name: Run emergency fallback test
run: |
tools/scripts/sim-update-emergency-fallback.sh
# TEST with encryption (aes128) and NVM_WRITEONCE and FLAGS_HOME

- name: make clean
Expand Down Expand Up @@ -355,6 +403,14 @@ jobs:
run: |
tools/scripts/sim-update-powerfail-resume.sh
- name: Rebuild wolfboot.elf
run: |
make clean && make test-sim-external-flash-with-enc-update
- name: Run emergency fallback test
run: |
tools/scripts/sim-update-emergency-fallback.sh
# TEST with encryption (aes128) and NVM_WRITEONCE and FLAGS_HOME and FLAGS_INVERT

- name: make clean
Expand Down Expand Up @@ -388,6 +444,14 @@ jobs:
run: |
tools/scripts/sim-update-powerfail-resume.sh
- name: Rebuild wolfboot.elf
run: |
make clean && make test-sim-external-flash-with-enc-update
- name: Run emergency fallback test
run: |
tools/scripts/sim-update-emergency-fallback.sh
# TEST with encryption (aes128) and NVM_WRITEONCE and DELTA updates
- name: make clean
run: |
Expand Down Expand Up @@ -451,6 +515,7 @@ jobs:
- name: Run update test with DISABLE_BACKUP and powefail
run: |
tools/scripts/sim-update-powerfail-resume-nobackup.sh
# TEST with backup disabled + NVM_WRITEONCE
- name: make clean
run: |
Expand Down Expand Up @@ -478,6 +543,7 @@ jobs:
- name: Run update test with DISABLE_BACKUP and powefail
run: |
tools/scripts/sim-update-powerfail-resume-nobackup.sh
# TEST with backup disabled + FLAGS_HOME
- name: make clean
run: |
Expand Down
31 changes: 28 additions & 3 deletions hal/sim.c
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
uint8_t *sim_ram_base;
static uint8_t *flash_base;

int forceEmergency = 0;
uint32_t erasefail_address = 0xFFFFFFFF;

#define INTERNAL_FLASH_FILE "./internal_flash.dd"
Expand Down Expand Up @@ -105,8 +106,29 @@ void hal_prepare_boot(void)

int hal_flash_write(uintptr_t address, const uint8_t *data, int len)
{
/* implicit cast abide compiler warning */
memcpy((void*)address, data, len);
int i;
if (forceEmergency == 1 && address == WOLFBOOT_PARTITION_BOOT_ADDRESS) {
/* implicit cast abide compiler warning */
memset((void*)address, 0, len);
/* let the rest of the writes work properly for the emergency update */
forceEmergency = 0;
}
else {
for (i = 0; i < len; i++) {
#ifdef NVM_FLASH_WRITEONCE
if (((uint8_t*)address)[i] != FLASH_BYTE_ERASED) {
/* no writing to non-erased page in NVM_FLASH_WRITEONCE */
printf("NVM_FLASH_WRITEONCE non-erased write detected!\n");
return -1;
}
#endif
#ifdef WOLFBOOT_FLAGS_INVERT
((uint8_t*)address)[i] |= data[i];
#else
((uint8_t*)address)[i] &= data[i];
#endif
}
}
return 0;
}

Expand Down Expand Up @@ -150,8 +172,11 @@ void hal_init(void)
erasefail_address = strtol(main_argv[++i], NULL, 16);
fprintf(stderr, "Set power fail to erase at address %x\n",
erasefail_address);
break;
}
/* force a bad write of the boot partition to trigger and test the
* emergency fallback feature */
else if (strcmp(main_argv[i], "emergency") == 0)
forceEmergency = 1;
}
}

Expand Down
6 changes: 4 additions & 2 deletions include/wolfboot/wolfboot.h
Original file line number Diff line number Diff line change
Expand Up @@ -257,16 +257,18 @@ extern "C" {
#ifndef WOLFBOOT_FLAGS_INVERT
#define IMG_STATE_NEW 0xFF
#define IMG_STATE_UPDATING 0x70
#define IMG_STATE_FINAL_FLAGS 0x30
/* now just an intermediary state, update state will always be either new or
* updating before the application boots*/
#define IMG_STATE_FINAL_FLAGS 0x30
#define IMG_STATE_TESTING 0x10
#define IMG_STATE_SUCCESS 0x00
#define FLASH_BYTE_ERASED 0xFF
#define FLASH_WORD_ERASED 0xFFFFFFFFUL
#else
#define IMG_STATE_NEW 0x00
#define IMG_STATE_UPDATING 0x8F
#define IMG_STATE_FINAL_FLAGS 0xBF
#define IMG_STATE_TESTING 0xEF
#define IMG_STATE_FINAL_FLAGS 0xBF
#define IMG_STATE_SUCCESS 0xFF
#define FLASH_BYTE_ERASED 0x00
#define FLASH_WORD_ERASED 0x00000000UL
Expand Down
30 changes: 3 additions & 27 deletions src/image.c
Original file line number Diff line number Diff line change
Expand Up @@ -611,8 +611,6 @@ static int image_sha256(struct wolfBoot_image *img, uint8_t *hash)
*/
static void key_sha256(uint8_t key_slot, uint8_t *hash)
{
int blksz;
unsigned int i = 0;
uint8_t *pubkey = keystore_get_buffer(key_slot);
int pubkey_sz = keystore_get_size(key_slot);
wc_Sha256 sha256_ctx;
Expand All @@ -621,13 +619,7 @@ static void key_sha256(uint8_t key_slot, uint8_t *hash)
return;

wc_InitSha256(&sha256_ctx);
while (i < (uint32_t)pubkey_sz) {
blksz = WOLFBOOT_SHA_BLOCK_SIZE;
if ((i + blksz) > (uint32_t)pubkey_sz)
blksz = pubkey_sz - i;
wc_Sha256Update(&sha256_ctx, (pubkey + i), blksz);
i += blksz;
}
wc_Sha256Update(&sha256_ctx, pubkey, (word32)pubkey_sz);
wc_Sha256Final(&sha256_ctx, hash);
}
#endif /* WOLFBOOT_NO_SIGN */
Expand Down Expand Up @@ -700,8 +692,6 @@ static int image_sha384(struct wolfBoot_image *img, uint8_t *hash)
*/
static void key_sha384(uint8_t key_slot, uint8_t *hash)
{
int blksz;
unsigned int i = 0;
uint8_t *pubkey = keystore_get_buffer(key_slot);
int pubkey_sz = keystore_get_size(key_slot);
wc_Sha384 sha384_ctx;
Expand All @@ -710,13 +700,7 @@ static void key_sha384(uint8_t key_slot, uint8_t *hash)
return;

wc_InitSha384(&sha384_ctx);
while (i < (uint32_t)(pubkey_sz)) {
blksz = WOLFBOOT_SHA_BLOCK_SIZE;
if ((i + blksz) > (uint32_t)pubkey_sz)
blksz = pubkey_sz - i;
wc_Sha384Update(&sha384_ctx, (pubkey + i), blksz);
i += blksz;
}
wc_Sha384Update(&sha384_ctx, pubkey, (word32)pubkey_sz);
wc_Sha384Final(&sha384_ctx, hash);
}
#endif /* WOLFBOOT_NO_SIGN */
Expand Down Expand Up @@ -789,22 +773,14 @@ static int image_sha3_384(struct wolfBoot_image *img, uint8_t *hash)
*/
static void key_sha3_384(uint8_t key_slot, uint8_t *hash)
{
int blksz;
unsigned int i = 0;
uint8_t *pubkey = keystore_get_buffer(key_slot);
int pubkey_sz = keystore_get_size(key_slot);
wc_Sha3 sha3_ctx;

if (!pubkey || (pubkey_sz < 0))
return;
wc_InitSha3_384(&sha3_ctx, NULL, INVALID_DEVID);
while (i < (uint32_t)pubkey_sz) {
blksz = WOLFBOOT_SHA_BLOCK_SIZE;
if ((i + blksz) > (uint32_t)pubkey_sz)
blksz = pubkey_sz - i;
wc_Sha3_384_Update(&sha3_ctx, pubkey + i, blksz);
i += blksz;
}
wc_Sha3_384_Update(&sha3_ctx, pubkey, (word32)pubkey_sz);
wc_Sha3_384_Final(&sha3_ctx, hash);
}
#endif /* WOLFBOOT_NO_SIGN */
Expand Down
50 changes: 20 additions & 30 deletions src/libwolfboot.c
Original file line number Diff line number Diff line change
Expand Up @@ -350,12 +350,8 @@ static int RAMFUNCTION trailer_write(uint8_t part, uintptr_t addr, uint8_t val)
/* Calculate write address */
addr_write = addr_align - ((!nvm_cached_sector) * NVM_CACHE_SIZE);

/* Ensure that the destination was erased, or force erase */
if (*((uint32_t *)(addr_write + NVM_CACHE_SIZE - sizeof(uint32_t)))
!= FLASH_WORD_ERASED)
{
hal_flash_erase(addr_write, NVM_CACHE_SIZE);
}
/* Ensure that the destination was erased */
hal_flash_erase(addr_write, NVM_CACHE_SIZE);
#if FLASHBUFFER_SIZE != WOLFBOOT_SECTOR_SIZE
addr_off = 0;
while ((addr_off < WOLFBOOT_SECTOR_SIZE) && (ret == 0)) {
Expand Down Expand Up @@ -718,17 +714,21 @@ void RAMFUNCTION wolfBoot_erase_partition(uint8_t part)
uint32_t address = 0;
int size = 0;

if (part == PART_BOOT) {
address = (uint32_t)WOLFBOOT_PARTITION_BOOT_ADDRESS;
size = WOLFBOOT_PARTITION_SIZE;
}
if (part == PART_UPDATE) {
address = (uint32_t)WOLFBOOT_PARTITION_UPDATE_ADDRESS;
size = WOLFBOOT_PARTITION_SIZE;
}
if (part == PART_SWAP) {
address = (uint32_t)WOLFBOOT_PARTITION_SWAP_ADDRESS;
size = WOLFBOOT_SECTOR_SIZE;
switch (part) {
case PART_BOOT:
address = (uint32_t)WOLFBOOT_PARTITION_BOOT_ADDRESS;
size = WOLFBOOT_PARTITION_SIZE;
break;
case PART_UPDATE:
address = (uint32_t)WOLFBOOT_PARTITION_UPDATE_ADDRESS;
size = WOLFBOOT_PARTITION_SIZE;
break;
case PART_SWAP:
address = (uint32_t)WOLFBOOT_PARTITION_SWAP_ADDRESS;
size = WOLFBOOT_SECTOR_SIZE;
break;
default:
break;
}

if (size > 0) {
Expand Down Expand Up @@ -819,16 +819,10 @@ void RAMFUNCTION wolfBoot_success(void)
if (FLAGS_BOOT_EXT()) {
ext_flash_unlock();
wolfBoot_set_partition_state(PART_BOOT, st);
/* set update so IMG_STATE_FINAL_FLAGS isn't triggering pointless calls
* to wolfBoot update */
wolfBoot_set_partition_state(PART_UPDATE, st);
ext_flash_lock();
} else {
hal_flash_unlock();
wolfBoot_set_partition_state(PART_BOOT, st);
/* set update so IMG_STATE_FINAL_FLAGS isn't triggering pointless calls
* to wolfBoot update */
wolfBoot_set_partition_state(PART_UPDATE, st);
hal_flash_lock();
}
#ifdef EXT_ENCRYPTED
Expand Down Expand Up @@ -866,13 +860,9 @@ uint16_t wolfBoot_find_header(uint8_t *haystack, uint16_t type, uint8_t **ptr)
unit_dbg("Explicit end of options reached\n");
break;
}
if (*p == HDR_PADDING) {
/* Padding byte (skip one position) */
p++;
continue;
}
/* Sanity check to prevent dereferencing unaligned half-words */
if ((((size_t)p) & 0x01) != 0) {
/* Sanity check to prevent dereferencing unaligned half-words and skip
* past padding bytes */
if ((*p == HDR_PADDING) || ((((size_t)p) & 0x01) != 0)) {
p++;
continue;
}
Expand Down
Loading

0 comments on commit b9dc7ee

Please sign in to comment.