From a98fba863f240669019e1c6e528c00366299be69 Mon Sep 17 00:00:00 2001 From: David Garske Date: Tue, 6 Oct 2026 17:56:05 -0700 Subject: [PATCH] Add QorIQ SEC support to the T2080 and T1040 bare-metal test apps --- .github/workflows/test-configs.yml | 18 ++++++ lib/wolfssl | 2 +- test-app/Makefile | 62 ++++++++++++++++++-- test-app/PPC.ld | 10 +++- test-app/app_nxp_t1040.c | 94 ++++++++++++++++++++++++++---- test-app/app_nxp_t2080.c | 63 +++++++++++++++++--- test-app/wolfcrypt_support.c | 15 +++-- 7 files changed, 233 insertions(+), 31 deletions(-) diff --git a/.github/workflows/test-configs.yml b/.github/workflows/test-configs.yml index 1c87e31f..08563bad 100644 --- a/.github/workflows/test-configs.yml +++ b/.github/workflows/test-configs.yml @@ -301,6 +301,24 @@ jobs: config-file: ./config/examples/nxp-t2080.config make-args: CFLAGS_EXTRA=-DBOARD_CW_VPX3152 + # ELF=0 on both: the test app is a flat image linked at + # WOLFBOOT_LOAD_ADDRESS, and ELF=1 would sign test-app/image.elf instead, + # which elf_load then refuses because it is staged at its own link address. + nxp_t2080_sec_qoriq_test: + uses: ./.github/workflows/test-build-powerpc.yml + with: + arch: ppc + config-file: ./config/examples/nxp-t2080.config + # The board macro relocates CCSRBAR; the SEC base follows it. + make-args: SEC_QORIQ=1 CFLAGS_EXTRA=-DBOARD_CW_VPX3152 WOLFCRYPT_TEST=1 ELF=0 + + nxp_t1040_sec_qoriq_test: + uses: ./.github/workflows/test-build-powerpc.yml + with: + arch: ppc + config-file: ./config/examples/nxp-t1040.config + make-args: SEC_QORIQ=1 WOLFCRYPT_TEST=1 ELF=0 + nxp_lpc54s0xx_test: uses: ./.github/workflows/test-build.yml with: diff --git a/lib/wolfssl b/lib/wolfssl index 3c5eead4..57502e3d 160000 --- a/lib/wolfssl +++ b/lib/wolfssl @@ -1 +1 @@ -Subproject commit 3c5eead44904df64e6a5a1f4ebdce377d35a849a +Subproject commit 57502e3ded5776ada0f3a15c4b0a6e0219007563 diff --git a/test-app/Makefile b/test-app/Makefile index 499d7bca..6de928ce 100644 --- a/test-app/Makefile +++ b/test-app/Makefile @@ -87,6 +87,15 @@ ifeq ($(TARGET),sim) STACK_USAGE_LIMIT:=4608 endif +# SP_MATH_ALL with RSA-2048 puts ~18 KB frames in sp_int.c. The PowerPC test +# app runs from DDR with a 256 KB stack, so that is affordable here even +# though it would not be on a small target. +ifeq ($(ARCH),PPC) + ifneq ($(filter 1,$(WOLFCRYPT_TEST) $(WOLFCRYPT_BENCHMARK)),) + STACK_USAGE_LIMIT:=20480 + endif +endif + ifeq ($(TARGET),ti_hercules) APP_OBJS:=app_$(TARGET).o ../test-app/libwolfboot.o CFLAGS+=-I"../include" @@ -216,6 +225,39 @@ ifeq ($(TARGET),max32666) endif endif +# NXP QorIQ SEC hardware crypto, selected through the crypto callback layer. +ifeq ($(SEC_QORIQ),1) + # The CCSR base has to be on the compile line, not a #define in the app: the + # sec_qoriq*.o driver objects are separate translation units and would + # otherwise fall through to the 0xFE000000 reset value in sec_qoriq.h while + # the app used the relocated one. Default it from the same board macro that + # selects the HAL's CCSRBAR so the two cannot disagree, and keep it + # overridable for a board whose SEC window sits elsewhere. + ifeq ($(SEC_QORIQ_CCSRBAR),) + ifneq ($(findstring BOARD_CW_VPX3152,$(CFLAGS_EXTRA)),) + SEC_QORIQ_CCSRBAR=0xEF000000UL + else + SEC_QORIQ_CCSRBAR=0xFE000000UL + endif + endif + CFLAGS+=-DWOLFSSL_SEC_QORIQ -DWOLFSSL_SEC_QORIQ_BAREMETAL + # The apps only bring the engine up under WOLFCRYPT_TEST/WOLFCRYPT_BENCHMARK, + # so SEC_QORIQ on its own links the driver without ever touching the device. + ifeq ($(WOLFCRYPT_TEST)$(WOLFCRYPT_BENCHMARK),) + $(warning SEC_QORIQ=1 has no effect without WOLFCRYPT_TEST or WOLFCRYPT_BENCHMARK) + endif + CFLAGS+=-DSEC_QORIQ_CCSRBAR=$(SEC_QORIQ_CCSRBAR) + WOLFCRYPT_SUPPORT=1 + APP_OBJS+=$(WOLFBOOT_LIB_WOLFSSL)/wolfcrypt/src/cryptocb.o + APP_OBJS+=$(WOLFBOOT_LIB_WOLFSSL)/wolfcrypt/src/port/nxp/sec_qoriq.o + APP_OBJS+=$(WOLFBOOT_LIB_WOLFSSL)/wolfcrypt/src/port/nxp/sec_qoriq_cb.o + APP_OBJS+=$(WOLFBOOT_LIB_WOLFSSL)/wolfcrypt/src/port/nxp/sec_qoriq_hash.o + APP_OBJS+=$(WOLFBOOT_LIB_WOLFSSL)/wolfcrypt/src/port/nxp/sec_qoriq_aes.o + APP_OBJS+=$(WOLFBOOT_LIB_WOLFSSL)/wolfcrypt/src/port/nxp/sec_qoriq_rng.o + APP_OBJS+=$(WOLFBOOT_LIB_WOLFSSL)/wolfcrypt/src/port/nxp/sec_qoriq_pkha.o + APP_OBJS+=$(WOLFBOOT_LIB_WOLFSSL)/wolfcrypt/src/port/nxp/sec_qoriq_baremetal.o +endif + ifeq ($(WOLFCRYPT_TEST),1) CFLAGS+=-DWOLFCRYPT_TEST WOLFCRYPT_SUPPORT=1 @@ -365,11 +407,21 @@ ifeq ($(WOLFCRYPT_SUPPORT),1) # wolfcrypt C sources expect these asm symbols; provide the objects here. ifeq ($(ARCH),RISCV64) CFLAGS+=-DWOLFSSL_RISCV_ASM - APP_OBJS+= \ - $(WOLFBOOT_LIB_WOLFSSL)/wolfcrypt/src/port/riscv/riscv-64-sha256.o \ - $(WOLFBOOT_LIB_WOLFSSL)/wolfcrypt/src/port/riscv/riscv-64-sha512.o \ - $(WOLFBOOT_LIB_WOLFSSL)/wolfcrypt/src/port/riscv/riscv-64-sha3.o \ - $(WOLFBOOT_LIB_WOLFSSL)/wolfcrypt/src/port/riscv/riscv-64-aes.o + # Same pre/post-move layout probe as arch.mk, which is included above and + # has already set RISCV_ASM_DIR. + ifneq ($(wildcard $(RISCV_ASM_DIR)/riscv-64-sha256-asm.S),) + APP_OBJS+= \ + $(RISCV_ASM_DIR)/riscv-64-sha256-asm.o \ + $(RISCV_ASM_DIR)/riscv-64-sha512-asm.o \ + $(RISCV_ASM_DIR)/riscv-64-sha3-asm.o \ + $(RISCV_ASM_DIR)/riscv-64-aes-asm.o + else + APP_OBJS+= \ + $(WOLFBOOT_LIB_WOLFSSL)/wolfcrypt/src/port/riscv/riscv-64-sha256.o \ + $(WOLFBOOT_LIB_WOLFSSL)/wolfcrypt/src/port/riscv/riscv-64-sha512.o \ + $(WOLFBOOT_LIB_WOLFSSL)/wolfcrypt/src/port/riscv/riscv-64-sha3.o \ + $(WOLFBOOT_LIB_WOLFSSL)/wolfcrypt/src/port/riscv/riscv-64-aes.o + endif endif endif diff --git a/test-app/PPC.ld b/test-app/PPC.ld index dad96fce..8ece86a5 100644 --- a/test-app/PPC.ld +++ b/test-app/PPC.ld @@ -67,9 +67,13 @@ SECTIONS /* Heap for _sbrk (used by syscalls.c malloc) */ _Min_Heap_Size = 0x10000; /* 64KB */ - /* Stack: 64KB, grows downward from _stack_top. - * wolfCrypt ECC384 operations need deep stack (~11KB per frame). */ - _Min_Stack_Size = 0x10000; /* 64KB */ + /* Stack: 256KB, grows downward from _stack_top. + * wolfCrypt ECC384 operations need deep stack (~11KB per frame), and an + * RSA-enabled wolfcrypt_test build needs far more again: SP_INT_BITS + * rises to the RSA key size, which enlarges every mp_int the PBKDF and + * PKCS#12 paths put on the stack. The app runs from DDR, so the space + * costs nothing. */ + _Min_Stack_Size = 0x40000; /* 256KB */ _stack_end = _end + _Min_Heap_Size; _stack_top = _stack_end + _Min_Stack_Size; } diff --git a/test-app/app_nxp_t1040.c b/test-app/app_nxp_t1040.c index 19548afb..68a86fc3 100644 --- a/test-app/app_nxp_t1040.c +++ b/test-app/app_nxp_t1040.c @@ -27,6 +27,23 @@ #include "target.h" #include "wolfboot/wolfboot.h" +/* wolfCrypt test/benchmark support */ +#ifdef WOLFCRYPT_TEST +#include +#include +int wolfcrypt_test(void *args); +#endif + +#ifdef WOLFCRYPT_BENCHMARK +#include +#include +int benchmark_test(void *args); +#endif + +#ifdef WOLFSSL_SEC_QORIQ +#include +#endif + /* wait_ticks: spin for r3 ticks using PPC timebase. * Required by udelay() in nxp_ppc.c (linked via HAL). */ __asm__ ( @@ -47,9 +64,8 @@ __asm__ ( " blr\n" ); -/* Assembly entry: set SP (_stack_top, PPC ABI: 16-byte aligned, back-chain 0), - * enable the FPU (MSR[FP]) -- the variadic printf ABI saves FP regs via stfd - * and would otherwise fault -- then branch to main. */ +/* Entry: set SP (PPC ABI, 16-byte aligned, back-chain 0), enable MSR[FP] so + * the variadic printf ABI can save FP regs with stfd, then branch to main. */ __asm__ ( ".section .text._app_entry\n" ".global _app_entry\n" @@ -152,14 +168,17 @@ static int print_info(void) void main(void) { - /* Zero BSS - required for bare-metal since there's no crt0 startup. - * Without this, static variables contain DDR garbage. */ extern char _start_bss[], _end_bss[]; - { - char *p = _start_bss; - while (p < _end_bss) - *p++ = 0; - } + char *p; +#if (defined(WOLFCRYPT_TEST) || defined(WOLFCRYPT_BENCHMARK)) && \ + defined(WOLFSSL_SEC_QORIQ) + SecQoriqDev* d; + int secRet; +#endif + + /* No crt0 on bare metal, so statics start as DDR garbage. */ + for (p = _start_bss; p < _end_bss; p++) + *p = 0; uart_init(); @@ -175,6 +194,61 @@ void main(void) wolfBoot_success(); wolfBoot_printf("\r\nBoot partition marked successful\r\n"); +#if defined(WOLFCRYPT_TEST) || defined(WOLFCRYPT_BENCHMARK) + wolfCrypt_Init(); + +#ifdef WOLFSSL_SEC_QORIQ + secRet = wc_SecQoriqInit(); + if (secRet == 0) { + wolfBoot_printf("QorIQ SEC: enabled, devId 0x%x\r\n", + (unsigned int)WOLFSSL_SEC_QORIQ_DEVID); + } + else { + wolfBoot_printf("QorIQ SEC: init failed (%d), software only\r\n", + secRet); + } +#endif + +#ifdef WOLFCRYPT_TEST + wolfBoot_printf("\r\nRunning wolfCrypt tests...\r\n"); + wolfcrypt_test(NULL); + wolfBoot_printf("Tests complete.\r\n\r\n"); +#endif + +#ifdef WOLFCRYPT_BENCHMARK + wolfBoot_printf("Running wolfCrypt benchmarks...\r\n"); + benchmark_test(NULL); + wolfBoot_printf("Benchmarks complete.\r\n\r\n"); +#endif + +#ifdef WOLFSSL_SEC_QORIQ + /* Report what actually reached the engine: a passing test proves nothing + * about offload, since every unhandled case falls back to software. */ + d = wc_SecQoriqGetDev(); + if (d != NULL) { + wolfBoot_printf("SEC offload counters:\r\n"); + wolfBoot_printf(" jobs submitted : %u\r\n", + (unsigned int)d->jobCount); + wolfBoot_printf(" hash seen %u offloaded %u\r\n", + (unsigned int)d->cbHashCount, (unsigned int)d->cbHashOffload); + wolfBoot_printf(" cipher seen %u offloaded %u\r\n", + (unsigned int)d->cbCipherCount, (unsigned int)d->cbCipherOffload); + wolfBoot_printf(" pk seen %u offloaded %u\r\n", + (unsigned int)d->cbPkCount, (unsigned int)d->cbPkOffload); + wolfBoot_printf(" seed seen %u\r\n", + (unsigned int)d->cbSeedCount); + } +#endif + +#ifdef WOLFSSL_SEC_QORIQ + if (secRet == 0) { + wc_SecQoriqFree(); + } +#endif + + wolfCrypt_Cleanup(); +#endif + #ifdef ENABLE_WOLFIP wolfip_tftp_test_report(); #endif diff --git a/test-app/app_nxp_t2080.c b/test-app/app_nxp_t2080.c index fd2e1cd1..26e5ed7e 100644 --- a/test-app/app_nxp_t2080.c +++ b/test-app/app_nxp_t2080.c @@ -68,6 +68,10 @@ int wolfcrypt_test(void *args); int benchmark_test(void *args); #endif +#ifdef WOLFSSL_SEC_QORIQ +#include +#endif + static uint8_t boot_part_state = IMG_STATE_NEW; static uint8_t update_part_state = IMG_STATE_NEW; @@ -143,14 +147,19 @@ static int print_info(void) void main(void) { - /* Zero BSS (no crt0 on bare metal): the wolfCrypt static-memory pools - * (gTestMemory/HEAP_HINT) must start zeroed or wc_LoadStaticMemory crashes. */ extern char _start_bss[], _end_bss[]; - { - char *p = _start_bss; - while (p < _end_bss) - *p++ = 0; - } + char *p; +#if (defined(WOLFCRYPT_TEST) || defined(WOLFCRYPT_BENCHMARK)) && \ + defined(WOLFSSL_SEC_QORIQ) + SecQoriqDev* d; + int secRet; +#endif + + /* No crt0 on bare metal, and the wolfCrypt static-memory pools + * (gTestMemory/HEAP_HINT) must start zeroed or wc_LoadStaticMemory + * crashes. */ + for (p = _start_bss; p < _end_bss; p++) + *p = 0; uart_init(); @@ -165,6 +174,21 @@ void main(void) #if defined(WOLFCRYPT_TEST) || defined(WOLFCRYPT_BENCHMARK) wolfCrypt_Init(); +#ifdef WOLFSSL_SEC_QORIQ + /* test.c and benchmark.c take their devId from WC_USE_DEVID, which + * wolfcrypt/settings.h maps to WOLFSSL_SEC_QORIQ_DEVID when the port + * is enabled. */ + secRet = wc_SecQoriqInit(); + if (secRet == 0) { + wolfBoot_printf("QorIQ SEC: enabled, devId 0x%x\r\n", + (unsigned int)WOLFSSL_SEC_QORIQ_DEVID); + } + else { + wolfBoot_printf("QorIQ SEC: init failed (%d), software only\r\n", + secRet); + } +#endif + #ifdef WOLFCRYPT_TEST wolfBoot_printf("\r\nRunning wolfCrypt tests...\r\n"); wolfcrypt_test(NULL); @@ -177,6 +201,31 @@ void main(void) wolfBoot_printf("Benchmarks complete.\r\n\r\n"); #endif +#ifdef WOLFSSL_SEC_QORIQ + /* Report what actually reached the engine: a passing test proves nothing + * about offload, since every unhandled case falls back to software. */ + d = wc_SecQoriqGetDev(); + if (d != NULL) { + wolfBoot_printf("SEC offload counters:\r\n"); + wolfBoot_printf(" jobs submitted : %u\r\n", + (unsigned int)d->jobCount); + wolfBoot_printf(" hash seen %u offloaded %u\r\n", + (unsigned int)d->cbHashCount, (unsigned int)d->cbHashOffload); + wolfBoot_printf(" cipher seen %u offloaded %u\r\n", + (unsigned int)d->cbCipherCount, (unsigned int)d->cbCipherOffload); + wolfBoot_printf(" pk seen %u offloaded %u\r\n", + (unsigned int)d->cbPkCount, (unsigned int)d->cbPkOffload); + wolfBoot_printf(" seed seen %u\r\n", + (unsigned int)d->cbSeedCount); + } +#endif + +#ifdef WOLFSSL_SEC_QORIQ + if (secRet == 0) { + wc_SecQoriqFree(); + } +#endif + wolfCrypt_Cleanup(); #endif diff --git a/test-app/wolfcrypt_support.c b/test-app/wolfcrypt_support.c index a9a5c6d6..7dd949a7 100644 --- a/test-app/wolfcrypt_support.c +++ b/test-app/wolfcrypt_support.c @@ -105,8 +105,9 @@ { (void)m7_get_ticks(); } -#elif defined(TARGET_nxp_t2080) || defined(TARGET_nxp_t1024) - /* PPC time base register for accurate timing (e6500). */ +#elif defined(TARGET_nxp_t2080) || defined(TARGET_nxp_t1024) || \ + defined(TARGET_nxp_t1040) + /* PPC time base register for accurate timing (e6500/e5500). */ static uint32_t ppc_tb_hz = 0; static unsigned long long ppc_start_ticks = 0; @@ -138,7 +139,9 @@ #endif volatile uint32_t *rcwsr0 = (volatile uint32_t *)(ccsr + 0xE0100UL); uint32_t plat_ratio = ((*rcwsr0) >> 25) & 0x1FU; - #if defined(BOARD_NAII_68PPC2) || defined(TARGET_nxp_t1024) + #if defined(BOARD_NAII_68PPC2) || defined(TARGET_nxp_t1024) || \ + defined(TARGET_nxp_t1040) + /* T10xx boards run a 100 MHz SYSCLK; see SYS_CLK in hal/nxp_t10xx.c */ uint32_t sys_clk = 100000000; /* 100 MHz */ #else uint32_t sys_clk = 66666667; /* 66.66 MHz */ @@ -214,7 +217,8 @@ unsigned long my_time(unsigned long* timer) if (timer) *timer = t; return t; } -#elif defined(TARGET_nxp_t2080) || defined(TARGET_nxp_t1024) +#elif defined(TARGET_nxp_t2080) || defined(TARGET_nxp_t1024) || \ + defined(TARGET_nxp_t1040) if (ppc_tb_hz == 0) ppc_tb_hz = ppc_get_timebase_hz(); { @@ -265,7 +269,8 @@ double current_time(int reset) if (reset) m7_start_ticks = m7_get_ticks(); return (double)(m7_get_ticks() - m7_start_ticks) / (double)IMX95_M7_HZ; -#elif defined(TARGET_nxp_t2080) || defined(TARGET_nxp_t1024) +#elif defined(TARGET_nxp_t2080) || defined(TARGET_nxp_t1024) || \ + defined(TARGET_nxp_t1040) if (ppc_tb_hz == 0) ppc_tb_hz = ppc_get_timebase_hz(); if (reset)