Skip to content

Commit b22c85e

Browse files
committed
Added support for fTPM in TrustZone + STM32H5 test app
1 parent 71b395d commit b22c85e

15 files changed

Lines changed: 780 additions & 12 deletions

File tree

.github/workflows/trustzone-emulator-tests.yml

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,19 @@ jobs:
106106
make
107107
m33mu wolfboot.bin test-app/image_v1_signed.bin:0x60000 --uart-stdout --expect-bkpt 0x7f --timeout 600
108108
109+
- name: Clean and build test with fTPM (stm32h5)
110+
run: |
111+
make clean distclean
112+
cp config/examples/stm32h5-tz-ftpm.config .config
113+
make
114+
m33mu wolfboot.bin test-app/image_v1_signed.bin:0x60000 --uart-stdout --expect-bkpt 0x7f --timeout 600 \
115+
| tee /tmp/m33mu-ftpm.log
116+
grep -q "fTPM PCR0 extended:" /tmp/m33mu-ftpm.log
117+
grep -q "fTPM unsealed secret: wolfBoot fTPM PCR secret" /tmp/m33mu-ftpm.log
118+
grep -q "fTPM NSC tests passed" /tmp/m33mu-ftpm.log
119+
grep -q "\\[BKPT\\] imm=0x7f" /tmp/m33mu-ftpm.log
120+
grep -q "\\[EXPECT BKPT\\] Success" /tmp/m33mu-ftpm.log
121+
109122
- name: Clean and build test with DICE attestation + OTP (stm32h5)
110123
run: |
111124
make clean distclean

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -575,7 +575,7 @@ keys: $(PRIVATE_KEY)
575575
clean:
576576
$(Q)rm -f src/*.o hal/*.o hal/spi/*.o test-app/*.o src/x86/*.o
577577
$(Q)rm -f src/wolfboot_tz_nsc.o
578-
$(Q)rm -f $(WOLFBOOT_LIB_WOLFSSL)/wolfcrypt/src/*.o $(WOLFBOOT_LIB_WOLFTPM)/src/*.o $(WOLFBOOT_LIB_WOLFTPM)/hal/*.o $(WOLFBOOT_LIB_WOLFTPM)/examples/pcr/*.o
578+
$(Q)rm -f $(WOLFBOOT_LIB_WOLFSSL)/wolfcrypt/src/*.o $(WOLFBOOT_LIB_WOLFTPM)/src/*.o $(WOLFBOOT_LIB_WOLFTPM)/src/fwtpm/*.o $(WOLFBOOT_LIB_WOLFTPM)/hal/*.o $(WOLFBOOT_LIB_WOLFTPM)/examples/pcr/*.o
579579
$(Q)rm -f $(WOLFBOOT_LIB_WOLFSSL)/wolfcrypt/src/port/Renesas/*.o
580580
$(Q)rm -f wolfboot.bin wolfboot.elf wolfboot.map test-update.rom wolfboot.hex wolfboot.srec factory.srec
581581
$(Q)rm -f $(MACHINE_OBJ) $(MAIN_TARGET) $(LSCRIPT)
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
ARCH?=ARM
2+
TZEN?=1
3+
TARGET?=stm32h5
4+
SIGN?=ECC256
5+
HASH?=SHA256
6+
DEBUG?=0
7+
VTOR?=1
8+
CORTEX_M0?=0
9+
CORTEX_M33?=1
10+
NO_ASM?=0
11+
NO_MPU=1
12+
EXT_FLASH?=0
13+
SPI_FLASH?=0
14+
ALLOW_DOWNGRADE?=0
15+
NVM_FLASH_WRITEONCE?=1
16+
WOLFBOOT_VERSION?=1
17+
V?=0
18+
SPMATH?=1
19+
RAM_CODE?=1
20+
DUALBANK_SWAP?=0
21+
WOLFBOOT_PARTITION_SIZE?=0xA0000
22+
WOLFBOOT_SECTOR_SIZE?=0x2000
23+
WOLFBOOT_KEYVAULT_ADDRESS?=0x0C040000
24+
WOLFBOOT_KEYVAULT_SIZE?=0x1C000
25+
WOLFBOOT_NSC_ADDRESS?=0x0C05C000
26+
WOLFBOOT_NSC_SIZE?=0x4000
27+
WOLFBOOT_PARTITION_BOOT_ADDRESS?=0x08060000
28+
WOLFBOOT_PARTITION_UPDATE_ADDRESS?=0x0C100000
29+
WOLFBOOT_PARTITION_SWAP_ADDRESS?=0x0C1A0000
30+
FLAGS_HOME=0
31+
DISABLE_BACKUP=0
32+
WOLFCRYPT_TZ=1
33+
WOLFCRYPT_TZ_FTPM=1
34+
IMAGE_HEADER_SIZE?=1024
35+
ARMORED=1

include/user_settings.h

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -434,7 +434,7 @@ extern int tolower(int c);
434434
# define NO_CODING
435435
#endif
436436

437-
#ifdef WOLFBOOT_TPM
437+
#if defined(WOLFBOOT_TPM) && !defined(WOLFBOOT_TZ_FTPM)
438438
/* Do not use heap */
439439
#define WOLFTPM2_NO_HEAP
440440
/* small stack options */
@@ -632,6 +632,13 @@ extern int tolower(int c);
632632
#undef NO_KDF
633633
#endif
634634

