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