diff --git a/config/examples/stm32l5-wolfcrypt-tz.config b/config/examples/stm32l5-wolfcrypt-tz.config index da470f2a4a..33533809af 100644 --- a/config/examples/stm32l5-wolfcrypt-tz.config +++ b/config/examples/stm32l5-wolfcrypt-tz.config @@ -31,3 +31,6 @@ FLAGS_HOME=0 DISABLE_BACKUP=0 WOLFCRYPT_TZ=1 WOLFCRYPT_TZ_PKCS11=1 + +# Use a larger image header size to enforce alignment requirements for the interrupt vector table +IMAGE_HEADER_SIZE?=1024 diff --git a/hal/stm32_tz.c b/hal/stm32_tz.c index fd2d0c8c1d..ae6f05c240 100644 --- a/hal/stm32_tz.c +++ b/hal/stm32_tz.c @@ -95,9 +95,7 @@ static int is_range_nonsecure(uint32_t address, int len) void hal_tz_claim_nonsecure_area(uint32_t address, int len) { int page_n, reg_idx; - uint32_t reg; uint32_t end = address + len; - uint32_t start_address = address; uint32_t start_page_n; uint32_t bank = 0; int pos; @@ -124,39 +122,14 @@ void hal_tz_claim_nonsecure_area(uint32_t address, int len) hal_flash_wait_complete(bank); hal_flash_clear_errors(bank); if (bank == 0) - FLASH_SECBB1[reg_idx] |= ( 1 << pos); + FLASH_SECBB1[reg_idx] |= (1u << pos); else - FLASH_SECBB2[reg_idx] |= ( 1 << pos); + FLASH_SECBB2[reg_idx] |= (1u << pos); ISB(); hal_flash_wait_complete(bank); address += FLASH_PAGE_SIZE; page_n++; } - address = start_address; - page_n = start_page_n; - while (address < end) { - /* Erase claimed non-secure page, in secure mode */ -#ifndef TARGET_stm32h5 - reg = FLASH_CR & (~((FLASH_CR_PNB_MASK << FLASH_CR_PNB_SHIFT) | FLASH_CR_PER | FLASH_CR_BKER | FLASH_CR_PG | FLASH_CR_MER1 | FLASH_CR_MER2)); - FLASH_CR = reg | ((page_n << FLASH_CR_PNB_SHIFT) | FLASH_CR_PER); -#else - reg = FLASH_CR & (~((FLASH_CR_PNB_MASK << FLASH_CR_PNB_SHIFT) | FLASH_CR_SER | FLASH_CR_BER | FLASH_CR_PG | FLASH_CR_MER | FLASH_CR_BKSEL)); - FLASH_CR = reg | ((page_n << FLASH_CR_PNB_SHIFT) | FLASH_CR_SER | (bank << 31)); -#endif - - DMB(); - ISB(); - FLASH_CR |= FLASH_CR_STRT; - ISB(); - hal_flash_wait_complete(bank); - address += FLASH_PAGE_SIZE; - page_n++; - } -#ifndef TARGET_stm32h5 - FLASH_CR &= ~FLASH_CR_PER ; -#else - FLASH_CR &= ~FLASH_CR_SER ; -#endif } #else #define claim_nonsecure_area(...) do{}while(0) @@ -295,32 +268,24 @@ void hal_gtzc_init(void) void hal_tz_sau_init(void) { - /* SAU is set up before staging. Set up all areas as secure. */ + /* SAU is set up before staging. Define non-secure windows only. */ /* Non-secure callable: NSC functions area */ sau_init_region(0, WOLFBOOT_NSC_ADDRESS, WOLFBOOT_NSC_ADDRESS + WOLFBOOT_NSC_SIZE - 1, 1); - /* Secure: application flash area (first bank) */ - sau_init_region(1, WOLFBOOT_PARTITION_BOOT_ADDRESS, FLASH_BANK2_BASE - 1, 0); - - /* Secure: application flash area (second bank) */ - sau_init_region(2, WOLFBOOT_PARTITION_UPDATE_ADDRESS, FLASH_TOP, 0); - - /* Secure RAM regions in SRAM1/SRAM2 */ - sau_init_region(3, 0x30000000, 0x3004FFFF, 1); + /* Non-secure flash alias (boot partition only) */ + sau_init_region(1, WOLFBOOT_PARTITION_BOOT_ADDRESS, + WOLFBOOT_PARTITION_BOOT_ADDRESS + WOLFBOOT_PARTITION_SIZE - 1, 0); - /* Non-secure RAM region in SRAM3 */ - sau_init_region(4, 0x20050000, 0x2008FFFF, 0); + /* Non-secure RAM region */ + sau_init_region(2, 0x20050000, 0x2008FFFF, 0); /* Non-secure: internal peripherals */ - sau_init_region(5, 0x40000000, 0x4FFFFFFF, 0); - - /* Secure mapped peripherals */ - sau_init_region(6, 0x50000000, 0x5FFFFFFF, 1); + sau_init_region(3, 0x40000000, 0x4FFFFFFF, 0); /* Set as non-secure: OTP + RO area */ - sau_init_region(7, 0x08FFF000, 0x08FFFFFF, 0); + sau_init_region(4, 0x08FFF000, 0x08FFFFFF, 0); /* Enable SAU */ SAU_CTRL = SAU_INIT_CTRL_ENABLE; @@ -336,9 +301,9 @@ void hal_tz_sau_init(void) sau_init_region(0, WOLFBOOT_NSC_ADDRESS, WOLFBOOT_NSC_ADDRESS + WOLFBOOT_NSC_SIZE - 1, 1); - /* Non-secure: application flash area */ + /* Non-secure: application flash area (boot partition only) */ sau_init_region(1, WOLFBOOT_PARTITION_BOOT_ADDRESS, - WOLFBOOT_PARTITION_BOOT_ADDRESS + 2 * WOLFBOOT_PARTITION_SIZE - 1, + WOLFBOOT_PARTITION_BOOT_ADDRESS + WOLFBOOT_PARTITION_SIZE - 1, 0); /* Non-secure RAM region in SRAM1/SRAM2 */ @@ -371,7 +336,6 @@ void hal_tz_sau_init(void) #define TRNG_CR_CONFIG1_SHIFT (20) #define TRNG_CR_CONDRST (1 << 30) - static void hsi48_on(void) { @@ -435,4 +399,3 @@ int hal_trng_get_entropy(unsigned char *out, unsigned len) } #endif - diff --git a/hal/stm32l5.c b/hal/stm32l5.c index 36843412de..dc43031d08 100644 --- a/hal/stm32l5.c +++ b/hal/stm32l5.c @@ -25,6 +25,7 @@ #include "hal.h" #include "hal/stm32l5.h" +#include "printf.h" static void RAMFUNCTION flash_set_waitstates(unsigned int waitstates) @@ -146,12 +147,18 @@ void RAMFUNCTION hal_flash_opt_lock(void) FLASH_CR |= FLASH_CR_OPTLOCK; } - int RAMFUNCTION hal_flash_erase(uint32_t address, int len) { uint32_t end_address; uint32_t p; + if (address < WOLFBOOT_PARTITION_BOOT_ADDRESS) { + wolfBoot_printf("hal_flash_erase: addr=0x%08x len=%d (below boot)\n", + address, len); + } else { + wolfBoot_printf("hal_flash_erase: addr=0x%08x len=%d\n", address, len); + } + hal_flash_clear_errors(0); if (len == 0) return -1; @@ -170,10 +177,6 @@ int RAMFUNCTION hal_flash_erase(uint32_t address, int len) } else if(p >= (FLASH_BANK2_BASE) && (p <= (FLASH_TOP) )) { -#if TZ_SECURE() - /* When in secure mode, skip erasing non-secure pages: will be erased upon claim */ - return 0; -#endif bker = FLASH_CR_BKER; base = FLASH_BANK2_BASE; } else { @@ -412,4 +415,3 @@ void hal_prepare_boot(void) periph_unsecure(); #endif } - diff --git a/include/image.h b/include/image.h index 6aa56da3f0..51c8ba9ad5 100644 --- a/include/image.h +++ b/include/image.h @@ -204,12 +204,20 @@ static void __attribute__((noinline)) wolfBoot_image_clear_signature_ok( /* Loading hdr_ok flag, verifying */ \ asm volatile("mov r2, %0" ::"r"((p)->hdr_ok):"r2"); \ asm volatile("cmp r2, #1":::"cc"); \ + asm volatile("cmp r2, #1":::"cc"); \ + asm volatile("cmp r2, #1":::"cc"); \ asm volatile("bne ."); \ asm volatile("cmp r2, #1":::"cc"); \ + asm volatile("cmp r2, #1":::"cc"); \ + asm volatile("cmp r2, #1":::"cc"); \ asm volatile("bne .-4"); \ asm volatile("cmp r2, #1":::"cc"); \ + asm volatile("cmp r2, #1":::"cc"); \ + asm volatile("cmp r2, #1":::"cc"); \ asm volatile("bne .-8"); \ asm volatile("cmp r2, #1":::"cc"); \ + asm volatile("cmp r2, #1":::"cc"); \ + asm volatile("cmp r2, #1":::"cc"); \ asm volatile("bne .-12"); \ /* Redundant set of r2=0 */ \ asm volatile("mov r2, #0":::"r2"); \ @@ -220,12 +228,20 @@ static void __attribute__((noinline)) wolfBoot_image_clear_signature_ok( /* Loading hdr_ok flag, verifying */ \ asm volatile("mov r2, %0" ::"r"((p)->sha_ok):"r2"); \ asm volatile("cmp r2, #1":::"cc"); \ + asm volatile("cmp r2, #1":::"cc"); \ + asm volatile("cmp r2, #1":::"cc"); \ asm volatile("bne ."); \ asm volatile("cmp r2, #1":::"cc"); \ + asm volatile("cmp r2, #1":::"cc"); \ + asm volatile("cmp r2, #1":::"cc"); \ asm volatile("bne .-4"); \ asm volatile("cmp r2, #1":::"cc"); \ + asm volatile("cmp r2, #1":::"cc"); \ + asm volatile("cmp r2, #1":::"cc"); \ asm volatile("bne .-8"); \ asm volatile("cmp r2, #1":::"cc"); \ + asm volatile("cmp r2, #1":::"cc"); \ + asm volatile("cmp r2, #1":::"cc"); \ asm volatile("bne .-12"); \ /* Redundant set of r2=0 */ \ asm volatile("mov r2, #0":::"r2"); \ @@ -236,12 +252,20 @@ static void __attribute__((noinline)) wolfBoot_image_clear_signature_ok( /* Loading signature_ok flag, verifying */ \ asm volatile("mov r2, %0" ::"r"((p)->signature_ok):"r2"); \ asm volatile("cmp r2, #1":::"cc"); \ + asm volatile("cmp r2, #1":::"cc"); \ + asm volatile("cmp r2, #1":::"cc"); \ asm volatile("bne ."); \ asm volatile("cmp r2, #1":::"cc"); \ + asm volatile("cmp r2, #1":::"cc"); \ + asm volatile("cmp r2, #1":::"cc"); \ asm volatile("bne .-4"); \ asm volatile("cmp r2, #1":::"cc"); \ + asm volatile("cmp r2, #1":::"cc"); \ + asm volatile("cmp r2, #1":::"cc"); \ asm volatile("bne .-8"); \ asm volatile("cmp r2, #1":::"cc"); \ + asm volatile("cmp r2, #1":::"cc"); \ + asm volatile("cmp r2, #1":::"cc"); \ asm volatile("bne .-12"); \ /* Redundant set of r2=0 */ \ asm volatile("mov r2, #0"); \ @@ -252,12 +276,20 @@ static void __attribute__((noinline)) wolfBoot_image_clear_signature_ok( /* Loading ~(signature_ok) flag, verifying */ \ asm volatile("mov r2, %0" ::"r"((p)->not_signature_ok):"r2"); \ asm volatile("cmp r2, #0xFFFFFFFE":::"cc"); \ + asm volatile("cmp r2, #0xFFFFFFFE":::"cc"); \ + asm volatile("cmp r2, #0xFFFFFFFE":::"cc"); \ asm volatile("bne ."); \ asm volatile("cmp r2, #0xFFFFFFFE":::"cc"); \ + asm volatile("cmp r2, #0xFFFFFFFE":::"cc"); \ + asm volatile("cmp r2, #0xFFFFFFFE":::"cc"); \ asm volatile("bne .-4"); \ asm volatile("cmp r2, #0xFFFFFFFE":::"cc"); \ + asm volatile("cmp r2, #0xFFFFFFFE":::"cc"); \ + asm volatile("cmp r2, #0xFFFFFFFE":::"cc"); \ asm volatile("bne .-8"); \ asm volatile("cmp r2, #0xFFFFFFFE":::"cc"); \ + asm volatile("cmp r2, #0xFFFFFFFE":::"cc"); \ + asm volatile("cmp r2, #0xFFFFFFFE":::"cc"); \ asm volatile("bne .-12"); \ /* Redundant set of r2=0 */ \ asm volatile("mov r2, #0":::"r2"); \ @@ -269,12 +301,20 @@ static void __attribute__((noinline)) wolfBoot_image_clear_signature_ok( asm volatile("mov r2, %0" ::"r"((p)->canary_FEED6789):"r2"); \ asm volatile("mov r0, %0" ::"r"(0xFEED6789):"r0"); \ asm volatile("cmp r2, r0":::"cc"); \ + asm volatile("cmp r2, r0":::"cc"); \ + asm volatile("cmp r2, r0":::"cc"); \ asm volatile("bne ."); \ asm volatile("cmp r2, r0":::"cc"); \ + asm volatile("cmp r2, r0":::"cc"); \ + asm volatile("cmp r2, r0":::"cc"); \ asm volatile("bne .-4"); \ asm volatile("cmp r2, r0":::"cc"); \ + asm volatile("cmp r2, r0":::"cc"); \ + asm volatile("cmp r2, r0":::"cc"); \ asm volatile("bne .-8"); \ asm volatile("cmp r2, r0":::"cc"); \ + asm volatile("cmp r2, r0":::"cc"); \ + asm volatile("cmp r2, r0":::"cc"); \ asm volatile("bne .-12"); \ /* Redundant set of r2=0 */ \ asm volatile("mov r2, #0":::"r2"); \ @@ -286,12 +326,20 @@ static void __attribute__((noinline)) wolfBoot_image_clear_signature_ok( asm volatile("mov r2, %0" ::"r"((p)->canary_FEED4567):"r2"); \ asm volatile("mov r0, %0" ::"r"(0xFEED4567):"r0"); \ asm volatile("cmp r2, r0":::"cc"); \ + asm volatile("cmp r2, r0":::"cc"); \ + asm volatile("cmp r2, r0":::"cc"); \ asm volatile("bne ."); \ asm volatile("cmp r2, r0":::"cc"); \ + asm volatile("cmp r2, r0":::"cc"); \ + asm volatile("cmp r2, r0":::"cc"); \ asm volatile("bne .-4"); \ asm volatile("cmp r2, r0":::"cc"); \ + asm volatile("cmp r2, r0":::"cc"); \ + asm volatile("cmp r2, r0":::"cc"); \ asm volatile("bne .-8"); \ asm volatile("cmp r2, r0":::"cc"); \ + asm volatile("cmp r2, r0":::"cc"); \ + asm volatile("cmp r2, r0":::"cc"); \ asm volatile("bne .-12"); \ /* Redundant set of r2=0 */ \ asm volatile("mov r2, #0":::"r2"); \ @@ -303,13 +351,21 @@ static void __attribute__((noinline)) wolfBoot_image_clear_signature_ok( asm volatile("mov r2, %0" ::"r"((p)->canary_FEED89AB):"r2"); \ asm volatile("mov r0, %0" ::"r"(0xFEED89AB):"r0"); \ asm volatile("cmp r2, r0":::"cc"); \ + asm volatile("cmp r2, r0":::"cc"); \ + asm volatile("cmp r2, r0":::"cc"); \ asm volatile("bne ."); \ asm volatile("cmp r2, r0":::"cc"); \ + asm volatile("cmp r2, r0":::"cc"); \ + asm volatile("cmp r2, r0":::"cc"); \ asm volatile("bne .-4"); \ asm volatile("cmp r2, r0":::"cc"); \ + asm volatile("cmp r2, r0":::"cc"); \ + asm volatile("cmp r2, r0":::"cc"); \ asm volatile("bne .-8"); \ asm volatile("cmp r2, r0":::"cc"); \ - asm volatile("bne .-12") + asm volatile("cmp r2, r0":::"cc"); \ + asm volatile("cmp r2, r0":::"cc"); \ + asm volatile("bne .-12") \ /** * First part of RSA verification. Ensure that the function is called by @@ -332,12 +388,20 @@ static void __attribute__((noinline)) wolfBoot_image_clear_signature_ok( asm volatile("mov r2, %0" ::"r"(WOLFBOOT_SHA_DIGEST_SIZE):"r2"); \ /* Redundant check for fn() return value >= r2 */ \ asm volatile("cmp r0, r2":::"cc"); \ + asm volatile("cmp r0, r2":::"cc"); \ + asm volatile("cmp r0, r2":::"cc"); \ asm volatile("blt nope"); \ asm volatile("cmp r0, r2":::"cc"); \ + asm volatile("cmp r0, r2":::"cc"); \ + asm volatile("cmp r0, r2":::"cc"); \ asm volatile("blt nope"); \ asm volatile("cmp r0, r2":::"cc"); \ + asm volatile("cmp r0, r2":::"cc"); \ + asm volatile("cmp r0, r2":::"cc"); \ asm volatile("blt nope"); \ asm volatile("cmp r0, r2":::"cc"); \ + asm volatile("cmp r0, r2":::"cc"); \ + asm volatile("cmp r0, r2":::"cc"); \ asm volatile("blt nope"); \ /* Return value is set here in case of success */ \ ret = tmp_ret; \ @@ -363,23 +427,39 @@ static void __attribute__((noinline)) wolfBoot_image_clear_signature_ok( compare_res = XMEMCMP(digest, img->sha_hash, WOLFBOOT_SHA_DIGEST_SIZE); \ /* Redundant checks that ensure the function actually returned 0 */ \ asm volatile("cmp r0, #0":::"cc"); \ + asm volatile("cmp r0, #0":::"cc"); \ + asm volatile("cmp r0, #0":::"cc"); \ asm volatile("bne hnope":::"cc"); \ asm volatile("cmp r0, #0"); \ + asm volatile("cmp r0, #0"); \ + asm volatile("cmp r0, #0"); \ asm volatile("bne hnope":::"cc"); \ asm volatile("cmp r0, #0":::"cc"); \ + asm volatile("cmp r0, #0":::"cc"); \ + asm volatile("cmp r0, #0":::"cc"); \ asm volatile("bne hnope"); \ asm volatile("cmp r0, #0":::"cc"); \ + asm volatile("cmp r0, #0":::"cc"); \ + asm volatile("cmp r0, #0":::"cc"); \ asm volatile("bne hnope"); \ /* Repeat memcmp call */ \ compare_res = XMEMCMP(digest, img->sha_hash, WOLFBOOT_SHA_DIGEST_SIZE); \ /* Redundant checks that ensure the function actually returned 0 */ \ asm volatile("cmp r0, #0":::"cc"); \ + asm volatile("cmp r0, #0":::"cc"); \ + asm volatile("cmp r0, #0":::"cc"); \ asm volatile("bne hnope"); \ asm volatile("cmp r0, #0":::"cc"); \ + asm volatile("cmp r0, #0":::"cc"); \ + asm volatile("cmp r0, #0":::"cc"); \ asm volatile("bne hnope"); \ asm volatile("cmp r0, #0":::"cc"); \ + asm volatile("cmp r0, #0":::"cc"); \ + asm volatile("cmp r0, #0":::"cc"); \ asm volatile("bne hnope"); \ asm volatile("cmp r0, #0":::"cc"); \ + asm volatile("cmp r0, #0":::"cc"); \ + asm volatile("cmp r0, #0":::"cc"); \ asm volatile("bne hnope"); \ /* Confirm that the signature is OK */ \ wolfBoot_image_confirm_signature_ok(img); \ @@ -408,30 +488,66 @@ static void __attribute__((noinline)) wolfBoot_image_clear_signature_ok( fn(__VA_ARGS__); \ /* Redundant checks that ensure the function actually returned 0 */ \ asm volatile("cmp r0, #0":::"cc"); \ + asm volatile("cmp r0, #0":::"cc"); \ + asm volatile("cmp r0, #0":::"cc"); \ asm volatile("bne nope"); \ asm volatile("cmp r0, #0":::"cc"); \ + asm volatile("cmp r0, #0":::"cc"); \ + asm volatile("cmp r0, #0":::"cc"); \ asm volatile("bne nope"); \ asm volatile("cmp r0, #0":::"cc"); \ + asm volatile("cmp r0, #0":::"cc"); \ + asm volatile("cmp r0, #0":::"cc"); \ asm volatile("bne nope"); \ asm volatile("cmp r0, #0":::"cc"); \ + asm volatile("cmp r0, #0":::"cc"); \ + asm volatile("cmp r0, #0":::"cc"); \ asm volatile("bne nope"); \ /* Check that res = 1, a few times, reading the value from memory */ \ asm volatile("ldr r2, [%0]" ::"r"(p_res)); \ asm volatile("cmp r2, #1":::"cc"); \ + asm volatile("cmp r2, #1":::"cc"); \ + asm volatile("cmp r2, #1":::"cc"); \ + asm volatile("bne nope"); \ + asm volatile("mvn r3, r2":::"r3"); \ + asm volatile("cmp r3, #0xFFFFFFFE":::"cc"); \ + asm volatile("cmp r3, #0xFFFFFFFE":::"cc"); \ + asm volatile("cmp r3, #0xFFFFFFFE":::"cc"); \ asm volatile("bne nope"); \ asm volatile("ldr r2, [%0]" ::"r"(p_res)); \ asm volatile("cmp r2, #1":::"cc"); \ + asm volatile("cmp r2, #1":::"cc"); \ + asm volatile("cmp r2, #1":::"cc"); \ + asm volatile("bne nope"); \ + asm volatile("mvn r3, r2":::"r3"); \ + asm volatile("cmp r3, #0xFFFFFFFE":::"cc"); \ + asm volatile("cmp r3, #0xFFFFFFFE":::"cc"); \ + asm volatile("cmp r3, #0xFFFFFFFE":::"cc"); \ asm volatile("bne nope"); \ asm volatile("ldr r2, [%0]" ::"r"(p_res)); \ asm volatile("cmp r2, #1":::"cc"); \ + asm volatile("cmp r2, #1":::"cc"); \ + asm volatile("cmp r2, #1":::"cc"); \ + asm volatile("bne nope"); \ + asm volatile("mvn r3, r2":::"r3"); \ + asm volatile("cmp r3, #0xFFFFFFFE":::"cc"); \ + asm volatile("cmp r3, #0xFFFFFFFE":::"cc"); \ + asm volatile("cmp r3, #0xFFFFFFFE":::"cc"); \ asm volatile("bne nope"); \ asm volatile("ldr r2, [%0]" ::"r"(p_res)); \ asm volatile("cmp r2, #1":::"cc"); \ + asm volatile("cmp r2, #1":::"cc"); \ + asm volatile("cmp r2, #1":::"cc"); \ + asm volatile("bne nope"); \ + asm volatile("mvn r3, r2":::"r3"); \ + asm volatile("cmp r3, #0xFFFFFFFE":::"cc"); \ + asm volatile("cmp r3, #0xFFFFFFFE":::"cc"); \ + asm volatile("cmp r3, #0xFFFFFFFE":::"cc"); \ asm volatile("bne nope"); \ /* Confirm that the signature is OK */ \ wolfBoot_image_confirm_signature_ok(img); \ asm volatile("nope:"); \ - asm volatile("nop") + asm volatile("nop") \ #elif defined(__ICCARM__) && defined(__IAR_SYSTEMS_ICC__) @@ -450,37 +566,136 @@ static void __attribute__((noinline)) wolfBoot_image_clear_signature_ok( fn(__VA_ARGS__); \ __asm volatile( \ "cmp r0, #0\n" \ - "bne 1f\n" \ "cmp r0, #0\n" \ - "bne 1f\n" \ "cmp r0, #0\n" \ + "beq 30f\n" \ + "bne 1f\n" \ + "bne 1f\n" \ "bne 1f\n" \ - "cmp r0, #0\n" \ "bne 1f\n" \ + "b .\n" \ + "b .\n" \ + "b .\n" \ + "30:\n" \ "ldr r2, [%0]\n" \ "cmp r2, #1\n" \ + "cmp r2, #1\n" \ + "cmp r2, #1\n" \ + "beq 31f\n" \ + "bne 1f\n" \ + "bne 1f\n" \ + "bne 1f\n" \ + "bne 1f\n" \ + "b .\n" \ + "b .\n" \ + "b .\n" \ + "31:\n" \ + "mvn r3, r2\n" \ + "cmp r3, #0xFFFFFFFE\n" \ + "cmp r3, #0xFFFFFFFE\n" \ + "cmp r3, #0xFFFFFFFE\n" \ + "beq 32f\n" \ "bne 1f\n" \ + "bne 1f\n" \ + "bne 1f\n" \ + "bne 1f\n" \ + "b .\n" \ + "b .\n" \ + "b .\n" \ + "32:\n" \ "ldr r2, [%0]\n" \ "cmp r2, #1\n" \ + "cmp r2, #1\n" \ + "cmp r2, #1\n" \ + "beq 33f\n" \ + "bne 1f\n" \ + "bne 1f\n" \ + "bne 1f\n" \ + "bne 1f\n" \ + "b .\n" \ + "b .\n" \ + "b .\n" \ + "33:\n" \ + "mvn r3, r2\n" \ + "cmp r3, #0xFFFFFFFE\n" \ + "cmp r3, #0xFFFFFFFE\n" \ + "cmp r3, #0xFFFFFFFE\n" \ + "beq 34f\n" \ + "bne 1f\n" \ + "bne 1f\n" \ + "bne 1f\n" \ "bne 1f\n" \ + "b .\n" \ + "b .\n" \ + "b .\n" \ + "34:\n" \ "ldr r2, [%0]\n" \ "cmp r2, #1\n" \ + "cmp r2, #1\n" \ + "cmp r2, #1\n" \ + "beq 35f\n" \ + "bne 1f\n" \ + "bne 1f\n" \ + "bne 1f\n" \ + "bne 1f\n" \ + "b .\n" \ + "b .\n" \ + "b .\n" \ + "35:\n" \ + "mvn r3, r2\n" \ + "cmp r3, #0xFFFFFFFE\n" \ + "cmp r3, #0xFFFFFFFE\n" \ + "cmp r3, #0xFFFFFFFE\n" \ + "beq 36f\n" \ "bne 1f\n" \ + "bne 1f\n" \ + "bne 1f\n" \ + "bne 1f\n" \ + "b .\n" \ + "b .\n" \ + "b .\n" \ + "36:\n" \ "ldr r2, [%0]\n" \ "cmp r2, #1\n" \ + "cmp r2, #1\n" \ + "cmp r2, #1\n" \ + "beq 37f\n" \ + "bne 1f\n" \ "bne 1f\n" \ + "bne 1f\n" \ + "bne 1f\n" \ + "b .\n" \ + "b .\n" \ + "b .\n" \ + "37:\n" \ + "mvn r3, r2\n" \ + "cmp r3, #0xFFFFFFFE\n" \ + "cmp r3, #0xFFFFFFFE\n" \ + "cmp r3, #0xFFFFFFFE\n" \ + "beq 38f\n" \ + "bne 1f\n" \ + "bne 1f\n" \ + "bne 1f\n" \ + "bne 1f\n" \ + "b .\n" \ + "b .\n" \ + "b .\n" \ + "38:\n" \ /* Load 'img' into r0 (first argument to the function) */ \ "mov r0, %1\n" \ /* Load the function pointer into r3 */ \ "mov r3, %2\n" \ "blx r3\n"\ "b 2f\n" \ + "b .\n" \ + "b .\n" \ + "b .\n" \ "1:\n" \ "nop\n" \ "2:\n" \ : /* No output operands */ \ : "r"(p_res), "r"(img), "r"(confirm_func) /* Input operands */ \ - : "r0", "r2", "lr" /* Clobbered registers */ \ + : "r0", "r2", "r3", "lr" /* Clobbered registers */ \ ); \ } while (0) #endif @@ -507,93 +722,192 @@ static void __attribute__((noinline)) wolfBoot_image_clear_signature_ok( #if defined(__GNUC__) #define VERIFY_VERSION_ALLOWED(fb_ok) \ - /* Stash the registry values */ \ - asm volatile("push {r4, r5, r6, r7}"); \ - /* Redundant initialization with 'failure' values */ \ - asm volatile("mov r0, #0":::"r0"); \ - asm volatile("mov r4, #1":::"r4"); \ - asm volatile("mov r5, #0":::"r5"); \ - asm volatile("mov r6, #2":::"r6"); \ - asm volatile("mov r7, #0":::"r7"); \ - asm volatile("mov r0, #0":::"r0"); \ - asm volatile("mov r4, #1":::"r4"); \ - asm volatile("mov r5, #0":::"r5"); \ - asm volatile("mov r6, #2":::"r6"); \ - asm volatile("mov r7, #0":::"r7"); \ - /* Read the fb_ok flag, jump to end_check \ - * if proven fb_ok == 1 */ \ - asm volatile("mov r0, %0" ::"r"(fb_ok):"r0"); \ - asm volatile("cmp r0, #1":::"cc"); \ - asm volatile("bne do_check"); \ - asm volatile("cmp r0, #1":::"cc"); \ - asm volatile("bne do_check"); \ - asm volatile("cmp r0, #1":::"cc"); \ - asm volatile("bne do_check"); \ - asm volatile("b end_check"); \ - /* Do the actual version check: */ \ - asm volatile("do_check:"); \ - /* Read update versions to reg r5 and r7 */ \ - asm volatile("mov r0, #1":::"r0"); \ - asm volatile("mov r0, #1":::"r0"); \ - asm volatile("mov r0, #1":::"r0"); \ - asm volatile("bl wolfBoot_get_image_version"); \ - asm volatile("mov r5, r0":::"r5"); \ - asm volatile("mov r5, r0":::"r5"); \ - asm volatile("mov r5, r0":::"r5"); \ - asm volatile("mov r0, #1":::"r0"); \ - asm volatile("mov r0, #1":::"r0"); \ - asm volatile("mov r0, #1":::"r0"); \ - asm volatile("bl wolfBoot_get_image_version"); \ - asm volatile("mov r7, r0":::"r7"); \ - asm volatile("mov r7, r0":::"r7"); \ - asm volatile("mov r7, r0":::"r7"); \ - /* Compare r5 and r7, if not equal, something went very wrong, */ \ - asm volatile("cmp r5, r7":::"cc"); \ - asm volatile("bne ."); \ - asm volatile("cmp r5, r7":::"cc"); \ - asm volatile("bne .-4"); \ - asm volatile("cmp r5, r7":::"cc"); \ - asm volatile("bne .-8"); \ - asm volatile("cmp r5, r7":::"cc"); \ - asm volatile("bne .-12"); \ - /* Read current versions to reg r4 and r6 */ \ - asm volatile("mov r0, #0":::"r0"); \ - asm volatile("mov r0, #0":::"r0"); \ - asm volatile("mov r0, #0":::"r0"); \ - asm volatile("bl wolfBoot_get_image_version"); \ - asm volatile("mov r4, r0":::"r4"); \ - asm volatile("mov r4, r0":::"r4"); \ - asm volatile("mov r4, r0":::"r4"); \ - asm volatile("mov r0, #0":::"r0"); \ - asm volatile("mov r0, #0":::"r0"); \ - asm volatile("mov r0, #0":::"r0"); \ - asm volatile("bl wolfBoot_get_image_version"); \ - asm volatile("mov r6, r0":::"r6"); \ - asm volatile("mov r6, r0":::"r6"); \ - asm volatile("mov r6, r0":::"r6"); \ - asm volatile("cmp r4, r6":::"cc"); \ - asm volatile("bne ."); \ - asm volatile("cmp r4, r6":::"cc"); \ - asm volatile("bne .-4"); \ - asm volatile("cmp r4, r6":::"cc"); \ - asm volatile("bne .-8"); \ - asm volatile("cmp r4, r6":::"cc"); \ - asm volatile("bne .-12"); \ - asm volatile("mov r0, #0":::"r0"); \ - asm volatile("mov r0, #0":::"r0"); \ - asm volatile("mov r0, #0":::"r0"); \ - /* Compare the two versions in registries */ \ - asm volatile("cmp r4, r5":::"cc"); \ - asm volatile("bge ."); \ - asm volatile("cmp r6, r7":::"cc"); \ - asm volatile("bge .-4"); \ - asm volatile("cmp r4, r5":::"cc"); \ - asm volatile("bge .-8"); \ - asm volatile("cmp r6, r7":::"cc"); \ - asm volatile("bge .-12"); \ - asm volatile("end_check:"); \ - /* Restore previously saved registry values */ \ - asm volatile("pop {r4, r5, r6, r7}":::"r4", "r5", "r6", "r7") + asm volatile( \ + "push {r4, r5, r6, r7}\n" \ + "mov r0, #0\n" \ + "mov r4, #1\n" \ + "mov r5, #0\n" \ + "mov r6, #2\n" \ + "mov r7, #0\n" \ + "mov r0, #0\n" \ + "mov r4, #1\n" \ + "mov r5, #0\n" \ + "mov r6, #2\n" \ + "mov r7, #0\n" \ + "mov r0, %0\n" \ + "mov r4, %0\n" \ + "cmp r0, #1\n" \ + "cmp r0, #1\n" \ + "cmp r0, #1\n" \ + "beq 20f\n" \ + "bne do_check\n" \ + "bne do_check\n" \ + "bne do_check\n" \ + "bne do_check\n" \ + "b .\n" \ + "b .\n" \ + "b .\n" \ + "20:\n" \ + "cmp r4, #1\n" \ + "cmp r4, #1\n" \ + "cmp r4, #1\n" \ + "beq 21f\n" \ + "bne do_check\n" \ + "bne do_check\n" \ + "bne do_check\n" \ + "bne do_check\n" \ + "b .\n" \ + "b .\n" \ + "b .\n" \ + "21:\n" \ + "cmp r0, r4\n" \ + "cmp r0, r4\n" \ + "cmp r0, r4\n" \ + "beq 22f\n" \ + "bne do_check\n" \ + "bne do_check\n" \ + "bne do_check\n" \ + "bne do_check\n" \ + "b .\n" \ + "b .\n" \ + "b .\n" \ + "22:\n" \ + "cmp r0, #1\n" \ + "cmp r0, #1\n" \ + "cmp r0, #1\n" \ + "beq 23f\n" \ + "bne do_check\n" \ + "bne do_check\n" \ + "bne do_check\n" \ + "bne do_check\n" \ + "b .\n" \ + "b .\n" \ + "b .\n" \ + "23:\n" \ + "b end_check\n" \ + "do_check:\n" \ + "mov r0, #1\n" \ + "mov r0, #1\n" \ + "mov r0, #1\n" \ + "bl wolfBoot_get_image_version\n" \ + "mov r5, r0\n" \ + "mov r5, r0\n" \ + "mov r5, r0\n" \ + "mov r0, #1\n" \ + "mov r0, #1\n" \ + "mov r0, #1\n" \ + "bl wolfBoot_get_image_version\n" \ + "mov r7, r0\n" \ + "mov r7, r0\n" \ + "mov r7, r0\n" \ + "cmp r5, r7\n" \ + "cmp r5, r7\n" \ + "cmp r5, r7\n" \ + "beq 24f\n" \ + "bne ver_panic\n" \ + "bne ver_panic\n" \ + "bne ver_panic\n" \ + "bne ver_panic\n" \ + "b .\n" \ + "b .\n" \ + "b .\n" \ + "24:\n" \ + "mov r0, #0\n" \ + "mov r0, #0\n" \ + "mov r0, #0\n" \ + "bl wolfBoot_get_image_version\n" \ + "mov r4, r0\n" \ + "mov r4, r0\n" \ + "mov r4, r0\n" \ + "mov r0, #0\n" \ + "mov r0, #0\n" \ + "mov r0, #0\n" \ + "bl wolfBoot_get_image_version\n" \ + "mov r6, r0\n" \ + "mov r6, r0\n" \ + "mov r6, r0\n" \ + "cmp r4, r6\n" \ + "cmp r4, r6\n" \ + "cmp r4, r6\n" \ + "beq 25f\n" \ + "bne ver_panic\n" \ + "bne ver_panic\n" \ + "bne ver_panic\n" \ + "bne ver_panic\n" \ + "b .\n" \ + "b .\n" \ + "b .\n" \ + "25:\n" \ + "mov r0, #0\n" \ + "mov r0, #0\n" \ + "mov r0, #0\n" \ + "cmp r4, r5\n" \ + "cmp r4, r5\n" \ + "cmp r4, r5\n" \ + "blo 26f\n" \ + "bhs ver_panic\n" \ + "bhs ver_panic\n" \ + "bhs ver_panic\n" \ + "bhs ver_panic\n" \ + "b .\n" \ + "b .\n" \ + "b .\n" \ + "26:\n" \ + "cmp r6, r7\n" \ + "cmp r6, r7\n" \ + "cmp r6, r7\n" \ + "blo 27f\n" \ + "bhs ver_panic\n" \ + "bhs ver_panic\n" \ + "bhs ver_panic\n" \ + "bhs ver_panic\n" \ + "b .\n" \ + "b .\n" \ + "b .\n" \ + "27:\n" \ + "cmp r4, r5\n" \ + "cmp r4, r5\n" \ + "cmp r4, r5\n" \ + "blo 28f\n" \ + "bhs ver_panic\n" \ + "bhs ver_panic\n" \ + "bhs ver_panic\n" \ + "bhs ver_panic\n" \ + "b .\n" \ + "b .\n" \ + "b .\n" \ + "28:\n" \ + "cmp r6, r7\n" \ + "cmp r6, r7\n" \ + "cmp r6, r7\n" \ + "blo 29f\n" \ + "bhs ver_panic\n" \ + "bhs ver_panic\n" \ + "bhs ver_panic\n" \ + "bhs ver_panic\n" \ + "b .\n" \ + "b .\n" \ + "b .\n" \ + "29:\n" \ + "b end_check\n" \ + "ver_panic:\n" \ + "b .\n" \ + "b .\n" \ + "b .\n" \ + "b .\n" \ + "b .\n" \ + "b .\n" \ + "b .\n" \ + "b .\n" \ + "b .\n" \ + "b .\n" \ + "b .\n" \ + "end_check:\n" \ + "pop {r4, r5, r6, r7}\n" \ + : \ + : "r"(fb_ok) \ + : "r0", "r4", "r5", "r6", "r7", "lr", "cc", "memory" \ + ) #elif defined(__ICCARM__) && defined(__IAR_SYSTEMS_ICC__) @@ -612,13 +926,107 @@ static void __attribute__((noinline)) wolfBoot_image_clear_signature_ok( "mov r6, #2\n" \ "mov r7, #0\n" \ "mov r0, %0\n" \ + "mov r4, %0\n" \ + "cmp r0, #0\n" \ + "cmp r0, #0\n" \ + "cmp r0, #0\n" \ + "beq 4f\n" \ + "bne 6f\n" \ + "bne 6f\n" \ + "bne 6f\n" \ + "bne 6f\n" \ + "b .\n" \ + "b .\n" \ + "b .\n" \ + "6:\n" \ + "cmp r0, #1\n" \ + "cmp r0, #1\n" \ "cmp r0, #1\n" \ + "beq 4f\n" \ + "bne 1f\n" \ + "bne 1f\n" \ + "bne 1f\n" \ + "bne 1f\n" \ + "b .\n" \ + "b .\n" \ + "b .\n" \ + "4:\n" \ + "cmp r4, #0\n" \ + "cmp r4, #0\n" \ + "cmp r4, #0\n" \ + "beq 5f\n" \ + "bne 7f\n" \ + "bne 7f\n" \ + "bne 7f\n" \ + "bne 7f\n" \ + "b .\n" \ + "b .\n" \ + "b .\n" \ + "7:\n" \ + "cmp r4, #1\n" \ + "cmp r4, #1\n" \ + "cmp r4, #1\n" \ + "beq 5f\n" \ + "bne 1f\n" \ + "bne 1f\n" \ "bne 1f\n" \ + "bne 1f\n" \ + "b .\n" \ + "b .\n" \ + "b .\n" \ + "5:\n" \ + "cmp r0, #1\n" \ + "cmp r0, #1\n" \ "cmp r0, #1\n" \ + "beq 8f\n" \ + "bne 1f\n" \ + "bne 1f\n" \ + "bne 1f\n" \ + "bne 1f\n" \ + "b .\n" \ + "b .\n" \ + "b .\n" \ + "8:\n" \ + "cmp r4, #1\n" \ + "cmp r4, #1\n" \ + "cmp r4, #1\n" \ + "beq 9f\n" \ + "bne 1f\n" \ + "bne 1f\n" \ + "bne 1f\n" \ + "bne 1f\n" \ + "b .\n" \ + "b .\n" \ + "b .\n" \ + "9:\n" \ + "cmp r0, r4\n" \ + "cmp r0, r4\n" \ + "cmp r0, r4\n" \ + "beq 10f\n" \ + "bne 1f\n" \ "bne 1f\n" \ + "bne 1f\n" \ + "bne 1f\n" \ + "b .\n" \ + "b .\n" \ + "b .\n" \ + "10:\n" \ + "cmp r0, #1\n" \ "cmp r0, #1\n" \ + "cmp r0, #1\n" \ + "beq 11f\n" \ + "bne 1f\n" \ + "bne 1f\n" \ "bne 1f\n" \ + "bne 1f\n" \ + "b .\n" \ + "b .\n" \ + "b .\n" \ + "11:\n" \ "b 2f\n" \ + "b .\n" \ + "b .\n" \ + "b .\n" \ "1:\n" \ "mov r0, #1\n" \ "mov r0, #1\n" \ @@ -635,13 +1043,17 @@ static void __attribute__((noinline)) wolfBoot_image_clear_signature_ok( "mov r7, r0\n" \ "mov r7, r0\n" \ "cmp r5, r7\n" \ - "bne .\n" \ - "cmp r5, r7\n" \ - "bne .-4\n" \ "cmp r5, r7\n" \ - "bne .-8\n" \ "cmp r5, r7\n" \ - "bne .-12\n" \ + "beq 12f\n" \ + "bne 3f\n" \ + "bne 3f\n" \ + "bne 3f\n" \ + "bne 3f\n" \ + "b .\n" \ + "b .\n" \ + "b .\n" \ + "12:\n" \ "mov r0, #0\n" \ "mov r0, #0\n" \ "mov r0, #0\n" \ @@ -657,24 +1069,81 @@ static void __attribute__((noinline)) wolfBoot_image_clear_signature_ok( "mov r6, r0\n" \ "mov r6, r0\n" \ "cmp r4, r6\n" \ - "bne .\n" \ - "cmp r4, r6\n" \ - "bne .-4\n" \ "cmp r4, r6\n" \ - "bne .-8\n" \ "cmp r4, r6\n" \ - "bne .-12\n" \ + "beq 13f\n" \ + "bne 3f\n" \ + "bne 3f\n" \ + "bne 3f\n" \ + "bne 3f\n" \ + "b .\n" \ + "b .\n" \ + "b .\n" \ + "13:\n" \ "mov r0, #0\n" \ "mov r0, #0\n" \ "mov r0, #0\n" \ "cmp r4, r5\n" \ - "bge .\n" \ + "cmp r4, r5\n" \ + "cmp r4, r5\n" \ + "blo 14f\n" \ + "bhs 3f\n" \ + "bhs 3f\n" \ + "bhs 3f\n" \ + "bhs 3f\n" \ + "b .\n" \ + "b .\n" \ + "b .\n" \ + "14:\n" \ + "cmp r6, r7\n" \ "cmp r6, r7\n" \ - "bge .-4\n" \ + "cmp r6, r7\n" \ + "blo 15f\n" \ + "bhs 3f\n" \ + "bhs 3f\n" \ + "bhs 3f\n" \ + "bhs 3f\n" \ + "b .\n" \ + "b .\n" \ + "b .\n" \ + "15:\n" \ + "cmp r4, r5\n" \ + "cmp r4, r5\n" \ "cmp r4, r5\n" \ - "bge .-8\n" \ + "blo 16f\n" \ + "bhs 3f\n" \ + "bhs 3f\n" \ + "bhs 3f\n" \ + "bhs 3f\n" \ + "b .\n" \ + "b .\n" \ + "b .\n" \ + "16:\n" \ "cmp r6, r7\n" \ - "bge .-12\n" \ + "cmp r6, r7\n" \ + "cmp r6, r7\n" \ + "blo 17f\n" \ + "bhs 3f\n" \ + "bhs 3f\n" \ + "bhs 3f\n" \ + "bhs 3f\n" \ + "b .\n" \ + "b .\n" \ + "b .\n" \ + "17:\n" \ + "b 2f\n" \ + "b .\n" \ + "b .\n" \ + "b .\n" \ + "3:\n" \ + "b .\n" \ + "b .\n" \ + "b .\n" \ + "b .\n" \ + "b .\n" \ + "b .\n" \ + "b .\n" \ + "b .\n" \ "2:\n" \ "pop {r4, r5, r6, r7}\n" \ : /* No output operands */ \ @@ -696,6 +1165,8 @@ static void __attribute__((noinline)) wolfBoot_image_clear_signature_ok( asm volatile("movs r0, #1":::"cc"); \ asm volatile("lsls r0, r1":::"r0","cc"); \ asm volatile("cmp r0, r2"); \ + asm volatile("cmp r0, r2"); \ + asm volatile("cmp r0, r2"); \ asm volatile("bne ."); \ asm volatile("mov r0, %0" :: "r"(mask)); \ asm volatile("movs r2, #1":::"r2"); \ @@ -704,6 +1175,8 @@ static void __attribute__((noinline)) wolfBoot_image_clear_signature_ok( asm volatile("movs r0, #1":::"r0"); \ asm volatile("lsls r0, r1":::"r0", "cc"); \ asm volatile("cmp r0, r2":::"cc"); \ + asm volatile("cmp r0, r2":::"cc"); \ + asm volatile("cmp r0, r2":::"cc"); \ asm volatile("bne ."); \ asm volatile("mov r0, %0" :: "r"(mask):"r0"); \ asm volatile("movs r2, #1":::"r2"); \ @@ -712,6 +1185,8 @@ static void __attribute__((noinline)) wolfBoot_image_clear_signature_ok( asm volatile("movs r0, #1":::"r0"); \ asm volatile("lsls r0, r1":::"r0", "cc"); \ asm volatile("cmp r0, r2":::"cc"); \ + asm volatile("cmp r0, r2":::"cc"); \ + asm volatile("cmp r0, r2":::"cc"); \ asm volatile("bne ."); \ #else diff --git a/src/image.c b/src/image.c index a3ce62cfc0..7e301e59f3 100644 --- a/src/image.c +++ b/src/image.c @@ -803,6 +803,26 @@ static void wolfBoot_verify_signature_ml_dsa(uint8_t key_slot, img->sha_hash, WOLFBOOT_SHA_DIGEST_SIZE, &verify_res); + #ifdef WOLFBOOT_ARMORED + if (ret == 0) { + uint32_t v = (uint32_t)verify_res; + uint32_t v_inv = ~v; + if ((v == 1U) && (v_inv == 0xFFFFFFFEU) && + (v == (uint32_t)verify_res) && + (v_inv == ~(uint32_t)verify_res)) { + wolfBoot_printf("info: wc_MlDsaKey_Verify returned OK\n"); + wolfBoot_image_confirm_signature_ok(img); + } + else { + wolfBoot_printf("error: wc_MlDsaKey_Verify returned: ret=%d, " + "res=%d\n", ret, verify_res); + } + } + else { + wolfBoot_printf("error: wc_MlDsaKey_Verify returned: ret=%d, " + "res=%d\n", ret, verify_res); + } + #else if (ret == 0 && verify_res == 1) { wolfBoot_printf("info: wc_MlDsaKey_Verify returned OK\n"); wolfBoot_image_confirm_signature_ok(img); @@ -811,6 +831,7 @@ static void wolfBoot_verify_signature_ml_dsa(uint8_t key_slot, wolfBoot_printf("error: wc_MlDsaKey_Verify returned: ret=%d, " "res=%d\n", ret, verify_res); } + #endif } wc_MlDsaKey_Free(&ml_dsa); @@ -2150,8 +2171,15 @@ int wolfBoot_verify_authenticity(struct wolfBoot_image *img) wolfBoot_verify_signature_primary(key_slot, img, stored_signature); (void)stored_signature_size; +#ifdef WOLFBOOT_ARMORED +#define SIG_OK(imgp) (((imgp)->signature_ok == 1) && \ + ((imgp)->not_signature_ok == ~(uint32_t)1)) +#else +#define SIG_OK(imgp) ((imgp)->signature_ok == 1) +#endif + #ifdef SIGN_HYBRID - if (img->signature_ok == 1) { + if (SIG_OK(img)) { uint8_t *stored_secondary_signature; uint16_t stored_secondary_signature_size; /* Invalidate the signature_ok flag */ @@ -2177,10 +2205,11 @@ int wolfBoot_verify_authenticity(struct wolfBoot_image *img) } } #endif - if (img->signature_ok == 1) { + if (SIG_OK(img)) { return 0; } return -2; +#undef SIG_OK } #endif diff --git a/src/update_flash.c b/src/update_flash.c index b51f400a97..45c7109aee 100644 --- a/src/update_flash.c +++ b/src/update_flash.c @@ -686,6 +686,11 @@ static int RAMFUNCTION wolfBoot_update(int fallback_allowed) int inverse = 0; #endif int fallback_image = 0; +#ifndef DISABLE_BACKUP + int rollback_needed = 0; + int bootStateRet = -1; + uint8_t bootState = 0; +#endif #if defined(DISABLE_BACKUP) && defined(EXT_ENCRYPTED) uint8_t key[ENCRYPT_KEY_SIZE]; uint8_t nonce[ENCRYPT_NONCE_SIZE]; @@ -748,6 +753,13 @@ static int RAMFUNCTION wolfBoot_update(int fallback_allowed) cur_ver = wolfBoot_current_firmware_version(); upd_ver = wolfBoot_update_firmware_version(); +#ifndef DISABLE_BACKUP + bootStateRet = wolfBoot_get_partition_state(PART_BOOT, &bootState); + if ((bootStateRet == 0) && (bootState == IMG_STATE_TESTING) && + (fallback_allowed != 0) && (cur_ver >= upd_ver)) { + rollback_needed = 1; + } +#endif wolfBoot_get_update_sector_flag(0, &flag); /* Check the first sector to detect interrupted update */ @@ -787,11 +799,12 @@ static int RAMFUNCTION wolfBoot_update(int fallback_allowed) cur_ver, upd_ver); #ifndef ALLOW_DOWNGRADE - if ( ((fallback_allowed==1) && - (~(uint32_t)fallback_allowed == 0xFFFFFFFE)) || - (cur_ver < upd_ver) ) { - VERIFY_VERSION_ALLOWED(fallback_allowed); - } else { + { + uint32_t fb_ok = (fallback_allowed == 1); + VERIFY_VERSION_ALLOWED(fb_ok); + (void)fb_ok; + } + if ((fallback_allowed == 0) && (cur_ver >= upd_ver)) { wolfBoot_printf("Update version not allowed\n"); return -1; } @@ -973,6 +986,19 @@ static int RAMFUNCTION wolfBoot_update(int fallback_allowed) /* start re-entrant final erase, return code is only for resumption in * wolfBoot_start */ wolfBoot_swap_and_final_erase(0); +#ifndef DISABLE_BACKUP + if (rollback_needed) { + hal_flash_unlock(); +#ifdef EXT_FLASH + ext_flash_unlock(); +#endif + wolfBoot_set_partition_state(PART_BOOT, IMG_STATE_SUCCESS); +#ifdef EXT_FLASH + ext_flash_lock(); +#endif + hal_flash_lock(); + } +#endif #else /* Mark boot partition as TESTING - this tells bootloader to fallback if update fails */ wolfBoot_set_partition_state(PART_BOOT, IMG_STATE_TESTING); @@ -1201,13 +1227,27 @@ void RAMFUNCTION wolfBoot_start(void) #if !defined(DISABLE_BACKUP) && !defined(CUSTOM_PARTITION_TRAILER) /* resume the final erase in case the power failed before it finished */ resumedFinalErase = wolfBoot_swap_and_final_erase(1); - if (resumedFinalErase != 0) + if ((resumedFinalErase != 0) || + ((bootRet == 0) && (bootState == IMG_STATE_TESTING))) #endif { /* Check if the BOOT partition is still in TESTING, * to trigger fallback. */ if ((bootRet == 0) && (bootState == IMG_STATE_TESTING)) { + if (updateRet != 0) { + 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(); + updateRet = 0; + updateState = IMG_STATE_UPDATING; + } wolfBoot_update(1); } diff --git a/tools/test.mk b/tools/test.mk index ff91bd80c9..0670301a76 100644 --- a/tools/test.mk +++ b/tools/test.mk @@ -1013,40 +1013,40 @@ test-all: clean test-size-all: - make test-size SIGN=NONE LIMIT=4896 NO_ARM_ASM=1 + make test-size SIGN=NONE LIMIT=5040 NO_ARM_ASM=1 make keysclean - make test-size SIGN=ED25519 LIMIT=11548 NO_ARM_ASM=1 + make test-size SIGN=ED25519 LIMIT=11696 NO_ARM_ASM=1 make keysclean - make test-size SIGN=ECC256 LIMIT=18656 NO_ARM_ASM=1 + make test-size SIGN=ECC256 LIMIT=18944 NO_ARM_ASM=1 make clean - make test-size SIGN=ECC256 NO_ASM=1 LIMIT=13700 NO_ARM_ASM=1 + make test-size SIGN=ECC256 NO_ASM=1 LIMIT=13840 NO_ARM_ASM=1 make keysclean - make test-size SIGN=RSA2048 LIMIT=11396 NO_ARM_ASM=1 + make test-size SIGN=RSA2048 LIMIT=11536 NO_ARM_ASM=1 make clean - make test-size SIGN=RSA2048 NO_ASM=1 LIMIT=11976 NO_ARM_ASM=1 + make test-size SIGN=RSA2048 NO_ASM=1 LIMIT=12128 NO_ARM_ASM=1 make keysclean - make test-size SIGN=RSA4096 LIMIT=11680 NO_ARM_ASM=1 + make test-size SIGN=RSA4096 LIMIT=11824 NO_ARM_ASM=1 make clean - make test-size SIGN=RSA4096 NO_ASM=1 LIMIT=12260 NO_ARM_ASM=1 + make test-size SIGN=RSA4096 NO_ASM=1 LIMIT=12400 NO_ARM_ASM=1 make keysclean - make test-size SIGN=ECC384 LIMIT=18616 NO_ARM_ASM=1 + make test-size SIGN=ECC384 LIMIT=19888 NO_ARM_ASM=1 make clean - make test-size SIGN=ECC384 NO_ASM=1 LIMIT=15076 NO_ARM_ASM=1 + make test-size SIGN=ECC384 NO_ASM=1 LIMIT=15216 NO_ARM_ASM=1 make keysclean - make test-size SIGN=ED448 LIMIT=13616 NO_ARM_ASM=1 + make test-size SIGN=ED448 LIMIT=13760 NO_ARM_ASM=1 make keysclean - make test-size SIGN=RSA3072 LIMIT=11536 NO_ARM_ASM=1 + make test-size SIGN=RSA3072 LIMIT=11680 NO_ARM_ASM=1 make clean - make test-size SIGN=RSA3072 NO_ASM=1 LIMIT=12080 NO_ARM_ASM=1 + make test-size SIGN=RSA3072 NO_ASM=1 LIMIT=12224 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=7620 NO_ARM_ASM=1 + IMAGE_HEADER_SIZE?=5288 LIMIT=7696 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=8408 NO_ARM_ASM=1 + LIMIT=8560 NO_ARM_ASM=1 make keysclean make clean - make test-size SIGN=ML_DSA ML_DSA_LEVEL=2 LIMIT=19246 \ - IMAGE_SIGNATURE_SIZE=2420 IMAGE_HEADER_SIZE?=8192 + make test-size SIGN=ML_DSA ML_DSA_LEVEL=2 LIMIT=19392 \ + IMAGE_SIGNATURE_SIZE=2420 IMAGE_HEADER_SIZE?=8192