From c32f05c9fbca1e67533143ac60fd5973ca7ba3b7 Mon Sep 17 00:00:00 2001 From: John Bland Date: Mon, 21 Aug 2023 01:26:55 -0400 Subject: [PATCH 1/4] add configs for NVM_FLASH_WRITEONCE with encription, FLAGS_HOME, and invert. the powerfail test will fail for these configs to show the problem --- .../workflows/test-powerfail-simulator.yml | 78 +++++++++++++++++++ ...-writeonce-flags-home-invert-update.config | 24 ++++++ ...ypt-nvm-writeonce-flags-home-update.config | 21 +++++ 3 files changed, 123 insertions(+) create mode 100644 config/examples/sim-encrypt-nvm-writeonce-flags-home-invert-update.config create mode 100644 config/examples/sim-encrypt-nvm-writeonce-flags-home-update.config diff --git a/.github/workflows/test-powerfail-simulator.yml b/.github/workflows/test-powerfail-simulator.yml index 93daf5deb..7b20fa4ca 100644 --- a/.github/workflows/test-powerfail-simulator.yml +++ b/.github/workflows/test-powerfail-simulator.yml @@ -322,3 +322,81 @@ jobs: - name: Run update-revert test with power failures (AES128 NVM_WRITEONCE) run: | tools/scripts/sim-update-powerfail-resume.sh + + # TEST with encryption (aes128) and NVM_WRITEONCE and FLAGS_HOME + + - name: make clean + run: | + make keysclean && make -C tools/keytools clean && rm -f include/target.h + - name: Select config with encrypted updates + run: | + cp config/examples/sim-encrypt-nvm-writeonce-flags-home-update.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-enc-update + - name: Run sunny day update test (AES128 NVM_WRITEONCE FLAGS_HOME) + run: | + tools/scripts/sim-sunnyday-update.sh + - name: Rebuild wolfboot.elf + run: | + make clean && make test-sim-external-flash-with-enc-update + - name: Run update-revert test (AES128 NVM_WRITEONCE FLAGS_HOME) + run: | + tools/scripts/sim-update-fallback.sh + - name: Rebuild wolfboot.elf + run: | + make clean && make test-sim-external-flash-with-enc-update + - name: Run update-revert test with power failures (AES128 NVM_WRITEONCE FLAGS_HOME) + 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 update-revert test with progressive power failures (AES128 NVM_WRITEONCE FLAGS_HOME) + run: | + tools/scripts/sim-update-powerfail-resume-nvm-writeonce.sh + + # TEST with encryption (aes128) and NVM_WRITEONCE and FLAGS_HOME and FLAGS_INVERT + + - name: make clean + run: | + make keysclean && make -C tools/keytools clean && rm -f include/target.h + - name: Select config with encrypted updates + run: | + cp config/examples/sim-encrypt-nvm-writeonce-flags-home-invert-update.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-enc-update + - name: Run sunny day update test (AES128 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-enc-update + - name: Run update-revert test (AES128 NVM_WRITEONCE FLAGS_HOME FLAGS_INVERT) + run: | + tools/scripts/sim-update-fallback.sh + - name: Rebuild wolfboot.elf + run: | + make clean && make test-sim-external-flash-with-enc-update + - name: Run update-revert test with power failures (AES128 NVM_WRITEONCE FLAGS_HOME FLAGS_INVERT) + 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 update-revert test with progressive power failures (AES128 NVM_WRITEONCE FLAGS_HOME FLAGS_INVERT) + run: | + tools/scripts/sim-update-powerfail-resume-nvm-writeonce.sh diff --git a/config/examples/sim-encrypt-nvm-writeonce-flags-home-invert-update.config b/config/examples/sim-encrypt-nvm-writeonce-flags-home-invert-update.config new file mode 100644 index 000000000..3a485749f --- /dev/null +++ b/config/examples/sim-encrypt-nvm-writeonce-flags-home-invert-update.config @@ -0,0 +1,24 @@ +ARCH=sim +TARGET=sim +SIGN?=ED25519 +HASH?=SHA256 +WOLFBOOT_SMALL_STACK=1 +SPI_FLASH=0 +EXT_FLASH=1 +ENCRYPT=1 +ENCRYPT_WITH_AES128=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 diff --git a/config/examples/sim-encrypt-nvm-writeonce-flags-home-update.config b/config/examples/sim-encrypt-nvm-writeonce-flags-home-update.config new file mode 100644 index 000000000..6ed5bdd14 --- /dev/null +++ b/config/examples/sim-encrypt-nvm-writeonce-flags-home-update.config @@ -0,0 +1,21 @@ +ARCH=sim +TARGET=sim +SIGN?=ED25519 +HASH?=SHA256 +WOLFBOOT_SMALL_STACK=1 +SPI_FLASH=0 +EXT_FLASH=1 +ENCRYPT=1 +ENCRYPT_WITH_AES128=1 +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=0xC0020000 +# 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 From 4a9973ce06d99eef2b20cecb9255557a3fdd7540 Mon Sep 17 00:00:00 2001 From: John Bland Date: Mon, 21 Aug 2023 01:30:49 -0400 Subject: [PATCH 2/4] fix powerfail problems with NVM_FLASH_WRITEONCE combinations simplify the erase address logic within nvm_select_fresh_sector add several checks to nvm_select_fresh_sector: when FLAGS_HOME is enabled, add a check for both the boot and update partition flags when EXT_ENCRYPTED is enabled, add a check for the encryption key, always perform this check when FLAGS_HOME is enabled update aes_init and chacha_init to properly account for NVM_FLASH_WRITEONCE --- src/libwolfboot.c | 70 +++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 62 insertions(+), 8 deletions(-) diff --git a/src/libwolfboot.c b/src/libwolfboot.c index 988643d0d..5a27ec77a 100644 --- a/src/libwolfboot.c +++ b/src/libwolfboot.c @@ -154,17 +154,55 @@ static const uint32_t wolfboot_magic_trail = WOLFBOOT_MAGIC_TRAIL; static uint8_t NVM_CACHE[NVM_CACHE_SIZE] __attribute__((aligned(16))); static int nvm_cached_sector = 0; -static int nvm_select_fresh_sector(int part) +static int RAMFUNCTION nvm_select_fresh_sector(int part) { int sel; uintptr_t off; uint8_t *base; - uint8_t *addr_align; + uint8_t* addrErase; - if (part == PART_BOOT) + /* if FLAGS_HOME check both boot and update for changes */ +#ifdef FLAGS_HOME + base = (uint8_t *)PART_BOOT_ENDFLAGS; + addrErase = (uint8_t *)WOLFBOOT_PARTITION_BOOT_ADDRESS + + WOLFBOOT_PARTITION_SIZE - WOLFBOOT_SECTOR_SIZE; +#else + if (part == PART_BOOT) { base = (uint8_t *)PART_BOOT_ENDFLAGS; - else + addrErase = (uint8_t *)WOLFBOOT_PARTITION_BOOT_ADDRESS + + WOLFBOOT_PARTITION_SIZE - WOLFBOOT_SECTOR_SIZE; + } + else { base = (uint8_t *)PART_UPDATE_ENDFLAGS; + addrErase = (uint8_t *)WOLFBOOT_PARTITION_UPDATE_ADDRESS + + WOLFBOOT_PARTITION_SIZE - WOLFBOOT_SECTOR_SIZE; + } +#endif + +#ifdef EXT_ENCRYPTED + uint32_t word_0; + uint32_t word_1; +#ifndef FLAGS_HOME + if (part == PART_BOOT) +#endif + { + word_0 = *((uint32_t *)(ENCRYPT_TMP_SECRET_OFFSET + + WOLFBOOT_PARTITION_BOOT_ADDRESS)); + word_1 = *((uint32_t *)(ENCRYPT_TMP_SECRET_OFFSET + + WOLFBOOT_PARTITION_BOOT_ADDRESS - WOLFBOOT_SECTOR_SIZE)); + + if (word_0 == FLASH_WORD_ERASED && word_1 != + FLASH_WORD_ERASED) { + sel = 1; + goto finish; + } + else if (word_0 != FLASH_WORD_ERASED && word_1 == + FLASH_WORD_ERASED) { + sel = 0; + goto finish; + } + } +#endif /* Default to last sector if no match is found */ sel = 0; @@ -184,6 +222,14 @@ static int nvm_select_fresh_sector(int part) } else if ((byte_0 == FLASH_BYTE_ERASED) && (byte_1 == FLASH_BYTE_ERASED)) { +#ifdef FLAGS_HOME + /* if we're still checking boot flags, check update flags */ + if (base - off > (uint8_t*)PART_UPDATE_ENDFLAGS) { + base = (uint8_t *)PART_UPDATE_ENDFLAGS; + off = 0; + continue; + } +#endif /* First time boot? Assume no pending update */ if(off == 1) { sel=0; @@ -196,12 +242,12 @@ static int nvm_select_fresh_sector(int part) break; } } +finish: /* Erase the non-selected partition */ - addr_align = (uint8_t *)((((uintptr_t)base - ((1 + (!sel)) * WOLFBOOT_SECTOR_SIZE))) - & ((~(NVM_CACHE_SIZE - 1)))); - if (*((uint32_t*)(addr_align + WOLFBOOT_SECTOR_SIZE - sizeof(uint32_t))) + addrErase -= WOLFBOOT_SECTOR_SIZE * (!sel); + if (*((uint32_t*)(addrErase + WOLFBOOT_SECTOR_SIZE - sizeof(uint32_t))) != FLASH_WORD_ERASED) { - hal_flash_erase((uintptr_t)addr_align, WOLFBOOT_SECTOR_SIZE); + hal_flash_erase((uintptr_t)addrErase, WOLFBOOT_SECTOR_SIZE); } return sel; } @@ -1076,6 +1122,10 @@ int RAMFUNCTION chacha_init(void) uint8_t ff[ENCRYPT_KEY_SIZE]; uint8_t* stored_nonce; +#ifdef NVM_FLASH_WRITEONCE + key -= WOLFBOOT_SECTOR_SIZE * nvm_select_fresh_sector(PART_BOOT); +#endif + stored_nonce = key + ENCRYPT_KEY_SIZE; XMEMSET(&chacha, 0, sizeof(chacha)); @@ -1111,6 +1161,10 @@ int aes_init(void) uint8_t iv_buf[ENCRYPT_NONCE_SIZE]; uint8_t* stored_nonce; +#ifdef NVM_FLASH_WRITEONCE + key -= WOLFBOOT_SECTOR_SIZE * nvm_select_fresh_sector(PART_BOOT); +#endif + stored_nonce = key + ENCRYPT_KEY_SIZE; XMEMSET(&aes_enc, 0, sizeof(aes_enc)); From 032fa172eca9742416c05c9aaac10257c9d33bee Mon Sep 17 00:00:00 2001 From: John Bland Date: Mon, 21 Aug 2023 01:39:31 -0400 Subject: [PATCH 3/4] remove missing test --- .github/workflows/test-powerfail-simulator.yml | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/.github/workflows/test-powerfail-simulator.yml b/.github/workflows/test-powerfail-simulator.yml index 7b20fa4ca..4c6869894 100644 --- a/.github/workflows/test-powerfail-simulator.yml +++ b/.github/workflows/test-powerfail-simulator.yml @@ -355,12 +355,6 @@ jobs: - name: Run update-revert test with power failures (AES128 NVM_WRITEONCE FLAGS_HOME) 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 update-revert test with progressive power failures (AES128 NVM_WRITEONCE FLAGS_HOME) - run: | - tools/scripts/sim-update-powerfail-resume-nvm-writeonce.sh # TEST with encryption (aes128) and NVM_WRITEONCE and FLAGS_HOME and FLAGS_INVERT @@ -394,9 +388,3 @@ jobs: - name: Run update-revert test with power failures (AES128 NVM_WRITEONCE FLAGS_HOME FLAGS_INVERT) 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 update-revert test with progressive power failures (AES128 NVM_WRITEONCE FLAGS_HOME FLAGS_INVERT) - run: | - tools/scripts/sim-update-powerfail-resume-nvm-writeonce.sh From 6302870a889ea6a16ed32ee428927588c95b3dca Mon Sep 17 00:00:00 2001 From: John Bland Date: Mon, 21 Aug 2023 01:47:22 -0400 Subject: [PATCH 4/4] fix bad config address for simulator --- .../examples/sim-encrypt-nvm-writeonce-flags-home-update.config | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/examples/sim-encrypt-nvm-writeonce-flags-home-update.config b/config/examples/sim-encrypt-nvm-writeonce-flags-home-update.config index 6ed5bdd14..97d2f4390 100644 --- a/config/examples/sim-encrypt-nvm-writeonce-flags-home-update.config +++ b/config/examples/sim-encrypt-nvm-writeonce-flags-home-update.config @@ -13,7 +13,7 @@ NVM_FLASH_WRITEONCE=1 FLAGS_HOME=1 WOLFBOOT_PARTITION_SIZE=0x40000 WOLFBOOT_SECTOR_SIZE=0x1000 -WOLFBOOT_PARTITION_BOOT_ADDRESS=0xC0020000 +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