STM32H5: added support for TrustZone

- Unified TZ support for STM32L5, STM32H5, STM32U5
- Fixed/added example configuration files
- Expanded documentation
- Added new configurations to automated tests
pull/420/head
Daniele Lacamera 2024-04-10 08:37:06 +02:00
parent fbba5d8370
commit 3ec982109c
31 changed files with 751 additions and 202 deletions

View File

@ -239,12 +239,24 @@ jobs:
arch: arm arch: arm
config-file: ./config/examples/stm32g0.config config-file: ./config/examples/stm32g0.config
stm32h5_test:
uses: ./.github/workflows/test-build.yml
with:
arch: arm
config-file: ./config/examples/stm32h5.config
stm32h5_dualbank_test: stm32h5_dualbank_test:
uses: ./.github/workflows/test-build.yml uses: ./.github/workflows/test-build.yml
with: with:
arch: arm arch: arm
config-file: ./config/examples/stm32h5-dualbank.config config-file: ./config/examples/stm32h5-dualbank.config
stm32h5_wolfcrypt_tz:
uses: ./.github/workflows/test-build.yml
with:
arch: arm
config-file: ./config/examples/stm32h5-wolfcrypt-tz.config
stm32h7_test: stm32h7_test:
uses: ./.github/workflows/test-build.yml uses: ./.github/workflows/test-build.yml
with: with:
@ -289,6 +301,12 @@ jobs:
arch: arm arch: arm
config-file: ./config/examples/stm32l5.config config-file: ./config/examples/stm32l5.config
stm32l5_wolfcrypt_tz:
uses: ./.github/workflows/test-build.yml
with:
arch: arm
config-file: ./config/examples/stm32l5-wolfcrypt-tz.config
stm32u5_nonsecure_dualbank_test: stm32u5_nonsecure_dualbank_test:
uses: ./.github/workflows/test-build.yml uses: ./.github/workflows/test-build.yml
with: with:
@ -301,6 +319,12 @@ jobs:
arch: arm arch: arm
config-file: ./config/examples/stm32u5.config config-file: ./config/examples/stm32u5.config
stm32u5_wolfcrypt_tz:
uses: ./.github/workflows/test-build.yml
with:
arch: arm
config-file: ./config/examples/stm32u5-wolfcrypt-tz.config
stm32wb_delta_enc_ext_test: stm32wb_delta_enc_ext_test:
uses: ./.github/workflows/test-build.yml uses: ./.github/workflows/test-build.yml
with: with:

View File

@ -78,6 +78,7 @@ endif
MAIN_TARGET=factory.bin MAIN_TARGET=factory.bin
TARGET_H_TEMPLATE:=include/target.h.in TARGET_H_TEMPLATE:=include/target.h.in
ifeq ($(TZEN),1)
ifeq ($(TARGET),stm32l5) ifeq ($(TARGET),stm32l5)
# Don't build a contiguous image # Don't build a contiguous image
MAIN_TARGET:=wolfboot.bin test-app/image_v1_signed.bin 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 MAIN_TARGET:=wolfboot.bin test-app/image_v1_signed.bin
endif 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) ifeq ($(TARGET),x86_64_efi)
MAIN_TARGET:=wolfboot.efi MAIN_TARGET:=wolfboot.efi
endif endif

View File

@ -146,8 +146,6 @@ ifeq ($(ARCH),ARM)
WOLFBOOT_ORIGIN=0x0C000000 WOLFBOOT_ORIGIN=0x0C000000
else else
WOLFBOOT_ORIGIN=0x08000000 WOLFBOOT_ORIGIN=0x08000000
endif
ifneq ($(TZEN),1)
LSCRIPT_IN=hal/$(TARGET)-ns.ld LSCRIPT_IN=hal/$(TARGET)-ns.ld
endif endif
endif endif
@ -160,6 +158,7 @@ ifeq ($(ARCH),ARM)
WOLFBOOT_ORIGIN=0x0C000000 WOLFBOOT_ORIGIN=0x0C000000
else else
WOLFBOOT_ORIGIN=0x08000000 WOLFBOOT_ORIGIN=0x08000000
LSCRIPT_IN=hal/$(TARGET)-ns.ld
endif endif
SPI_TARGET=stm32 SPI_TARGET=stm32
endif endif
@ -172,8 +171,6 @@ ifeq ($(ARCH),ARM)
WOLFBOOT_ORIGIN=0x0C000000 WOLFBOOT_ORIGIN=0x0C000000
else else
WOLFBOOT_ORIGIN=0x08000000 WOLFBOOT_ORIGIN=0x08000000
endif
ifneq ($(TZEN),1)
LSCRIPT_IN=hal/$(TARGET)-ns.ld LSCRIPT_IN=hal/$(TARGET)-ns.ld
endif endif
SPI_TARGET=stm32 SPI_TARGET=stm32

View File

@ -18,10 +18,10 @@ V?=0
SPMATH?=1 SPMATH?=1
RAM_CODE?=0 RAM_CODE?=0
DUALBANK_SWAP?=1 DUALBANK_SWAP?=1
WOLFBOOT_PARTITION_SIZE?=0x20000 WOLFBOOT_PARTITION_SIZE?=0xC0000
WOLFBOOT_SECTOR_SIZE?=0x2000 WOLFBOOT_SECTOR_SIZE?=0x2000
WOLFBOOT_PARTITION_BOOT_ADDRESS?=0x08100000 WOLFBOOT_PARTITION_BOOT_ADDRESS?=0x08040000
WOLFBOOT_PARTITION_UPDATE_ADDRESS?=0x817F000 WOLFBOOT_PARTITION_UPDATE_ADDRESS?=0x8140000
WOLFBOOT_PARTITION_SWAP_ADDRESS?=0x81FE000 WOLFBOOT_PARTITION_SWAP_ADDRESS?=0xFFFFFFFF
FLAGS_HOME=0 FLAGS_HOME=0
DISABLE_BACKUP=0 DISABLE_BACKUP=0

View File

@ -0,0 +1,29 @@
ARCH?=ARM
TZEN?=1
TARGET?=stm32h5
SIGN?=ECC256
HASH?=SHA256
DEBUG?=0
VTOR?=1
CORTEX_M0?=0
CORTEX_M33?=1
NO_ASM?=0
NO_MPU=1
EXT_FLASH?=0
SPI_FLASH?=0
ALLOW_DOWNGRADE?=0
NVM_FLASH_WRITEONCE?=1
WOLFBOOT_VERSION?=1
V?=0
SPMATH?=1
RAM_CODE?=0
DUALBANK_SWAP?=0
WOLFBOOT_PARTITION_SIZE?=0xC0000
WOLFBOOT_SECTOR_SIZE?=0x2000
WOLFBOOT_PARTITION_BOOT_ADDRESS?=0x08040000
WOLFBOOT_PARTITION_UPDATE_ADDRESS?=0x8140000
WOLFBOOT_PARTITION_SWAP_ADDRESS?=0x08010000
FLAGS_HOME=0
DISABLE_BACKUP=0
WOLFCRYPT_TZ=1
WOLFCRYPT_TZ_PKCS11=1

View File

