From c1acaf1f811fff294a58474a6dd4d89f87ac4719 Mon Sep 17 00:00:00 2001 From: Thomas Cook Date: Wed, 3 Jun 2026 10:29:03 -0400 Subject: [PATCH 1/5] Initial implementation --- arch.mk | 7 +++++ config/examples/lpc55s69-hwpuf.config | 44 +++++++++++++++++++++++++++ test-app/Makefile | 6 ++++ 3 files changed, 57 insertions(+) create mode 100644 config/examples/lpc55s69-hwpuf.config diff --git a/arch.mk b/arch.mk index f015647432..9f4ae9a989 100644 --- a/arch.mk +++ b/arch.mk @@ -1361,6 +1361,7 @@ ifeq ($(TARGET),lpc55s69) -I$(MCUXPRESSO)/drivers/iap1 \ -I$(MCUXPRESSO)/drivers/lpc_gpio \ -I$(MCUXPRESSO)/drivers/lpc_iocon \ + -I$(MCUXPRESSO)/drivers/puf \ -I$(MCUXPRESSO)/drivers/rng_1 \ -I$(MCUXPRESSO_CMSIS)/Include \ -I$(MCUXPRESSO_CMSIS)/Core/Include @@ -1392,6 +1393,12 @@ ifeq ($(TARGET),lpc55s69) $(WOLFBOOT_LIB_WOLFSSL)/wolfcrypt/src/port/nxp/casper_port.o \ $(WOLFBOOT_LIB_WOLFSSL)/wolfcrypt/src/port/nxp/hashcrypt_port.o endif + ifeq ($(HWPUF),1) + CFLAGS+=-DWOLFSSL_HWPUF -DWOLFSSL_NXP_PUF + OBJS+=\ + $(MCUXPRESSO)/drivers/puf/fsl_puf.o \ + $(WOLFBOOT_LIB_WOLFSSL)/wolfcrypt/src/port/nxp/hwpuf_port.o + endif endif ifeq ($(TARGET),psoc6) diff --git a/config/examples/lpc55s69-hwpuf.config b/config/examples/lpc55s69-hwpuf.config new file mode 100644 index 0000000000..7d0d252597 --- /dev/null +++ b/config/examples/lpc55s69-hwpuf.config @@ -0,0 +1,44 @@ +ARCH?=ARM +TZEN?=0 +TARGET?=lpc55s69 +SIGN?=ECC384 +HASH?=SHA256 +MCUXSDK?=1 +MCUXPRESSO?=$(PWD)/../NXP/mcuxpresso-sdk/mcuxsdk +MCUXPRESSO_CMSIS?=$(PWD)/../NXP/CMSIS_5/CMSIS +MCUXPRESSO_CPU?=LPC55S69JBD100_cm33_core0 +MCUXPRESSO_DRIVERS?=$(MCUXPRESSO)/devices/LPC/LPC5500/LPC55S69 +MCUXPRESSO_PROJECT_TEMPLATE?=$(MCUXPRESSO)/examples/_boards/lpcxpresso55s69/project_template +DEBUG?=0 +DEBUG_UART?=1 +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 +NO_ARM_ASM=1 +WOLFBOOT_VERSION?=0 +V?=0 +SPMATH?=1 +RAM_CODE?=1 +DUALBANK_SWAP?=0 +FLASH_MULTI_SECTOR_ERASE?=1 + +# Turn on or off hw acceleration of crypto algs in the lpc55s69 +PKA?=0 +# Turn on or off hw puf +HWPUF?=1 + +WOLFBOOT_SECTOR_SIZE?=0x200 + +# use these for test/benchmark +WOLFBOOT_PARTITION_SIZE?=0x2b000 +WOLFBOOT_PARTITION_BOOT_ADDRESS?=0x10000 +WOLFBOOT_PARTITION_UPDATE_ADDRESS?=0x3b000 +WOLFBOOT_PARTITION_SWAP_ADDRESS?=0x66000 + +WOLFCRYPT_TEST?=1 diff --git a/test-app/Makefile b/test-app/Makefile index 7fc2c19c76..d4374c39f0 100644 --- a/test-app/Makefile +++ b/test-app/Makefile @@ -805,6 +805,12 @@ ifeq ($(TARGET),lpc55s69) $(WOLFBOOT_LIB_WOLFSSL)/wolfcrypt/src/port/nxp/casper_port.o \ $(WOLFBOOT_LIB_WOLFSSL)/wolfcrypt/src/port/nxp/hashcrypt_port.o endif + ifeq ($(HWPUF),1) + CFLAGS+=-DWOLFSSL_HWPUF -DWOLFSSL_NXP_PUF + APP_OBJS+=\ + $(MCUXPRESSO)/drivers/puf/fsl_puf.o \ + $(WOLFBOOT_LIB_WOLFSSL)/wolfcrypt/src/port/nxp/hwpuf_port.o + endif ifeq ($(WOLFCRYPT_SUPPORT),1) LDFLAGS+=--specs=nano.specs endif From ca634c2b0f5f2508fcb613761c73da496405be79 Mon Sep 17 00:00:00 2001 From: Thomas Cook Date: Thu, 11 Jun 2026 14:12:49 -0400 Subject: [PATCH 2/5] fixes --- arch.mk | 3 ++- test-app/Makefile | 4 +++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/arch.mk b/arch.mk index 9f4ae9a989..15bd1caffb 100644 --- a/arch.mk +++ b/arch.mk @@ -1394,9 +1394,10 @@ ifeq ($(TARGET),lpc55s69) $(WOLFBOOT_LIB_WOLFSSL)/wolfcrypt/src/port/nxp/hashcrypt_port.o endif ifeq ($(HWPUF),1) - CFLAGS+=-DWOLFSSL_HWPUF -DWOLFSSL_NXP_PUF + CFLAGS+=-DWOLFSSL_HWPUF -DWOLFSSL_NXP_HWPUF OBJS+=\ $(MCUXPRESSO)/drivers/puf/fsl_puf.o \ + $(WOLFBOOT_LIB_WOLFSSL)/wolfcrypt/src/cryptocb.o \ $(WOLFBOOT_LIB_WOLFSSL)/wolfcrypt/src/port/nxp/hwpuf_port.o endif endif diff --git a/test-app/Makefile b/test-app/Makefile index d4374c39f0..25d9abdd53 100644 --- a/test-app/Makefile +++ b/test-app/Makefile @@ -806,9 +806,11 @@ ifeq ($(TARGET),lpc55s69) $(WOLFBOOT_LIB_WOLFSSL)/wolfcrypt/src/port/nxp/hashcrypt_port.o endif ifeq ($(HWPUF),1) - CFLAGS+=-DWOLFSSL_HWPUF -DWOLFSSL_NXP_PUF + CFLAGS+=-DWOLFSSL_HWPUF -DWOLFSSL_NXP_HWPUF APP_OBJS+=\ $(MCUXPRESSO)/drivers/puf/fsl_puf.o \ + $(WOLFBOOT_LIB_WOLFSSL)/wolfcrypt/src/cryptocb.o \ + $(WOLFBOOT_LIB_WOLFSSL)/wolfcrypt/src/hwpuf.o \ $(WOLFBOOT_LIB_WOLFSSL)/wolfcrypt/src/port/nxp/hwpuf_port.o endif ifeq ($(WOLFCRYPT_SUPPORT),1) From 612105cdf028ad05c242d5ff42060345b911bf60 Mon Sep 17 00:00:00 2001 From: Thomas Cook Date: Thu, 11 Jun 2026 14:17:40 -0400 Subject: [PATCH 3/5] default HWPUF off --- config/examples/lpc55s69-hwpuf.config | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/examples/lpc55s69-hwpuf.config b/config/examples/lpc55s69-hwpuf.config index 7d0d252597..30385a1d1b 100644 --- a/config/examples/lpc55s69-hwpuf.config +++ b/config/examples/lpc55s69-hwpuf.config @@ -31,7 +31,7 @@ FLASH_MULTI_SECTOR_ERASE?=1 # Turn on or off hw acceleration of crypto algs in the lpc55s69 PKA?=0 # Turn on or off hw puf -HWPUF?=1 +HWPUF?=0 WOLFBOOT_SECTOR_SIZE?=0x200 From 695b93b5d005815149c50da94cd101e1ef757ee6 Mon Sep 17 00:00:00 2001 From: Thomas Cook Date: Thu, 25 Jun 2026 14:16:18 -0400 Subject: [PATCH 4/5] Add psa attestation support for lpc55s69 --- .github/workflows/test-configs.yml | 21 ++ arch.mk | 1 + config/examples/lpc55s69-tz-psa.config | 48 ++++ docs/Targets.md | 1 + hal/lpc55s69.c | 308 ++++++++++++++++++++++++- options.mk | 7 + test-app/ARM-lpc55s69-ns.ld | 22 +- test-app/app_lpc55s69.c | 75 ++++++ 8 files changed, 475 insertions(+), 8 deletions(-) create mode 100644 config/examples/lpc55s69-tz-psa.config diff --git a/.github/workflows/test-configs.yml b/.github/workflows/test-configs.yml index 19f239ac50..2b8b554665 100644 --- a/.github/workflows/test-configs.yml +++ b/.github/workflows/test-configs.yml @@ -151,6 +151,27 @@ jobs: config-file: ./config/examples/lpc55s69-tz.config board-name: lpcxpresso55s69 + lpc55s69_tz_psa_test: + uses: ./.github/workflows/test-build-mcux-sdk-manifests.yml + with: + arch: arm + config-file: ./config/examples/lpc55s69-tz-psa.config + board-name: lpcxpresso55s69 + + lpc55s69_hwpuf_test: + uses: ./.github/workflows/test-build-mcux-sdk-manifests.yml + with: + arch: arm + config-file: ./config/examples/lpc55s69-hwpuf.config + board-name: lpcxpresso55s69 + + lpc55s69_benchmark_test: + uses: ./.github/workflows/test-build-mcux-sdk-manifests.yml + with: + arch: arm + config-file: ./config/examples/lpc55s69-benchmark.config + board-name: lpcxpresso55s69 + nrf52840_test: uses: ./.github/workflows/test-build.yml with: diff --git a/arch.mk b/arch.mk index 15bd1caffb..4c1b02feb6 100644 --- a/arch.mk +++ b/arch.mk @@ -1398,6 +1398,7 @@ ifeq ($(TARGET),lpc55s69) OBJS+=\ $(MCUXPRESSO)/drivers/puf/fsl_puf.o \ $(WOLFBOOT_LIB_WOLFSSL)/wolfcrypt/src/cryptocb.o \ + $(WOLFBOOT_LIB_WOLFSSL)/wolfcrypt/src/hwpuf.o \ $(WOLFBOOT_LIB_WOLFSSL)/wolfcrypt/src/port/nxp/hwpuf_port.o endif endif diff --git a/config/examples/lpc55s69-tz-psa.config b/config/examples/lpc55s69-tz-psa.config new file mode 100644 index 0000000000..6dab4ff2bf --- /dev/null +++ b/config/examples/lpc55s69-tz-psa.config @@ -0,0 +1,48 @@ +ARCH?=ARM +TZEN?=1 +TARGET?=lpc55s69 +SIGN?=ECC384 +HASH?=SHA256 +MCUXSDK?=1 +MCUXPRESSO?=$(PWD)/../NXP/mcuxpresso-sdk/mcuxsdk +MCUXPRESSO_CMSIS?=$(PWD)/../NXP/CMSIS_5/CMSIS +MCUXPRESSO_CPU?=LPC55S69JBD100_cm33_core0 +MCUXPRESSO_DRIVERS?=$(MCUXPRESSO)/devices/LPC/LPC5500/LPC55S69 +MCUXPRESSO_PROJECT_TEMPLATE?=$(MCUXPRESSO)/examples/_boards/lpcxpresso55s69/project_template +DEBUG?=0 +DEBUG_UART?=1 +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 +NO_ARM_ASM=1 +WOLFBOOT_VERSION?=0 +V?=0 +SPMATH?=1 +RAM_CODE?=1 +DUALBANK_SWAP?=0 +FLASH_MULTI_SECTOR_ERASE?=1 +WOLFCRYPT_TZ?=1 +WOLFCRYPT_TZ_PSA?=1 +WOLFBOOT_ATTESTATION_TEST?=1 +WOLFBOOT_UDS_UID_FALLBACK_FORTEST?=0 +PKA?=0 +HWPUF?=0 +WOLFBOOT_HWPUF_PROVISION?=0 + +WOLFBOOT_SECTOR_SIZE?=0x200 + +# 200KB boot, 80KB keyvault, 8KB NSC, 56KB partitions, 512 swap +WOLFBOOT_KEYVAULT_ADDRESS?=0x10032000 +WOLFBOOT_KEYVAULT_SIZE?=0x14000 +WOLFBOOT_NSC_ADDRESS?=0x10046000 +WOLFBOOT_NSC_SIZE?=0x2000 +WOLFBOOT_PARTITION_SIZE?=0xE000 +WOLFBOOT_PARTITION_BOOT_ADDRESS?=0x00048000 +WOLFBOOT_PARTITION_UPDATE_ADDRESS?=0x00056000 +WOLFBOOT_PARTITION_SWAP_ADDRESS?=0x00064000 diff --git a/docs/Targets.md b/docs/Targets.md index daa95c6e4e..7bd88b8050 100644 --- a/docs/Targets.md +++ b/docs/Targets.md @@ -2828,6 +2828,7 @@ support is turned off in the config files, and all crypto is software based. To turn on hardware acceleration, set PKA=1 in the config file. Basic hardware acceleration supported: +- hardware PUF (HWPUF) - SHA1 - SHA-256 - AES-ECB (128, 192, 256 key sizes) diff --git a/hal/lpc55s69.c b/hal/lpc55s69.c index 7e461c3195..da0fae0f0c 100644 --- a/hal/lpc55s69.c +++ b/hal/lpc55s69.c @@ -28,20 +28,312 @@ #include "clock_config.h" #include "fsl_clock.h" #include "fsl_iap.h" +#include "fsl_iap_ffr.h" #include "fsl_iocon.h" +#include "fsl_puf.h" #include "fsl_reset.h" #include "fsl_rng.h" #include "fsl_usart.h" +#include "hal.h" #include "loader.h" #ifdef TZEN #include "hal/armv8m_tz.h" #endif +#include +#include + +#ifdef WOLFSSL_HWPUF +#include +#endif + +#if defined(WOLFCRYPT_TZ_PSA) +# if defined(WOLFBOOT_HASH_SHA256) +# include +# define HAL_KDF_HASH_TYPE WC_HASH_TYPE_SHA256 +# elif defined(WOLFBOOT_HASH_SHA384) +# include +# define HAL_KDF_HASH_TYPE WC_HASH_TYPE_SHA384 +# elif defined(WOLFBOOT_HASH_SHA3_384) +# include +# define HAL_KDF_HASH_TYPE WC_HASH_TYPE_SHA3_384 +# else +# error "No supported hash type for HAL_KDF" +# endif +#endif + static flash_config_t pflash; static const uint32_t pflash_page_size = 512U; uint32_t SystemCoreClock; /* set in clock_config.c */ +static void flashInit(void) +{ + static int initialized = 0; + + if (!initialized) { + XMEMSET(&pflash, 0, sizeof(pflash)); + FLASH_Init(&pflash); + FFR_Init(&pflash); + initialized = 1; + } +} + +static NOINLINEFUNCTION void hal_zeroize(void *ptr, size_t len) +{ + volatile uint8_t *p = (volatile uint8_t *)ptr; + while (len-- > 0U) { + *p++ = 0U; + } +} + + +#if defined(__WOLFBOOT) && defined(WOLFSSL_HWPUF) +#define HWPUF_PROV_MAGIC 0x564f5250ul /* "PROV" */ +#define HWPUF_PROV_FLASH_BASEADR 0x80000ul +#define HWPUF_PROV_FLASH_LEN 0x1000ul +#define HWPUF_PROV_UDS_KEY_INDEX 14 /* NOT the one in PFR */ +#define HWPUF_PROV_UDS_KEY_SIZE 32 + +typedef struct hwpuf_prov { + word32 magic; + byte ac[HWPUF_ACTIVATION_CODE_SIZE]; + byte uds_kc[PUF_GET_KEY_CODE_SIZE_FOR_KEY_SIZE(HWPUF_PROV_UDS_KEY_SIZE)]; +} hwpuf_prov; + +static hwpuf_prov prov; + +static int hwpuf_provision_get(void) +{ + if (sizeof(prov) > HWPUF_PROV_FLASH_LEN) + return -1; + + flashInit(); + + /* verify none of sectors in erased state */ + { + uint32_t addr; + uint32_t start = HWPUF_PROV_FLASH_BASEADR; + uint32_t end = HWPUF_PROV_FLASH_BASEADR + HWPUF_PROV_FLASH_LEN; + + for (addr = start; addr < end; addr += pflash_page_size) { + if (FLASH_VerifyErase(&pflash, addr, pflash_page_size) + == kStatus_FLASH_Success) { + return -1; + } + } + } + + XMEMCPY(&prov, (byte *)HWPUF_PROV_FLASH_BASEADR, sizeof(prov)); + + if (prov.magic != HWPUF_PROV_MAGIC) + return -1; + + return 0; +} + +#ifdef WOLFBOOT_HWPUF_PROVISION +static int hwpuf_provision_set(int force) +{ + int ret = -1; + wc_HWPUF hwpuf; + + if (sizeof(prov) > HWPUF_PROV_FLASH_LEN) + return -1; + + if (!force) { + if (hwpuf_provision_get() == 0) + return -1; + } + + XMEMSET(&prov, 0, sizeof(prov)); + + if (wc_HWPUF_Register(&hwpuf, NULL, INVALID_DEVID) != 0) + return -1; + + if (wc_HWPUF_Init(&hwpuf) != 0) + goto error_out; + + if (wc_HWPUF_Enroll(&hwpuf, prov.ac, sizeof(prov.ac)) != 0) + goto error_out; + + (void)wc_HWPUF_Deinit(&hwpuf); + (void)wc_HWPUF_Init(&hwpuf); + + if (wc_HWPUF_Start(&hwpuf, prov.ac, sizeof(prov.ac)) != 0) + goto error_out; + + if (wc_HWPUF_GenerateKey(&hwpuf, + HWPUF_PROV_UDS_KEY_INDEX, HWPUF_PROV_UDS_KEY_SIZE, + prov.uds_kc, sizeof(prov.uds_kc)) != 0) + goto error_out; + + prov.magic = HWPUF_PROV_MAGIC; + + flashInit(); + + hal_flash_unlock(); + ret = hal_flash_erase(HWPUF_PROV_FLASH_BASEADR, HWPUF_PROV_FLASH_LEN); + if (ret != 0) { + hal_flash_lock(); + goto error_out; + } + ret = hal_flash_write(HWPUF_PROV_FLASH_BASEADR, + (const uint8_t *)&prov, sizeof(prov)); + hal_flash_lock(); + if (ret != 0) + goto error_out; + + ret = 0; + +error_out: + hal_zeroize(&prov, sizeof(prov)); + (void)wc_HWPUF_Zeroize(&hwpuf); + (void)wc_HWPUF_Deinit(&hwpuf); + (void)wc_HWPUF_Unregister(&hwpuf); + return ret; +} +#endif /* WOLFBOOT_HWPUF_PROVISION */ + +#if defined(WOLFCRYPT_TZ_PSA) +static int uds_from_hwpuf(uint8_t *out, size_t out_len) +{ + int ret = -1; + wc_HWPUF hwpuf; + byte uds[HWPUF_PROV_UDS_KEY_SIZE]; + + if (hwpuf_provision_get() != 0) + return -1; + + if (wc_HWPUF_Register(&hwpuf, NULL, INVALID_DEVID) != 0) + return -1; + + if (wc_HWPUF_Init(&hwpuf) != 0) + goto error_out; + + if (wc_HWPUF_Start(&hwpuf, prov.ac, sizeof(prov.ac)) != 0) + goto error_out; + + ret = wc_HWPUF_GetKey(&hwpuf, prov.uds_kc, sizeof(prov.uds_kc), + uds, sizeof(uds)); + if (ret != 0) + goto error_out; + + ret = wc_HKDF_ex((int)HAL_KDF_HASH_TYPE, uds, (word32)sizeof(uds), + (const byte *)"WOLFBOOT-UDS", (word32)12, + (const byte *)"WOLFBOOT-UDS", (word32)12, + (byte *)out, (word32)out_len, + NULL, INVALID_DEVID); + if (ret != 0) + goto error_out; + +error_out: + hal_zeroize(uds, sizeof(uds)); + hal_zeroize(&prov, sizeof(prov)); + (void)wc_HWPUF_Zeroize(&hwpuf); + (void)wc_HWPUF_Deinit(&hwpuf); + (void)wc_HWPUF_Unregister(&hwpuf); + return ret == 0 ? 0 : -1; +} +#endif /* WOLFCRYPT_TZ_PSA */ +#endif /* __WOLFBOOT && WOLFSSL_HWPUF */ + +#if defined(__WOLFBOOT) && defined(WOLFCRYPT_TZ_PSA) +static void reverse_array(byte *s, int len) +{ + int up, dn; + + if (s == NULL) + return; + + up = 0; + dn = len - 1; + while (up < dn) { + byte t = s[up]; + s[up] = s[dn]; + s[dn] = t; + ++up; + --dn; + } +} +#endif + +#if defined(__WOLFBOOT) && defined(WOLFCRYPT_TZ_PSA) && !defined(WOLFBOOT_DICE_HW) +#ifdef WOLFBOOT_UDS_UID_FALLBACK_FORTEST +static int uds_from_uid(uint8_t *out, size_t out_len) +{ + uint8_t uid[16]; +#if defined(WOLFBOOT_HASH_SHA256) + uint8_t digest[SHA256_DIGEST_SIZE]; +#elif defined(WOLFBOOT_HASH_SHA384) + uint8_t digest[SHA384_DIGEST_SIZE]; +#elif defined(WOLFBOOT_HASH_SHA3_384) + uint8_t digest[SHA3_384_DIGEST_SIZE]; +#endif + size_t copy_len = sizeof(digest); + + flashInit(); + + if (FFR_GetUUID(&pflash, uid) != kStatus_Success) + return -1; + reverse_array(uid, sizeof(uid)); + +#if defined(WOLFBOOT_HASH_SHA256) + { + wc_Sha256 hash; + wc_InitSha256(&hash); + wc_Sha256Update(&hash, uid, sizeof(uid)); + wc_Sha256Final(&hash, digest); + } +#elif defined(WOLFBOOT_HASH_SHA384) + { + wc_Sha384 hash; + wc_InitSha384(&hash); + wc_Sha384Update(&hash, uid, sizeof(uid)); + wc_Sha384Final(&hash, digest); + } +#elif defined(WOLFBOOT_HASH_SHA3_384) + { + wc_Sha3 hash; + wc_InitSha3_384(&hash, NULL, INVALID_DEVID); + wc_Sha3_384_Update(&hash, uid, sizeof(uid)); + wc_Sha3_384_Final(&hash, digest); + } +#endif + + if (copy_len > out_len) { + copy_len = out_len; + } + memcpy(out, digest, copy_len); +#ifdef DEBUG + { + int idx; + wolfBoot_printf("[ATTEST] UDS FORTEST:"); + for (idx = 0; idx < (int)out_len; ++idx) + wolfBoot_printf(" %02x", out[idx]); + wolfBoot_printf("\n"); + } +#endif + return 0; +} +#endif /* WOLFBOOT_UDS_UID_FALLBACK_FORTEST */ + +/* Derive UDS from hw puf, fall back to derive from uid */ +int hal_uds_derive_key(uint8_t *out, size_t out_len) +{ + if (out == NULL || out_len == 0) + return -1; + +#ifdef WOLFBOOT_UDS_UID_FALLBACK_FORTEST + return uds_from_uid(out, out_len); +#elif defined(WOLFSSL_HWPUF) + return uds_from_hwpuf(out, out_len); +#else + return -1; +#endif +} +#endif /* __WOLFBOOT && WOLFCRYPT_TZ_PSA && !WOLFBOOT_DICE_HW */ + #ifdef TZEN static void hal_sau_init(void) { @@ -55,7 +347,7 @@ static void hal_sau_init(void) 0); /* Non-secure RAM */ - sau_init_region(2, 0x20020000, 0x20027FFF, 0); + sau_init_region(2, 0x20020000, 0x2002FFFF, 0); /* Peripherals */ sau_init_region(3, 0x40000000, 0x4003FFFF, 0); @@ -121,14 +413,24 @@ void hal_init(void) #endif /* __WOLFBOOT */ #if defined(__WOLFBOOT) || !defined(TZEN) - memset(&pflash, 0, sizeof(pflash)); - FLASH_Init(&pflash); + flashInit(); hal_flash_fix_ecc(); #endif #if defined(TZEN) && !defined(NONSECURE_APP) hal_sau_init(); #endif + +#ifdef __WOLFBOOT + wolfCrypt_Init(); +#endif + +#if defined(__WOLFBOOT) && defined(WOLFBOOT_HWPUF_PROVISION) + if (hwpuf_provision_set(0) != 0) + uart_write("hwpuf provision failure (already provisioned?)\n", 47); + else + uart_write("hwpuf provision success\n", 24); +#endif } #ifdef __WOLFBOOT diff --git a/options.mk b/options.mk index 52146818d1..3fdba02056 100644 --- a/options.mk +++ b/options.mk @@ -949,6 +949,13 @@ ifeq ($(WOLFBOOT_DICE_HW),1) endif endif +ifeq ($(WOLFBOOT_HWPUF_PROVISION),1) + ifneq ($(HWPUF),1) + $(error WOLFBOOT_HWPUF_PROVISION requires HWPUF=1) + endif + CFLAGS+=-DWOLFBOOT_HWPUF_PROVISION +endif + ifeq ($(WOLFCRYPT_TZ_PKCS11),1) CFLAGS+=-DSECURE_PKCS11 CFLAGS+=-DWOLFPKCS11_USER_SETTINGS diff --git a/test-app/ARM-lpc55s69-ns.ld b/test-app/ARM-lpc55s69-ns.ld index aa3200f9eb..ea288a69a2 100644 --- a/test-app/ARM-lpc55s69-ns.ld +++ b/test-app/ARM-lpc55s69-ns.ld @@ -1,7 +1,10 @@ +_Min_Heap_Size = 0x00000100; /* minimal heap (not using malloc) */ +_Min_Stack_Size = 0x00008000; /* required amount of stack */ + MEMORY { FLASH (rx) : ORIGIN = @WOLFBOOT_TEST_APP_ADDRESS@, LENGTH = @WOLFBOOT_TEST_APP_SIZE@ - RAM (rwx) : ORIGIN = 0x20020000, LENGTH = 32K + RAM (rwx) : ORIGIN = 0x20020000, LENGTH = 64K } SECTIONS @@ -46,13 +49,22 @@ SECTIONS _end_bss = .; _end = .; } > RAM + + ._user_heap_stack : + { + . = ALIGN(8); + PROVIDE ( end = . ); + PROVIDE ( _end = . ); + PROVIDE ( _start_heap = . ); + . = . + _Min_Heap_Size; + . = . + _Min_Stack_Size; + . = ALIGN(8); + PROVIDE ( END_STACK = . ); + PROVIDE ( _end_stack = . ); + } > RAM } _wolfboot_partition_boot_address = @WOLFBOOT_PARTITION_BOOT_ADDRESS@; _wolfboot_partition_size = @WOLFBOOT_PARTITION_SIZE@; _wolfboot_partition_update_address = @WOLFBOOT_PARTITION_UPDATE_ADDRESS@; _wolfboot_partition_swap_address = @WOLFBOOT_PARTITION_SWAP_ADDRESS@; - -PROVIDE(_start_heap = _end); -PROVIDE(end = _end); -PROVIDE(_end_stack = ORIGIN(RAM) + LENGTH(RAM)); diff --git a/test-app/app_lpc55s69.c b/test-app/app_lpc55s69.c index 5bacdf98fb..72c85df307 100644 --- a/test-app/app_lpc55s69.c +++ b/test-app/app_lpc55s69.c @@ -41,6 +41,12 @@ int wolfcrypt_test(void *args); int benchmark_test(void *args); #endif +#ifdef WOLFCRYPT_TZ_PSA +#include "psa/crypto.h" +#include "psa/error.h" +#include "psa/initial_attestation.h" +#endif + #define RED_LED 6 #define GREEN_LED 7 #define BLUE_LED 4 @@ -128,6 +134,70 @@ static void check_parts( wolfBoot_printf(" update: ver=0x%lx state=0x%02x\n", *pupdate_ver, *pupdate_state); } +#if defined(WOLFBOOT_ATTESTATION_TEST) && defined(WOLFCRYPT_TZ_PSA) + +#define LINE_LEN 16 +static void print_hex(const uint8_t *buffer, uint32_t length, int dumpChars) +{ + uint32_t i, sz; + + if (!buffer) { + wolfBoot_printf("\tNULL\n"); + return; + } + + while (length > 0) { + sz = length; + if (sz > LINE_LEN) + sz = LINE_LEN; + + wolfBoot_printf("\t"); + for (i = 0; i < LINE_LEN; i++) { + if (i < sz) + wolfBoot_printf("%02x ", buffer[i]); + else + wolfBoot_printf(" "); + } + if (dumpChars) { + wolfBoot_printf("| "); + for (i = 0; i < sz; i++) { + if (buffer[i] > 31 && buffer[i] < 127) + wolfBoot_printf("%c", buffer[i]); + else + wolfBoot_printf("."); + } + } + wolfBoot_printf("\n"); + + buffer += sz; + length -= sz; + } +} + +static int run_attestation_test(void) +{ + uint8_t challenge[PSA_INITIAL_ATTEST_CHALLENGE_SIZE_64]; + uint8_t token[1024]; + size_t token_size = 0; + psa_status_t status; + size_t i; + + for (i = 0; i < sizeof(challenge); i++) { + challenge[i] = (uint8_t)i; + } + + status = psa_initial_attest_get_token(challenge, sizeof(challenge), + token, sizeof(token), &token_size); + if (status != PSA_SUCCESS) { + wolfBoot_printf("attest: get token failed (%d)\n", status); + return -1; + } + wolfBoot_printf("attest: token size %lu bytes\n", (unsigned long)token_size); + print_hex(token, (uint32_t)token_size, 1); + return 0; +} +#endif /* WOLFBOOT_ATTESTATION_TEST && WOLFCRYPT_TZ_PSA */ + void main(void) { uint32_t boot_ver, update_ver; @@ -184,6 +254,11 @@ void main(void) GPIO_PinWrite(GPIO, 1, GREEN_LED, 0); } +#if defined(WOLFBOOT_ATTESTATION_TEST) && defined(WOLFCRYPT_TZ_PSA) + if (run_attestation_test() != 0) + wolfBoot_printf("Make sure WOLFBOOT_HWPUF_PROVISION is set\n"); +#endif + #if defined(WOLFCRYPT_TEST) || defined(WOLFCRYPT_BENCHMARK) wolfCrypt_Init(); From 477c71c4e773f68a6275a5eb49fbe884ed9a25a1 Mon Sep 17 00:00:00 2001 From: Thomas Cook Date: Thu, 25 Jun 2026 23:40:54 -0400 Subject: [PATCH 5/5] Update docs, tweak configs --- config/examples/lpc55s69-benchmark.config | 2 - config/examples/lpc55s69-tz-psa.config | 2 +- config/examples/lpc55s69-tz.config | 4 +- config/examples/lpc55s69.config | 4 +- docs/Targets.md | 55 +++++++++++++++++++++-- 5 files changed, 54 insertions(+), 13 deletions(-) diff --git a/config/examples/lpc55s69-benchmark.config b/config/examples/lpc55s69-benchmark.config index 9804dedae5..8d16996c4b 100644 --- a/config/examples/lpc55s69-benchmark.config +++ b/config/examples/lpc55s69-benchmark.config @@ -31,8 +31,6 @@ FLASH_MULTI_SECTOR_ERASE?=1 # Turn on or off hw acceleration of crypto algs in the lpc55s69 PKA?=0 -# use 1024-byte sector to accommodate RSA4096 signature -# WOLFBOOT_SECTOR_SIZE?=0x400 WOLFBOOT_SECTOR_SIZE?=0x200 # use these for test/benchmark diff --git a/config/examples/lpc55s69-tz-psa.config b/config/examples/lpc55s69-tz-psa.config index 6dab4ff2bf..2afc62fef9 100644 --- a/config/examples/lpc55s69-tz-psa.config +++ b/config/examples/lpc55s69-tz-psa.config @@ -30,7 +30,7 @@ FLASH_MULTI_SECTOR_ERASE?=1 WOLFCRYPT_TZ?=1 WOLFCRYPT_TZ_PSA?=1 WOLFBOOT_ATTESTATION_TEST?=1 -WOLFBOOT_UDS_UID_FALLBACK_FORTEST?=0 +WOLFBOOT_UDS_UID_FALLBACK_FORTEST?=1 PKA?=0 HWPUF?=0 WOLFBOOT_HWPUF_PROVISION?=0 diff --git a/config/examples/lpc55s69-tz.config b/config/examples/lpc55s69-tz.config index 58d4fb6f6a..5fce4fde8d 100644 --- a/config/examples/lpc55s69-tz.config +++ b/config/examples/lpc55s69-tz.config @@ -33,11 +33,9 @@ WOLFCRYPT_TZ_PKCS11?=1 # Turn on or off hw acceleration of crypto algs in the lpc55s69 PKA?=0 -# use 1024-byte sector to accommodate RSA4096 signature -# WOLFBOOT_SECTOR_SIZE?=0x400 WOLFBOOT_SECTOR_SIZE?=0x200 -# 200KB boot, 80KB keyvault, 8KB NSC, 56KB partitions, 512/1024 swap +# 200KB boot, 80KB keyvault, 8KB NSC, 56KB partitions, 512 swap WOLFBOOT_KEYVAULT_ADDRESS?=0x10032000 WOLFBOOT_KEYVAULT_SIZE?=0x14000 WOLFBOOT_NSC_ADDRESS?=0x10046000 diff --git a/config/examples/lpc55s69.config b/config/examples/lpc55s69.config index 57c6647c3f..8643b1dcbe 100644 --- a/config/examples/lpc55s69.config +++ b/config/examples/lpc55s69.config @@ -31,12 +31,10 @@ FLASH_MULTI_SECTOR_ERASE?=1 # Turn on or off hw acceleration of crypto algs in the lpc55s69 PKA?=0 -# use 1024-byte sector to accommodate RSA4096 signature -# WOLFBOOT_SECTOR_SIZE?=0x400 WOLFBOOT_SECTOR_SIZE?=0x200 # Default configuration -# 44KB boot, 52KB partitions, 512/1024 swap +# 44KB boot, 52KB partitions, 512 swap WOLFBOOT_PARTITION_SIZE?=0xB000 WOLFBOOT_PARTITION_BOOT_ADDRESS?=0xD000 WOLFBOOT_PARTITION_UPDATE_ADDRESS?=0x18000 diff --git a/docs/Targets.md b/docs/Targets.md index 7bd88b8050..2bedfaa817 100644 --- a/docs/Targets.md +++ b/docs/Targets.md @@ -2828,7 +2828,6 @@ support is turned off in the config files, and all crypto is software based. To turn on hardware acceleration, set PKA=1 in the config file. Basic hardware acceleration supported: -- hardware PUF (HWPUF) - SHA1 - SHA-256 - AES-ECB (128, 192, 256 key sizes) @@ -2842,6 +2841,57 @@ Basic hardware acceleration supported: See [Test and Benchmark](#lpc55s69-test-and-benchmark) for a comparison with and without hardware acceleration. +### LPC55S69: Hardware PUF (HWPUF) + +wolfBoot / wolfCrypt provide support for the LPC55S69's SRAM PUF (Physically +Unclonable Function), which provides root of trust, identity, and key +generation & storage, without the need to expose keys during manufacturing. +Keys of size 128, 192, and 256 bits are supported. +To turn on HWPUF, set HWPUF=1 in the config file (see below). + +### LPC55S69: Example Configurations + +#### The following example configurations are provided: + +- [lpc55s69.config](/config/examples/lpc55s69.config): + - Both wolfBoot and the test-app live in the non-secure realm + - Set PKA=1 in the config file to turn on hardware acceleration + (off by default) + +- [lpc55s69-benchmark.config](/config/examples/lpc55s69-benchmark.config): + - Same as `lpc55s69.config`, but turns on test and benchmark code + - Set PKA=1 in the config file to turn on hardware acceleration + (off by default) + +- [lpc55s69-hwpuf.config](/config/examples/lpc55s69-hwpuf.config): + - Same as `lpc55s69.config`, but turns on test code showing how to use the + hwpuf api + - Set HWPUF=1 in the config file to turn on HWPUF support (off by default) + +- [lpc55s69-tz.config](/config/examples/lpc55s69-tz.config): + - wolfBoot lives in the secure realm, test-app lives in the non-secure realm + - Provides a standard PKCS #11 api to interface with crypto algs in the secure + realm + +- [lpc55s69-tz-psa.config](/config/examples/lpc55s69-tz-psa.config): + - wolfBoot lives in the secure realm, test-app lives in the non-secure realm + - Provides a standard PSA api to interface with crypto algs in the secure + realm + - Provides an example of PSA Attestation + - To turn on HWPUF for use with attestation, set the following in the config + file: + - WOLFBOOT_UDS_UID_FALLBACK_FORTEST=0 + - HWPUF=1 + - WOLFBOOT_HWPUF_PROVISION=1 + +#### Summary of configurables applicable to all lpc55s69 example configurations: +- `PKA` : Turn on/off hardware acceleration of crypto algs +- `HWPUF` : Turn on/off support for the hardware PUF +- `WOLFBOOT_HWPUF_PROVISION` : Turn on/off auto-provisioning of the HWPUF on +first boot. Performs PUF enrollment and generates a UDS key for device +attestation. Stores PUF keycodes in a known flash location and uses them when +necessary. + ### LPC55S69: Configuring and compiling Copy the example configuration file and build with make: @@ -2851,9 +2901,6 @@ cp config/examples/lpc55s69.config .config make ``` -We also provide a TrustZone configuration at `config/examples/lpc55s69-tz.config` -and a benchmarking configuration at `config/examples/lpc55s69-benchmark.config`. - ### LPC55S69: Loading the firmware Download and install the LinkServer tool: