From ccc0425a211e0134d0d108b0aaad2b733075644c Mon Sep 17 00:00:00 2001 From: David Garske Date: Fri, 20 Jun 2025 14:45:25 -0700 Subject: [PATCH 1/5] Add support for PowerPC 32-bit SHA256 assembly speedups. Minor fix for ELF loading to set entry point before copying sections (resolves issue with loading on top of current location). Rename elf_load_image_mmu argument `entry` to `pentry` to avoid confusion with GET_H64 macro's use of header member "entry". --- arch.mk | 32 +++++++++++------------- config/examples/nxp-p1021.config | 6 +++-- docs/Targets.md | 11 ++++++--- hal/nxp_p1021.c | 42 ++++++++++++++++++++++++++++++++ hal/nxp_ppc.h | 1 + include/elf.h | 2 +- lib/wolfssl | 2 +- src/elf.c | 8 +++--- 8 files changed, 75 insertions(+), 29 deletions(-) diff --git a/arch.mk b/arch.mk index ea0b631ab9..7c3680e069 100644 --- a/arch.mk +++ b/arch.mk @@ -561,6 +561,19 @@ ifeq ($(ARCH),PPC) LDFLAGS+=-Wl,--gc-sections OBJS+=src/boot_ppc_start.o src/boot_ppc.o + + ifeq ($(SPMATH),1) + MATH_OBJS += ./lib/wolfssl/wolfcrypt/src/sp_c32.o + endif + + ifneq ($(NO_ASM),1) + # Use the SHA256 and SP math all assembly accelerations + CFLAGS+=-DWOLFSSL_SP_PPC + CFLAGS+=-DWOLFSSL_PPC32_ASM -DWOLFSSL_PPC32_ASM_INLINE + #CFLAGS+=-DWOLFSSL_PPC32_ASM_SMALL + #CFLAGS+=-DUSE_SLOW_SHA256 + OBJS+=./lib/wolfssl/wolfcrypt/src/port/ppc32/ppc32-sha256-asm_c.o + endif endif ifeq ($(TARGET),kinetis) @@ -788,12 +801,7 @@ ifeq ($(TARGET),nxp_t1024) OBJS+=src/pci.o CFLAGS+=-DWOLFBOOT_USE_PCI UPDATE_OBJS:=src/update_ram.o - ifeq ($(SPMATH),1) - MATH_OBJS += ./lib/wolfssl/wolfcrypt/src/sp_c32.o - else - # Use the SP math all assembly accelerations - CFLAGS+=-DWOLFSSL_SP_PPC - endif + SPI_TARGET=nxp OPTIMIZATION_LEVEL=0 # using default -Os causes issues with alignment endif @@ -811,12 +819,6 @@ ifeq ($(TARGET),nxp_t2080) LDFLAGS+=-Wl,--as-needed # remove weak functions not used UPDATE_OBJS:=src/update_ram.o OBJS+=src/fdt.o - ifeq ($(SPMATH),1) - MATH_OBJS += ./lib/wolfssl/wolfcrypt/src/sp_c32.o - else - # Use the SP math all assembly accelerations - CFLAGS+=-DWOLFSSL_SP_PPC - endif endif ifeq ($(TARGET),nxp_p1021) @@ -835,12 +837,6 @@ ifeq ($(TARGET),nxp_p1021) # Use PPC stdlib for memcpy, etc. #CFLAGS+=-DWOLFBOOT_USE_STDLIBC - ifeq ($(SPMATH),1) - MATH_OBJS += ./lib/wolfssl/wolfcrypt/src/sp_c32.o - else - # Use the SP math all assembly accelerations - CFLAGS+=-DWOLFSSL_SP_PPC - endif SPI_TARGET=nxp endif diff --git a/config/examples/nxp-p1021.config b/config/examples/nxp-p1021.config index 196f9de023..9b9ec912e5 100644 --- a/config/examples/nxp-p1021.config +++ b/config/examples/nxp-p1021.config @@ -4,6 +4,7 @@ SIGN?=ECC384 HASH?=SHA384 IMAGE_HEADER_SIZE?=512 DEBUG?=0 +DEBUG_SYMBOLS?=1 DEBUG_UART?=1 VTOR?=1 CORTEX_M0?=0 @@ -16,12 +17,13 @@ ALLOW_DOWNGRADE?=0 NVM_FLASH_WRITEONCE?=0 WOLFBOOT_VERSION?=0 NO_MPU?=0 -SPMATH?=0 -SPMATHALL?=1 +SPMATH?=1 +SPMATHALL?=0 RAM_CODE?=0 DUALBANK_SWAP?=0 WOLFTPM?=0 ELF?=1 +DEBUG_ELF?=0 # Flash Sector (Block) Size (16KB) WOLFBOOT_SECTOR_SIZE=0x4000 diff --git a/docs/Targets.md b/docs/Targets.md index 0000e3ec83..599b7229ec 100644 --- a/docs/Targets.md +++ b/docs/Targets.md @@ -1990,12 +1990,15 @@ make DEBUG=1 wolfboot.bin # OR make wolfboot.bin -# Sign application +# Build test app +make test-app/image.bin + +# Sign the ELF32 application # 1=version (can be any 32-bit value) -./tools/keytools/sign \ +IMAGE_HEADER_SIZE=512 ./tools/keytools/sign \ --ecc384 \ --sha384 \ - test-app/image.bin \ + test-app/image.elf \ wolfboot_signing_private_key.der \ 1 @@ -2003,7 +2006,7 @@ make wolfboot.bin factory.bin \ 0x0 hal/nxp_p1021_stage1.bin \ 0x8000 wolfboot.bin \ - 0x200000 test-app/image.bin \ + 0x200000 test-app/image_v1_signed.bin \ 0x01F00000 fsl_qe_ucode_1021_10_A.bin ``` diff --git a/hal/nxp_p1021.c b/hal/nxp_p1021.c index 85d3b9bac1..b580555ba3 100644 --- a/hal/nxp_p1021.c +++ b/hal/nxp_p1021.c @@ -514,6 +514,48 @@ static void udelay(uint32_t delay_us) wait_ticks(delay_us * DELAY_US); } +#if 0 /* useful timer code */ + +uint64_t hal_timer_ms(void) +{ + uint64_t val; + /* time base is updated every 8 CCB clocks */ + uint64_t cntfrq = hal_get_bus_clk() / 8; + uint64_t cntpct = get_ticks(); + val = (cntpct * 1000ULL) / cntfrq; + return val; +} + +/* example usage */ +//uint64_t start = hal_get_tick_count(); +// do some work +//wolfBoot_printf("done (%lu ms)\n", (uint32_t)hal_elapsed_time_ms(start)); + +/* Calculate elapsed time in milliseconds, handling timer overflow properly */ +uint64_t hal_elapsed_time_ms(uint64_t start_ticks) +{ + uint64_t current_ticks, elapsed_ticks; + uint64_t cntfrq = hal_get_bus_clk() / 8; + + current_ticks = get_ticks(); + + /* Handle timer overflow using unsigned arithmetic + * This works correctly even if the timer has rolled over, + * as long as the elapsed time is less than the full timer range + */ + elapsed_ticks = current_ticks - start_ticks; + + /* Convert elapsed ticks to milliseconds */ + return (elapsed_ticks * 1000ULL) / cntfrq; +} + +/* Get current tick count for use with hal_elapsed_time_ms() */ +uint64_t hal_get_tick_count(void) +{ + return get_ticks(); +} +#endif + /* ---- eSPI Driver ---- */ #ifdef ENABLE_ESPI void hal_espi_init(uint32_t cs, uint32_t clock_hz, uint32_t mode) diff --git a/hal/nxp_ppc.h b/hal/nxp_ppc.h index cd6c37d10a..9a1ad94d88 100644 --- a/hal/nxp_ppc.h +++ b/hal/nxp_ppc.h @@ -498,6 +498,7 @@ /* Hardware Implementation-Dependent Registers */ #define SPRN_HID0 0x3F0 #define HID0_TBEN (1 << 14) /* Time base enable */ +#define HID0_TBCLK (1 << 13) /* select clock: 0=every 8 ccb clocks, 1=rising edge of RTC */ #define HID0_ENMAS7 (1 << 7) /* Enable hot-wire update of MAS7 register */ #define HID0_EMCP (1 << 31) /* Enable machine check pin */ diff --git a/include/elf.h b/include/elf.h index ca1f2bdfdb..615155c77b 100644 --- a/include/elf.h +++ b/include/elf.h @@ -166,7 +166,7 @@ typedef struct elf64_program_header { #define GET_E32(name) (is_elf32 ? GET32(e32->name) : GET32(e64->name)) typedef int (*elf_mmu_map_cb)(uint64_t, uint64_t, uint32_t); -int elf_load_image_mmu(uint8_t *image, uintptr_t *entry, elf_mmu_map_cb mmu_cb); +int elf_load_image_mmu(uint8_t *image, uintptr_t *pentry, elf_mmu_map_cb mmu_cb); int elf_load_image(uint8_t *image, uintptr_t *entry, int is_ext); int64_t elf_hdr_pht_combined_size(const unsigned char* ehdr); int elf_open(const unsigned char *ehdr, int *is_elf32); diff --git a/lib/wolfssl b/lib/wolfssl index 2151a1b8a1..f30c54abdd 160000 --- a/lib/wolfssl +++ b/lib/wolfssl @@ -1 +1 @@ -Subproject commit 2151a1b8a1f8f81c4dba985429d50b76db7307e5 +Subproject commit f30c54abdddf0ffee7a45ed7c89d9007a0a7c54e diff --git a/src/elf.c b/src/elf.c index b3ff6bb972..d1417452d4 100644 --- a/src/elf.c +++ b/src/elf.c @@ -54,7 +54,7 @@ static int check_scatter_format(const unsigned char* ehdr, int is_elf32); /* Loader for elf32 or elf64 format program headers * Returns the entry point function */ -int elf_load_image_mmu(uint8_t *image, uintptr_t *entry, elf_mmu_map_cb mmu_cb) +int elf_load_image_mmu(uint8_t *image, uintptr_t *pentry, elf_mmu_map_cb mmu_cb) { elf32_header* h32 = (elf32_header*)image; elf64_header* h64 = (elf64_header*)image; @@ -86,6 +86,9 @@ int elf_load_image_mmu(uint8_t *image, uintptr_t *entry, elf_mmu_map_cb mmu_cb) is_elf32 ? 32 : 64, is_le ? "little" : "big"); #endif + /* set entry point */ + *pentry = GET_H64(entry); + /* programs */ entry_off = image + GET_H32(ph_offset); entry_size = GET_H16(ph_entry_size); @@ -144,9 +147,8 @@ int elf_load_image_mmu(uint8_t *image, uintptr_t *entry, elf_mmu_map_cb mmu_cb) #endif } - *entry = GET_H64(entry); #ifdef DEBUG_ELF - wolfBoot_printf("Entry point %p\r\n", (void*)*entry); + wolfBoot_printf("Entry point %p\r\n", (void*)*pentry); #endif return 0; From b26f8f95c4800dfe39af68def93b64436ccd5b62 Mon Sep 17 00:00:00 2001 From: David Garske Date: Fri, 20 Jun 2025 14:51:36 -0700 Subject: [PATCH 2/5] Fix issue with wolfssl submodule update and random.c change keytool failure because of NO_FILESYTEM. --- tools/keytools/user_settings.h | 1 - 1 file changed, 1 deletion(-) diff --git a/tools/keytools/user_settings.h b/tools/keytools/user_settings.h index b057df6754..2815f8f40d 100644 --- a/tools/keytools/user_settings.h +++ b/tools/keytools/user_settings.h @@ -149,7 +149,6 @@ #define NO_DES3 #define NO_PWDBASED #define NO_WRITEV -#define NO_FILESYSTEM #define NO_OLD_RNGNAME #define NO_WOLFSSL_DIR #define WOLFSSL_NO_SOCK From 45498ba0a108bc4f481ee04b8859401ac69cc6a8 Mon Sep 17 00:00:00 2001 From: David Garske Date: Mon, 23 Jun 2025 10:12:20 -0700 Subject: [PATCH 3/5] Update wolfssl submodule to resolve issue with TPM builds (no malloc, cert gen, crypto callback missing max digest size). --- lib/wolfssl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/wolfssl b/lib/wolfssl index f30c54abdd..b361c62372 160000 --- a/lib/wolfssl +++ b/lib/wolfssl @@ -1 +1 @@ -Subproject commit f30c54abdddf0ffee7a45ed7c89d9007a0a7c54e +Subproject commit b361c62372744dfca5168f6233730cb5351745ef From 11156ec3a544fcc55f4759d077815a0d8f2bf466 Mon Sep 17 00:00:00 2001 From: David Garske Date: Mon, 23 Jun 2025 11:15:10 -0700 Subject: [PATCH 4/5] Fixes for wolfssl submodule update. Also requires https://github.com/wolfSSL/wolfssl/pull/8913 --- arch.mk | 3 +-- lib/wolfssl | 2 +- tools/test.mk | 28 ++++++++++++++-------------- 3 files changed, 16 insertions(+), 17 deletions(-) diff --git a/arch.mk b/arch.mk index 7c3680e069..d990942e6a 100644 --- a/arch.mk +++ b/arch.mk @@ -571,8 +571,7 @@ ifeq ($(ARCH),PPC) CFLAGS+=-DWOLFSSL_SP_PPC CFLAGS+=-DWOLFSSL_PPC32_ASM -DWOLFSSL_PPC32_ASM_INLINE #CFLAGS+=-DWOLFSSL_PPC32_ASM_SMALL - #CFLAGS+=-DUSE_SLOW_SHA256 - OBJS+=./lib/wolfssl/wolfcrypt/src/port/ppc32/ppc32-sha256-asm_c.o + MATH_OBJS+=./lib/wolfssl/wolfcrypt/src/port/ppc32/ppc32-sha256-asm_c.o endif endif diff --git a/lib/wolfssl b/lib/wolfssl index b361c62372..aec13923a7 160000 --- a/lib/wolfssl +++ b/lib/wolfssl @@ -1 +1 @@ -Subproject commit b361c62372744dfca5168f6233730cb5351745ef +Subproject commit aec13923a7bdacf92e09e744ce40681c92395b67 diff --git a/tools/test.mk b/tools/test.mk index 404182c93a..8bc86c9e4a 100644 --- a/tools/test.mk +++ b/tools/test.mk @@ -961,40 +961,40 @@ test-all: clean test-size-all: - make test-size SIGN=NONE LIMIT=4860 NO_ARM_ASM=1 + make test-size SIGN=NONE LIMIT=4824 NO_ARM_ASM=1 make keysclean - make test-size SIGN=ED25519 LIMIT=11448 NO_ARM_ASM=1 + make test-size SIGN=ED25519 LIMIT=11428 NO_ARM_ASM=1 make keysclean - make test-size SIGN=ECC256 LIMIT=17988 NO_ARM_ASM=1 + make test-size SIGN=ECC256 LIMIT=17968 NO_ARM_ASM=1 make clean make test-size SIGN=ECC256 NO_ASM=1 LIMIT=13536 NO_ARM_ASM=1 make keysclean - make test-size SIGN=RSA2048 LIMIT=11272 NO_ARM_ASM=1 + make test-size SIGN=RSA2048 LIMIT=11264 NO_ARM_ASM=1 make clean - make test-size SIGN=RSA2048 NO_ASM=1 LIMIT=11840 NO_ARM_ASM=1 + make test-size SIGN=RSA2048 NO_ASM=1 LIMIT=11844 NO_ARM_ASM=1 make keysclean - make test-size SIGN=RSA4096 LIMIT=11556 NO_ARM_ASM=1 + make test-size SIGN=RSA4096 LIMIT=11552 NO_ARM_ASM=1 make clean - make test-size SIGN=RSA4096 NO_ASM=1 LIMIT=12128 NO_ARM_ASM=1 + make test-size SIGN=RSA4096 NO_ASM=1 LIMIT=12132 NO_ARM_ASM=1 make keysclean - make test-size SIGN=ECC384 LIMIT=17556 NO_ARM_ASM=1 + make test-size SIGN=ECC384 LIMIT=17464 NO_ARM_ASM=1 make clean - make test-size SIGN=ECC384 NO_ASM=1 LIMIT=14924 NO_ARM_ASM=1 + make test-size SIGN=ECC384 NO_ASM=1 LIMIT=14912 NO_ARM_ASM=1 make keysclean - make test-size SIGN=ED448 LIMIT=13464 NO_ARM_ASM=1 + make test-size SIGN=ED448 LIMIT=13416 NO_ARM_ASM=1 make keysclean - make test-size SIGN=RSA3072 LIMIT=11408 NO_ARM_ASM=1 + make test-size SIGN=RSA3072 LIMIT=11404 NO_ARM_ASM=1 make clean - make test-size SIGN=RSA3072 NO_ASM=1 LIMIT=11944 NO_ARM_ASM=1 + make test-size SIGN=RSA3072 NO_ASM=1 LIMIT=11948 NO_ARM_ASM=1 make keysclean make test-size SIGN=LMS LMS_LEVELS=2 LMS_HEIGHT=5 LMS_WINTERNITZ=8 \ WOLFBOOT_SMALL_STACK=0 IMAGE_SIGNATURE_SIZE=2644 \ - IMAGE_HEADER_SIZE?=5288 LIMIT=7536 NO_ARM_ASM=1 + IMAGE_HEADER_SIZE?=5288 LIMIT=7516 NO_ARM_ASM=1 make keysclean make test-size SIGN=XMSS XMSS_PARAMS='XMSS-SHA2_10_256' \ IMAGE_SIGNATURE_SIZE=2500 IMAGE_HEADER_SIZE?=4096 \ LIMIT=8292 NO_ARM_ASM=1 make keysclean make clean - make test-size SIGN=ML_DSA ML_DSA_LEVEL=2 LIMIT=20168 \ + make test-size SIGN=ML_DSA ML_DSA_LEVEL=2 LIMIT=18866 \ IMAGE_SIGNATURE_SIZE=2420 IMAGE_HEADER_SIZE?=8192 From e0950742db02cc965e206076465f59751ffb3551 Mon Sep 17 00:00:00 2001 From: David Garske Date: Tue, 24 Jun 2025 09:00:36 -0700 Subject: [PATCH 5/5] Add logic to detect ELF loader collision and skip. --- lib/wolfssl | 2 +- src/elf.c | 24 +++++++++++++++++------- 2 files changed, 18 insertions(+), 8 deletions(-) diff --git a/lib/wolfssl b/lib/wolfssl index aec13923a7..978a29da0b 160000 --- a/lib/wolfssl +++ b/lib/wolfssl @@ -1 +1 @@ -Subproject commit aec13923a7bdacf92e09e744ce40681c92395b67 +Subproject commit 978a29da0b76eb868748967f4cb74421dc2382a2 diff --git a/src/elf.c b/src/elf.c index d1417452d4..4f06b5c32e 100644 --- a/src/elf.c +++ b/src/elf.c @@ -136,15 +136,25 @@ int elf_load_image_mmu(uint8_t *image, uintptr_t *pentry, elf_mmu_map_cb mmu_cb) } } - memcpy((void*)(uintptr_t)vaddr, image + offset, file_size); - if (mem_size > file_size) { - memset((void*)(uintptr_t)(vaddr + file_size), 0, - mem_size - file_size); + /* confirm the entry won't clobber any of the headers */ + if ((uint8_t*)vaddr + file_size < image || + (uint8_t*)vaddr > (entry_off + entry_count * entry_size)) + { + memcpy((void*)vaddr, image + offset, file_size); + if (mem_size > file_size) { + memset((void*)(uintptr_t)(vaddr + file_size), 0, + mem_size - file_size); + } + #ifdef ARCH_PPC + flush_cache(paddr, mem_size); + #endif + } + #ifdef DEBUG_ELF + else { + wolfBoot_printf("Section would collide with headers! Skipping\n"); } - #ifdef ARCH_PPC - flush_cache(paddr, mem_size); #endif -#endif +#endif /* !ELF_PARSER */ } #ifdef DEBUG_ELF