diff --git a/.github/workflows/infineon-psoc-e8.yml b/.github/workflows/infineon-psoc-e8.yml
new file mode 100644
index 000000000..d3cecd780
--- /dev/null
+++ b/.github/workflows/infineon-psoc-e8.yml
@@ -0,0 +1,82 @@
+name: Infineon PSOC Edge E8
+
+on:
+ push:
+ branches: [master]
+ paths:
+ - 'embedded/infineon_psoc_e8/**'
+ - '.github/workflows/infineon-psoc-e8.yml'
+ pull_request:
+ types: [opened, synchronize, reopened, ready_for_review]
+ paths:
+ - 'embedded/infineon_psoc_e8/**'
+ - '.github/workflows/infineon-psoc-e8.yml'
+ # No cron: nightly.yml calls this, so the nightly stays one run and one triage writer
+ workflow_call:
+ inputs:
+ caller_run_id:
+ description: 'run id of the calling workflow; keeps a called run in its own concurrency group'
+ type: string
+ default: ''
+ workflow_dispatch:
+
+# github.workflow is the CALLER's name in a called workflow, so hardcode ours
+concurrency:
+ group: ${{ inputs.caller_run_id && format('psoc-e8-call-{0}', inputs.caller_run_id) || format('psoc-e8-{0}', github.ref) }}
+ cancel-in-progress: ${{ !inputs.caller_run_id }}
+
+permissions:
+ contents: read
+
+jobs:
+ psoc_e8:
+ name: Build / infineon_psoc_e8 (arm-none-eabi) wolfSSL master
+ if: github.event_name != 'pull_request' || github.event.pull_request.draft == false
+ runs-on: ubuntu-24.04
+ timeout-minutes: 20
+ steps:
+ - uses: actions/checkout@v5
+
+ - uses: ./.github/actions/apt-update
+ - name: Install toolchain
+ run: |
+ set -euo pipefail
+ sudo apt-get install -y --no-install-recommends \
+ gcc-arm-none-eabi libnewlib-arm-none-eabi build-essential
+
+ # The Infineon device support is pinned to the releases the example was
+ # validated with; see embedded/infineon_psoc_e8/README.md.
+ - name: Fetch wolfSSL and Infineon device support
+ run: |
+ set -euo pipefail
+ clone() { bash "$GITHUB_WORKSPACE/.github/scripts/git-clone-retry.sh" -q --depth 1 --branch "$1" "$2" "$3"; }
+ clone master https://github.com/wolfSSL/wolfssl /tmp/wolfssl
+ clone release-v1.8.0 https://github.com/Infineon/mtb-dsl-pse8xxgp /tmp/mtb-dsl-pse8xxgp
+ clone release-v1.5.0 https://github.com/Infineon/mtb-template-pse8xxgp /tmp/mtb-template-pse8xxgp
+ clone release-v1.8.0 https://github.com/Infineon/core-lib /tmp/core-lib
+ clone v6.4.0 https://github.com/ARM-software/CMSIS_6 /tmp/CMSIS_6
+
+ - name: Build (crypto engine, engine ECDSA verify, software only)
+ run: |
+ set -euo pipefail
+ cd embedded/infineon_psoc_e8
+ args="WOLFSSL_ROOT=/tmp/wolfssl PSE84_DSL=/tmp/mtb-dsl-pse8xxgp \
+ PSE84_TEMPLATE=/tmp/mtb-template-pse8xxgp CORE_LIB=/tmp/core-lib \
+ CMSIS=/tmp/CMSIS_6"
+ make $args
+ make $args PSOC_CRYPTO_ECC=1
+ make $args PSOC_CRYPTO=0
+
+ - name: Assert it really cross-compiled
+ run: |
+ set -euo pipefail
+ cd embedded/infineon_psoc_e8
+ for elf in Build/wolfcrypt_test.elf Build-ecc/wolfcrypt_test.elf \
+ Build-sw/wolfcrypt_bench.elf; do
+ arch=$(readelf -h "$elf" | awk -F: '/Machine:/ {print $2}' | xargs)
+ echo "$elf: $arch"
+ case "$arch" in
+ *ARM*) ;;
+ *) echo "FAIL: not an ARM binary: $arch"; exit 1 ;;
+ esac
+ done
diff --git a/.github/workflows/nightly.yml b/.github/workflows/nightly.yml
index 97e567944..36c618fc2 100644
--- a/.github/workflows/nightly.yml
+++ b/.github/workflows/nightly.yml
@@ -79,6 +79,12 @@ jobs:
with:
caller_run_id: ${{ github.run_id }}
+ infineon-psoc-e8:
+ needs: [refs]
+ uses: ./.github/workflows/infineon-psoc-e8.yml
+ with:
+ caller_run_id: ${{ github.run_id }}
+
mynewt:
needs: [refs]
uses: ./.github/workflows/mynewt.yml
diff --git a/README.md b/README.md
index 343aa8f37..662146757 100644
--- a/README.md
+++ b/README.md
@@ -294,6 +294,17 @@ Please see the [riot-os-posix-lwip/README.md](riot-os-posix-lwip/README.md) for
further usage and details.
+
+
+#### Infineon PSOC Edge E8 (KIT_PSE84_AI)
+
+This directory contains a bare-metal wolfCrypt test and benchmark for the
+PSOC Edge E84 Cortex-M33, using the on-chip crypto engine for SHA and AES,
+and its TRNG to seed the DRBG.
+
+Please see the [embedded/infineon_psoc_e8/README.md](embedded/infineon_psoc_e8/README.md) for further usage and details.
+
+
#### RT1060 (i.MX RT1060-EVK)
diff --git a/embedded/infineon_psoc_e8/.gitignore b/embedded/infineon_psoc_e8/.gitignore
new file mode 100644
index 000000000..816ff0b61
--- /dev/null
+++ b/embedded/infineon_psoc_e8/.gitignore
@@ -0,0 +1,4 @@
+Build/
+Build-sw/
+Build-ecc/
+Build-sw-ecc/
diff --git a/embedded/infineon_psoc_e8/Makefile b/embedded/infineon_psoc_e8/Makefile
new file mode 100644
index 000000000..f2f0c516c
--- /dev/null
+++ b/embedded/infineon_psoc_e8/Makefile
@@ -0,0 +1,121 @@
+# Makefile for the wolfCrypt test and benchmark on Infineon PSOC Edge E8
+#
+# Target: KIT_PSE84_AI (PSE846GPS2DBZC4A), CM33 Secure, run in place from QSPI
+# Usage: make - build wolfcrypt_test and wolfcrypt_bench
+# make PSOC_CRYPTO=0 - software only, for comparison
+# make PSOC_CRYPTO_ECC=1 - ECDSA verify on the engine as well
+# make clean
+#
+# Copyright (C) 2006-2026 wolfSSL Inc.
+
+TOOLCHAIN ?= arm-none-eabi-
+CC = $(TOOLCHAIN)gcc
+OBJCOPY = $(TOOLCHAIN)objcopy
+SIZE = $(TOOLCHAIN)size
+
+WOLFSSL_ROOT ?= ../../../wolfssl
+
+# Infineon device support, from github.com/Infineon (see README.md).
+PSE84_DSL ?= ../../../mtb-dsl-pse8xxgp
+PSE84_TEMPLATE ?= ../../../mtb-template-pse8xxgp
+CORE_LIB ?= ../../../core-lib
+CMSIS ?= ../../../CMSIS_6
+PSE84_PART ?= pse846gps2dbzc4a
+
+PSOC_CRYPTO ?= 1
+PSOC_CRYPTO_ECC ?= 0
+
+BUILD_DIR ?= ./Build$(if $(filter 0,$(PSOC_CRYPTO)),-sw)$(if $(filter 1,$(PSOC_CRYPTO_ECC)),-ecc)
+
+ARCHFLAGS = -mcpu=cortex-m33 -mthumb -mabi=aapcs
+
+CFLAGS = $(ARCHFLAGS) -std=gnu99 -Wall -O2 -g
+CFLAGS += -ffunction-sections -fdata-sections
+CFLAGS += -DWOLFSSL_USER_SETTINGS -DWOLFSSL_IGNORE_FILE_WARN
+CFLAGS += -DCOMPONENT_CM33 -DCORE_NAME_CM33_0 -DCOMPONENT_SECURE_DEVICE
+CFLAGS += -D$(shell echo $(PSE84_PART) | tr a-z A-Z)
+CFLAGS += -DPSE84_PART_HEADER='"$(PSE84_PART)_s.h"'
+CFLAGS += -I. -I$(WOLFSSL_ROOT)
+CFLAGS += -I$(PSE84_DSL)/pdl/drivers/include
+CFLAGS += -I$(PSE84_DSL)/pdl/drivers/third_party/ethernet/include
+CFLAGS += -I$(PSE84_DSL)/pdl/devices/include
+CFLAGS += -I$(PSE84_DSL)/pdl/devices/include/ip
+CFLAGS += -I$(PSE84_TEMPLATE)/files
+CFLAGS += -I$(PSE84_TEMPLATE)/files/devices/include
+CFLAGS += -I$(CORE_LIB)/include
+CFLAGS += -I$(CMSIS)/CMSIS/Core/Include
+ifeq ($(PSOC_CRYPTO),1)
+CFLAGS += -DWOLFSSL_PSOC6_CRYPTO
+endif
+ifneq ($(PSOC_CRYPTO_ECC),1)
+CFLAGS += -DNO_PSOC6_CRYPTO_ECC
+endif
+
+LDFLAGS = $(ARCHFLAGS) --specs=nano.specs -nostartfiles
+LDFLAGS += -Wl,--gc-sections -T./linker.ld
+LIBS = -lm
+
+WOLF = $(WOLFSSL_ROOT)/wolfcrypt/src
+SRC_WOLF = $(WOLF)/aes.c $(WOLF)/ecc.c $(WOLF)/error.c $(WOLF)/hash.c \
+ $(WOLF)/hmac.c $(WOLF)/logging.c $(WOLF)/memory.c $(WOLF)/misc.c \
+ $(WOLF)/random.c $(WOLF)/sha.c $(WOLF)/sha256.c $(WOLF)/sha512.c \
+ $(WOLF)/sha3.c $(WOLF)/sp_int.c $(WOLF)/sp_cortexm.c $(WOLF)/wc_port.c \
+ $(WOLF)/wolfmath.c $(WOLF)/asn.c $(WOLF)/coding.c $(WOLF)/kdf.c \
+ $(WOLF)/wc_encrypt.c $(WOLF)/signature.c \
+ $(WOLF)/port/cypress/psoc6_crypto.c
+
+# PDL crypto core drivers: the engine, its TRNG, and the ECC drivers when
+# ECDSA verify runs on the engine.
+PDL = $(PSE84_DSL)/pdl/drivers/source
+SRC_PDL = $(PDL)/cy_crypto_core_hw.c $(PDL)/cy_crypto_core_mem_v2.c \
+ $(PDL)/cy_crypto_core_sha_v2.c $(PDL)/cy_crypto_core_aes_v2.c \
+ $(PDL)/cy_crypto_core_vu.c $(PDL)/cy_crypto_core_trng.c
+ifeq ($(PSOC_CRYPTO_ECC),1)
+SRC_PDL += $(PDL)/cy_crypto_core_ecc_domain_params.c \
+ $(PDL)/cy_crypto_core_ecc_nist_p.c $(PDL)/cy_crypto_core_ecc_ecdsa.c \
+ $(PDL)/cy_crypto_core_ecc_key_gen.c $(PDL)/cy_crypto_core_ecc_ec25519.c
+endif
+
+SRC_TEST = $(WOLFSSL_ROOT)/wolfcrypt/test/test.c
+SRC_BENCH = $(WOLFSSL_ROOT)/wolfcrypt/benchmark/benchmark.c
+
+objs = $(addprefix $(BUILD_DIR)/$(1)/, $(notdir $(2:.c=.o)))
+OBJS_COMMON = $(call objs,common,$(SRC_WOLF) $(SRC_PDL) startup.c board.c)
+OBJS_TEST = $(OBJS_COMMON) $(call objs,test,main.c $(SRC_TEST))
+OBJS_BENCH = $(OBJS_COMMON) $(call objs,bench,main.c $(SRC_BENCH))
+
+vpath %.c . $(sort $(dir $(SRC_WOLF) $(SRC_PDL) $(SRC_TEST) $(SRC_BENCH)))
+
+.PHONY: all clean check-deps
+
+all: check-deps $(BUILD_DIR)/wolfcrypt_test.bin $(BUILD_DIR)/wolfcrypt_bench.bin
+ $(SIZE) $(BUILD_DIR)/wolfcrypt_test.elf $(BUILD_DIR)/wolfcrypt_bench.elf
+
+check-deps:
+ @for d in $(WOLFSSL_ROOT)/wolfcrypt $(PSE84_DSL)/pdl \
+ $(PSE84_TEMPLATE)/files $(CORE_LIB)/include $(CMSIS)/CMSIS; do \
+ test -d $$d || { echo "missing $$d (see README.md)"; exit 1; }; done
+
+$(BUILD_DIR)/common/%.o: %.c
+ @mkdir -p $(dir $@)
+ $(CC) $(CFLAGS) -c -o $@ $<
+
+$(BUILD_DIR)/test/%.o: %.c
+ @mkdir -p $(dir $@)
+ $(CC) $(CFLAGS) -c -o $@ $<
+
+$(BUILD_DIR)/bench/%.o: %.c
+ @mkdir -p $(dir $@)
+ $(CC) $(CFLAGS) -DBENCH_APP -c -o $@ $<
+
+$(BUILD_DIR)/wolfcrypt_test.elf: $(OBJS_TEST)
+ $(CC) $(LDFLAGS) -Wl,-Map=$(@:.elf=.map) -o $@ $^ $(LIBS)
+
+$(BUILD_DIR)/wolfcrypt_bench.elf: $(OBJS_BENCH)
+ $(CC) $(LDFLAGS) -Wl,-Map=$(@:.elf=.map) -o $@ $^ $(LIBS)
+
+$(BUILD_DIR)/%.bin: $(BUILD_DIR)/%.elf
+ $(OBJCOPY) -O binary $< $@
+
+clean:
+ rm -rf ./Build ./Build-sw ./Build-ecc ./Build-sw-ecc
diff --git a/embedded/infineon_psoc_e8/README.md b/embedded/infineon_psoc_e8/README.md
new file mode 100644
index 000000000..41067e0df
--- /dev/null
+++ b/embedded/infineon_psoc_e8/README.md
@@ -0,0 +1,47 @@
+# wolfCrypt on Infineon PSOC Edge E8
+
+Bare-metal wolfCrypt test and benchmark for the PSOC Edge E84 Cortex-M33 on the KIT_PSE84_AI board. The example runs in the Secure state as the first CM33 image Infineon's extended boot launches, in place from QSPI. It uses the on-chip crypto engine (MXCRYPTO) through wolfSSL's `WOLFSSL_PSOC6_CRYPTO` port for SHA-1/2/3 and AES (ECB, CBC, CFB, GCM), and seeds the Hash-DRBG from the engine's TRNG.
+
+## Requirements
+
+- `arm-none-eabi-gcc` with newlib
+- wolfSSL, with PSOC Edge support in the `WOLFSSL_PSOC6_CRYPTO` port
+- Infineon device support and CMSIS, at the releases this example was tested with:
+
+```sh
+git clone --depth 1 -b release-v1.8.0 https://github.com/Infineon/mtb-dsl-pse8xxgp
+git clone --depth 1 -b release-v1.5.0 https://github.com/Infineon/mtb-template-pse8xxgp
+git clone --depth 1 -b release-v1.8.0 https://github.com/Infineon/core-lib
+git clone --depth 1 -b v6.4.0 https://github.com/ARM-software/CMSIS_6
+```
+
+- ModusToolbox Programming Tools, for OpenOCD and the KitProg3 QSPI flash loader
+
+## Building
+
+The Makefile expects wolfSSL and the four repositories above next to `wolfssl-examples`. Override `WOLFSSL_ROOT`, `PSE84_DSL`, `PSE84_TEMPLATE`, `CORE_LIB` and `CMSIS` to point elsewhere.
+
+```sh
+make # Build/wolfcrypt_test.bin and Build/wolfcrypt_bench.bin
+make PSOC_CRYPTO=0 # software only, in Build-sw/
+make PSOC_CRYPTO_ECC=1 # ECDSA verify on the engine too, in Build-ecc/
+```
+
+Only the PDL crypto core drivers are compiled, so no ModusToolbox project or BSP is needed. `PSE84_PART` selects the part header (default `pse846gps2dbzc4a`).
+
+## Running
+
+```sh
+tools/flash.sh Build/wolfcrypt_test.bin
+tools/flash.sh Build/wolfcrypt_bench.bin
+```
+
+`tools/flash.sh` wraps the image in the MCUboot-format header that extended boot expects (`tools/mcuboot_wrap.py`) and programs it to QSPI `0x60100000` through the kit's KitProg3. Set `MTB_PROGTOOLS` if the tools are not in `/opt/Tools/ModusToolboxProgtools-1.6`, and `KITPROG_SERIAL` if several probes are attached. Output appears on the KitProg3 COM port at 115200 baud.
+
+This replaces the factory CM33 image, so read QSPI back first to keep the stock demo.
+
+## Notes
+
+- The clocks are left as extended boot sets them: the CM33 at 200 MHz and the console's peripheral clock at 100 MHz. Benchmark timing uses the DWT cycle counter.
+- Code and constants run from QSPI through the Secure code-bus alias. The port translates such addresses for the crypto engine, which reads memory over the system bus.
+- ECC runs in software with wolfSSL's SP math assembly, which verifies faster than the engine; `PSOC_CRYPTO_ECC=1` moves ECDSA verify to the engine. `WOLFSSL_SP_SMALL` is set because the full-size SP tables are slow to read from XIP flash.
diff --git a/embedded/infineon_psoc_e8/board.c b/embedded/infineon_psoc_e8/board.c
new file mode 100644
index 000000000..15b1a98c1
--- /dev/null
+++ b/embedded/infineon_psoc_e8/board.c
@@ -0,0 +1,237 @@
+/* board.c
+ *
+ * KIT_PSE84_AI board support: console UART, benchmark time base, TRNG seed
+ * and heap for the wolfCrypt test and benchmark.
+ *
+ * Copyright (C) 2006-2026 wolfSSL Inc.
+ *
+ * This file is part of wolfSSL.
+ *
+ * wolfSSL 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.
+ *
+ * wolfSSL 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
+#include
+#include
+#include
+
+#include "cy_crypto_core.h"
+#include "board.h"
+
+/* Extended boot leaves the clocks running and this example does not change
+ * them: CLK_HF0 (CM33) at 200 MHz and CLK_HF10 (peripheral group 1) at
+ * 100 MHz. */
+#ifndef BOARD_CPU_HZ
+#define BOARD_CPU_HZ 200000000UL
+#endif
+#ifndef BOARD_PCLK_HZ
+#define BOARD_PCLK_HZ 100000000UL
+#endif
+#define BOARD_UART_BAUD 115200UL
+#define BOARD_UART_OVS 8UL
+
+/* Console: SCB2 on P6.5 (RX) / P6.7 (TX), the KitProg3 COM port. */
+#define SCB2_BASE 0x529A0000UL
+#define UART_PORT 6
+#define UART_RX_PIN 5
+#define UART_TX_PIN 7
+#define UART_HSIOM_SEL 20UL
+#define UART_PCLK_GR 1UL /* PCLK_SCB2_CLOCK_SCB_EN = 0x101 */
+#define UART_PCLK_IDX 1UL
+#define UART_PCLK_DIV 0UL
+
+#define REG(a) (*(volatile uint32_t *)(a))
+
+#define PERI0_GR_SL_CTL(g) REG(0x52004010UL + ((g) * 0x40UL))
+#define PERI0_GR_SL_CTL2(g) REG(0x52004014UL + ((g) * 0x40UL))
+#define PCLK_GR(g) (0x52040000UL + ((g) * 0x2000UL))
+#define PCLK_DIV_CMD(g) REG(PCLK_GR(g))
+#define PCLK_CLOCK_CTL(g,i) REG(PCLK_GR(g) + 0xC00UL + ((i) * 4UL))
+#define PCLK_DIV_16_5(g,d) REG(PCLK_GR(g) + 0x1800UL + ((d) * 4UL))
+#define HSIOM_PORT_SEL(p,n) REG(0x52800000UL + ((p) * 0x10UL) + \
+ (((n) < 4) ? 0x0UL : 0x4UL))
+#define HSIOM_NSMASK(p) REG(0x52801000UL + ((p) * 0x10UL))
+#define GPIO_CFG(p) REG(0x52810000UL + ((p) * 0x80UL) + 0x44UL)
+
+#define UART_CTRL(b) REG((b) + 0x000UL)
+#define UART_UART_CTRL(b) REG((b) + 0x040UL)
+#define UART_UART_TX_CTRL(b) REG((b) + 0x044UL)
+#define UART_UART_RX_CTRL(b) REG((b) + 0x048UL)
+#define UART_TX_CTRL(b) REG((b) + 0x200UL)
+#define UART_TX_FIFO_CTRL(b) REG((b) + 0x204UL)
+#define UART_TX_FIFO_STAT(b) REG((b) + 0x208UL)
+#define UART_TX_FIFO_WR(b) REG((b) + 0x240UL)
+#define UART_RX_CTRL(b) REG((b) + 0x300UL)
+#define UART_RX_FIFO_CTRL(b) REG((b) + 0x304UL)
+
+#define DEMCR REG(0xE000EDFCUL)
+#define DWT_CTRL REG(0xE0001000UL)
+#define DWT_CYCCNT REG(0xE0001004UL)
+
+static int uart_ready;
+
+static void pin_setup(uint32_t port, uint32_t pin, uint32_t drive)
+{
+ uint32_t sh = (pin & 3U) * 8U;
+
+ /* Secure writes to a pin marked non-secure are ignored. */
+ HSIOM_NSMASK(port) &= ~(1UL << pin);
+ HSIOM_PORT_SEL(port, pin) = (HSIOM_PORT_SEL(port, pin) &
+ ~(0xFFUL << sh)) | (UART_HSIOM_SEL << sh);
+ GPIO_CFG(port) = (GPIO_CFG(port) & ~(0xFUL << (pin * 4U))) |
+ (drive << (pin * 4U));
+}
+
+static void uart_init(void)
+{
+ uint32_t scaled = (uint32_t)(((uint64_t)BOARD_PCLK_HZ * 32U) /
+ (BOARD_UART_BAUD * BOARD_UART_OVS));
+ uint32_t timeout = 1000000;
+
+ /* PERI0 group 1 holds the SCBs and is partly gated out of extended boot. */
+ PERI0_GR_SL_CTL2(1) = 0;
+ PERI0_GR_SL_CTL(1) = 0xFFFFFFFFUL;
+
+ pin_setup(UART_PORT, UART_RX_PIN, 0x8UL); /* high-Z input */
+ pin_setup(UART_PORT, UART_TX_PIN, 0x6UL); /* strong drive */
+
+ /* 16.5 fractional divider: pclk / (int + 1 + frac / 32). */
+ PCLK_DIV_16_5(UART_PCLK_GR, UART_PCLK_DIV) =
+ (((scaled / 32U) - 1U) << 8) | ((scaled % 32U) << 3);
+ PCLK_CLOCK_CTL(UART_PCLK_GR, UART_PCLK_IDX) = (2UL << 8) | UART_PCLK_DIV;
+ PCLK_DIV_CMD(UART_PCLK_GR) = (1UL << 31) | (3UL << 24) | (0xFFUL << 16) |
+ (2UL << 8) | UART_PCLK_DIV;
+ while (((PCLK_DIV_16_5(UART_PCLK_GR, UART_PCLK_DIV) & 1U) == 0) &&
+ (timeout > 0))
+ timeout--;
+ if (timeout == 0)
+ return; /* an unclocked SCB bus-faults, so stay silent */
+
+ UART_CTRL(SCB2_BASE) = 0;
+ UART_UART_CTRL(SCB2_BASE) = 0;
+ UART_UART_TX_CTRL(SCB2_BASE) = 1;
+ UART_UART_RX_CTRL(SCB2_BASE) = 1;
+ UART_TX_CTRL(SCB2_BASE) = 7; /* 8 data bits */
+ UART_RX_CTRL(SCB2_BASE) = 7;
+ UART_TX_FIFO_CTRL(SCB2_BASE) = 0x3F;
+ UART_RX_FIFO_CTRL(SCB2_BASE) = 0x3F;
+ UART_CTRL(SCB2_BASE) = (1UL << 31) | (2UL << 24) | (BOARD_UART_OVS - 1U);
+ uart_ready = 1;
+}
+
+static void uart_putc(char c)
+{
+ uint32_t timeout = 1000000;
+
+ if (!uart_ready)
+ return;
+ while (((UART_TX_FIFO_STAT(SCB2_BASE) & 0x1FFU) >= 8U) && (timeout > 0))
+ timeout--;
+ UART_TX_FIFO_WR(SCB2_BASE) = (uint32_t)(uint8_t)c;
+}
+
+void board_init(void)
+{
+ uart_init();
+ DEMCR |= (1UL << 24); /* TRCENA */
+ DWT_CYCCNT = 0;
+ DWT_CTRL |= 1UL; /* CYCCNTENA */
+ (void)Cy_Crypto_Core_Enable(CRYPTO);
+}
+
+/* DWT cycle counter extended to 64 bits. It wraps every ~21 s, and each read
+ * recovers one wrap, which the benchmark's timing windows stay well inside. */
+static uint64_t cycles(void)
+{
+ static uint64_t hi;
+ static uint32_t last;
+ uint32_t now = DWT_CYCCNT;
+
+ if (now < last)
+ hi += 0x100000000ULL;
+ last = now;
+ return hi + now;
+}
+
+double current_time(int reset)
+{
+ (void)reset;
+ return (double)cycles() / (double)BOARD_CPU_HZ;
+}
+
+unsigned long board_time(unsigned long *t)
+{
+ unsigned long s = (unsigned long)(cycles() / BOARD_CPU_HZ);
+
+ if (t != NULL)
+ *t = s;
+ return s;
+}
+
+/* Seed the Hash-DRBG from the crypto engine's TRNG, one 32-bit word at a
+ * time. */
+int board_rng_seed(unsigned char *out, unsigned int sz)
+{
+ uint32_t rnd;
+ unsigned int i;
+
+ if (!Cy_Crypto_Core_IsEnabled(CRYPTO) &&
+ (Cy_Crypto_Core_Enable(CRYPTO) != CY_CRYPTO_SUCCESS))
+ return -1;
+ for (i = 0; i < sz; i++) {
+ if ((i & 3U) == 0U) {
+ if (Cy_Crypto_Core_Trng_Ext(CRYPTO, 32U, &rnd) !=
+ CY_CRYPTO_SUCCESS)
+ return -1;
+ }
+ out[i] = (unsigned char)(rnd >> ((i & 3U) * 8U));
+ }
+ return 0;
+}
+
+/* newlib hooks: console output, and a heap bounded below the stack. */
+int _write(int fd, const char *buf, int len)
+{
+ int i;
+
+ (void)fd;
+ for (i = 0; i < len; i++) {
+ if (buf[i] == '\n')
+ uart_putc('\r');
+ uart_putc(buf[i]);
+ }
+ return len;
+}
+
+void *_sbrk(ptrdiff_t incr)
+{
+ extern char end;
+ extern char _heap_limit;
+ static char *brk = &end;
+ char *prev = brk;
+
+ if ((brk + incr) > &_heap_limit) {
+ errno = ENOMEM;
+ return (void *)-1;
+ }
+ brk += incr;
+ return prev;
+}
+
+int _close(int fd) { (void)fd; return -1; }
+int _fstat(int fd, struct stat *st) { (void)fd; st->st_mode = S_IFCHR; return 0; }
+int _isatty(int fd) { (void)fd; return 1; }
+int _lseek(int fd, int off, int dir) { (void)fd; (void)off; (void)dir; return 0; }
+int _read(int fd, char *buf, int len) { (void)fd; (void)buf; (void)len; return 0; }
diff --git a/embedded/infineon_psoc_e8/board.h b/embedded/infineon_psoc_e8/board.h
new file mode 100644
index 000000000..0dcaf0b4f
--- /dev/null
+++ b/embedded/infineon_psoc_e8/board.h
@@ -0,0 +1,32 @@
+/* board.h
+ *
+ * KIT_PSE84_AI board support for the wolfCrypt test and benchmark.
+ *
+ * Copyright (C) 2006-2026 wolfSSL Inc.
+ *
+ * This file is part of wolfSSL.
+ *
+ * wolfSSL 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.
+ *
+ * wolfSSL 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 BOARD_H
+#define BOARD_H
+
+void board_init(void);
+double current_time(int reset);
+unsigned long board_time(unsigned long *t);
+int board_rng_seed(unsigned char *out, unsigned int sz);
+
+#endif
diff --git a/embedded/infineon_psoc_e8/cy_device_headers_s.h b/embedded/infineon_psoc_e8/cy_device_headers_s.h
new file mode 100644
index 000000000..19afb3f06
--- /dev/null
+++ b/embedded/infineon_psoc_e8/cy_device_headers_s.h
@@ -0,0 +1,15 @@
+/* cy_device_headers_s.h
+ *
+ * The PSE84 template's cy_device_headers.h includes this file for a Secure
+ * build; it selects the part header. PSE84_PART_HEADER is set by the
+ * Makefile.
+ *
+ * Copyright (C) 2006-2026 wolfSSL Inc.
+ */
+
+#ifndef CY_DEVICE_HEADERS_S_H
+#define CY_DEVICE_HEADERS_S_H
+
+#include PSE84_PART_HEADER
+
+#endif
diff --git a/embedded/infineon_psoc_e8/linker.ld b/embedded/infineon_psoc_e8/linker.ld
new file mode 100644
index 000000000..be9ff0cf6
--- /dev/null
+++ b/embedded/infineon_psoc_e8/linker.ld
@@ -0,0 +1,94 @@
+/* linker.ld
+ *
+ * PSOC Edge E8 CM33 Secure image, run in place from QSPI.
+ *
+ * Extended boot launches the image at QSPI 0x60100000 after its 0x400-byte
+ * MCUboot header, through the Secure code-bus alias 0x18100400. SRAM below
+ * 0x34002000 is reserved for extended boot and the Secure Enclave.
+ *
+ * Copyright (C) 2006-2026 wolfSSL Inc.
+ */
+
+MEMORY
+{
+ FLASH (rx) : ORIGIN = 0x18100400, LENGTH = 0x001FFC00
+ RAM (rwx) : ORIGIN = 0x34002000, LENGTH = 0x00056000
+}
+
+_Min_Stack_Size = 0x8000;
+
+SECTIONS
+{
+ .isr_vector :
+ {
+ . = ALIGN(4);
+ KEEP(*(.isr_vector))
+ . = ALIGN(4);
+ } > FLASH
+
+ .text :
+ {
+ . = ALIGN(4);
+ *(.text*)
+ *(.rodata*)
+ KEEP(*(.init))
+ KEEP(*(.fini))
+ . = ALIGN(4);
+ } > FLASH
+
+ .ARM.exidx :
+ {
+ *(.ARM.exidx*)
+ } > FLASH
+
+ .preinit_array :
+ {
+ PROVIDE_HIDDEN(__preinit_array_start = .);
+ KEEP(*(.preinit_array*))
+ PROVIDE_HIDDEN(__preinit_array_end = .);
+ } > FLASH
+ .init_array :
+ {
+ PROVIDE_HIDDEN(__init_array_start = .);
+ KEEP(*(SORT(.init_array.*)))
+ KEEP(*(.init_array*))
+ PROVIDE_HIDDEN(__init_array_end = .);
+ } > FLASH
+ .fini_array :
+ {
+ PROVIDE_HIDDEN(__fini_array_start = .);
+ KEEP(*(SORT(.fini_array.*)))
+ KEEP(*(.fini_array*))
+ PROVIDE_HIDDEN(__fini_array_end = .);
+ } > FLASH
+
+ _sidata = LOADADDR(.data);
+
+ .data :
+ {
+ . = ALIGN(4);
+ _sdata = .;
+ *(.data*)
+ . = ALIGN(4);
+ _edata = .;
+ } > RAM AT > FLASH
+
+ .bss (NOLOAD) :
+ {
+ . = ALIGN(4);
+ _sbss = .;
+ *(.bss*)
+ *(COMMON)
+ . = ALIGN(4);
+ _ebss = .;
+ } > RAM
+
+ /* Heap from here up to the stack. */
+ . = ALIGN(8);
+ PROVIDE(end = .);
+ PROVIDE(_end = .);
+
+ _estack = ORIGIN(RAM) + LENGTH(RAM);
+ _heap_limit = _estack - _Min_Stack_Size;
+ ASSERT(end < _heap_limit, "no room left for the heap")
+}
diff --git a/embedded/infineon_psoc_e8/main.c b/embedded/infineon_psoc_e8/main.c
new file mode 100644
index 000000000..ec908c929
--- /dev/null
+++ b/embedded/infineon_psoc_e8/main.c
@@ -0,0 +1,57 @@
+/* main.c
+ *
+ * wolfCrypt test or benchmark on the PSOC Edge E8 CM33.
+ *
+ * Copyright (C) 2006-2026 wolfSSL Inc.
+ *
+ * This file is part of wolfSSL.
+ *
+ * wolfSSL 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.
+ *
+ * wolfSSL 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
+
+#include
+#include
+#include
+#include
+
+#include "board.h"
+
+int main(void)
+{
+ int ret;
+
+ board_init();
+ printf("\nwolfCrypt on PSOC Edge E8 (CM33), crypto engine %s\n",
+#ifdef WOLFSSL_PSOC6_CRYPTO
+ "enabled"
+#else
+ "disabled"
+#endif
+ );
+
+ ret = wolfCrypt_Init();
+ if (ret == 0) {
+#ifdef BENCH_APP
+ ret = benchmark_test(NULL);
+#else
+ ret = wolfcrypt_test(NULL);
+#endif
+ wolfCrypt_Cleanup();
+ }
+ printf("%s: %d\n", (ret == 0) ? "Done" : "Failed", ret);
+ return ret;
+}
diff --git a/embedded/infineon_psoc_e8/startup.c b/embedded/infineon_psoc_e8/startup.c
new file mode 100644
index 000000000..764ecb0a9
--- /dev/null
+++ b/embedded/infineon_psoc_e8/startup.c
@@ -0,0 +1,87 @@
+/* startup.c
+ *
+ * Vector table and reset handler for the PSOC Edge E8 CM33 (Secure).
+ *
+ * Copyright (C) 2006-2026 wolfSSL Inc.
+ *
+ * This file is part of wolfSSL.
+ *
+ * wolfSSL 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.
+ *
+ * wolfSSL 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
+
+extern uint32_t _estack;
+extern uint32_t _sidata, _sdata, _edata;
+extern uint32_t _sbss, _ebss;
+extern void __libc_init_array(void);
+extern int main(void);
+
+void Reset_Handler(void);
+void Default_Handler(void);
+void HardFault_Handler(void);
+
+/* Extended boot has already set VTOR to this table and left the clocks
+ * running, so the reset handler only has to set up the C runtime. */
+void Reset_Handler(void)
+{
+ uint32_t *src = &_sidata;
+ uint32_t *dst;
+
+ for (dst = &_sdata; dst < &_edata; dst++)
+ *dst = *src++;
+ for (dst = &_sbss; dst < &_ebss; dst++)
+ *dst = 0;
+
+ __libc_init_array();
+ (void)main();
+ while (1)
+ ;
+}
+
+/* Called by __libc_init_array; nothing to do without crt0. */
+void _init(void) {}
+void _fini(void) {}
+
+void Default_Handler(void)
+{
+ while (1)
+ ;
+}
+
+void HardFault_Handler(void)
+{
+ while (1)
+ ;
+}
+
+/* Exceptions only; the example uses no interrupts. */
+__attribute__((section(".isr_vector"), used))
+void (* const g_pfnVectors[16])(void) = {
+ (void (*)(void))&_estack,
+ Reset_Handler,
+ Default_Handler, /* NMI */
+ HardFault_Handler,
+ Default_Handler, /* MemManage */
+ Default_Handler, /* BusFault */
+ Default_Handler, /* UsageFault */
+ Default_Handler, /* SecureFault */
+ 0, 0, 0,
+ Default_Handler, /* SVCall */
+ Default_Handler, /* DebugMonitor */
+ 0,
+ Default_Handler, /* PendSV */
+ Default_Handler, /* SysTick */
+};
diff --git a/embedded/infineon_psoc_e8/tools/flash.sh b/embedded/infineon_psoc_e8/tools/flash.sh
new file mode 100755
index 000000000..8dcfb71c3
--- /dev/null
+++ b/embedded/infineon_psoc_e8/tools/flash.sh
@@ -0,0 +1,35 @@
+#!/bin/bash
+# Wrap an image with the extended-boot header and program it to QSPI
+# 0x60100000 on KIT_PSE84_AI through the on-board KitProg3.
+#
+# Usage: tools/flash.sh Build/wolfcrypt_test.bin
+#
+# Environment: MTB_PROGTOOLS (default /opt/Tools/ModusToolboxProgtools-1.6),
+# KITPROG_SERIAL to pick the probe when several are attached.
+
+set -e
+
+IMG=${1:?usage: $0 image.bin}
+MTB_PROGTOOLS=${MTB_PROGTOOLS:-/opt/Tools/ModusToolboxProgtools-1.6}
+OCD=$MTB_PROGTOOLS/openocd
+SCRIPTS=$MTB_PROGTOOLS/mtb-programmer/scripts
+HERE=$(cd "$(dirname "$0")" && pwd)
+
+WRAPPED=$(mktemp --suffix=.bin)
+trap 'rm -f "$WRAPPED"' EXIT
+python3 "$HERE/mcuboot_wrap.py" "$IMG" "$WRAPPED"
+
+SERIAL_ARGS=()
+if [ -n "$KITPROG_SERIAL" ]; then
+ SERIAL_ARGS=(-c "adapter serial $KITPROG_SERIAL")
+fi
+
+# "reset run" would leave the part in KitProg3 acquire mode.
+"$OCD/bin/openocd" -s "$OCD/scripts" -s "$SCRIPTS" \
+ -c "set SCRIPTS_DIR $SCRIPTS" \
+ -f interface/kitprog3.cfg "${SERIAL_ARGS[@]}" -c "transport select swd" \
+ -f CAT1D/kit_PSE84_AI_external.cfg \
+ -c "init; reset init" \
+ -c "flash write_image erase $WRAPPED 0x60100000 bin" \
+ -c "verify_image $WRAPPED 0x60100000 bin" \
+ -c "reset halt; resume; shutdown"
diff --git a/embedded/infineon_psoc_e8/tools/mcuboot_wrap.py b/embedded/infineon_psoc_e8/tools/mcuboot_wrap.py
new file mode 100755
index 000000000..2ad772752
--- /dev/null
+++ b/embedded/infineon_psoc_e8/tools/mcuboot_wrap.py
@@ -0,0 +1,45 @@
+#!/usr/bin/env python3
+"""Wrap an image for the PSOC Edge E8 extended boot.
+
+Extended boot expects the first CM33 image in MCUboot format: a 0x400-byte
+header, the image, and a TLV area with the SHA-256 of both. No key is used.
+The output matches the factory image byte for byte.
+
+Usage: mcuboot_wrap.py image.bin image_mcuboot.bin
+"""
+
+import hashlib
+import struct
+import sys
+
+IMAGE_MAGIC = 0x96F3B83D
+TLV_INFO_MAGIC = 0x6907
+TLV_SHA256 = 0x10
+HDR_SIZE = 0x400
+
+
+def wrap(img):
+ # magic, load_addr, hdr_size, protect_tlv_size, img_size, flags,
+ # version (major, minor, revision, build), pad
+ hdr = struct.pack('