wolfssl-examples/uefi-library/Makefile

350 lines
14 KiB
Makefile

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 \
-U__unix__ \
-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/wc_mldsa.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