diff --git a/config/examples/stm32h5-tz-dualbank-otp-lms.config b/config/examples/stm32h5-tz-dualbank-otp-lms.config index 7f76f6af3d..7ffe9ccd20 100644 --- a/config/examples/stm32h5-tz-dualbank-otp-lms.config +++ b/config/examples/stm32h5-tz-dualbank-otp-lms.config @@ -21,7 +21,7 @@ DUALBANK_SWAP?=1 WOLFBOOT_PARTITION_SIZE?=0xA0000 WOLFBOOT_SECTOR_SIZE?=0x2000 WOLFBOOT_PARTITION_BOOT_ADDRESS?=0x08060000 -WOLFBOOT_PARTITION_UPDATE_ADDRESS?=0x08160000 +WOLFBOOT_PARTITION_UPDATE_ADDRESS?=0x0C160000 WOLFBOOT_PARTITION_SWAP_ADDRESS?=0xFFFFFFFF FLAGS_HOME=0 DISABLE_BACKUP=0 diff --git a/config/examples/stm32h5-tz-dualbank-otp.config b/config/examples/stm32h5-tz-dualbank-otp.config index b09b08fbae..af7421eff7 100644 --- a/config/examples/stm32h5-tz-dualbank-otp.config +++ b/config/examples/stm32h5-tz-dualbank-otp.config @@ -21,7 +21,7 @@ DUALBANK_SWAP?=1 WOLFBOOT_PARTITION_SIZE?=0xA0000 WOLFBOOT_SECTOR_SIZE?=0x2000 WOLFBOOT_PARTITION_BOOT_ADDRESS?=0x08060000 -WOLFBOOT_PARTITION_UPDATE_ADDRESS?=0x08160000 +WOLFBOOT_PARTITION_UPDATE_ADDRESS?=0x0C160000 WOLFBOOT_PARTITION_SWAP_ADDRESS?=0xFFFFFFFF FLAGS_HOME=0 DISABLE_BACKUP=0 diff --git a/config/examples/stm32h5-tz.config b/config/examples/stm32h5-tz.config index 66c1bae751..aeb4d6a52d 100644 --- a/config/examples/stm32h5-tz.config +++ b/config/examples/stm32h5-tz.config @@ -21,8 +21,8 @@ DUALBANK_SWAP?=0 WOLFBOOT_PARTITION_SIZE?=0xA0000 WOLFBOOT_SECTOR_SIZE?=0x2000 WOLFBOOT_PARTITION_BOOT_ADDRESS?=0x08060000 -WOLFBOOT_PARTITION_UPDATE_ADDRESS?=0x08100000 -WOLFBOOT_PARTITION_SWAP_ADDRESS?=0x081A0000 +WOLFBOOT_PARTITION_UPDATE_ADDRESS?=0x0C100000 +WOLFBOOT_PARTITION_SWAP_ADDRESS?=0x0C1A0000 FLAGS_HOME=0 DISABLE_BACKUP=0 WOLFCRYPT_TZ=1 diff --git a/docs/API.md b/docs/API.md index ebc0883de4..99a5586762 100644 --- a/docs/API.md +++ b/docs/API.md @@ -66,3 +66,35 @@ the two images again. For more information about the update process, see [Firmware Update](firmware_update.md) For the image format, see [Firmware Image](firmware_image.md) + +## NSC API + +If you're running wolfBoot on an ARM TrustZone-enabled device (see for example +[STM32-TZ](STM32-TZ.md)) you may wish to run your application in non-secure +mode, while keeping the UPDATE and SWAP partitions in the secure domain. In +order to accomplish this, any operation by the application that requires access +to those partitions needs to be performed via wolfBoot code running in the +secure domain. For this purpose, wolfBoot provides Non-Secure Callable (NSC) +APIs that allow code running in the non-secure domain to call into the secure +domain managed by wolfBoot. + +These APIs are listed below. + +- `void wolfBoot_nsc_success(void)`: wrapper for `wolfBoot_success()` +- `void wolfBoot_nsc_update_trigger(void)`: wrapper for + `wolfBoot_update_trigger()` +- `uint32_t wolfBoot_nsc_get_image_version(uint8_t part)`: wrapper for + `wolfBoot_get_image_version()` +- `uint32_t wolfBoot_nsc_current_firmware_version(void)`: wrapper for + `wolfBoot_current_firmware_version()` +- `uint32_t wolfBoot_nsc_update_firmware_version(void)`: wrapper for + `wolfBoot_update_firmware_version()` +- `int wolfBoot_nsc_get_partition_state(uint8_t part, uint8_t *st)`: wrapper + for `wolfBoot_get_partition_state()` +- `int wolfBoot_nsc_erase_update(uint32_t address, uint32_t len)`: allows the + application to erase the update partition in secure mode. The `address` + parameter is an offset from the beginning of the partition. +- `int wolfBoot_nsc_write_update(uint32_t address, const uint8_t *buf, uint32_t + len)`: allows the application to write to the update partition in secure + mode. The `address` parameter is an offset from the beginning of the + partition. diff --git a/docs/STM32-TZ.md b/docs/STM32-TZ.md index 9e969e9ee5..72cdaaf4e2 100644 --- a/docs/STM32-TZ.md +++ b/docs/STM32-TZ.md @@ -55,6 +55,12 @@ image header size must be supplied as an environment variable. For example: IMAGE_HEADER_SIZE=1024 ./tools/keytools/sign --sha256 --ecc256 myapp.bin wolfboot_signing_private_key.der 1 ``` +### NSC API + +wolfBoot provides a few Non-Secure Callable functions to allow a non-secure +application to perform certain operations that must be run from the secure +domain. For more information, see [API](API.md#nsc-api). + ### Example using STM32L552 - Copy the example configuration for STM32-L5 with support for wolfCrypt in @@ -192,7 +198,7 @@ OPTION BYTES BANK: 2 Boot Configuration: - NSBOOTADD : 0x80400 (0x8040000) + NSBOOTADD : 0x80600 (0x8060000) NSBOOT_LOCK : 0xC3 (The SWAP_BANK and NSBOOTADD can still be modified following their individual rules.) SECBOOT_LOCK : 0xC3 (The BOOT_UBE, SWAP_BANK and SECBOOTADD can still be modified following their individual rules.) SECBOOTADD : 0xC0000 (0xC000000) @@ -201,7 +207,7 @@ OPTION BYTES BANK: 3 Bank1 - Flash watermark area definition: SECWM1_STRT : 0x0 (0x8000000) - SECWM1_END : 0x1F (0x803E000) + SECWM1_END : 0x2F (0x805e000) Write sector group protection 1: @@ -211,7 +217,7 @@ OPTION BYTES BANK: 4 Bank2 - Flash watermark area definition: SECWM2_STRT : 0x0 (0x08100000) - SECWM2_END : 0x1F (0x0813e000) + SECWM2_END : 0x7F (0x081fe0000) Write sector group protection 2: @@ -251,7 +257,7 @@ OPTION BYTES BANK: 9 ``` STM32_Programmer_CLI -c port=swd -d wolfboot.bin 0x0C000000 -STM32_Programmer_CLI -c port=swd -d test-app/image_v1_signed.bin 0x08040000 +STM32_Programmer_CLI -c port=swd -d test-app/image_v1_signed.bin 0x08060000 ``` - After rebooting, the LED on the board should turn on sequentially: diff --git a/docs/Targets.md b/docs/Targets.md index e0cd31ea2b..a3409e91a3 100644 --- a/docs/Targets.md +++ b/docs/Targets.md @@ -175,10 +175,10 @@ The example configuration for this scenario is available in [/config/examples/st - User Option Bytes requirement (with STM32CubeProgrammer tool - see below for instructions) ``` -TZEN = 1 System with TrustZone-M enabled -DBANK = 1 Dual bank mode -SECWM1_PSTRT=0x0 SECWM1_PEND=0x7F All 128 pages of internal Flash Bank1 set as secure -SECWM2_PSTRT=0x1 SECWM2_PEND=0x0 No page of internal Flash Bank2 set as secure, hence Bank2 non-secure +TZEN = 1 System with TrustZone-M enabled +DBANK = 1 Dual bank mode +SECWM1_STRT=0x0 SECWM1_END=0x7F All 128 pages of internal Flash Bank1 set as secure +SECWM2_STRT=0x1 SECWM2_END=0x0 No page of internal Flash Bank2 set as secure, hence Bank2 non-secure ``` - NOTE: STM32CubeProgrammer V2.3.0 is required (v2.4.0 has a known bug for STM32L5) @@ -189,7 +189,7 @@ SECWM2_PSTRT=0x1 SECWM2_PEND=0x0 No page of internal Flash Bank2 set as secur 2. `make` 3. Prepare board with option bytes configuration reported above - `STM32_Programmer_CLI -c port=swd mode=hotplug -ob TZEN=1 DBANK=1` - - `STM32_Programmer_CLI -c port=swd mode=hotplug -ob SECWM1_PSTRT=0x0 SECWM1_PEND=0x7F SECWM2_PSTRT=0x1 SECWM2_PEND=0x0` + - `STM32_Programmer_CLI -c port=swd mode=hotplug -ob SECWM1_STRT=0x0 SECWM1_END=0x7F SECWM2_STRT=0x1 SECWM2_END=0x0` 4. flash wolfBoot.bin to 0x0c00 0000 - `STM32_Programmer_CLI -c port=swd -d ./wolfboot.bin 0x0C000000` 5. flash .\test-app\image_v1_signed.bin to 0x0804 0000 @@ -316,10 +316,10 @@ SRAM memories into two parts: - User Option Bytes requirement (with STM32CubeProgrammer tool - see below for instructions) ``` -TZEN = 1 System with TrustZone-M enabled -DBANK = 1 Dual bank mode -SECWM1_PSTRT=0x0 SECWM1_PEND=0x7F All 128 pages of internal Flash Bank1 set as secure -SECWM2_PSTRT=0x1 SECWM2_PEND=0x0 No page of internal Flash Bank2 set as secure, hence Bank2 non-secure +TZEN = 1 System with TrustZone-M enabled +DBANK = 1 Dual bank mode +SECWM1_STRT=0x0 SECWM1_END=0x7F All 128 pages of internal Flash Bank1 set as secure +SECWM2_STRT=0x1 SECWM2_END=0x0 No page of internal Flash Bank2 set as secure, hence Bank2 non-secure ``` - NOTE: STM32CubeProgrammer V2.8.0 or newer is required @@ -330,7 +330,7 @@ SECWM2_PSTRT=0x1 SECWM2_PEND=0x0 No page of internal Flash Bank2 set as secur 2. `make TZEN=1` 3. Prepare board with option bytes configuration reported above - `STM32_Programmer_CLI -c port=swd mode=hotplug -ob TZEN=1 DBANK=1` - - `STM32_Programmer_CLI -c port=swd mode=hotplug -ob SECWM1_PSTRT=0x0 SECWM1_PEND=0x7F SECWM2_PSTRT=0x1 SECWM2_PEND=0x0` + - `STM32_Programmer_CLI -c port=swd mode=hotplug -ob SECWM1_STRT=0x0 SECWM1_END=0x7F SECWM2_STRT=0x1 SECWM2_END=0x0` 4. flash wolfBoot.bin to 0x0c000000 - `STM32_Programmer_CLI -c port=swd -d ./wolfboot.bin 0x0C000000` 5. flash .\test-app\image_v1_signed.bin to 0x08010000 @@ -915,7 +915,7 @@ The example configuration for this scenario is available in [/config/examples/st `STM32_Programmer_CLI -c port=swd -ob TZEN=0xB4` - set the option bytes to enable flash secure protection of first 384KB and remainder as non-secure: -`STM32_Programmer_CLI -c port=swd -ob SECWM1_PSTRT=0x0 SECWM1_PEND=0x2F SECWM2_PSTRT=0x2F SECWM2_PEND=0x0` +`STM32_Programmer_CLI -c port=swd -ob SECWM1_STRT=0x0 SECWM1_END=0x2F SECWM2_STRT=0x0 SECWM2_END=0x7F` - flash the wolfboot image to the secure partition: `STM32_Programmer_CLI -c port=swd -d wolfboot.bin 0x0C000000` @@ -925,6 +925,19 @@ The example configuration for this scenario is available in [/config/examples/st For a full list of all the option bytes tested with this configuration, refer to [STM32-TZ.md](/docs/STM32-TZ.md). +You can use the "update" command and XMODEM to send a newly signed update (see docs/flash-OTP.md) or use the steps below using the STM32_Programmer: + +```sh +IMAGE_HEADER_SIZE=1024 tools/keytools/sign --ecc256 test-app/image.bin wolfboot_signing_private_key.der 2 +echo -n "pBOOT" > trigger_magic.bin +./tools/bin-assemble/bin-assemble \ + update.bin \ + 0x0 test-app/image_v2_signed.bin \ + 0x9FFFB trigger_magic.bin +STM32_Programmer_CLI -c port=swd -d update.bin 0x0C100000 +``` + + ### Scenario 2: TrustZone Enabled, wolfCrypt as secure engine for NS applications This is similar to Scenario 1, but also includes wolfCrypt in secure mode, and @@ -975,7 +988,7 @@ To initiate an update, sign a new version of the app and upload the v3 to the up on the second bank: ```sh -tools/keytools/sign --ecc256 test-app/image.bin wolfboot_signing_private_key.der 3 +IMAGE_HEADER_SIZE=1024 tools/keytools/sign --ecc256 test-app/image.bin wolfboot_signing_private_key.der 3 STM32_Programmer_CLI -c port=swd -d test-app/image_v3_signed.bin 0x08160000 ``` diff --git a/hal/stm32_tz.c b/hal/stm32_tz.c index 4be441bbb4..52b33e160f 100644 --- a/hal/stm32_tz.c +++ b/hal/stm32_tz.c @@ -96,6 +96,7 @@ void hal_tz_claim_nonsecure_area(uint32_t address, int len) uint32_t reg; uint32_t end = address + len; uint32_t start_address = address; + uint32_t start_page_n; uint32_t bank = 0; int pos; @@ -103,12 +104,13 @@ void hal_tz_claim_nonsecure_area(uint32_t address, int len) return; if (address < FLASH_BANK2_BASE) { - page_n = (address - ARCH_FLASH_OFFSET) / FLASH_PAGE_SIZE; + start_page_n = (address - ARCH_FLASH_OFFSET) / FLASH_PAGE_SIZE; bank = 0; } else { - page_n = (address - FLASH_BANK2_BASE) / FLASH_PAGE_SIZE; + start_page_n = (address - FLASH_BANK2_BASE) / FLASH_PAGE_SIZE; bank = 1; } + page_n = start_page_n; #ifdef TARGET_stm32h5 /* Take into account current swap configuration */ if ((FLASH_OPTSR_CUR & FLASH_OPTSR_SWAP_BANK) >> 31) @@ -129,13 +131,14 @@ void hal_tz_claim_nonsecure_area(uint32_t address, int len) 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)); + 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 @@ -162,8 +165,11 @@ void hal_tz_release_nonsecure_area(void) { #ifndef DUALBANK_SWAP int i; - for (i = 0; i < FLASH_SECBB_NREGS; i++) + /* Set all banks as non-secure */ + for (i = 0; i < FLASH_SECBB_NREGS; i++) { + FLASH_SECBB1[i] = 0; FLASH_SECBB2[i] = 0; + } #else uint32_t addr; int bank_swp = 0; diff --git a/hal/stm32h5.c b/hal/stm32h5.c index 3df657d76b..fe60a72bf9 100644 --- a/hal/stm32h5.c +++ b/hal/stm32h5.c @@ -32,15 +32,11 @@ #define PLL_SRC_HSE 1 #if TZ_SECURE() - -/* This function assumes that the boot and the update - * partitions are at the same address in the two banks, - * regardless if DUALBANK_SWAP is active or not. - */ static int is_flash_nonsecure(uint32_t address) { - uint32_t in_bank_offset = (address & 0x000FFFFF); - if (in_bank_offset >= (WOLFBOOT_PARTITION_BOOT_ADDRESS - FLASHMEM_ADDRESS_SPACE)) { + if (address >= WOLFBOOT_PARTITION_BOOT_ADDRESS && + address < WOLFBOOT_PARTITION_BOOT_ADDRESS + + WOLFBOOT_PARTITION_SIZE) { return 1; } return 0; @@ -189,6 +185,7 @@ void RAMFUNCTION hal_flash_opt_lock(void) int RAMFUNCTION hal_flash_erase(uint32_t address, int len) { + uint32_t start_address; uint32_t end_address; uint32_t p; @@ -199,24 +196,33 @@ int RAMFUNCTION hal_flash_erase(uint32_t address, int len) if (address < 0x08000000) return -1; - end_address = address + len - 1; - for (p = address; p < end_address; p += FLASH_PAGE_SIZE) { +#if TZ_SECURE() + if (address & FLASH_SECURE_MMAP_BIT) { + /* Get address in non-secure address space */ + start_address = address & ~FLASH_SECURE_MMAP_BIT; + } + else { + if (is_flash_nonsecure(address)) { + hal_tz_claim_nonsecure_area(address, len); + } + start_address = address; + } +#else + start_address = address; +#endif + + end_address = start_address + len - 1; + for (p = start_address; p < end_address; p += FLASH_PAGE_SIZE) { uint32_t reg; uint32_t base; uint32_t bnksel = 0; base = FLASHMEM_ADDRESS_SPACE; - reg = FLASH_CR & (~((FLASH_CR_PNB_MASK << FLASH_CR_PNB_SHIFT) | FLASH_CR_BER)); - if(p >= (FLASH_BANK2_BASE) && (p <= (FLASH_TOP) )) + 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)); + if (p >= FLASH_BANK2_BASE && p <= FLASH_TOP) { base = FLASH_BANK2_BASE; bnksel = 1; } -#if TZ_SECURE() - /* When in secure mode, skip erasing non-secure pages: will be erased upon claim */ - if (is_flash_nonsecure(address)) { - return 0; - } -#endif /* Check for swapped banks to invert bnksel */ if ((FLASH_OPTSR_CUR & FLASH_OPTSR_SWAP_BANK) >> 31) bnksel = !bnksel; @@ -224,10 +230,16 @@ int RAMFUNCTION hal_flash_erase(uint32_t address, int len) FLASH_CR = reg; ISB(); FLASH_CR |= FLASH_CR_STRT; - hal_flash_wait_complete(0); + hal_flash_wait_complete(bnksel); } /* If the erase operation is completed, disable the associated bits */ FLASH_CR &= ~FLASH_CR_SER ; + +#if TZ_SECURE() + if (!(address & FLASH_SECURE_MMAP_BIT) && is_flash_nonsecure(address)) { + hal_tz_release_nonsecure_area(); + } +#endif return 0; } diff --git a/hal/stm32h5.h b/hal/stm32h5.h index 95e203ebf0..d80add0736 100644 --- a/hal/stm32h5.h +++ b/hal/stm32h5.h @@ -49,6 +49,7 @@ #endif #define FLASH_SECURE_MMAP_BASE (0x0C000000) +#define FLASH_SECURE_MMAP_BIT (0x04000000) #define RCC_CR (*(volatile uint32_t *)(RCC_BASE + 0x00)) /* RM0481 - Table 108 */ #define RCC_CR_PLL3RDY (1 << 29) /* RM0481 - Table 108 */ diff --git a/include/wolfboot/wolfboot.h b/include/wolfboot/wolfboot.h index f51b380628..09a14fb273 100644 --- a/include/wolfboot/wolfboot.h +++ b/include/wolfboot/wolfboot.h @@ -420,7 +420,6 @@ int wolfBoot_erase_encrypt_key(void); */ /* Call wolfBoot_success from non-secure application */ - __attribute__((cmse_nonsecure_entry)) void wolfBoot_nsc_success(void); @@ -428,6 +427,16 @@ void wolfBoot_nsc_success(void); __attribute__((cmse_nonsecure_entry)) void wolfBoot_nsc_update_trigger(void); +/* Call wolfBoot_get_image_version from non-secure application */ +__attribute__((cmse_nonsecure_entry)) +uint32_t wolfBoot_nsc_get_image_version(uint8_t part); +#define wolfBoot_nsc_current_firmware_version() wolfBoot_nsc_get_image_version(PART_BOOT) +#define wolfBoot_nsc_update_firmware_version() wolfBoot_nsc_get_image_version(PART_UPDATE) + +/* Call wolfBoot_get_partition_state from non-secure application */ +__attribute__((cmse_nonsecure_entry)) +int wolfBoot_nsc_get_partition_state(uint8_t part, uint8_t *st); + /* Erase one or more sectors in the update partition. * - address: offset within the update partition ('0' corresponds to PARTITION_UPDATE_ADDRESS) * - len: size, in bytes diff --git a/src/libwolfboot.c b/src/libwolfboot.c index 6c08380daf..a94434bca6 100644 --- a/src/libwolfboot.c +++ b/src/libwolfboot.c @@ -2051,25 +2051,48 @@ void wolfBoot_nsc_update_trigger(void) wolfBoot_update_trigger(); } +__attribute__((cmse_nonsecure_entry)) +uint32_t wolfBoot_nsc_get_image_version(uint8_t part) +{ + return wolfBoot_get_image_version(part); +} + +__attribute__((cmse_nonsecure_entry)) +int wolfBoot_nsc_get_partition_state(uint8_t part, uint8_t *st) +{ + return wolfBoot_get_partition_state(part, st); +} + __attribute__((cmse_nonsecure_entry)) int wolfBoot_nsc_erase_update(uint32_t address, uint32_t len) { + int ret; + if (address > WOLFBOOT_PARTITION_SIZE) return -1; if (address + len > WOLFBOOT_PARTITION_SIZE) return -1; - return hal_flash_erase(address + WOLFBOOT_PARTITION_UPDATE_ADDRESS, len); + hal_flash_unlock(); + ret = hal_flash_erase(address + WOLFBOOT_PARTITION_UPDATE_ADDRESS, len); + hal_flash_lock(); + return ret; } __attribute__((cmse_nonsecure_entry)) int wolfBoot_nsc_write_update(uint32_t address, const uint8_t *buf, uint32_t len) { + int ret; + if (address > WOLFBOOT_PARTITION_SIZE) return -1; if (address + len > WOLFBOOT_PARTITION_SIZE) return -1; - return hal_flash_write(address + WOLFBOOT_PARTITION_UPDATE_ADDRESS, buf, len); + + hal_flash_unlock(); + ret = hal_flash_write(address + WOLFBOOT_PARTITION_UPDATE_ADDRESS, buf, len); + hal_flash_lock(); + return ret; } #endif diff --git a/test-app/app_stm32h5.c b/test-app/app_stm32h5.c index f6749c692e..7f1e4eb91e 100644 --- a/test-app/app_stm32h5.c +++ b/test-app/app_stm32h5.c @@ -267,21 +267,27 @@ static int cmd_update_xmodem(const char *args) { int ret = -1; uint8_t xpkt[XMODEM_PACKET_SIZE]; - uint32_t dst_flash = (uint32_t)WOLFBOOT_PARTITION_UPDATE_ADDRESS; + uint32_t dst_offset = 0; uint8_t pkt_num = 0, pkt_num_expected=0xFF; uint32_t pkt_size = XMODEM_PACKET_SIZE; + uint32_t t_size = 0; uint32_t update_ver = 0; uint32_t now = jiffies; uint32_t i = 0; uint8_t pkt_num_inv; uint8_t crc, calc_crc; int transfer_started = 0; + int eot_expected = 0; printf("Erasing update partition..."); fflush(stdout); +#ifdef WOLFCRYPT_SECURE_MODE + wolfBoot_nsc_erase_update(dst_offset, WOLFBOOT_PARTITION_SIZE); +#else hal_flash_unlock(); - hal_flash_erase(dst_flash, WOLFBOOT_PARTITION_SIZE); + hal_flash_erase(WOLFBOOT_PARTITION_UPDATE_ADDRESS + dst_offset, WOLFBOOT_PARTITION_SIZE); +#endif printf("Done.\r\n"); printf("Waiting for XMODEM transfer...\r\n"); @@ -303,6 +309,8 @@ static int cmd_update_xmodem(const char *args) } } else { now = jiffies; + if (i == 0 && xpkt[0] == XEOT) + break; i += ret; } } @@ -313,6 +321,12 @@ static int cmd_update_xmodem(const char *args) extra_led_on(); break; } + else if (eot_expected) { + ret = 1; + uart_tx(XNAK); + break; + } + if (xpkt[0] != XSOH) { continue; } @@ -335,10 +349,13 @@ static int cmd_update_xmodem(const char *args) crc = xpkt[XMODEM_PACKET_SIZE - 1]; calc_crc = crc8(xpkt, XMODEM_PACKET_SIZE - 1); if (crc == calc_crc) { - uint32_t t_size; /* CRC is valid */ memcpy(xpkt_payload, xpkt + 3, XMODEM_PAYLOAD_SIZE); - ret = hal_flash_write(dst_flash, xpkt_payload, XMODEM_PAYLOAD_SIZE); +#ifdef WOLFCRYPT_SECURE_MODE + ret = wolfBoot_nsc_write_update(dst_offset, xpkt_payload, XMODEM_PAYLOAD_SIZE); +#else + ret = hal_flash_write(WOLFBOOT_PARTITION_UPDATE_ADDRESS + dst_offset, xpkt_payload, XMODEM_PAYLOAD_SIZE); +#endif if (ret != 0) { xcancel(); printf("Error writing to flash\r\n"); @@ -347,15 +364,16 @@ static int cmd_update_xmodem(const char *args) uart_tx(XACK); pkt_num++; pkt_num_expected++; - dst_flash += XMODEM_PAYLOAD_SIZE; - t_size = *((uint32_t *)(WOLFBOOT_PARTITION_UPDATE_ADDRESS + 4)); - t_size += IMAGE_HEADER_SIZE; - if ((uint32_t)dst_flash >= (WOLFBOOT_PARTITION_UPDATE_ADDRESS + t_size)) { - ret = 0; - extra_led_off(); - break; + dst_offset += XMODEM_PAYLOAD_SIZE; + if (t_size == 0) { + /* At first packet, save expected partition size */ + t_size = *(uint32_t *)(xpkt_payload + 4); + t_size += IMAGE_HEADER_SIZE; } - uart_tx(XACK); + if (dst_offset >= t_size) { + eot_expected = 1; + } + /*uart_tx(XACK);*/ } else { uart_tx(XNAK); } @@ -367,17 +385,34 @@ static int cmd_update_xmodem(const char *args) uart_tx('\r'); printf("End of transfer. ret: %d\r\n", ret); - update_ver = wolfBoot_update_firmware_version(); - if (update_ver != 0) { - printf("New firmware version: 0x%lx\r\n", update_ver); - printf("Triggering update...\r\n"); - wolfBoot_update_trigger(); - printf("Update completed successfully.\r\n"); - } else { - printf("No valid image in update partition\r\n"); + if (ret != 0) { + printf("Transfer failed\r\n"); + } + else { + printf("Transfer succeeded\r\n"); +#ifdef WOLFCRYPT_SECURE_MODE + update_ver = wolfBoot_nsc_update_firmware_version(); +#else + update_ver = wolfBoot_update_firmware_version(); +#endif + if (update_ver != 0) { + printf("New firmware version: 0x%lx\r\n", update_ver); + printf("Triggering update...\r\n"); +#ifdef WOLFCRYPT_SECURE_MODE + wolfBoot_nsc_update_trigger(); +#else + wolfBoot_update_trigger(); +#endif + printf("Update written successfully. Reboot to apply.\r\n"); + } else { + printf("No valid image in update partition\r\n"); + } } +#ifndef WOLFCRYPT_SECURE_MODE hal_flash_lock(); +#endif + return ret; } @@ -427,17 +462,25 @@ static int cmd_info(const char *args) uint16_t hdrSz; uint8_t boot_part_state = IMG_STATE_NEW, update_part_state = IMG_STATE_NEW; +#ifdef WOLFCRYPT_SECURE_MODE + cur_fw_version = wolfBoot_nsc_current_firmware_version(); + update_fw_version = wolfBoot_nsc_update_firmware_version(); + + wolfBoot_nsc_get_partition_state(PART_BOOT, &boot_part_state); + wolfBoot_nsc_get_partition_state(PART_UPDATE, &update_part_state); +#else cur_fw_version = wolfBoot_current_firmware_version(); update_fw_version = wolfBoot_update_firmware_version(); wolfBoot_get_partition_state(PART_BOOT, &boot_part_state); wolfBoot_get_partition_state(PART_UPDATE, &update_part_state); +#endif printf("\r\n"); printf("System information\r\n"); printf("====================================\r\n"); printf("Flash banks are %sswapped.\r\n", ((FLASH_OPTSR_CUR & (FLASH_OPTSR_SWAP_BANK)) == 0)?"not ":""); - printf("Firmware version : 0x%lx\r\n", wolfBoot_current_firmware_version()); + printf("Firmware version : 0x%lx\r\n", cur_fw_version); printf("Current firmware state: %s\r\n", part_state_name(boot_part_state)); if (update_fw_version != 0) { if (update_part_state == IMG_STATE_UPDATING) @@ -482,7 +525,11 @@ static int cmd_info(const char *args) static int cmd_success(const char *args) { +#ifdef WOLFCRYPT_SECURE_MODE + wolfBoot_nsc_success(); +#else wolfBoot_success(); +#endif printf("update success confirmed.\r\n"); return 0; } @@ -741,14 +788,17 @@ void main(void) int ret; uint32_t app_version; - /* Turn on boot LED */ boot_led_on(); /* Enable SysTick */ systick_enable(); +#ifdef WOLFCRYPT_SECURE_MODE + app_version = wolfBoot_nsc_current_firmware_version(); +#else app_version = wolfBoot_current_firmware_version(); +#endif nvic_irq_setprio(NVIC_USART3_IRQN, 0); nvic_irq_enable(NVIC_USART3_IRQN);