diff --git a/.gitignore b/.gitignore
index d558a505..9dc1eda3 100644
--- a/.gitignore
+++ b/.gitignore
@@ -6,6 +6,7 @@
*.ko
*.obj
*.elf
+*.efi
# Libraries
*.lib
@@ -407,3 +408,6 @@ kernel/bsdkm/x86
stsafe/stsafe_test
stsafe/wolfssl_stsafe_test
stsafe/wolfssl_stsafe_full_test
+
+# uefi-library generated filesystem content
+uefi-library/efifs
diff --git a/README.md b/README.md
index 09ecc3fa..acbde482 100644
--- a/README.md
+++ b/README.md
@@ -381,11 +381,22 @@ details.
-#### UEFI (wolfCrypt UEFI application Example)
+#### uefi-static (wolfCrypt UEFI application Example)
This directory contains an example UEFI application that runs wolfcrypt test.
-Please see the [uefi/README.md](uefi/README.md) for further usage and
+Please see the [uefi-static/README.md](uefi-static/README.md) for further usage and
+details.
+
+
+
+
+#### uefi-library (wolfCrypt UEFI boot module and test app)
+
+This directory contains a UEFI wolfCrypt protocol driver (`libwolfcrypt.efi`)
+and a companion test application (`test.efi`). Examples run on qemu.
+
+Please see the [uefi-library/README.md](uefi-library/README.md) for further usage and
details.
@@ -406,4 +417,3 @@ To generate your own cert text, see the [DER to C script](https://github.com/wol
Please contact wolfSSL at support@wolfssl.com with any questions, bug fixes,
or suggested feature additions.
-
diff --git a/uefi-library/Makefile b/uefi-library/Makefile
new file mode 100644
index 00000000..3aa672b0
--- /dev/null
+++ b/uefi-library/Makefile
@@ -0,0 +1,348 @@
+uC = gcc
+LD = ld
+OBJCOPY = objcopy
+SIZE = size
+
+# Path to the wolfssl source tree (sibling of wolfssl-examples by default)
+WOLFSSL_PATH ?= $(abspath $(CURDIR)/../../wolfssl)
+
+# QEMU configuration
+QEMU_CPU ?= qemu64
+# Use a named Intel CPU model so CPUID leaf 0 reports "GenuineIntel".
+# wolfSSL's cpuid_flag() only sets AES-NI when the vendor is Intel or AMD;
+# the generic "qemu64" model reports "TCGTCGTCGTCG" and fails that check
+# even when +aes is passed. "Broadwell" includes AES-NI and PCLMULQDQ by
+# default and works with both KVM and TCG (accel=kvm:tcg falls back cleanly).
+QEMU_CPU_HW ?= host,migratable=off
+QEMU_ACCEL ?=
+
+# -----------------------------------------------------------------------
+# x86_64 paths / flags common to all 64-bit variants
+# -----------------------------------------------------------------------
+GNU_EFI_LIB_PATH ?= /usr/lib
+GNU_EFI_CRT0_X64 := $(GNU_EFI_LIB_PATH)/crt0-efi-x86_64.o
+GNU_EFI_LSCRIPT_X64 := $(GNU_EFI_LIB_PATH)/elf_x86_64_efi.lds
+EFI_DRIVER_TARGET_X64 := efi-bsdrv-x86_64
+EFI_APP_TARGET_X64 := efi-app-x86_64
+
+LIBGCC_X64 := $(shell $(CC) -print-libgcc-file-name)
+
+# -----------------------------------------------------------------------
+# i386 paths / flags
+# -----------------------------------------------------------------------
+GNU_EFI_LIB_PATH32 ?= /usr/lib32
+GNU_EFI_CRT0_I32 := $(GNU_EFI_LIB_PATH32)/crt0-efi-ia32.o
+GNU_EFI_LSCRIPT_I32 := $(GNU_EFI_LIB_PATH32)/elf_ia32_efi.lds
+EFI_DRIVER_TARGET_I32 := efi-bsdrv-ia32
+EFI_APP_TARGET_I32 := efi-app-ia32
+LIBGCC_I32 := /usr/lib/gcc-cross/i686-linux-gnu/14/libgcc.a
+
+# -----------------------------------------------------------------------
+# Common CFLAGS (base)
+# -----------------------------------------------------------------------
+CFLAGS_COMMON := \
+ -fpic -ffreestanding -fno-stack-protector -fno-stack-check \
+ -fshort-wchar -mno-red-zone -maccumulate-outgoing-args \
+ -DUEFI -DGNUEFI -DWOLFSSL_USER_SETTINGS -DNEED_DYNAMIC_TYPE_FIX_UEFI \
+ -I. -I/usr/include/efi -I/usr/include/efi/x86_64 \
+ -I$(WOLFSSL_PATH) \
+ -DTARGET_X86_64_EFI
+
+CFLAGS_HW := $(CFLAGS_COMMON) -maes -mpclmul -DUEFI_HW_ACCEL
+
+CFLAGS_NOHW := $(CFLAGS_COMMON)
+
+CFLAGS_I32 := \
+ -m32 -fpic -ffreestanding -fno-stack-protector -fno-stack-check \
+ -fshort-wchar -mno-red-zone -maccumulate-outgoing-args \
+ -fno-asynchronous-unwind-tables -fno-unwind-tables \
+ -DUEFI -DGNUEFI -DWOLFSSL_USER_SETTINGS -DNEED_DYNAMIC_TYPE_FIX_UEFI \
+ -I. -I/usr/include/efi -I/usr/include/efi/ia32 \
+ -I$(WOLFSSL_PATH) \
+ -DTARGET_IA32_EFI -DEFI_FUNCTION_WRAPPER -DTARGET_IA32_EFI
+
+# -----------------------------------------------------------------------
+# wolfcrypt object list
+# -----------------------------------------------------------------------
+OBJS_WOLFCRYPT := \
+ $(WOLFSSL_PATH)/wolfcrypt/src/aes.o \
+ $(WOLFSSL_PATH)/wolfcrypt/src/asn.o \
+ $(WOLFSSL_PATH)/wolfcrypt/src/coding.o \
+ $(WOLFSSL_PATH)/wolfcrypt/src/logging.o \
+ $(WOLFSSL_PATH)/wolfcrypt/src/cpuid.o \
+ $(WOLFSSL_PATH)/wolfcrypt/src/memory.o \
+ $(WOLFSSL_PATH)/wolfcrypt/src/rsa.o \
+ $(WOLFSSL_PATH)/wolfcrypt/src/dilithium.o \
+ $(WOLFSSL_PATH)/wolfcrypt/src/falcon.o \
+ $(WOLFSSL_PATH)/wolfcrypt/src/dh.o \
+ $(WOLFSSL_PATH)/wolfcrypt/src/kdf.o \
+ $(WOLFSSL_PATH)/wolfcrypt/src/ecc.o \
+ $(WOLFSSL_PATH)/wolfcrypt/src/misc.o \
+ $(WOLFSSL_PATH)/wolfcrypt/src/sha.o \
+ $(WOLFSSL_PATH)/wolfcrypt/src/sha256.o \
+ $(WOLFSSL_PATH)/wolfcrypt/src/sha512.o \
+ $(WOLFSSL_PATH)/wolfcrypt/src/sha3.o \
+ $(WOLFSSL_PATH)/wolfcrypt/src/hash.o \
+ $(WOLFSSL_PATH)/wolfcrypt/src/hmac.o \
+ $(WOLFSSL_PATH)/wolfcrypt/src/cmac.o \
+ $(WOLFSSL_PATH)/wolfcrypt/src/pwdbased.o \
+ $(WOLFSSL_PATH)/wolfcrypt/src/pkcs7.o \
+ $(WOLFSSL_PATH)/wolfcrypt/src/pkcs12.o \
+ $(WOLFSSL_PATH)/wolfcrypt/src/wolfmath.o \
+ $(WOLFSSL_PATH)/wolfcrypt/src/tfm.o \
+ $(WOLFSSL_PATH)/wolfcrypt/src/wc_encrypt.o \
+ $(WOLFSSL_PATH)/wolfcrypt/src/error.o \
+ $(WOLFSSL_PATH)/wolfcrypt/src/random.o \
+ $(WOLFSSL_PATH)/wolfcrypt/src/wc_port.o \
+ $(WOLFSSL_PATH)/wolfcrypt/src/wc_mlkem.o \
+ $(WOLFSSL_PATH)/wolfcrypt/src/wc_mlkem_poly.o \
+ $(WOLFSSL_PATH)/wolfcrypt/src/chacha.o \
+ $(WOLFSSL_PATH)/wolfcrypt/src/chacha20_poly1305.o \
+ $(WOLFSSL_PATH)/wolfcrypt/src/poly1305.o \
+ $(WOLFSSL_PATH)/wolfcrypt/src/curve25519.o \
+ $(WOLFSSL_PATH)/wolfcrypt/src/ed25519.o \
+ $(WOLFSSL_PATH)/wolfcrypt/src/fe_operations.o \
+ $(WOLFSSL_PATH)/wolfcrypt/src/ge_operations.o \
+ src/driver.o \
+ src/utility_wolf.o
+
+# AES-NI assembly objects (hw variant only)
+OBJS_HW := \
+ $(WOLFSSL_PATH)/wolfcrypt/src/aes_asm.o \
+ $(WOLFSSL_PATH)/wolfcrypt/src/aes_gcm_asm.o
+
+# Test app objects
+OBJS_TEST := \
+ src/test_app.o
+
+# -----------------------------------------------------------------------
+# LDFLAGS helpers
+# -----------------------------------------------------------------------
+LDFLAGS_X64 = -shared -Bsymbolic -L$(GNU_EFI_LIB_PATH) -T$(GNU_EFI_LSCRIPT_X64)
+LD_GROUP_X64 = --start-group $(GNU_EFI_CRT0_X64) $(OBJS_WOLFCRYPT) --end-group -lgnuefi -lefi $(LIBGCC_X64)
+LD_GROUP_X64_HW = --start-group $(GNU_EFI_CRT0_X64) $(OBJS_WOLFCRYPT) $(OBJS_HW) --end-group -lgnuefi -lefi $(LIBGCC_X64)
+LD_GROUP_X64_TEST = --start-group $(GNU_EFI_CRT0_X64) $(OBJS_TEST) --end-group -lgnuefi -lefi $(LIBGCC_X64)
+
+LDFLAGS_I32 = -shared -Bsymbolic -L$(GNU_EFI_LIB_PATH32) -m elf_i386 -T$(GNU_EFI_LSCRIPT_I32)
+LD_GROUP_I32 = --start-group $(GNU_EFI_CRT0_I32) $(OBJS_WOLFCRYPT) --end-group \
+ $(GNU_EFI_LIB_PATH32)/libgnuefi.a $(GNU_EFI_LIB_PATH32)/libefi.a $(LIBGCC_I32)
+LD_GROUP_I32_TEST = --start-group $(GNU_EFI_CRT0_I32) $(OBJS_TEST) --end-group \
+ $(GNU_EFI_LIB_PATH32)/libgnuefi.a $(GNU_EFI_LIB_PATH32)/libefi.a $(LIBGCC_I32)
+
+EFI_EH_FRAME ?= -j .eh_frame
+EFI_REMOVE_EH ?=
+
+# -----------------------------------------------------------------------
+# Main targets
+# -----------------------------------------------------------------------
+.PHONY: all clean
+
+all: run-fallback-nohw
+
+
+
+# -----------------------------------------------------------------------
+# Pattern rules
+# -----------------------------------------------------------------------
+%.o: %.c
+ $(CC) $(CFLAGS) -c -o $@ $<
+
+%.o: %.S
+ $(CC) $(CFLAGS) -c -o $@ $<
+
+# sha3.o must always have SHAKE128/256 enabled
+$(WOLFSSL_PATH)/wolfcrypt/src/sha3.o: $(WOLFSSL_PATH)/wolfcrypt/src/sha3.c
+ $(CC) $(CFLAGS) -DWOLFSSL_SHAKE128 -DWOLFSSL_SHAKE256 \
+ -UWOLFSSL_NO_SHAKE128 -UWOLFSSL_NO_SHAKE256 -c -o $@ $<
+
+# AES-NI assembly: compile without -DWOLFSSL_USER_SETTINGS to prevent user_settings.h
+# from pulling in EFI C headers that the assembler cannot parse. Only define the
+# macros the .S file actually needs: WOLFSSL_X86_64_BUILD triggers the x86_64 path.
+CFLAGS_ASM := -ffreestanding -fno-stack-protector -fpic -mno-red-zone \
+ -DWOLFSSL_X86_64_BUILD -maes -mpclmul
+
+$(WOLFSSL_PATH)/wolfcrypt/src/aes_asm.o: $(WOLFSSL_PATH)/wolfcrypt/src/aes_asm.S
+ $(CC) $(CFLAGS_ASM) -c -o $@ $<
+
+$(WOLFSSL_PATH)/wolfcrypt/src/aes_gcm_asm.o: $(WOLFSSL_PATH)/wolfcrypt/src/aes_gcm_asm.S
+ $(CC) $(CFLAGS_ASM) -c -o $@ $<
+
+# -----------------------------------------------------------------------
+# EFI image rules
+# -----------------------------------------------------------------------
+libwolfcrypt.elf: $(OBJS_WOLFCRYPT) $(EXTRA_OBJS)
+ $(LD) $(LDFLAGS) --defsym=EFI_SUBSYSTEM=11 -o $@ $(LD_GROUPS)
+
+libwolfcrypt.efi: libwolfcrypt.elf
+ @echo Creating $@
+ $(OBJCOPY) -j .rodata -j .text -j .sdata -j .data \
+ -j .dynamic -j .dynsym -j .rel \
+ -j .rela -j .reloc $(EFI_EH_FRAME) \
+ --target=$(EFI_DRV_TGT) --subsystem=11 $(EFI_REMOVE_EH) $^ $@
+ @echo Size:
+ $(SIZE) $@
+
+test.elf: $(OBJS_TEST) $(EXTRA_TEST_OBJS)
+ $(LD) $(LDFLAGS) --defsym=EFI_SUBSYSTEM=10 -o $@ $(LD_GROUPS_TEST)
+
+test.efi: test.elf
+ @echo Creating $@
+ $(OBJCOPY) -j .rodata -j .text -j .sdata -j .data \
+ -j .dynamic -j .dynsym -j .rel \
+ -j .rela -j .reloc $(EFI_EH_FRAME) \
+ --target=$(EFI_APP_TGT) --subsystem=10 $(EFI_REMOVE_EH) $^ $@
+ @echo Size:
+ $(SIZE) $@
+
+# -----------------------------------------------------------------------
+# install
+# -----------------------------------------------------------------------
+install: libwolfcrypt.efi test.efi
+ mkdir -p efifs
+ cp libwolfcrypt.efi efifs/
+ cp test.efi efifs/
+ cp startup-single.nsh efifs/startup.nsh
+ cp NvVars efifs/ 2>/dev/null || true
+
+install-dual: libwolfcrypt.efi libwolfcrypt-nohw.efi test.efi
+ mkdir -p efifs
+ cp libwolfcrypt.efi efifs/
+ cp libwolfcrypt-nohw.efi efifs/
+ cp test.efi efifs/
+ cp startup.nsh efifs/
+ cp NvVars efifs/ 2>/dev/null || true
+
+# -----------------------------------------------------------------------
+# lib — x86_64 with AES-NI (hw)
+# -----------------------------------------------------------------------
+.PHONY: lib
+lib:
+ @$(MAKE) CFLAGS="$(CFLAGS_HW)" LDFLAGS="$(LDFLAGS_X64)" \
+ LD_GROUPS="$(LD_GROUP_X64_HW)" LD_GROUPS_TEST="$(LD_GROUP_X64_TEST)" \
+ EXTRA_OBJS="$(OBJS_HW)" EXTRA_TEST_OBJS="$(GNU_EFI_CRT0_X64)" \
+ EFI_DRV_TGT="$(EFI_DRIVER_TARGET_X64)" EFI_APP_TGT="$(EFI_APP_TARGET_X64)" \
+ libwolfcrypt.efi test.efi install
+
+# -----------------------------------------------------------------------
+# lib-nohw — x86_64 software-only
+# -----------------------------------------------------------------------
+.PHONY: lib-nohw
+lib-nohw: CFLAGS = $(CFLAGS_NOHW)
+lib-nohw: LDFLAGS = $(LDFLAGS_X64)
+lib-nohw: LD_GROUPS = $(LD_GROUP_X64)
+lib-nohw: LD_GROUPS_TEST = $(LD_GROUP_X64_TEST)
+lib-nohw: EXTRA_TEST_OBJS = $(GNU_EFI_CRT0_X64)
+lib-nohw: EFI_DRV_TGT = $(EFI_DRIVER_TARGET_X64)
+lib-nohw: EFI_APP_TGT = $(EFI_APP_TARGET_X64)
+lib-nohw: libwolfcrypt.efi test.efi install
+
+# -----------------------------------------------------------------------
+# lib32 — i386, software-only
+# -----------------------------------------------------------------------
+.PHONY: lib32
+lib32: CFLAGS = $(CFLAGS_I32)
+lib32: LDFLAGS = $(LDFLAGS_I32)
+lib32: LD_GROUPS = $(LD_GROUP_I32)
+lib32: LD_GROUPS_TEST = $(LD_GROUP_I32_TEST)
+lib32: EXTRA_TEST_OBJS =
+lib32: EFI_DRV_TGT = $(EFI_DRIVER_TARGET_I32)
+lib32: EFI_APP_TGT = $(EFI_APP_TARGET_I32)
+lib32: EFI_EH_FRAME =
+lib32: EFI_REMOVE_EH = --remove-section .eh_frame
+lib32: libwolfcrypt.efi test.efi install
+
+# -----------------------------------------------------------------------
+# lib32-nohw — alias for lib32 (i386 has no hw accel)
+# -----------------------------------------------------------------------
+.PHONY: lib32-nohw
+lib32-nohw: lib32
+
+# -----------------------------------------------------------------------
+# run targets
+# -----------------------------------------------------------------------
+.PHONY: run
+run: lib
+ qemu-system-x86_64 -machine q35,accel=kvm -m 512 -net none -serial stdio \
+ -display none -cpu $(QEMU_CPU_HW) \
+ -bios /usr/share/ovmf/OVMF.fd \
+ -drive format=raw,file=fat:rw:./efifs \
+ -object rng-random,id=rng0,filename=/dev/urandom \
+ -device virtio-rng-pci,rng=rng0
+
+.PHONY: run-nohw
+run-nohw: lib-nohw
+ qemu-system-x86_64 -machine q35,accel=kvm -m 512 -net none -serial stdio \
+ -display none -cpu $(QEMU_CPU) \
+ -bios /usr/share/ovmf/OVMF.fd \
+ -drive format=raw,file=fat:rw:./efifs \
+ -object rng-random,id=rng0,filename=/dev/urandom \
+ -device virtio-rng-pci,rng=rng0
+
+.PHONY: run32
+run32: lib32
+ qemu-system-i386 -m 512 -machine q35,accel=kvm -net none -serial stdio \
+ -display none -cpu $(QEMU_CPU_HW) \
+ -drive if=pflash,format=raw,readonly=on,file=/usr/share/OVMF/OVMF32_CODE_4M.fd \
+ -drive format=raw,file=fat:rw:./efifs
+
+.PHONY: run32-nohw
+run32-nohw: lib32-nohw
+ qemu-system-i386 -m 512 -machine q35,accel=kvm -net none -serial stdio \
+ -display none -cpu qemu32 \
+ -drive if=pflash,format=raw,readonly=on,file=/usr/share/OVMF/OVMF32_CODE_4M.fd \
+ -drive format=raw,file=fat:rw:./efifs
+
+# -----------------------------------------------------------------------
+# run-fallback-nohw
+# Build hw + nohw drivers, install both; run QEMU without AES-NI so the
+# hw driver exits EFI_UNSUPPORTED and startup.nsh loads the nohw driver.
+# -----------------------------------------------------------------------
+.PHONY: run-fallback-nohw
+run-fallback-nohw:
+ @echo "=== Building hw driver (with AES-NI) ==="
+ @$(MAKE) CFLAGS="$(CFLAGS_HW)" LDFLAGS="$(LDFLAGS_X64)" \
+ LD_GROUPS="$(LD_GROUP_X64_HW)" LD_GROUPS_TEST="$(LD_GROUP_X64_TEST)" \
+ EXTRA_OBJS="$(OBJS_HW)" EXTRA_TEST_OBJS="$(GNU_EFI_CRT0_X64)" \
+ EFI_DRV_TGT="$(EFI_DRIVER_TARGET_X64)" EFI_APP_TGT="$(EFI_APP_TARGET_X64)" \
+ libwolfcrypt.efi test.efi
+ @echo "=== Saving hw driver ==="
+ @cp libwolfcrypt.efi libwolfcrypt-hw-tmp.efi
+ @echo "=== Cleaning objects ==="
+ @$(MAKE) clean-objs
+ @echo "=== Building nohw driver ==="
+ @$(MAKE) CFLAGS="$(CFLAGS_NOHW)" LDFLAGS="$(LDFLAGS_X64)" \
+ LD_GROUPS="$(LD_GROUP_X64)" LD_GROUPS_TEST="$(LD_GROUP_X64_TEST)" \
+ EXTRA_TEST_OBJS="$(GNU_EFI_CRT0_X64)" \
+ EFI_DRV_TGT="$(EFI_DRIVER_TARGET_X64)" EFI_APP_TGT="$(EFI_APP_TARGET_X64)" \
+ libwolfcrypt.efi
+ @mv libwolfcrypt.efi libwolfcrypt-nohw.efi
+ @mv libwolfcrypt-hw-tmp.efi libwolfcrypt.efi
+ @echo "=== Installing dual build to efifs ==="
+ @mkdir -p efifs
+ @cp libwolfcrypt.efi efifs/
+ @cp libwolfcrypt-nohw.efi efifs/
+ @cp test.efi efifs/
+ @cp startup.nsh efifs/
+ @cp NvVars efifs/ 2>/dev/null || true
+ @echo "=== Running QEMU without AES-NI (fallback test) ==="
+ qemu-system-x86_64 -m 512 -net none -serial stdio -display none \
+ -cpu $(QEMU_CPU) \
+ -bios /usr/share/ovmf/OVMF.fd \
+ -drive format=raw,file=fat:rw:./efifs \
+ -object rng-random,id=rng0,filename=/dev/urandom \
+ -device virtio-rng-pci,rng=rng0
+
+# -----------------------------------------------------------------------
+# clean
+# -----------------------------------------------------------------------
+.PHONY: clean
+clean:
+ rm -f *.elf *.efi *.o libwolfcrypt-hw-tmp.efi libwolfcrypt-nohw.efi
+ rm -f $(WOLFSSL_PATH)/wolfcrypt/src/*.o src/*.o
+
+.PHONY: clean-objs
+clean-objs:
+ rm -f $(WOLFSSL_PATH)/wolfcrypt/src/*.o src/*.o
+
+.PHONY: all
+all: lib-nohw
diff --git a/uefi-library/NvVars b/uefi-library/NvVars
new file mode 100644
index 00000000..46f4962b
Binary files /dev/null and b/uefi-library/NvVars differ
diff --git a/uefi-library/README.md b/uefi-library/README.md
new file mode 100644
index 00000000..c9b59d07
--- /dev/null
+++ b/uefi-library/README.md
@@ -0,0 +1,175 @@
+# wolfCrypt UEFI Library
+
+## wolfCrypt as a UEFI Boot-Service Driver
+
+A UEFI boot-services driver that exposes wolfCrypt cryptographic operations to
+other UEFI applications and drivers via an EFI protocol interface.
+
+Applications running in efi after loading the wolfcrypt driver can use the
+`wolfcrypt_protocol` to call wolfCrypt functions directly from UEFI.
+
+See `test_app.c` for example usage.
+
+
+
+### Directory Structure
+
+```
+uefi-library/
+├── Makefile
+├── user_settings.h wolfSSL platform/feature configuration
+├── wolfcrypt_api.h EFI protocol GUID + WOLFCRYPT_PROTOCOL struct
+├── utility_wolf.h UEFI utility function declarations
+├── NvVars OVMF NVRAM state file (boot order, etc.)
+├── startup.nsh Dual-build fallback NSH script
+├── startup-single.nsh Single-build NSH script
+├── src/
+│ ├── driver.c EFI driver entry point + EFIAPI wrappers
+│ ├── test_app.c Smoke-test UEFI application
+│ └── utility_wolf.c UEFI platform utility implementations
+└── README.md
+```
+
+---
+
+## Prerequisites (Linux)
+
+| Package | Purpose |
+|---------|---------|
+| `gnu-efi` | EFI CRT0, linker scripts, headers (`/usr/include/efi`) |
+| `gcc-multilib` | 32-bit cross-build support (`-m32`) |
+| `qemu-system-x86` | x86_64 and i386 UEFI emulation |
+| `ovmf` | UEFI firmware for QEMU (`/usr/share/ovmf/OVMF.fd`) |
+| wolfssl source | wolfCrypt source tree (see `WOLFSSL_PATH` below) |
+
+Install on Debian/Ubuntu:
+```bash
+sudo apt install gnu-efi gcc-multilib qemu-system-x86 ovmf
+```
+
+---
+
+## Build Targets
+
+| Target | Architecture | AES-NI | Description |
+|--------|-------------|--------|-------------|
+| `lib` | x86_64 | yes | Driver with AES-NI acceleration |
+| `lib-nohw` | x86_64 | no | Pure software driver |
+| `lib32` | i386 | no | 32-bit driver (software only) |
+| `lib32-nohw` | i386 | no | Alias for lib32 |
+| `run` | x86_64 | yes | Build + QEMU (KVM, host CPU) |
+| `run-nohw` | x86_64 | no | Build + QEMU (qemu64 CPU, no AES-NI) |
+| `run32` | i386 | no | Build + QEMU i386 |
+| `run32-nohw` | i386 | no | Alias for run32 |
+| `run-fallback-nohw` | x86_64 | both | Build hw+nohw, run QEMU without AES-NI |
+| `clean` | — | — | Remove all build artifacts |
+
+---
+
+## WOLFSSL_PATH Variable
+
+The Makefile defaults to:
+```makefile
+WOLFSSL_PATH ?= $(abspath $(CURDIR)/../../wolfssl)
+```
+This resolves to the `wolfssl` directory that is a sibling of `wolfssl-examples`.
+Override on the command line:
+```bash
+make run-nohw WOLFSSL_PATH=/path/to/wolfssl
+```
+
+The wolfssl source does not need to be configured or compiled separately — the
+Makefile compiles only the required `.c` files from the wolfssl tree directly.
+
+---
+
+## hw vs nohw Builds
+
+**`lib` (hw)** compiles with `-maes -mpclmul -DUEFI_HW_ACCEL`, enabling AES-NI
+intrinsics. At runtime the driver checks CPUID for AES-NI support in `efi_main`.
+If AES-NI is absent the driver prints a message and returns `EFI_UNSUPPORTED`,
+staying unloaded. This enables the CPUID-based fallback mechanism.
+
+**`lib-nohw`** compiles without hardware intrinsics, using portable C
+implementations. It loads on any x86_64 CPU regardless of AES-NI.
+
+---
+
+## CPUID-Based Fallback Mechanism
+
+The `run-fallback-nohw` target demonstrates automatic driver selection:
+
+1. Both `libwolfcrypt.efi` (hw) and `libwolfcrypt-nohw.efi` (software-only) are
+ built and copied to the `efifs/` FAT image.
+2. `startup.nsh` is installed in `efifs/`:
+ ```
+ fs0:
+ load libwolfcrypt.efi
+ if %lasterror% == 0 then
+ goto loaded
+ endif
+ echo Falling back to software-only driver...
+ load libwolfcrypt-nohw.efi
+ :loaded
+ test.efi
+ ```
+3. QEMU is launched with `-cpu qemu64` (no AES-NI).
+4. The hw driver detects the missing capability and returns `EFI_UNSUPPORTED`.
+5. The shell sees a non-zero `%lasterror%` and loads the nohw driver instead.
+6. `test.efi` runs against whichever driver is resident.
+
+This mirrors real-world deployment where a single firmware image ships both
+variants, choosing at boot time based on hardware capability.
+
+---
+
+## Example Invocations
+
+```bash
+# Safest — software only, no KVM or AES-NI required
+make run-nohw
+
+# Hardware accelerated (requires KVM host with AES-NI), runs in KVM/qemu
+make run
+
+# Demonstrate fallback on qemu64: CPU does not support AES-NI
+# hw driver `load` fails, exits with EFI_UNSUPPORTED, nohw driver loaded
+# as fallback via startup.nsh
+make run-fallback-nohw
+
+# 32-bit build, software only, run in qemu32
+make run32-nohw
+
+# Build only, no QEMU (full HW accelerated build)
+make lib-nohw
+```
+
+---
+
+## Protocol Interface
+
+The driver installs a `WOLFCRYPT_PROTOCOL` on its image handle. Consumer
+applications locate it via:
+```c
+#include "wolfcrypt_api.h"
+
+static EFI_GUID gWolfCryptProtocolGuid = WOLFCRYPT_PROTOCOL_GUID;
+WOLFCRYPT_PROTOCOL *wc = NULL;
+Status = BS->LocateProtocol(&gWolfCryptProtocolGuid, NULL, (VOID **)&wc);
+```
+
+The protocol struct provides function pointers for:
+- **Symmetric**: AES (ECB/CBC/CFB/CTR/OFB/GCM/CCM), ChaCha20, Poly1305,
+ ChaCha20-Poly1305 AEAD, CMAC
+- **Hash**: SHA-1, SHA-224, SHA-256, SHA-384, SHA-512, SHA-3 (256/384/512),
+ SHAKE-128, SHAKE-256
+- **MAC**: HMAC
+- **Asymmetric**: RSA, ECC, DH, Curve25519, Ed25519
+- **Post-quantum**: ML-KEM (Kyber), Dilithium (ML-DSA), Falcon, SPHINCS+, XMSS, LMS
+- **KDF**: PBKDF2, PKCS12-PBKDF, HKDF
+- **RNG**: hardware-seeded DRBG via UEFI `EFI_RNG_PROTOCOL`
+- **Misc**: logging, error strings, version
+
+See `wolfcrypt_api.h` for the complete `WOLFCRYPT_PROTOCOL` definition.
+
+
diff --git a/uefi-library/src/driver.c b/uefi-library/src/driver.c
new file mode 100644
index 00000000..410117c0
--- /dev/null
+++ b/uefi-library/src/driver.c
@@ -0,0 +1,825 @@
+/* driver.c
+ *
+ * wolfCrypt as standalone bootloader driver for UEFI
+ *
+ * Copyright (C) 2026 wolfSSL Inc.
+ *
+ * This file is part of wolfSSL. (formerly known as CyaSSL)
+ *
+ * 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 2 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-1301, USA
+ */
+
+#include
+#include
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#ifdef HAVE_DILITHIUM
+#include
+#endif
+#ifdef HAVE_FALCON
+#include
+#endif
+#ifdef UEFI_HW_ACCEL
+#include
+#endif
+
+#include "wolfcrypt_api.h"
+
+#ifdef GNUEFI
+#define EFI_API_TAG EFIAPI
+#else
+#define EFI_API_TAG __attribute__((ms_abi))
+#endif
+
+
+#define WRAP_FUNC(ret_type, name, args, call_args) \
+ static ret_type EFI_API_TAG name##_EfiAPI args { \
+ return name call_args; \
+ }
+
+#define WRAP_VOID(name, args, call_args) \
+ static void EFI_API_TAG name##_EfiAPI args { \
+ name call_args; \
+ }
+
+#define WRAP_FUNC_ALIAS(ret_type, alias, target, args, call_args) \
+ static ret_type EFI_API_TAG alias##_EfiAPI args { \
+ return target call_args; \
+ }
+
+#define WRAP_VOID_ALIAS(alias, target, args, call_args) \
+ static void EFI_API_TAG alias##_EfiAPI args { \
+ target call_args; \
+ }
+
+#define WC_UNUSED(x) ((void)(x))
+
+WOLFSSL_API int wc_RsaSetRNG(RsaKey* key, WC_RNG* rng);
+
+static EFI_HANDLE g_wolfcrypt_handle = NULL;
+EFI_GUID g_wolfcrypt_protocol_guid = WOLFCRYPT_PROTOCOL_GUID;
+
+/* ------------------------------------------------------------------ */
+/* AES wrappers */
+/* ------------------------------------------------------------------ */
+WRAP_FUNC(int, wc_AesInit, (Aes* aes, void* heap, int devId), (aes, heap, devId))
+WRAP_FUNC(int, wc_AesSetKey, (Aes* aes, const byte* key, word32 len, const byte* iv, int dir),
+ (aes, key, len, iv, dir))
+WRAP_FUNC(int, wc_AesEcbEncrypt, (Aes* aes, byte* out, const byte* in, word32 sz),
+ (aes, out, in, sz))
+WRAP_FUNC(int, wc_AesEcbDecrypt, (Aes* aes, byte* out, const byte* in, word32 sz),
+ (aes, out, in, sz))
+WRAP_FUNC(int, wc_AesCbcEncrypt, (Aes* aes, byte* out, const byte* in, word32 sz),
+ (aes, out, in, sz))
+WRAP_FUNC(int, wc_AesCbcDecrypt, (Aes* aes, byte* out, const byte* in, word32 sz),
+ (aes, out, in, sz))
+WRAP_FUNC(int, wc_AesCfbEncrypt, (Aes* aes, byte* out, const byte* in, word32 sz),
+ (aes, out, in, sz))
+WRAP_FUNC(int, wc_AesCfbDecrypt, (Aes* aes, byte* out, const byte* in, word32 sz),
+ (aes, out, in, sz))
+WRAP_FUNC(int, wc_AesSetIV, (Aes* aes, const byte* iv), (aes, iv))
+WRAP_VOID(wc_AesFree, (Aes* aes), (aes))
+WRAP_FUNC(int, wc_AesGcmSetKey, (Aes* aes, const byte* key, word32 len), (aes, key, len))
+WRAP_FUNC(int, wc_AesGcmEncrypt, (Aes* aes, byte* out, const byte* in, word32 sz,
+ const byte* iv, word32 ivSz, byte* authTag, word32 authTagSz,
+ const byte* authIn, word32 authInSz),
+ (aes, out, in, sz, iv, ivSz, authTag, authTagSz, authIn, authInSz))
+WRAP_FUNC(int, wc_AesGcmDecrypt, (Aes* aes, byte* out, const byte* in, word32 sz,
+ const byte* iv, word32 ivSz, const byte* authTag, word32 authTagSz,
+ const byte* authIn, word32 authInSz),
+ (aes, out, in, sz, iv, ivSz, authTag, authTagSz, authIn, authInSz))
+WRAP_FUNC(int, wc_AesCcmSetKey, (Aes* aes, const byte* key, word32 keySz), (aes, key, keySz))
+WRAP_FUNC(int, wc_AesCcmEncrypt, (Aes* aes, byte* out, const byte* in, word32 inSz,
+ const byte* nonce, word32 nonceSz, byte* authTag, word32 authTagSz,
+ const byte* authIn, word32 authInSz),
+ (aes, out, in, inSz, nonce, nonceSz, authTag, authTagSz, authIn, authInSz))
+WRAP_FUNC(int, wc_AesCcmDecrypt, (Aes* aes, byte* out, const byte* in, word32 inSz,
+ const byte* nonce, word32 nonceSz, const byte* authTag, word32 authTagSz,
+ const byte* authIn, word32 authInSz),
+ (aes, out, in, inSz, nonce, nonceSz, authTag, authTagSz, authIn, authInSz))
+WRAP_FUNC(int, wc_AesCtrEncrypt, (Aes* aes, byte* out, const byte* in, word32 sz),
+ (aes, out, in, sz))
+WRAP_FUNC(int, wc_AesOfbEncrypt, (Aes* aes, byte* out, const byte* in, word32 sz),
+ (aes, out, in, sz))
+
+/* ------------------------------------------------------------------ */
+/* RNG wrappers */
+/* ------------------------------------------------------------------ */
+WRAP_FUNC(int, wc_InitRng, (WC_RNG* rng), (rng))
+WRAP_FUNC(int, wc_FreeRng, (WC_RNG* rng), (rng))
+WRAP_FUNC(int, wc_RNG_GenerateBlock, (WC_RNG* rng, byte* output, word32 sz), (rng, output, sz))
+WRAP_FUNC(int, wc_RNG_GenerateByte, (WC_RNG* rng, byte* b), (rng, b))
+WRAP_FUNC(int, wc_SetSeed_Cb, (wc_RngSeed_Cb cb), (cb))
+WRAP_FUNC(int, wc_RNG_TestSeed, (const byte* seed, word32 seedSz), (seed, seedSz))
+WRAP_FUNC(int, wc_GenerateSeed, (OS_Seed* os, byte* output, word32 sz), (os, output, sz))
+
+static int EFIAPI wc_GenerateSeed_IntelRD_EfiAPI(OS_Seed* os, byte* output, word32 sz)
+{
+ return wc_GenerateSeed(os, output, sz);
+}
+
+static int EFIAPI wc_GenerateRand_IntelRD_EfiAPI(OS_Seed* os, byte* output, word32 sz)
+{
+ return wc_GenerateSeed(os, output, sz);
+}
+
+static void EFIAPI wc_InitRng_IntelRD_EfiAPI(void)
+{
+ /* All entropy sources are assumed ready in this configuration. */
+}
+
+/* ------------------------------------------------------------------ */
+/* RSA wrappers */
+/* ------------------------------------------------------------------ */
+WRAP_FUNC(int, wc_InitRsaKey, (RsaKey* key, void* heap), (key, heap))
+WRAP_FUNC(int, wc_MakeRsaKey, (RsaKey* key, int size, long e, WC_RNG* rng), (key, size, e, rng))
+WRAP_FUNC(int, wc_RsaKeyToDer, (RsaKey* key, byte* output, word32 inLen), (key, output, inLen))
+WRAP_FUNC(int, wc_FreeRsaKey, (RsaKey* key), (key))
+WRAP_FUNC(int, wc_RsaEncryptSize, (const RsaKey* key), (key))
+WRAP_FUNC(int, wc_RsaPrivateKeyDecode, (const byte* input, word32* inOutIdx, RsaKey* key, word32 inSz),
+ (input, inOutIdx, key, inSz))
+WRAP_FUNC(int, wc_RsaPublicKeyDecode, (const byte* input, word32* inOutIdx, RsaKey* key, word32 inSz),
+ (input, inOutIdx, key, inSz))
+WRAP_FUNC(int, wc_RsaPrivateDecrypt_ex,
+ (const byte* in, word32 inLen, byte* out, word32 outLen, RsaKey* key, int type,
+ enum wc_HashType hash, int mgf, byte* label, word32 labelSz),
+ (in, inLen, out, outLen, key, type, hash, mgf, label, labelSz))
+WRAP_FUNC(int, wc_RsaPrivateDecrypt, (const byte* in, word32 inLen, byte* out, word32 outLen, RsaKey* key),
+ (in, inLen, out, outLen, key))
+WRAP_FUNC(int, wc_RsaPublicEncrypt, (const byte* in, word32 inLen, byte* out, word32 outLen, RsaKey* key, WC_RNG* rng),
+ (in, inLen, out, outLen, key, rng))
+WRAP_FUNC(int, wc_RsaPublicEncrypt_ex,
+ (const byte* in, word32 inLen, byte* out, word32 outLen, RsaKey* key, WC_RNG* rng,
+ int type, enum wc_HashType hash, int mgf, byte* label, word32 labelSz),
+ (in, inLen, out, outLen, key, rng, type, hash, mgf, label, labelSz))
+WRAP_FUNC(int, wc_RsaExportKey,
+ (RsaKey* key, byte* e, word32* eSz, byte* n, word32* nSz,
+ byte* d, word32* dSz, byte* p, word32* pSz, byte* q, word32* qSz),
+ (key, e, eSz, n, nSz, d, dSz, p, pSz, q, qSz))
+WRAP_FUNC(int, wc_CheckRsaKey, (RsaKey* key), (key))
+WRAP_FUNC(int, wc_RsaPublicKeyDerSize, (RsaKey* key, int withHeader), (key, withHeader))
+WRAP_FUNC(int, wc_RsaKeyToPublicDer, (RsaKey* key, byte* output, word32 inLen), (key, output, inLen))
+WRAP_FUNC(int, wc_RsaSetRNG, (RsaKey* key, WC_RNG* rng), (key, rng))
+
+static void EFIAPI wc_RsaCleanup_EfiAPI(RsaKey* key)
+{
+ if (key == NULL) {
+ return;
+ }
+
+ if (key->data != NULL && key->dataLen > 0 &&
+ (key->type == RSA_PRIVATE_DECRYPT || key->type == RSA_PRIVATE_ENCRYPT)) {
+ ForceZero(key->data, key->dataLen);
+ }
+
+ if (key->dataIsAlloc) {
+ XFREE(key->data, key->heap, DYNAMIC_TYPE_WOLF_BIGINT);
+ key->dataIsAlloc = 0;
+ }
+
+ key->data = NULL;
+ key->dataLen = 0;
+}
+
+/* ------------------------------------------------------------------ */
+/* HMAC wrappers */
+/* ------------------------------------------------------------------ */
+WRAP_FUNC(int, wc_HmacSetKey, (Hmac* hmac, int type, const byte* key, word32 length), (hmac, type, key, length))
+WRAP_FUNC(int, wc_HmacUpdate, (Hmac* hmac, const byte* msg, word32 length), (hmac, msg, length))
+WRAP_FUNC(int, wc_HmacFinal, (Hmac* hmac, byte* hash), (hmac, hash))
+
+/* ------------------------------------------------------------------ */
+/* SHA-1 wrappers */
+/* ------------------------------------------------------------------ */
+WRAP_FUNC(int, wc_InitSha, (wc_Sha* sha), (sha))
+WRAP_FUNC(int, wc_ShaUpdate, (wc_Sha* sha, const byte* data, word32 len), (sha, data, len))
+WRAP_FUNC(int, wc_ShaFinal, (wc_Sha* sha, byte* hash), (sha, hash))
+WRAP_VOID(wc_ShaFree, (wc_Sha* sha), (sha))
+
+/* ------------------------------------------------------------------ */
+/* SHA-224 wrappers */
+/* ------------------------------------------------------------------ */
+WRAP_FUNC(int, wc_InitSha224, (wc_Sha224* sha), (sha))
+WRAP_FUNC(int, wc_Sha224Update, (wc_Sha224* sha, const byte* data, word32 len), (sha, data, len))
+WRAP_FUNC(int, wc_Sha224Final, (wc_Sha224* sha, byte* hash), (sha, hash))
+WRAP_VOID(wc_Sha224Free, (wc_Sha224* sha), (sha))
+
+/* ------------------------------------------------------------------ */
+/* SHA-256 wrappers */
+/* ------------------------------------------------------------------ */
+WRAP_FUNC(int, wc_InitSha256, (wc_Sha256* sha), (sha))
+WRAP_FUNC(int, wc_InitSha256_ex, (wc_Sha256* sha, void* heap, int devId), (sha, heap, devId))
+WRAP_FUNC(int, wc_Sha256Update, (wc_Sha256* sha, const byte* data, word32 len), (sha, data, len))
+WRAP_FUNC(int, wc_Sha256Final, (wc_Sha256* sha256, byte* hash), (sha256, hash))
+WRAP_VOID(wc_Sha256Free, (wc_Sha256* sha), (sha))
+
+/* ------------------------------------------------------------------ */
+/* SHA-384 wrappers */
+/* ------------------------------------------------------------------ */
+WRAP_FUNC(int, wc_InitSha384, (wc_Sha384* sha), (sha))
+WRAP_FUNC(int, wc_Sha384Update, (wc_Sha384* sha, const byte* data, word32 len), (sha, data, len))
+WRAP_FUNC(int, wc_Sha384Final, (wc_Sha384* sha, byte* hash), (sha, hash))
+WRAP_VOID(wc_Sha384Free, (wc_Sha384* sha), (sha))
+
+/* ------------------------------------------------------------------ */
+/* SHA-512 wrappers */
+/* ------------------------------------------------------------------ */
+WRAP_FUNC(int, wc_InitSha512, (wc_Sha512* sha), (sha))
+WRAP_FUNC(int, wc_Sha512Update, (wc_Sha512* sha, const byte* data, word32 len), (sha, data, len))
+WRAP_FUNC(int, wc_Sha512Final, (wc_Sha512* sha, byte* hash), (sha, hash))
+WRAP_VOID(wc_Sha512Free, (wc_Sha512* sha), (sha))
+
+/* ------------------------------------------------------------------ */
+/* SHA-3 wrappers */
+/* ------------------------------------------------------------------ */
+WRAP_FUNC(int, wc_InitSha3_256, (wc_Sha3* sha, void* heap, int devId), (sha, heap, devId))
+WRAP_FUNC(int, wc_Sha3_256_Update, (wc_Sha3* sha, const byte* data, word32 len), (sha, data, len))
+WRAP_FUNC(int, wc_Sha3_256_Final, (wc_Sha3* sha, byte* hash), (sha, hash))
+WRAP_VOID(wc_Sha3_256_Free, (wc_Sha3* sha), (sha))
+
+WRAP_FUNC(int, wc_InitSha3_384, (wc_Sha3* sha, void* heap, int devId), (sha, heap, devId))
+WRAP_FUNC(int, wc_Sha3_384_Update, (wc_Sha3* sha, const byte* data, word32 len), (sha, data, len))
+WRAP_FUNC(int, wc_Sha3_384_Final, (wc_Sha3* sha, byte* hash), (sha, hash))
+WRAP_VOID(wc_Sha3_384_Free, (wc_Sha3* sha), (sha))
+
+WRAP_FUNC(int, wc_InitSha3_512, (wc_Sha3* sha, void* heap, int devId), (sha, heap, devId))
+WRAP_FUNC(int, wc_Sha3_512_Update, (wc_Sha3* sha, const byte* data, word32 len), (sha, data, len))
+WRAP_FUNC(int, wc_Sha3_512_Final, (wc_Sha3* sha, byte* hash), (sha, hash))
+WRAP_VOID(wc_Sha3_512_Free, (wc_Sha3* sha), (sha))
+
+/* ------------------------------------------------------------------ */
+/* SHAKE128/256 wrappers */
+/* ------------------------------------------------------------------ */
+WRAP_FUNC(int, wc_InitShake128, (wc_Shake* shake, void* heap, int devId), (shake, heap, devId))
+WRAP_FUNC(int, wc_Shake128_Update, (wc_Shake* shake, const byte* data, word32 len), (shake, data, len))
+WRAP_FUNC(int, wc_Shake128_Final, (wc_Shake* shake, byte* hash, word32 hashLen), (shake, hash, hashLen))
+WRAP_FUNC(int, wc_Shake128_SqueezeBlocks, (wc_Shake* shake, byte* out, word32 blockCnt), (shake, out, blockCnt))
+WRAP_VOID(wc_Shake128_Free, (wc_Shake* shake), (shake))
+
+WRAP_FUNC(int, wc_InitShake256, (wc_Shake* shake, void* heap, int devId), (shake, heap, devId))
+WRAP_FUNC(int, wc_Shake256_Update, (wc_Shake* shake, const byte* data, word32 len), (shake, data, len))
+WRAP_FUNC(int, wc_Shake256_Final, (wc_Shake* shake, byte* hash, word32 hashLen), (shake, hash, hashLen))
+WRAP_FUNC(int, wc_Shake256_SqueezeBlocks, (wc_Shake* shake, byte* out, word32 blockCnt), (shake, out, blockCnt))
+WRAP_VOID(wc_Shake256_Free, (wc_Shake* shake), (shake))
+
+/* ------------------------------------------------------------------ */
+/* ECC wrappers */
+/* ------------------------------------------------------------------ */
+WRAP_FUNC(int, wc_ecc_init, (ecc_key* key), (key))
+WRAP_VOID(wc_ecc_free, (ecc_key* key), (key))
+WRAP_FUNC(int, wc_ecc_make_key, (WC_RNG* rng, int keysize, ecc_key* key), (rng, keysize, key))
+WRAP_FUNC(int, wc_ecc_set_rng, (ecc_key* key, WC_RNG* rng), (key, rng))
+WRAP_FUNC(int, wc_ecc_shared_secret, (ecc_key* priv, ecc_key* pub, byte* out, word32* outlen),
+ (priv, pub, out, outlen))
+WRAP_FUNC(int, wc_ecc_sign_hash, (const byte* in, word32 inlen, byte* out, word32* outlen,
+ WC_RNG* rng, ecc_key* key), (in, inlen, out, outlen, rng, key))
+WRAP_FUNC(int, wc_ecc_verify_hash, (const byte* sig, word32 siglen, const byte* hash,
+ word32 hashlen, int* stat, ecc_key* key), (sig, siglen, hash, hashlen, stat, key))
+WRAP_FUNC(int, wc_ecc_export_x963, (ecc_key* key, byte* out, word32* outLen), (key, out, outLen))
+WRAP_FUNC(int, wc_ecc_import_x963, (const byte* in, word32 inLen, ecc_key* key), (in, inLen, key))
+WRAP_FUNC(int, wc_EccKeyToDer, (ecc_key* key, byte* output, word32 inLen), (key, output, inLen))
+WRAP_FUNC(int, wc_EccPublicKeyDecode, (const byte* input, word32* inOutIdx, ecc_key* key, word32 inSz),
+ (input, inOutIdx, key, inSz))
+WRAP_FUNC(int, wc_EccPrivateKeyDecode, (const byte* input, word32* inOutIdx, ecc_key* key, word32 inSz),
+ (input, inOutIdx, key, inSz))
+
+/* ------------------------------------------------------------------ */
+/* DH wrappers */
+/* ------------------------------------------------------------------ */
+WRAP_FUNC(int, wc_DhGenerateParams, (WC_RNG* rng, int modSz, DhKey* key), (rng, modSz, key))
+WRAP_FUNC(int, wc_DhGenerateKeyPair, (DhKey* key, WC_RNG* rng, byte* priv, word32* privSz,
+ byte* pub, word32* pubSz), (key, rng, priv, privSz, pub, pubSz))
+WRAP_FUNC(int, wc_DhAgree, (DhKey* key, byte* agree, word32* agreeSz,
+ const byte* priv, word32 privSz, const byte* otherPub, word32 pubSz),
+ (key, agree, agreeSz, priv, privSz, otherPub, pubSz))
+
+/* ------------------------------------------------------------------ */
+/* ChaCha20 wrappers */
+/* ------------------------------------------------------------------ */
+WRAP_FUNC(int, wc_Chacha_SetKey, (ChaCha* ctx, const byte* key, word32 keySz), (ctx, key, keySz))
+WRAP_FUNC(int, wc_Chacha_Process, (ChaCha* ctx, byte* output, const byte* input, word32 msglen),
+ (ctx, output, input, msglen))
+
+/* ------------------------------------------------------------------ */
+/* Poly1305 wrappers */
+/* ------------------------------------------------------------------ */
+WRAP_FUNC(int, wc_Poly1305SetKey, (Poly1305* ctx, const byte* key, word32 keySz), (ctx, key, keySz))
+WRAP_FUNC(int, wc_Poly1305Update, (Poly1305* ctx, const byte* m, word32 bytes), (ctx, m, bytes))
+WRAP_FUNC(int, wc_Poly1305Final, (Poly1305* ctx, byte* tag), (ctx, tag))
+
+/* ------------------------------------------------------------------ */
+/* ChaCha20-Poly1305 AEAD wrappers */
+/* ------------------------------------------------------------------ */
+WRAP_FUNC(int, wc_ChaCha20Poly1305_Encrypt,
+ (const byte* inKey, const byte* inIV,
+ const byte* inAAD, word32 inAADLen,
+ const byte* inPlaintext, word32 inPlaintextLen,
+ byte* outCiphertext, byte* outAuthTag),
+ (inKey, inIV, inAAD, inAADLen, inPlaintext, inPlaintextLen,
+ outCiphertext, outAuthTag))
+WRAP_FUNC(int, wc_ChaCha20Poly1305_Decrypt,
+ (const byte* inKey, const byte* inIV,
+ const byte* inAAD, word32 inAADLen,
+ const byte* inCiphertext, word32 inCiphertextLen,
+ const byte* inAuthTag, byte* outPlaintext),
+ (inKey, inIV, inAAD, inAADLen, inCiphertext, inCiphertextLen,
+ inAuthTag, outPlaintext))
+
+/* ------------------------------------------------------------------ */
+/* Curve25519 wrappers */
+/* ------------------------------------------------------------------ */
+WRAP_FUNC(int, wc_curve25519_init, (curve25519_key* key), (key))
+WRAP_VOID(wc_curve25519_free, (curve25519_key* key), (key))
+WRAP_FUNC(int, wc_curve25519_make_key, (WC_RNG* rng, int keysize, curve25519_key* key),
+ (rng, keysize, key))
+WRAP_FUNC(int, wc_curve25519_shared_secret, (curve25519_key* priv, curve25519_key* pub,
+ byte* out, word32* outlen), (priv, pub, out, outlen))
+WRAP_FUNC(int, wc_curve25519_export_key_raw, (curve25519_key* key, byte* priv, word32* privSz,
+ byte* pub, word32* pubSz), (key, priv, privSz, pub, pubSz))
+WRAP_FUNC(int, wc_curve25519_import_public, (const byte* in, word32 inLen, curve25519_key* key),
+ (in, inLen, key))
+
+/* ------------------------------------------------------------------ */
+/* Ed25519 wrappers */
+/* ------------------------------------------------------------------ */
+WRAP_FUNC(int, wc_ed25519_init, (ed25519_key* key), (key))
+WRAP_VOID(wc_ed25519_free, (ed25519_key* key), (key))
+WRAP_FUNC(int, wc_ed25519_make_key, (WC_RNG* rng, int keysize, ed25519_key* key),
+ (rng, keysize, key))
+WRAP_FUNC(int, wc_ed25519_sign_msg, (const byte* in, word32 inlen, byte* out, word32* outlen,
+ ed25519_key* key), (in, inlen, out, outlen, key))
+WRAP_FUNC(int, wc_ed25519_verify_msg, (const byte* sig, word32 siglen, const byte* msg,
+ word32 msglen, int* stat, ed25519_key* key), (sig, siglen, msg, msglen, stat, key))
+WRAP_FUNC(int, wc_ed25519_export_key, (ed25519_key* key, byte* priv, word32* privSz,
+ byte* pub, word32* pubSz), (key, priv, privSz, pub, pubSz))
+WRAP_FUNC(int, wc_ed25519_import_public, (const byte* in, word32 inLen, ed25519_key* key),
+ (in, inLen, key))
+
+/* ------------------------------------------------------------------ */
+/* ML-KEM wrappers */
+/* ------------------------------------------------------------------ */
+#ifdef WOLFSSL_HAVE_MLKEM
+WRAP_FUNC(int, wc_MlKemKey_Init, (MlKemKey* key, int type, void* heap, int devId), (key, type, heap, devId))
+WRAP_FUNC(int, wc_MlKemKey_Free, (MlKemKey* key), (key))
+WRAP_FUNC(int, wc_MlKemKey_MakeKey, (MlKemKey* key, WC_RNG* rng), (key, rng))
+WRAP_FUNC(int, wc_MlKemKey_CipherTextSize, (MlKemKey* key, word32* len), (key, len))
+WRAP_FUNC(int, wc_MlKemKey_SharedSecretSize, (MlKemKey* key, word32* len), (key, len))
+WRAP_FUNC(int, wc_MlKemKey_Encapsulate,
+ (MlKemKey* key, unsigned char* ct, unsigned char* ss, WC_RNG* rng),
+ (key, ct, ss, rng))
+WRAP_FUNC(int, wc_MlKemKey_Decapsulate,
+ (MlKemKey* key, unsigned char* ss, const unsigned char* ct, word32 len),
+ (key, ss, ct, len))
+WRAP_FUNC(int, wc_MlKemKey_DecodePrivateKey,
+ (MlKemKey* key, const unsigned char* in, word32 len), (key, in, len))
+WRAP_FUNC(int, wc_MlKemKey_DecodePublicKey,
+ (MlKemKey* key, const unsigned char* in, word32 len), (key, in, len))
+WRAP_FUNC(int, wc_MlKemKey_PrivateKeySize, (MlKemKey* key, word32* len), (key, len))
+WRAP_FUNC(int, wc_MlKemKey_PublicKeySize, (MlKemKey* key, word32* len), (key, len))
+WRAP_FUNC(int, wc_MlKemKey_EncodePrivateKey,
+ (MlKemKey* key, unsigned char* out, word32 len), (key, out, len))
+WRAP_FUNC(int, wc_MlKemKey_EncodePublicKey,
+ (MlKemKey* key, unsigned char* out, word32 len), (key, out, len))
+#endif /* WOLFSSL_HAVE_MLKEM */
+
+/* ------------------------------------------------------------------ */
+/* Dilithium wrappers */
+/* ------------------------------------------------------------------ */
+#ifdef HAVE_DILITHIUM
+WRAP_FUNC(int, wc_dilithium_init, (dilithium_key* key), (key))
+WRAP_VOID(wc_dilithium_free, (dilithium_key* key), (key))
+WRAP_FUNC(int, wc_dilithium_set_level, (dilithium_key* key, byte level), (key, level))
+WRAP_FUNC(int, wc_dilithium_make_key, (dilithium_key* key, WC_RNG* rng), (key, rng))
+WRAP_FUNC(int, wc_dilithium_sign_msg, (const byte* in, word32 inLen, byte* out, word32* outLen,
+ dilithium_key* key, WC_RNG* rng), (in, inLen, out, outLen, key, rng))
+WRAP_FUNC(int, wc_dilithium_verify_msg, (const byte* sig, word32 sigLen, const byte* msg,
+ word32 msgLen, int* res, dilithium_key* key), (sig, sigLen, msg, msgLen, res, key))
+WRAP_FUNC(int, wc_dilithium_export_key, (dilithium_key* key, byte* priv, word32* privSz,
+ byte* pub, word32* pubSz), (key, priv, privSz, pub, pubSz))
+WRAP_FUNC(int, wc_dilithium_import_key, (const byte* priv, word32 privSz,
+ const byte* pub, word32 pubSz, dilithium_key* key),
+ (priv, privSz, pub, pubSz, key))
+#endif /* HAVE_DILITHIUM */
+
+/* ------------------------------------------------------------------ */
+/* Falcon wrappers */
+/* ------------------------------------------------------------------ */
+#ifdef HAVE_FALCON
+WRAP_FUNC(int, wc_falcon_init, (falcon_key* key), (key))
+WRAP_VOID(wc_falcon_free, (falcon_key* key), (key))
+WRAP_FUNC(int, wc_falcon_make_key, (falcon_key* key, WC_RNG* rng), (key, rng))
+WRAP_FUNC(int, wc_falcon_sign_msg, (const byte* in, word32 inLen, byte* out, word32* outLen,
+ falcon_key* key, WC_RNG* rng), (in, inLen, out, outLen, key, rng))
+WRAP_FUNC(int, wc_falcon_verify_msg, (const byte* sig, word32 sigLen, const byte* msg,
+ word32 msgLen, int* res, falcon_key* key), (sig, sigLen, msg, msgLen, res, key))
+WRAP_FUNC(int, wc_falcon_export_key, (falcon_key* key, byte* priv, word32* privSz,
+ byte* pub, word32* pubSz), (key, priv, privSz, pub, pubSz))
+WRAP_FUNC(int, wc_falcon_import_key, (const byte* priv, word32 privSz,
+ const byte* pub, word32 pubSz, falcon_key* key),
+ (priv, privSz, pub, pubSz, key))
+#endif /* HAVE_FALCON */
+
+/* ------------------------------------------------------------------ */
+/* CMAC wrappers */
+/* ------------------------------------------------------------------ */
+WRAP_FUNC(int, wc_InitCmac, (Cmac* cmac, const byte* key, word32 keySz, int type, void* unused),
+ (cmac, key, keySz, type, unused))
+WRAP_FUNC(int, wc_CmacUpdate, (Cmac* cmac, const byte* in, word32 inSz), (cmac, in, inSz))
+WRAP_FUNC(int, wc_CmacFinal, (Cmac* cmac, byte* out, word32* outSz), (cmac, out, outSz))
+
+/* ------------------------------------------------------------------ */
+/* KDF / PKCS wrappers */
+/* ------------------------------------------------------------------ */
+WRAP_FUNC(int, wc_PBKDF2,
+ (byte* output, const byte* passwd, int pLen, const byte* salt, int sLen,
+ int iterations, int kLen, int hashType),
+ (output, passwd, pLen, salt, sLen, iterations, kLen, hashType))
+WRAP_FUNC(int, wc_PKCS12_PBKDF,
+ (byte* output, const byte* passwd, int passLen, const byte* salt, int saltLen,
+ int iterations, int kLen, int hashType, int id),
+ (output, passwd, passLen, salt, saltLen, iterations, kLen, hashType, id))
+WRAP_FUNC(int, wc_PKCS7_PadData, (byte* in, word32 inSz, byte* out, word32 outSz, word32 blockSz),
+ (in, inSz, out, outSz, blockSz))
+WRAP_FUNC(int, wc_HKDF, (int type, const byte* inKey, word32 inKeySz,
+ const byte* salt, word32 saltSz, const byte* info, word32 infoSz,
+ byte* out, word32 outSz),
+ (type, inKey, inKeySz, salt, saltSz, info, infoSz, out, outSz))
+
+/* ------------------------------------------------------------------ */
+/* Logging / Error wrappers */
+/* ------------------------------------------------------------------ */
+WRAP_FUNC(int, wolfSSL_Debugging_ON, (void), ())
+WRAP_FUNC(int, wolfSSL_SetLoggingCb, (wolfSSL_Logging_cb cb), (cb))
+WRAP_FUNC(wolfSSL_Logging_cb, wolfSSL_GetLoggingCb, (void), ())
+WRAP_VOID(wolfSSL_Debugging_OFF, (void), ())
+
+WRAP_FUNC(const char*, wc_GetErrorString, (int error), (error))
+WRAP_VOID(wc_ErrorString, (int err, char* buff), (err, buff))
+
+/* ------------------------------------------------------------------ */
+/* Protocol instance */
+/* ------------------------------------------------------------------ */
+static WOLFCRYPT_PROTOCOL g_wolfcrypt_api = {
+ .Version = LIBWOLFSSL_VERSION_HEX,
+
+ /* AES */
+ .wc_AesInit = wc_AesInit_EfiAPI,
+ .wc_AesSetKey = wc_AesSetKey_EfiAPI,
+ .wc_AesEcbEncrypt = wc_AesEcbEncrypt_EfiAPI,
+ .wc_AesEcbDecrypt = wc_AesEcbDecrypt_EfiAPI,
+ .wc_AesCbcEncrypt = wc_AesCbcEncrypt_EfiAPI,
+ .wc_AesCbcDecrypt = wc_AesCbcDecrypt_EfiAPI,
+ .wc_AesCfbEncrypt = wc_AesCfbEncrypt_EfiAPI,
+ .wc_AesCfbDecrypt = wc_AesCfbDecrypt_EfiAPI,
+ .wc_AesSetIV = wc_AesSetIV_EfiAPI,
+ .wc_AesFree = wc_AesFree_EfiAPI,
+ .wc_AesGcmSetKey = wc_AesGcmSetKey_EfiAPI,
+ .wc_AesGcmEncrypt = wc_AesGcmEncrypt_EfiAPI,
+ .wc_AesGcmDecrypt = wc_AesGcmDecrypt_EfiAPI,
+ .wc_AesCcmSetKey = wc_AesCcmSetKey_EfiAPI,
+ .wc_AesCcmEncrypt = wc_AesCcmEncrypt_EfiAPI,
+ .wc_AesCcmDecrypt = wc_AesCcmDecrypt_EfiAPI,
+ .wc_AesCtrEncrypt = wc_AesCtrEncrypt_EfiAPI,
+ .wc_AesOfbEncrypt = wc_AesOfbEncrypt_EfiAPI,
+
+ /* RNG */
+ .wc_InitRng = wc_InitRng_EfiAPI,
+ .wc_FreeRng = wc_FreeRng_EfiAPI,
+ .wc_RNG_GenerateBlock = wc_RNG_GenerateBlock_EfiAPI,
+ .wc_RNG_GenerateByte = wc_RNG_GenerateByte_EfiAPI,
+ .wc_SetSeed_Cb = wc_SetSeed_Cb_EfiAPI,
+ .wc_RNG_TestSeed = wc_RNG_TestSeed_EfiAPI,
+ .wc_GenerateSeed_IntelRD = wc_GenerateSeed_IntelRD_EfiAPI,
+ .wc_GenerateSeed = wc_GenerateSeed_EfiAPI,
+ .wc_GenerateRand_IntelRD = wc_GenerateRand_IntelRD_EfiAPI,
+ .wc_InitRng_IntelRD = wc_InitRng_IntelRD_EfiAPI,
+
+ /* RSA */
+ .wc_InitRsaKey = wc_InitRsaKey_EfiAPI,
+ .wc_MakeRsaKey = wc_MakeRsaKey_EfiAPI,
+ .wc_RsaKeyToDer = wc_RsaKeyToDer_EfiAPI,
+ .wc_FreeRsaKey = wc_FreeRsaKey_EfiAPI,
+ .wc_RsaEncryptSize = wc_RsaEncryptSize_EfiAPI,
+ .wc_RsaPrivateKeyDecode = wc_RsaPrivateKeyDecode_EfiAPI,
+ .wc_RsaPublicKeyDecode = wc_RsaPublicKeyDecode_EfiAPI,
+ .wc_RsaPrivateDecryptEx = wc_RsaPrivateDecrypt_ex_EfiAPI,
+ .wc_RsaPrivateDecrypt = wc_RsaPrivateDecrypt_EfiAPI,
+ .wc_RsaPublicEncrypt = wc_RsaPublicEncrypt_EfiAPI,
+ .wc_RsaPublicEncryptEx = wc_RsaPublicEncrypt_ex_EfiAPI,
+ .wc_RsaExportKey = wc_RsaExportKey_EfiAPI,
+ .wc_RsaCleanup = wc_RsaCleanup_EfiAPI,
+ .wc_CheckRsaKey = wc_CheckRsaKey_EfiAPI,
+ .wc_RsaPublicKeyDerSize = wc_RsaPublicKeyDerSize_EfiAPI,
+ .wc_RsaKeyToPublicDer = wc_RsaKeyToPublicDer_EfiAPI,
+ .wc_RsaSetRNG = wc_RsaSetRNG_EfiAPI,
+
+ /* HMAC */
+ .wc_HmacSetKey = wc_HmacSetKey_EfiAPI,
+ .wc_HmacUpdate = wc_HmacUpdate_EfiAPI,
+ .wc_HmacFinal = wc_HmacFinal_EfiAPI,
+
+ /* SHA-1 */
+ .wc_InitSha = wc_InitSha_EfiAPI,
+ .wc_ShaUpdate = wc_ShaUpdate_EfiAPI,
+ .wc_ShaFinal = wc_ShaFinal_EfiAPI,
+ .wc_ShaFree = wc_ShaFree_EfiAPI,
+
+ /* SHA-224 */
+ .wc_InitSha224 = wc_InitSha224_EfiAPI,
+ .wc_Sha224Update = wc_Sha224Update_EfiAPI,
+ .wc_Sha224Final = wc_Sha224Final_EfiAPI,
+ .wc_Sha224Free = wc_Sha224Free_EfiAPI,
+
+ /* SHA-256 */
+ .wc_InitSha256 = wc_InitSha256_EfiAPI,
+ .wc_InitSha256_ex = wc_InitSha256_ex_EfiAPI,
+ .wc_Sha256Update = wc_Sha256Update_EfiAPI,
+ .wc_Sha256Final = wc_Sha256Final_EfiAPI,
+ .wc_Sha256Free = wc_Sha256Free_EfiAPI,
+
+ /* SHA-384 */
+ .wc_InitSha384 = wc_InitSha384_EfiAPI,
+ .wc_Sha384Update = wc_Sha384Update_EfiAPI,
+ .wc_Sha384Final = wc_Sha384Final_EfiAPI,
+ .wc_Sha384Free = wc_Sha384Free_EfiAPI,
+
+ /* SHA-512 */
+ .wc_InitSha512 = wc_InitSha512_EfiAPI,
+ .wc_Sha512Update = wc_Sha512Update_EfiAPI,
+ .wc_Sha512Final = wc_Sha512Final_EfiAPI,
+ .wc_Sha512Free = wc_Sha512Free_EfiAPI,
+
+ /* SHA-3 */
+ .wc_InitSha3_256 = wc_InitSha3_256_EfiAPI,
+ .wc_Sha3_256_Update = wc_Sha3_256_Update_EfiAPI,
+ .wc_Sha3_256_Final = wc_Sha3_256_Final_EfiAPI,
+ .wc_Sha3_256_Free = wc_Sha3_256_Free_EfiAPI,
+ .wc_InitSha3_384 = wc_InitSha3_384_EfiAPI,
+ .wc_Sha3_384_Update = wc_Sha3_384_Update_EfiAPI,
+ .wc_Sha3_384_Final = wc_Sha3_384_Final_EfiAPI,
+ .wc_Sha3_384_Free = wc_Sha3_384_Free_EfiAPI,
+ .wc_InitSha3_512 = wc_InitSha3_512_EfiAPI,
+ .wc_Sha3_512_Update = wc_Sha3_512_Update_EfiAPI,
+ .wc_Sha3_512_Final = wc_Sha3_512_Final_EfiAPI,
+ .wc_Sha3_512_Free = wc_Sha3_512_Free_EfiAPI,
+
+ /* SHAKE */
+ .wc_InitShake128 = wc_InitShake128_EfiAPI,
+ .wc_Shake128_Update = wc_Shake128_Update_EfiAPI,
+ .wc_Shake128_Final = wc_Shake128_Final_EfiAPI,
+ .wc_Shake128_SqueezeBlocks = wc_Shake128_SqueezeBlocks_EfiAPI,
+ .wc_Shake128_Free = wc_Shake128_Free_EfiAPI,
+ .wc_InitShake256 = wc_InitShake256_EfiAPI,
+ .wc_Shake256_Update = wc_Shake256_Update_EfiAPI,
+ .wc_Shake256_Final = wc_Shake256_Final_EfiAPI,
+ .wc_Shake256_SqueezeBlocks = wc_Shake256_SqueezeBlocks_EfiAPI,
+ .wc_Shake256_Free = wc_Shake256_Free_EfiAPI,
+
+ /* ECC */
+ .wc_ecc_init = wc_ecc_init_EfiAPI,
+ .wc_ecc_free = wc_ecc_free_EfiAPI,
+ .wc_ecc_make_key = wc_ecc_make_key_EfiAPI,
+ .wc_ecc_set_rng = wc_ecc_set_rng_EfiAPI,
+ .wc_ecc_shared_secret = wc_ecc_shared_secret_EfiAPI,
+ .wc_ecc_sign_hash = wc_ecc_sign_hash_EfiAPI,
+ .wc_ecc_verify_hash = wc_ecc_verify_hash_EfiAPI,
+ .wc_ecc_export_x963 = wc_ecc_export_x963_EfiAPI,
+ .wc_ecc_import_x963 = wc_ecc_import_x963_EfiAPI,
+ .wc_EccKeyToDer = wc_EccKeyToDer_EfiAPI,
+ .wc_EccPublicKeyDecode = wc_EccPublicKeyDecode_EfiAPI,
+ .wc_EccPrivateKeyDecode = wc_EccPrivateKeyDecode_EfiAPI,
+
+ /* DH */
+ .wc_DhGenerateParams = wc_DhGenerateParams_EfiAPI,
+ .wc_DhGenerateKeyPair = wc_DhGenerateKeyPair_EfiAPI,
+ .wc_DhAgree = wc_DhAgree_EfiAPI,
+
+ /* ChaCha20 */
+ .wc_Chacha_SetKey = wc_Chacha_SetKey_EfiAPI,
+ .wc_Chacha_Process = wc_Chacha_Process_EfiAPI,
+
+ /* Poly1305 */
+ .wc_Poly1305SetKey = wc_Poly1305SetKey_EfiAPI,
+ .wc_Poly1305Update = wc_Poly1305Update_EfiAPI,
+ .wc_Poly1305Final = wc_Poly1305Final_EfiAPI,
+
+ /* ChaCha20-Poly1305 AEAD */
+ .wc_ChaCha20Poly1305_Encrypt = wc_ChaCha20Poly1305_Encrypt_EfiAPI,
+ .wc_ChaCha20Poly1305_Decrypt = wc_ChaCha20Poly1305_Decrypt_EfiAPI,
+
+ /* Curve25519 */
+ .wc_curve25519_init = wc_curve25519_init_EfiAPI,
+ .wc_curve25519_free = wc_curve25519_free_EfiAPI,
+ .wc_curve25519_make_key = wc_curve25519_make_key_EfiAPI,
+ .wc_curve25519_shared_secret = wc_curve25519_shared_secret_EfiAPI,
+ .wc_curve25519_export_key_raw = wc_curve25519_export_key_raw_EfiAPI,
+ .wc_curve25519_import_public = wc_curve25519_import_public_EfiAPI,
+
+ /* Ed25519 */
+ .wc_ed25519_init = wc_ed25519_init_EfiAPI,
+ .wc_ed25519_free = wc_ed25519_free_EfiAPI,
+ .wc_ed25519_make_key = wc_ed25519_make_key_EfiAPI,
+ .wc_ed25519_sign_msg = wc_ed25519_sign_msg_EfiAPI,
+ .wc_ed25519_verify_msg = wc_ed25519_verify_msg_EfiAPI,
+ .wc_ed25519_export_key = wc_ed25519_export_key_EfiAPI,
+ .wc_ed25519_import_public = wc_ed25519_import_public_EfiAPI,
+
+ /* ML-KEM */
+#ifdef WOLFSSL_HAVE_MLKEM
+ .wc_MlKemKey_Init = wc_MlKemKey_Init_EfiAPI,
+ .wc_MlKemKey_Free = wc_MlKemKey_Free_EfiAPI,
+ .wc_MlKemKey_MakeKey = wc_MlKemKey_MakeKey_EfiAPI,
+ .wc_MlKemKey_CipherTextSize = wc_MlKemKey_CipherTextSize_EfiAPI,
+ .wc_MlKemKey_SharedSecretSize = wc_MlKemKey_SharedSecretSize_EfiAPI,
+ .wc_MlKemKey_Encapsulate = wc_MlKemKey_Encapsulate_EfiAPI,
+ .wc_MlKemKey_Decapsulate = wc_MlKemKey_Decapsulate_EfiAPI,
+ .wc_MlKemKey_DecodePrivateKey = wc_MlKemKey_DecodePrivateKey_EfiAPI,
+ .wc_MlKemKey_DecodePublicKey = wc_MlKemKey_DecodePublicKey_EfiAPI,
+ .wc_MlKemKey_PrivateKeySize = wc_MlKemKey_PrivateKeySize_EfiAPI,
+ .wc_MlKemKey_PublicKeySize = wc_MlKemKey_PublicKeySize_EfiAPI,
+ .wc_MlKemKey_EncodePrivateKey = wc_MlKemKey_EncodePrivateKey_EfiAPI,
+ .wc_MlKemKey_EncodePublicKey = wc_MlKemKey_EncodePublicKey_EfiAPI,
+#endif
+
+ /* Dilithium */
+#ifdef HAVE_DILITHIUM
+ .wc_dilithium_init = wc_dilithium_init_EfiAPI,
+ .wc_dilithium_free = wc_dilithium_free_EfiAPI,
+ .wc_dilithium_set_level = wc_dilithium_set_level_EfiAPI,
+ .wc_dilithium_make_key = wc_dilithium_make_key_EfiAPI,
+ .wc_dilithium_sign_msg = wc_dilithium_sign_msg_EfiAPI,
+ .wc_dilithium_verify_msg = wc_dilithium_verify_msg_EfiAPI,
+ .wc_dilithium_export_key = wc_dilithium_export_key_EfiAPI,
+ .wc_dilithium_import_key = wc_dilithium_import_key_EfiAPI,
+#endif
+
+ /* Falcon */
+#ifdef HAVE_FALCON
+ .wc_falcon_init = wc_falcon_init_EfiAPI,
+ .wc_falcon_free = wc_falcon_free_EfiAPI,
+ .wc_falcon_make_key = wc_falcon_make_key_EfiAPI,
+ .wc_falcon_sign_msg = wc_falcon_sign_msg_EfiAPI,
+ .wc_falcon_verify_msg = wc_falcon_verify_msg_EfiAPI,
+ .wc_falcon_export_key = wc_falcon_export_key_EfiAPI,
+ .wc_falcon_import_key = wc_falcon_import_key_EfiAPI,
+#endif
+
+ /* CMAC */
+ .wc_InitCmac = wc_InitCmac_EfiAPI,
+ .wc_CmacUpdate = wc_CmacUpdate_EfiAPI,
+ .wc_CmacFinal = wc_CmacFinal_EfiAPI,
+
+ /* KDF / PKCS */
+ .wc_PBKDF2 = wc_PBKDF2_EfiAPI,
+ .wc_PKCS12_PBKDF = wc_PKCS12_PBKDF_EfiAPI,
+ .wc_PKCS7_PadData = wc_PKCS7_PadData_EfiAPI,
+ .wc_HKDF = wc_HKDF_EfiAPI,
+
+ /* Logging / Error */
+ .wolfSSL_Debugging_ON = wolfSSL_Debugging_ON_EfiAPI,
+ .wolfSSL_SetLoggingCb = wolfSSL_SetLoggingCb_EfiAPI,
+ .wolfSSL_GetLoggingCb = wolfSSL_GetLoggingCb_EfiAPI,
+ .wolfSSL_Debugging_OFF = wolfSSL_Debugging_OFF_EfiAPI,
+ .wc_GetErrorString = wc_GetErrorString_EfiAPI,
+ .wc_ErrorString = wc_ErrorString_EfiAPI,
+};
+
+EFI_STATUS EFIAPI efi_main(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable)
+{
+ EFI_LOADED_IMAGE *loaded_image = NULL;
+ volatile int halted = 1;
+ EFI_STATUS status;
+
+ InitializeLib(ImageHandle, SystemTable);
+ wolfSSL_Debugging_ON();
+ wolfSSL_SetLoggingCb(logging_cb);
+
+#ifdef UEFI_HW_ACCEL
+ /* hw build requires AES-NI; exit gracefully if absent so startup.nsh can
+ * fall back to the nohw driver. */
+ {
+ cpuid_flags_t cpu_flags = 0;
+ cpuid_get_flags_ex(&cpu_flags);
+
+ if (!IS_INTEL_AESNI(cpu_flags)) {
+ Print(L"Error: hw driver requires AES-NI support (not detected)\n");
+ Print(L"Please load libwolfcrypt-nohw.efi instead\n");
+ return EFI_UNSUPPORTED;
+ }
+ Print(L"CPU AES-NI support detected, loading hw driver\n");
+ }
+#endif
+
+ status = uefi_call_wrapper(SystemTable->BootServices->HandleProtocol,
+ 3,
+ ImageHandle,
+ &LoadedImageProtocol,
+ (void **)&loaded_image);
+ Print(L"wolfCrypt image loaded.\n");
+ if (loaded_image != NULL) {
+ Print(L"Image size: 0x%lx\n", loaded_image->ImageSize);
+ Print(L"Image base: 0x%lx\n", loaded_image->ImageBase);
+ }
+ Print(L"status: 0x%lx\n", status);
+
+#if WAIT_FOR_GDB
+ Print(L"Debugging is enabled. Type the following in gdb to continue\n");
+ if (loaded_image != NULL) {
+ Print(L"symbol-file libwolfcrypt.elf -o 0x%lx\n", loaded_image->ImageBase);
+ }
+ Print(L"set halted = 0\n");
+ while (halted) {
+ }
+#else
+ WC_UNUSED(halted);
+#endif
+
+ /* Runtime relocation guard for API pointers.
+ * If pointers are already relocated by the EFI loader we leave them as-is.
+ * If pointers still look unrelocated, apply image-base adjustment once. */
+ {
+ UINTN *wc_api_ptr = (UINTN *)&g_wolfcrypt_api;
+ UINTN wc_api_size = (sizeof(g_wolfcrypt_api) / sizeof(UINTN));
+ UINTN image_base = (UINTN)loaded_image->ImageBase;
+ UINTN relocated_count = 0;
+ UINTN unrelocated_count = 0;
+ int apply_fixup = 0;
+ int i;
+
+ for (i = 1; i < (int)wc_api_size; i++) {
+ UINTN p = wc_api_ptr[i];
+ if (p == 0) {
+ continue;
+ }
+ if (p >= image_base) {
+ relocated_count++;
+ }
+ else {
+ unrelocated_count++;
+ }
+ }
+
+ /* If most non-zero API entries are still below ImageBase, treat the
+ * table as unrelocated and apply image-base adjustment. */
+ apply_fixup = (unrelocated_count > relocated_count);
+
+ if (apply_fixup) {
+ for (i = 1; i < (int)wc_api_size; i++) {
+ if (wc_api_ptr[i] != 0 && wc_api_ptr[i] < image_base) {
+ wc_api_ptr[i] += image_base;
+ }
+ }
+ Print(L"wolfCrypt API symbols adjusted to image base\n");
+ }
+ else {
+ Print(L"wolfCrypt API symbols verified at correct location\n");
+ }
+ }
+
+ status = uefi_call_wrapper(BS->InstallProtocolInterface, 4,
+ &g_wolfcrypt_handle,
+ &g_wolfcrypt_protocol_guid,
+ EFI_NATIVE_INTERFACE,
+ &g_wolfcrypt_api);
+
+ Print(L"InstallProtocolInterface status: 0x%lx\n", status);
+
+ if (EFI_ERROR(status)) {
+ Print(L"ERROR: Failed to install wolfCrypt protocol\n");
+ return status;
+ }
+
+ Print(L"wolfCrypt driver loaded successfully (version 0x%08x)\n",
+ g_wolfcrypt_api.Version);
+
+ return EFI_SUCCESS;
+}
diff --git a/uefi-library/src/test_app.c b/uefi-library/src/test_app.c
new file mode 100644
index 00000000..217a2787
--- /dev/null
+++ b/uefi-library/src/test_app.c
@@ -0,0 +1,1362 @@
+/* test_app.c
+ *
+ * UEFI standalone application to test wolfCrypt
+ * loaded as standalone bootloader driver
+ *
+ * Copyright (C) 2026 wolfSSL Inc.
+ *
+ * This file is part of wolfSSL. (formerly known as CyaSSL)
+ *
+ * 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 2 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-1301, USA
+ */
+#include
+#include
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include "wolfcrypt_api.h"
+
+#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
+
+EFI_GUID g_wolfcrypt_protocol_guid = WOLFCRYPT_PROTOCOL_GUID;
+WOLFCRYPT_PROTOCOL *Api = NULL;
+
+/* ------------------------------------------------------------------ */
+/* Test vectors */
+/* ------------------------------------------------------------------ */
+
+/* AES-128 key/IV (NIST SP 800-38A) */
+static const UINT8 kAesKey128[16] = {
+ 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6,
+ 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c,
+};
+static const UINT8 kAesIv128[16] = {
+ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+ 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
+};
+static const UINT8 kAesPlain[16] = {
+ 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96,
+ 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a,
+};
+static const UINT8 kAesEcbCipher[16] = {
+ 0x3a, 0xd7, 0x7b, 0xb4, 0x0d, 0x7a, 0x36, 0x60,
+ 0xa8, 0x9e, 0xca, 0xf3, 0x24, 0x66, 0xef, 0x97,
+};
+static const UINT8 kAesCbcCipher[16] = {
+ 0x76, 0x49, 0xab, 0xac, 0x81, 0x19, 0xb2, 0x46,
+ 0xce, 0xe9, 0x8e, 0x9b, 0x12, 0xe9, 0x19, 0x7d,
+};
+static const UINT8 kAesCfbCipher[16] = {
+ 0x3b, 0x3f, 0xd9, 0x2e, 0xb7, 0x2d, 0xad, 0x20,
+ 0x33, 0x34, 0x49, 0xf8, 0xe8, 0x3c, 0xfb, 0x4a,
+};
+/* AES-CTR (NIST SP 800-38A, F.5.1) */
+static const UINT8 kAesCtrIv[16] = {
+ 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
+ 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff,
+};
+static const UINT8 kAesCtrCipher[16] = {
+ 0x87, 0x4d, 0x61, 0x91, 0xb6, 0x20, 0xe3, 0x26,
+ 0x1b, 0xef, 0x68, 0x64, 0x99, 0x0d, 0xb6, 0xce,
+};
+
+/* SHA digests of "abc" */
+static const UINT8 kShaMsg[] = { 'a', 'b', 'c' };
+static const UINT8 kSha1Digest[20] = {
+ 0xa9, 0x99, 0x3e, 0x36, 0x47, 0x06, 0x81, 0x6a,
+ 0xba, 0x3e, 0x25, 0x71, 0x78, 0x50, 0xc2, 0x6c,
+ 0x9c, 0xd0, 0xd8, 0x9d,
+};
+static const UINT8 kSha224Digest[28] = {
+ 0x23, 0x09, 0x7d, 0x22, 0x34, 0x05, 0xd8, 0x22,
+ 0x86, 0x42, 0xa4, 0x77, 0xbd, 0xa2, 0x55, 0xb3,
+ 0x2a, 0xad, 0xbc, 0xe4, 0xbd, 0xa0, 0xb3, 0xf7,
+ 0xe3, 0x6c, 0x9d, 0xa7,
+};
+static const UINT8 kSha256Digest[32] = {
+ 0xba, 0x78, 0x16, 0xbf, 0x8f, 0x01, 0xcf, 0xea,
+ 0x41, 0x41, 0x40, 0xde, 0x5d, 0xae, 0x22, 0x23,
+ 0xb0, 0x03, 0x61, 0xa3, 0x96, 0x17, 0x7a, 0x9c,
+ 0xb4, 0x10, 0xff, 0x61, 0xf2, 0x00, 0x15, 0xad,
+};
+static const UINT8 kSha384Digest[48] = {
+ 0xcb, 0x00, 0x75, 0x3f, 0x45, 0xa3, 0x5e, 0x8b,
+ 0xb5, 0xa0, 0x3d, 0x69, 0x9a, 0xc6, 0x50, 0x07,
+ 0x27, 0x2c, 0x32, 0xab, 0x0e, 0xde, 0xd1, 0x63,
+ 0x1a, 0x8b, 0x60, 0x5a, 0x43, 0xff, 0x5b, 0xed,
+ 0x80, 0x86, 0x07, 0x2b, 0xa1, 0xe7, 0xcc, 0x23,
+ 0x58, 0xba, 0xec, 0xa1, 0x34, 0xc8, 0x25, 0xa7,
+};
+static const UINT8 kSha512Digest[64] = {
+ 0xdd, 0xaf, 0x35, 0xa1, 0x93, 0x61, 0x7a, 0xba,
+ 0xcc, 0x41, 0x73, 0x49, 0xae, 0x20, 0x41, 0x31,
+ 0x12, 0xe6, 0xfa, 0x4e, 0x89, 0xa9, 0x7e, 0xa2,
+ 0x0a, 0x9e, 0xee, 0xe6, 0x4b, 0x55, 0xd3, 0x9a,
+ 0x21, 0x92, 0x99, 0x2a, 0x27, 0x4f, 0xc1, 0xa8,
+ 0x36, 0xba, 0x3c, 0x23, 0xa3, 0xfe, 0xeb, 0xbd,
+ 0x45, 0x4d, 0x44, 0x23, 0x64, 0x3c, 0xe8, 0x0e,
+ 0x2a, 0x9a, 0xc9, 0x4f, 0xa5, 0x4c, 0xa4, 0x9f,
+};
+static const UINT8 kSha3_256Digest[32] = {
+ 0x3a, 0x98, 0x5d, 0xa7, 0x4f, 0xe2, 0x25, 0xb2,
+ 0x04, 0x5c, 0x17, 0x2d, 0x6b, 0xd3, 0x90, 0xbd,
+ 0x85, 0x5f, 0x08, 0x6e, 0x3e, 0x9d, 0x52, 0x5b,
+ 0x46, 0xbf, 0xe2, 0x45, 0x11, 0x43, 0x15, 0x32,
+};
+static const UINT8 kSha3_384Digest[48] = {
+ 0xec, 0x01, 0x49, 0x82, 0x88, 0x51, 0x6f, 0xc9,
+ 0x26, 0x45, 0x9f, 0x58, 0xe2, 0xc6, 0xad, 0x8d,
+ 0xf9, 0xb4, 0x73, 0xcb, 0x0f, 0xc0, 0x8c, 0x25,
+ 0x96, 0xda, 0x7c, 0xf0, 0xe4, 0x9b, 0xe4, 0xb2,
+ 0x98, 0xd8, 0x8c, 0xea, 0x92, 0x7a, 0xc7, 0xf5,
+ 0x39, 0xf1, 0xed, 0xf2, 0x28, 0x37, 0x6d, 0x25,
+};
+static const UINT8 kSha3_512Digest[64] = {
+ 0xb7, 0x51, 0x85, 0x0b, 0x1a, 0x57, 0x16, 0x8a,
+ 0x56, 0x93, 0xcd, 0x92, 0x4b, 0x6b, 0x09, 0x6e,
+ 0x08, 0xf6, 0x21, 0x82, 0x74, 0x44, 0xf7, 0x0d,
+ 0x88, 0x4f, 0x5d, 0x02, 0x40, 0xd2, 0x71, 0x2e,
+ 0x10, 0xe1, 0x16, 0xe9, 0x19, 0x2a, 0xf3, 0xc9,
+ 0x1a, 0x7e, 0xc5, 0x76, 0x47, 0xe3, 0x93, 0x40,
+ 0x57, 0x34, 0x0b, 0x4c, 0xf4, 0x08, 0xd5, 0xa5,
+ 0x65, 0x92, 0xf8, 0x27, 0x4e, 0xec, 0x53, 0xf0,
+};
+
+/* HMAC-SHA256 (RFC 4231 test case 1) */
+static const UINT8 kHmacKey[20] = {
+ 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
+ 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
+ 0x0b, 0x0b, 0x0b, 0x0b,
+};
+static const UINT8 kHmacMsg[] = "Hi There";
+static const UINT8 kHmacSha256[32] = {
+ 0xb0, 0x34, 0x4c, 0x61, 0xd8, 0xdb, 0x38, 0x53,
+ 0x5c, 0xa8, 0xaf, 0xce, 0xaf, 0x0b, 0xf1, 0x2b,
+ 0x88, 0x1d, 0xc2, 0x00, 0xc9, 0x83, 0x3d, 0xa7,
+ 0x26, 0xe9, 0x37, 0x6c, 0x2e, 0x32, 0xcf, 0xf7,
+};
+static const UINT8 kHmacSha384[48] = {
+ 0xaf, 0xd0, 0x39, 0x44, 0xd8, 0x48, 0x95, 0x62,
+ 0x6b, 0x08, 0x25, 0xf4, 0xab, 0x46, 0x90, 0x7f,
+ 0x15, 0xf9, 0xda, 0xdb, 0xe4, 0x10, 0x1e, 0xc6,
+ 0x82, 0xaa, 0x03, 0x4c, 0x7c, 0xeb, 0xc5, 0x9c,
+ 0xfa, 0xea, 0x9e, 0xa9, 0x07, 0x6e, 0xde, 0x7f,
+ 0x4a, 0xf1, 0x52, 0xe8, 0xb2, 0xfa, 0x9c, 0xb6,
+};
+static const UINT8 kHmacSha512[64] = {
+ 0x87, 0xaa, 0x7c, 0xde, 0xa5, 0xef, 0x61, 0x9d,
+ 0x4f, 0xf0, 0xb4, 0x24, 0x1a, 0x1d, 0x6c, 0xb0,
+ 0x23, 0x79, 0xf4, 0xe2, 0xce, 0x4e, 0xc2, 0x78,
+ 0x7a, 0xd0, 0xb3, 0x05, 0x45, 0xe1, 0x7c, 0xde,
+ 0xda, 0xa8, 0x33, 0xb7, 0xd6, 0xb8, 0xa7, 0x02,
+ 0x03, 0x8b, 0x27, 0x4e, 0xae, 0xa3, 0xf4, 0xe4,
+ 0xbe, 0x9d, 0x91, 0x4e, 0xeb, 0x61, 0xf1, 0x70,
+ 0x2e, 0x69, 0x6c, 0x20, 0x3a, 0x12, 0x68, 0x54,
+};
+
+/* CMAC-AES-128 (NIST SP 800-38B example 2: Mlen=128) */
+static const UINT8 kCmacMsg[16] = {
+ 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96,
+ 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a,
+};
+static const UINT8 kCmacTag[16] = {
+ 0x07, 0x0a, 0x16, 0xb4, 0x6b, 0x4d, 0x41, 0x44,
+ 0xf7, 0x9b, 0xdd, 0x9d, 0xd0, 0x4a, 0x28, 0x7c,
+};
+
+/* PBKDF2 (wolfSSL test suite vector) */
+static const UINT8 kPbkdf2Salt[8] = { 0x78,0x57,0x8e,0x5a,0x5d,0x63,0xcb,0x06 };
+static const UINT8 kPbkdf2Expected[24] = {
+ 0x43, 0x6d, 0xb5, 0xe8, 0xd0, 0xfb, 0x3f, 0x35,
+ 0x42, 0x48, 0x39, 0xbc, 0x2d, 0xd4, 0xf9, 0x37,
+ 0xd4, 0x95, 0x16, 0xa7, 0x2a, 0x9a, 0x21, 0xd1,
+};
+static const UINT8 kPkcs7Input[] = { 0x61,0x62,0x63,0x64,0x65 };
+static const UINT8 kPkcs7Expected[] = { 0x61,0x62,0x63,0x64,0x65,0x03,0x03,0x03 };
+
+/* RSA-1024 private key DER (wolfSSL test asset) */
+static const UINT8 kRsaKeyDer1024[] = {
+ 0x30,0x82,0x02,0x5D,0x02,0x01,0x00,0x02,0x81,0x81,
+ 0x00,0xBE,0x70,0x70,0xB8,0x04,0x18,0xE5,0x28,0xFE,
+ 0x66,0xD8,0x90,0x88,0xE0,0xF1,0xB7,0xC3,0xD0,0xD2,
+ 0x3E,0xE6,0x4B,0x94,0x74,0xB0,0xFF,0xB0,0xF7,0x63,
+ 0xA5,0xAB,0x7E,0xAF,0xB6,0x2B,0xB7,0x38,0x16,0x1A,
+ 0x50,0xBF,0xF1,0xCA,0x87,0x3A,0xD5,0xB0,0xDA,0xF8,
+ 0x43,0x7A,0x15,0xB9,0x7E,0xEA,0x2A,0x80,0xD2,0x51,
+ 0xB0,0x35,0xAF,0x07,0xF3,0xF2,0x5D,0x24,0x3A,0x4B,
+ 0x87,0x56,0x48,0x1B,0x3C,0x24,0x9A,0xDA,0x70,0x80,
+ 0xBD,0x3C,0x8B,0x03,0x4A,0x0C,0x83,0x71,0xDE,0xE3,
+ 0x03,0x70,0xA2,0xB7,0x60,0x09,0x1B,0x5E,0xC7,0x3D,
+ 0xA0,0x64,0x60,0xE3,0xA9,0x06,0x8D,0xD3,0xFF,0x42,
+ 0xBB,0x0A,0x94,0x27,0x2D,0x57,0x42,0x0D,0xB0,0x2D,
+ 0xE0,0xBA,0x18,0x25,0x60,0x92,0x11,0x92,0xF3,0x02,
+ 0x03,0x01,0x00,0x01,0x02,0x81,0x80,0x0E,0xEE,0x1D,
+ 0xC8,0x2F,0x7A,0x0C,0x2D,0x44,0x94,0xA7,0x91,0xDD,
+ 0x49,0x55,0x6A,0x04,0xCE,0x10,0x4D,0xA2,0x1C,0x76,
+ 0xCD,0x17,0x3B,0x54,0x92,0x70,0x9B,0x82,0x70,0x72,
+ 0x32,0x24,0x07,0x3F,0x3C,0x6C,0x5F,0xBC,0x4C,0xA6,
+ 0x86,0x27,0x94,0xAD,0x42,0xDD,0x87,0xDC,0xC0,0x6B,
+ 0x44,0x89,0xF3,0x3F,0x1A,0x3E,0x11,0x44,0x84,0x2E,
+ 0x69,0x4C,0xBB,0x4A,0x71,0x1A,0xBB,0x9A,0x52,0x3C,
+ 0x6B,0xDE,0xBC,0xB2,0x7C,0x51,0xEF,0x4F,0x8F,0x3A,
+ 0xDC,0x50,0x04,0x4E,0xB6,0x31,0x66,0xA8,0x8E,0x06,
+ 0x3B,0x51,0xA9,0xC1,0x8A,0xCB,0xC4,0x81,0xCA,0x2D,
+ 0x69,0xEC,0x88,0xFC,0x33,0x88,0xD1,0xD4,0x29,0x47,
+ 0x87,0x37,0xF9,0x6A,0x22,0x69,0xB9,0xC9,0xFE,0xEB,
+ 0x8C,0xC5,0x21,0x41,0x71,0x02,0x41,0x00,0xFD,0x17,
+ 0x98,0x42,0x54,0x1C,0x23,0xF8,0xD7,0x5D,0xEF,0x49,
+ 0x4F,0xAF,0xD9,0x35,0x6F,0x08,0xC6,0xC7,0x40,0x5C,
+ 0x7E,0x58,0x86,0xC2,0xB2,0x16,0x39,0x24,0xC5,0x06,
+ 0xB0,0x3D,0xAF,0x02,0xD2,0x87,0x77,0xD2,0x76,0xBA,
+ 0xE3,0x59,0x60,0x42,0xF1,0x16,0xEF,0x33,0x0B,0xF2,
+ 0x0B,0xBA,0x99,0xCC,0xB6,0x4C,0x46,0x3F,0x33,0xE4,
+ 0xD4,0x67,0x02,0x41,0x00,0xC0,0xA0,0x91,0x6D,0xFE,
+ 0x28,0xE0,0x81,0x5A,0x15,0xA7,0xC9,0xA8,0x98,0xC6,
+ 0x0A,0xAB,0x00,0xC5,0x40,0xC9,0x21,0xBB,0xB2,0x33,
+ 0x5A,0xA7,0xCB,0x6E,0xB8,0x08,0x56,0x4A,0x76,0x28,
+ 0xE8,0x6D,0xBD,0xF5,0x26,0x7B,0xBF,0xC5,0x46,0x45,
+ 0x0D,0xEC,0x7D,0xEE,0x82,0xD6,0xCA,0x5F,0x3D,0x6E,
+ 0xCC,0x94,0x73,0xCD,0xCE,0x86,0x6E,0x95,0x95,0x02,
+ 0x40,0x38,0xFD,0x28,0x1E,0xBF,0x5B,0xBA,0xC9,0xDC,
+ 0x8C,0xDD,0x45,0xAF,0xB8,0xD3,0xFB,0x11,0x2E,0x73,
+ 0xBC,0x08,0x05,0x0B,0xBA,0x19,0x56,0x1B,0xCD,0x9F,
+ 0x3E,0x65,0x53,0x15,0x3A,0x3E,0x7F,0x2F,0x32,0xAB,
+ 0xCB,0x6B,0x4A,0xB7,0xC8,0xB7,0x41,0x3B,0x92,0x43,
+ 0x78,0x46,0x17,0x51,0x86,0xC9,0xFC,0xEB,0x8B,0x8F,
+ 0x41,0xCA,0x08,0x9B,0xBF,0x02,0x41,0x00,0xAD,0x9B,
+ 0x89,0xB6,0xF2,0x8C,0x70,0xDA,0xE4,0x10,0x04,0x6B,
+ 0x11,0x92,0xAF,0x5A,0xCA,0x08,0x25,0xBF,0x60,0x07,
+ 0x11,0x1D,0x68,0x7F,0x5A,0x1F,0x55,0x28,0x74,0x0B,
+ 0x21,0x8D,0x21,0x0D,0x6A,0x6A,0xFB,0xD9,0xB5,0x4A,
+ 0x7F,0x47,0xF7,0xD0,0xB6,0xC6,0x41,0x02,0x97,0x07,
+ 0x49,0x93,0x1A,0x9B,0x33,0x68,0xB3,0xA2,0x61,0x32,
+ 0xA5,0x89,0x02,0x41,0x00,0x8F,0xEF,0xAD,0xB5,0xB0,
+ 0xB0,0x7E,0x86,0x03,0x43,0x93,0x6E,0xDD,0x3C,0x2D,
+ 0x9B,0x6A,0x55,0xFF,0x6F,0x3E,0x70,0x2A,0xD4,0xBF,
+ 0x1F,0x8C,0x93,0x60,0x9E,0x6D,0x2F,0x18,0x6C,0x11,
+ 0x36,0x98,0x3F,0x10,0x78,0xE8,0x3E,0x8F,0xFE,0x55,
+ 0xB9,0x9E,0xD5,0x5B,0x2E,0x87,0x1C,0x58,0xD0,0x37,
+ 0x89,0x96,0xEC,0x48,0x54,0xF5,0x9F,0x0F,0xB3,
+};
+static const UINT8 kRsaCiphertext[128] = {
+ 0x01,0x0c,0x1f,0xaf,0x1b,0x3c,0x5d,0xb6,0x6f,0x44,0xc5,0x6a,
+ 0xf6,0xbb,0x2c,0x52,0x36,0xd7,0x21,0xa2,0x25,0x41,0x28,0x36,
+ 0x0b,0xd8,0xa3,0xcd,0x74,0x43,0xe0,0xc3,0x76,0x73,0x3c,0x2b,
+ 0x96,0x93,0x68,0xfd,0x33,0x86,0xa6,0x09,0x39,0x14,0x6c,0x7b,
+ 0x9e,0xf5,0x68,0xf0,0x59,0x2d,0x0e,0x73,0xe3,0x12,0xf3,0xff,
+ 0xdb,0xce,0x31,0x37,0x54,0x30,0x36,0x57,0x7a,0x40,0xe4,0x34,
+ 0x43,0xa9,0x2f,0x33,0x57,0x38,0xc1,0x55,0x59,0x0b,0x68,0x4d,
+ 0x90,0x2a,0xd1,0x94,0x70,0x81,0x51,0x61,0xfb,0x85,0x96,0x1d,
+ 0x79,0x85,0x43,0xb1,0x4c,0x3b,0x57,0xff,0x57,0xa5,0x7d,0x58,
+ 0xaf,0xcd,0x61,0x74,0xae,0xe0,0xe8,0x22,0x52,0x12,0x91,0xf1,
+ 0x75,0xe4,0x16,0x47,0x40,0xd2,0x47,0xa1,
+};
+static const UINT8 kRsaPlain[] = { 'w','o','l','f','C','r','y','p','t' };
+
+/* ML-KEM Kyber512 deterministic seeds */
+#if defined(WOLFSSL_HAVE_MLKEM)
+static const UINT8 kyber512_rand[] = {
+ 0x7c,0x99,0x35,0xa0,0xb0,0x76,0x94,0xaa,
+ 0x0c,0x6d,0x10,0xe4,0xdb,0x6b,0x1a,0xdd,
+ 0x2f,0xd8,0x1a,0x25,0xcc,0xb1,0x48,0x03,
+ 0x2d,0xcd,0x73,0x99,0x36,0x73,0x7f,0x2d,
+ 0x86,0x26,0xed,0x79,0xd4,0x51,0x14,0x08,
+ 0x00,0xe0,0x3b,0x59,0xb9,0x56,0xf8,0x21,
+ 0x0e,0x55,0x60,0x67,0x40,0x7d,0x13,0xdc,
+ 0x90,0xfa,0x9e,0x8b,0x87,0x2b,0xfb,0x8f,
+};
+static const UINT8 kyber512enc_rand[] = {
+ 0x14,0x7c,0x03,0xf7,0xa5,0xbe,0xbb,0xa4,
+ 0x06,0xc8,0xfa,0xe1,0x87,0x4d,0x7f,0x13,
+ 0xc8,0x0e,0xfe,0x79,0xa3,0xa9,0xa8,0x74,
+ 0xcc,0x09,0xfe,0x76,0xf6,0x99,0x76,0x15,
+};
+#endif
+
+/* Deterministic RNG seed */
+static const UINT8 kDeterministicSeed[32] = {
+ 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
+ 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,
+ 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
+ 0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,
+};
+
+/* ------------------------------------------------------------------ */
+/* Helpers */
+/* ------------------------------------------------------------------ */
+static EFI_STATUS CheckWolfResult(int ret, const CHAR16 *label)
+{
+ if (ret == 0) return EFI_SUCCESS;
+ const char *err = (Api && Api->wc_GetErrorString) ?
+ Api->wc_GetErrorString(ret) : NULL;
+ if (err) Print(L"%s failed: %d (%a)\n", label, ret, err);
+ else Print(L"%s failed: %d\n", label, ret);
+ return EFI_ABORTED;
+}
+
+static EFI_STATUS CheckCondition(BOOLEAN cond, const CHAR16 *label)
+{
+ if (cond) return EFI_SUCCESS;
+ Print(L"%s check failed\n", label);
+ return EFI_ABORTED;
+}
+
+static BOOLEAN BuffersEqual(const UINT8 *a, const UINT8 *b, UINTN len)
+{
+ return CompareMem(a, b, len) == 0;
+}
+
+static VOID CopyBytes(UINT8 *dst, const UINT8 *src, UINTN len)
+{
+ for (UINTN i = 0; i < len; ++i) dst[i] = src[i];
+}
+
+static UINTN NonZeroCount(const UINT8 *buf, UINTN len)
+{
+ UINTN n = 0;
+ for (UINTN i = 0; i < len; ++i) if (buf[i]) ++n;
+ return n;
+}
+
+static BOOLEAN IsOptionalRngError(int ret)
+{
+ return (ret == NOT_COMPILED_IN) || (ret == WC_HW_E) ||
+ (ret == BAD_FUNC_ARG) || (ret == RNG_FAILURE_E);
+}
+
+static int EFIAPI DeterministicSeedCb(OS_Seed *os, byte *seed, word32 sz)
+{
+ (void)os;
+ for (word32 i = 0; i < sz; ++i) seed[i] = (byte)(i & 0xff);
+ return 0;
+}
+
+/* Init RNG with deterministic seed callback; clears callback on return. */
+static int InitRngDet(WC_RNG *rng)
+{
+ Api->wc_SetSeed_Cb(DeterministicSeedCb);
+ int ret = Api->wc_InitRng(rng);
+ Api->wc_SetSeed_Cb(NULL);
+ return ret;
+}
+
+/* ------------------------------------------------------------------ */
+/* AES: ECB, CBC, CFB, CTR, GCM, CCM, OFB */
+/* ------------------------------------------------------------------ */
+static EFI_STATUS TestAes(void)
+{
+ EFI_STATUS status;
+ int ret;
+ Aes aes;
+ UINT8 buf[32];
+ UINT8 tag[16];
+ UINT8 plain[16];
+
+ ZeroMem(&aes, sizeof(aes));
+
+ ret = Api->wc_AesInit(&aes, NULL, INVALID_DEVID);
+ status = CheckWolfResult(ret, L"wc_AesInit");
+ if (EFI_ERROR(status)) return status;
+
+ /* ECB */
+ ret = Api->wc_AesSetKey(&aes, kAesKey128, 16, NULL, AES_ENCRYPTION);
+ status = CheckWolfResult(ret, L"AesSetKey ECB enc");
+ if (EFI_ERROR(status)) goto done;
+ CopyBytes(buf, kAesPlain, 16);
+ ret = Api->wc_AesEcbEncrypt(&aes, buf, buf, 16);
+ status = CheckWolfResult(ret, L"AesEcbEncrypt");
+ if (EFI_ERROR(status)) goto done;
+ status = CheckCondition(BuffersEqual(buf, kAesEcbCipher, 16), L"AES-ECB enc KAT");
+ if (EFI_ERROR(status)) goto done;
+
+ ret = Api->wc_AesSetKey(&aes, kAesKey128, 16, NULL, AES_DECRYPTION);
+ status = CheckWolfResult(ret, L"AesSetKey ECB dec");
+ if (EFI_ERROR(status)) goto done;
+ ret = Api->wc_AesEcbDecrypt(&aes, buf, buf, 16);
+ status = CheckWolfResult(ret, L"AesEcbDecrypt");
+ if (EFI_ERROR(status)) goto done;
+ status = CheckCondition(BuffersEqual(buf, kAesPlain, 16), L"AES-ECB dec KAT");
+ if (EFI_ERROR(status)) goto done;
+
+ /* CBC */
+ ret = Api->wc_AesSetKey(&aes, kAesKey128, 16, kAesIv128, AES_ENCRYPTION);
+ status = CheckWolfResult(ret, L"AesSetKey CBC enc");
+ if (EFI_ERROR(status)) goto done;
+ ret = Api->wc_AesCbcEncrypt(&aes, buf, kAesPlain, 16);
+ status = CheckWolfResult(ret, L"AesCbcEncrypt");
+ if (EFI_ERROR(status)) goto done;
+ status = CheckCondition(BuffersEqual(buf, kAesCbcCipher, 16), L"AES-CBC enc KAT");
+ if (EFI_ERROR(status)) goto done;
+
+ ret = Api->wc_AesSetKey(&aes, kAesKey128, 16, kAesIv128, AES_DECRYPTION);
+ status = CheckWolfResult(ret, L"AesSetKey CBC dec");
+ if (EFI_ERROR(status)) goto done;
+ ret = Api->wc_AesCbcDecrypt(&aes, buf, buf, 16);
+ status = CheckWolfResult(ret, L"AesCbcDecrypt");
+ if (EFI_ERROR(status)) goto done;
+ status = CheckCondition(BuffersEqual(buf, kAesPlain, 16), L"AES-CBC dec KAT");
+ if (EFI_ERROR(status)) goto done;
+
+ /* CFB */
+ ret = Api->wc_AesSetKey(&aes, kAesKey128, 16, kAesIv128, AES_ENCRYPTION);
+ status = CheckWolfResult(ret, L"AesSetKey CFB");
+ if (EFI_ERROR(status)) goto done;
+ CopyBytes(buf, kAesPlain, 16);
+ ret = Api->wc_AesCfbEncrypt(&aes, buf, buf, 16);
+ status = CheckWolfResult(ret, L"AesCfbEncrypt");
+ if (EFI_ERROR(status)) goto done;
+ status = CheckCondition(BuffersEqual(buf, kAesCfbCipher, 16), L"AES-CFB enc KAT");
+ if (EFI_ERROR(status)) goto done;
+ ret = Api->wc_AesSetIV(&aes, kAesIv128);
+ status = CheckWolfResult(ret, L"AesSetIV");
+ if (EFI_ERROR(status)) goto done;
+ ret = Api->wc_AesCfbDecrypt(&aes, buf, buf, 16);
+ status = CheckWolfResult(ret, L"AesCfbDecrypt");
+ if (EFI_ERROR(status)) goto done;
+ status = CheckCondition(BuffersEqual(buf, kAesPlain, 16), L"AES-CFB dec KAT");
+ if (EFI_ERROR(status)) goto done;
+
+ /* CTR */
+ ret = Api->wc_AesSetKey(&aes, kAesKey128, 16, kAesCtrIv, AES_ENCRYPTION);
+ status = CheckWolfResult(ret, L"AesSetKey CTR");
+ if (EFI_ERROR(status)) goto done;
+ ret = Api->wc_AesCtrEncrypt(&aes, buf, kAesPlain, 16);
+ status = CheckWolfResult(ret, L"AesCtrEncrypt");
+ if (EFI_ERROR(status)) goto done;
+ status = CheckCondition(BuffersEqual(buf, kAesCtrCipher, 16), L"AES-CTR enc KAT");
+ if (EFI_ERROR(status)) goto done;
+ /* CTR decrypt == encrypt */
+ ret = Api->wc_AesSetKey(&aes, kAesKey128, 16, kAesCtrIv, AES_ENCRYPTION);
+ status = CheckWolfResult(ret, L"AesSetKey CTR dec");
+ if (EFI_ERROR(status)) goto done;
+ ret = Api->wc_AesCtrEncrypt(&aes, plain, buf, 16);
+ status = CheckWolfResult(ret, L"AesCtrEncrypt dec");
+ if (EFI_ERROR(status)) goto done;
+ status = CheckCondition(BuffersEqual(plain, kAesPlain, 16), L"AES-CTR dec KAT");
+ if (EFI_ERROR(status)) goto done;
+
+ /* GCM — round-trip (12-byte IV, no AAD) */
+ {
+ UINT8 gcmIv[12];
+ UINT8 gcmCt[16];
+ UINT8 gcmPt[16];
+ UINT8 gcmTag[16];
+ ZeroMem(gcmIv, sizeof(gcmIv));
+ ret = Api->wc_AesGcmSetKey(&aes, kAesKey128, 16);
+ status = CheckWolfResult(ret, L"AesGcmSetKey");
+ if (EFI_ERROR(status)) goto done;
+ ret = Api->wc_AesGcmEncrypt(&aes, gcmCt, kAesPlain, 16,
+ gcmIv, 12, gcmTag, 16, NULL, 0);
+ status = CheckWolfResult(ret, L"AesGcmEncrypt");
+ if (EFI_ERROR(status)) goto done;
+ ret = Api->wc_AesGcmDecrypt(&aes, gcmPt, gcmCt, 16,
+ gcmIv, 12, gcmTag, 16, NULL, 0);
+ status = CheckWolfResult(ret, L"AesGcmDecrypt");
+ if (EFI_ERROR(status)) goto done;
+ status = CheckCondition(BuffersEqual(gcmPt, kAesPlain, 16), L"AES-GCM round-trip");
+ if (EFI_ERROR(status)) goto done;
+ }
+
+ /* CCM — round-trip (12-byte nonce, no AAD) */
+ {
+ UINT8 ccmNonce[12];
+ UINT8 ccmCt[16];
+ UINT8 ccmPt[16];
+ UINT8 ccmTag[8];
+ ZeroMem(ccmNonce, sizeof(ccmNonce));
+ ret = Api->wc_AesCcmSetKey(&aes, kAesKey128, 16);
+ status = CheckWolfResult(ret, L"AesCcmSetKey");
+ if (EFI_ERROR(status)) goto done;
+ ret = Api->wc_AesCcmEncrypt(&aes, ccmCt, kAesPlain, 16,
+ ccmNonce, 12, ccmTag, 8, NULL, 0);
+ status = CheckWolfResult(ret, L"AesCcmEncrypt");
+ if (EFI_ERROR(status)) goto done;
+ ret = Api->wc_AesCcmDecrypt(&aes, ccmPt, ccmCt, 16,
+ ccmNonce, 12, ccmTag, 8, NULL, 0);
+ status = CheckWolfResult(ret, L"AesCcmDecrypt");
+ if (EFI_ERROR(status)) goto done;
+ status = CheckCondition(BuffersEqual(ccmPt, kAesPlain, 16), L"AES-CCM round-trip");
+ if (EFI_ERROR(status)) goto done;
+ }
+
+ /* OFB — round-trip */
+ {
+ UINT8 ofbCt[16];
+ UINT8 ofbPt[16];
+ ret = Api->wc_AesSetKey(&aes, kAesKey128, 16, kAesIv128, AES_ENCRYPTION);
+ status = CheckWolfResult(ret, L"AesSetKey OFB enc");
+ if (EFI_ERROR(status)) goto done;
+ ret = Api->wc_AesOfbEncrypt(&aes, ofbCt, kAesPlain, 16);
+ status = CheckWolfResult(ret, L"AesOfbEncrypt");
+ if (EFI_ERROR(status)) goto done;
+ ret = Api->wc_AesSetKey(&aes, kAesKey128, 16, kAesIv128, AES_ENCRYPTION);
+ status = CheckWolfResult(ret, L"AesSetKey OFB dec");
+ if (EFI_ERROR(status)) goto done;
+ ret = Api->wc_AesOfbEncrypt(&aes, ofbPt, ofbCt, 16);
+ status = CheckWolfResult(ret, L"AesOfbEncrypt dec");
+ if (EFI_ERROR(status)) goto done;
+ status = CheckCondition(BuffersEqual(ofbPt, kAesPlain, 16), L"AES-OFB round-trip");
+ if (EFI_ERROR(status)) goto done;
+ }
+
+ (void)tag; (void)plain;
+
+done:
+ Api->wc_AesFree(&aes);
+ return status;
+}
+
+/* ------------------------------------------------------------------ */
+/* SHA: 1, 224, 256, 384, 512, SHA-3 (256/384/512), SHAKE-128/256 */
+/* ------------------------------------------------------------------ */
+static EFI_STATUS TestSha(void)
+{
+ EFI_STATUS status;
+ int ret;
+ UINT8 digest[WC_SHA3_512_DIGEST_SIZE];
+ wc_Sha sha1;
+ wc_Sha224 sha224;
+ wc_Sha256 sha256;
+ wc_Sha384 sha384;
+ wc_Sha512 sha512;
+ wc_Sha3 sha3;
+ wc_Shake shake;
+
+#define SHA_TEST(init_fn, update_fn, final_fn, free_fn, ctx, dgst, expect, sz, label) \
+ ret = Api->init_fn(&ctx); \
+ status = CheckWolfResult(ret, L ## label " Init"); \
+ if (EFI_ERROR(status)) return status; \
+ ret = Api->update_fn(&ctx, kShaMsg, (word32)sizeof(kShaMsg)); \
+ status = CheckWolfResult(ret, L ## label " Update"); \
+ if (EFI_ERROR(status)) { Api->free_fn(&ctx); return status; } \
+ ret = Api->final_fn(&ctx, dgst); \
+ Api->free_fn(&ctx); \
+ status = CheckWolfResult(ret, L ## label " Final"); \
+ if (EFI_ERROR(status)) return status; \
+ status = CheckCondition(BuffersEqual(dgst, expect, sz), L ## label " KAT"); \
+ if (EFI_ERROR(status)) return status;
+
+ SHA_TEST(wc_InitSha, wc_ShaUpdate, wc_ShaFinal, wc_ShaFree, sha1, digest, kSha1Digest, 20, "SHA-1")
+ SHA_TEST(wc_InitSha224, wc_Sha224Update, wc_Sha224Final, wc_Sha224Free, sha224, digest, kSha224Digest, 28, "SHA-224")
+ SHA_TEST(wc_InitSha256, wc_Sha256Update, wc_Sha256Final, wc_Sha256Free, sha256, digest, kSha256Digest, 32, "SHA-256")
+ SHA_TEST(wc_InitSha384, wc_Sha384Update, wc_Sha384Final, wc_Sha384Free, sha384, digest, kSha384Digest, 48, "SHA-384")
+ SHA_TEST(wc_InitSha512, wc_Sha512Update, wc_Sha512Final, wc_Sha512Free, sha512, digest, kSha512Digest, 64, "SHA-512")
+#define SHA3_TEST(init_fn, update_fn, final_fn, free_fn, dgst, expect, sz, label) \
+ ret = Api->init_fn(&sha3, NULL, INVALID_DEVID); \
+ status = CheckWolfResult(ret, L ## label " Init"); \
+ if (EFI_ERROR(status)) return status; \
+ ret = Api->update_fn(&sha3, kShaMsg, (word32)sizeof(kShaMsg)); \
+ status = CheckWolfResult(ret, L ## label " Update"); \
+ if (EFI_ERROR(status)) { Api->free_fn(&sha3); return status; } \
+ ret = Api->final_fn(&sha3, dgst); \
+ Api->free_fn(&sha3); \
+ status = CheckWolfResult(ret, L ## label " Final"); \
+ if (EFI_ERROR(status)) return status; \
+ status = CheckCondition(BuffersEqual(dgst, expect, sz), L ## label " KAT"); \
+ if (EFI_ERROR(status)) return status;
+
+ SHA3_TEST(wc_InitSha3_256, wc_Sha3_256_Update, wc_Sha3_256_Final, wc_Sha3_256_Free, digest, kSha3_256Digest, 32, "SHA3-256")
+ SHA3_TEST(wc_InitSha3_384, wc_Sha3_384_Update, wc_Sha3_384_Final, wc_Sha3_384_Free, digest, kSha3_384Digest, 48, "SHA3-384")
+ SHA3_TEST(wc_InitSha3_512, wc_Sha3_512_Update, wc_Sha3_512_Final, wc_Sha3_512_Free, digest, kSha3_512Digest, 64, "SHA3-512")
+#undef SHA3_TEST
+#undef SHA_TEST
+
+ /* SHAKE-128: produce 32 bytes, check non-zero */
+ ret = Api->wc_InitShake128(&shake, NULL, INVALID_DEVID);
+ status = CheckWolfResult(ret, L"SHAKE128 Init");
+ if (EFI_ERROR(status)) return status;
+ ret = Api->wc_Shake128_Update(&shake, kShaMsg, (word32)sizeof(kShaMsg));
+ status = CheckWolfResult(ret, L"SHAKE128 Update");
+ if (EFI_ERROR(status)) { Api->wc_Shake128_Free(&shake); return status; }
+ ret = Api->wc_Shake128_Final(&shake, digest, 32);
+ Api->wc_Shake128_Free(&shake);
+ status = CheckWolfResult(ret, L"SHAKE128 Final");
+ if (EFI_ERROR(status)) return status;
+ status = CheckCondition(NonZeroCount(digest, 32) > 0, L"SHAKE128 output");
+ if (EFI_ERROR(status)) return status;
+
+ /* SHAKE-256: produce 64 bytes, check non-zero */
+ ret = Api->wc_InitShake256(&shake, NULL, INVALID_DEVID);
+ status = CheckWolfResult(ret, L"SHAKE256 Init");
+ if (EFI_ERROR(status)) return status;
+ ret = Api->wc_Shake256_Update(&shake, kShaMsg, (word32)sizeof(kShaMsg));
+ status = CheckWolfResult(ret, L"SHAKE256 Update");
+ if (EFI_ERROR(status)) { Api->wc_Shake256_Free(&shake); return status; }
+ ret = Api->wc_Shake256_Final(&shake, digest, 64);
+ Api->wc_Shake256_Free(&shake);
+ status = CheckWolfResult(ret, L"SHAKE256 Final");
+ if (EFI_ERROR(status)) return status;
+ status = CheckCondition(NonZeroCount(digest, 64) > 0, L"SHAKE256 output");
+
+ return status;
+}
+
+/* ------------------------------------------------------------------ */
+/* HMAC: SHA-256 (KAT), SHA-384 (KAT), SHA-512 (KAT) */
+/* ------------------------------------------------------------------ */
+static EFI_STATUS TestHmac(void)
+{
+ EFI_STATUS status;
+ int ret;
+ Hmac hmac;
+ UINT8 digest[WC_SHA512_DIGEST_SIZE];
+
+ ZeroMem(&hmac, sizeof(hmac));
+
+#define HMAC_TEST(hashtype, expected, sz, label) \
+ ret = Api->wc_HmacSetKey(&hmac, hashtype, kHmacKey, (word32)sizeof(kHmacKey)); \
+ status = CheckWolfResult(ret, L ## label " HmacSetKey"); \
+ if (EFI_ERROR(status)) return status; \
+ ret = Api->wc_HmacUpdate(&hmac, kHmacMsg, (word32)sizeof(kHmacMsg) - 1); \
+ status = CheckWolfResult(ret, L ## label " HmacUpdate"); \
+ if (EFI_ERROR(status)) return status; \
+ ret = Api->wc_HmacFinal(&hmac, digest); \
+ status = CheckWolfResult(ret, L ## label " HmacFinal"); \
+ if (EFI_ERROR(status)) return status; \
+ status = CheckCondition(BuffersEqual(digest, expected, sz), L ## label " KAT"); \
+ if (EFI_ERROR(status)) return status;
+
+ HMAC_TEST(WC_SHA256, kHmacSha256, 32, "HMAC-SHA256")
+ HMAC_TEST(WC_SHA384, kHmacSha384, 48, "HMAC-SHA384")
+ HMAC_TEST(WC_SHA512, kHmacSha512, 64, "HMAC-SHA512")
+#undef HMAC_TEST
+
+ return EFI_SUCCESS;
+}
+
+/* ------------------------------------------------------------------ */
+/* CMAC-AES-128 (NIST SP 800-38B example 2) */
+/* ------------------------------------------------------------------ */
+static EFI_STATUS TestCmac(void)
+{
+ EFI_STATUS status;
+ int ret;
+ Cmac cmac;
+ UINT8 tag[AES_BLOCK_SIZE];
+ word32 tagSz = sizeof(tag);
+
+ ZeroMem(&cmac, sizeof(cmac));
+
+ ret = Api->wc_InitCmac(&cmac, kAesKey128, (word32)sizeof(kAesKey128),
+ WC_CMAC_AES, NULL);
+ status = CheckWolfResult(ret, L"wc_InitCmac");
+ if (EFI_ERROR(status)) return status;
+
+ ret = Api->wc_CmacUpdate(&cmac, kCmacMsg, (word32)sizeof(kCmacMsg));
+ status = CheckWolfResult(ret, L"wc_CmacUpdate");
+ if (EFI_ERROR(status)) return status;
+
+ ret = Api->wc_CmacFinal(&cmac, tag, &tagSz);
+ status = CheckWolfResult(ret, L"wc_CmacFinal");
+ if (EFI_ERROR(status)) return status;
+
+ status = CheckCondition(tagSz == AES_BLOCK_SIZE &&
+ BuffersEqual(tag, kCmacTag, AES_BLOCK_SIZE),
+ L"CMAC-AES-128 KAT");
+ return status;
+}
+
+/* ------------------------------------------------------------------ */
+/* KDF: PBKDF2, PKCS12-PBKDF, PKCS7-PadData, HKDF */
+/* ------------------------------------------------------------------ */
+static EFI_STATUS TestKdf(void)
+{
+ EFI_STATUS status;
+ int ret;
+ UINT8 derived[64];
+ UINT8 padded[16];
+ const char passwd[] = "passwordpassword";
+
+ /* PBKDF2-SHA256 */
+ ret = Api->wc_PBKDF2(derived, (const byte *)passwd, (int)(sizeof(passwd)-1),
+ kPbkdf2Salt, (int)sizeof(kPbkdf2Salt), 2048,
+ (int)sizeof(kPbkdf2Expected), WC_SHA256);
+ status = CheckWolfResult(ret, L"wc_PBKDF2");
+ if (EFI_ERROR(status)) return status;
+ status = CheckCondition(BuffersEqual(derived, kPbkdf2Expected,
+ sizeof(kPbkdf2Expected)), L"PBKDF2 KAT");
+ if (EFI_ERROR(status)) return status;
+
+ /* PKCS7 padding */
+ ret = Api->wc_PKCS7_PadData((byte *)kPkcs7Input, (word32)sizeof(kPkcs7Input),
+ padded, (word32)sizeof(padded), 8);
+ if (ret < 0) return CheckWolfResult(ret, L"wc_PKCS7_PadData");
+ status = CheckCondition((ret == (int)sizeof(kPkcs7Expected)) &&
+ BuffersEqual(padded, kPkcs7Expected, sizeof(kPkcs7Expected)),
+ L"PKCS7 pad KAT");
+ if (EFI_ERROR(status)) return status;
+
+ /* HKDF — RFC 5869 test case 1 (SHA-256) */
+ {
+ static const UINT8 hkdfIkm[22] = { 0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b };
+ static const UINT8 hkdfSalt[13] = { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c };
+ static const UINT8 hkdfInfo[10] = { 0xf0,0xf1,0xf2,0xf3,0xf4,0xf5,0xf6,0xf7,0xf8,0xf9 };
+ static const UINT8 hkdfOkm[42] = {
+ 0x3c,0xb2,0x5f,0x25,0xfa,0xac,0xd5,0x7a,0x90,0x43,0x4f,0x64,0xd0,0x36,0x2f,0x2a,
+ 0x2d,0x2d,0x0a,0x90,0xcf,0x1a,0x5a,0x4c,0x5d,0xb0,0x2d,0x56,0xec,0xc4,0xc5,0xbf,
+ 0x34,0x00,0x72,0x08,0xd5,0xb8,0x87,0x18,0x58,0x65,
+ };
+ ret = Api->wc_HKDF(WC_SHA256,
+ hkdfIkm, (word32)sizeof(hkdfIkm),
+ hkdfSalt, (word32)sizeof(hkdfSalt),
+ hkdfInfo, (word32)sizeof(hkdfInfo),
+ derived, (word32)sizeof(hkdfOkm));
+ status = CheckWolfResult(ret, L"wc_HKDF");
+ if (EFI_ERROR(status)) return status;
+ status = CheckCondition(BuffersEqual(derived, hkdfOkm, sizeof(hkdfOkm)),
+ L"HKDF RFC5869 TC1 KAT");
+ if (EFI_ERROR(status)) return status;
+ }
+
+ return EFI_SUCCESS;
+}
+
+/* ------------------------------------------------------------------ */
+/* RNG */
+/* ------------------------------------------------------------------ */
+static EFI_STATUS TestRng(void)
+{
+ EFI_STATUS status;
+ int ret;
+ WC_RNG rng;
+ UINT8 block[32];
+ byte single;
+ OS_Seed os;
+
+ ZeroMem(&rng, sizeof(rng));
+
+ ret = InitRngDet(&rng);
+ status = CheckWolfResult(ret, L"wc_InitRng");
+ if (EFI_ERROR(status)) return status;
+
+ ret = Api->wc_RNG_TestSeed(kDeterministicSeed, (word32)sizeof(kDeterministicSeed));
+ status = CheckWolfResult(ret, L"wc_RNG_TestSeed");
+ if (EFI_ERROR(status)) { Api->wc_FreeRng(&rng); return status; }
+
+ ret = Api->wc_RNG_GenerateBlock(&rng, block, (word32)sizeof(block));
+ status = CheckWolfResult(ret, L"wc_RNG_GenerateBlock");
+ if (EFI_ERROR(status)) { Api->wc_FreeRng(&rng); return status; }
+ status = CheckCondition(NonZeroCount(block, sizeof(block)) > 0, L"RNG entropy");
+ if (EFI_ERROR(status)) { Api->wc_FreeRng(&rng); return status; }
+
+ ret = Api->wc_RNG_GenerateByte(&rng, &single);
+ status = CheckWolfResult(ret, L"wc_RNG_GenerateByte");
+ Api->wc_FreeRng(&rng);
+ if (EFI_ERROR(status)) return status;
+
+ /* Optional platform seed paths */
+ ZeroMem(&os, sizeof(os));
+ ret = Api->wc_GenerateSeed(&os, block, 16);
+ if (ret != 0 && !IsOptionalRngError(ret))
+ return CheckWolfResult(ret, L"wc_GenerateSeed");
+
+ ret = Api->wc_GenerateSeed_IntelRD(&os, block, 16);
+ if (ret != 0 && !IsOptionalRngError(ret))
+ return CheckWolfResult(ret, L"wc_GenerateSeed_IntelRD");
+
+ return EFI_SUCCESS;
+}
+
+/* ------------------------------------------------------------------ */
+/* RSA: decode, decrypt KAT, encrypt/decrypt round-trip, keygen */
+/* ------------------------------------------------------------------ */
+static EFI_STATUS TestRsa(void)
+{
+ EFI_STATUS status = EFI_SUCCESS;
+ int ret;
+ WC_RNG rng;
+ RsaKey key, pubKey, genKey;
+ BOOLEAN rngInit = FALSE, keyInit = FALSE, pubInit = FALSE, genInit = FALSE;
+ UINT8 buffer[sizeof(kRsaKeyDer1024)];
+ UINT8 cipher[sizeof(kRsaCiphertext)];
+ UINT8 plain[sizeof(kRsaCiphertext)];
+ word32 idx;
+ int cipherLen;
+ const UINT8 sample[] = "wolfSSL RSA";
+
+ ZeroMem(&rng, sizeof(rng)); ZeroMem(&key, sizeof(key));
+ ZeroMem(&pubKey, sizeof(pubKey)); ZeroMem(&genKey, sizeof(genKey));
+
+ ret = Api->wc_InitRsaKey(&key, NULL);
+ status = CheckWolfResult(ret, L"wc_InitRsaKey"); if (EFI_ERROR(status)) goto cleanup;
+ keyInit = TRUE;
+
+ idx = 0;
+ ret = Api->wc_RsaPrivateKeyDecode(kRsaKeyDer1024, &idx, &key, (word32)sizeof(kRsaKeyDer1024));
+ status = CheckWolfResult(ret, L"wc_RsaPrivateKeyDecode"); if (EFI_ERROR(status)) goto cleanup;
+
+ ret = InitRngDet(&rng);
+ if (ret == 0) {
+ rngInit = TRUE;
+ ret = Api->wc_RNG_TestSeed(kDeterministicSeed, (word32)sizeof(kDeterministicSeed));
+ status = CheckWolfResult(ret, L"wc_RNG_TestSeed RSA"); if (EFI_ERROR(status)) goto cleanup;
+
+ ret = Api->wc_RsaSetRNG(&key, &rng);
+ status = CheckWolfResult(ret, L"wc_RsaSetRNG"); if (EFI_ERROR(status)) goto cleanup;
+ } else if (IsOptionalRngError(ret)) {
+ status = EFI_UNSUPPORTED; goto cleanup;
+ } else {
+ status = CheckWolfResult(ret, L"wc_InitRng RSA"); goto cleanup;
+ }
+
+ ret = Api->wc_CheckRsaKey(&key);
+ status = CheckWolfResult(ret, L"wc_CheckRsaKey"); if (EFI_ERROR(status)) goto cleanup;
+
+ cipherLen = Api->wc_RsaEncryptSize(&key);
+ status = CheckCondition(cipherLen == (int)sizeof(kRsaCiphertext), L"wc_RsaEncryptSize");
+ if (EFI_ERROR(status)) goto cleanup;
+
+ /* DER re-encode */
+ ret = Api->wc_RsaKeyToDer(&key, buffer, (word32)sizeof(buffer));
+ if (ret < 0) { status = CheckWolfResult(ret, L"wc_RsaKeyToDer"); goto cleanup; }
+ status = CheckCondition((ret == (int)sizeof(kRsaKeyDer1024)) &&
+ BuffersEqual(buffer, kRsaKeyDer1024, sizeof(kRsaKeyDer1024)),
+ L"RSA DER re-encode");
+ if (EFI_ERROR(status)) goto cleanup;
+
+ /* Deterministic decrypt KAT */
+ ret = Api->wc_RsaPrivateDecrypt(kRsaCiphertext, (word32)sizeof(kRsaCiphertext),
+ plain, (word32)sizeof(plain), &key);
+ if (ret < 0) { status = CheckWolfResult(ret, L"wc_RsaPrivateDecrypt KAT"); goto cleanup; }
+ status = CheckCondition((ret == (int)sizeof(kRsaPlain)) &&
+ BuffersEqual(plain, kRsaPlain, sizeof(kRsaPlain)),
+ L"RSA decrypt KAT");
+ if (EFI_ERROR(status)) goto cleanup;
+
+ /* Encrypt / decrypt round-trip */
+ ret = Api->wc_RsaPublicEncrypt(sample, (word32)(sizeof(sample)-1),
+ cipher, (word32)sizeof(cipher), &key, &rng);
+ if (ret < 0) { status = CheckWolfResult(ret, L"wc_RsaPublicEncrypt"); goto cleanup; }
+ cipherLen = ret;
+ ret = Api->wc_RsaPrivateDecrypt(cipher, (word32)cipherLen,
+ plain, (word32)sizeof(plain), &key);
+ if (ret < 0) { status = CheckWolfResult(ret, L"wc_RsaPrivateDecrypt round-trip"); goto cleanup; }
+ status = CheckCondition((ret == (int)(sizeof(sample)-1)) &&
+ BuffersEqual(plain, sample, sizeof(sample)-1),
+ L"RSA round-trip");
+ if (EFI_ERROR(status)) goto cleanup;
+
+ /* Export public DER, re-import, encrypt with public */
+ ret = Api->wc_RsaKeyToPublicDer(&key, buffer, (word32)sizeof(buffer));
+ if (ret < 0) { status = CheckWolfResult(ret, L"wc_RsaKeyToPublicDer"); goto cleanup; }
+ int pubDerSz = ret;
+
+ ret = Api->wc_InitRsaKey(&pubKey, NULL);
+ status = CheckWolfResult(ret, L"wc_InitRsaKey pub"); if (EFI_ERROR(status)) goto cleanup;
+ pubInit = TRUE;
+
+ idx = 0;
+ ret = Api->wc_RsaPublicKeyDecode(buffer, &idx, &pubKey, (word32)pubDerSz);
+ status = CheckWolfResult(ret, L"wc_RsaPublicKeyDecode"); if (EFI_ERROR(status)) goto cleanup;
+
+ ret = Api->wc_RsaPublicEncrypt(sample, (word32)(sizeof(sample)-1),
+ cipher, (word32)sizeof(cipher), &pubKey, &rng);
+ if (ret < 0) { status = CheckWolfResult(ret, L"wc_RsaPublicEncrypt pubKey"); goto cleanup; }
+ cipherLen = ret;
+ ret = Api->wc_RsaPrivateDecrypt(cipher, (word32)cipherLen,
+ plain, (word32)sizeof(plain), &key);
+ if (ret < 0) { status = CheckWolfResult(ret, L"wc_RsaPrivateDecrypt pubKey"); goto cleanup; }
+ status = CheckCondition((ret == (int)(sizeof(sample)-1)) &&
+ BuffersEqual(plain, sample, sizeof(sample)-1),
+ L"RSA pub-import round-trip");
+ if (EFI_ERROR(status)) goto cleanup;
+
+ /* Export key components */
+ {
+ UINT8 e[4], n[128], d[128], p[64], q[64];
+ word32 eSz=sizeof(e), nSz=sizeof(n), dSz=sizeof(d), pSz=sizeof(p), qSz=sizeof(q);
+ ret = Api->wc_RsaExportKey(&key, e,&eSz, n,&nSz, d,&dSz, p,&pSz, q,&qSz);
+ status = CheckWolfResult(ret, L"wc_RsaExportKey"); if (EFI_ERROR(status)) goto cleanup;
+ status = CheckCondition(eSz==3 && e[0]==0x01 && e[1]==0x00 && e[2]==0x01,
+ L"RSA exponent");
+ if (EFI_ERROR(status)) goto cleanup;
+ }
+
+ /* Key generation (2048-bit) */
+ ret = Api->wc_InitRsaKey(&genKey, NULL);
+ status = CheckWolfResult(ret, L"wc_InitRsaKey gen"); if (EFI_ERROR(status)) goto cleanup;
+ genInit = TRUE;
+ ret = Api->wc_MakeRsaKey(&genKey, 2048, 65537, &rng);
+ status = CheckWolfResult(ret, L"wc_MakeRsaKey"); if (EFI_ERROR(status)) goto cleanup;
+ ret = Api->wc_RsaSetRNG(&genKey, &rng);
+ status = CheckWolfResult(ret, L"wc_RsaSetRNG gen"); if (EFI_ERROR(status)) goto cleanup;
+ ret = Api->wc_CheckRsaKey(&genKey);
+ status = CheckWolfResult(ret, L"wc_CheckRsaKey gen");
+
+cleanup:
+ if (genInit) { Api->wc_FreeRsaKey(&genKey); Api->wc_RsaCleanup(&genKey); }
+ if (pubInit) { Api->wc_FreeRsaKey(&pubKey); Api->wc_RsaCleanup(&pubKey); }
+ if (keyInit) { Api->wc_FreeRsaKey(&key); Api->wc_RsaCleanup(&key); }
+ if (rngInit) Api->wc_FreeRng(&rng);
+ return status;
+}
+
+/* ------------------------------------------------------------------ */
+/* ECC: keygen, ECDH, sign/verify */
+/* ------------------------------------------------------------------ */
+static EFI_STATUS TestEcc(void)
+{
+ EFI_STATUS status = EFI_SUCCESS;
+ int ret;
+ WC_RNG rng;
+ ecc_key keyA, keyB;
+ BOOLEAN rngInit = FALSE, aInit = FALSE, bInit = FALSE;
+ UINT8 sharedA[32], sharedB[32];
+ word32 sharedASz = sizeof(sharedA), sharedBSz = sizeof(sharedB);
+ UINT8 pub[65];
+ word32 pubSz = sizeof(pub);
+ UINT8 hash[WC_SHA256_DIGEST_SIZE];
+ UINT8 sig[ECC_MAX_SIG_SIZE];
+ word32 sigSz = sizeof(sig);
+ int verified = 0;
+
+ ZeroMem(&rng, sizeof(rng));
+ ZeroMem(&keyA, sizeof(keyA));
+ ZeroMem(&keyB, sizeof(keyB));
+
+ ret = InitRngDet(&rng);
+ if (IsOptionalRngError(ret)) { return EFI_UNSUPPORTED; }
+ status = CheckWolfResult(ret, L"wc_InitRng ECC");
+ if (EFI_ERROR(status)) return status;
+ rngInit = TRUE;
+
+ ret = Api->wc_ecc_init(&keyA);
+ status = CheckWolfResult(ret, L"wc_ecc_init A"); if (EFI_ERROR(status)) goto cleanup;
+ aInit = TRUE;
+
+ ret = Api->wc_ecc_init(&keyB);
+ status = CheckWolfResult(ret, L"wc_ecc_init B"); if (EFI_ERROR(status)) goto cleanup;
+ bInit = TRUE;
+
+ ret = Api->wc_ecc_make_key(&rng, 32, &keyA); /* P-256 */
+ status = CheckWolfResult(ret, L"wc_ecc_make_key A"); if (EFI_ERROR(status)) goto cleanup;
+
+ ret = Api->wc_ecc_make_key(&rng, 32, &keyB);
+ status = CheckWolfResult(ret, L"wc_ecc_make_key B"); if (EFI_ERROR(status)) goto cleanup;
+
+ /* Set RNG for timing-resistant ECDH */
+ ret = Api->wc_ecc_set_rng(&keyA, &rng);
+ status = CheckWolfResult(ret, L"wc_ecc_set_rng A"); if (EFI_ERROR(status)) goto cleanup;
+ ret = Api->wc_ecc_set_rng(&keyB, &rng);
+ status = CheckWolfResult(ret, L"wc_ecc_set_rng B"); if (EFI_ERROR(status)) goto cleanup;
+
+ /* ECDH */
+ ret = Api->wc_ecc_shared_secret(&keyA, &keyB, sharedA, &sharedASz);
+ status = CheckWolfResult(ret, L"wc_ecc_shared_secret A"); if (EFI_ERROR(status)) goto cleanup;
+
+ ret = Api->wc_ecc_shared_secret(&keyB, &keyA, sharedB, &sharedBSz);
+ status = CheckWolfResult(ret, L"wc_ecc_shared_secret B"); if (EFI_ERROR(status)) goto cleanup;
+
+ status = CheckCondition(sharedASz == sharedBSz &&
+ BuffersEqual(sharedA, sharedB, sharedASz),
+ L"ECC ECDH shared secret matches");
+ if (EFI_ERROR(status)) goto cleanup;
+
+ /* Sign/verify (hash of "wolfCrypt ECC test") */
+ {
+ wc_Sha256 sha;
+ const byte msg[] = "wolfCrypt ECC test";
+ ret = Api->wc_InitSha256(&sha);
+ status = CheckWolfResult(ret, L"ECC SHA256 init"); if (EFI_ERROR(status)) goto cleanup;
+ ret = Api->wc_Sha256Update(&sha, msg, (word32)sizeof(msg)-1);
+ status = CheckWolfResult(ret, L"ECC SHA256 update"); if (EFI_ERROR(status)) { Api->wc_Sha256Free(&sha); goto cleanup; }
+ ret = Api->wc_Sha256Final(&sha, hash);
+ Api->wc_Sha256Free(&sha);
+ status = CheckWolfResult(ret, L"ECC SHA256 final"); if (EFI_ERROR(status)) goto cleanup;
+ }
+
+ ret = Api->wc_ecc_sign_hash(hash, sizeof(hash), sig, &sigSz, &rng, &keyA);
+ status = CheckWolfResult(ret, L"wc_ecc_sign_hash"); if (EFI_ERROR(status)) goto cleanup;
+
+ ret = Api->wc_ecc_verify_hash(sig, sigSz, hash, sizeof(hash), &verified, &keyA);
+ status = CheckWolfResult(ret, L"wc_ecc_verify_hash"); if (EFI_ERROR(status)) goto cleanup;
+ status = CheckCondition(verified == 1, L"ECC signature verified");
+ if (EFI_ERROR(status)) goto cleanup;
+
+ /* Export / import public key X9.63 */
+ ret = Api->wc_ecc_export_x963(&keyA, pub, &pubSz);
+ status = CheckWolfResult(ret, L"wc_ecc_export_x963"); if (EFI_ERROR(status)) goto cleanup;
+
+ Api->wc_ecc_free(&keyB); bInit = FALSE;
+ ret = Api->wc_ecc_init(&keyB); bInit = TRUE;
+ status = CheckWolfResult(ret, L"wc_ecc_init B2"); if (EFI_ERROR(status)) goto cleanup;
+
+ ret = Api->wc_ecc_import_x963(pub, pubSz, &keyB);
+ status = CheckWolfResult(ret, L"wc_ecc_import_x963");
+ if (EFI_ERROR(status)) goto cleanup;
+
+ verified = 0;
+ ret = Api->wc_ecc_verify_hash(sig, sigSz, hash, sizeof(hash), &verified, &keyB);
+ status = CheckWolfResult(ret, L"wc_ecc_verify_hash imported"); if (EFI_ERROR(status)) goto cleanup;
+ status = CheckCondition(verified == 1, L"ECC verify with imported key");
+
+cleanup:
+ if (bInit) Api->wc_ecc_free(&keyB);
+ if (aInit) Api->wc_ecc_free(&keyA);
+ if (rngInit) Api->wc_FreeRng(&rng);
+ return status;
+}
+
+/* ------------------------------------------------------------------ */
+/* ChaCha20-Poly1305 AEAD round-trip */
+/* ------------------------------------------------------------------ */
+static EFI_STATUS TestChaCha20Poly1305(void)
+{
+ EFI_STATUS status;
+ int ret;
+ static const UINT8 key[CHACHA20_POLY1305_AEAD_KEYSIZE] = {
+ 0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,
+ 0x88,0x89,0x8a,0x8b,0x8c,0x8d,0x8e,0x8f,
+ 0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,
+ 0x98,0x99,0x9a,0x9b,0x9c,0x9d,0x9e,0x9f,
+ };
+ static const UINT8 iv[CHACHA20_POLY1305_AEAD_IV_SIZE] = {
+ 0x07,0x00,0x00,0x00,0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47,
+ };
+ static const UINT8 aad[12] = {
+ 0x50,0x51,0x52,0x53,0xc0,0xc1,0xc2,0xc3,0xc4,0xc5,0xc6,0xc7,
+ };
+ static const byte plaintext[] = "wolfCrypt ChaCha20-Poly1305 AEAD test message";
+ UINT8 ct[sizeof(plaintext)];
+ UINT8 pt[sizeof(plaintext)];
+ UINT8 authTag[CHACHA20_POLY1305_AEAD_AUTHTAG_SIZE];
+
+ ZeroMem(ct, sizeof(ct));
+ ZeroMem(pt, sizeof(pt));
+
+ ret = Api->wc_ChaCha20Poly1305_Encrypt(key, iv,
+ aad, sizeof(aad),
+ (const byte *)plaintext, sizeof(plaintext)-1,
+ ct, authTag);
+ status = CheckWolfResult(ret, L"ChaCha20Poly1305_Encrypt");
+ if (EFI_ERROR(status)) return status;
+
+ ret = Api->wc_ChaCha20Poly1305_Decrypt(key, iv,
+ aad, sizeof(aad),
+ ct, sizeof(plaintext)-1,
+ authTag, pt);
+ status = CheckWolfResult(ret, L"ChaCha20Poly1305_Decrypt");
+ if (EFI_ERROR(status)) return status;
+
+ return CheckCondition(BuffersEqual(pt, (const UINT8 *)plaintext, sizeof(plaintext)-1),
+ L"ChaCha20-Poly1305 round-trip");
+}
+
+/* ------------------------------------------------------------------ */
+/* Curve25519 (X25519) ECDH round-trip */
+/* ------------------------------------------------------------------ */
+static EFI_STATUS TestCurve25519(void)
+{
+ EFI_STATUS status = EFI_SUCCESS;
+ int ret;
+ WC_RNG rng;
+ curve25519_key alice, bob;
+ BOOLEAN rngInit = FALSE, aliceInit = FALSE, bobInit = FALSE;
+ UINT8 sharedA[CURVE25519_KEYSIZE], sharedB[CURVE25519_KEYSIZE];
+ word32 sharedASz = sizeof(sharedA), sharedBSz = sizeof(sharedB);
+
+ ZeroMem(&rng, sizeof(rng));
+
+ ret = InitRngDet(&rng);
+ if (IsOptionalRngError(ret)) return EFI_UNSUPPORTED;
+ status = CheckWolfResult(ret, L"wc_InitRng Curve25519"); if (EFI_ERROR(status)) return status;
+ rngInit = TRUE;
+
+ ret = Api->wc_curve25519_init(&alice); status = CheckWolfResult(ret, L"curve25519_init alice"); if (EFI_ERROR(status)) goto cleanup; aliceInit = TRUE;
+ ret = Api->wc_curve25519_init(&bob); status = CheckWolfResult(ret, L"curve25519_init bob"); if (EFI_ERROR(status)) goto cleanup; bobInit = TRUE;
+
+ ret = Api->wc_curve25519_make_key(&rng, CURVE25519_KEYSIZE, &alice);
+ status = CheckWolfResult(ret, L"curve25519_make_key alice"); if (EFI_ERROR(status)) goto cleanup;
+
+ ret = Api->wc_curve25519_make_key(&rng, CURVE25519_KEYSIZE, &bob);
+ status = CheckWolfResult(ret, L"curve25519_make_key bob"); if (EFI_ERROR(status)) goto cleanup;
+
+ ret = Api->wc_curve25519_shared_secret(&alice, &bob, sharedA, &sharedASz);
+ status = CheckWolfResult(ret, L"curve25519_shared_secret alice"); if (EFI_ERROR(status)) goto cleanup;
+
+ ret = Api->wc_curve25519_shared_secret(&bob, &alice, sharedB, &sharedBSz);
+ status = CheckWolfResult(ret, L"curve25519_shared_secret bob"); if (EFI_ERROR(status)) goto cleanup;
+
+ status = CheckCondition(sharedASz == sharedBSz &&
+ BuffersEqual(sharedA, sharedB, sharedASz),
+ L"Curve25519 shared secret matches");
+
+cleanup:
+ if (bobInit) Api->wc_curve25519_free(&bob);
+ if (aliceInit) Api->wc_curve25519_free(&alice);
+ if (rngInit) Api->wc_FreeRng(&rng);
+ return status;
+}
+
+/* ------------------------------------------------------------------ */
+/* Ed25519: keygen, sign, verify */
+/* ------------------------------------------------------------------ */
+static EFI_STATUS TestEd25519(void)
+{
+ EFI_STATUS status = EFI_SUCCESS;
+ int ret;
+ WC_RNG rng;
+ ed25519_key key;
+ BOOLEAN rngInit = FALSE, keyInit = FALSE;
+ static const byte msg[] = "wolfCrypt UEFI Ed25519 test";
+ UINT8 sig[ED25519_SIG_SIZE];
+ word32 sigSz = sizeof(sig);
+ int verified = 0;
+
+ ZeroMem(&rng, sizeof(rng));
+ ZeroMem(&key, sizeof(key));
+
+ ret = InitRngDet(&rng);
+ if (IsOptionalRngError(ret)) return EFI_UNSUPPORTED;
+ status = CheckWolfResult(ret, L"wc_InitRng Ed25519"); if (EFI_ERROR(status)) return status;
+ rngInit = TRUE;
+
+ ret = Api->wc_ed25519_init(&key);
+ status = CheckWolfResult(ret, L"wc_ed25519_init"); if (EFI_ERROR(status)) goto cleanup;
+ keyInit = TRUE;
+
+ ret = Api->wc_ed25519_make_key(&rng, ED25519_KEY_SIZE, &key);
+ status = CheckWolfResult(ret, L"wc_ed25519_make_key"); if (EFI_ERROR(status)) goto cleanup;
+
+ ret = Api->wc_ed25519_sign_msg(msg, (word32)sizeof(msg)-1, sig, &sigSz, &key);
+ status = CheckWolfResult(ret, L"wc_ed25519_sign_msg"); if (EFI_ERROR(status)) goto cleanup;
+
+ ret = Api->wc_ed25519_verify_msg(sig, sigSz, msg, (word32)sizeof(msg)-1, &verified, &key);
+ status = CheckWolfResult(ret, L"wc_ed25519_verify_msg"); if (EFI_ERROR(status)) goto cleanup;
+ status = CheckCondition(verified == 1, L"Ed25519 signature verified");
+
+cleanup:
+ if (keyInit) Api->wc_ed25519_free(&key);
+ if (rngInit) Api->wc_FreeRng(&rng);
+ return status;
+}
+
+/* ------------------------------------------------------------------ */
+/* ML-KEM (Kyber512): full encode/decode round-trip */
+/* ------------------------------------------------------------------ */
+#if defined(WOLFSSL_HAVE_MLKEM)
+static EFI_STATUS TestMlKem(void)
+{
+ EFI_STATUS status = EFI_SUCCESS;
+ int ret;
+ WC_RNG rng;
+ MlKemKey key;
+ BOOLEAN rngInit = FALSE, keyInit = FALSE, seedCbActive = FALSE;
+ UINT8 priv[KYBER512_PRIVATE_KEY_SIZE];
+ UINT8 privExpected[KYBER512_PRIVATE_KEY_SIZE];
+ UINT8 pub[KYBER512_PUBLIC_KEY_SIZE];
+ UINT8 pubExpected[KYBER512_PUBLIC_KEY_SIZE];
+ UINT8 ct[KYBER512_CIPHER_TEXT_SIZE];
+ UINT8 ss[KYBER_SS_SZ], ssDec[KYBER_SS_SZ];
+ word32 len;
+
+ ZeroMem(&rng, sizeof(rng)); ZeroMem(&key, sizeof(key));
+
+ if (Api->wc_SetSeed_Cb(DeterministicSeedCb) == 0) seedCbActive = TRUE;
+ ret = Api->wc_InitRng(&rng);
+ status = CheckWolfResult(ret, L"wc_InitRng ML-KEM");
+ if (EFI_ERROR(status)) { if (seedCbActive) Api->wc_SetSeed_Cb(NULL); return status; }
+ rngInit = TRUE;
+
+ ret = Api->wc_RNG_TestSeed(kyber512_rand, (word32)sizeof(kyber512_rand));
+ status = CheckWolfResult(ret, L"wc_RNG_TestSeed ML-KEM key"); if (EFI_ERROR(status)) goto cleanup;
+
+ ret = Api->wc_MlKemKey_Init(&key, KYBER512, NULL, INVALID_DEVID);
+ status = CheckWolfResult(ret, L"wc_MlKemKey_Init"); if (EFI_ERROR(status)) goto cleanup;
+ keyInit = TRUE;
+
+ ret = Api->wc_MlKemKey_MakeKey(&key, &rng);
+ status = CheckWolfResult(ret, L"wc_MlKemKey_MakeKey"); if (EFI_ERROR(status)) goto cleanup;
+
+ ret = Api->wc_MlKemKey_EncodePublicKey(&key, pub, (word32)sizeof(pub));
+ status = CheckWolfResult(ret, L"EncodePublicKey"); if (EFI_ERROR(status)) goto cleanup;
+ CopyBytes(pubExpected, pub, sizeof(pub));
+
+ ret = Api->wc_MlKemKey_EncodePrivateKey(&key, priv, (word32)sizeof(priv));
+ status = CheckWolfResult(ret, L"EncodePrivateKey"); if (EFI_ERROR(status)) goto cleanup;
+ CopyBytes(privExpected, priv, sizeof(priv));
+
+ ret = Api->wc_MlKemKey_PublicKeySize(&key, &len);
+ status = CheckWolfResult(ret, L"PublicKeySize"); if (EFI_ERROR(status)) goto cleanup;
+ status = CheckCondition(len == KYBER512_PUBLIC_KEY_SIZE, L"ML-KEM pub size"); if (EFI_ERROR(status)) goto cleanup;
+
+ ret = Api->wc_MlKemKey_PrivateKeySize(&key, &len);
+ status = CheckWolfResult(ret, L"PrivateKeySize"); if (EFI_ERROR(status)) goto cleanup;
+ status = CheckCondition(len == KYBER512_PRIVATE_KEY_SIZE, L"ML-KEM priv size"); if (EFI_ERROR(status)) goto cleanup;
+
+ ret = Api->wc_MlKemKey_CipherTextSize(&key, &len);
+ status = CheckWolfResult(ret, L"CipherTextSize"); if (EFI_ERROR(status)) goto cleanup;
+ status = CheckCondition(len == KYBER512_CIPHER_TEXT_SIZE, L"ML-KEM ct size"); if (EFI_ERROR(status)) goto cleanup;
+
+ ret = Api->wc_MlKemKey_SharedSecretSize(&key, &len);
+ status = CheckWolfResult(ret, L"SharedSecretSize"); if (EFI_ERROR(status)) goto cleanup;
+ status = CheckCondition(len == KYBER_SS_SZ, L"ML-KEM ss size"); if (EFI_ERROR(status)) goto cleanup;
+
+ ret = Api->wc_RNG_TestSeed(kyber512enc_rand, (word32)sizeof(kyber512enc_rand));
+ status = CheckWolfResult(ret, L"wc_RNG_TestSeed ML-KEM enc"); if (EFI_ERROR(status)) goto cleanup;
+
+ ret = Api->wc_MlKemKey_Encapsulate(&key, ct, ss, &rng);
+ status = CheckWolfResult(ret, L"wc_MlKemKey_Encapsulate"); if (EFI_ERROR(status)) goto cleanup;
+
+ ret = Api->wc_MlKemKey_Decapsulate(&key, ssDec, ct, (word32)sizeof(ct));
+ status = CheckWolfResult(ret, L"wc_MlKemKey_Decapsulate"); if (EFI_ERROR(status)) goto cleanup;
+ status = CheckCondition(BuffersEqual(ss, ssDec, sizeof(ss)), L"ML-KEM shared secret"); if (EFI_ERROR(status)) goto cleanup;
+
+ /* Decode round-trip */
+ Api->wc_MlKemKey_Free(&key); keyInit = FALSE;
+ ret = Api->wc_MlKemKey_Init(&key, KYBER512, NULL, INVALID_DEVID);
+ status = CheckWolfResult(ret, L"wc_MlKemKey_Init decode"); if (EFI_ERROR(status)) goto cleanup;
+ keyInit = TRUE;
+
+ ret = Api->wc_MlKemKey_DecodePublicKey(&key, pubExpected, (word32)sizeof(pubExpected));
+ status = CheckWolfResult(ret, L"DecodePublicKey"); if (EFI_ERROR(status)) goto cleanup;
+ ret = Api->wc_MlKemKey_EncodePublicKey(&key, pub, (word32)sizeof(pub));
+ status = CheckWolfResult(ret, L"EncodePublicKey decoded"); if (EFI_ERROR(status)) goto cleanup;
+ status = CheckCondition(BuffersEqual(pub, pubExpected, sizeof(pub)), L"ML-KEM pub round-trip"); if (EFI_ERROR(status)) goto cleanup;
+
+ ret = Api->wc_MlKemKey_DecodePrivateKey(&key, privExpected, (word32)sizeof(privExpected));
+ status = CheckWolfResult(ret, L"DecodePrivateKey"); if (EFI_ERROR(status)) goto cleanup;
+ ret = Api->wc_MlKemKey_EncodePrivateKey(&key, priv, (word32)sizeof(priv));
+ status = CheckWolfResult(ret, L"EncodePrivateKey decoded"); if (EFI_ERROR(status)) goto cleanup;
+ status = CheckCondition(BuffersEqual(priv, privExpected, sizeof(priv)), L"ML-KEM priv round-trip");
+
+cleanup:
+ if (seedCbActive) Api->wc_SetSeed_Cb(NULL);
+ if (keyInit) Api->wc_MlKemKey_Free(&key);
+ if (rngInit) Api->wc_FreeRng(&rng);
+ return status;
+}
+#endif /* WOLFSSL_HAVE_MLKEM */
+
+/* ------------------------------------------------------------------ */
+/* Dilithium (ML-DSA-44): keygen, sign, verify */
+/* ------------------------------------------------------------------ */
+#if defined(HAVE_DILITHIUM)
+static EFI_STATUS TestDilithium(void)
+{
+ EFI_STATUS status = EFI_SUCCESS;
+ int ret;
+ WC_RNG rng;
+ dilithium_key key;
+ BOOLEAN rngInit = FALSE, keyInit = FALSE;
+ static const byte msg[] = "wolfCrypt UEFI Dilithium test";
+ byte sig[DILITHIUM_MAX_SIG_SIZE];
+ word32 sigLen = sizeof(sig);
+ int verify = 0;
+
+ ZeroMem(&rng, sizeof(rng)); ZeroMem(&key, sizeof(key));
+
+ ret = InitRngDet(&rng);
+ status = CheckWolfResult(ret, L"wc_InitRng Dilithium"); if (EFI_ERROR(status)) return status;
+ rngInit = TRUE;
+
+ ret = Api->wc_dilithium_init(&key);
+ status = CheckWolfResult(ret, L"wc_dilithium_init"); if (EFI_ERROR(status)) goto cleanup;
+ keyInit = TRUE;
+
+ ret = Api->wc_dilithium_set_level(&key, 2); /* ML-DSA-44 */
+ status = CheckWolfResult(ret, L"wc_dilithium_set_level"); if (EFI_ERROR(status)) goto cleanup;
+
+ ret = Api->wc_dilithium_make_key(&key, &rng);
+ status = CheckWolfResult(ret, L"wc_dilithium_make_key"); if (EFI_ERROR(status)) goto cleanup;
+
+ ret = Api->wc_dilithium_sign_msg(msg, (word32)sizeof(msg)-1, sig, &sigLen, &key, &rng);
+ status = CheckWolfResult(ret, L"wc_dilithium_sign_msg"); if (EFI_ERROR(status)) goto cleanup;
+
+ ret = Api->wc_dilithium_verify_msg(sig, sigLen, msg, (word32)sizeof(msg)-1, &verify, &key);
+ status = CheckWolfResult(ret, L"wc_dilithium_verify_msg"); if (EFI_ERROR(status)) goto cleanup;
+ status = CheckCondition(verify == 1, L"Dilithium signature verified");
+
+cleanup:
+ if (keyInit) Api->wc_dilithium_free(&key);
+ if (rngInit) Api->wc_FreeRng(&rng);
+ return status;
+}
+#endif /* HAVE_DILITHIUM */
+
+/* ------------------------------------------------------------------ */
+/* Test runner */
+/* ------------------------------------------------------------------ */
+static EFI_STATUS RunAllTests(void)
+{
+ static const struct {
+ const CHAR16 *name;
+ EFI_STATUS (*func)(void);
+ } tests[] = {
+ { L"AES", TestAes },
+ { L"SHA", TestSha },
+ { L"HMAC", TestHmac },
+ { L"CMAC", TestCmac },
+ { L"KDF", TestKdf },
+ { L"RNG", TestRng },
+ { L"RSA", TestRsa },
+ { L"ECC", TestEcc },
+ { L"ChaCha20-Poly1305", TestChaCha20Poly1305 },
+ { L"Curve25519", TestCurve25519 },
+ { L"Ed25519", TestEd25519 },
+#if defined(WOLFSSL_HAVE_MLKEM)
+ { L"ML-KEM", TestMlKem },
+#endif
+#if defined(HAVE_DILITHIUM)
+ { L"Dilithium", TestDilithium },
+#endif
+ };
+
+ for (UINTN i = 0; i < ARRAY_SIZE(tests); ++i) {
+ Print(L"Running %-20s ... ", tests[i].name);
+ EFI_STATUS st = tests[i].func();
+ if (st == EFI_UNSUPPORTED) { Print(L"skipped\n"); continue; }
+ if (EFI_ERROR(st)) { Print(L"FAILED\n"); return st; }
+ Print(L"passed\n");
+ }
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS EFIAPI efi_main(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable)
+{
+ EFI_STATUS status;
+
+ InitializeLib(ImageHandle, SystemTable);
+ Print(L"test.efi loaded\n");
+
+ status = uefi_call_wrapper(BS->LocateProtocol, 3,
+ &g_wolfcrypt_protocol_guid, NULL, (VOID **)&Api);
+ if (EFI_ERROR(status) || Api == NULL) {
+ Print(L"wolfCrypt protocol not found: %r\n", status);
+ return status;
+ }
+
+ Print(L"wolfCrypt protocol found, version 0x%08x\n", Api->Version);
+ Print(L"\n");
+
+ status = RunAllTests();
+ if (EFI_ERROR(status)) {
+ Print(L"\nTest suite FAILED: %r\n", status);
+ return status;
+ }
+
+ Print(L"\nAll tests passed!\n");
+ return EFI_SUCCESS;
+}
diff --git a/uefi-library/src/utility_wolf.c b/uefi-library/src/utility_wolf.c
new file mode 100644
index 00000000..32e13367
--- /dev/null
+++ b/uefi-library/src/utility_wolf.c
@@ -0,0 +1,1651 @@
+#include
+#include
+#include
+#include
+#include
+
+#include
+#include
+#include
+
+#define STR_SIZE 512
+#define MSG_BUFFER_TMP 1024
+
+#define uefi_printf AsciiPrint /* Native Print */
+
+/* Used to debug verbosely to see where code fails, or gets hung */
+#ifdef UEFI_VERBOSE_DEBUG
+ #define uefi_printf_debug uefi_printf_wolfssl
+#else
+ #define uefi_printf_debug(...) ((void)0)
+#endif
+
+#ifdef UEFI_LOG_PRINTF
+
+extern FILE* printfLog;
+
+#endif
+
+/* Needed from main */
+extern EFI_LOADED_IMAGE *loaded_image;
+/* Function to parse and replace a search string with a replacement string */
+/* used to find options such %s and replace with %a, but is setup to parse */
+/* any needed string */
+
+int parseAndReplace(const char* msg, char* temp, const char* search,
+ const char* replace)
+{
+ size_t searchLen = XSTRLEN(search);
+ size_t replaceLen = XSTRLEN(replace);
+ size_t tempIndex = 0;
+ size_t msgIndex = 0;
+ if (searchLen == 0) {
+ return -1; /* Invalid search string */
+ }
+
+ while (msg[msgIndex] != '\0' && tempIndex < MSG_BUFFER_TMP - 1) {
+ /* Check if the search string matches at the current position */
+ if (XSTRNCMP(&msg[msgIndex], search, searchLen) == 0) {
+ /* Ensure there's enough space in temp for the replacement */
+ if (tempIndex + replaceLen >= MSG_BUFFER_TMP - 1) {
+ break;
+ }
+
+ /* Copy the replacement string */
+ XMEMCPY(&temp[tempIndex], replace, replaceLen);
+ tempIndex += replaceLen;
+
+ /* Skip the search string length in the input */
+ msgIndex += searchLen;
+ } else {
+ /* Copy the current character */
+ temp[tempIndex++] = msg[msgIndex++];
+ }
+ }
+
+ /* Null-terminate the output */
+ temp[tempIndex] = '\0';
+ return 0;
+}
+
+unsigned int calculateBufferSize(const char* msg, va_list args)
+{
+ va_list args_copy;
+ unsigned int size = 0;
+ const char* p = msg;
+
+ if (msg == NULL) {
+ return 0;
+ }
+
+ va_copy(args_copy, args);
+ size = XSTRLEN(msg) + 1;
+
+ while (*p) {
+ if (*p == '%' && *(p + 1)) {
+ p++; // Move past '%'
+ if (*p == 's' || *p == 'a') { // Handle strings
+ char* str = va_arg(args_copy, char*);
+ if (str) {
+ size += XSTRLEN(str); // Add the length of the string
+ }
+ } else if (*p == 'd' || *p == 'u' || *p == 'x') {
+ va_arg(args_copy, int); // Skip integers
+ } else if (*p == 'f') {
+ va_arg(args_copy, double); // Skip doubles
+ }
+ }
+ p++;
+ }
+
+ va_end(args_copy);
+ return size;
+}
+
+int uefi_vsnprintf_wolfssl(char* buffer, size_t size, const char* format,
+ va_list args)
+{
+ int result;
+ char* tempFormat = NULL;
+ va_list argsCpy;
+ va_copy(argsCpy, args);
+ unsigned int fmtSize = strlena(format);
+#ifdef UEFI_VECTOR_TEST
+ int check = 1;
+#endif
+ if (buffer == NULL || format == NULL) {
+ AsciiPrint("Null Buffer given to snprintf");
+ return -1;
+ }
+
+ tempFormat = (char*)XMALLOC(2 * fmtSize*sizeof(char), NULL,
+ DYNAMIC_TYPE_TMP_BUFFER);
+ if (tempFormat == NULL) {
+ AsciiPrint("Failed to allocate temp buffer");
+ return -1;
+ }
+
+
+ /* Need to replace certain charaters */
+ parseAndReplace(format, tempFormat, "%s", "%a");
+
+/* Needed to run benchmark utility */
+#ifdef UEFI_BENCHMARK
+ parseAndReplace(tempFormat, tempFormat, "%8s", "%8a");
+ parseAndReplace(tempFormat, tempFormat, "%15s", "%15a");
+ parseAndReplace(tempFormat, tempFormat, "%-2s", "%-2a");
+ parseAndReplace(tempFormat, tempFormat, "%-5s", "%-5a");
+ parseAndReplace(tempFormat, tempFormat, "%-6s", "%-6a");
+ parseAndReplace(tempFormat, tempFormat, "%-9s", "%-9a");
+ parseAndReplace(tempFormat, tempFormat, "%-16s", "%-16a");
+ parseAndReplace(tempFormat, tempFormat, "%-24s", "%-24a");
+#endif
+
+/* Needed for Internal vector tests */
+#ifdef UEFI_VECTOR_TEST
+ check = parseAndReplace(tempFormat, tempFormat, "%1.15g", "%1.0f");
+ check = parseAndReplace(tempFormat, tempFormat, "%1.17g", "%1.0f");
+#endif
+
+#ifdef NO_MAIN_OPTEST_DRIVER
+ parseAndReplace(tempFormat, tempFormat, "%25s", "%25a");
+ parseAndReplace(tempFormat, tempFormat, "%10s", "%10a");
+#ifdef OPTEST_INVALID_LOGGING_ENABLED
+ parseAndReplace(tempFormat, tempFormat, "%*s", "%*a");
+#endif
+#endif
+
+
+ /* Pass the variadic arguments to AsciiVSPrintf */
+ result = (int)AsciiVSPrint(buffer, size, tempFormat, args);
+
+ /* Needed for internal vector tests */
+#ifdef UEFI_VECTOR_TEST
+ if (check == 0) {
+ parseAndReplace(buffer, buffer, ".0", " \b");
+ }
+#endif
+
+ va_end(argsCpy);
+ XFREE(tempFormat, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+ return result;
+}
+
+int uefi_snprintf_wolfssl(char* buffer, size_t n, const char* format, ...)
+{
+ int result;
+ char* tempFormat = NULL;
+ va_list args;
+ if (buffer == NULL || format == NULL) {
+ AsciiPrint("Null Buffer given to snprintf");
+ return -1;
+ }
+
+ /* Initialize args to store all values after 'format' */
+ va_start(args, format);
+
+ /* Just pass to vsnprintf */
+ result = uefi_vsnprintf_wolfssl(buffer, n, format, args);
+
+ /* Clean up the va_list */
+ va_end(args);
+
+ return result;
+}
+
+/* Wrap because AsciiPrint returns unsigned int, printf return a int normally */
+int uefi_printf_wolfssl(const char* msg, ...)
+{
+ int ret = 0;
+ va_list args, argsCpy;
+ char* temp = NULL;
+ size_t size;
+
+ if (msg == NULL) {
+ AsciiPrint("NULL sent to uefi_printf_wolfssl");
+ return -1;
+ }
+
+ /* Initialize variadic argument list */
+ va_start(args, msg);
+ va_copy(argsCpy, args);
+
+ /* Estimate needed buffer and add a temp size for args */
+ size = ((XSTRLEN(msg) + calculateBufferSize(msg, argsCpy) + MSG_BUFFER_TMP));
+
+ temp = (char*)XMALLOC(2 * size*sizeof(char), NULL, DYNAMIC_TYPE_TMP_BUFFER);
+ if (temp == NULL) {
+ AsciiPrint("Failed to allocate temp buffer\n");
+ return -1;
+ }
+
+ /* Pass to vsnprintf */
+ uefi_vsnprintf_wolfssl(temp, size, msg, args);
+
+ /* Use AsciiPrint to print the formatted message */
+ ret = (int)AsciiPrint("%a", temp);
+#ifdef UEFI_LOG_PRINTF
+ if (printfLog != NULL) {
+ fwrite(temp, strlena(temp), 1, printfLog);
+ }
+ else {
+ Print(L"Logging file in NULL prt\n");
+ }
+#endif
+ /* Clean up */
+ va_end(argsCpy);
+ va_end(args);
+ XFREE(temp, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+
+ return ret;
+}
+
+int uefi_vprintf_wolfssl(const char* msg, va_list args)
+{
+ int ret = 0;
+ int size = 0;
+ char* temp = NULL;
+ va_list argsCpy;
+
+ if (msg == NULL) {
+ AsciiPrint("NULL sent to uefi_vprintf_wolfssl");
+ return -1;
+ }
+
+ /* Initialize variadic argument list */
+ va_copy(argsCpy, args);
+
+ /* Estimate needed buffer and add a temp size for args */
+ size = ((XSTRLEN(msg)+calculateBufferSize(msg, argsCpy)+MSG_BUFFER_TMP));
+
+ temp = (char*)XMALLOC(2 * size*sizeof(char), NULL, DYNAMIC_TYPE_TMP_BUFFER);
+ if (temp == NULL) {
+ AsciiPrint("Failed to allocate temp buffer\n");
+ return -1;
+ }
+
+ uefi_vsnprintf_wolfssl(temp, size, msg, args);
+
+ /* Use AsciiPrint to print the formatted message */
+ ret = (int)AsciiPrint("%a", temp);
+
+ /* Clean up */
+ va_end(argsCpy);
+ XFREE(temp, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+
+ return ret;
+}
+
+int uefi_fprintf_wolfssl(FILE* stream, const char* format, ...)
+{
+ unsigned int ret = 0;
+
+ if (stream == NULL || format == NULL) {
+ return -1;
+ }
+
+ AsciiPrint("fPrintf() Not Implemented\n");
+
+ va_list args;
+ va_start(args, format);
+
+
+ va_end(args);
+ return ret;
+}
+
+/* Helper function to write an integer to the stream */
+static int write_integer(FILE* stream, int value) {
+ char buffer[12];
+ int len = 0;
+
+ if (value < 0) {
+ buffer[len++] = '-';
+ value = -value;
+ }
+
+ int temp = value;
+ int digits = 0;
+
+ /* Count digits */
+ do {
+ temp /= 10;
+ digits++;
+ } while (temp > 0);
+
+ /* Write digits to the buffer */
+ for (int i = 0; i < digits; i++) {
+ buffer[len + digits - 1 - i] = '0' + (value % 10);
+ value /= 10;
+ }
+ len += digits;
+
+ /* Write to the file */
+ size_t written = fwrite(buffer, sizeof(char), len, stream);
+ return (written == (size_t)len) ? len : -1;
+}
+
+/* Helper function to write a string to the stream */
+static int write_string(FILE* stream, const char* str) {
+ size_t len = XSTRLEN(str);
+ size_t written = fwrite(str, sizeof(char), len, stream);
+ return (written == len) ? len : -1;
+}
+
+/* Convert standard 8 bit char to 16 bit wide char */
+void char8_to_char16(const char* str8, char16_t* str16)
+{
+ char8_to_char16_ex(str8, str16, XSTRLEN(str8));
+ return;
+}
+
+/* Convert standard 8 bit char to 16 bit wide char only copy based on n */
+void char8_to_char16_ex(const char* str8, char16_t* str16, int n)
+{
+ size_t i;
+ for (i = 0; i < n; ++i) {
+ str16[i] = (char16_t)str8[i];
+ }
+ str16[i] = L'\0';
+ return;
+}
+
+/* Returns the filesize of given handle */
+uint64_t fileSize(EFI_FILE_HANDLE FileHandle)
+{
+ uint64_t ret;
+ EFI_FILE_INFO *FileInfo; /* file information structure */
+ /* get the file's size */
+ FileInfo = LibFileInfo(FileHandle);
+ ret = FileInfo->FileSize;
+ FreePool(FileInfo);
+ return ret;
+}
+
+
+int uefi_wolfssl_fflush(FILE* stream)
+{
+ size_t ret = 0; /* Number of items successfully read */
+ EFI_FILE_HANDLE* fPtr = NULL;
+ uefi_printf_debug("Inside custom fflush\n");
+ if (stream == NULL) {
+ uefi_printf_wolfssl("NULL given to FFLUSH\n");
+ return -1;
+ }
+ if (stream == stdout) {
+ SIMPLE_TEXT_OUTPUT_INTERFACE* uefi_stdout = NULL;
+ uefi_stdout = (SIMPLE_TEXT_OUTPUT_INTERFACE*)stream;
+ uefi_call_wrapper(uefi_stdout->OutputString, 1, uefi_stdout, L"\n");
+ return 0;
+ }
+ fPtr = (EFI_FILE_HANDLE*)stream;
+
+
+ /* Attempt to read from the file */
+ uefi_call_wrapper((*fPtr)->Flush, 1, *fPtr);
+
+ return 0;
+}
+
+void exit(int n)
+{
+ Exit(n, 0, (CHAR16*)"Exiting Called");
+}
+
+void logging_cb(const int logLevel, const char *const logMessage)
+{
+ char16_t str16[STR_SIZE];
+ char8_to_char16(logMessage, str16);
+ uefi_printf_wolfssl("%s", str16);
+}
+
+void *XMALLOC(size_t n, void* heap, int type)
+{
+ void* newBuffer;
+ newBuffer = AllocateZeroPool(n);
+ if (newBuffer == NULL) {
+ AsciiPrint("Malloc Failed: return NULL\n");
+ return NULL;
+ }
+ return newBuffer;
+}
+
+/* Dirty Memcopy.... For proper we have to pass the old buffer size to UEFI */
+/* To use ReallocatePool function..... */
+void *XREALLOC(void *p, size_t n, void* heap, int type)
+{
+ void* newBuffer = NULL;
+ (void)heap;
+ (void)type;
+
+ if (n == 0) {
+ AsciiPrint("Size 0 given returning NULL...\n");
+ FreePool(p);
+ p = NULL;
+ return NULL;
+ }
+
+ /* Allocate new Buffer */
+ newBuffer = AllocateZeroPool(n);
+ if (newBuffer == NULL) {
+ AsciiPrint("Realloc Failed: return NULL\n");
+ FreePool(p);
+ return NULL;
+ }
+ if (p == NULL) {
+ return newBuffer;
+ }
+
+ /* preform XMEMCPY on old buffer using n.... */
+ XMEMCPY(newBuffer, p, n);
+
+ /* Free Old Buffer */
+ FreePool(p);
+ p = NULL;
+ return newBuffer;
+}
+
+void XFREE(void *p, void* heap, int type)
+{
+ FreePool(p);
+ p = NULL;
+ return;
+}
+
+void *uefi_malloc_wolfssl(size_t n)
+{
+ return XMALLOC(n, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+}
+
+void *uefi_realloc_wolfssl(void* ptr, size_t n)
+{
+ return XREALLOC(ptr, n, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+}
+
+void uefi_free_wolfssl(void* ptr)
+{
+ return XFREE(ptr, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+}
+
+/* USER FILE IO SECTION */
+
+double fabs(double x) {
+ return (x < 0) ? -x : x;
+}
+
+
+ssize_t read(int fd, void *buf, size_t cnt)
+{
+ uefi_printf_wolfssl("Inside Read Open\n");
+ return -1;
+}
+
+
+ssize_t write(int fd, const void* buf, size_t cnt)
+{
+ uefi_printf_wolfssl("Inside Write Close\n");
+ return -1;
+}
+
+/* Opens a file specified by filename and mode, */
+/* returns a FILE pointer or NULL on failure */
+/* UEFI requires that the filepath be in wchar format aka unicode */
+/* however fopen is specified as taking in a const char buffer */
+/* so custom fopen will assume this is the case, but then convert */
+/* the buffer to wchar */
+FILE* fopen(const char* filename, const char* mode)
+{
+ EFI_FILE_HANDLE* fPtr = NULL;
+ FILE_OPS option = NONE;
+ EFI_FILE_HANDLE volume;
+ EFI_STATUS status;
+ uint64_t size;
+ /* Temporary buffer pointer */
+ char* temp;
+ /* Since fopen is */
+ char16_t* filename_w;
+
+ uefi_printf_debug("Inside custom fopen\n");
+
+ fPtr = (EFI_FILE_HANDLE*)XMALLOC(sizeof(EFI_FILE_HANDLE),
+ NULL, DYNAMIC_TYPE_TMP_BUFFER);
+ if (fPtr == NULL) {
+ uefi_printf_wolfssl("Malloc failed: fPtr\n");
+ return NULL;
+ }
+
+/* need if for some reason we need to replace "/" with "\" dos style paths */
+#ifdef NEED_DYNAMIC_PATH_FIX_UEFI
+ uefi_printf_wolfssl("Filename: %s\n", filename);
+ /* Malloc out temp buffer to needed size */
+ temp = (char*)XMALLOC(XSTRLEN(filename)*sizeof(char),
+ NULL, DYNAMIC_TYPE_TMP_BUFFER);
+ if (temp == NULL) {
+ uefi_printf_wolfssl("Malloc failed: temp filename\n");
+ return NULL;
+ }
+
+ parseAndReplace(filename, temp, "/", "\\");
+ uefi_printf_wolfssl("Filename After: %s\n", filename);
+ //parseAndReplace(filename, temp, "./", "\\");
+#else
+ temp = (char*)filename;
+#endif
+
+#ifdef NEED_DYNAMIC_TYPE_FIX_UEFI
+ filename_w = (char16_t*)XMALLOC(XSTRLEN(temp) * sizeof(char16_t),
+ NULL, DYNAMIC_TYPE_TMP_BUFFER);
+ if (filename_w == NULL) {
+ uefi_printf_wolfssl("Malloc failed: temp filename wide\n");
+ return NULL;
+ }
+ char8_to_char16(temp, filename_w);
+
+ if (filename == NULL) {
+ uefi_printf_wolfssl("Bad Argument given to fopen for filename\n");
+ return NULL;
+ }
+#else
+ filename_w = filename;
+#endif
+ /* Debugging file paths for UEFI */
+ /* Use %a to properly print out the string */
+ uefi_printf_debug("The file being open: %a\n", filename);
+#ifdef NEED_DYNAMIC_PATH_FIX_UEFI
+ uefi_printf_debug("The fixed file path being open is: %a\n", temp);
+#endif
+ /* filename_w is proper conversion so use */
+ uefi_printf_debug("The wide file being open is: %s\n", filename_w);
+
+ option = getFileOperation(mode);
+ if (option == NULL_ARG) {
+ uefi_printf_wolfssl("Bad Argument given to to fopen for mode\n");
+ return NULL;
+ }
+
+ volume = getVolume();
+
+ switch (option) {
+ case READ:
+ /* Debug for usage */
+ uefi_printf_debug("Mode: read\n");
+ uefi_call_wrapper(volume->Open, 5, volume, fPtr, filename_w,
+ EFI_FILE_MODE_READ, EFI_FILE_READ_ONLY | \
+ EFI_FILE_HIDDEN | EFI_FILE_SYSTEM);
+ if (fPtr == NULL) {
+ uefi_printf_wolfssl("File Pointer is NULL after Open Call\n");
+ return NULL;
+ }
+ break;
+
+ case WRITE:
+ uefi_printf_debug("Mode: write\n");
+ uefi_call_wrapper(volume->Open, 5, volume, fPtr, filename_w,
+ EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE | \
+ EFI_FILE_MODE_CREATE, 0);
+ if (fPtr == NULL) {
+ uefi_printf_wolfssl("File Pointer is NULL after Open Call\n");
+ return NULL;
+ }
+ break;
+
+ case READWRITE:
+ /* custom I/O not written for this TODO if needed */
+ uefi_printf_wolfssl("Mode: %s for read/write\n", mode);
+ uefi_printf_wolfssl("Not Supported yet\n");
+ return NULL;
+
+ case OPENDIR:
+ uefi_printf_debug("Mode: opendir\n");
+ status = uefi_call_wrapper(volume->Open, 5, volume, fPtr,
+ filename_w, EFI_FILE_MODE_READ, EFI_FILE_DIRECTORY);
+ if (fPtr == NULL || status != 0) {
+ uefi_printf_wolfssl("File Pointer is NULL after Open Call\n");
+ return NULL;
+ }
+ break;
+
+ default:
+ /* Mode not mapped or support yet for custom I/O */
+ uefi_printf_wolfssl("Fopen Mode: %s is not supported\n", mode);
+ return NULL;
+ }
+
+ if (EFI_ERROR(status)) {
+ uefi_printf_wolfssl("Error Opening File: %r\n", status);
+ return 0; /* Return 0 to indicate failure */
+ }
+
+ XFREE(temp, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+ XFREE(filename_w, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+ return (FILE*)fPtr;
+}
+
+/* Closes the file associated with stream, */
+/* returns 0 on success or -1 on failure */
+int fclose(FILE* stream)
+{
+ int ret = -1;
+ (void)stream;
+ EFI_FILE_HANDLE* fPtr = NULL;
+
+ uefi_printf_debug("Inside custom fclose\n");
+ if (stream == NULL) {
+ uefi_printf_wolfssl("NULL pointer given");
+ return -1;
+ }
+ fPtr = (EFI_FILE_HANDLE*)stream;
+
+ uefi_call_wrapper((*fPtr)->Close, 1, *fPtr);
+
+
+ XFREE(fPtr, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+ stream = NULL;
+ uefi_printf_debug("Leaving custom fclose\n");
+
+ return ret;
+}
+
+
+
+
+int fseek(FILE* stream, long offset, int whence) {
+ int ret = -1; /* Default to failure */
+ EFI_FILE_HANDLE* fPtr = NULL;
+ UINT64 currentPosition = 0;
+ UINT64 newPosition = 0;
+ EFI_STATUS status;
+
+ /* Debug message */
+
+ /* Validate the file stream */
+ if (stream == NULL) {
+ uefi_printf_wolfssl("Bad File Pointer Argument\n");
+ return -1;
+ }
+
+ fPtr = (EFI_FILE_HANDLE*)stream;
+
+ /* Handle the 'whence' parameter */
+ switch (whence) {
+ case SEEK_SET:
+ newPosition = offset;
+ break;
+
+ case SEEK_CUR:
+ /* Get the current position */
+ status = uefi_call_wrapper((*fPtr)->GetPosition, 2, *fPtr, ¤tPosition);
+ if (EFI_ERROR(status)) {
+ uefi_printf_wolfssl("Failed to get current position: %r\n", status);
+ return -1;
+ }
+ newPosition = currentPosition + offset;
+ break;
+
+ case SEEK_END:
+ /* Get the file size by seeking to the end */
+ status = uefi_call_wrapper((*fPtr)->SetPosition, 2, *fPtr, 0xFFFFFFFFFFFFFFFF);
+ if (EFI_ERROR(status)) {
+ uefi_printf_wolfssl("Failed to get file size: %r\n", status);
+ return -1;
+ }
+ status = uefi_call_wrapper((*fPtr)->GetPosition, 2, *fPtr, ¤tPosition);
+ if (EFI_ERROR(status)) {
+ uefi_printf_wolfssl("Failed to get end position: %r\n", status);
+ return -1;
+ }
+ newPosition = currentPosition + offset;
+ break;
+
+ default:
+ uefi_printf_wolfssl("Invalid 'whence' value\n");
+ return -1;
+ }
+
+ /* Set the new file position */
+ status = uefi_call_wrapper((*fPtr)->SetPosition, 2, *fPtr, newPosition);
+ if (EFI_ERROR(status)) {
+ uefi_printf_wolfssl("Failed to set position: %r\n", status);
+ return -1;
+ }
+
+ /* Success */
+ ret = 0;
+
+ return ret;
+}
+
+
+/* Returns the current position of the file pointer in the stream, */
+/* or -1L on failure */
+long ftell(FILE* stream)
+{
+ EFI_FILE_HANDLE* fPtr = NULL;
+ uint64_t fSize = 0;
+
+ if (stream == NULL) {
+ uefi_printf_wolfssl("Bad File Pointer Argument\n");
+ return 0;
+ }
+ fPtr = (EFI_FILE_HANDLE*)stream;
+
+ fSize = fileSize(*(fPtr));
+ if (fileSize == 0) {
+ uefi_printf_wolfssl("File is of size 0\n");
+ return 0;
+ }
+
+ return fSize;
+}
+
+
+/* Reads data from the stream into ptr, */
+/* returns the number of items read or 0 on failure */
+size_t fread(void* ptr, size_t size, size_t count, FILE* stream)
+{
+ size_t ret = 0; /* Number of items successfully read */
+ EFI_FILE_HANDLE* fPtr = NULL;
+ uint64_t fSize = 0;
+ if (count > 0) {
+ size = size*count;
+ }
+ if (stream == NULL) {
+ uefi_printf_wolfssl("Bad File Pointer Argument\n");
+ return 0;
+ }
+ fPtr = (EFI_FILE_HANDLE*)stream;
+
+ fSize = fileSize(*(fPtr));
+ if (fileSize == 0) {
+ uefi_printf_wolfssl("File is of size 0\n");
+ return 0;
+ }
+ if (ptr == NULL) {
+ uefi_printf_debug("ptr is NULL\n");
+ }
+ /* Attempt to read from the file */
+ uefi_call_wrapper((*fPtr)->Read, 3, *fPtr, &size, ptr);
+ return size;
+}
+
+char *fgets(char* str, int n, FILE* stream)
+{
+ char* rPtr = NULL;
+ char* tempRead = NULL;
+ int ret = 0;
+ int i = 0;
+ UINTN len = 1;
+
+ if (str == NULL || stream == NULL) {
+ uefi_printf_wolfssl("NULL Arg given to fgets\n");
+ return NULL;
+ }
+
+ tempRead = (char*)XMALLOC((n+1*sizeof(char)), NULL,
+ DYNAMIC_TYPE_TMP_BUFFER);
+ if (tempRead == NULL) {
+ uefi_printf_wolfssl("Malloc Failed in FGETS\n");
+ return NULL;
+ }
+
+ /* read in 1 char at a time */
+ for (i = 0; i < n; i++) {
+ len = 1;
+ ret = ReadSimpleReadFile(stream, i, &len, &tempRead[i]);
+ if (ret == 0) {
+ /* Break out if nothing was read in */
+ break;
+ }
+ if (tempRead[i] == '\n') {
+ break;
+ }
+ }
+
+ /* Nothing at all was read return NULL */
+ if (i == 0) {
+ rPtr = NULL;
+ }
+ else {
+ if (tempRead[i] != '\0') {
+ tempRead[i+1] = '\0';
+ }
+ rPtr = str;
+ }
+
+ XFREE(tempRead, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+
+ return rPtr;
+}
+
+int sscanf(const char *str, const char *format, ...)
+{
+ const char *f = format;
+ const char *s = str;
+ va_list args;
+ int assigned = 0;
+
+ va_start(args, format);
+
+ while (*f) {
+ if (*f == '%') {
+ f++; /* Move past '%' */
+
+ switch (*f) {
+ case 'd': { /* Parse integer */
+ int *intArg = va_arg(args, int *);
+ int value = 0;
+ int negative = 0; /* 0 for positive, 1 for negative */
+
+ /* Skip leading whitespace */
+ while (*s == ' ' || *s == '\t') {
+ s++;
+ }
+
+ /* Handle sign */
+ if (*s == '-') {
+ negative = 1;
+ s++;
+ } else if (*s == '+') {
+ s++;
+ }
+
+ /* Parse digits */
+ while (*s >= '0' && *s <= '9') {
+ value = value * 10 + (*s - '0');
+ s++;
+ }
+
+ *intArg = negative ? -value : value;
+ assigned++;
+ break;
+ }
+ case 'f': { /* Parse floating-point */
+ float *floatArg = va_arg(args, float *);
+ float value = 0.0f;
+ float fraction = 0.0f;
+ float divisor = 10.0f;
+ int negative = 0;
+
+ /* Skip leading whitespace */
+ while (*s == ' ' || *s == '\t') {
+ s++;
+ }
+
+ /* Handle sign */
+ if (*s == '-') {
+ negative = 1;
+ s++;
+ } else if (*s == '+') {
+ s++;
+ }
+
+ /* Parse integer part */
+ while (*s >= '0' && *s <= '9') {
+ value = value * 10.0f + (*s - '0');
+ s++;
+ }
+
+ /* Parse fractional part */
+ if (*s == '.') {
+ s++;
+ while (*s >= '0' && *s <= '9') {
+ fraction += (*s - '0') / divisor;
+ divisor *= 10.0f;
+ s++;
+ }
+ }
+
+ *floatArg = (value + fraction) * (negative ? -1.0f : 1.0f);
+ assigned++;
+ break;
+ }
+ case 's': { /* Parse string */
+ char *strArg = va_arg(args, char *);
+
+ /* Skip leading whitespace */
+ while (*s == ' ' || *s == '\t') {
+ s++;
+ }
+
+ /* Copy characters until whitespace or null */
+ while (*s && *s != ' ' && *s != '\t' && *s != '\n') {
+ *strArg++ = *s++;
+ }
+ *strArg = '\0'; /* Null-terminate the string */
+ assigned++;
+ break;
+ }
+ case 'l': { /* Handle 'l' length modifier */
+ f++; /* Move past 'l' */
+ if (*f == 'd') { /* Parse long integer */
+ long *longArg = va_arg(args, long *);
+ long value = 0;
+ int negative = 0;
+
+ /* Skip leading whitespace */
+ while (*s == ' ' || *s == '\t') {
+ s++;
+ }
+
+ /* Handle sign */
+ if (*s == '-') {
+ negative = 1;
+ s++;
+ } else if (*s == '+') {
+ s++;
+ }
+
+ /* Parse digits */
+ while (*s >= '0' && *s <= '9') {
+ value = value * 10 + (*s - '0');
+ s++;
+ }
+
+ *longArg = negative ? -value : value;
+ assigned++;
+ } else if (*f == 'u') { /* Parse unsigned long integer */
+ unsigned long *ulongArg = va_arg(args, unsigned long *);
+ unsigned long value = 0;
+
+ /* Skip leading whitespace */
+ while (*s == ' ' || *s == '\t') {
+ s++;
+ }
+
+ /* Parse digits */
+ while (*s >= '0' && *s <= '9') {
+ value = value * 10 + (*s - '0');
+ s++;
+ }
+
+ *ulongArg = value;
+ assigned++;
+ } else if (*f == 'f') { /* Parse double */
+ double *doubleArg = va_arg(args, double *);
+ double value = 0.0;
+ double fraction = 0.0;
+ double divisor = 10.0;
+ int negative = 0;
+
+ /* Skip leading whitespace */
+ while (*s == ' ' || *s == '\t') {
+ s++;
+ }
+
+ /* Handle sign */
+ if (*s == '-') {
+ negative = 1;
+ s++;
+ } else if (*s == '+') {
+ s++;
+ }
+
+ /* Parse integer part */
+ while (*s >= '0' && *s <= '9') {
+ value = value * 10.0 + (*s - '0');
+ s++;
+ }
+
+ /* Parse fractional part */
+ if (*s == '.') {
+ s++;
+ while (*s >= '0' && *s <= '9') {
+ fraction += (*s - '0') / divisor;
+ divisor *= 10.0;
+ s++;
+ }
+ }
+
+ *doubleArg = (value + fraction) * (negative ? -1.0 : 1.0);
+ assigned++;
+ } else {
+ /* Unsupported 'l' format */
+ va_end(args);
+ return -1;
+ }
+ break;
+ }
+ default:
+ /* Unsupported format specifier */
+ uefi_printf_wolfssl("SSCANF Case Not Supported: %c\n", *f);
+ va_end(args);
+ return -1;
+ }
+ } else if (*s == *f) {
+ /* Match literal character */
+ s++;
+ } else {
+ /* Mismatch */
+ break;
+ }
+ f++;
+ }
+
+ va_end(args);
+ return assigned;
+}
+
+int mkdir(const char *pathname, mode_t mode)
+{
+ int ret = -1;
+ uefi_printf_wolfssl("MKDIR not Implemented\n");
+ return ret;
+}
+
+DIR *opendir(const char *name)
+{
+ DIR* ptr = NULL;
+ uefi_printf_wolfssl("OPENDIR not Implemented\n");
+ return ptr;
+}
+
+size_t fwrite(const void* ptr, size_t size, size_t count, FILE* stream)
+{
+ size_t ret = 0; /* Number of items successfully written */
+ EFI_FILE_HANDLE* fPtr = NULL;
+ //UINTN totalBytes = count * size * 8; /* Total bytes to write */
+ EFI_STATUS status;
+ uefi_printf_debug("Inside custom fwrite\n");
+
+ /* Check for a valid stream */
+ if (stream == NULL) {
+ uefi_printf_wolfssl("Bad File Pointer Argument\n");
+ return 0;
+ }
+
+ if (count > 0) {
+ size = size*count;
+ }
+
+ fPtr = (EFI_FILE_HANDLE*)stream;
+
+ /* Call EFI Write */
+ status = uefi_call_wrapper((*fPtr)->Write, 3, *fPtr, &size, ptr);
+
+ if (EFI_ERROR(status)) {
+ /* Handle error */
+ uefi_printf_wolfssl("EFI_FILE_PROTOCOL Write failed with status: %r\n", status);
+ return 0;
+ }
+
+ uefi_printf_debug("Write succeeded\n");
+ uefi_printf_debug("Leaving custom fwrite\n");
+ return size;
+}
+
+/* Opens a directory stream for the directory specified by name, */
+/* returns a DIR pointer or NULL on failure */
+
+/* Reads the next directory entry from dirp, */
+/* returns a pointer to a dirent structure or NULL on failure */
+struct dirent* readdir(DIR* stream)
+{
+ EFI_STATUS status;
+ size_t ret = 0; /* Number of items successfully read */
+ struct dirent* dirPtr;
+ char16_t tempWide[8192];
+ unsigned int size = 8192;
+ EFI_FILE_HANDLE* fPtr = NULL;
+ uint64_t fSize = 0;
+ if (stream == NULL) {
+ uefi_printf_wolfssl("Bad File Pointer Argument\n");
+ return 0;
+ }
+
+#ifdef UEFI_READDIR /* work in progress */
+ fPtr = (EFI_FILE_HANDLE*)stream;
+
+ dirPtr = (struct dirent*)XMALLOC(sizeof(struct dirent), NULL,
+ DYNAMIC_TYPE_TMP_BUFFER);
+ if (dirPtr == NULL) {
+ uefi_printf_wolfssl("Failed to malloc dirPtr");
+ return NULL;
+ }
+
+ fSize = fileSize(*(fPtr));
+ if (fileSize == 0) {
+ uefi_printf_wolfssl("File is of size 0\n");
+ return 0;
+ }
+
+ uefi_printf_debug("Size of file being read: %d\n", fSize);
+ status = uefi_call_wrapper((*fPtr)->Read, 3, *fPtr, &fSize, tempWide);
+ if (EFI_ERROR(status)) {
+ uefi_printf_wolfssl("Returned %d\n\n", status);
+ if (EFI_ERROR(status) == EFI_NO_MEDIA) {
+ uefi_printf_wolfssl("Error: No medium found on the device.\n");
+ } else if (EFI_ERROR(status) == EFI_DEVICE_ERROR) {
+ uefi_printf_wolfssl("Error: Device reported an error.\n");
+ uefi_printf_wolfssl(" - This could be due to an attempt to read a deleted file.\n");
+ uefi_printf_wolfssl(" - Or the current file position is beyond the end of the file.\n");
+ } else if (EFI_ERROR(status) == EFI_VOLUME_CORRUPTED) {
+ uefi_printf_wolfssl("Error: File system is corrupted.\n");
+ } else if (EFI_ERROR(status) == EFI_BUFFER_TOO_SMALL) {
+ /* The buffer provided is too small */
+ uefi_printf_wolfssl("Error: Buffer size is too small for the requested operation.\n");
+ } else {
+ uefi_printf_wolfssl("Error: Unknown EFI status: %r\n", status);
+ }
+ return NULL;
+ }
+ uefi_printf_debug("Leaving custom readdir\n");
+#else
+ uefi_printf_wolfssl("READDIR not implemented\n");
+#endif
+ return NULL;
+}
+
+/* Closes the directory stream associated with dirp, */
+/* returns 0 on success or -1 on failure */
+int closedir(DIR* dirp)
+{
+ uefi_printf_wolfssl("CLOSEDIR not implemented\n");
+ return -1;
+}
+
+/* Retrieves information about the file or directory specified by path, */
+/* returns 0 on success or -1 on failure */
+int stat(const char* path, struct stat* buf)
+{
+ uefi_printf_wolfssl("STAT not implemented\n");
+ return -1;
+}
+
+
+/* Function to map modes to FILE_OPS enum*/
+FILE_OPS getFileOperation(const char* mode)
+{
+ FILE_OPS option = NONE; /* Assume mode is not supported */
+ if (mode == NULL) {
+ uefi_printf_wolfssl("Bad Argument for Mode was NULL\n");
+ option = NULL_ARG;
+ return option;
+ }
+
+ if (XSTRCMP(mode, "r") == 0 || strcmp(mode, "rb") == 0){
+ option = READ; /* Read-only mode */
+ }
+ else if (XSTRCMP(mode, "w") == 0|| strcmp(mode, "wb") == 0) {
+ option = WRITE; /* Write-only mode */
+ }
+ else if (XSTRCMP(mode, "r+") == 0 || strcmp(mode, "w+") == 0 ||
+ XSTRCMP(mode, "rb+") == 0 || strcmp(mode, "wb+") == 0) {
+ option = READWRITE; /* Read-Write mode */
+ }
+ else if (XSTRCMP(mode, "od") == 0) {
+ option = OPENDIR; /* Read-Write mode */
+ }
+ return option;
+}
+
+EFI_FILE_HANDLE getVolume(void)
+{
+ EFI_LOADED_IMAGE *image = loaded_image;
+ return LibOpenRoot(image->DeviceHandle);
+}
+
+/* RNG SECTION */
+/* Use to seed the HASH DRGB */
+
+
+/* Functions just incase EFI_RNG Protocal Does not exist */
+static unsigned int seed;
+
+void set_seed(double new_seed) {
+ seed = (unsigned int)new_seed;
+}
+
+static unsigned int pseudo_rng() {
+ seed = (seed * 1103515245 + 12345) & 0x7FFFFFFF;
+ return seed;
+}
+
+
+
+int uefi_random_gen(char* output, unsigned int sz)
+{
+ EFI_STATUS status;
+ EFI_RNG_PROTOCOL* rngInterface;
+ EFI_GUID gEfiRngProtocolGuid = EFI_RNG_PROTOCOL_GUID;
+ EFI_RNG_ALGORITHM rngAlgo = EFI_RNG_ALGORITHM_RAW;
+
+ /* Locate the RNG protocol */
+ status = LibLocateProtocol(&gEfiRngProtocolGuid, (void**)&rngInterface);
+ if (EFI_ERROR(status)) {
+ /* Use fake rng seeded by time if functions are not avaliable */
+ uefi_printf_debug("No RNG Avaliable using Alternate\n");
+ set_seed(current_time(0));
+ for (int i = 0; i < sz; i++) {
+ output[i] = (char)(pseudo_rng() & 0xFF);
+ }
+ return 0; /* Fallback to time */
+ }
+
+ /* Generate a random number */
+ status = uefi_call_wrapper(rngInterface->GetRNG, 4, rngInterface,
+ &rngAlgo, sz,
+ output);
+ if (EFI_ERROR(status)) {
+ uefi_printf_wolfssl("RNG Failed\n");
+ return -1; /* Fallback to 0 on error */
+ }
+
+ return 0;
+}
+
+/* Time function */
+
+unsigned long convertToEpochUefi(EFI_TIME ts)
+{
+ /* Calculate the total days since the Unix epoch (1970-01-01) */
+ unsigned long days_since_epoch =
+ (ts.Year - 1970) * 365 +
+ (ts.Year - 1969) / 4 - /* Leap years */
+ (ts.Year - 1901) / 100 +
+ (ts.Year - 1601) / 400 +
+ (367 * ts.Month - 362) / 12 +
+ ts.Day - 1;
+
+ /* Adjust for months after February for leap years */
+ if (ts.Month <= 2) {
+ days_since_epoch -= 1; /* Remove 1 day for pre-March months */
+ if ((ts.Year % 4 == 0 && (ts.Year % 100 != 0 || ts.Year % 400 == 0))) {
+ days_since_epoch += 1; /* Add back 1 day if it's a leap year */
+ }
+ }
+
+ /* Calculate total seconds since epoch */
+ unsigned long total_seconds =
+ days_since_epoch * 86400 + /* Convert days to seconds */
+ ts.Hour * 3600 +
+ ts.Minute * 60 +
+ ts.Second;
+
+ /* Adjust for timezone if specified */
+ if (ts.TimeZone != 2047) {
+ total_seconds -= ts.TimeZone * 60; /* TimeZone is in minutes */
+ }
+
+ return total_seconds;
+}
+
+
+int uefi_timeStruct_wolfssl(EFI_TIME* timeStruct)
+{
+ EFI_STATUS status;
+
+ status = uefi_call_wrapper(RT->GetTime, 2, timeStruct, NULL);
+ if (EFI_ERROR(status)) {
+ uefi_printf_wolfssl("Failed to get time\n");
+ return -1; /* Fallback to 0 on error */
+ }
+
+ return 0;
+}
+
+unsigned long uefi_time_wolfssl(unsigned long* timer)
+{
+ EFI_TIME time_uefi;
+ unsigned long epoch = 0;
+
+ if (uefi_timeStruct_wolfssl(&time_uefi)) {
+ uefi_printf_wolfssl("Failed to get time\n");
+ return 0;
+ }
+ epoch = convertToEpochUefi(time_uefi);
+ if (timer != NULL) {
+ *timer = epoch;
+ }
+ else {
+ uefi_printf_wolfssl("Bad timer argumnet\n");
+ }
+
+ return epoch;
+}
+
+unsigned long long current_time(int reset)
+{
+ (void)reset;
+ unsigned long long seconds = 0;
+ unsigned long long result = 0;
+ EFI_TIME time_uefi;
+
+ if (uefi_timeStruct_wolfssl(&time_uefi)) {
+ uefi_printf_wolfssl("Failed to get time\n");
+ return 0;
+ }
+
+ /* Calculate days since epoch directly using the struct fields */
+ long days_since_epoch =
+ (time_uefi.Year - 1970) * 365 +
+ (time_uefi.Year - 1969) / 4 -
+ (time_uefi.Year - 1901) / 100 +
+ (time_uefi.Year - 1601) / 400 +
+ (367 * time_uefi.Month - 362) / 12 +
+ time_uefi.Day - 1;
+
+ /* Adjust for months after February */
+ if (time_uefi.Month <= 2) {
+ days_since_epoch -= 1;
+ if ((time_uefi.Year % 4 == 0 && (time_uefi.Year % 100 != 0 || time_uefi.Year % 400 == 0))) {
+ days_since_epoch += 1;
+ }
+ }
+
+ /* Convert to total seconds */
+ unsigned long long total_seconds =
+ //(days_since_epoch * 86400) + // Uncomment to return epoch time
+ (time_uefi.Hour * 3600) +
+ (time_uefi.Minute * 60) +
+ time_uefi.Second;
+
+ /* Adjust for timezone if specified */
+ if (time_uefi.TimeZone != 2047) {
+ total_seconds -= time_uefi.TimeZone * 60;
+ }
+
+ /* Calculate seconds as a double */
+#ifdef BENCH_MICROSECOND
+ seconds = (total_seconds * 1000000) + (unsigned long long)(time_uefi.Nanosecond / 1000);
+#else
+ seconds = total_seconds + (unsigned long long)(time_uefi.Nanosecond / 1000000000);
+#endif
+
+ result = seconds;
+ return result;
+}
+
+/* Need to convert to wide char buffer before we can send it to atoi for uefi */
+int atoi(const char *str)
+{
+ int ret;
+ char16_t* tempWide;
+
+ tempWide = (char16_t*)XMALLOC(XSTRLEN(str)*sizeof(char16_t),
+ NULL, DYNAMIC_TYPE_TMP_BUFFER);
+ if (tempWide == NULL) {
+ uefi_printf_wolfssl("UEFI wolfSSL Print Failed: wide char buffer allocation");
+ return -1;
+ }
+
+ char8_to_char16(str, tempWide);
+ ret = Atoi(tempWide);
+ XFREE(tempWide, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+ return ret;
+}
+
+void *uefi_memcpy_wolfssl(void *dst, const void *src, size_t n)
+{
+ size_t i;
+ const char *s = (const char *)src;
+ char *d = (char *)dst;
+
+ /* is 32-bit aligned pointer */
+ if (((size_t)dst & (sizeof(unsigned long)-1)) == 0 &&
+ ((size_t)src & (sizeof(unsigned long)-1)) == 0)
+ {
+ while (n >= sizeof(unsigned long)) {
+ *(unsigned long*)d = *(unsigned long*)s;
+ d += sizeof(unsigned long);
+ s += sizeof(unsigned long);
+ n -= sizeof(unsigned long);
+ }
+ }
+ for (i = 0; i < n; i++) {
+ d[i] = s[i];
+ }
+ return dst;
+}
+
+void *uefi_memmove_wolfssl(void *dst, const void *src, size_t n)
+{
+ size_t i;
+ const char *s = (const char *)src;
+ char *d = (char *)dst;
+
+ if (d < s) {
+ /* Copy forward */
+ for (i = 0; i < n; i++) {
+ d[i] = s[i];
+ }
+ } else if (d > s) {
+ /* Copy backward */
+ for (i = n; i != 0; i--) {
+ d[i - 1] = s[i - 1];
+ }
+ }
+ /* If d == s, do nothing */
+ return dst;
+}
+
+void* uefi_memset_wolfssl(void *str, int c, size_t n)
+{
+ unsigned char* dst = (unsigned char*)str;
+ unsigned char value = (unsigned char)c;
+
+ if (dst == NULL || n == 0)
+ return str;
+
+ while (n-- > 0) {
+ *dst++ = value;
+ }
+
+ return str;
+}
+
+int uefi_memcmp_wolfssl(const void *s1, const void *s2, size_t n)
+{
+ int ret = 0;
+ if (n != 0) {
+ const uint8_t *p1 = s1, *p2 = s2;
+ do {
+ if (*p1++ != *p2++) {
+ ret = *--p1 - *--p2;
+ break;
+ }
+ } while (--n != 0);
+ }
+ return ret;
+}
+
+int uefi_strlen_wolfssl(const char *s)
+{
+ int ret = -1;
+ if (!s)
+ return ret;
+ while (s[++ret] != '\0')
+ ;
+ return ret;
+}
+
+/* do all allocation based on n */
+int uefi_strncmp_wolfssl(const char *s1, const char *s2, size_t n)
+{
+ int ret = -1;
+ char16_t* s1_temp;
+ char16_t* s2_temp;
+ int s1_len;
+ int s2_len;
+
+ if (s1 == NULL || s2 == NULL) {
+ uefi_printf_wolfssl("Null Args to XSTRNCMP\n");
+ }
+
+ s1_len = n*sizeof(char16_t);
+ s2_len = n*sizeof(char16_t);
+
+ /* Nothing to compare */
+ if ((s1_len == 0 && s2_len == 0) || n == 0) {
+ return 0;
+ }
+
+ s1_temp = (char16_t*)XMALLOC(s1_len, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+ if (s1_temp == NULL) {
+ uefi_printf_wolfssl("Failed to malloc s1 in XSTRNCMP\n");
+ return -1;
+ }
+ char8_to_char16_ex(s1, s1_temp, n);
+
+ s2_temp = (char16_t*)XMALLOC(s2_len, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+ if (s2_temp == NULL) {
+ uefi_printf_wolfssl("Failed to malloc s2 in XSTRNCMP\n");
+ XFREE(s1_temp, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+ return -1;
+ }
+ char8_to_char16_ex(s2, s2_temp, n);
+
+ ret = StrnCmp(s1_temp, s2_temp, n);
+
+ XFREE(s1_temp, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+ XFREE(s2_temp, NULL, DYNAMIC_TYPE_TMP_BUFFER);
+ return ret;
+}
+
+int uefi_strcmp_wolfssl(const char *s1, const char *s2)
+{
+ int i = 0;
+ int ret = 0;
+ if (s1 == NULL && s2 == NULL) {
+ return 0;
+ }
+ if (s1 == NULL) {
+ return -1;
+ }
+ if (s2 == NULL) {
+ return 1;
+ }
+ while (s1[i] != '\0' && s2[i] != '\0') {
+ if (s1[i] < s2[i]) {
+ return -1;
+ }
+ if (s1[i] > s2[i]) {
+ return 1;
+ }
+ i++;
+ }
+ if (s1[i] == '\0' && s2[i] == '\0') {
+ return 0;
+ }
+ if (s1[i] == '\0') {
+ return -1;
+ }
+ return 1;
+}
+
+char *uefi_strncpy_wolfssl(char *dest, const char *src, size_t n)
+{
+ size_t i = 0;
+ if (dest == NULL || src == NULL) {
+ return NULL;
+ }
+ for (i = 0; i < n && src[i] != '\0'; i++) {
+ dest[i] = src[i];
+ }
+ for (; i < n; i++) {
+ dest[i] = '\0';
+ }
+ return dest;
+}
+
+char *uefi_strcpy_wolfssl(char *dest, const char *src)
+{
+ size_t i = 0;
+ if (dest == NULL || src == NULL) {
+ return NULL;
+ }
+ for (i = 0; src[i] != '\0'; i++) {
+ dest[i] = src[i];
+ }
+ dest[i] = '\0';
+ return dest;
+}
+int uefi_strcasecmp_wolfssl(const char *s1, const char *s2)
+{
+ int diff = 0;
+
+ while (!diff && *s1) {
+ diff = (int)*s1 - (int)*s2;
+
+ if ((diff == 'A' - 'a') || (diff == 'a' - 'A'))
+ diff = 0;
+
+ s1++;
+ s2++;
+ }
+
+ return diff;
+}
+
+int uefi_strncasecmp_wolfssl(const char *s1, const char *s2, size_t n)
+{
+ int diff = 0;
+ size_t i = 0;
+
+ while (!diff && *s1) {
+ diff = (int)*s1 - (int)*s2;
+
+ if ((diff == 'A' - 'a') || (diff == 'a' - 'A'))
+ diff = 0;
+
+ s1++;
+ s2++;
+ if (++i > n)
+ break;
+ }
+ return diff;
+}
+
+char *uefi_strnstr_wolfssl(const char *s1, const char *s2, size_t n)
+{
+ size_t i = 0;
+ size_t j = 0;
+ size_t len = 0;
+
+ if (!s1 || !s2)
+ return NULL;
+
+ len = XSTRLEN(s2);
+
+ if (len > n)
+ return NULL;
+
+ for (i = 0; i < n; i++) {
+ if (s1[i] == s2[0]) {
+ for (j = 0; j < len; j++) {
+ if (s1[i + j] != s2[j])
+ break;
+ }
+ if (j == len)
+ return (char *)(uintptr_t)(s1 + i);
+ }
+ }
+ return NULL;
+}
+
+char *uefi_strncat_wolfssl(char *dest, const char *src, size_t n)
+{
+ size_t len = 0;
+ size_t i = 0;
+
+ if (!dest || !src)
+ return dest;
+
+ len = XSTRLEN(dest);
+
+ if (len >= n)
+ return dest;
+
+ for (i = 0; i < (n - len) && src[i] != '\0'; i++) {
+ dest[len + i] = src[i];
+ }
+ dest[len + i] = '\0';
+ return dest;
+}
+
+unsigned int sleep(unsigned int seconds)
+{
+ unsigned int i = 0;
+ for (i = 0; i < (1000000 * seconds); i++) {
+ }
+ return seconds;
+}
diff --git a/uefi-library/startup-single.nsh b/uefi-library/startup-single.nsh
new file mode 100644
index 00000000..fa535e5d
--- /dev/null
+++ b/uefi-library/startup-single.nsh
@@ -0,0 +1,3 @@
+fs0:
+load libwolfcrypt.efi
+test.efi
diff --git a/uefi-library/startup.nsh b/uefi-library/startup.nsh
new file mode 100644
index 00000000..43fbed5d
--- /dev/null
+++ b/uefi-library/startup.nsh
@@ -0,0 +1,9 @@
+fs0:
+load libwolfcrypt.efi
+if %lasterror% == 0 then
+ goto loaded
+endif
+echo Falling back to software-only driver...
+load libwolfcrypt-nohw.efi
+:loaded
+test.efi
diff --git a/uefi-library/user_settings.h b/uefi-library/user_settings.h
new file mode 100644
index 00000000..aaebc65b
--- /dev/null
+++ b/uefi-library/user_settings.h
@@ -0,0 +1,425 @@
+#ifndef USER_H
+#define USER_H
+#include
+#include
+
+extern int uefi_snprintf_wolfssl(char* buffer, size_t n, const char* format, ...);
+#define XSNPRINTF uefi_snprintf_wolfssl
+extern int uefi_printf_wolfssl(const char*, ...);
+#define XPRINTF uefi_printf_wolfssl
+extern void* uefi_memcpy_wolfssl(void* dest, const void* src, size_t len);
+#define XMEMCPY uefi_memcpy_wolfssl
+extern void* uefi_memset_wolfssl(void* str, int c, size_t n);
+#define XMEMSET uefi_memset_wolfssl
+extern int uefi_strncmp_wolfssl(const char* s1, const char* s2, size_t n);
+#define XSTRNCMP uefi_strncmp_wolfssl
+#define XFFLUSH uefi_wolfssl_fflush
+
+#define XMALLOC XMALLOC
+#define XFREE XFREE
+#define XREALLOC XREALLOC
+#define SINGLE_THREADED
+#define NO_FILESYSTEM
+#define STRING_USER
+#define NO_DSA
+#define NO_MD4
+
+#define WOLFSSL_AES_CFB
+#define HAVE_PKCS7
+#define WC_RNG_SEED_CB
+#undef HAVE_INTEL_RDRAND
+#undef HAVE_INTEL_RDSEED
+#undef USE_INTEL_SPEEDUP
+#undef WOLFSSL_ASM
+
+#define WOLFSSL_SHA3
+#define WC_SHA3_NO_ASM
+#define WC_MLKEM_NO_ASM
+#define WOLFSSL_HAVE_MLKEM
+#define HAVE_PBKDF2
+
+/* ChaCha20 / Poly1305 */
+#define HAVE_CHACHA
+#define HAVE_POLY1305
+#define HAVE_ONE_TIME_AUTH
+
+/* Curve25519 / Ed25519 */
+#define HAVE_CURVE25519
+#define HAVE_ED25519
+
+/* Curve448 / Ed448 */
+#define HAVE_CURVE448
+#define HAVE_ED448
+
+/* Post-quantum: Dilithium (ML-DSA) — native wolfSSL implementation */
+#define HAVE_DILITHIUM
+#define WOLFSSL_WC_DILITHIUM
+/* All levels enabled by default (use WOLFSSL_NO_ML_DSA_44/65/87 to disable) */
+
+/* Falcon requires liboqs; omit unless liboqs is available */
+/* #define HAVE_FALCON */
+
+/* SHA-224 */
+#define WOLFSSL_SHA224
+
+#ifdef WOLFSSL_HAVE_MLKEM
+ #define WOLFSSL_MLKEM_KYBER
+ #define WOLFSSL_WC_MLKEM
+ #define WC_MLKEM_NO_ASM
+ #define WC_SHA3_NO_ASM
+ #ifndef WOLFSSL_SHAKE128
+ #define WOLFSSL_SHAKE128
+ #endif
+ #ifndef WOLFSSL_SHAKE256
+ #define WOLFSSL_SHAKE256
+ #endif
+#else
+ #define WOLFSSL_NO_SHAKE128
+ #define WOLFSSL_NO_SHAKE256
+#endif
+
+
+#define XPRINTF uefi_printf_wolfssl
+#define XFPRINTF uefi_fprintf_wolfssl
+#define XSNPRINTF uefi_snprintf_wolfssl
+#define XVSNPRINTF uefi_vsnprintf_wolfssl
+#define XSTRNCMP uefi_strncmp_wolfssl
+#define XSTRCMP uefi_strcmp_wolfssl
+#define XSTRLEN uefi_strlen_wolfssl
+#define XSTRNCPY uefi_strncpy_wolfssl
+#define XSTRCASECMP uefi_strcasecmp_wolfssl
+#define XSTRNCASECMP uefi_strncasecmp_wolfssl
+#define XSTRNSTR uefi_strnstr_wolfssl
+#define XSTRNCAT uefi_strncat_wolfssl
+#define XMEMCMP uefi_memcmp_wolfssl
+#define XMEMMOVE uefi_memmove_wolfssl
+
+
+/* Only Matter for the test */
+#define CERT_PREFIX "\\" /* Assume everything needs is at the root of device */
+#define CERT_PATH_SEP "\\"
+
+/* Debugging UEFI (for example code only not wolfSSL proper) */
+#if 1
+ #undef UEFI_VERBOSE_DEBUG
+ #define UEFI_VERBOSE_DEBUG
+#endif
+
+/* AES-NI hardware acceleration (hw build only) */
+#ifdef UEFI_HW_ACCEL
+ #define WOLFSSL_AESNI
+#endif
+
+
+/* ------------------------------------------------------------------------- */
+/* Platform */
+/* ------------------------------------------------------------------------- */
+#undef WOLFSSL_GENERAL_ALIGNMENT
+#define WOLFSSL_GENERAL_ALIGNMENT 4
+
+#if 1
+ #undef SINGLE_THREADED
+ #define SINGLE_THREADED
+#else
+ #define HAVE_THREAD_LS
+#endif
+
+#ifdef SINGLE_THREADED
+ #undef NO_THREAD_LS
+ #define NO_THREAD_LS
+#endif
+
+#undef WOLFSSL_USER_IO
+#define WOLFSSL_USER_IO
+
+#undef WOLFSSL_SMALL_STACK
+//#define WOLFSSL_SMALL_STACK
+
+
+
+/* ------------------------------------------------------------------------- */
+/* Math Configuration */
+/* ------------------------------------------------------------------------- */
+
+#undef SIZEOF_LONG_LONG
+#define SIZEOF_LONG_LONG 8
+
+
+#undef USE_FAST_MATH
+#if 1
+ #define USE_FAST_MATH
+ #define FP_MAX_BITS 16384
+
+ #undef TFM_TIMING_RESISTANT
+ #define TFM_TIMING_RESISTANT
+
+#else
+ #define WOLFSSL_SP_MATH_ALL
+ #define WOLFSSL_SP_INT_NEGATIVE
+ #define WOLFSSL_SP_SMALL /* use smaller version of code */
+ /* Maximum math bits (largest supported key bits) */
+ #undef SP_INT_BITS
+ #define SP_INT_BITS 8192
+#endif
+
+
+
+/* ------------------------------------------------------------------------- */
+/* Crypto */
+/* ------------------------------------------------------------------------- */
+/* RSA */
+#undef NO_RSA
+#if 1
+
+ /* half as much memory but twice as slow */
+ #undef RSA_LOW_MEM
+ #define RSA_LOW_MEM
+
+ /* Enables blinding mode, to prevent timing attacks */
+ #if 1
+ #undef WC_RSA_BLINDING
+ #define WC_RSA_BLINDING
+ #else
+ #undef WC_NO_HARDEN
+ #define WC_NO_HARDEN
+ #endif
+
+ /* RSA PSS Support */
+ #if 1
+ #undef WC_RSA_PSS
+ #define WC_RSA_PSS
+
+ #undef WOLFSSL_PSS_LONG_SALT
+ #define WOLFSSL_PSS_LONG_SALT
+
+ #undef WOLFSSL_PSS_SALT_LEN_DISCOVER
+ #define WOLFSSL_PSS_SALT_LEN_DISCOVER
+ #endif
+
+ #if 1
+ #define WC_RSA_NO_PADDING
+ #endif
+
+ #define WOLFSSL_KEY_GEN
+ #define WOLFSSL_RSA_KEY_CHECK
+
+#else
+ #define NO_RSA
+#endif
+
+
+/* ECC */
+#undef HAVE_ECC
+#if 1
+ #define HAVE_ECC
+
+ /* Manually define enabled curves */
+ #undef ECC_USER_CURVES
+ #define ECC_USER_CURVES
+
+ #ifdef ECC_USER_CURVES
+ /* Manual Curve Selection */
+ #define HAVE_ECC192
+ #define HAVE_ECC224
+ #undef NO_ECC256
+ #define HAVE_ECC256
+ #define HAVE_ECC384
+ #define HAVE_ECC521
+ #endif
+
+ /* Fixed point cache (speeds repeated operations against same private key) */
+ #undef FP_ECC
+ //#define FP_ECC
+ #ifdef FP_ECC
+ /* Bits / Entries */
+ #undef FP_ENTRIES
+ #define FP_ENTRIES 2
+ #undef FP_LUT
+ #define FP_LUT 4
+ #endif
+
+ /* Optional ECC calculation method */
+ /* Note: doubles heap usage, but slightly faster */
+ #undef ECC_SHAMIR
+ //#define ECC_SHAMIR
+
+ /* Reduces heap usage, but slower */
+ #undef ECC_TIMING_RESISTANT
+ #define ECC_TIMING_RESISTANT
+
+ /* Use alternate ECC size for ECC math */
+ #ifdef USE_FAST_MATH
+ #undef ALT_ECC_SIZE
+ #define ALT_ECC_SIZE
+
+ /* Speedups specific to curve */
+ #ifndef NO_ECC256
+ #undef TFM_ECC256
+ #define TFM_ECC256
+ #endif
+ #endif
+#endif
+
+/* DH */
+#undef NO_DH
+#if 1
+ #define HAVE_DH
+ /* Use table for DH instead of -lm (math) lib dependency */
+ #if 1
+ #define HAVE_DH_DEFAULT_PARAMS
+ #define WOLFSSL_DH_CONST
+ #define HAVE_FFDHE_2048
+ #define HAVE_FFDHE_3072
+ #define HAVE_FFDHE_4096
+ #define HAVE_FFDHE_6144
+ #define HAVE_FFDHE_8192
+ #endif
+#else
+ #define NO_DH
+#endif
+
+
+/* AES */
+#undef NO_AES
+#if 1
+ #undef HAVE_AES_CBC
+ #define HAVE_AES_CBC
+
+ #undef HAVE_AESGCM
+ #define HAVE_AESGCM
+
+ /* GCM Method (slowest to fastest): GCM_SMALL, GCM_WORD32, GCM_TABLE or
+ * GCM_TABLE_4BIT */
+ #define GCM_TABLE_4BIT
+
+ #undef WOLFSSL_AES_DIRECT
+ #define WOLFSSL_AES_DIRECT
+
+ #undef HAVE_AES_ECB
+ #define HAVE_AES_ECB
+
+ #undef WOLFSSL_AES_COUNTER
+ #define WOLFSSL_AES_COUNTER
+
+ #undef HAVE_AESCCM
+ #define HAVE_AESCCM
+
+ #undef WOLFSSL_AES_OFB
+ #define WOLFSSL_AES_OFB
+
+#else
+ #define NO_AES
+#endif
+
+#undef NO_DES3
+#define NO_DES3
+
+/* ------------------------------------------------------------------------- */
+/* Hashing */
+/* ------------------------------------------------------------------------- */
+/* Sha */
+#undef NO_SHA
+#if 1
+ /* 1k smaller, but 25% slower */
+ // #define USE_SLOW_SHA
+#else
+ #define NO_SHA
+#endif
+
+/* Sha256 */
+#undef NO_SHA256
+#if 1
+ /* Sha224 */
+ #if 1
+ #define WOLFSSL_SHA224
+ #endif
+#else
+ #define NO_SHA256
+#endif
+
+/* Sha512 */
+#undef WOLFSSL_SHA512
+#if 1
+ #define WOLFSSL_SHA512
+
+ /* Sha384 */
+ #undef WOLFSSL_SHA384
+ #if 1
+ #define WOLFSSL_SHA384
+ #endif
+#endif
+
+/* MD5 */
+#undef NO_MD5
+#define NO_MD5
+
+/* HKDF / PRF */
+#undef HAVE_HKDF
+#if 1
+ #define HAVE_HKDF
+ #define WOLFSSL_HAVE_PRF
+#endif
+
+/* CMAC */
+#undef WOLFSSL_CMAC
+#if 1
+ #define WOLFSSL_CMAC
+#endif
+
+
+/* ------------------------------------------------------------------------- */
+/* RNG */
+/* ------------------------------------------------------------------------- */
+
+/* Choose RNG method */
+#if 1
+ /* Use built-in P-RNG (SHA256 based) with HW RNG */
+ /* P-RNG + HW RNG (P-RNG is ~8K) */
+ #undef HAVE_HASHDRBG
+ #define HAVE_HASHDRBG
+#else
+ #undef WC_NO_HASHDRBG
+ #define WC_NO_HASHDRBG
+#endif
+
+ /* Bypass P-RNG and use only HW RNG */
+#if 1
+ #define CUSTOM_RAND_TYPE unsigned int
+ extern int uefi_random_gen(char* output, unsigned int sz);
+ #undef CUSTOM_RAND_GENERATE_SEED
+ #define CUSTOM_RAND_GENERATE_SEED uefi_random_gen
+#endif
+
+/* ------------------------------------------------------------------------- */
+/* Debugging */
+/* ------------------------------------------------------------------------- */
+
+#undef DEBUG_WOLFSSL
+#undef NO_ERROR_STRINGS
+#if 0
+ #define DEBUG_WOLFSSL
+#else
+ #if 0
+ #define NO_ERROR_STRINGS
+ #endif
+#endif
+
+/* ------------------------------------------------------------------------- */
+/* Enable features */
+/* ------------------------------------------------------------------------- */
+#define XMALLOC_USER
+#define WOLFSSL_IGNORE_FILE_WARN
+
+/* ------------------------------------------------------------------------- */
+/* Disable features */
+/* ------------------------------------------------------------------------- */
+
+#define WOLFCRYPT_ONLY
+#define NO_ASN_TIME
+#define NO_OLD_TLS
+#define NO_INLINE
+#define NO_SIG_WRAPPER
+#define NO_CRYPT_BENCHMARK
+#define NO_MAIN_DRIVER
+
+#endif /* USER_H */
diff --git a/uefi-library/utility_wolf.h b/uefi-library/utility_wolf.h
new file mode 100644
index 00000000..6eb6c977
--- /dev/null
+++ b/uefi-library/utility_wolf.h
@@ -0,0 +1,113 @@
+#ifndef UTILITY_WOLF_H
+#define UTILITY_WOLF_H
+
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include
+#include
+#include
+
+
+
+/* Custom Types */
+typedef enum {
+ READ,
+ WRITE,
+ READWRITE,
+ OPENDIR,
+ NONE,
+ NULL_ARG,
+} FILE_OPS;
+
+/* UEFI RNG */
+int uefi_random_gen(char* output, unsigned int sz);
+
+
+/* Logging Functions */
+
+/* These use AsciiPrint and AsciiVSprint and simply wrap to produce a result */
+/* as an int instead of a unsigned int */
+int uefi_printf_wolfssl(const char* msg, ...);
+int uefi_snprintf_wolfssl(char* buffer, size_t n, const char* format, ...);
+int uefi_vsnprintf_wolfssl(char* buffer, size_t size, const char* format,
+ va_list args);
+int uefi_vprintf_wolfssl(const char* msg, va_list args);
+int uefi_fprintf_wolfssl(FILE* stream, const char* format, ...);
+
+int uefi_wolfssl_fflush(FILE* stream);
+
+/* Memory Allocation Functions */
+void* uefi_malloc_wolfssl(size_t n);
+void* uefi_realloc_wolfssl(void* ptr, size_t n);
+void uefi_free_wolfssl(void* ptr);
+void* XMALLOC(size_t n, void* heap, int type);
+void* XREALLOC(void *p, size_t n, void* heap, int type);
+void XFREE(void *p, void* heap, int type);
+
+void* uefi_memcpy_wolfssl(void* dest, const void* src, size_t len);
+void* uefi_memset_wolfssl(void* str, int c, size_t n);
+int uefi_memcmp_wolfssl(const void* s1, const void* s2, size_t n);
+void *uefi_memmove_wolfssl(void* dest, const void* src, size_t n);
+
+char* uefi_strncpy_wolfssl(char* dest, const char* src, size_t len);
+int uefi_strncmp_wolfssl(const char* s1, const char* s2, size_t n);
+int uefi_strcmp_wolfssl(const char* s1, const char* s2);
+int uefi_strlen_wolfssl(const char *s);
+int uefi_strcasecmp_wolfssl(const char* s1, const char* s2);
+int uefi_strncasecmp_wolfssl(const char* s1, const char* s2, size_t n);
+char *uefi_strncat_wolfssl(char* dest, const char* src, size_t len);
+char *uefi_strnstr_wolfssl(const char* haystack, const char* needle, size_t len);
+
+
+/* Utility Functions */
+unsigned long uefi_time_wolfssl(unsigned long* timer);
+unsigned long convertToEpochUefi(EFI_TIME ts);
+int uefi_timeStruct_wolfssl(EFI_TIME* timeStruct);
+int parseAndReplace(const char* msg, char* temp, const char* search, const char* replace);
+void char8_to_char16(const char* str8, char16_t* str16);
+void char8_to_char16_ex(const char* str8, char16_t* str16, int n);
+unsigned int calculateBufferSize(const char* msg, va_list args);
+
+/* Logging Functions */
+void logging_cb(const int logLevel, const char *const logMessage);
+
+
+
+/* Not Implemented Functions */
+int create(char *filename, mode_t mode);
+int open (const char *__file, int __oflag);
+int close(int __fd);
+
+/* Needed for USER IO functions */
+
+/* Functional */
+FILE_OPS getFileOperation(const char* mode);
+EFI_FILE_HANDLE getVolume(void);
+uint64_t fileSize(EFI_FILE_HANDLE FileHandle);
+
+
+
+/* TODO */
+ssize_t read(int fd, void *buf, size_t cnt);
+ssize_t write(int fd, const void* buf, size_t cnt);
+FILE* fopen(const char* filename, const char* mode);
+int fclose(FILE* stream);
+int fseek(FILE* stream, long offset, int whence);
+long ftell(FILE* stream);
+size_t fread(void* ptr, size_t size, size_t count, FILE* stream);
+size_t fwrite(const void* ptr, size_t size, size_t count, FILE* stream);
+DIR* opendir(const char* name);
+struct dirent* readdir(DIR* dirp);
+int closedir(DIR* dirp);
+int stat(const char* path, struct stat* buf);
+void uefi_strerr(const char* message);
+static int write_integer(FILE* stream, int value);
+static int write_string(FILE* stream, const char* str);
+unsigned long long current_time(int reset);
+
+#endif
diff --git a/uefi-library/wolfcrypt_api.h b/uefi-library/wolfcrypt_api.h
new file mode 100644
index 00000000..619ffbc1
--- /dev/null
+++ b/uefi-library/wolfcrypt_api.h
@@ -0,0 +1,682 @@
+#ifndef WOLFCRYPT_API_H_INCLUDED
+#define WOLFCRYPT_API_H_INCLUDED
+
+#include
+#include
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#ifdef HAVE_DILITHIUM
+#include
+#endif
+#ifdef HAVE_FALCON
+#include
+#endif
+
+/* UUID: generated via uuidgen -r */
+/* UUID: a3f2c1d7-8e4b-4f9a-b6c3-1d5e7f0a2b48 */
+#define WOLFCRYPT_PROTOCOL_GUID \
+ { 0xa3f2c1d7, 0x8e4b, 0x4f9a, { 0xb6, 0xc3, 0x1d, 0x5e, 0x7f, 0x0a, 0x2b, 0x48 } }
+
+#ifndef WC_RNG_SEED_CB
+typedef int (*wc_RngSeed_Cb)(OS_Seed* os, byte* seed, word32 sz);
+#endif
+
+#ifndef WOLFSSL_HAVE_MLKEM
+typedef struct MlKemKey MlKemKey;
+#endif
+
+/* ------------------------------------------------------------------ */
+/* AES */
+/* ------------------------------------------------------------------ */
+typedef int (EFIAPI *wc_AesInit_API)(Aes* aes, void* heap, int devId);
+typedef int (EFIAPI *wc_AesSetKey_API)(Aes* aes, const byte* key, word32 len,
+ const byte* iv, int dir);
+typedef int (EFIAPI *wc_AesEcbEncrypt_API)(Aes* aes, byte* out, const byte* in,
+ word32 sz);
+typedef int (EFIAPI *wc_AesEcbDecrypt_API)(Aes* aes, byte* out, const byte* in,
+ word32 sz);
+typedef int (EFIAPI *wc_AesCbcEncrypt_API)(Aes* aes, byte* out, const byte* in,
+ word32 sz);
+typedef int (EFIAPI *wc_AesCbcDecrypt_API)(Aes* aes, byte* out, const byte* in,
+ word32 sz);
+typedef int (EFIAPI *wc_AesCfbEncrypt_API)(Aes* aes, byte* out, const byte* in,
+ word32 sz);
+typedef int (EFIAPI *wc_AesCfbDecrypt_API)(Aes* aes, byte* out, const byte* in,
+ word32 sz);
+typedef int (EFIAPI *wc_AesSetIV_API)(Aes* aes, const byte* iv);
+typedef void (EFIAPI *wc_AesFree_API)(Aes* aes);
+typedef int (EFIAPI *wc_AesGcmSetKey_API)(Aes* aes, const byte* key, word32 len);
+typedef int (EFIAPI *wc_AesGcmEncrypt_API)(Aes* aes, byte* out, const byte* in,
+ word32 sz, const byte* iv, word32 ivSz,
+ byte* authTag, word32 authTagSz,
+ const byte* authIn, word32 authInSz);
+typedef int (EFIAPI *wc_AesGcmDecrypt_API)(Aes* aes, byte* out, const byte* in,
+ word32 sz, const byte* iv, word32 ivSz,
+ const byte* authTag, word32 authTagSz,
+ const byte* authIn, word32 authInSz);
+typedef int (EFIAPI *wc_AesCcmSetKey_API)(Aes* aes, const byte* key, word32 keySz);
+typedef int (EFIAPI *wc_AesCcmEncrypt_API)(Aes* aes, byte* out, const byte* in,
+ word32 inSz, const byte* nonce, word32 nonceSz,
+ byte* authTag, word32 authTagSz,
+ const byte* authIn, word32 authInSz);
+typedef int (EFIAPI *wc_AesCcmDecrypt_API)(Aes* aes, byte* out, const byte* in,
+ word32 inSz, const byte* nonce, word32 nonceSz,
+ const byte* authTag, word32 authTagSz,
+ const byte* authIn, word32 authInSz);
+typedef int (EFIAPI *wc_AesCtrEncrypt_API)(Aes* aes, byte* out, const byte* in,
+ word32 sz);
+typedef int (EFIAPI *wc_AesOfbEncrypt_API)(Aes* aes, byte* out, const byte* in,
+ word32 sz);
+
+/* ------------------------------------------------------------------ */
+/* RNG */
+/* ------------------------------------------------------------------ */
+typedef int (EFIAPI *wc_InitRng_API)(WC_RNG* rng);
+typedef int (EFIAPI *wc_FreeRng_API)(WC_RNG* rng);
+typedef int (EFIAPI *wc_RNG_GenerateBlock_API)(WC_RNG* rng, byte* output,
+ word32 sz);
+typedef int (EFIAPI *wc_RNG_GenerateByte_API)(WC_RNG* rng, byte* b);
+typedef int (EFIAPI *wc_SetSeed_Cb_API)(wc_RngSeed_Cb cb);
+typedef int (EFIAPI *wc_RNG_TestSeed_API)(const byte* seed, word32 seedSz);
+typedef int (EFIAPI *wc_GenerateSeed_IntelRD_API)(OS_Seed* os, byte* output,
+ word32 sz);
+typedef int (EFIAPI *wc_GenerateSeed_API)(OS_Seed* os, byte* output,
+ word32 sz);
+typedef int (EFIAPI *wc_GenerateRand_IntelRD_API)(OS_Seed* os, byte* output,
+ word32 sz);
+typedef void (EFIAPI *wc_InitRng_IntelRD_API)(void);
+
+/* ------------------------------------------------------------------ */
+/* RSA */
+/* ------------------------------------------------------------------ */
+typedef int (EFIAPI *wc_InitRsaKey_API)(RsaKey* key, void* heap);
+typedef int (EFIAPI *wc_MakeRsaKey_API)(RsaKey* key, int size, long e,
+ WC_RNG* rng);
+typedef int (EFIAPI *wc_RsaKeyToDer_API)(RsaKey* key, byte* output,
+ word32 inLen);
+typedef int (EFIAPI *wc_FreeRsaKey_API)(RsaKey* key);
+typedef int (EFIAPI *wc_RsaEncryptSize_API)(const RsaKey* key);
+typedef int (EFIAPI *wc_RsaPrivateKeyDecode_API)(const byte* input,
+ word32* inOutIdx,
+ RsaKey* key, word32 inSz);
+typedef int (EFIAPI *wc_RsaPublicKeyDecode_API)(const byte* input,
+ word32* inOutIdx,
+ RsaKey* key, word32 inSz);
+typedef int (EFIAPI *wc_RsaPrivateDecryptEx_API)(const byte* in, word32 inLen,
+ byte* out, word32 outLen,
+ RsaKey* key, int type,
+ enum wc_HashType hash, int mgf,
+ byte* label, word32 labelSz);
+typedef int (EFIAPI *wc_RsaPrivateDecrypt_API)(const byte* in, word32 inLen,
+ byte* out, word32 outLen,
+ RsaKey* key);
+typedef int (EFIAPI *wc_RsaPublicEncrypt_API)(const byte* in, word32 inLen,
+ byte* out, word32 outLen,
+ RsaKey* key, WC_RNG* rng);
+typedef int (EFIAPI *wc_RsaPublicEncryptEx_API)(const byte* in, word32 inLen,
+ byte* out, word32 outLen,
+ RsaKey* key, WC_RNG* rng,
+ int type, enum wc_HashType hash,
+ int mgf, byte* label,
+ word32 labelSz);
+typedef int (EFIAPI *wc_RsaExportKey_API)(RsaKey* key,
+ byte* e, word32* eSz,
+ byte* n, word32* nSz,
+ byte* d, word32* dSz,
+ byte* p, word32* pSz,
+ byte* q, word32* qSz);
+typedef void (EFIAPI *wc_RsaCleanup_API)(RsaKey* key);
+typedef int (EFIAPI *wc_CheckRsaKey_API)(RsaKey* key);
+typedef int (EFIAPI *wc_RsaPublicKeyDerSize_API)(RsaKey* key, int withHeader);
+typedef int (EFIAPI *wc_RsaKeyToPublicDer_API)(RsaKey* key, byte* output,
+ word32 inLen);
+typedef int (EFIAPI *wc_RsaSetRNG_API)(RsaKey* key, WC_RNG* rng);
+
+/* ------------------------------------------------------------------ */
+/* HMAC */
+/* ------------------------------------------------------------------ */
+typedef int (EFIAPI *wc_HmacSetKey_API)(Hmac* hmac, int type, const byte* key,
+ word32 length);
+typedef int (EFIAPI *wc_HmacUpdate_API)(Hmac* hmac, const byte* msg,
+ word32 length);
+typedef int (EFIAPI *wc_HmacFinal_API)(Hmac* hmac, byte* hash);
+
+/* ------------------------------------------------------------------ */
+/* SHA-1 */
+/* ------------------------------------------------------------------ */
+typedef int (EFIAPI *wc_InitSha_API)(wc_Sha* sha);
+typedef int (EFIAPI *wc_ShaUpdate_API)(wc_Sha* sha, const byte* data,
+ word32 len);
+typedef int (EFIAPI *wc_ShaFinal_API)(wc_Sha* sha, byte* hash);
+typedef void (EFIAPI *wc_ShaFree_API)(wc_Sha* sha);
+
+/* ------------------------------------------------------------------ */
+/* SHA-256 / SHA-224 */
+/* ------------------------------------------------------------------ */
+typedef int (EFIAPI *wc_InitSha256_API)(wc_Sha256* sha);
+typedef int (EFIAPI *wc_InitSha256_ex_API)(wc_Sha256* sha, void* heap,
+ int devId);
+typedef int (EFIAPI *wc_Sha256Update_API)(wc_Sha256* sha, const byte* data,
+ word32 len);
+typedef int (EFIAPI *wc_Sha256Final_API)(wc_Sha256* sha256, byte* hash);
+typedef void (EFIAPI *wc_Sha256Free_API)(wc_Sha256* sha256);
+
+/* SHA-224 reuses wc_Sha256 struct with different init */
+typedef int (EFIAPI *wc_InitSha224_API)(wc_Sha224* sha);
+typedef int (EFIAPI *wc_Sha224Update_API)(wc_Sha224* sha, const byte* data,
+ word32 len);
+typedef int (EFIAPI *wc_Sha224Final_API)(wc_Sha224* sha, byte* hash);
+typedef void (EFIAPI *wc_Sha224Free_API)(wc_Sha224* sha);
+
+/* ------------------------------------------------------------------ */
+/* SHA-384 / SHA-512 */
+/* ------------------------------------------------------------------ */
+typedef int (EFIAPI *wc_InitSha384_API)(wc_Sha384* sha);
+typedef int (EFIAPI *wc_Sha384Update_API)(wc_Sha384* sha, const byte* data,
+ word32 len);
+typedef int (EFIAPI *wc_Sha384Final_API)(wc_Sha384* sha, byte* hash);
+typedef void (EFIAPI *wc_Sha384Free_API)(wc_Sha384* sha);
+
+typedef int (EFIAPI *wc_InitSha512_API)(wc_Sha512* sha);
+typedef int (EFIAPI *wc_Sha512Update_API)(wc_Sha512* sha, const byte* data,
+ word32 len);
+typedef int (EFIAPI *wc_Sha512Final_API)(wc_Sha512* sha, byte* hash);
+typedef void (EFIAPI *wc_Sha512Free_API)(wc_Sha512* sha);
+
+/* ------------------------------------------------------------------ */
+/* SHA-3 (256/384/512) and SHAKE128/256 */
+/* ------------------------------------------------------------------ */
+typedef int (EFIAPI *wc_InitSha3_256_API)(wc_Sha3* sha, void* heap, int devId);
+typedef int (EFIAPI *wc_Sha3_256_Update_API)(wc_Sha3* sha, const byte* data, word32 len);
+typedef int (EFIAPI *wc_Sha3_256_Final_API)(wc_Sha3* sha, byte* hash);
+typedef void (EFIAPI *wc_Sha3_256_Free_API)(wc_Sha3* sha);
+
+typedef int (EFIAPI *wc_InitSha3_384_API)(wc_Sha3* sha, void* heap, int devId);
+typedef int (EFIAPI *wc_Sha3_384_Update_API)(wc_Sha3* sha, const byte* data, word32 len);
+typedef int (EFIAPI *wc_Sha3_384_Final_API)(wc_Sha3* sha, byte* hash);
+typedef void (EFIAPI *wc_Sha3_384_Free_API)(wc_Sha3* sha);
+
+typedef int (EFIAPI *wc_InitSha3_512_API)(wc_Sha3* sha, void* heap, int devId);
+typedef int (EFIAPI *wc_Sha3_512_Update_API)(wc_Sha3* sha, const byte* data, word32 len);
+typedef int (EFIAPI *wc_Sha3_512_Final_API)(wc_Sha3* sha, byte* hash);
+typedef void (EFIAPI *wc_Sha3_512_Free_API)(wc_Sha3* sha);
+
+typedef int (EFIAPI *wc_InitShake128_API)(wc_Shake* shake, void* heap, int devId);
+typedef int (EFIAPI *wc_Shake128_Update_API)(wc_Shake* shake, const byte* data, word32 len);
+typedef int (EFIAPI *wc_Shake128_Final_API)(wc_Shake* shake, byte* hash, word32 hashLen);
+typedef int (EFIAPI *wc_Shake128_SqueezeBlocks_API)(wc_Shake* shake, byte* out, word32 blockCnt);
+typedef void (EFIAPI *wc_Shake128_Free_API)(wc_Shake* shake);
+
+typedef int (EFIAPI *wc_InitShake256_API)(wc_Shake* shake, void* heap, int devId);
+typedef int (EFIAPI *wc_Shake256_Update_API)(wc_Shake* shake, const byte* data, word32 len);
+typedef int (EFIAPI *wc_Shake256_Final_API)(wc_Shake* shake, byte* hash, word32 hashLen);
+typedef int (EFIAPI *wc_Shake256_SqueezeBlocks_API)(wc_Shake* shake, byte* out, word32 blockCnt);
+typedef void (EFIAPI *wc_Shake256_Free_API)(wc_Shake* shake);
+
+/* ------------------------------------------------------------------ */
+/* ECC */
+/* ------------------------------------------------------------------ */
+typedef int (EFIAPI *wc_ecc_init_API)(ecc_key* key);
+typedef void (EFIAPI *wc_ecc_free_API)(ecc_key* key);
+typedef int (EFIAPI *wc_ecc_make_key_API)(WC_RNG* rng, int keysize, ecc_key* key);
+typedef int (EFIAPI *wc_ecc_set_rng_API)(ecc_key* key, WC_RNG* rng);
+typedef int (EFIAPI *wc_ecc_shared_secret_API)(ecc_key* priv, ecc_key* pub,
+ byte* out, word32* outlen);
+typedef int (EFIAPI *wc_ecc_sign_hash_API)(const byte* in, word32 inlen,
+ byte* out, word32* outlen,
+ WC_RNG* rng, ecc_key* key);
+typedef int (EFIAPI *wc_ecc_verify_hash_API)(const byte* sig, word32 siglen,
+ const byte* hash, word32 hashlen,
+ int* stat, ecc_key* key);
+typedef int (EFIAPI *wc_ecc_export_x963_API)(ecc_key* key, byte* out, word32* outLen);
+typedef int (EFIAPI *wc_ecc_import_x963_API)(const byte* in, word32 inLen,
+ ecc_key* key);
+typedef int (EFIAPI *wc_EccKeyToDer_API)(ecc_key* key, byte* output, word32 inLen);
+typedef int (EFIAPI *wc_EccPublicKeyDecode_API)(const byte* input, word32* inOutIdx,
+ ecc_key* key, word32 inSz);
+typedef int (EFIAPI *wc_EccPrivateKeyDecode_API)(const byte* input, word32* inOutIdx,
+ ecc_key* key, word32 inSz);
+
+/* ------------------------------------------------------------------ */
+/* DH */
+/* ------------------------------------------------------------------ */
+typedef int (EFIAPI *wc_DhGenerateParams_API)(WC_RNG* rng, int modSz, DhKey* key);
+typedef int (EFIAPI *wc_DhGenerateKeyPair_API)(DhKey* key, WC_RNG* rng,
+ byte* priv, word32* privSz,
+ byte* pub, word32* pubSz);
+typedef int (EFIAPI *wc_DhAgree_API)(DhKey* key, byte* agree, word32* agreeSz,
+ const byte* priv, word32 privSz,
+ const byte* otherPub, word32 pubSz);
+
+/* ------------------------------------------------------------------ */
+/* ChaCha20 */
+/* ------------------------------------------------------------------ */
+typedef int (EFIAPI *wc_Chacha_SetKey_API)(ChaCha* ctx, const byte* key, word32 keySz);
+typedef int (EFIAPI *wc_Chacha_Process_API)(ChaCha* ctx, byte* output,
+ const byte* input, word32 msglen);
+
+/* ------------------------------------------------------------------ */
+/* Poly1305 */
+/* ------------------------------------------------------------------ */
+typedef int (EFIAPI *wc_Poly1305SetKey_API)(Poly1305* ctx, const byte* key, word32 keySz);
+typedef int (EFIAPI *wc_Poly1305Update_API)(Poly1305* ctx, const byte* m, word32 bytes);
+typedef int (EFIAPI *wc_Poly1305Final_API)(Poly1305* ctx, byte* tag);
+
+/* ------------------------------------------------------------------ */
+/* ChaCha20-Poly1305 AEAD */
+/* ------------------------------------------------------------------ */
+typedef int (EFIAPI *wc_ChaCha20Poly1305_Encrypt_API)(
+ const byte* inKey, const byte* inIV,
+ const byte* inAAD, word32 inAADLen,
+ const byte* inPlaintext, word32 inPlaintextLen,
+ byte* outCiphertext, byte* outAuthTag);
+typedef int (EFIAPI *wc_ChaCha20Poly1305_Decrypt_API)(
+ const byte* inKey, const byte* inIV,
+ const byte* inAAD, word32 inAADLen,
+ const byte* inCiphertext, word32 inCiphertextLen,
+ const byte* inAuthTag, byte* outPlaintext);
+
+/* ------------------------------------------------------------------ */
+/* Curve25519 */
+/* ------------------------------------------------------------------ */
+typedef int (EFIAPI *wc_curve25519_init_API)(curve25519_key* key);
+typedef void (EFIAPI *wc_curve25519_free_API)(curve25519_key* key);
+typedef int (EFIAPI *wc_curve25519_make_key_API)(WC_RNG* rng, int keysize,
+ curve25519_key* key);
+typedef int (EFIAPI *wc_curve25519_shared_secret_API)(curve25519_key* priv,
+ curve25519_key* pub,
+ byte* out, word32* outlen);
+typedef int (EFIAPI *wc_curve25519_export_key_raw_API)(curve25519_key* key,
+ byte* priv, word32* privSz,
+ byte* pub, word32* pubSz);
+typedef int (EFIAPI *wc_curve25519_import_public_API)(const byte* in, word32 inLen,
+ curve25519_key* key);
+
+/* ------------------------------------------------------------------ */
+/* Ed25519 */
+/* ------------------------------------------------------------------ */
+typedef int (EFIAPI *wc_ed25519_init_API)(ed25519_key* key);
+typedef void (EFIAPI *wc_ed25519_free_API)(ed25519_key* key);
+typedef int (EFIAPI *wc_ed25519_make_key_API)(WC_RNG* rng, int keysize,
+ ed25519_key* key);
+typedef int (EFIAPI *wc_ed25519_sign_msg_API)(const byte* in, word32 inlen,
+ byte* out, word32* outlen,
+ ed25519_key* key);
+typedef int (EFIAPI *wc_ed25519_verify_msg_API)(const byte* sig, word32 siglen,
+ const byte* msg, word32 msglen,
+ int* stat, ed25519_key* key);
+typedef int (EFIAPI *wc_ed25519_export_key_API)(ed25519_key* key,
+ byte* priv, word32* privSz,
+ byte* pub, word32* pubSz);
+typedef int (EFIAPI *wc_ed25519_import_public_API)(const byte* in, word32 inLen,
+ ed25519_key* key);
+
+/* ------------------------------------------------------------------ */
+/* ML-KEM */
+/* ------------------------------------------------------------------ */
+#ifdef WOLFSSL_HAVE_MLKEM
+typedef int (EFIAPI *wc_MlKemKey_Init_API)(MlKemKey* key, int type, void* heap,
+ int devId);
+typedef int (EFIAPI *wc_MlKemKey_Free_API)(MlKemKey* key);
+typedef int (EFIAPI *wc_MlKemKey_MakeKey_API)(MlKemKey* key, WC_RNG* rng);
+typedef int (EFIAPI *wc_MlKemKey_CipherTextSize_API)(MlKemKey* key, word32* len);
+typedef int (EFIAPI *wc_MlKemKey_SharedSecretSize_API)(MlKemKey* key,
+ word32* len);
+typedef int (EFIAPI *wc_MlKemKey_Encapsulate_API)(MlKemKey* key,
+ unsigned char* ct,
+ unsigned char* ss,
+ WC_RNG* rng);
+typedef int (EFIAPI *wc_MlKemKey_Decapsulate_API)(MlKemKey* key,
+ unsigned char* ss,
+ const unsigned char* ct,
+ word32 len);
+typedef int (EFIAPI *wc_MlKemKey_DecodePrivateKey_API)(MlKemKey* key,
+ const unsigned char* in,
+ word32 len);
+typedef int (EFIAPI *wc_MlKemKey_DecodePublicKey_API)(MlKemKey* key,
+ const unsigned char* in,
+ word32 len);
+typedef int (EFIAPI *wc_MlKemKey_PrivateKeySize_API)(MlKemKey* key,
+ word32* len);
+typedef int (EFIAPI *wc_MlKemKey_PublicKeySize_API)(MlKemKey* key,
+ word32* len);
+typedef int (EFIAPI *wc_MlKemKey_EncodePrivateKey_API)(MlKemKey* key,
+ unsigned char* out,
+ word32 len);
+typedef int (EFIAPI *wc_MlKemKey_EncodePublicKey_API)(MlKemKey* key,
+ unsigned char* out,
+ word32 len);
+#endif /* WOLFSSL_HAVE_MLKEM */
+
+/* ------------------------------------------------------------------ */
+/* Dilithium (ML-DSA) */
+/* ------------------------------------------------------------------ */
+#ifdef HAVE_DILITHIUM
+typedef int (EFIAPI *wc_dilithium_init_API)(dilithium_key* key);
+typedef void (EFIAPI *wc_dilithium_free_API)(dilithium_key* key);
+typedef int (EFIAPI *wc_dilithium_set_level_API)(dilithium_key* key, byte level);
+typedef int (EFIAPI *wc_dilithium_make_key_API)(dilithium_key* key, WC_RNG* rng);
+typedef int (EFIAPI *wc_dilithium_sign_msg_API)(const byte* in, word32 inLen,
+ byte* out, word32* outLen,
+ dilithium_key* key, WC_RNG* rng);
+typedef int (EFIAPI *wc_dilithium_verify_msg_API)(const byte* sig, word32 sigLen,
+ const byte* msg, word32 msgLen,
+ int* res, dilithium_key* key);
+typedef int (EFIAPI *wc_dilithium_export_key_API)(dilithium_key* key,
+ byte* priv, word32* privSz,
+ byte* pub, word32* pubSz);
+typedef int (EFIAPI *wc_dilithium_import_key_API)(const byte* priv, word32 privSz,
+ const byte* pub, word32 pubSz,
+ dilithium_key* key);
+#endif /* HAVE_DILITHIUM */
+
+/* ------------------------------------------------------------------ */
+/* Falcon */
+/* ------------------------------------------------------------------ */
+#ifdef HAVE_FALCON
+typedef int (EFIAPI *wc_falcon_init_API)(falcon_key* key);
+typedef void (EFIAPI *wc_falcon_free_API)(falcon_key* key);
+typedef int (EFIAPI *wc_falcon_make_key_API)(falcon_key* key, WC_RNG* rng);
+typedef int (EFIAPI *wc_falcon_sign_msg_API)(const byte* in, word32 inLen,
+ byte* out, word32* outLen,
+ falcon_key* key, WC_RNG* rng);
+typedef int (EFIAPI *wc_falcon_verify_msg_API)(const byte* sig, word32 sigLen,
+ const byte* msg, word32 msgLen,
+ int* res, falcon_key* key);
+typedef int (EFIAPI *wc_falcon_export_key_API)(falcon_key* key,
+ byte* priv, word32* privSz,
+ byte* pub, word32* pubSz);
+typedef int (EFIAPI *wc_falcon_import_key_API)(const byte* priv, word32 privSz,
+ const byte* pub, word32 pubSz,
+ falcon_key* key);
+#endif /* HAVE_FALCON */
+
+/* ------------------------------------------------------------------ */
+/* CMAC */
+/* ------------------------------------------------------------------ */
+typedef int (EFIAPI *wc_InitCmac_API)(Cmac* cmac, const byte* key, word32 keySz,
+ int type, void* unused);
+typedef int (EFIAPI *wc_CmacUpdate_API)(Cmac* cmac, const byte* in, word32 inSz);
+typedef int (EFIAPI *wc_CmacFinal_API)(Cmac* cmac, byte* out, word32* outSz);
+
+/* ------------------------------------------------------------------ */
+/* PBKDF2 / PKCS12 / PKCS7 / HKDF */
+/* ------------------------------------------------------------------ */
+typedef int (EFIAPI *wc_PBKDF2_API)(byte* output, const byte* passwd, int pLen,
+ const byte* salt, int sLen, int iterations,
+ int kLen, int hashType);
+typedef int (EFIAPI *wc_PKCS12_PBKDF_API)(byte* output, const byte* passwd,
+ int passLen, const byte* salt,
+ int saltLen, int iterations,
+ int kLen, int hashType, int id);
+typedef int (EFIAPI *wc_PKCS7_PadData_API)(byte* in, word32 inSz, byte* out,
+ word32 outSz, word32 blockSz);
+typedef int (EFIAPI *wc_HKDF_API)(int type, const byte* inKey, word32 inKeySz,
+ const byte* salt, word32 saltSz,
+ const byte* info, word32 infoSz,
+ byte* out, word32 outSz);
+
+/* ------------------------------------------------------------------ */
+/* Logging / Error / Version */
+/* ------------------------------------------------------------------ */
+typedef int (EFIAPI *wolfSSL_Debugging_ON_API)(void);
+typedef int (EFIAPI *wolfSSL_SetLoggingCb_API)(wolfSSL_Logging_cb cb);
+typedef wolfSSL_Logging_cb (EFIAPI *wolfSSL_GetLoggingCb_API)(void);
+typedef void (EFIAPI *wolfSSL_Debugging_OFF_API)(void);
+
+typedef const char* (EFIAPI *wc_GetErrorString_API)(int error);
+typedef void (EFIAPI *wc_ErrorString_API)(int err, char* buff);
+
+/* ------------------------------------------------------------------ */
+/* Protocol struct */
+/* ------------------------------------------------------------------ */
+extern EFI_GUID g_wolfcrypt_protocol_guid;
+typedef struct {
+ UINT32 Version;
+
+ /* AES */
+ wc_AesInit_API wc_AesInit;
+ wc_AesSetKey_API wc_AesSetKey;
+ wc_AesEcbEncrypt_API wc_AesEcbEncrypt;
+ wc_AesEcbDecrypt_API wc_AesEcbDecrypt;
+ wc_AesCbcEncrypt_API wc_AesCbcEncrypt;
+ wc_AesCbcDecrypt_API wc_AesCbcDecrypt;
+ wc_AesCfbEncrypt_API wc_AesCfbEncrypt;
+ wc_AesCfbDecrypt_API wc_AesCfbDecrypt;
+ wc_AesSetIV_API wc_AesSetIV;
+ wc_AesFree_API wc_AesFree;
+ wc_AesGcmSetKey_API wc_AesGcmSetKey;
+ wc_AesGcmEncrypt_API wc_AesGcmEncrypt;
+ wc_AesGcmDecrypt_API wc_AesGcmDecrypt;
+ wc_AesCcmSetKey_API wc_AesCcmSetKey;
+ wc_AesCcmEncrypt_API wc_AesCcmEncrypt;
+ wc_AesCcmDecrypt_API wc_AesCcmDecrypt;
+ wc_AesCtrEncrypt_API wc_AesCtrEncrypt;
+ wc_AesOfbEncrypt_API wc_AesOfbEncrypt;
+
+ /* RNG */
+ wc_InitRng_API wc_InitRng;
+ wc_FreeRng_API wc_FreeRng;
+ wc_RNG_GenerateBlock_API wc_RNG_GenerateBlock;
+ wc_RNG_GenerateByte_API wc_RNG_GenerateByte;
+ wc_SetSeed_Cb_API wc_SetSeed_Cb;
+ wc_RNG_TestSeed_API wc_RNG_TestSeed;
+ wc_GenerateSeed_IntelRD_API wc_GenerateSeed_IntelRD;
+ wc_GenerateSeed_API wc_GenerateSeed;
+ wc_GenerateRand_IntelRD_API wc_GenerateRand_IntelRD;
+ wc_InitRng_IntelRD_API wc_InitRng_IntelRD;
+
+ /* RSA */
+ wc_InitRsaKey_API wc_InitRsaKey;
+ wc_MakeRsaKey_API wc_MakeRsaKey;
+ wc_RsaKeyToDer_API wc_RsaKeyToDer;
+ wc_FreeRsaKey_API wc_FreeRsaKey;
+ wc_RsaEncryptSize_API wc_RsaEncryptSize;
+ wc_RsaPrivateKeyDecode_API wc_RsaPrivateKeyDecode;
+ wc_RsaPublicKeyDecode_API wc_RsaPublicKeyDecode;
+ wc_RsaPrivateDecryptEx_API wc_RsaPrivateDecryptEx;
+ wc_RsaPrivateDecrypt_API wc_RsaPrivateDecrypt;
+ wc_RsaPublicEncrypt_API wc_RsaPublicEncrypt;
+ wc_RsaPublicEncryptEx_API wc_RsaPublicEncryptEx;
+ wc_RsaExportKey_API wc_RsaExportKey;
+ wc_RsaCleanup_API wc_RsaCleanup;
+ wc_CheckRsaKey_API wc_CheckRsaKey;
+ wc_RsaPublicKeyDerSize_API wc_RsaPublicKeyDerSize;
+ wc_RsaKeyToPublicDer_API wc_RsaKeyToPublicDer;
+ wc_RsaSetRNG_API wc_RsaSetRNG;
+
+ /* HMAC */
+ wc_HmacSetKey_API wc_HmacSetKey;
+ wc_HmacUpdate_API wc_HmacUpdate;
+ wc_HmacFinal_API wc_HmacFinal;
+
+ /* SHA-1 */
+ wc_InitSha_API wc_InitSha;
+ wc_ShaUpdate_API wc_ShaUpdate;
+ wc_ShaFinal_API wc_ShaFinal;
+ wc_ShaFree_API wc_ShaFree;
+
+ /* SHA-224 */
+ wc_InitSha224_API wc_InitSha224;
+ wc_Sha224Update_API wc_Sha224Update;
+ wc_Sha224Final_API wc_Sha224Final;
+ wc_Sha224Free_API wc_Sha224Free;
+
+ /* SHA-256 */
+ wc_InitSha256_API wc_InitSha256;
+ wc_InitSha256_ex_API wc_InitSha256_ex;
+ wc_Sha256Update_API wc_Sha256Update;
+ wc_Sha256Final_API wc_Sha256Final;
+ wc_Sha256Free_API wc_Sha256Free;
+
+ /* SHA-384 */
+ wc_InitSha384_API wc_InitSha384;
+ wc_Sha384Update_API wc_Sha384Update;
+ wc_Sha384Final_API wc_Sha384Final;
+ wc_Sha384Free_API wc_Sha384Free;
+
+ /* SHA-512 */
+ wc_InitSha512_API wc_InitSha512;
+ wc_Sha512Update_API wc_Sha512Update;
+ wc_Sha512Final_API wc_Sha512Final;
+ wc_Sha512Free_API wc_Sha512Free;
+
+ /* SHA-3 */
+ wc_InitSha3_256_API wc_InitSha3_256;
+ wc_Sha3_256_Update_API wc_Sha3_256_Update;
+ wc_Sha3_256_Final_API wc_Sha3_256_Final;
+ wc_Sha3_256_Free_API wc_Sha3_256_Free;
+ wc_InitSha3_384_API wc_InitSha3_384;
+ wc_Sha3_384_Update_API wc_Sha3_384_Update;
+ wc_Sha3_384_Final_API wc_Sha3_384_Final;
+ wc_Sha3_384_Free_API wc_Sha3_384_Free;
+ wc_InitSha3_512_API wc_InitSha3_512;
+ wc_Sha3_512_Update_API wc_Sha3_512_Update;
+ wc_Sha3_512_Final_API wc_Sha3_512_Final;
+ wc_Sha3_512_Free_API wc_Sha3_512_Free;
+
+ /* SHAKE128/256 */
+ wc_InitShake128_API wc_InitShake128;
+ wc_Shake128_Update_API wc_Shake128_Update;
+ wc_Shake128_Final_API wc_Shake128_Final;
+ wc_Shake128_SqueezeBlocks_API wc_Shake128_SqueezeBlocks;
+ wc_Shake128_Free_API wc_Shake128_Free;
+ wc_InitShake256_API wc_InitShake256;
+ wc_Shake256_Update_API wc_Shake256_Update;
+ wc_Shake256_Final_API wc_Shake256_Final;
+ wc_Shake256_SqueezeBlocks_API wc_Shake256_SqueezeBlocks;
+ wc_Shake256_Free_API wc_Shake256_Free;
+
+ /* ECC */
+ wc_ecc_init_API wc_ecc_init;
+ wc_ecc_free_API wc_ecc_free;
+ wc_ecc_make_key_API wc_ecc_make_key;
+ wc_ecc_set_rng_API wc_ecc_set_rng;
+ wc_ecc_shared_secret_API wc_ecc_shared_secret;
+ wc_ecc_sign_hash_API wc_ecc_sign_hash;
+ wc_ecc_verify_hash_API wc_ecc_verify_hash;
+ wc_ecc_export_x963_API wc_ecc_export_x963;
+ wc_ecc_import_x963_API wc_ecc_import_x963;
+ wc_EccKeyToDer_API wc_EccKeyToDer;
+ wc_EccPublicKeyDecode_API wc_EccPublicKeyDecode;
+ wc_EccPrivateKeyDecode_API wc_EccPrivateKeyDecode;
+
+ /* DH */
+ wc_DhGenerateParams_API wc_DhGenerateParams;
+ wc_DhGenerateKeyPair_API wc_DhGenerateKeyPair;
+ wc_DhAgree_API wc_DhAgree;
+
+ /* ChaCha20 */
+ wc_Chacha_SetKey_API wc_Chacha_SetKey;
+ wc_Chacha_Process_API wc_Chacha_Process;
+
+ /* Poly1305 */
+ wc_Poly1305SetKey_API wc_Poly1305SetKey;
+ wc_Poly1305Update_API wc_Poly1305Update;
+ wc_Poly1305Final_API wc_Poly1305Final;
+
+ /* ChaCha20-Poly1305 AEAD */
+ wc_ChaCha20Poly1305_Encrypt_API wc_ChaCha20Poly1305_Encrypt;
+ wc_ChaCha20Poly1305_Decrypt_API wc_ChaCha20Poly1305_Decrypt;
+
+ /* Curve25519 */
+ wc_curve25519_init_API wc_curve25519_init;
+ wc_curve25519_free_API wc_curve25519_free;
+ wc_curve25519_make_key_API wc_curve25519_make_key;
+ wc_curve25519_shared_secret_API wc_curve25519_shared_secret;
+ wc_curve25519_export_key_raw_API wc_curve25519_export_key_raw;
+ wc_curve25519_import_public_API wc_curve25519_import_public;
+
+ /* Ed25519 */
+ wc_ed25519_init_API wc_ed25519_init;
+ wc_ed25519_free_API wc_ed25519_free;
+ wc_ed25519_make_key_API wc_ed25519_make_key;
+ wc_ed25519_sign_msg_API wc_ed25519_sign_msg;
+ wc_ed25519_verify_msg_API wc_ed25519_verify_msg;
+ wc_ed25519_export_key_API wc_ed25519_export_key;
+ wc_ed25519_import_public_API wc_ed25519_import_public;
+
+ /* ML-KEM */
+#ifdef WOLFSSL_HAVE_MLKEM
+ wc_MlKemKey_Init_API wc_MlKemKey_Init;
+ wc_MlKemKey_Free_API wc_MlKemKey_Free;
+ wc_MlKemKey_MakeKey_API wc_MlKemKey_MakeKey;
+ wc_MlKemKey_CipherTextSize_API wc_MlKemKey_CipherTextSize;
+ wc_MlKemKey_SharedSecretSize_API wc_MlKemKey_SharedSecretSize;
+ wc_MlKemKey_Encapsulate_API wc_MlKemKey_Encapsulate;
+ wc_MlKemKey_Decapsulate_API wc_MlKemKey_Decapsulate;
+ wc_MlKemKey_DecodePrivateKey_API wc_MlKemKey_DecodePrivateKey;
+ wc_MlKemKey_DecodePublicKey_API wc_MlKemKey_DecodePublicKey;
+ wc_MlKemKey_PrivateKeySize_API wc_MlKemKey_PrivateKeySize;
+ wc_MlKemKey_PublicKeySize_API wc_MlKemKey_PublicKeySize;
+ wc_MlKemKey_EncodePrivateKey_API wc_MlKemKey_EncodePrivateKey;
+ wc_MlKemKey_EncodePublicKey_API wc_MlKemKey_EncodePublicKey;
+#endif
+
+ /* Dilithium */
+#ifdef HAVE_DILITHIUM
+ wc_dilithium_init_API wc_dilithium_init;
+ wc_dilithium_free_API wc_dilithium_free;
+ wc_dilithium_set_level_API wc_dilithium_set_level;
+ wc_dilithium_make_key_API wc_dilithium_make_key;
+ wc_dilithium_sign_msg_API wc_dilithium_sign_msg;
+ wc_dilithium_verify_msg_API wc_dilithium_verify_msg;
+ wc_dilithium_export_key_API wc_dilithium_export_key;
+ wc_dilithium_import_key_API wc_dilithium_import_key;
+#endif
+
+ /* Falcon */
+#ifdef HAVE_FALCON
+ wc_falcon_init_API wc_falcon_init;
+ wc_falcon_free_API wc_falcon_free;
+ wc_falcon_make_key_API wc_falcon_make_key;
+ wc_falcon_sign_msg_API wc_falcon_sign_msg;
+ wc_falcon_verify_msg_API wc_falcon_verify_msg;
+ wc_falcon_export_key_API wc_falcon_export_key;
+ wc_falcon_import_key_API wc_falcon_import_key;
+#endif
+
+ /* CMAC */
+ wc_InitCmac_API wc_InitCmac;
+ wc_CmacUpdate_API wc_CmacUpdate;
+ wc_CmacFinal_API wc_CmacFinal;
+
+ /* PBKDF2 / PKCS12 / PKCS7 / HKDF */
+ wc_PBKDF2_API wc_PBKDF2;
+ wc_PKCS12_PBKDF_API wc_PKCS12_PBKDF;
+ wc_PKCS7_PadData_API wc_PKCS7_PadData;
+ wc_HKDF_API wc_HKDF;
+
+ /* Logging / Error */
+ wolfSSL_Debugging_ON_API wolfSSL_Debugging_ON;
+ wolfSSL_SetLoggingCb_API wolfSSL_SetLoggingCb;
+ wolfSSL_GetLoggingCb_API wolfSSL_GetLoggingCb;
+ wolfSSL_Debugging_OFF_API wolfSSL_Debugging_OFF;
+
+ wc_GetErrorString_API wc_GetErrorString;
+ wc_ErrorString_API wc_ErrorString;
+} WOLFCRYPT_PROTOCOL;
+
+#endif /* WOLFCRYPT_API_H_INCLUDED */
diff --git a/uefi/Makefile b/uefi-static/Makefile
similarity index 100%
rename from uefi/Makefile
rename to uefi-static/Makefile
diff --git a/uefi/README.md b/uefi-static/README.md
similarity index 100%
rename from uefi/README.md
rename to uefi-static/README.md
diff --git a/uefi/main.c b/uefi-static/main.c
similarity index 100%
rename from uefi/main.c
rename to uefi-static/main.c
diff --git a/uefi/startup.nsh b/uefi-static/startup.nsh
similarity index 100%
rename from uefi/startup.nsh
rename to uefi-static/startup.nsh
diff --git a/uefi/string.c b/uefi-static/string.c
similarity index 100%
rename from uefi/string.c
rename to uefi-static/string.c
diff --git a/uefi/user_settings.h b/uefi-static/user_settings.h
similarity index 100%
rename from uefi/user_settings.h
rename to uefi-static/user_settings.h