635+
#if defined(WOLFBOOT_TZ_FTPM)
636+
#undef NO_CMAC
637+
#undef NO_KDF
638+
#define WOLFSSL_AES_CFB
639+
#define WOLFSSL_SHA384
640+
#endif
641+
635642
#ifdef __QNX__
636643
# define WOLFSSL_HAVE_MIN
637644
# define WOLFSSL_HAVE_MAX

include/wolfboot/wcs_ftpm.h

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
/* wcs_ftpm.h
2+
*
3+
* Copyright (C) 2026 wolfSSL Inc.
4+
*
5+
* This file is part of wolfBoot.
6+
*/
7+
8+
#ifndef WOLFBOOT_WCS_FTPM_H
9+
#define WOLFBOOT_WCS_FTPM_H
10+
11+
#include <stdint.h>
12+
#include "wolfboot/wc_secure.h"
13+
14+
#ifdef WOLFBOOT_TZ_FTPM
15+
16+
#ifndef WCS_FTPM_MAX_COMMAND_SIZE
17+
#define WCS_FTPM_MAX_COMMAND_SIZE 4096U
18+
#endif
19+
20+
int CSME_NSE_API wcs_ftpm_transmit(const uint8_t *cmd, uint32_t cmdSz,
21+
uint8_t *rsp, uint32_t *rspSz);
22+
23+
void wcs_ftpm_init(void);
24+
25+
#endif /* WOLFBOOT_TZ_FTPM */
26+
27+
#endif /* WOLFBOOT_WCS_FTPM_H */

lib/wolfTPM

Submodule wolfTPM updated 128 files

options.mk

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -810,6 +810,15 @@ ifeq ($(WOLFCRYPT_TZ_PKCS11),1)
810810
ifeq ($(WOLFCRYPT_TZ_PSA),1)
811811
$(error WOLFCRYPT_TZ_PKCS11 and WOLFCRYPT_TZ_PSA are mutually exclusive)
812812
endif
813+
ifeq ($(WOLFCRYPT_TZ_FTPM),1)
814+
$(error WOLFCRYPT_TZ_PKCS11 and WOLFCRYPT_TZ_FTPM are mutually exclusive)
815+
endif
816+
endif
817+
818+
ifeq ($(WOLFCRYPT_TZ_PSA),1)
819+
ifeq ($(WOLFCRYPT_TZ_FTPM),1)
820+
$(error WOLFCRYPT_TZ_PSA and WOLFCRYPT_TZ_FTPM are mutually exclusive)
821+
endif
813822
endif
814823

