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

add combinations of NVM_FLASH_WRITEONCE config tests #343

Merged
merged 6 commits into from
Aug 17, 2023
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
83 changes: 74 additions & 9 deletions .github/workflows/test-powerfail-simulator.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,29 +33,28 @@ jobs:

- name: Build wolfboot.elf
run: |
make && make test-sim-internal-flash-with-update
make clean && make test-sim-internal-flash-with-update

- name: Run sunny day update test
run: |
tools/scripts/sim-sunnyday-update.sh

- name: Rebuild wolfboot.elf
run: |
make test-sim-internal-flash-with-update
make clean && make test-sim-internal-flash-with-update

- name: Run update-revert test
run: |
tools/scripts/sim-update-fallback.sh

- name: Rebuild wolfboot.elf
run: |
make test-sim-internal-flash-with-update
make clean && make test-sim-internal-flash-with-update

- name: Run update-revert test with power failures
run: |
tools/scripts/sim-update-powerfail-resume.sh


# TEST with NVM_WRITEONCE enabled

- name: make clean
Expand All @@ -76,28 +75,94 @@ jobs:

- name: Build wolfboot.elf
run: |
make && make test-sim-internal-flash-with-update
make clean && make test-sim-internal-flash-with-update

- name: Run sunny day update test (NVM_WRITEONCE)
run: |
tools/scripts/sim-sunnyday-update.sh

- name: Rebuild wolfboot.elf
run: |
make test-sim-internal-flash-with-update
make clean && make test-sim-internal-flash-with-update

- name: Run update-revert test (NVM_WRITEONCE)
run: |
tools/scripts/sim-update-fallback.sh

- name: Rebuild wolfboot.elf
run: |
make test-sim-internal-flash-with-update
make clean && make test-sim-internal-flash-with-update

- name: Run update-revert test with power failures (NVM_WRITEONCE)
run: |
tools/scripts/sim-update-powerfail-resume.sh

# TEST with NVM_WRITEONCE AND FLAGS_HOME enabled

- name: make clean
run: |
make keysclean && make -C tools/keytools clean && rm -f include/target.h
- name: Select config with NVM_WRITEONCE and FLAGS_HOME
run: |
cp config/examples/sim-nvm-writeonce-flags-home.config .config
- name: Build key tools
run: |
make -C tools/keytools
- name: Build bin assemble
run: |
make -C tools/bin-assemble
- name: Build wolfboot.elf
run: |
make clean && make test-sim-internal-flash-with-update
- name: Run sunny day update test (NVM_WRITEONCE FLAGS_HOME)
run: |
tools/scripts/sim-sunnyday-update.sh
- name: Rebuild wolfboot.elf
run: |
make clean && make test-sim-internal-flash-with-update
- name: Run update-revert test (NVM_WRITEONCE FLAGS_HOME)
run: |
tools/scripts/sim-update-fallback.sh
- name: Rebuild wolfboot.elf
run: |
make clean && make test-sim-internal-flash-with-update
- name: Run update-revert test with power failures (NVM_WRITEONCE FLAGS_HOME)
run: |
tools/scripts/sim-update-powerfail-resume.sh

# TEST with NVM_WRITEONCE AND FLAGS_HOME AND FLAGS_INVERT enabled

- name: make clean
run: |
make keysclean && make -C tools/keytools clean && rm -f include/target.h
- name: Select config with NVM_WRITEONCE and FLAGS_HOME and FLAGS_INVERT
run: |
cp config/examples/sim-nvm-writeonce-flags-home-invert.config .config
- name: Build key tools
run: |
make -C tools/keytools
- name: Build bin assemble
run: |
make -C tools/bin-assemble
- name: Build wolfboot.elf
run: |
make clean && make test-sim-external-flash-with-update
- name: Run sunny day update test (NVM_WRITEONCE FLAGS_HOME FLAGS_INVERT)
run: |
tools/scripts/sim-sunnyday-update.sh
- name: Rebuild wolfboot.elf
run: |
make clean && make test-sim-external-flash-with-update
- name: Run update-revert test (NVM_WRITEONCE FLAGS_HOME)
run: |
tools/scripts/sim-update-fallback.sh
- name: Rebuild wolfboot.elf
run: |
make clean && make test-sim-external-flash-with-update
- name: Run update-revert test with power failures (NVM_WRITEONCE FLAGS_HOME FLAGS_INVERT)
run: |
tools/scripts/sim-update-powerfail-resume.sh