@ -1,9 +1,9 @@
ARCH?=ARM ARCH?=ARM
TZEN?=0 TZEN?=1
TARGET?=stm32h5 TARGET?=stm32h5
SIGN?=ECC256 SIGN?=ECC256
HASH?=SHA256 HASH?=SHA256
DEBUG?=1 DEBUG?=0
VTOR?=1 VTOR?=1
CORTEX_M0?=0 CORTEX_M0?=0
CORTEX_M33?=1 CORTEX_M33?=1
@ -18,10 +18,10 @@ V?=0
SPMATH?=1 SPMATH?=1
RAM_CODE?=0 RAM_CODE?=0
DUALBANK_SWAP?=0 DUALBANK_SWAP?=0
WOLFBOOT_PARTITION_SIZE?=0x20000 WOLFBOOT_PARTITION_SIZE?=0xC0000
WOLFBOOT_SECTOR_SIZE?=0x2000 WOLFBOOT_SECTOR_SIZE?=0x2000
WOLFBOOT_PARTITION_BOOT_ADDRESS?=0x08100000 WOLFBOOT_PARTITION_BOOT_ADDRESS?=0x08040000
WOLFBOOT_PARTITION_UPDATE_ADDRESS?=0x817F000 WOLFBOOT_PARTITION_UPDATE_ADDRESS?=0x8140000
WOLFBOOT_PARTITION_SWAP_ADDRESS?=0x81FE000 WOLFBOOT_PARTITION_SWAP_ADDRESS?=0x08010000
FLAGS_HOME=0 FLAGS_HOME=0
DISABLE_BACKUP=0 DISABLE_BACKUP=0

View File

@ -1,5 +1,5 @@
ARCH?=ARM ARCH?=ARM
TZEN?=1 TZEN?=0
TARGET?=stm32l5 TARGET?=stm32l5
SIGN?=ECC256 SIGN?=ECC256
HASH?=SHA256 HASH?=SHA256
@ -17,11 +17,12 @@ WOLFBOOT_VERSION?=1
V?=0 V?=0
SPMATH?=1 SPMATH?=1
RAM_CODE?=0 RAM_CODE?=0
DUALBANK_SWAP?=0 DUALBANK_SWAP?=1
WOLFBOOT_PARTITION_SIZE?=0x1F800 WOLFBOOT_PARTITION_SIZE?=0x30000
WOLFBOOT_SECTOR_SIZE?=0x800 WOLFBOOT_SECTOR_SIZE?=0x2000
WOLFBOOT_PARTITION_BOOT_ADDRESS?=0x08040000 WOLFBOOT_PARTITION_BOOT_ADDRESS?=0x08010000
WOLFBOOT_PARTITION_UPDATE_ADDRESS?=0x805F800 WOLFBOOT_PARTITION_UPDATE_ADDRESS?=0x08110000
WOLFBOOT_PARTITION_SWAP_ADDRESS?=0x0807F000 WOLFBOOT_PARTITION_SWAP_ADDRESS?=0xFFFFFFFF
FLAGS_HOME=0
DISABLE_BACKUP=0 # Use a larger image header size to enforce alignment requirements for the interrupt vector table
IMAGE_HEADER_SIZE?=1024

View File

@ -3,7 +3,7 @@ TZEN?=0
TARGET?=stm32u5 TARGET?=stm32u5
SIGN?=ECC256 SIGN?=ECC256
HASH?=SHA256 HASH?=SHA256
DEBUG?=1 DEBUG?=0
VTOR?=1 VTOR?=1
CORTEX_M0?=0 CORTEX_M0?=0
CORTEX_M33?=1 CORTEX_M33?=1

View File

@ -0,0 +1,29 @@
ARCH?=ARM
TZEN?=1
TARGET?=stm32u5
SIGN?=ECC256
HASH?=SHA256
DEBUG?=0
VTOR?=1
CORTEX_M0?=0
CORTEX_M33?=1
NO_ASM?=0
NO_MPU=1
EXT_FLASH?=0
SPI_FLASH?=0
ALLOW_DOWNGRADE?=0
NVM_FLASH_WRITEONCE?=1
WOLFBOOT_VERSION?=1
V?=0
SPMATH?=1
RAM_CODE?=0
DUALBANK_SWAP?=0
WOLFBOOT_PARTITION_SIZE?=0x1F800
WOLFBOOT_SECTOR_SIZE?=0x800
WOLFBOOT_PARTITION_BOOT_ADDRESS?=0x08040000
WOLFBOOT_PARTITION_UPDATE_ADDRESS?=0x805F800
WOLFBOOT_PARTITION_SWAP_ADDRESS?=0x0807F000
FLAGS_HOME=0
DISABLE_BACKUP=0
WOLFCRYPT_TZ=1
WOLFCRYPT_TZ_PKCS11=1

View File

@ -3,7 +3,7 @@ TZEN?=1
TARGET?=stm32u5 TARGET?=stm32u5
SIGN?=ECC256 SIGN?=ECC256
HASH?=SHA256 HASH?=SHA256
DEBUG?=1 DEBUG?=0
VTOR?=1 VTOR?=1
CORTEX_M0?=0 CORTEX_M0?=0
CORTEX_M33?=1 CORTEX_M33?=1
@ -18,13 +18,10 @@ V?=0
SPMATH?=1 SPMATH?=1
RAM_CODE?=0 RAM_CODE?=0
DUALBANK_SWAP?=0 DUALBANK_SWAP?=0
WOLFBOOT_PARTITION_SIZE?=0x20000 WOLFBOOT_PARTITION_SIZE?=0x1F800
WOLFBOOT_SECTOR_SIZE?=0x2000 WOLFBOOT_SECTOR_SIZE?=0x800
WOLFBOOT_PARTITION_BOOT_ADDRESS?=0x08100000 WOLFBOOT_PARTITION_BOOT_ADDRESS?=0x08040000
WOLFBOOT_PARTITION_UPDATE_ADDRESS?=0x817F000 WOLFBOOT_PARTITION_UPDATE_ADDRESS?=0x805F800
WOLFBOOT_PARTITION_SWAP_ADDRESS?=0x81FE000 WOLFBOOT_PARTITION_SWAP_ADDRESS?=0x0807F000
FLAGS_HOME=0 FLAGS_HOME=0
DISABLE_BACKUP=0 DISABLE_BACKUP=0
# Use a larger image header size to enforce alignment requirements for the interrupt vector table
IMAGE_HEADER_SIZE?=1024

View File