815824
ifeq ($(WOLFCRYPT_TZ_PKCS11),1)
@@ -919,6 +928,50 @@ ifeq ($(WOLFCRYPT_TZ_PSA),1)
919928
endif
920929
endif
921930

931+
ifeq ($(WOLFCRYPT_TZ_FTPM),1)
932+
CFLAGS+=-DWOLFBOOT_TZ_FTPM
933+
CFLAGS+=-DWOLFCRYPT_SECURE_MODE
934+
CFLAGS+=-DWOLFTPM_FWTPM
935+
CFLAGS+=-DFWTPM_NO_NV
936+
CFLAGS+=-DWC_RSA_PSS
937+
CFLAGS+=-DWOLFSSL_PSS_SALT_LEN_DISCOVER
938+
CFLAGS+=-DFWTPM_MAX_COMMAND_SIZE=4096
939+
CFLAGS+=-I$(WOLFBOOT_LIB_WOLFTPM)
940+
ifeq ($(USE_CLANG),1)
941+
CLANG_MULTILIB_FLAGS:=$(filter -mthumb -mlittle-endian,$(LDFLAGS)) $(filter -mcpu=%,$(CFLAGS))
942+
LIBS+=$(shell $(CLANG_GCC_NAME) $(CLANG_MULTILIB_FLAGS) -print-file-name=libc.a)
943+
LIBS+=$(shell $(CLANG_GCC_NAME) $(CLANG_MULTILIB_FLAGS) -print-libgcc-file-name)
944+
else
945+
LDFLAGS+=--specs=nano.specs
946+
endif
947+
WOLFCRYPT_OBJS+=src/store_sbrk.o
948+
WOLFCRYPT_OBJS+=src/ftpm_callable.o
949+
WOLFCRYPT_OBJS+=$(WOLFBOOT_LIB_WOLFTPM)/src/fwtpm/fwtpm.o
950+
WOLFCRYPT_OBJS+=$(WOLFBOOT_LIB_WOLFTPM)/src/fwtpm/fwtpm_command.o
951+
WOLFCRYPT_OBJS+=$(WOLFBOOT_LIB_WOLFTPM)/src/fwtpm/fwtpm_crypto.o
952+
WOLFCRYPT_OBJS+=$(WOLFBOOT_LIB_WOLFTPM)/src/fwtpm/fwtpm_nv.o
953+
WOLFCRYPT_OBJS+=$(WOLFBOOT_LIB_WOLFTPM)/src/tpm2_util.o
954+
WOLFCRYPT_OBJS+=$(WOLFBOOT_LIB_WOLFTPM)/src/tpm2_packet.o
955+
WOLFCRYPT_OBJS+=$(WOLFBOOT_LIB_WOLFTPM)/src/tpm2_crypto.o
956+
WOLFCRYPT_OBJS+=$(WOLFBOOT_LIB_WOLFTPM)/src/tpm2_param_enc.o
957+
WOLFCRYPT_OBJS+=$(WOLFBOOT_LIB_WOLFSSL)/wolfcrypt/src/hmac.o
958+
ifneq ($(SIGN),ED25519)
959+
WOLFCRYPT_OBJS+=$(WOLFBOOT_LIB_WOLFSSL)/wolfcrypt/src/sha512.o
960+
endif
961+
WOLFCRYPT_OBJS+=$(WOLFBOOT_LIB_WOLFSSL)/wolfcrypt/src/wc_encrypt.o
962+
ifeq ($(ENCRYPT_WITH_AES128)$(ENCRYPT_WITH_AES256),)
963+
WOLFCRYPT_OBJS+=$(WOLFBOOT_LIB_WOLFSSL)/wolfcrypt/src/aes.o
964+
endif
965+
WOLFCRYPT_OBJS+=$(RSA_OBJS)
966+
ifeq ($(findstring ECC,$(SIGN)),)
967+
ifeq ($(findstring ECC,$(SIGN_SECONDARY)),)
968+
WOLFCRYPT_OBJS+=$(ECC_OBJS)
969+
WOLFCRYPT_OBJS+=$(MATH_OBJS)
970+
endif
971+
endif
972+
STACK_USAGE=20000
973+
endif
974+
922975
OBJS+=$(PUBLIC_KEY_OBJS)
923976
ifneq ($(STAGE1),1)
924977
OBJS+=$(UPDATE_OBJS)