# TEST with DELTA updates

- name: make clean
Expand Down Expand Up @@ -161,7 +226,7 @@ jobs:

- name: Build wolfboot.elf
run: |
make test-sim-external-flash-with-enc-update
make clean && make test-sim-external-flash-with-enc-update

- name: Run sunny day update test (AES128)
run: |
Expand Down Expand Up @@ -203,7 +268,7 @@ jobs:

- name: Build wolfboot.elf
run: |
make test-sim-external-flash-with-enc-delta-update
make clean && make test-sim-external-flash-with-enc-delta-update

- name: Run sunny day update test (AES128 DELTA)
run: |
Expand Down
22 changes: 22 additions & 0 deletions config/examples/sim-nvm-writeonce-flags-home-invert.config
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
ARCH=sim
TARGET=sim
SIGN?=ED25519
HASH?=SHA256
WOLFBOOT_SMALL_STACK=1
SPI_FLASH=0
EXT_FLASH=1
DEBUG=1
# it should be multiple of system page size
NVM_FLASH_WRITEONCE=1
FLAGS_HOME=1
ALLOW_DOWNGRADE?=0
FLAGS_INVERT?=1
FILL_BYTE?=0x00
WOLFBOOT_PARTITION_SIZE=0x40000
WOLFBOOT_SECTOR_SIZE=0x1000
WOLFBOOT_PARTITION_BOOT_ADDRESS=0x20000
# if on external flash, it should be multiple of system page size
WOLFBOOT_PARTITION_UPDATE_ADDRESS=0x00000
WOLFBOOT_PARTITION_SWAP_ADDRESS=0x40000
# required for keytools
WOLFBOOT_FIXED_PARTITIONS=1
18 changes: 18 additions & 0 deletions config/examples/sim-nvm-writeonce-flags-home.config
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
ARCH=sim
TARGET=sim
SIGN?=ED25519
HASH?=SHA256
WOLFBOOT_SMALL_STACK=1
SPI_FLASH=0
DEBUG=1
# it should be multiple of system page size
NVM_FLASH_WRITEONCE=1
FLAGS_HOME=1
WOLFBOOT_PARTITION_SIZE=0x40000
WOLFBOOT_SECTOR_SIZE=0x1000
WOLFBOOT_PARTITION_BOOT_ADDRESS=0x20000
# if on external flash, it should be multiple of system page size
WOLFBOOT_PARTITION_UPDATE_ADDRESS=0x60000
WOLFBOOT_PARTITION_SWAP_ADDRESS=0xA0000
# required for keytools
WOLFBOOT_FIXED_PARTITIONS=1
4 changes: 2 additions & 2 deletions hal/sim.c
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ int hal_flash_erase(uintptr_t address, int len)
memset((void*)address, 0xEE, len);
exit(0);
}
memset((void*)address, 0xff, len);
memset((void*)address, FLASH_BYTE_ERASED, len);
return 0;
}

Expand Down Expand Up @@ -179,7 +179,7 @@ int ext_flash_read(uintptr_t address, uint8_t *data, int len)

int ext_flash_erase(uintptr_t address, int len)
{
memset(flash_base + address, 0xff, len);
memset(flash_base + address, FLASH_BYTE_ERASED, len);
return 0;
}

