Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 50 additions & 0 deletions .github/workflows/trustzone-emulator-tests.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
name: trustzone-emulator-tests

on:
push:
pull_request:

jobs:
trustzone-emulator-tests:
runs-on: ubuntu-latest
container:
image: ghcr.io/danielinux/m33mu-ci:1.2
steps:
- uses: actions/checkout@v4

- name: Init submodules
run: |
git config --global --add safe.directory "$GITHUB_WORKSPACE"
git submodule update --init --single-branch

- name: Configure stm32h5 (TZ) and build wolfboot
run: |
cp config/examples/stm32h5-tz.config .config
make wolfboot.bin

- name: Run emu test (stm32h5)
working-directory: test-app/emu-test-apps
run: |
./test.sh

- name: Clean and build stm32u5 (TZ + wolfcrypt)
run: |
make clean distclean
cp config/examples/stm32u5-wolfcrypt-tz.config .config
make wolfboot.bin

- name: Run emu test (stm32u5)
working-directory: test-app/emu-test-apps
run: |
TARGET=stm32u5 ./test.sh

- name: Clean and build stm32l5 (TZ + wolfcrypt)
run: |
make clean distclean
cp config/examples/stm32l5-wolfcrypt-tz.config .config
make wolfboot.bin

- name: Run emu test (stm32u5)
working-directory: test-app/emu-test-apps
run: |
TARGET=stm32l5 ./test.sh
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
*.idb
*.pdb
*.gdb
*.log

# automatically generated keys
*.der
Expand Down Expand Up @@ -91,6 +92,9 @@ tools/delta/bmpatch
# otp-keystore-gen binary
tools/keytools/otp/otp-keystore-gen

# test-server binary
test-app/emu-test-apps/*/test-update-server

# Vim swap files
.*.swp

Expand Down
2 changes: 1 addition & 1 deletion .gitmodules
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,4 @@
url = https://github.com/wolfssl/wolfhsm.git
[submodule "lib/wolfPSA"]
path = lib/wolfPSA
url = git@github.com:wolfSSL/wolfPSA.git
url = https://github.com/wolfSSL/wolfPSA.git
3 changes: 3 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -340,6 +340,9 @@ hal/$(TARGET).o:

keytools_check: keytools

test-emu:
$(MAKE) -C test-app/emu-test-apps WOLFBOOT_ROOT="$(CURDIR)" test-emu

# Generate the initial signing key (only if not using user-provided keys)
# - Creates wolfboot_signing_private_key.der when USER_PRIVATE_KEY is not set
# - If CERT_CHAIN_VERIFY is enabled and USER_CERT_CHAIN not provided, also generates cert chain with leaf key
Expand Down
8 changes: 4 additions & 4 deletions config/examples/stm32u5-wolfcrypt-tz.config
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,15 @@ V?=0
SPMATH?=1
RAM_CODE?=0
DUALBANK_SWAP?=0
WOLFBOOT_PARTITION_SIZE?=0x1F800
WOLFBOOT_SECTOR_SIZE?=0x800
WOLFBOOT_PARTITION_SIZE?=0x20000
WOLFBOOT_SECTOR_SIZE?=0x2000
WOLFBOOT_KEYVAULT_ADDRESS?=0x0C020000
WOLFBOOT_KEYVAULT_SIZE?=0x18000
WOLFBOOT_NSC_ADDRESS?=0x0C038000
WOLFBOOT_NSC_SIZE?=0x8000
WOLFBOOT_PARTITION_BOOT_ADDRESS?=0x08040000
WOLFBOOT_PARTITION_UPDATE_ADDRESS?=0x805F800
WOLFBOOT_PARTITION_SWAP_ADDRESS?=0x0807F000
WOLFBOOT_PARTITION_UPDATE_ADDRESS?=0x08060000
WOLFBOOT_PARTITION_SWAP_ADDRESS?=0x08080000
FLAGS_HOME=0
DISABLE_BACKUP=0
WOLFCRYPT_TZ=1
Expand Down
2 changes: 1 addition & 1 deletion config/examples/stm32u5.config
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ SPMATH?=1
RAM_CODE?=0
DUALBANK_SWAP?=0
WOLFBOOT_PARTITION_SIZE?=0x1F800
WOLFBOOT_SECTOR_SIZE?=0x800
WOLFBOOT_SECTOR_SIZE?=0x2000
WOLFBOOT_KEYVAULT_ADDRESS?=0x0C020000
WOLFBOOT_KEYVAULT_SIZE?=0x18000
WOLFBOOT_NSC_ADDRESS?=0x0C038000
Expand Down
34 changes: 33 additions & 1 deletion hal/stm32_tz.c
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
#include "hal/stm32u5.h"
#endif

#ifdef TARGET_stm32h5
#if defined(TARGET_stm32h5)
#include "hal/stm32h5.h"
#endif

Expand Down Expand Up @@ -225,6 +225,38 @@ void hal_gtzc_init(void)
}
}

#elif defined(TARGET_stm32u5)

#define GTZC_MPCBB1_S_BASE (0x50032C00)
#define GTZC_MPCBB1_S_VCTR_BASE (GTZC_MPCBB1_S_BASE + 0x100)

#define GTZC_MPCBB2_S_BASE (0x50033000)
#define GTZC_MPCBB2_S_VCTR_BASE (GTZC_MPCBB2_S_BASE + 0x100)

#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;
/* One bit in the bitmask: 512B (STM32U5) */