src/ftpm_callable.c

Lines changed: 146 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,146 @@
1+
/* ftpm_callable.c
2+
*
3+
* Copyright (C) 2026 wolfSSL Inc.
4+
*
5+
* This file is part of wolfBoot.
6+
*/
7+
8+
#ifdef WOLFBOOT_TZ_FTPM
9+
10+
#include <stdint.h>
11+
#include <string.h>
12+
13+
#include "store_sbrk.h"
14+
#include "wolfboot/wcs_ftpm.h"
15+
#include "wolftpm/fwtpm/fwtpm.h"
16+
#include "wolftpm/fwtpm/fwtpm_command.h"
17+
#include "wolftpm/fwtpm/fwtpm_nv.h"
18+
#include "wolftpm/tpm2_types.h"
19+
20+
static FWTPM_CTX ftpm_ctx;
21+
static int ftpm_ready;
22+
23+
extern unsigned int _start_heap;
24+
extern unsigned int _heap_size;
25+
26+
void *_sbrk(unsigned int incr)
27+
{
28+
static uint8_t *heap;
29+
return wolfboot_store_sbrk(incr, &heap, (uint8_t *)&_start_heap,
30+
(uint32_t)(&_heap_size));
31+
}
32+
33+
#ifndef FWTPM_NO_NV
34+
#define WCS_FTPM_NV_SIZE (16U * 1024U)
35+
static uint8_t ftpm_nv[WCS_FTPM_NV_SIZE];
36+
37+
static int ftpm_nv_read(void *ctx, word32 offset, byte *buf, word32 size)
38+
{
39+
uint8_t *nv = (uint8_t *)ctx;
40+
41+
if (nv == NULL || buf == NULL || offset > WCS_FTPM_NV_SIZE ||
42+
size > (WCS_FTPM_NV_SIZE - offset)) {
43+
return BAD_FUNC_ARG;
44+
}
45+
46+
XMEMCPY(buf, nv + offset, size);
47+
return TPM_RC_SUCCESS;
48+
}
49+
50+
static int ftpm_nv_write(void *ctx, word32 offset, const byte *buf,
51+
word32 size)
52+
{
53+
uint8_t *nv = (uint8_t *)ctx;
54+
55+
if (nv == NULL || buf == NULL || offset > WCS_FTPM_NV_SIZE ||
56+
size > (WCS_FTPM_NV_SIZE - offset)) {
57+
return BAD_FUNC_ARG;
58+
}
59+
60+
XMEMCPY(nv + offset, buf, size);
61+
return TPM_RC_SUCCESS;
62+
}
63+
64+
static int ftpm_nv_erase(void *ctx, word32 offset, word32 size)
65+
{
66+
uint8_t *nv = (uint8_t *)ctx;
67+
68+
if (nv == NULL || offset > WCS_FTPM_NV_SIZE ||
69+
size > (WCS_FTPM_NV_SIZE - offset)) {
70+
return BAD_FUNC_ARG;
71+
}
72+
73+
XMEMSET(nv + offset, 0xFF, size);
74+
return TPM_RC_SUCCESS;
75+
}
76+
77+
static FWTPM_NV_HAL ftpm_nv_hal = {
78+
ftpm_nv_read,
79+
ftpm_nv_write,
80+
ftpm_nv_erase,
81+
ftpm_nv,
82+
WCS_FTPM_NV_SIZE
83+
};
84+
#endif /* !FWTPM_NO_NV */
85+
86+
static uint32_t ftpm_rsp_size(const uint8_t *rsp, int rspLen)
87+
{
88+
if (rsp == NULL || rspLen < TPM2_HEADER_SIZE) {
89+
return 0;
90+
}
91+
92+
return ((uint32_t)rsp[2] << 24) |
93+
((uint32_t)rsp[3] << 16) |
94+
((uint32_t)rsp[4] << 8) |
95+
(uint32_t)rsp[5];
96+
}
97+
98+
void wcs_ftpm_init(void)
99+
{
100+
int rc;
101+
102+
#ifndef FWTPM_NO_NV
103+
XMEMSET(ftpm_nv, 0xFF, sizeof(ftpm_nv));
104+
#endif
105+
XMEMSET(&ftpm_ctx, 0, sizeof(ftpm_ctx));
106+
#ifndef FWTPM_NO_NV
107+
(void)FWTPM_NV_SetHAL(&ftpm_ctx, &ftpm_nv_hal);
108+
#endif
109+
110+
rc = FWTPM_Init(&ftpm_ctx);
111+
if (rc == 0) {
112+
ftpm_ctx.wasStarted = 1;
113+
ftpm_ready = 1;
114+
}
115+
}
116+
117+
int CSME_NSE_API wcs_ftpm_transmit(const uint8_t *cmd, uint32_t cmdSz,
118+
uint8_t *rsp, uint32_t *rspSz)
119+
{
120+
int rspLen;
121+
122+
if (!ftpm_ready) {
123+
return TPM_RC_INITIALIZE;
124+
}
125+
if (cmd == NULL || rsp == NULL || rspSz == NULL || cmdSz == 0U ||
126+
cmdSz > WCS_FTPM_MAX_COMMAND_SIZE || *rspSz == 0U ||
127+
*rspSz > WCS_FTPM_MAX_COMMAND_SIZE) {
128+
return BAD_FUNC_ARG;
129+
}
130+
131+
rspLen = (int)*rspSz;
132+
int rc = FWTPM_ProcessCommand(&ftpm_ctx, cmd, (int)cmdSz, rsp, &rspLen, 0);
133+
if (rc >= 0) {
134+
uint32_t wireSz = ftpm_rsp_size(rsp, rspLen);
135+
if (wireSz > 0U && wireSz <= *rspSz) {
136+
*rspSz = wireSz;
137+
rc = TPM_RC_SUCCESS;
138+
}
139+
else if (rspLen >= 0) {
140+
*rspSz = (uint32_t)rspLen;
141+
}
142+
}
143+
return rc;
144+
}
145+
146+
#endif /* WOLFBOOT_TZ_FTPM */

src/loader.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,7 @@ int main(void)
123123
uart_init(UART_FLASH_BITRATE, 8, 'N', 1);
124124
uart_send_current_version();
125125
#endif
126-
#ifdef WOLFBOOT_TPM
126+
#if defined(WOLFBOOT_TPM) && !defined(WOLFBOOT_TZ_FTPM)
127127
if (wolfBoot_tpm2_init() != 0) {
128128
wolfBoot_panic();
129129
}

src/wc_callable.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,10 @@
3030
#include "hal.h"
3131
#include <stdint.h>
3232

33+
#ifdef WOLFBOOT_TZ_FTPM
34+
#include "wolfboot/wcs_ftpm.h"
35+
#endif
36+
3337
static WC_RNG wcs_rng;
3438

3539
int CSME_NSE_API wcs_get_random(uint8_t *rand, uint32_t size)
@@ -41,6 +45,9 @@ void wcs_Init(void)
4145
{
4246
hal_trng_init();
4347
wc_InitRng(&wcs_rng);
48+
#ifdef WOLFBOOT_TZ_FTPM
49+
wcs_ftpm_init();
50+
#endif
4451
}
4552

4653
#endif /* WOLFCRYPT_SECURE_MODE */

0 commit comments

Comments
 (0)