Expand Down
60 changes: 46 additions & 14 deletions src/libwolfboot.c
Original file line number Diff line number Diff line change
Expand Up @@ -57,10 +57,15 @@ static uint8_t encrypt_iv_nonce[ENCRYPT_NONCE_SIZE];
(TRAILER_SKIP + ENCRYPT_KEY_SIZE + ENCRYPT_NONCE_SIZE))
#define TRAILER_OVERHEAD (4 + 1 + (WOLFBOOT_PARTITION_SIZE / \
(2 * WOLFBOOT_SECTOR_SIZE)))
/* MAGIC + PART_FLAG (1B) + (N_SECTORS / 2) */
/* MAGIC (4B) + PART_FLAG (1B) + (N_SECTORS / 2) */
#define START_FLAGS_OFFSET (ENCRYPT_TMP_SECRET_OFFSET - TRAILER_OVERHEAD)
#define SECTOR_FLAGS_SIZE WOLFBOOT_SECTOR_SIZE - (4 + 1 + \
ENCRYPT_KEY_SIZE + ENCRYPT_NONCE_SIZE)
/* MAGIC (4B) + PART_FLAG (1B) + ENCRYPT_KEY_SIZE + ENCRYPT_NONCE_SIZE */
#else
#define ENCRYPT_TMP_SECRET_OFFSET (WOLFBOOT_PARTITION_SIZE - (TRAILER_SKIP))
#define SECTOR_FLAGS_SIZE WOLFBOOT_SECTOR_SIZE - (4 + 1)
/* MAGIC (4B) + PART_FLAG (1B) */
#endif /* EXT_FLASH && EXT_ENCRYPTED */

#if !defined(__WOLFBOOT) && !defined(UNIT_TEST)
Expand Down Expand Up @@ -138,7 +143,7 @@ static const uint32_t wolfboot_magic_trail = WOLFBOOT_MAGIC_TRAIL;
*
*/

