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 support for Armored mode with IAR #540

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
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
6 changes: 3 additions & 3 deletions IDE/IAR/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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.
2 changes: 1 addition & 1 deletion IDE/IAR/sign_test_app.bat
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
158 changes: 155 additions & 3 deletions include/image.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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"); \
Expand Down Expand Up @@ -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.
Expand All @@ -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}"); \
Expand Down Expand Up @@ -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 */ \
Expand Down
19 changes: 14 additions & 5 deletions src/update_flash.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
Expand Down Expand Up @@ -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();
Expand All @@ -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();
Expand Down Expand Up @@ -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
8 changes: 4 additions & 4 deletions tools/test-renode.mk
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
8 changes: 4 additions & 4 deletions tools/test.mk
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Loading