From 9e2b8aa37fb417a4c70042de9d201d6a521c7d92 Mon Sep 17 00:00:00 2001 From: Daniele Lacamera Date: Wed, 10 Apr 2024 08:37:06 +0200 Subject: [PATCH] STM32H5L added support for TrustZone --- Makefile | 7 ++ arch.mk | 4 -- docs/Targets.md | 6 ++ hal/stm32_tz.c | 144 +++++++++++++++++++++++++++---------- hal/stm32_tz.h | 57 +++++++++++++++ hal/stm32h5-ns.ld | 2 +- hal/stm32h5.c | 46 ++++++------ hal/stm32h5.h | 7 +- hal/stm32h5.ld | 20 ++++-- hal/stm32u5.h | 3 + include/hal.h | 1 + src/boot_arm.c | 12 +++- test-app/ARM-stm32h5-ns.ld | 2 +- test-app/app_stm32h5.c | 1 - 14 files changed, 240 insertions(+), 72 deletions(-) create mode 100644 hal/stm32_tz.h diff --git a/Makefile b/Makefile index 2560a381f..acfcd4edf 100644 --- a/Makefile +++ b/Makefile @@ -78,6 +78,7 @@ endif MAIN_TARGET=factory.bin TARGET_H_TEMPLATE:=include/target.h.in +ifeq ($(TZEN),1) ifeq ($(TARGET),stm32l5) # Don't build a contiguous image MAIN_TARGET:=wolfboot.bin test-app/image_v1_signed.bin @@ -88,6 +89,12 @@ ifeq ($(TARGET),stm32u5) MAIN_TARGET:=wolfboot.bin test-app/image_v1_signed.bin endif +ifeq ($(TARGET),stm32h5) + # Don't build a contiguous image + MAIN_TARGET:=wolfboot.bin test-app/image_v1_signed.bin +endif +endif # TZEN=1 + ifeq ($(TARGET),x86_64_efi) MAIN_TARGET:=wolfboot.efi endif diff --git a/arch.mk b/arch.mk index 52fb38d86..2844470d7 100644 --- a/arch.mk +++ b/arch.mk @@ -146,8 +146,6 @@ ifeq ($(ARCH),ARM) WOLFBOOT_ORIGIN=0x0C000000 else WOLFBOOT_ORIGIN=0x08000000 - endif - ifneq ($(TZEN),1) LSCRIPT_IN=hal/$(TARGET)-ns.ld endif endif @@ -172,8 +170,6 @@ ifeq ($(ARCH),ARM) WOLFBOOT_ORIGIN=0x0C000000 else WOLFBOOT_ORIGIN=0x08000000 - endif - ifneq ($(TZEN),1) LSCRIPT_IN=hal/$(TARGET)-ns.ld endif SPI_TARGET=stm32 diff --git a/docs/Targets.md b/docs/Targets.md index af1011559..5701e75f3 100644 --- a/docs/Targets.md +++ b/docs/Targets.md @@ -861,6 +861,12 @@ STM32_Programmer_CLI -c port=swd -d test-app/image_v3_signed.bin 0x08110000 Reboot the board to initiate an update via DUALBANK hw-assisted swap. Any version except the first one will also turn on the orange LED. +### TrustZone mode + +- set the option bytes to enable trustzone: + +`STM32_Programmer_CLI -c port=swd -ob TZEN=0xB4` + ## STM32H7 diff --git a/hal/stm32_tz.c b/hal/stm32_tz.c index 631b02bdd..fec0f49b7 100644 --- a/hal/stm32_tz.c +++ b/hal/stm32_tz.c @@ -33,12 +33,12 @@ #include "hal/stm32h5.h" #endif +#include "hal/stm32_tz.h" + #include "image.h" #include "hal.h" #if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) && (!defined(FLAGS_HOME) || !defined(DISABLE_BACKUP)) -#define SCB_SHCSR (*(volatile uint32_t *)(0xE000ED24)) -#define SCB_SHCSR_SECUREFAULT_EN (1<<19) static void RAMFUNCTION hal_flash_nonsecure_unlock(void) { @@ -120,6 +120,42 @@ void hal_tz_release_nonsecure_area(void) #define release_nonsecure_area(...) do{}while(0) #endif + + +#ifdef PLATFORM_stm32h5 +#define GTZC1_BASE (0x50032400) +#define GTZC1_TZSC (*(volatile uint32_t *)(GTZC1_BASE + 0x00)) +#define GTZC1_TZIC (*(volatile uint32_t *)(GTZC1_BASE + 0x0400)) +#define GTZC1_MPCBB1_S ((volatile uint32_t *)(GTZC1_BASE + 0x0800)) +#define GTZC1_MPCBB2_S ((volatile uint32_t *)(GTZC1_BASE + 0x0C00)) +#define GTZC1_MPCBB3_S ((volatile uint32_t *)(GTZC1_BASE + 0x1000)) + +#define SET_GTZC1_MPCBBx_S_VCTR(bank,n,val) \ + (*((volatile uint32_t *)(GTZC1_MPCBB##bank##_S) + n ))= val + +void hal_gtzc_init(void) +{ + int i; + /* One bit in the bitmask: 512B */ + + /* Configure SRAM1 as secure (Low 256 KB) */ + for (i = 0; i < 16; i++) { + SET_GTZC1_MPCBBx_S_VCTR(1, i, 0xFFFFFFFF); + } + + /* Configure SRAM2 as secure (64 KB) */ + for (i = 0; i < 4; i++) { + SET_GTZC1_MPCBBx_S_VCTR(2, i, 0xFFFFFFFF); + } + + /* Configure SRAM3 as non-secure (320 KB) */ + for (i = 0; i < 20; i++) { + SET_GTZC1_MPCBBx_S_VCTR(3, i, 0x0); + } +} + +#else + #define GTZC_MPCBB1_S_BASE (0x50032C00) #define GTZC_MPCBB1_S_VCTR_BASE (GTZC_MPCBB1_S_BASE + 0x100) @@ -129,13 +165,14 @@ void hal_tz_release_nonsecure_area(void) #define SET_GTZC_MPCBBx_S_VCTR(bank,n,val) \ (*((volatile uint32_t *)(GTZC_MPCBB##bank##_S_VCTR_BASE ) + n ))= val - void hal_gtzc_init(void) { int i; - /* Configure lower half of total RAM as secure - * 0x3000 0000 : 0x3001 FFFF - 128KB - */ + /* One bit in the bitmask: 256B */ + + /* Configure lower half of total RAM as secure + * 0x3000 0000 : 0x3001 FFFF - 128KB + */ for (i = 0; i < 16; i++) { SET_GTZC_MPCBBx_S_VCTR(1, i, 0xFFFFFFFF); } @@ -147,43 +184,48 @@ void hal_gtzc_init(void) SET_GTZC_MPCBBx_S_VCTR(1, i, 0x0); } - /* Configure SRAM2 as non-secure - * 0x2003 0000 : 0x2003 FFFF - 64 KB - */ + /* Configure SRAM2 as non-secure + * 0x2003 0000 : 0x2003 FFFF - 64 KB + */ for (i = 0; i < 8; i++) { SET_GTZC_MPCBBx_S_VCTR(2, i, 0x0); } } +#endif -/* SAU registers, used to define memory mapped regions */ -#define SAU_CTRL (*(volatile uint32_t *)(0xE000EDD0)) -#define SAU_RNR (*(volatile uint32_t *)(0xE000EDD8)) /** SAU_RNR - region number register **/ -#define SAU_RBAR (*(volatile uint32_t *)(0xE000EDDC)) /** SAU_RBAR - region base address register **/ -#define SAU_RLAR (*(volatile uint32_t *)(0xE000EDE0)) /** SAU_RLAR - region limit address register **/ +#ifdef PLATFORM_stm32h5 -#define SAU_REGION_MASK 0x000000FF -#define SAU_ADDR_MASK 0xFFFFFFE0 /* LS 5 bit are reserved or used for flags */ +void hal_tz_sau_init(void) +{ + /* WIP: SAU is set up before staging */ +#if 0 + /* Non-secure callable: NSC functions area */ + sau_init_region(0, 0x0C038000, 0x0C040000, 1); -/* Flag for the SAU region limit register */ -#define SAU_REG_ENABLE (1 << 0) /* Indicates that the region is enabled. */ -#define SAU_REG_SECURE (1 << 1) /* When on, the region is S or NSC */ + /* Secure: application flash area (first bank) */ + sau_init_region(1, 0x08040000, 0x080FFFFF, 1); -#define SAU_INIT_CTRL_ENABLE (1 << 0) -#define SAU_INIT_CTRL_ALLNS (1 << 1) + /* Secure: application flash area (second bank) */ + sau_init_region(2, 0x08140000, 0x081FFFFF, 1); -static void sau_init_region(uint32_t region, uint32_t start_addr, - uint32_t end_addr, int secure) -{ - uint32_t secure_flag = 0; - if (secure) - secure_flag = SAU_REG_SECURE; - SAU_RNR = region & SAU_REGION_MASK; - SAU_RBAR = start_addr & SAU_ADDR_MASK; - SAU_RLAR = (end_addr & SAU_ADDR_MASK) - | secure_flag | SAU_REG_ENABLE; -} + /* Secure RAM regions in SRAM1/SRAM2 */ + sau_init_region(3, 0x0A000000, 0x0A04FFFF, 1); + + /* Non-secure RAM region in SRAM3 */ + sau_init_region(4, 0x0A050000, 0x0A09FFFF, 0); + /* Non-secure: internal peripherals */ + sau_init_region(5, 0x40000000, 0x4FFFFFFF, 0); + /* Enable SAU */ + SAU_CTRL = SAU_INIT_CTRL_ENABLE; + + /* Enable securefault handler */ + SCB_SHCSR |= SCB_SHCSR_SECUREFAULT_EN; +#endif +} + +#else void hal_tz_sau_init(void) { /* Non-secure callable: NSC functions area */ @@ -204,6 +246,40 @@ void hal_tz_sau_init(void) /* Enable securefault handler */ SCB_SHCSR |= SCB_SHCSR_SECUREFAULT_EN; +} +#endif + +void hal_tz_sau_ns_region(void) +{ +#ifdef PLATFORM_stm32h5 + /* Disable SAU */ + SAU_CTRL &= ~SAU_INIT_CTRL_ENABLE; + + /* Non-secure callable: NSC functions area */ + sau_init_region(0, 0x0C038000, 0x0C040000, 1); + + /* Non-secure: application flash area (first bank) */ + sau_init_region(1, 0x08040000, 0x080FFFFF, 0); + + /* Non-secure: application flash area (second bank) */ + sau_init_region(2, 0x08140000, 0x081FFFFF, 0); + + /* Secure RAM regions in SRAM1/SRAM2 */ + sau_init_region(3, 0x0A000000, 0x0A04FFFF, 1); + + /* Non-secure RAM region in SRAM3 */ + sau_init_region(4, 0x0A050000, 0x0A09FFFF, 0); + + /* Non-secure: internal peripherals */ + sau_init_region(5, 0x40000000, 0x4FFFFFFF, 0); + + /* Enable SAU */ + SAU_CTRL = SAU_INIT_CTRL_ENABLE; + + /* Enable securefault handler */ + SCB_SHCSR |= SCB_SHCSR_SECUREFAULT_EN; +#endif + } #ifdef WOLFCRYPT_SECURE_MODE @@ -237,14 +313,10 @@ static void hsi48_on(void) #endif } - void hal_trng_init(void) { uint32_t reg_val; hsi48_on(); -#ifdef PLATFORM_stm32u5 - #define RCC_AHB2_CLOCK_ER RCC_AHB2ENR1_CLOCK_ER -#endif RCC_AHB2_CLOCK_ER |= TRNG_AHB2_CLOCK_ER; reg_val = TRNG_CR; diff --git a/hal/stm32_tz.h b/hal/stm32_tz.h new file mode 100644 index 000000000..85b41eaf6 --- /dev/null +++ b/hal/stm32_tz.h @@ -0,0 +1,57 @@ +/* stm32_tz.h + * + * Copyright (C) 2024 wolfSSL Inc. + * + * This file is part of wolfBoot. + * + * wolfBoot is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfBoot is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + +#ifndef STM32_TZ_INCLUDED +#define STM32_TZ_INCLUDED +#include + +/* SAU registers, used to define memory mapped regions */ +#define SAU_CTRL (*(volatile uint32_t *)(0xE000EDD0)) +#define SAU_RNR (*(volatile uint32_t *)(0xE000EDD8)) /** SAU_RNR - region number register **/ +#define SAU_RBAR (*(volatile uint32_t *)(0xE000EDDC)) /** SAU_RBAR - region base address register **/ +#define SAU_RLAR (*(volatile uint32_t *)(0xE000EDE0)) /** SAU_RLAR - region limit address register **/ + +#define SAU_REGION_MASK 0x000000FF +#define SAU_ADDR_MASK 0xFFFFFFE0 /* LS 5 bit are reserved or used for flags */ + +/* Flag for the SAU region limit register */ +#define SAU_REG_ENABLE (1 << 0) /* Indicates that the region is enabled. */ +#define SAU_REG_SECURE (1 << 1) /* When on, the region is S or NSC */ + +#define SAU_INIT_CTRL_ENABLE (1 << 0) +#define SAU_INIT_CTRL_ALLNS (1 << 1) + +#define SCB_SHCSR (*(volatile uint32_t *)(0xE000ED24)) +#define SCB_SHCSR_SECUREFAULT_EN (1<<19) + +static inline void sau_init_region(uint32_t region, uint32_t start_addr, + uint32_t end_addr, int secure) +{ + uint32_t secure_flag = 0; + if (secure) + secure_flag = SAU_REG_SECURE; + SAU_RNR = region & SAU_REGION_MASK; + SAU_RBAR = start_addr & SAU_ADDR_MASK; + SAU_RLAR = (end_addr & SAU_ADDR_MASK) + | secure_flag | SAU_REG_ENABLE; +} + +#endif diff --git a/hal/stm32h5-ns.ld b/hal/stm32h5-ns.ld index ee4634d27..0ee538bc7 100644 --- a/hal/stm32h5-ns.ld +++ b/hal/stm32h5-ns.ld @@ -1,7 +1,7 @@ MEMORY { FLASH (rx) : ORIGIN = 0x08000000, LENGTH = @BOOTLOADER_PARTITION_SIZE@ - RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00020000 /* mapping TCM only */ + RAM (rwx) : ORIGIN = 0x0A000000, LENGTH = 0x00020000 /* mapping TCM only */ } SECTIONS diff --git a/hal/stm32h5.c b/hal/stm32h5.c index cac379ecf..08f126e2f 100644 --- a/hal/stm32h5.c +++ b/hal/stm32h5.c @@ -71,7 +71,8 @@ int RAMFUNCTION hal_flash_write(uint32_t address, const uint8_t *data, int len) dst = (uint32_t *)address; #if (TZ_SECURE()) - if (address >= FLASH_BANK2_BASE) + if ( ((address < FLASH_BANK2_BASE) && (address >= WOLFBOOT_PARTITION_BOOT_ADDRESS)) || + (address >= WOLFBOOT_PARTITION_UPDATE_ADDRESS)) hal_tz_claim_nonsecure_area(address, len); /* Convert into secure address space */ dst = (uint32_t *)((address & (~FLASHMEM_ADDRESS_SPACE)) | FLASH_SECURE_MMAP_BASE); @@ -301,8 +302,8 @@ static void clock_pll_on(void) } -#if TZ_SECURE() -static void periph_unsecure() +#if (TZ_SECURE()) +static void periph_unsecure(void) { uint32_t pin; @@ -315,19 +316,16 @@ static void periph_unsecure() PWR_CR2 |= PWR_CR2_IOSV; /*Un-secure User LED GPIO pins */ -#ifdef STM32_DISCOVERY - GPIO_SECCFGR(GPIOD_BASE) &= ~(1< RAM . = ALIGN(8); - } END_STACK = ORIGIN(RAM) + LENGTH(RAM); + +_keyvault_origin = ORIGIN(RAM_KV); +_keyvault_size = LENGTH(RAM_KV); + +_flash_keyvault = ORIGIN(FLASH_KEYVAULT); +_flash_keyvault_size = LENGTH(FLASH_KEYVAULT); + +_start_heap = ORIGIN(RAM_HEAP); +_heap_size = LENGTH(RAM_HEAP); diff --git a/hal/stm32u5.h b/hal/stm32u5.h index 1e143ad33..5aa9a5092 100644 --- a/hal/stm32u5.h +++ b/hal/stm32u5.h @@ -164,6 +164,7 @@ /*** FLASH ***/ #define SYSCFG_APB2_CLOCK_ER_VAL (1 << 0) /* <> - RCC_APB2ENR - SYSCFGEN */ + #if (TZ_SECURE()) /*Secure*/ #define FLASH_BASE (0x50022000) /* RM0456 - Table 4 */ @@ -253,6 +254,8 @@ #define GPIOH_AHB2ENR1_CLOCK_ER (1 << 7) #define TRNG_AHB2_CLOCK_ER (1 << 18) +#define RCC_AHB2_CLOCK_ER RCC_AHB2ENR1_CLOCK_ER + /* Reset */ #define OPTR_SWAP_BANK (1 << 20) diff --git a/include/hal.h b/include/hal.h index 404a1aacb..8f3e1ce5c 100644 --- a/include/hal.h +++ b/include/hal.h @@ -113,6 +113,7 @@ void hal_prepare_boot(void); void hal_tz_claim_nonsecure_area(uint32_t address, int len); void hal_tz_release_nonsecure_area(void); void hal_tz_sau_init(void); +void hal_tz_sau_ns_region(void); void hal_gtzc_init(void); /* Needed by TZ to claim/release nonsecure flash areas */ diff --git a/src/boot_arm.c b/src/boot_arm.c index 287ea8288..4a84cd685 100644 --- a/src/boot_arm.c +++ b/src/boot_arm.c @@ -326,10 +326,10 @@ void isr_empty(void) * - Call the application entry point * */ -#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) -#define VTOR (*(volatile uint32_t *)(0xE002ED08)) // SCB_NS -> VTOR -#else #define VTOR (*(volatile uint32_t *)(0xE000ED08)) + +#ifdef TZEN +#include "hal.h" #endif @@ -353,6 +353,12 @@ void RAMFUNCTION do_boot(const uint32_t *app_offset) app_entry = (void *)(*((uint32_t *)(app_offset + 1))); /* Disable interrupts */ asm volatile("cpsid i"); + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) + /* Unclaim secure flash areas if needed */ + hal_tz_sau_ns_region(); +#endif + /* Update IV */ VTOR = ((uint32_t)app_offset); asm volatile("msr msplim, %0" ::"r"(0)); diff --git a/test-app/ARM-stm32h5-ns.ld b/test-app/ARM-stm32h5-ns.ld index ab154492c..f6daef9e7 100644 --- a/test-app/ARM-stm32h5-ns.ld +++ b/test-app/ARM-stm32h5-ns.ld @@ -1,7 +1,7 @@ MEMORY { FLASH (rx) : ORIGIN = @WOLFBOOT_TEST_APP_ADDRESS@, LENGTH = @WOLFBOOT_TEST_APP_SIZE@ - RAM (rwx) : ORIGIN = 0x20020000, LENGTH = 0x20000 + RAM (rwx) : ORIGIN = 0x0A050000, LENGTH = 0x20000 } SECTIONS diff --git a/test-app/app_stm32h5.c b/test-app/app_stm32h5.c index e5f2ab78f..2445f6fdd 100644 --- a/test-app/app_stm32h5.c +++ b/test-app/app_stm32h5.c @@ -119,7 +119,6 @@ void usr2_led_off(void) void main(void) { - hal_init(); boot_led_on(); usr_led_on(); boot_led_off();