@ -53,7 +53,7 @@ OPTION BYTES BANK: 0
nRST_STOP : 0x1 (No reset generated when entering Stop mode) nRST_STOP : 0x1 (No reset generated when entering Stop mode)
nRST_STDBY : 0x1 (No reset generated when entering Standby mode) nRST_STDBY : 0x1 (No reset generated when entering Standby mode)
nRST_SHDW : 0x1 (No reset generated when entering the Shutdown mode) nRST_SHDW : 0x1 (No reset generated when entering the Shutdown mode)
IWDG_SW : 0x1 (Software independent watchdog) IWDG_SW : 0x1 (Software independant watchdog)
IWDG_STOP : 0x1 (IWDG counter active in stop mode) IWDG_STOP : 0x1 (IWDG counter active in stop mode)
IWDG_STDBY : 0x1 (IWDG counter active in standby mode) IWDG_STDBY : 0x1 (IWDG counter active in standby mode)
WWDG_SW : 0x1 (Software window watchdog) WWDG_SW : 0x1 (Software window watchdog)
@ -115,4 +115,117 @@ STM32_Programmer_CLI -c port=swd -d test-app/image_v1_signed.bin 0x08040000
- Green LED: ECDSA Sign/Verify test successful - Green LED: ECDSA Sign/Verify test successful
### Example using STM32H563
- Copy the example configuration for STM32-L5 with support for wolfCrypt in
TrustZone-M and PKCS11 interface: `cp config/examples/stm32l5-wolfcrypt-tz.config .config`
- Run `make`. `wolfboot.elf` and the test applications are built as separate
objects. The application is signed and stored as `test-app/image_v1_signed.bin`.
- Ensure that the option bytes on your target device are set as follows:
```
OPTION BYTES BANK: 0
Product state:
PRODUCT_STATE: 0xED (Open)
BOR Level:
BOR_LEV : 0x0 (BOR Level 1, the threshold level is low (around 2.1 V))
BORH_EN : 0x0 (0x0)
User Configuration:
IO_VDD_HSLV : 0x0 (0x0)
IO_VDDIO2_HSLV: 0x0 (0x0)
IWDG_STOP : 0x1 (0x1)
IWDG_STDBY : 0x1 (0x1)
BOOT_UBE : 0xB4 (OEM-iRoT (user flash) selected)
SWAP_BANK : 0x0 (0x0)
IWDG_SW : 0x1 (0x1)
NRST_STOP : 0x1 (0x1)
NRST_STDBY : 0x1 (0x1)
OPTION BYTES BANK: 1
User Configuration 2:
TZEN : 0xB4 (Trust zone enabled)
SRAM2_ECC : 0x1 (SRAM2 ECC check disabled)
SRAM3_ECC : 0x1 (SRAM3 ECC check disabled)
BKPRAM_ECC : 0x1 (BKPRAM ECC check disabled)
SRAM2_RST : 0x1 (SRAM2 not erased when a system reset occurs)
SRAM1_3_RST : 0x1 (SRAM1 and SRAM3 not erased when a system reset occurs)
OPTION BYTES BANK: 2
Boot Configuration:
NSBOOTADD : 0x80400 (0x8040000)
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)
OPTION BYTES BANK: 3
Bank1 - Flash watermark area definition:
SECWM1_STRT : 0x0 (0x8000000)
SECWM1_END : 0x1F (0x803E000)
Write sector group protection 1:
WRPSGn1 : 0xFFFFFFFF (0x0)
OPTION BYTES BANK: 4
Bank2 - Flash watermark area definition:
SECWM2_STRT : 0x7F (0x81FE000)
SECWM2_END : 0x0 (0x8100000)
Write sector group protection 2:
WRPSGn2 : 0xFFFFFFFF (0x8000000)
OPTION BYTES BANK: 5
OTP write protection:
LOCKBL : 0x0 (0x0)
OPTION BYTES BANK: 6
Flash data bank 1 sectors:
EDATA1_EN : 0x0 (No Flash high-cycle data area)
EDATA1_STRT : 0x0 (0x0)
OPTION BYTES BANK: 7
Flash data bank 2 sectors :
EDATA2_EN : 0x0 (No Flash high-cycle data area)
EDATA2_STRT : 0x0 (0x0)
OPTION BYTES BANK: 8
Flash HDP bank 1:
HDP1_STRT : 0x1 (0x2000)
HDP1_END : 0x0 (0x0)
OPTION BYTES BANK: 9
Flash HDP bank 2:
HDP2_STRT : 0x1 (0x2000)
HDP2_END : 0x0 (0x0)
```
- Upload `wolfboot.bin` and the test application to the two different domains in flash:
```
STM32_Programmer_CLI -c port=swd -d wolfboot.bin 0x0C000000
STM32_Programmer_CLI -c port=swd -d test-app/image_v1_signed.bin 0x08040000
```
- After rebooting, the LED on the board should turn on sequentially:
- Red LED: Secure boot was successful. Application has started.
- Blue LED: PKCS11 Token has been initialized and stored
- Green LED: ECDSA Sign/Verify test successful

View File

