Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

properly unlock flash on re-entry of wolfBoot_swap_and_final_erase #526

Merged
merged 8 commits into from
Dec 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 30 additions & 4 deletions hal/sim.c
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,8 @@ static uint8_t *flash_base;

int forceEmergency = 0;
uint32_t erasefail_address = 0xFFFFFFFF;
int flashLocked = 1;
int extFlashLocked = 1;

#define INTERNAL_FLASH_FILE "./internal_flash.dd"
#define EXTERNAL_FLASH_FILE "./external_flash.dd"
Expand Down Expand Up @@ -134,12 +136,12 @@ static int mmap_file(const char *path, uint8_t *address, uint8_t** ret_address)

void hal_flash_unlock(void)
{
/* no op */
flashLocked = 0;
}

void hal_flash_lock(void)
{
/* no op */
flashLocked = 1;
}

void hal_prepare_boot(void)
Expand All @@ -150,6 +152,10 @@ void hal_prepare_boot(void)
int hal_flash_write(uintptr_t address, const uint8_t *data, int len)
{
int i;
if (flashLocked == 1) {
wolfBoot_printf("FLASH IS BEING WRITTEN TO WHILE LOCKED\n");
return -1;
}
if (forceEmergency == 1 && address == WOLFBOOT_PARTITION_BOOT_ADDRESS) {
/* implicit cast abide compiler warning */
memset((void*)address, 0, len);
Expand Down Expand Up @@ -179,6 +185,10 @@ int hal_flash_write(uintptr_t address, const uint8_t *data, int len)

int hal_flash_erase(uintptr_t address, int len)
{
if (flashLocked == 1) {
wolfBoot_printf("FLASH IS BEING ERASED WHILE LOCKED\n");
return -1;
}
/* implicit cast abide compiler warning */
wolfBoot_printf( "hal_flash_erase addr %p len %d\n", (void*)address, len);
if (address == erasefail_address + WOLFBOOT_PARTITION_BOOT_ADDRESS) {
Expand Down Expand Up @@ -227,16 +237,20 @@ void hal_init(void)

void ext_flash_lock(void)
{
/* no op */
extFlashLocked = 1;
}

void ext_flash_unlock(void)
{
/* no op */
extFlashLocked = 0;
}

int ext_flash_write(uintptr_t address, const uint8_t *data, int len)
{
if (extFlashLocked == 1) {
wolfBoot_printf("EXT FLASH IS BEING WRITTEN TO WHILE LOCKED\n");
return -1;
}
memcpy(flash_base + address, data, len);
return 0;
}
Expand All @@ -249,6 +263,10 @@ int ext_flash_read(uintptr_t address, uint8_t *data, int len)

int ext_flash_erase(uintptr_t address, int len)
{
if (extFlashLocked == 1) {
wolfBoot_printf("EXT FLASH IS BEING ERASED WHILE LOCKED\n");
return -1;
}
memset(flash_base + address, FLASH_BYTE_ERASED, len);
return 0;
}
Expand Down Expand Up @@ -287,6 +305,14 @@ void do_boot(const uint32_t *app_offset)
int ret;
size_t app_size = WOLFBOOT_PARTITION_SIZE - IMAGE_HEADER_SIZE;

if (flashLocked == 0) {
wolfBoot_printf("WARNING FLASH IS UNLOCKED AT BOOT");
}

if (extFlashLocked == 0) {
wolfBoot_printf("WARNING EXT FLASH IS UNLOCKED AT BOOT");
}

#ifdef __APPLE__
typedef int (*main_entry)(int, char**, char**, char**);
NSObjectFileImage fileImage = NULL;
Expand Down
2 changes: 1 addition & 1 deletion src/libwolfboot.c
Original file line number Diff line number Diff line change
Expand Up @@ -268,7 +268,7 @@ static int RAMFUNCTION nvm_select_fresh_sector(int part)
}
}
finish:
/* Erase the non-selected partition */
/* Erase the non-selected partition, requires unlocked flash */
addrErase -= WOLFBOOT_SECTOR_SIZE * (!sel);
if (*((uint32_t*)(addrErase + WOLFBOOT_SECTOR_SIZE - sizeof(uint32_t)))
!= FLASH_WORD_ERASED) {
Expand Down
74 changes: 57 additions & 17 deletions src/update_flash.c
Original file line number Diff line number Diff line change
Expand Up @@ -245,31 +245,39 @@ static int wolfBoot_swap_and_final_erase(int resume)
if ((resume == 1) && (swapDone == 0) && (st != IMG_STATE_FINAL_FLAGS)) {
return -1;
}
if (swapDone == 0) {
/* IMG_STATE_FINAL_FLAGS allows re-entry without blowing away swap */
if (st != IMG_STATE_FINAL_FLAGS) {
/* store the sector at tmpBootPos into swap */
wolfBoot_copy_sector(boot, swap, tmpBootPos / WOLFBOOT_SECTOR_SIZE);
/* set FINAL_SWAP for re-entry */
wolfBoot_set_partition_state(PART_UPDATE, IMG_STATE_FINAL_FLAGS);
}

hal_flash_unlock();
#ifdef EXT_FLASH
ext_flash_unlock();
#endif

/* IMG_STATE_FINAL_FLAGS allows re-entry without blowing away swap */
if (st != IMG_STATE_FINAL_FLAGS) {
/* store the sector at tmpBootPos into swap */
wolfBoot_copy_sector(boot, swap, tmpBootPos / WOLFBOOT_SECTOR_SIZE);
/* set FINAL_SWAP for re-entry */
wolfBoot_set_partition_state(PART_UPDATE, IMG_STATE_FINAL_FLAGS);
}
#ifdef EXT_ENCRYPTED
if (swapDone == 0) {
/* get encryption key and iv if encryption is enabled */
wolfBoot_get_encrypt_key((uint8_t*)tmpBuffer,
(uint8_t*)&tmpBuffer[ENCRYPT_KEY_SIZE/sizeof(uint32_t)]);
#endif
/* write TRAIL, encryption key and iv if enabled to tmpBootPos*/
tmpBuffer[TRAILER_OFFSET_WORDS] = WOLFBOOT_MAGIC_TRAIL;

wb_flash_erase(boot, tmpBootPos, WOLFBOOT_SECTOR_SIZE);
wb_flash_write(boot, tmpBootPos, (void*)tmpBuffer, sizeof(tmpBuffer));
}
#endif
/* erase the last boot sector(s) */
wb_flash_erase(boot, WOLFBOOT_PARTITION_SIZE - eraseLen, eraseLen);
/* set the encryption key */
#ifdef EXT_ENCRYPTED
wolfBoot_set_encrypt_key((uint8_t*)tmpBuffer,
(uint8_t*)&tmpBuffer[ENCRYPT_KEY_SIZE/sizeof(uint32_t)]);
/* wolfBoot_set_encrypt_key calls hal_flash_unlock, need to unlock again */
hal_flash_unlock();
#endif
/* write the original contents of tmpBootPos back */
if (tmpBootPos < boot->fw_size + IMAGE_HEADER_SIZE) {
Expand All @@ -282,6 +290,12 @@ static int wolfBoot_swap_and_final_erase(int resume)
wolfBoot_set_partition_state(PART_BOOT, IMG_STATE_TESTING);
/* erase the last sector(s) of update */
wb_flash_erase(update, WOLFBOOT_PARTITION_SIZE - eraseLen, eraseLen);

#ifdef EXT_FLASH
ext_flash_lock();
#endif
hal_flash_lock();

return 0;
}
#endif
Expand Down Expand Up @@ -479,16 +493,18 @@ static int wolfBoot_delta_update(struct wolfBoot_image *boot,
wb_flash_erase(boot, sector * WOLFBOOT_SECTOR_SIZE, WOLFBOOT_SECTOR_SIZE);
sector++;
}
#ifndef DISABLE_BACKUP
/* start re-entrant final erase, return code is only for resumption in
* wolfBoot_start */
wolfBoot_swap_and_final_erase(0);
#endif
out:
#ifdef EXT_FLASH
ext_flash_lock();
#endif
hal_flash_lock();
/* start re-entrant final erase, return code is only for resumption in
* wolfBoot_start */
#ifndef DISABLE_BACKUP
if (ret == 0) {
wolfBoot_swap_and_final_erase(0);
}
#endif
/* encryption key was not erased, will be erased by success */
return ret;
}
Expand Down Expand Up @@ -634,7 +650,15 @@ static int RAMFUNCTION wolfBoot_update(int fallback_allowed)
* we need to set to UPDATING, otherwise there's no way to tell the
* original direction of the update once interrupted */
else if ((inverse == 0) && (fallback_allowed == 1)) {
hal_flash_unlock();
#ifdef EXT_FLASH
ext_flash_unlock();
#endif
wolfBoot_set_partition_state(PART_UPDATE, IMG_STATE_UPDATING);
#ifdef EXT_FLASH
ext_flash_lock();
#endif
hal_flash_lock();
}

return wolfBoot_delta_update(&boot, &update, &swap, inverse, resume);
Expand Down Expand Up @@ -741,14 +765,14 @@ static int RAMFUNCTION wolfBoot_update(int fallback_allowed)
}
#endif /* WOLFBOOT_FLASH_MULTI_SECTOR_ERASE */

/* start re-entrant final erase, return code is only for resumption in
* wolfBoot_start*/
wolfBoot_swap_and_final_erase(0);
/* encryption key was not erased, will be erased by success */
#ifdef EXT_FLASH
ext_flash_lock();
#endif
hal_flash_lock();
/* start re-entrant final erase, return code is only for resumption in
* wolfBoot_start*/
wolfBoot_swap_and_final_erase(0);

#else /* DISABLE_BACKUP */
/* Direct Swap without power fail safety */
Expand Down Expand Up @@ -922,9 +946,25 @@ void RAMFUNCTION wolfBoot_start(void)
wolfBoot_check_self_update();
#endif

#ifdef NVM_FLASH_WRITEONCE
/* nvm_select_fresh_sector needs unlocked flash in cases where the unused
* sector needs to be erased */
hal_flash_unlock();
#ifdef EXT_FLASH
ext_flash_unlock();
#endif
#endif

bootRet = wolfBoot_get_partition_state(PART_BOOT, &bootState);
updateRet = wolfBoot_get_partition_state(PART_UPDATE, &updateState);

#ifdef NVM_FLASH_WRITEONCE
hal_flash_lock();
#ifdef EXT_FLASH
ext_flash_lock();
#endif
#endif

#if !defined(DISABLE_BACKUP)
/* resume the final erase in case the power failed before it finished */
resumedFinalErase = wolfBoot_swap_and_final_erase(1);
Expand Down
32 changes: 16 additions & 16 deletions tools/test.mk
Original file line number Diff line number Diff line change
Expand Up @@ -986,40 +986,40 @@ test-all: clean


test-size-all:
make test-size SIGN=NONE LIMIT=4840 NO_ARM_ASM=1
make test-size SIGN=NONE LIMIT=4860 NO_ARM_ASM=1
make keysclean
make test-size SIGN=ED25519 LIMIT=11428 NO_ARM_ASM=1
make test-size SIGN=ED25519 LIMIT=11448 NO_ARM_ASM=1
make keysclean
make test-size SIGN=ECC256 LIMIT=17948 NO_ARM_ASM=1
make test-size SIGN=ECC256 LIMIT=17968 NO_ARM_ASM=1
make clean
make test-size SIGN=ECC256 NO_ASM=1 LIMIT=13492 NO_ARM_ASM=1
make test-size SIGN=ECC256 NO_ASM=1 LIMIT=13512 NO_ARM_ASM=1
make keysclean
make test-size SIGN=RSA2048 LIMIT=11212 NO_ARM_ASM=1
make test-size SIGN=RSA2048 LIMIT=11232 NO_ARM_ASM=1
make clean
make test-size SIGN=RSA2048 NO_ASM=1 LIMIT=11788 NO_ARM_ASM=1
make test-size SIGN=RSA2048 NO_ASM=1 LIMIT=11808 NO_ARM_ASM=1
make keysclean
make test-size SIGN=RSA4096 LIMIT=11500 NO_ARM_ASM=1
make test-size SIGN=RSA4096 LIMIT=11520 NO_ARM_ASM=1
make clean
make test-size SIGN=RSA4096 NO_ASM=1 LIMIT=12076 NO_ARM_ASM=1
make test-size SIGN=RSA4096 NO_ASM=1 LIMIT=12096 NO_ARM_ASM=1
make keysclean
make test-size SIGN=ECC384 LIMIT=17516 NO_ARM_ASM=1
make test-size SIGN=ECC384 LIMIT=17536 NO_ARM_ASM=1
make clean
make test-size SIGN=ECC384 NO_ASM=1 LIMIT=14884 NO_ARM_ASM=1
make test-size SIGN=ECC384 NO_ASM=1 LIMIT=14904 NO_ARM_ASM=1
make keysclean
make test-size SIGN=ED448 LIMIT=13440 NO_ARM_ASM=1
make test-size SIGN=ED448 LIMIT=13464 NO_ARM_ASM=1
make keysclean
make test-size SIGN=RSA3072 LIMIT=11352 NO_ARM_ASM=1
make test-size SIGN=RSA3072 LIMIT=11372 NO_ARM_ASM=1
make clean
make test-size SIGN=RSA3072 NO_ASM=1 LIMIT=11892 NO_ARM_ASM=1
make test-size SIGN=RSA3072 NO_ASM=1 LIMIT=11912 NO_ARM_ASM=1
make keysclean
make test-size SIGN=LMS LMS_LEVELS=2 LMS_HEIGHT=5 LMS_WINTERNITZ=8 \
WOLFBOOT_SMALL_STACK=0 IMAGE_SIGNATURE_SIZE=2644 \
IMAGE_HEADER_SIZE?=5288 LIMIT=7516 NO_ARM_ASM=1
IMAGE_HEADER_SIZE?=5288 LIMIT=7536 NO_ARM_ASM=1
make keysclean
make test-size SIGN=XMSS XMSS_PARAMS='XMSS-SHA2_10_256' \
IMAGE_SIGNATURE_SIZE=2500 IMAGE_HEADER_SIZE?=4096 \
LIMIT=8232 NO_ARM_ASM=1
LIMIT=8252 NO_ARM_ASM=1
make keysclean
make clean
make test-size SIGN=ML_DSA ML_DSA_LEVEL=2 LIMIT=20148 \
make test-size SIGN=ML_DSA ML_DSA_LEVEL=2 LIMIT=20168 \
IMAGE_SIGNATURE_SIZE=2420 IMAGE_HEADER_SIZE?=8192
Loading