#ifndef FLAGS_INVERT
#ifndef WOLFBOOT_FLAGS_INVERT
#define FLAG_CMP(a,b) ((a < b)? 0 : 1)
#else
#define FLAG_CMP(a,b) ((a > b)? 0 : 1)
Expand Down Expand Up @@ -522,25 +527,52 @@ void RAMFUNCTION wolfBoot_erase_partition(uint8_t part)
void RAMFUNCTION wolfBoot_update_trigger(void)
{
uint8_t st = IMG_STATE_UPDATING;

#ifdef FLAGS_HOME
/* Erase last sector of boot partition prior to
* setting the partition state.
*/
uint32_t last_sector = PART_UPDATE_ENDFLAGS -
#if defined(NVM_FLASH_WRITEONCE) || defined(WOLFBOOT_FLAGS_INVERT)
uintptr_t lastSector = PART_UPDATE_ENDFLAGS -
(PART_UPDATE_ENDFLAGS % WOLFBOOT_SECTOR_SIZE);
hal_flash_unlock();
hal_flash_erase(last_sector, WOLFBOOT_SECTOR_SIZE);
hal_flash_lock();
#endif
#ifdef NVM_FLASH_WRITEONCE
uint8_t selSec = 0;
#endif

/* erase the sector flags */
if (FLAGS_UPDATE_EXT()) {
ext_flash_unlock();
wolfBoot_set_partition_state(PART_UPDATE, st);
ext_flash_lock();
} else {
hal_flash_unlock();
wolfBoot_set_partition_state(PART_UPDATE, st);
}

/* NVM_FLASH_WRITEONCE needs erased flags since it selects the fresh
* partition based on how many flags are non-erased
* FLAGS_INVERT needs erased flags because the bin-assemble's fill byte may
* not match what's in wolfBoot */
#if defined(NVM_FLASH_WRITEONCE) || defined(WOLFBOOT_FLAGS_INVERT)
if (FLAGS_UPDATE_EXT()) {
ext_flash_erase(lastSector, SECTOR_FLAGS_SIZE);
} else {
#ifdef NVM_FLASH_WRITEONCE
selSec = nvm_select_fresh_sector(PART_UPDATE);
XMEMCPY(NVM_CACHE,
(uint8_t*)(lastSector - WOLFBOOT_SECTOR_SIZE * selSec),
WOLFBOOT_SECTOR_SIZE);
XMEMSET(NVM_CACHE, FLASH_BYTE_ERASED, SECTOR_FLAGS_SIZE);
/* write to the non selected sector */
hal_flash_write(lastSector - WOLFBOOT_SECTOR_SIZE * !selSec, NVM_CACHE,
WOLFBOOT_SECTOR_SIZE);
/* erase the previously selected sector */
hal_flash_erase(lastSector - WOLFBOOT_SECTOR_SIZE * selSec,
WOLFBOOT_SECTOR_SIZE);
#elif defined(WOLFBOOT_FLAGS_INVERT)
hal_flash_erase(lastSector, SECTOR_FLAGS_SIZE);
#endif
}
#endif

wolfBoot_set_partition_state(PART_UPDATE, st);

if (FLAGS_UPDATE_EXT()) {
ext_flash_lock();
} else {
hal_flash_lock();
}
}
Expand Down
10 changes: 9 additions & 1 deletion src/update_flash.c
Original file line number Diff line number Diff line change
Expand Up @@ -580,7 +580,15 @@ void RAMFUNCTION wolfBoot_start(void)
* to trigger fallback.
*/
if ((wolfBoot_get_partition_state(PART_BOOT, &st) == 0) && (st == IMG_STATE_TESTING)) {
wolfBoot_update_trigger();
/* these flags require erasing the sector flags when
* wolfBoot_update_trigger is called and thus it shouldn't be called
* if an update is already in progress */
#if defined(NVM_FLASH_WRITEONCE) || defined(WOLFBOOT_FLAGS_INVERT)
if ((wolfBoot_get_partition_state(PART_UPDATE, &st) != 0) || (st != IMG_STATE_UPDATING))
#endif
{
wolfBoot_update_trigger();
}
wolfBoot_update(1);
} else if ((wolfBoot_get_partition_state(PART_UPDATE, &st) == 0) && (st == IMG_STATE_UPDATING)) {
/* Check for new updates in the UPDATE partition */
Expand Down
18 changes: 18 additions & 0 deletions tools/test.mk
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,24 @@ test-update: test-app/image.bin FORCE
(make test-reset && sleep 1 && st-flash --reset write test-update.bin 0x08040000) || \
(make test-reset && sleep 1 && st-flash --reset write test-update.bin 0x08040000)

test-sim-external-flash-with-update: wolfboot.bin test-app/image.elf FORCE
$(Q)cp test-app/image.elf test-app/image.bak.elf
$(Q)dd if=/dev/urandom of=test-app/image.elf bs=1K count=16 oflag=append conv=notrunc
$(Q)$(SIGN_TOOL) $(SIGN_OPTIONS) test-app/image.elf $(PRIVATE_KEY) 1
$(Q)cp test-app/image.bak.elf test-app/image.elf
$(Q)dd if=/dev/urandom of=test-app/image.elf bs=1K count=16 oflag=append conv=notrunc
$(Q)$(SIGN_TOOL) $(SIGN_OPTIONS) test-app/image.elf $(PRIVATE_KEY) $(TEST_UPDATE_VERSION)
# Assembling internal flash image
#
$(Q)dd if=/dev/zero bs=$$(($(WOLFBOOT_PARTITION_SIZE))) count=1 2>/dev/null | tr "\000" "\377" > v1_part.dd
$(Q)dd if=test-app/image_v1_signed.bin bs=256 of=v1_part.dd conv=notrunc
$(Q)$(BINASSEMBLE) internal_flash.dd 0 wolfboot.bin \
$$(($(WOLFBOOT_PARTITION_BOOT_ADDRESS) - $(ARCH_FLASH_OFFSET))) v1_part.dd
$(Q)dd if=/dev/zero bs=$$(($(WOLFBOOT_SECTOR_SIZE))) count=1 2>/dev/null | tr "\000" "\377" > erased_sec.dd
$(Q)$(BINASSEMBLE) external_flash.dd 0 test-app/image_v$(TEST_UPDATE_VERSION)_signed.bin \
$(WOLFBOOT_PARTITION_SIZE) erased_sec.dd


test-sim-external-flash-with-enc-update:SIGN_ENC_ARGS=--encrypt /tmp/enc_key.der --aes128
test-sim-external-flash-with-enc-update: wolfboot.bin test-app/image.elf FORCE
$(Q)cp test-app/image.elf test-app/image.bak.elf
Expand Down
Loading