diff --git a/IDE/IAR/README.md b/IDE/IAR/README.md index 0e3e09f89..587fb28a9 100644 --- a/IDE/IAR/README.md +++ b/IDE/IAR/README.md @@ -33,11 +33,10 @@ ST-Link utilities (e.g. [STSW-LINK004](https://www.st.com/en/development-tools/s This step is required to compile the bootloader. -Open a command line terminal in the [IAR](./) directory. Execute the following script: +Open a command line terminal in the [IDE/IAR](./) directory. Execute the following script: ``` generate_key.bat - ``` The script will generate a keypair. The file `wolfboot_signing_private_key.der` in the root of the repository contains the private key that will be used @@ -90,5 +89,6 @@ Using the ST-LINK Utility, perform the following steps: If you are using a STM32F407-discovery board, a red LED will turn on upon application boot. +## Armored Mode (Glitch Resistance) - +If you would like to enable the "Armored" mode (glitch resistance) in IAR you can set the compiler pre-processor macro `WOLFBOOT_ARMORED`. Note: This has only been tested with ECDSA on Cortex-M. \ No newline at end of file diff --git a/IDE/IAR/sign_test_app.bat b/IDE/IAR/sign_test_app.bat index 6a74fd764..d31f44e09 100644 --- a/IDE/IAR/sign_test_app.bat +++ b/IDE/IAR/sign_test_app.bat @@ -2,7 +2,7 @@ echo off if "%~1"=="" goto fail -keytools\sign.exe --ecc256 --sha256 Debug\Exe\wolfboot-test-app.bin wolfboot_signing_private_key.der %1 +keytools\sign.exe --ecc256 --sha256 Debug\Exe\wolfboot-test-app.bin ..\..\wolfboot_signing_private_key.der %1 goto out diff --git a/include/image.h b/include/image.h index a63bcda0d..eab349ed2 100644 --- a/include/image.h +++ b/include/image.h @@ -168,13 +168,18 @@ int wolfBot_get_dts_size(void *dts_addr); #if (defined(WOLFBOOT_ARMORED) && defined(__WOLFBOOT)) - -#if !defined(ARCH_ARM) || !defined(__GNUC__) -# error WOLFBOOT_ARMORED only available with arm-gcc compiler +#if !defined(ARCH_ARM) || (!defined(__GNUC__) && \ + !(defined(__ICCARM__) && defined(__IAR_SYSTEMS_ICC__))) +# error WOLFBOOT_ARMORED only available for ARM with IAR or gcc compilers #endif +#if defined(__GNUC__) #define likely(x) __builtin_expect((x),1) #define unlikely(x) __builtin_expect((x),0) +#else +#define likely(x) (x) +#define unlikely(x) (x) +#endif struct wolfBoot_image { uint8_t *hdr; @@ -434,6 +439,8 @@ static void __attribute__((noinline)) wolfBoot_image_clear_signature_ok( * * Double check by reading the value in p_res from memory a few times. */ +#if defined(__GNUC__) + #define VERIFY_FN(img,p_res,fn,...) \ /* Redundant set of r0=50*/ \ asm volatile("mov r0, #50":::"r0"); \ @@ -468,6 +475,59 @@ static void __attribute__((noinline)) wolfBoot_image_clear_signature_ok( asm volatile("nope:"); \ asm volatile("nop") +#elif defined(__ICCARM__) && defined(__IAR_SYSTEMS_ICC__) + +#define VERIFY_FN(img, p_res, fn, ...) \ + do { \ + __asm volatile( \ + "mov r0, #50\n" \ + "mov r0, #50\n" \ + "mov r0, #50\n" \ + : /* No output operands */ \ + : /* No input operands */ \ + : "r0" /* Clobbered registers */ \ + ); \ + void (*confirm_func)(struct wolfBoot_image *) = \ + wolfBoot_image_confirm_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" \ + "bne 1f\n" \ + "cmp r0, #0\n" \ + "bne 1f\n" \ + "ldr r2, [%0]\n" \ + "cmp r2, #1\n" \ + "bne 1f\n" \ + "ldr r2, [%0]\n" \ + "cmp r2, #1\n" \ + "bne 1f\n" \ + "ldr r2, [%0]\n" \ + "cmp r2, #1\n" \ + "bne 1f\n" \ + "ldr r2, [%0]\n" \ + "cmp r2, #1\n" \ + "bne 1f\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" \ + "1:\n" \ + "nop\n" \ + "2:\n" \ + : /* No output operands */ \ + : "r"(p_res), "r"(img), "r"(confirm_func) /* Input operands */ \ + : "r0", "r2", "lr" /* Clobbered registers */ \ + ); \ + } while (0) +#endif + + /** * This macro is only invoked after a successful update version check, prior to * initiating the update installation. @@ -486,6 +546,8 @@ static void __attribute__((noinline)) wolfBoot_image_clear_signature_ok( * version is not strictly greater than the current one. * */ +#if defined(__GNUC__) + #define VERIFY_VERSION_ALLOWED(fb_ok) \ /* Stash the registry values */ \ asm volatile("push {r4, r5, r6, r7}"); \ @@ -575,6 +637,96 @@ static void __attribute__((noinline)) wolfBoot_image_clear_signature_ok( /* Restore previously saved registry values */ \ asm volatile("pop {r4, r5, r6, r7}":::"r4", "r5", "r6", "r7") +#elif defined(__ICCARM__) && defined(__IAR_SYSTEMS_ICC__) + +#define VERIFY_VERSION_ALLOWED(fb_ok) \ + do { \ + __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" \ + "cmp r0, #1\n" \ + "bne 1f\n" \ + "cmp r0, #1\n" \ + "bne 1f\n" \ + "cmp r0, #1\n" \ + "bne 1f\n" \ + "b 2f\n" \ + "1:\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" \ + "bne .\n" \ + "cmp r5, r7\n" \ + "bne .-4\n" \ + "cmp r5, r7\n" \ + "bne .-8\n" \ + "cmp r5, r7\n" \ + "bne .-12\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" \ + "bne .\n" \ + "cmp r4, r6\n" \ + "bne .-4\n" \ + "cmp r4, r6\n" \ + "bne .-8\n" \ + "cmp r4, r6\n" \ + "bne .-12\n" \ + "mov r0, #0\n" \ + "mov r0, #0\n" \ + "mov r0, #0\n" \ + "cmp r4, r5\n" \ + "bge .\n" \ + "cmp r6, r7\n" \ + "bge .-4\n" \ + "cmp r4, r5\n" \ + "bge .-8\n" \ + "cmp r6, r7\n" \ + "bge .-12\n" \ + "2:\n" \ + "pop {r4, r5, r6, r7}\n" \ + : /* No output operands */ \ + : "r"(fb_ok) /* Input operands */ \ + : "r0", "r4", "r5", "r6", "r7" /* Clobbered registers */ \ + ); \ + } while (0) +#endif + + #define CONFIRM_MASK_VALID(id, mask) \ asm volatile("mov r1, %0" :: "r"(id):"r1"); \ /* id &= 0x0F */ \ diff --git a/src/update_flash.c b/src/update_flash.c index 914b0b483..a9e3fc8fe 100644 --- a/src/update_flash.c +++ b/src/update_flash.c @@ -513,8 +513,12 @@ static int wolfBoot_delta_update(struct wolfBoot_image *boot, #ifdef WOLFBOOT_ARMORED -# pragma GCC push_options -# pragma GCC optimize("O0") +# ifdef __GNUC__ +# pragma GCC push_options +# pragma GCC optimize("O0") +# elif defined(__IAR_SYSTEMS_ICC__) +# pragma optimize=none +# endif #endif /* Reserve space for two sectors in case of NVM_FLASH_WRITEONCE, for redundancy */ @@ -946,7 +950,7 @@ void RAMFUNCTION wolfBoot_start(void) wolfBoot_check_self_update(); #endif -#ifdef NVM_FLASH_WRITEONCE +#ifdef NVM_FLASH_WRITEONCE /* nvm_select_fresh_sector needs unlocked flash in cases where the unused * sector needs to be erased */ hal_flash_unlock(); @@ -958,7 +962,7 @@ void RAMFUNCTION wolfBoot_start(void) bootRet = wolfBoot_get_partition_state(PART_BOOT, &bootState); updateRet = wolfBoot_get_partition_state(PART_UPDATE, &updateState); -#ifdef NVM_FLASH_WRITEONCE +#ifdef NVM_FLASH_WRITEONCE hal_flash_lock(); #ifdef EXT_FLASH ext_flash_lock(); @@ -1034,6 +1038,11 @@ void RAMFUNCTION wolfBoot_start(void) hal_prepare_boot(); do_boot((void *)boot.fw_base); } + #ifdef WOLFBOOT_ARMORED -# pragma GCC pop_options +# ifdef __GNUC__ +# pragma GCC pop_options +# elif defined(__IAR_SYSTEMS_ICC__) +# pragma optimize=default +# endif #endif diff --git a/tools/test-renode.mk b/tools/test-renode.mk index 195a63f31..dca27c94e 100644 --- a/tools/test-renode.mk +++ b/tools/test-renode.mk @@ -25,15 +25,15 @@ XMSS_OPTS=WOLFBOOT_XMSS_PARAMS='XMSS-SHA2_10_256' WOLFBOOT_SMALL_STACK=0 \ IMAGE_SIGNATURE_SIZE=2500 IMAGE_HEADER_SIZE=5000 ifneq ("$(wildcard $(WOLFBOOT_ROOT)/tools/keytools/keygen.exe)","") - KEYGEN_TOOL?=$(WOLFBOOT_ROOT)/tools/keytools/keygen.exe + KEYGEN_TOOL?="$(WOLFBOOT_ROOT)/tools/keytools/keygen.exe" else - KEYGEN_TOOL?=$(WOLFBOOT_ROOT)/tools/keytools/keygen + KEYGEN_TOOL?="$(WOLFBOOT_ROOT)/tools/keytools/keygen" endif ifneq ("$(wildcard $(WOLFBOOT_ROOT)/tools/keytools/sign.exe)","") - SIGN_TOOL?=$(WOLFBOOT_ROOT)/tools/keytools/sign.exe + SIGN_TOOL?="$(WOLFBOOT_ROOT)/tools/keytools/sign.exe" else - SIGN_TOOL?=$(WOLFBOOT_ROOT)/tools/keytools/sign + SIGN_TOOL?="$(WOLFBOOT_ROOT)/tools/keytools/sign" endif ifeq ($(TARGET),stm32f7) diff --git a/tools/test.mk b/tools/test.mk index 2b5638376..19672a883 100644 --- a/tools/test.mk +++ b/tools/test.mk @@ -10,15 +10,15 @@ SIGN_ENC_ARGS= DELTA_DATA_SIZE?=2000 ifneq ("$(wildcard $(WOLFBOOT_ROOT)/tools/keytools/keygen.exe)","") - KEYGEN_TOOL=$(WOLFBOOT_ROOT)/tools/keytools/keygen.exe + KEYGEN_TOOL="$(WOLFBOOT_ROOT)/tools/keytools/keygen.exe" else - KEYGEN_TOOL=$(WOLFBOOT_ROOT)/tools/keytools/keygen + KEYGEN_TOOL="$(WOLFBOOT_ROOT)/tools/keytools/keygen" endif ifneq ("$(wildcard $(WOLFBOOT_ROOT)/tools/keytools/sign.exe)","") - SIGN_TOOL=$(WOLFBOOT_ROOT)/tools/keytools/sign.exe + SIGN_TOOL="$(WOLFBOOT_ROOT)/tools/keytools/sign.exe" else - SIGN_TOOL=$(WOLFBOOT_ROOT)/tools/keytools/sign + SIGN_TOOL="$(WOLFBOOT_ROOT)/tools/keytools/sign" endif # Make sign algorithm argument