/* Configure SRAM1 lower 128 KB as secure (0x20000000 - 0x2001FFFF). */
for (i = 0; i < 8; i++) {
SET_GTZC_MPCBBx_S_VCTR(1, i, 0xFFFFFFFF);
}

/* Configure SRAM1 upper 128 KB as non-secure (0x20020000 - 0x2003FFFF). */
for (i = 8; i < 16; i++) {
SET_GTZC_MPCBBx_S_VCTR(1, i, 0x0);
}

/* Configure SRAM2 as non-secure (0x20030000 - 0x2003FFFF). */
for (i = 0; i < 4; i++) {
SET_GTZC_MPCBBx_S_VCTR(2, i, 0x0);
}
}

#else

#define GTZC_MPCBB1_S_BASE (0x50032C00)
Expand Down
8 changes: 0 additions & 8 deletions hal/stm32l5.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@

#include "hal.h"
#include "hal/stm32l5.h"
#include "printf.h"


static void RAMFUNCTION flash_set_waitstates(unsigned int waitstates)
Expand Down Expand Up @@ -152,13 +151,6 @@ int RAMFUNCTION hal_flash_erase(uint32_t address, int len)
uint32_t end_address;
uint32_t p;

if (address < WOLFBOOT_PARTITION_BOOT_ADDRESS) {
wolfBoot_printf("hal_flash_erase: addr=0x%08x len=%d (below boot)\n",
address, len);
} else {
wolfBoot_printf("hal_flash_erase: addr=0x%08x len=%d\n", address, len);
}

hal_flash_clear_errors(0);
if (len == 0)
return -1;
Expand Down
30 changes: 30 additions & 0 deletions hal/stm32u5.c
Original file line number Diff line number Diff line change
Expand Up @@ -489,6 +489,35 @@ static void led_unsecure()
#endif
}

#if TZ_SECURE()
#define TZSC1_BASE 0x50032400u
#define TZSC_SECCFGR1 (*(volatile uint32_t *)(TZSC1_BASE + 0x10u))
#define TZSC_SECCFGR1_USART3SEC (1u << 10)