@ -116,16 +116,16 @@ Example 1MB partitioning on STM32L4
### Scenario 1: TrustZone Enabled ### Scenario 1: TrustZone Enabled
__NOTE__: to run wolfBoot in secure mode with wolfCrypt as secure crypto engine,
please refer to [/docs/STM32-TZ.md](/docs/STM32-TZ.md).
#### Example Description #### Example Description
The implementation shows how to switch from secure application to non-secure application, The implementation shows how to switch from secure application to non-secure application,
thanks to the system isolation performed, which splits the internal Flash and internal thanks to the system isolation performed, which splits the internal Flash and internal
SRAM memories into two halves: SRAM memories into two parts:
- the first half for secure application - the first half is used by wolfboot running in secure mode and the secure application
- the second half for non-secure application - the remaining available space is used for non-secure application and update partition
The example configuration for this scenario is available in [/config/examples/stm32l5.config](/config/examples/stm32l5.config).
#### Hardware and Software environment #### Hardware and Software environment
@ -145,7 +145,7 @@ SECWM2_PSTRT=0x1 SECWM2_PEND=0x0 No page of internal Flash Bank2 set as secur
#### How to use it #### How to use it
1. `cp ./config/examples/stm32l5.config .config` 1. `cp ./config/examples/stm32l5.config .config`
2. `make TZEN=1` 2. `make`
3. Prepare board with option bytes configuration reported above 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 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_PSTRT=0x0 SECWM1_PEND=0x7F SECWM2_PSTRT=0x1 SECWM2_PEND=0x0`
@ -160,12 +160,25 @@ SECWM2_PSTRT=0x1 SECWM2_PEND=0x0 No page of internal Flash Bank2 set as secur
* Linux: `/usr/local/STMicroelectronics/STM32Cube/STM32CubeProgrammer/bin/STM32_Programmer_CLI` * Linux: `/usr/local/STMicroelectronics/STM32Cube/STM32CubeProgrammer/bin/STM32_Programmer_CLI`
* Mac OS/X: `/Applications/STMicroelectronics/STM32Cube/STM32CubeProgrammer/STM32CubeProgrammer.app/Contents/MacOs/bin/STM32_Programmer_CLI` * Mac OS/X: `/Applications/STMicroelectronics/STM32Cube/STM32CubeProgrammer/STM32CubeProgrammer.app/Contents/MacOs/bin/STM32_Programmer_CLI`
### Scenario 2: Trustzone Enabled, wolfCrypt as secure engine for NS applications
### Scenario 2: Trustzone Disabled This is similar to Scenario 1, but also includes wolfCrypt in secure mode, and
that can be accessed via PKCS11 interface by non-secure applications.
This option can be enabled with the `WOLFCRYPT_TZ=1` and `WOLFCRYPT_TZ_PKCS11=1`
options in your configuration. This enables a PKCS11 accessible from NS domain via
non-secure callables (NSC).
The example configuration for this scenario is available in [/config/examples/stm32l5-wolfcrypt-tz.config](/config/examples/stm32l5-wolfcrypt-tz.config).
For more information, see [/docs/STM32-TZ.md](/docs/STM32-TZ.md).
### Scenario 3: Trustzone Disabled, using DUAL BANK
#### Example Description #### Example Description
The implementation shows how to use STM32L5xx in DUAL_BANK mode, with TrustZone disabled. The implementation shows how to use STM32L5xx in DUAL BANK mode, with TrustZone disabled.
The DUAL_BANK option is only available on this target when TrustZone is disabled (TZEN = 0). The DUAL_BANK option is only available on this target when TrustZone is disabled (TZEN = 0).
The flash memory is segmented into two different banks: The flash memory is segmented into two different banks:
@ -235,13 +248,23 @@ The STM32U5 is a Cortex-M33 (ARMv8-M).
Note: We have seen issues with vector table alignment, so the default image header size (IMAGE_HEADER_SIZE) has been increased to 1024 bytes to avoid potential issues. Note: We have seen issues with vector table alignment, so the default image header size (IMAGE_HEADER_SIZE) has been increased to 1024 bytes to avoid potential issues.
### Scenario 1: TrustZone Enabled ### Scenario 1: TrustZone enabled, staging non-secure application
#### Example description
The implementation shows how to switch from secure application to non-secure application,
thanks to the system isolation performed, which splits the internal Flash and internal
SRAM memories into two parts:
- the first 256KB are used by wolfboot running in secure mode and the secure application
- the remaining available space is used for non-secure application and update partition
The example configuration for this scenario is available in [/config/examples/stm32u5.config](/config/examples/stm32u5.config).
#### Example Description #### Example Description
The implementation shows how to switch from secure application to non-secure application, The implementation shows how to switch from secure application to non-secure application,
thanks to the system isolation performed, which splits the internal Flash and internal thanks to the system isolation performed, which splits the internal Flash and internal
SRAM memories into two halves: SRAM memories into two parts:
- the first half for secure application - the first half for secure application
- the second half for non-secure application - the second half for non-secure application
@ -278,7 +301,21 @@ SECWM2_PSTRT=0x1 SECWM2_PEND=0x0 No page of internal Flash Bank2 set as secur
* Linux: `/usr/local/STMicroelectronics/STM32Cube/STM32CubeProgrammer/bin/STM32_Programmer_CLI` * Linux: `/usr/local/STMicroelectronics/STM32Cube/STM32CubeProgrammer/bin/STM32_Programmer_CLI`
* Mac OS/X: `/Applications/STMicroelectronics/STM32Cube/STM32CubeProgrammer/STM32CubeProgrammer.app/Contents/MacOs/bin/STM32_Programmer_CLI` * Mac OS/X: `/Applications/STMicroelectronics/STM32Cube/STM32CubeProgrammer/STM32CubeProgrammer.app/Contents/MacOs/bin/STM32_Programmer_CLI`
### Scenario 2: TrustZone Disabled ### 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
that can be accessed via PKCS11 interface by non-secure applications.
This option can be enabled with the `WOLFCRYPT_TZ=1` and `WOLFCRYPT_TZ_PKCS11=1`
options in your configuration. This enables a PKCS11 accessible from NS domain via
non-secure callables (NSC).
The example configuration for this scenario is available in [/config/examples/stm32u5-wolfcrypt-tz.config](/config/examples/stm32u5-wolfcrypt-tz.config).
For more information, see [/docs/STM32-TZ.md](/docs/STM32-TZ.md).
### Scenario 3: TrustZone Disabled (DUAL BANK mode)
#### Example Description #### Example Description
@ -810,7 +847,52 @@ arm-none-eabi-gdb
## STM32H5 ## STM32H5
### DUALBANK mode (Trustzone disabled) Like [STM32L5](#stm32l5) and [STM32U5](#stm32u5), STM32H5 support is also demonstrated
through different scenarios.
### Scenario 1: TrustZone enabled, staging non-secure application
#### Example description
The implementation shows how to switch from secure application to non-secure application,
thanks to the system isolation performed, which splits the internal Flash and internal
SRAM memories into two parts:
- the first 256KB are used by wolfboot running in secure mode and the secure application
- the remaining available space is used for non-secure application and update partition
The example configuration for this scenario is available in [/config/examples/stm32h5.config](/config/examples/stm32h5.config).
#### How to use it
- set the option bytes to enable trustzone:
`STM32_Programmer_CLI -c port=swd -ob TZEN=0xB4`
- set the option bytes to enable flash secure protection of first 256KB:
`STM32_Programmer_CLI -c port=swd -ob SECWM1_PSTRT=0x0 SECWM1_PEND=0x1F SECWM2_PSTRT=0x1F SECWM2_PEND=0x0`
- flash the wolfboot image to the secure partition:
`STM32_Programmer_CLI -c port=swd -d wolfboot.bin 0x0C000000`
- flash the application image to the non-secure partition:
`STM32_Programmer_CLI -c port=swd -d test-app/image_v1_signed.bin 0x08040000`
For a full list of all the option bytes tested with this configuration, refer to [STM32-TZ.md](/docs/STM32-TZ.md).
### 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
that can be accessed via PKCS11 interface by non-secure applications.
This option can be enabled with the `WOLFCRYPT_TZ=1` and `WOLFCRYPT_TZ_PKCS11=1`
options in your configuration. This enables a PKCS11 accessible from NS domain via
non-secure callables (NSC).
The example configuration for this scenario is available in [/config/examples/stm32h5-wolfcrypt-tz.config](/config/examples/stm32h5-wolfcrypt-tz.config).
For more information, see [/docs/STM32-TZ.md](/docs/STM32-TZ.md).
### Scenario 3: DUALBANK mode (Trustzone disabled)
The STM32H5 can be configured to use hardware-assisted bank swapping to facilitate the update. The STM32H5 can be configured to use hardware-assisted bank swapping to facilitate the update.
The configuration file to copy into `.config` is `config/examples/stm32h5-dualbank.config`. The configuration file to copy into `.config` is `config/examples/stm32h5-dualbank.config`.

View File

@ -33,12 +33,12 @@
#include "hal/stm32h5.h" #include "hal/stm32h5.h"
#endif #endif
#include "hal/stm32_tz.h"
#include "image.h" #include "image.h"
#include "hal.h" #include "hal.h"
#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) && (!defined(FLAGS_HOME) || !defined(DISABLE_BACKUP)) #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) 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) #define release_nonsecure_area(...) do{}while(0)
#endif #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 + 0x100))
#define GTZC1_MPCBB2_S ((volatile uint32_t *)(GTZC1_BASE + 0x0C00 + 0x100))
#define GTZC1_MPCBB3_S ((volatile uint32_t *)(GTZC1_BASE + 0x1000 + 0x100))
#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_BASE (0x50032C00)
#define GTZC_MPCBB1_S_VCTR_BASE (GTZC_MPCBB1_S_BASE + 0x100) #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) \ #define SET_GTZC_MPCBBx_S_VCTR(bank,n,val) \
(*((volatile uint32_t *)(GTZC_MPCBB##bank##_S_VCTR_BASE ) + n ))= val (*((volatile uint32_t *)(GTZC_MPCBB##bank##_S_VCTR_BASE ) + n ))= val
void hal_gtzc_init(void) void hal_gtzc_init(void)
{ {
int i; int i;
/* Configure lower half of total RAM as secure /* One bit in the bitmask: 256B */
* 0x3000 0000 : 0x3001 FFFF - 128KB
*/ /* Configure lower half of total RAM as secure
* 0x3000 0000 : 0x3001 FFFF - 128KB
*/
for (i = 0; i < 16; i++) { for (i = 0; i < 16; i++) {
SET_GTZC_MPCBBx_S_VCTR(1, i, 0xFFFFFFFF); SET_GTZC_MPCBBx_S_VCTR(1, i, 0xFFFFFFFF);
} }
@ -147,43 +184,47 @@ void hal_gtzc_init(void)
SET_GTZC_MPCBBx_S_VCTR(1, i, 0x0); SET_GTZC_MPCBBx_S_VCTR(1, i, 0x0);
} }
/* Configure SRAM2 as non-secure /* Configure SRAM2 as non-secure
* 0x2003 0000 : 0x2003 FFFF - 64 KB * 0x2003 0000 : 0x2003 FFFF - 64 KB
*/ */
for (i = 0; i < 8; i++) { for (i = 0; i < 8; i++) {
SET_GTZC_MPCBBx_S_VCTR(2, i, 0x0); SET_GTZC_MPCBBx_S_VCTR(2, i, 0x0);
} }
} }
#endif
/* SAU registers, used to define memory mapped regions */ #ifdef PLATFORM_stm32h5
#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 void hal_tz_sau_init(void)
#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)
static void sau_init_region(uint32_t region, uint32_t start_addr,
uint32_t end_addr, int secure)
{ {
uint32_t secure_flag = 0; uint32_t page_n = 0;
if (secure) /* WIP: SAU is set up before staging */
secure_flag = SAU_REG_SECURE; /* Non-secure callable: NSC functions area */
SAU_RNR = region & SAU_REGION_MASK; sau_init_region(0, 0x0C038000, 0x0C040000, 1);
SAU_RBAR = start_addr & SAU_ADDR_MASK;
SAU_RLAR = (end_addr & SAU_ADDR_MASK) /* Non-Secure: application flash area (first bank) */
| secure_flag | SAU_REG_ENABLE; 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, 0x30000000, 0x3004FFFF, 1);
/* Non-secure RAM region in SRAM3 */
sau_init_region(4, 0x20050000, 0x2008FFFF, 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;
} }
#else
void hal_tz_sau_init(void) void hal_tz_sau_init(void)
{ {
/* Non-secure callable: NSC functions area */ /* Non-secure callable: NSC functions area */
@ -205,6 +246,7 @@ void hal_tz_sau_init(void)
SCB_SHCSR |= SCB_SHCSR_SECUREFAULT_EN; SCB_SHCSR |= SCB_SHCSR_SECUREFAULT_EN;
} }
#endif
#ifdef WOLFCRYPT_SECURE_MODE #ifdef WOLFCRYPT_SECURE_MODE
@ -229,22 +271,17 @@ static void hsi48_on(void)
RCC_CRRCR |= RCC_CRRCR_HSI48ON; RCC_CRRCR |= RCC_CRRCR_HSI48ON;
while ((RCC_CRRCR & RCC_CRRCR_HSI48RDY) == 0) while ((RCC_CRRCR & RCC_CRRCR_HSI48RDY) == 0)
; ;
#endif #else /* U5 and H5 */
#ifdef PLATFORM_stm32u5
RCC_CR |= RCC_CR_HSI48ON; RCC_CR |= RCC_CR_HSI48ON;
while ((RCC_CR & RCC_CR_HSI48RDY) == 0) while ((RCC_CR & RCC_CR_HSI48RDY) == 0)
; ;
#endif #endif
} }
void hal_trng_init(void) void hal_trng_init(void)
{ {
uint32_t reg_val; uint32_t reg_val;
hsi48_on(); hsi48_on();
#ifdef PLATFORM_stm32u5
#define RCC_AHB2_CLOCK_ER RCC_AHB2ENR1_CLOCK_ER
#endif
RCC_AHB2_CLOCK_ER |= TRNG_AHB2_CLOCK_ER; RCC_AHB2_CLOCK_ER |= TRNG_AHB2_CLOCK_ER;
reg_val = TRNG_CR; reg_val = TRNG_CR;
@ -252,9 +289,9 @@ void hal_trng_init(void)
reg_val &= ~(0x7 << TRNG_CR_CLKDIV_SHIFT); reg_val &= ~(0x7 << TRNG_CR_CLKDIV_SHIFT);
reg_val &= ~(0x3 << TRNG_CR_CONFIG2_SHIFT); reg_val &= ~(0x3 << TRNG_CR_CONFIG2_SHIFT);
reg_val &= ~(0x7 << TRNG_CR_CONFIG3_SHIFT); reg_val &= ~(0x7 << TRNG_CR_CONFIG3_SHIFT);
reg_val |= 0x0F << TRNG_CR_CONFIG1_SHIFT; reg_val |= 0x0F << TRNG_CR_CONFIG1_SHIFT;
reg_val |= 0x0D << TRNG_CR_CONFIG3_SHIFT; reg_val |= 0x0D << TRNG_CR_CONFIG3_SHIFT;
#ifdef PLATFORM_stm32u5 /* RM0456 40.6.2 */ #ifdef PLATFORM_stm32u5 /* RM0456 40.6.2 */
reg_val |= 0x06 << TRNG_CR_CLKDIV_SHIFT; reg_val |= 0x06 << TRNG_CR_CLKDIV_SHIFT;
#endif #endif

57
hal/stm32_tz.h 100644
View File

@ -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 <stdint.h>
/* 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

View File

@ -1,7 +1,7 @@
MEMORY MEMORY
{ {
FLASH (rx) : ORIGIN = 0x08000000, LENGTH = @BOOTLOADER_PARTITION_SIZE@ 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 SECTIONS

View File

@ -71,7 +71,8 @@ int RAMFUNCTION hal_flash_write(uint32_t address, const uint8_t *data, int len)
dst = (uint32_t *)address; dst = (uint32_t *)address;
#if (TZ_SECURE()) #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); hal_tz_claim_nonsecure_area(address, len);
/* Convert into secure address space */ /* Convert into secure address space */
dst = (uint32_t *)((address & (~FLASHMEM_ADDRESS_SPACE)) | FLASH_SECURE_MMAP_BASE); dst = (uint32_t *)((address & (~FLASHMEM_ADDRESS_SPACE)) | FLASH_SECURE_MMAP_BASE);
@ -301,8 +302,8 @@ static void clock_pll_on(void)
} }
#if TZ_SECURE() #if (TZ_SECURE())
static void periph_unsecure() static void periph_unsecure(void)
{ {
uint32_t pin; uint32_t pin;
@ -315,19 +316,16 @@ static void periph_unsecure()
PWR_CR2 |= PWR_CR2_IOSV; PWR_CR2 |= PWR_CR2_IOSV;
/*Un-secure User LED GPIO pins */ /*Un-secure User LED GPIO pins */
#ifdef STM32_DISCOVERY GPIO_SECCFGR(GPIOG_BASE) &= ~(1 << 4);
GPIO_SECCFGR(GPIOD_BASE) &= ~(1<<LED_USR_PIN); GPIO_SECCFGR(GPIOB_BASE) &= ~(1 << 0);
GPIO_SECCFGR(GPIOG_BASE) &= ~(1<<LED_BOOT_PIN); GPIO_SECCFGR(GPIOF_BASE) &= ~(1 << 4);
#else /* Nucleo board */
GPIO_SECCFGR(GPIOA_BASE) &= ~(1<<LED_BOOT_PIN);
GPIO_SECCFGR(GPIOB_BASE) &= ~(1<<LED_USR_PIN);
GPIO_SECCFGR(GPIOC_BASE) &= ~(1<<LED_EXTRA_PIN);
#endif
#if 0
/* Unsecure LPUART1 */ /* Unsecure LPUART1 */
TZSC_PRIVCFGR2 &= ~(TZSC_PRIVCFG2_LPUARTPRIV); TZSC_PRIVCFGR2 &= ~(TZSC_PRIVCFG2_LPUARTPRIV);
GPIO_SECCFGR(GPIOG_BASE) &= ~(1<<UART1_TX_PIN); GPIO_SECCFGR(GPIOG_BASE) &= ~(1<<UART1_TX_PIN);
GPIO_SECCFGR(GPIOG_BASE) &= ~(1<<UART1_RX_PIN); GPIO_SECCFGR(GPIOG_BASE) &= ~(1<<UART1_RX_PIN);
#endif
} }
#endif #endif
@ -371,17 +369,22 @@ static uint8_t bootloader_copy_mem[BOOTLOADER_SIZE];
static void fork_bootloader(void) static void fork_bootloader(void)
{ {
uint8_t *data = (uint8_t *) FLASHMEM_ADDRESS_SPACE; uint32_t data = (uint32_t) FLASHMEM_ADDRESS_SPACE;
uint32_t dst = FLASH_BANK2_BASE; uint32_t dst = FLASH_BANK2_BASE;
uint32_t r = 0, w = 0; uint32_t r = 0, w = 0;
int i; int i;
#if TZ_SECURE()
data = (uint32_t)((data & (~FLASHMEM_ADDRESS_SPACE)) | FLASH_SECURE_MMAP_BASE);
dst = (uint32_t)((dst & (~FLASHMEM_ADDRESS_SPACE)) | FLASH_SECURE_MMAP_BASE);
#endif
/* Return if content already matches */ /* Return if content already matches */
if (memcmp(data, (const char*)FLASH_BANK2_BASE, BOOTLOADER_SIZE) == 0) if (memcmp((void *)data, (const char*)dst, BOOTLOADER_SIZE) == 0)
return; return;
/* Read the wolfBoot image in RAM */ /* Read the wolfBoot image in RAM */
memcpy(bootloader_copy_mem, data, BOOTLOADER_SIZE); memcpy(bootloader_copy_mem, (void*)data, BOOTLOADER_SIZE);
/* Mass-erase */ /* Mass-erase */
hal_flash_unlock(); hal_flash_unlock();
@ -393,24 +396,27 @@ static void fork_bootloader(void)
void hal_init(void) void hal_init(void)
{ {
#if defined(DUALBANK_SWAP) && defined(__WOLFBOOT)
if ((FLASH_OPTSR_CUR & (FLASH_OPTSR_SWAP_BANK)) == 0)
fork_bootloader();
#endif
#if TZ_SECURE() #if TZ_SECURE()
hal_tz_sau_init(); hal_tz_sau_init();
hal_gtzc_init(); hal_gtzc_init();
#endif #endif
clock_pll_on(); clock_pll_on();
#if defined(DUALBANK_SWAP) && defined(__WOLFBOOT)
if ((FLASH_OPTSR_CUR & (FLASH_OPTSR_SWAP_BANK)) == 0)
fork_bootloader();
#endif
} }
void hal_prepare_boot(void) void hal_prepare_boot(void)
{ {
clock_pll_off(); clock_pll_off();
#if TZ_SECURE() #if (TZ_SECURE())
periph_unsecure(); periph_unsecure();
#endif #endif
} }

View File

@ -335,6 +335,7 @@
#define GPIOB_BASE 0x52020400 #define GPIOB_BASE 0x52020400
#define GPIOC_BASE 0x52020800 #define GPIOC_BASE 0x52020800
#define GPIOD_BASE 0x52020C00 #define GPIOD_BASE 0x52020C00
#define GPIOF_BASE 0x52021400
#define GPIOG_BASE 0x52021800 #define GPIOG_BASE 0x52021800
/* RCC AHB2 Clock Enable Register */ /* RCC AHB2 Clock Enable Register */
@ -343,8 +344,13 @@
#define GPIOB_AHB2_CLOCK_ER (1 << 1) #define GPIOB_AHB2_CLOCK_ER (1 << 1)
#define GPIOC_AHB2_CLOCK_ER (1 << 2) #define GPIOC_AHB2_CLOCK_ER (1 << 2)
#define GPIOD_AHB2_CLOCK_ER (1 << 3) #define GPIOD_AHB2_CLOCK_ER (1 << 3)
#define GPIOF_AHB2_CLOCK_ER (1 << 5)
#define GPIOG_AHB2_CLOCK_ER (1 << 6) #define GPIOG_AHB2_CLOCK_ER (1 << 6)
#define TRNG_AHB2_CLOCK_ER (1 << 18) #define TRNG_AHB2_CLOCK_ER (1 << 18)
#define PKA_AHB2_CLOCK_ER (1 << 19)
#define SAES_AHB2_CLOCK_ER (1 << 20)
#define SRAM2_AHB2_CLOCK_ER (1 << 30)
#define SRAM3_AHB2_CLOCK_ER (1 << 31)
#define RCC_APB2_CLOCK_ER (*(volatile uint32_t *)(RCC_BASE + 0xA4)) #define RCC_APB2_CLOCK_ER (*(volatile uint32_t *)(RCC_BASE + 0xA4))
#define UART1_APB2_CLOCK_ER_VAL (1 << 14) #define UART1_APB2_CLOCK_ER_VAL (1 << 14)
@ -355,16 +361,12 @@
#define GPIO_SECCFGR(base) (*(volatile uint32_t *)(base + 0x30)) #define GPIO_SECCFGR(base) (*(volatile uint32_t *)(base + 0x30))
#ifdef STM32_DISCOVERY
#define LED_AHB2_ENABLE (GPIOD_AHB2_CLOCK_ER | GPIOG_AHB2_CLOCK_ER)
#define LED_BOOT_PIN (12) /* PG12 - Discovery - Green Led */ #define LED_AHB2_ENABLE (GPIOG_AHB2_CLOCK_ER | GPIOB_AHB2_CLOCK_ER | \
#define LED_USR_PIN (3) /* PD3 - Discovery - Red Led */ GPIOF_AHB2_CLOCK_ER)
#else #define LED_BOOT_PIN (4) /* PG4 - Nucleo board - Orange Led */
#define LED_AHB2_ENABLE (GPIOA_AHB2_CLOCK_ER | GPIOB_AHB2_CLOCK_ER | \ #define LED_USR_PIN (0) /* PB0 - Nucleo board - Green Led */
GPIOC_AHB2_CLOCK_ER) #define LED_EXTRA_PIN (4) /* PF4 - Nucleo board - Blue Led */
#define LED_BOOT_PIN (9) /* PA9 - Nucleo board - Red Led */
#define LED_USR_PIN (7) /* PC7 - Nucleo board - Green Led */
#define LED_EXTRA_PIN (7) /* PB7 - Nucleo board - Blue Led */
#endif
#endif /* STM32H5_DEF_INCLUDED */ #endif /* STM32H5_DEF_INCLUDED */

View File

@ -1,8 +1,11 @@
MEMORY MEMORY
{ {
FLASH (rx) : ORIGIN = @WOLFBOOT_ORIGIN@, LENGTH = @BOOTLOADER_PARTITION_SIZE@ FLASH (rx) : ORIGIN = @WOLFBOOT_ORIGIN@, LENGTH = @BOOTLOADER_PARTITION_SIZE@ - 0x20000
RAM (rwx) : ORIGIN = 0x30000000, LENGTH = 0x00017FFF RAM (rwx) : ORIGIN = 0x30000000, LENGTH = 0x30000
FLASH_NSC(rx): ORIGIN = @WOLFBOOT_ORIGIN@ + 0x20000, LENGTH = 0x20000 RAM_KV (rw): ORIGIN = 0x30020000, LENGTH = 0x10000
RAM_HEAP (rw): ORIGIN = 0x30030000, LENGTH = 0x10000 /* 64KB Heap for wolfcrypt/PKCS11 */
FLASH_KEYVAULT(rw): ORIGIN = @WOLFBOOT_ORIGIN@ + 0x20000, LENGTH = 0x18000
FLASH_NSC(rx): ORIGIN = @WOLFBOOT_ORIGIN@ + 0x38000, LENGTH = 0x8000
} }
SECTIONS SECTIONS
@ -25,6 +28,7 @@ SECTIONS
.gnu.sgstubs : .gnu.sgstubs :
{ {
. += 0x400;
. = ALIGN(4); . = ALIGN(4);
*(.gnu.sgstubs*) /* Secure Gateway stubs */ *(.gnu.sgstubs*) /* Secure Gateway stubs */
. = ALIGN(4); . = ALIGN(4);
@ -53,7 +57,15 @@ SECTIONS
_end = .; _end = .;
} > RAM } > RAM
. = ALIGN(8); . = ALIGN(8);
} }
END_STACK = ORIGIN(RAM) + LENGTH(RAM); 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);

50
hal/stm32u5-ns.ld 100644
View File

@ -0,0 +1,50 @@
MEMORY
{
FLASH (rx) : ORIGIN = 0x08000000, LENGTH = @BOOTLOADER_PARTITION_SIZE@
RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00020000 /* mapping TCM only */
}
SECTIONS
{
.text :
{
_start_text = .;
KEEP(*(.isr_vector))
*(.text*)
*(.rodata*)
. = ALIGN(4);
_end_text = .;
} > FLASH
.edidx :
{
. = ALIGN(4);
*(.ARM.exidx*)
} > FLASH
_stored_data = .;
.data : AT (_stored_data)
{
_start_data = .;
KEEP(*(.data*))
. = ALIGN(4);
KEEP(*(.ramcode))
. = ALIGN(4);
_end_data = .;
} > RAM
.bss (NOLOAD) :
{
_start_bss = .;
__bss_start__ = .;
*(.bss*)
*(COMMON)
. = ALIGN(4);
_end_bss = .;
__bss_end__ = .;
_end = .;
} > RAM
. = ALIGN(4);
}
END_STACK = ORIGIN(RAM) + LENGTH(RAM);

View File

@ -164,6 +164,7 @@
/*** FLASH ***/ /*** FLASH ***/
#define SYSCFG_APB2_CLOCK_ER_VAL (1 << 0) /* <<RM0438>> - RCC_APB2ENR - SYSCFGEN */ #define SYSCFG_APB2_CLOCK_ER_VAL (1 << 0) /* <<RM0438>> - RCC_APB2ENR - SYSCFGEN */
#if (TZ_SECURE()) #if (TZ_SECURE())
/*Secure*/ /*Secure*/
#define FLASH_BASE (0x50022000) /* RM0456 - Table 4 */ #define FLASH_BASE (0x50022000) /* RM0456 - Table 4 */
@ -253,6 +254,8 @@
#define GPIOH_AHB2ENR1_CLOCK_ER (1 << 7) #define GPIOH_AHB2ENR1_CLOCK_ER (1 << 7)
#define TRNG_AHB2_CLOCK_ER (1 << 18) #define TRNG_AHB2_CLOCK_ER (1 << 18)
#define RCC_AHB2_CLOCK_ER RCC_AHB2ENR1_CLOCK_ER
/* Reset */ /* Reset */
#define OPTR_SWAP_BANK (1 << 20) #define OPTR_SWAP_BANK (1 << 20)

View File

@ -1,8 +1,11 @@
MEMORY MEMORY
{ {
FLASH (rx) : ORIGIN = @WOLFBOOT_ORIGIN@, LENGTH = @BOOTLOADER_PARTITION_SIZE@ FLASH (rx) : ORIGIN = @WOLFBOOT_ORIGIN@, LENGTH = @BOOTLOADER_PARTITION_SIZE@ - 0x20000
RAM (rwx) : ORIGIN = 0x30000000, LENGTH = 0x00017FFF RAM (rwx) : ORIGIN = 0x30000000, LENGTH = 0x00012000
FLASH_NSC(rx): ORIGIN = @WOLFBOOT_ORIGIN@ + 0x20000, LENGTH = 0x20000 RAM_HEAP (rw): ORIGIN = 0x30012000, LENGTH = 0xc000 /* 49152 B Heap for wolfcrypt/PKCS11 */
RAM_KV (rw): ORIGIN = 0x3001e000, LENGTH = 0x2000
FLASH_KEYVAULT(rw): ORIGIN = @WOLFBOOT_ORIGIN@ + 0x20000, LENGTH = 0x18000
FLASH_NSC(rx): ORIGIN = @WOLFBOOT_ORIGIN@ + 0x38000, LENGTH = 0x8000
} }
SECTIONS SECTIONS
@ -25,6 +28,7 @@ SECTIONS
.gnu.sgstubs : .gnu.sgstubs :
{ {
. += 0x400;
. = ALIGN(4); . = ALIGN(4);
*(.gnu.sgstubs*) /* Secure Gateway stubs */ *(.gnu.sgstubs*) /* Secure Gateway stubs */
. = ALIGN(4); . = ALIGN(4);
@ -53,7 +57,15 @@ SECTIONS
_end = .; _end = .;
} > RAM } > RAM
. = ALIGN(8); . = ALIGN(8);
} }
END_STACK = ORIGIN(RAM) + LENGTH(RAM); 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);

View File

@ -113,6 +113,7 @@ void hal_prepare_boot(void);
void hal_tz_claim_nonsecure_area(uint32_t address, int len); void hal_tz_claim_nonsecure_area(uint32_t address, int len);
void hal_tz_release_nonsecure_area(void); void hal_tz_release_nonsecure_area(void);
void hal_tz_sau_init(void); void hal_tz_sau_init(void);
void hal_tz_sau_ns_region(void);
void hal_gtzc_init(void); void hal_gtzc_init(void);
/* Needed by TZ to claim/release nonsecure flash areas */ /* Needed by TZ to claim/release nonsecure flash areas */

View File

@ -254,6 +254,7 @@ extern int tolower(int c);
#endif #endif
#if defined(SECURE_PKCS11) #if defined(SECURE_PKCS11)
# include <time.h>
# define HAVE_PWDBASED # define HAVE_PWDBASED
# define HAVE_PBKDF2 # define HAVE_PBKDF2
# define WOLFPKCS11_CUSTOM_STORE # define WOLFPKCS11_CUSTOM_STORE
@ -268,7 +269,6 @@ extern int tolower(int c);
# define HAVE_SCRYPT # define HAVE_SCRYPT
# define HAVE_AESGCM # define HAVE_AESGCM
# define HAVE_PKCS8 # define HAVE_PKCS8
typedef unsigned long time_t;
#endif #endif
#ifndef HAVE_PWDBASED #ifndef HAVE_PWDBASED
@ -412,10 +412,6 @@ extern int tolower(int c);
# define WOLFSSL_SMALL_STACK # define WOLFSSL_SMALL_STACK
#endif #endif
#ifdef WOLFCRYPT_SECURE_MODE
typedef unsigned long time_t;
#endif
#endif /* WOLFBOOT_PKCS11_APP */ #endif /* WOLFBOOT_PKCS11_APP */
#endif /* !H_USER_SETTINGS_ */ #endif /* !H_USER_SETTINGS_ */

View File

@ -647,9 +647,6 @@ ifeq ($(WOLFCRYPT_TZ_PKCS11),1)
./lib/wolfPKCS11/src/internal.o \ ./lib/wolfPKCS11/src/internal.o \
./lib/wolfPKCS11/src/slot.o \ ./lib/wolfPKCS11/src/slot.o \
./lib/wolfPKCS11/src/wolfpkcs11.o ./lib/wolfPKCS11/src/wolfpkcs11.o
endif
ifeq ($(WOLFCRYPT_TZ),1)
STACK_USAGE=16688 STACK_USAGE=16688
endif endif

View File

@ -326,10 +326,10 @@ void isr_empty(void)
* - Call the application entry point * - 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)) #define VTOR (*(volatile uint32_t *)(0xE000ED08))
#ifdef TZEN
#include "hal.h"
#endif #endif
@ -353,6 +353,7 @@ void RAMFUNCTION do_boot(const uint32_t *app_offset)
app_entry = (void *)(*((uint32_t *)(app_offset + 1))); app_entry = (void *)(*((uint32_t *)(app_offset + 1)));
/* Disable interrupts */ /* Disable interrupts */
asm volatile("cpsid i"); asm volatile("cpsid i");
/* Update IV */ /* Update IV */
VTOR = ((uint32_t)app_offset); VTOR = ((uint32_t)app_offset);
asm volatile("msr msplim, %0" ::"r"(0)); asm volatile("msr msplim, %0" ::"r"(0));

View File

@ -1,7 +1,7 @@
MEMORY MEMORY
{ {
FLASH (rx) : ORIGIN = @WOLFBOOT_TEST_APP_ADDRESS@, LENGTH = @WOLFBOOT_TEST_APP_SIZE@ FLASH (rx) : ORIGIN = @WOLFBOOT_TEST_APP_ADDRESS@, LENGTH = @WOLFBOOT_TEST_APP_SIZE@
RAM (rwx) : ORIGIN = 0x20020000, LENGTH = 0x20000 RAM (rwx) : ORIGIN = 0x20050000, LENGTH = 0x40000
} }
SECTIONS SECTIONS

View File

@ -90,7 +90,7 @@ ifeq ($(TZEN),1)
APP_OBJS+=./wcs/wc_encrypt.o APP_OBJS+=./wcs/wc_encrypt.o
APP_OBJS+=./wcs/wc_port.o APP_OBJS+=./wcs/wc_port.o
endif endif
CFLAGS+=-DWOLFBOOT_SECURE_CALLS -Wstack-usage=12940 CFLAGS+=-DWOLFBOOT_SECURE_CALLS -Wstack-usage=12944
endif endif
else else
APP_OBJS+=../hal/$(TARGET).o APP_OBJS+=../hal/$(TARGET).o

View File

@ -29,9 +29,18 @@
#include "hal.h" #include "hal.h"
#include "wolfboot/wolfboot.h" #include "wolfboot/wolfboot.h"
#ifdef SECURE_PKCS11
#include "wcs/user_settings.h"
#include <wolfssl/wolfcrypt/settings.h>
#include <wolfssl/wolfcrypt/wc_pkcs11.h>
#include <wolfssl/wolfcrypt/random.h>
extern const char pkcs11_library_name[];
extern const CK_FUNCTION_LIST wolfpkcs11nsFunctionList;
#endif
#define LED_BOOT_PIN (4) /* PG4 - Nucleo - Red Led */ #define LED_BOOT_PIN (4) /* PG4 - Nucleo - Red Led */
#define LED_USR_PIN (0) /* PB0 - Nucleo - Green Led */ #define LED_USR_PIN (0) /* PB0 - Nucleo - Green Led */
#define LED_USR2_PIN (4) /* PF4 - Nucleo - Orange Led */ #define LED_EXTRA_PIN (4) /* PF4 - Nucleo - Orange Led */
/*Non-Secure */ /*Non-Secure */
#define RCC_BASE (0x44020C00) /* RM0481 - Table 3 */ #define RCC_BASE (0x44020C00) /* RM0481 - Table 3 */
@ -97,10 +106,10 @@ void usr_led_off(void)
GPIOB_BSRR |= (1 << (LED_USR_PIN + 16)); GPIOB_BSRR |= (1 << (LED_USR_PIN + 16));
} }
void usr2_led_on(void) void extra_led_on(void)
{ {
uint32_t reg; uint32_t reg;
uint32_t pin = LED_USR2_PIN; uint32_t pin = LED_EXTRA_PIN;
RCC_AHB2ENR1_CLOCK_ER|= GPIOF_AHB2ENR1_CLOCK_ER; RCC_AHB2ENR1_CLOCK_ER|= GPIOF_AHB2ENR1_CLOCK_ER;
/* Delay after an RCC peripheral clock enabling */ /* Delay after an RCC peripheral clock enabling */
@ -112,19 +121,103 @@ void usr2_led_on(void)
GPIOF_BSRR |= (1 << (pin)); GPIOF_BSRR |= (1 << (pin));
} }
void usr2_led_off(void) void extra_led_off(void)
{ {
GPIOF_BSRR |= (1 << (LED_USR2_PIN + 16)); GPIOF_BSRR |= (1 << (LED_EXTRA_PIN + 16));
} }
static char CaBuf[2048];
static uint8_t my_pubkey[200];
extern int ecdsa_sign_verify(int devId);
void main(void) void main(void)
{ {
hal_init(); int ret;
uint32_t rand;
uint32_t i;
uint32_t klen = 200;
int otherkey_slot;
unsigned int devId = 0;
#ifdef SECURE_PKCS11
WC_RNG rng;
Pkcs11Token token;
Pkcs11Dev PKCS11_d;
unsigned long session;
char TokenPin[] = "0123456789ABCDEF";
char UserPin[] = "ABCDEF0123456789";
char SoPinName[] = "SO-PIN";
#endif
/* Turn on boot LED */
boot_led_on(); boot_led_on();
usr_led_on();
boot_led_off(); #ifdef SECURE_PKCS11
if (wolfBoot_current_firmware_version() > 1) wolfCrypt_Init();
usr2_led_on();
PKCS11_d.heap = NULL,
PKCS11_d.func = (CK_FUNCTION_LIST *)&wolfpkcs11nsFunctionList;
ret = wc_Pkcs11Token_Init(&token, &PKCS11_d, 1, "EccKey",
(const byte*)TokenPin, strlen(TokenPin));
if (ret == 0) {
ret = wolfpkcs11nsFunctionList.C_OpenSession(1,
CKF_SERIAL_SESSION | CKF_RW_SESSION,
NULL, NULL, &session);
}
if (ret == 0) {
ret = wolfpkcs11nsFunctionList.C_InitToken(1,
(byte *)TokenPin, strlen(TokenPin), (byte *)SoPinName);
}
if (ret == 0) {
extra_led_on();
ret = wolfpkcs11nsFunctionList.C_Login(session, CKU_SO,
(byte *)TokenPin,
strlen(TokenPin));
}
if (ret == 0) {
ret = wolfpkcs11nsFunctionList.C_InitPIN(session,
(byte *)TokenPin,
strlen(TokenPin));
}
if (ret == 0) {
ret = wolfpkcs11nsFunctionList.C_Logout(session);
}
if (ret != 0) {
while(1)
;
}
if (ret == 0) {
ret = wc_CryptoDev_RegisterDevice(devId, wc_Pkcs11_CryptoDevCb,
&token);
if (ret != 0) {
while(1)
;
}
if (ret == 0) {
#ifdef HAVE_ECC
ret = ecdsa_sign_verify(devId);
if (ret != 0)
ret = 1;
else
usr_led_on();
#endif
}
wc_Pkcs11Token_Final(&token);
}
#else
/* Check if version > 1 and turn on user led */
if (wolfBoot_current_firmware_version() > 1) {
usr_led_on();
}
#endif /* SECURE_PKCS11 */
while(1) while(1)
; ;
/* Never reached */
} }

View File

@ -34,7 +34,7 @@ extern void isr_tim2(void);
#endif #endif
#ifndef STACK_PAINTING #ifndef STACK_PAINTING
#define STACK_PAINTING 1 #define STACK_PAINTING 0
#endif #endif
static volatile unsigned int avail_mem = 0; static volatile unsigned int avail_mem = 0;

View File

@ -80,7 +80,9 @@ CK_FUNCTION_LIST wolfpkcs11nsFunctionList = {
const char pkcs11_library_name[]="wolfCrypt_secure_mode"; const char pkcs11_library_name[]="wolfCrypt_secure_mode";
extern unsigned int _start_heap; extern unsigned int _start_heap;
#ifndef NULL
#define NULL (((void *)0)) #define NULL (((void *)0))
#endif
void * _sbrk(unsigned int incr) void * _sbrk(unsigned int incr)
{ {

View File

@ -48,6 +48,7 @@ extern int tolower(int c);
#define HAVE_WOLF_BIGINT #define HAVE_WOLF_BIGINT
#define HAVE_PKCS11_STATIC #define HAVE_PKCS11_STATIC
#define WOLF_CRYPTO_CB #define WOLF_CRYPTO_CB
#define MAX_CRYPTO_DEVID_CALLBACKS 2
/* ECC */ /* ECC */