Update H5 app to use new NSC API

- Make the update and swap partitions secure and inaccessible from the
  app except via NSC API
- Add a couple of necessary new NSC functions
- Update the app to only use NSC API
- Fix hal_flash_erase to account for secure addresses
- Fix some bugs in xmodem implementation
pull/617/head
Mattia Moffa 2025-10-29 00:06:19 +01:00
parent e0e9217161
commit 177358e88d
9 changed files with 101 additions and 56 deletions

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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
IMAGE_HEADER_SIZE?=1024

View File

@ -32,21 +32,14 @@
#define PLL_SRC_HSE 1
#if TZ_SECURE()
static int is_flash_nonsecure(uint32_t address)
{
#ifndef DUALBANK_SWAP
if (address >= WOLFBOOT_PARTITION_BOOT_ADDRESS) {
if (address >= WOLFBOOT_PARTITION_BOOT_ADDRESS &&
address < WOLFBOOT_PARTITION_BOOT_ADDRESS +
WOLFBOOT_PARTITION_SIZE) {
return 1;
}
return 0;
#else
uint32_t in_bank_offset = (address & 0x000FFFFF);
if (in_bank_offset >= (WOLFBOOT_PARTITION_BOOT_ADDRESS - FLASHMEM_ADDRESS_SPACE)) {
return 1;
}
return 0;
#endif
}
#endif
@ -204,9 +197,15 @@ int RAMFUNCTION hal_flash_erase(uint32_t address, int len)
return -1;
#if TZ_SECURE()
start_address = address | FLASH_SECURE_MMAP_BASE;
if (is_flash_nonsecure(address)) {
hal_tz_claim_nonsecure_area(address, len);
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;
@ -218,8 +217,8 @@ int RAMFUNCTION hal_flash_erase(uint32_t address, int len)
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;
@ -231,13 +230,13 @@ 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 (is_flash_nonsecure(address)) {
if (!(address & FLASH_SECURE_MMAP_BIT) && is_flash_nonsecure(address)) {
hal_tz_release_nonsecure_area();
}
#endif

View File

@ -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 */

View File

@ -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

View File

@ -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

View File

@ -267,21 +267,22 @@ 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);
hal_flash_unlock();
hal_flash_erase(dst_flash, WOLFBOOT_PARTITION_SIZE);
wolfBoot_nsc_erase_update(dst_offset, WOLFBOOT_PARTITION_SIZE);
printf("Done.\r\n");
printf("Waiting for XMODEM transfer...\r\n");
@ -303,6 +304,8 @@ static int cmd_update_xmodem(const char *args)
}
} else {
now = jiffies;
if (i == 0 && xpkt[0] == XEOT)
break;
i += ret;
}
}
@ -313,6 +316,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 +344,9 @@ 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);
ret = wolfBoot_nsc_write_update(dst_offset, xpkt_payload, XMODEM_PAYLOAD_SIZE);
if (ret != 0) {
xcancel();
printf("Error writing to flash\r\n");
@ -347,15 +355,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 +376,22 @@ 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");
update_ver = wolfBoot_nsc_update_firmware_version();
if (update_ver != 0) {
printf("New firmware version: 0x%lx\r\n", update_ver);
printf("Triggering update...\r\n");
wolfBoot_nsc_update_trigger();
printf("Update written successfully. Reboot to apply.\r\n");
} else {
printf("No valid image in update partition\r\n");
}
}
hal_flash_lock();
return ret;
}
@ -427,17 +441,17 @@ static int cmd_info(const char *args)
uint16_t hdrSz;
uint8_t boot_part_state = IMG_STATE_NEW, update_part_state = IMG_STATE_NEW;
cur_fw_version = wolfBoot_current_firmware_version();
update_fw_version = wolfBoot_update_firmware_version();
cur_fw_version = wolfBoot_nsc_current_firmware_version();
update_fw_version = wolfBoot_nsc_update_firmware_version();
wolfBoot_get_partition_state(PART_BOOT, &boot_part_state);
wolfBoot_get_partition_state(PART_UPDATE, &update_part_state);
wolfBoot_nsc_get_partition_state(PART_BOOT, &boot_part_state);
wolfBoot_nsc_get_partition_state(PART_UPDATE, &update_part_state);
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 +496,7 @@ static int cmd_info(const char *args)
static int cmd_success(const char *args)
{
wolfBoot_success();
wolfBoot_nsc_success();
printf("update success confirmed.\r\n");
return 0;
}
@ -741,14 +755,13 @@ void main(void)
int ret;
uint32_t app_version;
/* Turn on boot LED */
boot_led_on();
/* Enable SysTick */
systick_enable();
app_version = wolfBoot_current_firmware_version();
app_version = wolfBoot_nsc_current_firmware_version();
nvic_irq_setprio(NVIC_USART3_IRQN, 0);
nvic_irq_enable(NVIC_USART3_IRQN);