static void periph_unsecure(void)
{
volatile uint32_t reg;

/* Enable clock for GPIO D (USART3 pins PD8/PD9) */
RCC_AHB2ENR1_CLOCK_ER |= GPIOD_AHB2ENR1_CLOCK_ER;

/* Enable clock for USART3 */
RCC_APB1LENR |= (1u << 18);

/* Unsecure USART3 pins (PD8 TX, PD9 RX) */
GPIOD_SECCFGR &= ~(1u << 8);
GPIOD_SECCFGR &= ~(1u << 9);

/* Unsecure USART3 peripheral in GTZC TZSC */
reg = TZSC_SECCFGR1;
if (reg & TZSC_SECCFGR1_USART3SEC) {
reg &= ~TZSC_SECCFGR1_USART3SEC;
DMB();
TZSC_SECCFGR1 = reg;
}
}
#endif

#if defined(DUALBANK_SWAP) && defined(__WOLFBOOT)
static uint8_t bootloader_copy_mem[BOOTLOADER_SIZE];
static void RAMFUNCTION fork_bootloader(void)
Expand Down Expand Up @@ -530,6 +559,7 @@ void hal_prepare_boot(void)
clock_pll_off();
#endif
#if TZ_SECURE()
periph_unsecure();
led_unsecure();
#endif
}
Expand Down
5 changes: 5 additions & 0 deletions hal/stm32u5.h
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,8 @@

#define RCC_AHB3ENR (*(volatile uint32_t *)(RCC_BASE + 0x94)) /* RM0456 - Table 108 */
#define RCC_AHB3ENR_GTZC2EN (1 << 12)

#define RCC_APB1LENR (*(volatile uint32_t *)(RCC_BASE + 0x9C)) /* RM0456 - Table 108 */
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this should be RCC_APB1ENR1

#define RCC_AHB3ENR_PWREN (1 << 2)

#define RCC_ICSCR1 (*(volatile uint32_t *)(RCC_BASE + 0x08))
Expand Down Expand Up @@ -249,10 +251,12 @@

/* GPIO*/
#define GPIOC_BASE 0x52020800
#define GPIOD_BASE 0x52020C00
#define GPIOG_BASE 0x52021800
#define GPIOH_BASE 0x52021C00

#define GPIOC_SECCFGR (*(volatile uint32_t *)(GPIOC_BASE + 0x30))
#define GPIOD_SECCFGR (*(volatile uint32_t *)(GPIOD_BASE + 0x30))
#define GPIOG_SECCFGR (*(volatile uint32_t *)(GPIOG_BASE + 0x30))
#define GPIOH_SECCFGR (*(volatile uint32_t *)(GPIOH_BASE + 0x30))

Expand All @@ -266,6 +270,7 @@

#define RCC_AHB2ENR1_CLOCK_ER (*(volatile uint32_t *)(RCC_BASE + 0x8C ))
#define GPIOC_AHB2ENR1_CLOCK_ER (1 << 2)
#define GPIOD_AHB2ENR1_CLOCK_ER (1 << 3)
#define GPIOG_AHB2ENR1_CLOCK_ER (1 << 6)
#define GPIOH_AHB2ENR1_CLOCK_ER (1 << 7)
#define TRNG_AHB2_CLOCK_ER (1 << 18)
Expand Down
105 changes: 105 additions & 0 deletions test-app/emu-test-apps/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
# Makefile
#
# Copyright (C) 2026 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 3 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

-include ../../.config
include ../../tools/config.mk
include ../../options.mk
include ../../tools/test.mk

ifneq ($(wildcard $(WOLFBOOT_ROOT)/lib/wolfssl/wolfcrypt/src/asn.c),)
WOLFBOOT_LIB_WOLFSSL:=$(WOLFBOOT_ROOT)/lib/wolfssl
else ifneq ($(wildcard $(WOLFBOOT_ROOT)/../wolfssl/wolfcrypt/src/asn.c),)
WOLFBOOT_LIB_WOLFSSL:=$(WOLFBOOT_ROOT)/../wolfssl
endif
export WOLFBOOT_LIB_WOLFSSL

WOLFBOOT_ROOT?=$(abspath ../..)

