diff --git a/src/update_flash.c b/src/update_flash.c index 20564b5cd..c09112e43 100644 --- a/src/update_flash.c +++ b/src/update_flash.c @@ -361,6 +361,19 @@ static int wolfBoot_delta_update(struct wolfBoot_image *boot, #define MAX_UPDATE_SIZE (size_t)((WOLFBOOT_PARTITION_SIZE - (2 *WOLFBOOT_SECTOR_SIZE))) #endif +static inline int wolfBoot_get_total_size(struct wolfBoot_image* boot, + struct wolfBoot_image* update) +{ + uint32_t total_size = 0; + + /* Use biggest size for the swap */ + total_size = boot->fw_size + IMAGE_HEADER_SIZE; + if ((update->fw_size + IMAGE_HEADER_SIZE) > total_size) + total_size = update->fw_size + IMAGE_HEADER_SIZE; + + return total_size; +} + static int RAMFUNCTION wolfBoot_update(int fallback_allowed) { uint32_t total_size = 0; @@ -369,6 +382,7 @@ static int RAMFUNCTION wolfBoot_update(int fallback_allowed) uint8_t flag, st; struct wolfBoot_image boot, update, swap; uint16_t update_type; + uint32_t fw_size; #ifdef EXT_ENCRYPTED uint8_t key[ENCRYPT_KEY_SIZE]; uint8_t nonce[ENCRYPT_NONCE_SIZE]; @@ -385,10 +399,8 @@ static int RAMFUNCTION wolfBoot_update(int fallback_allowed) wolfBoot_open_image(&boot, PART_BOOT); wolfBoot_open_image(&swap, PART_SWAP); - /* Use biggest size for the swap */ - total_size = boot.fw_size + IMAGE_HEADER_SIZE; - if ((update.fw_size + IMAGE_HEADER_SIZE) > total_size) - total_size = update.fw_size + IMAGE_HEADER_SIZE; + /* get total size */ + total_size = wolfBoot_get_total_size(&boot, &update); if (total_size <= IMAGE_HEADER_SIZE) return -1; @@ -492,6 +504,25 @@ static int RAMFUNCTION wolfBoot_update(int fallback_allowed) wolfBoot_set_update_sector_flag(sector, flag); } sector++; + /* headers that can be in different positions depending on when the + * power fails are now in a known state, re-read and swap fw_size + * because the locations are correct but the metadata is now swapped + * also recalculate total_size since it could be invalid */ + if (sector == 1) { + wolfBoot_open_image(&boot, PART_BOOT); + wolfBoot_open_image(&update, PART_UPDATE); + + /* swap the fw_size since they're now swapped */ + fw_size = boot.fw_size; + boot.fw_size = update.fw_size; + update.fw_size = fw_size; + + /* get total size */ + total_size = wolfBoot_get_total_size(&boot, &update); + + if (total_size <= IMAGE_HEADER_SIZE) + return -1; + } } while((sector * sector_size) < WOLFBOOT_PARTITION_SIZE) { wb_flash_erase(&boot, sector * sector_size, sector_size); diff --git a/tools/scripts/sim-update-powerfail-resume.sh b/tools/scripts/sim-update-powerfail-resume.sh index c3d1b35e6..e3980d03d 100755 --- a/tools/scripts/sim-update-powerfail-resume.sh +++ b/tools/scripts/sim-update-powerfail-resume.sh @@ -5,6 +5,7 @@ if [ "x$V" != "x1" ]; then exit 1 fi +./wolfboot.elf powerfail 0 get_version 2>/dev/null ./wolfboot.elf powerfail 15000 get_version 2>/dev/null ./wolfboot.elf powerfail 18000 get_version 2>/dev/null ./wolfboot.elf powerfail 1a000 get_version 2>/dev/null @@ -15,6 +16,7 @@ if [ "x$V" != "x2" ]; then exit 1 fi +./wolfboot.elf powerfail 1000 get_version 2>/dev/null ./wolfboot.elf powerfail 11000 get_version 2>/dev/null ./wolfboot.elf powerfail 14000 get_version 2>/dev/null ./wolfboot.elf powerfail 1e000 get_version 2>/dev/null diff --git a/tools/test.mk b/tools/test.mk index fc8a949a1..441120671 100644 --- a/tools/test.mk +++ b/tools/test.mk @@ -920,29 +920,29 @@ test-all: clean test-size-all: - make test-size SIGN=NONE LIMIT=4683 + make test-size SIGN=NONE LIMIT=4722 make keysclean - make test-size SIGN=ED25519 LIMIT=11350 + make test-size SIGN=ED25519 LIMIT=11398 make keysclean - make test-size SIGN=ECC256 LIMIT=22212 + make test-size SIGN=ECC256 LIMIT=22174 make keysclean - make test-size SIGN=ECC256 NO_ASM=1 LIMIT=13646 + make test-size SIGN=ECC256 NO_ASM=1 LIMIT=13610 make keysclean - make test-size SIGN=RSA2048 LIMIT=11144 + make test-size SIGN=RSA2048 LIMIT=11182 make keysclean - make test-size SIGN=RSA2048 NO_ASM=1 LIMIT=11112 + make test-size SIGN=RSA2048 NO_ASM=1 LIMIT=11162 make keysclean - make test-size SIGN=RSA4096 LIMIT=11502 + make test-size SIGN=RSA4096 LIMIT=11546 make keysclean - make test-size SIGN=RSA4096 NO_ASM=1 LIMIT=11422 + make test-size SIGN=RSA4096 NO_ASM=1 LIMIT=11462 make keysclean - make test-size SIGN=ECC384 LIMIT=17550 + make test-size SIGN=ECC384 LIMIT=17470 make keysclean - make test-size SIGN=ECC384 NO_ASM=1 LIMIT=15082 + make test-size SIGN=ECC384 NO_ASM=1 LIMIT=15042 make keysclean - make test-size SIGN=ED448 LIMIT=13394 + make test-size SIGN=ED448 LIMIT=13414 make keysclean - make test-size SIGN=RSA3072 LIMIT=11342 + make test-size SIGN=RSA3072 LIMIT=11382 make keysclean - make test-size SIGN=RSA3072 NO_ASM=1 LIMIT=11216 + make test-size SIGN=RSA3072 NO_ASM=1 LIMIT=11254 make keysclean