EMU_VERSION?=1
EMU_EXPECT_VERSION?=$(EMU_VERSION)
PRIVATE_KEY?=$(WOLFBOOT_ROOT)/wolfboot_signing_private_key.der

M33MU?=$(WOLFBOOT_ROOT)/../m33mu/build/m33mu

ifeq ($(TARGET),stm32h563)
EMU_DIR=stm32h563
EMU_CPU=stm32h563
else ifeq ($(TARGET),stm32h5)
EMU_DIR=stm32h563
EMU_CPU=stm32h563
else ifeq ($(TARGET),stm32u585)
EMU_DIR=stm32u585
EMU_CPU=stm32u585
else ifeq ($(TARGET),stm32u5)
EMU_DIR=stm32u585
EMU_CPU=stm32u585
else ifeq ($(TARGET),stm32l552)
EMU_DIR=stm32l552
EMU_CPU=stm32l552
else ifeq ($(TARGET),stm32l5)
EMU_DIR=stm32l552
EMU_CPU=stm32l552
else ifeq ($(TARGET),nrf5340)
EMU_DIR=nrf5340
EMU_CPU=nrf5340
else ifeq ($(TARGET),mcxw)
EMU_DIR=mcxw71
EMU_CPU=mcxw71c
else ifeq ($(TARGET),mcxw71)
EMU_DIR=mcxw71
EMU_CPU=mcxw71c
else
EMU_DIR=
EMU_CPU=
endif

ifeq ($(strip $(EMU_DIR)),)
$(error Unsupported or unset TARGET=$(TARGET). Use TARGET=stm32h563|stm32h5|stm32u585|stm32u5|stm32l552|stm32l5|nrf5340|mcxw)
endif

EMU_PATH=$(WOLFBOOT_ROOT)/test-app/emu-test-apps/$(EMU_DIR)

.PHONY: all clean test-emu sign-emu run-emu

all:
$(MAKE) -C $(EMU_PATH) clean app.bin

sign-emu: all $(WOLFBOOT_ROOT)/wolfboot_signing_private_key.der
@cp $(EMU_PATH)/app.bin $(EMU_PATH)/image.bin
$(SIGN_ENV) $(SIGN_TOOL) $(SIGN_OPTIONS) $(EMU_PATH)/image.bin $(PRIVATE_KEY) $(EMU_VERSION)

run-emu: sign-emu
@echo "[EMU] CPU=$(EMU_CPU) VERSION=$(EMU_VERSION)"
@$(M33MU) --cpu $(EMU_CPU) --uart-stdout --no-tz --boot-offset=$(IMAGE_HEADER_SIZE) \
$(EMU_PATH)/image_v$(EMU_VERSION)_signed.bin --timeout 2 \
| tee $(EMU_PATH)/emu_uart.log
@grep -q "get_version=$(EMU_EXPECT_VERSION)" $(EMU_PATH)/emu_uart.log

# Entry point for top-level make test-emu
# Builds, signs, runs, and validates UART output.

test-emu: run-emu

clean:
$(MAKE) -C $(EMU_PATH) clean
@rm -f $(EMU_PATH)/image.bin $(EMU_PATH)/image_v*_signed.bin $(EMU_PATH)/emu_uart.log

$(WOLFBOOT_ROOT)/wolfboot_signing_private_key.der:
$(MAKE) -C $(WOLFBOOT_ROOT) WOLFBOOT_LIB_WOLFSSL="$(WOLFBOOT_LIB_WOLFSSL)" wolfboot_signing_private_key.der
31 changes: 31 additions & 0 deletions test-app/emu-test-apps/common/emu_app.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/* emu_app.h
*
* Copyright (C) 2026 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 3 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 EMU_APP_H
#define EMU_APP_H

#include <stdint.h>

void emu_uart_init(void);
int emu_uart_read(uint8_t *c);
void emu_uart_write(uint8_t c);

#endif /* EMU_APP_H */
Loading