diff --git a/uefi/Makefile b/uefi/basic-uefi/Makefile similarity index 100% rename from uefi/Makefile rename to uefi/basic-uefi/Makefile diff --git a/uefi/README.md b/uefi/basic-uefi/README.md similarity index 100% rename from uefi/README.md rename to uefi/basic-uefi/README.md diff --git a/uefi/main.c b/uefi/basic-uefi/main.c similarity index 100% rename from uefi/main.c rename to uefi/basic-uefi/main.c diff --git a/uefi/startup.nsh b/uefi/basic-uefi/startup.nsh similarity index 100% rename from uefi/startup.nsh rename to uefi/basic-uefi/startup.nsh diff --git a/uefi/string.c b/uefi/basic-uefi/string.c similarity index 100% rename from uefi/string.c rename to uefi/basic-uefi/string.c diff --git a/uefi/user_settings.h b/uefi/basic-uefi/user_settings.h similarity index 100% rename from uefi/user_settings.h rename to uefi/basic-uefi/user_settings.h diff --git a/uefi/fips-ready-uefi/.gitignore b/uefi/fips-ready-uefi/.gitignore new file mode 100644 index 000000000..6b22cd39f --- /dev/null +++ b/uefi/fips-ready-uefi/.gitignore @@ -0,0 +1,4 @@ +wolf* +.vscode +build +efi.disk \ No newline at end of file diff --git a/uefi/fips-ready-uefi/Makefile b/uefi/fips-ready-uefi/Makefile new file mode 100644 index 000000000..b8b2d8e63 --- /dev/null +++ b/uefi/fips-ready-uefi/Makefile @@ -0,0 +1,76 @@ +BUILD_DIR=./build +CRYPTO_SRC=./wolfssl/wolfcrypt/src +CFLAGS=-maes -msse4 -mpclmul -fpie -ffreestanding -fno-stack-protector -fno-stack-check -fshort-wchar -mno-red-zone -maccumulate-outgoing-args -static-libgcc -nostdlib +CFLAGS+=-DWOLFSSL_USER_SETTINGS +CFLAGS+=-I./wolfssl/ -I. -I/usr/include/efi -I/usr/include/efi/x86_64 +CFLAGS+=-ggdb +CC=gcc +LD=ld +LDFLAGS_START=-static -pie --no-dynamic-linker -Bsymbolic -L/usr/lib -L/usr/lib/gcc/x86_64-linux-gnu/12/ -Lgnu-efi-dir/x86_64/gnuefi -T/usr/lib/elf_x86_64_efi.lds /usr/lib/crt0-efi-x86_64.o $(LDFLAGS) +LDFLAGS_END=-lgnuefi -lefi -lgcc + +# New VPATH and IPATH system +VPATH = . +VPATH += src +VPATH += wolfssl/src +VPATH += wolfssl/wolfcrypt/src +VPATH += wolfssl/wolfcrypt/test +VPATH += wolfssl/wolfcrypt/benchmark + +VPATH := $(VPATH) + +IPATH = . +IPATH += include +IPATH += wolfssl +IPATH := $(IPATH) + +CFLAGS += $(addprefix -I, $(IPATH)) + +# Auto-detect sources +AUTOSEARCH ?= 1 +ifeq ($(AUTOSEARCH), 1) +SRCS += $(wildcard $(addsuffix /*.c, $(VPATH))) +SRCS += $(wildcard $(addsuffix /*.cpp, $(VPATH))) +endif + +# Object files +_OBJS=$(SRCS:.c=.o) +OBJS=$(addprefix $(BUILD_DIR)/,$(notdir $(_OBJS))) + +$(shell mkdir -p $(BUILD_DIR)) + +all: check_wolfssl wolfcrypt.efi + +.PHONY: check_wolfssl +check_wolfssl: + @if [ ! -d "wolfssl" ]; then \ + echo "Error: 'wolfssl' directory does not exist."; \ + exit 1; \ + fi + +.PHONY: wolfssl-dir +wolfssl-dir: + @read -p "Please provide the path to the wolfSSL directory: " dir_path; \ + dir_path=$$(eval echo $$dir_path); \ + if [ -d "$$dir_path" ]; then \ + ln -sf $$dir_path wolfssl; \ + echo "Symlink created: 'wolfssl' -> $$dir_path"; \ + else \ + echo "Error: Provided path '$$dir_path' is not a valid directory."; \ + exit 1; \ + fi + +create_build_dir: + @if [ ! -d $(BUILD_DIR) ]; then mkdir -p $(BUILD_DIR); fi + +$(BUILD_DIR)/wolfcrypt.elf: $(OBJS) + $(LD) $(LDFLAGS_START) $(OBJS) -o $(BUILD_DIR)/wolfcrypt.elf $(LDFLAGS_END) + +wolfcrypt.efi: $(BUILD_DIR)/wolfcrypt.elf + objcopy -j .text -j .sdata -j .data -j .dynamic -j .dynsym -j .rel -j .rela -j .rel.* -j .rela.* -j .reloc --target efi-app-x86_64 --subsystem=10 $(BUILD_DIR)/wolfcrypt.elf wolfcrypt.efi + +$(BUILD_DIR)/%.o: %.c + $(CC) $(CFLAGS) -c $< -o $@ + +clean: + rm -rf $(BUILD_DIR) wolfcrypt.efi \ No newline at end of file diff --git a/uefi/fips-ready-uefi/Makefile.x86_64_PAA b/uefi/fips-ready-uefi/Makefile.x86_64_PAA new file mode 100644 index 000000000..34a097449 --- /dev/null +++ b/uefi/fips-ready-uefi/Makefile.x86_64_PAA @@ -0,0 +1,91 @@ +BUILD_DIR=./build +CRYPTO_SRC=./wolfssl/wolfcrypt/src +CFLAGS=-fpie -ffreestanding -fno-stack-protector -fno-stack-check -fshort-wchar -mno-red-zone -maccumulate-outgoing-args -static-libgcc -nostdlib +CFLAGS+=-DWOLFSSL_USER_SETTINGS -DUEFI -DUEFI_VECTOR_TEST +CFLAGS+=-I./wolfssl/ -I. -I/usr/include/efi -I/usr/include/efi/x86_64 +CFLAGS+=-ggdb -maes +CC=gcc +LD=ld +LDFLAGS_START=-static -pie --no-dynamic-linker -Bsymbolic -L/usr/lib -L/usr/lib/gcc/x86_64-linux-gnu/12/ -L/usr/lib/x86_64-linux-gnu/ -Lgnu-efi-dir/x86_64/gnuefi -T/usr/lib/elf_x86_64_efi.lds /usr/lib/crt0-efi-x86_64.o $(LDFLAGS) +LDFLAGS_END=-lgnuefi -lefi -lgcc + +# New VPATH and IPATH system +VPATH = . +VPATH += src +VPATH += wolfssl/src +VPATH += wolfssl/wolfcrypt/src +VPATH += wolfssl/wolfcrypt/test +VPATH += wolfssl/wolfcrypt/benchmark +VPATH += utilities/src +VPATH := $(VPATH) + +IPATH = . +IPATH += include +IPATH += wolfssl +IPATH += utilities/include +IPATH += ../../ +IPATH += ../../src/harness +IPATH += ../../../optest-140-3 +IPATH := $(IPATH) + +CFLAGS += $(addprefix -I, $(IPATH)) + +# Auto-detect sources +AUTOSEARCH ?= 1 +ifeq ($(AUTOSEARCH), 1) +SRCS += $(wildcard $(addsuffix /*.c, $(VPATH))) +SRCS += $(wildcard $(addsuffix /*.cpp, $(VPATH))) + +# For AESNI PAA +SRCS += wolfssl/wolfcrypt/src/aes_gcm_asm.S +SRCS += wolfssl/wolfcrypt/src/aes_asm.S + +endif + +# Object files +_OBJS=$(SRCS:%.c=$(BUILD_DIR)/%.o) +_OBJS := $(_OBJS:%.S=$(BUILD_DIR)/%.o) + +OBJS=$(addprefix $(BUILD_DIR)/,$(notdir $(_OBJS))) + + +$(shell mkdir -p $(BUILD_DIR)) + +all: check_wolfssl wolfcrypt.efi + +.PHONY: check_wolfssl +check_wolfssl: + @if [ ! -d "wolfssl" ]; then \ + echo "Error: 'wolfssl' directory does not exist."; \ + exit 1; \ + fi + +.PHONY: wolfssl-dir +wolfssl-dir: + @read -p "Please provide the path to the wolfSSL directory: " dir_path; \ + dir_path=$$(eval echo $$dir_path); \ + if [ -d "$$dir_path" ]; then \ + ln -sf $$dir_path wolfssl; \ + echo "Symlink created: 'wolfssl' -> $$dir_path"; \ + else \ + echo "Error: Provided path '$$dir_path' is not a valid directory."; \ + exit 1; \ + fi + +create_build_dir: + @if [ ! -d $(BUILD_DIR) ]; then mkdir -p $(BUILD_DIR); fi + +$(BUILD_DIR)/wolfcrypt.elf: $(OBJS) + $(LD) $(LDFLAGS_START) $(OBJS) -o $(BUILD_DIR)/wolfcrypt.elf $(LDFLAGS_END) + +wolfcrypt.efi: $(BUILD_DIR)/wolfcrypt.elf + objcopy -j .text -j .sdata -j .data -j .dynamic -j .dynsym -j .rel -j .rela -j .rel.* -j .rela.* -j .reloc --target efi-app-x86_64 --subsystem=10 $(BUILD_DIR)/wolfcrypt.elf wolfcrypt.efi + +$(BUILD_DIR)/%.o: %.c + $(CC) $(CFLAGS) -c $< -o $@ + +$(BUILD_DIR)/%.o: %.S + gcc -c $< -o $@ + +clean: + rm -rf $(BUILD_DIR) wolfcrypt.efi \ No newline at end of file diff --git a/uefi/fips-ready-uefi/README.md b/uefi/fips-ready-uefi/README.md new file mode 100644 index 000000000..6825af712 --- /dev/null +++ b/uefi/fips-ready-uefi/README.md @@ -0,0 +1,125 @@ +wolfcrypt UEFI FIPS Ready Example Application +=================================== + +This application is an expansion of the `basic-uefi` project found in the +`wolfssl-examples` github repository. This application is an example on how to +setup a FIPS Ready build of wolfSSL to help kickstart development for an +eventual FIPS required UEFI applicaiton. FIPS Ready is only for evaluation and +development purposes for eventual usage and aquirement of the FIPS Certified +bundle of wolfSSL. FIPS Ready is not certified in anyway, to learn more refer to +the wolfSSL FIPS Ready user guide. + +As UEFI is not POSIX there are a few functions that will need to be added in +order to for wolfSSL to properly function. These functions are like open/close +for files and then standard printing functions that wolfSSL uses. The example +will leverage gnu-efi for some of these standard operations. wolfSSL will need +access to a form of RNG/Entropy as well. + +The functions in this example are not meant for production and only +serve as an example of functions needed for wolfSSL's crypto to function in +UEFI. For how the functions are setup please refer to the comments and +`utility_wolf.c`. + + + +Requires gnu-efi. Tested with qemu and OVFM UEFI implementation. It uses a +custom implementation for string.h functions (`string.c`) based on wolfBoot +`src/string.c`. You can customize the build by changing `user_settings.h` and +adding the relevant `.o` file into the Makefile `_OBJS` variable. + + + +# Compile + +## Pre-requisites + +``` +git make gcc gnu-efi +``` + +You will need to download and unzip the wolfSSL FIPS ready bundle. + +wolfSSL FIPS Ready: + - [bundle download](https://www.wolfssl.com/download/) + - [user guide](https://www.wolfssl.com/documentation/manuals/wolfssl-fips-ready/) + +## build + +``` +make + +``` + +# Test on qemu + +## Pre-requisites +``` +dosfstools qemu qemu-system-x86 ovmf +``` +## Create efi disk + +We need to create a FAT partition to store efi application. + +``` +dd if=/dev/zero of=./efi.disk bs=256M count=1 +sudo mkfs.vfat ./efi.disk +``` + +Move wolfcrypt.efi and startup.nsh into the fat32 partition +``` +mkdir -p /tmp/efi +sudo mount ./efi.disk /tmp/efi -oloop +sudo cp wolfcrypt.efi /tmp/efi +sudo cp startup.nsh /tmp/efi +sudo umount /tmp/efi +``` + +## Run qemu + +``` +qemu-system-x86_64 -bios /path/to/OVMF.fd -display none -serial stdio -net none -m 256M -drive file=./efi.disk,index=0,media=disk,format=raw +``` + +/path/to/OVMF.fd may be /usr/share/edk2-ovmf/x64 or /usr/share/qemu + +## Example output + +``` +UEFI Interactive Shell v2.2 +EDK II +UEFI v2.70 (EDK II, 0x00010000) +Mapping table + FS0: Alias(s):F0a:;BLK0: + PciRoot(0x0)/Pci(0x1,0x1)/Ata(0x0) + BLK1: Alias(s): + PciRoot(0x0)/Pci(0x1,0x1)/Ata(0x0) +Press ESC in 1 seconds to skip startup.nsh or any other key to continue. +Shell> fs0: +FS0:\> wolfcrypt.efi +status: 0x0 +Image base: 0xE15E000 +------------------------------------------------------------------------------ + wolfSSL version ⸵⸶6 +------------------------------------------------------------------------------ +error test passed! +MEMORY test passed! +base64 test passed! +asn test passed! +RANDOM test passed! +SHA-256 test passed! +SHA-3 test passed! +SHAKE128 test passed! +SHAKE256 test passed! +Hash test passed! +HMAC-SHA256 test passed! +HMAC-SHA3 test passed! +AES test passed! +AES192 test passed! +AES256 test passed! +RSA test passed! +logging test passed! +mutex test passed! +Test complete +ret: 0 +FS0:\> +``` diff --git a/uefi/fips-ready-uefi/include/utility_wolf.h b/uefi/fips-ready-uefi/include/utility_wolf.h new file mode 100644 index 000000000..535ee6d3d --- /dev/null +++ b/uefi/fips-ready-uefi/include/utility_wolf.h @@ -0,0 +1,100 @@ +#ifndef UTILITY_WOLF_H +#define UTILITY_WOLF_H + +#include +#include +#include +#include +#include + + + +/* Custom Types */ +typedef enum { + READ, + WRITE, + READWRITE, + OPENDIR, + NONE, + NULL_ARG, +} FILE_OPS; + +/* Done */ +/* 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_uefi(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_strncmp_wolfssl(const char* s1, const char* s2, size_t n); + +/* 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); + +/* Need to review TODO */ + +/* 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); +double current_time(int reset); + +#endif \ No newline at end of file diff --git a/uefi/fips-ready-uefi/main.c b/uefi/fips-ready-uefi/main.c new file mode 100644 index 000000000..c353400c0 --- /dev/null +++ b/uefi/fips-ready-uefi/main.c @@ -0,0 +1,69 @@ + +#include +#include +#include +#include +#include +#include +#include + + +#ifndef WOLFSSL_USER_SETTINGS + #error "USER SETTINGS not set" +#endif + +#ifndef WAIT_FOR_GDB +#define WAIT_FOR_GDB 0 +#endif + +#define uefi_printf uefi_printf_wolfssl +#define uefi_snprintf(_buf_, _size_, _fmt_, ...) SPrint((_buf_), (_size_), L##_fmt_, ##__VA_ARGS__) +FILE* stdout = NULL; +FILE* stderr = NULL; + + +EFI_LOADED_IMAGE* loaded_image; +//EFI_SYSTEM_TABLE* stdout_uefi; + +EFI_STATUS +EFIAPI +efi_main (EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable) +{ + loaded_image = NULL; + volatile int debug = 1; + EFI_STATUS status; + int ret; + + InitializeLib(ImageHandle, SystemTable); + stdout = (FILE*)(SystemTable->ConOut); + wolfSSL_Debugging_ON(); + wolfSSL_SetLoggingCb(logging_cb); + + status = uefi_call_wrapper(SystemTable->BootServices->HandleProtocol, + 3, + ImageHandle, + &LoadedImageProtocol, + (void **)&loaded_image); + Print(L"status: 0x%lx\n", status); + Print(L"Image base: 0x%lx\n", loaded_image->ImageBase); + +#if WAIT_FOR_GDB + /* to debug from gdb: + * + * 1. run qemu with -s option. Take note of Image base value printed by the + * app. + * 2. run gdb, use command: symbol-file wolfcrypt.elf -o $image_base + * with image based value from the print above. + * 3. set variable debug = 0 to exit the loop and continue the debugging */ + while(debug) {}; +#else + (void)debug; +#endif + + fipsEntry(); + //ret = wolfcrypt_test(NULL); + ret = benchmark_test(NULL); + Print(L"ret: %d\n", ret); + + return EFI_SUCCESS; +} diff --git a/uefi/fips-ready-uefi/setup-qemu-uefi.sh b/uefi/fips-ready-uefi/setup-qemu-uefi.sh new file mode 100644 index 000000000..6691ea20b --- /dev/null +++ b/uefi/fips-ready-uefi/setup-qemu-uefi.sh @@ -0,0 +1,101 @@ +#!/bin/bash + +set -e # Exit immediately if a command exits with a non-zero status. + +# Default paths +EFI_DISK="./efi.disk" +EFI_MOUNT_DIR="/tmp/efi" +WOLFCRYPT_EFI="wolfcrypt.efi" +STARTUP_NSH="startup.nsh" +QEMU_BIOS="/usr/share/OVMF/OVMF_CODE.fd" +WOLFSSL_DIR="wolfssl" + +# Self-updating script paths +SCRIPT_FILE=$(realpath "$0") + +update_script_paths() { + echo "Updating paths in the script..." + for var in QEMU_BIOS; do + current_path=$(eval echo \$$var) + echo "Current path for $var: $current_path" + read -p "Do you want to update this path? (y/N): " confirm + if [[ "$confirm" =~ ^[Yy]$ ]]; then + read -p "Enter new path for $var: " new_path + sed -i "s|^$var=\".*\"|$var=\"$new_path\"|" "$SCRIPT_FILE" + eval "$var=\"$new_path\"" + fi + done +} + +prompt_for_path() { + local var_name="$1" + local current_path="$2" + local prompt_msg="$3" + + while [ ! -e "$current_path" ]; do + echo "$prompt_msg" + read -p "Enter a valid path: " new_path + sed -i "s|^$var_name=\".*\"|$var_name=\"$new_path\"|" "$SCRIPT_FILE" + eval "$var_name=\"$new_path\"" + current_path="$new_path" + done +} + +# Function to create the EFI disk +create_efi_disk() { + echo "Creating EFI disk..." + dd if=/dev/zero of="$EFI_DISK" bs=1024M count=1 + sudo mkfs.vfat "$EFI_DISK" +} + +# Function to copy files to the EFI disk +populate_efi_disk() { + echo "Populating EFI disk..." + mkdir -p "$EFI_MOUNT_DIR" + sudo mount "$EFI_DISK" "$EFI_MOUNT_DIR" -o loop + + if [ ! -f "$WOLFCRYPT_EFI" ]; then + echo "Error: $WOLFCRYPT_EFI not found." + exit 1 + fi + + if [ ! -f "$STARTUP_NSH" ]; then + echo "Error: $STARTUP_NSH not found." + exit 1 + fi + sudo cp -rf --dereference wolfssl/* "$EFI_MOUNT_DIR" + sudo cp "$WOLFCRYPT_EFI" "$EFI_MOUNT_DIR" + sudo cp "$STARTUP_NSH" "$EFI_MOUNT_DIR" + sudo umount "$EFI_MOUNT_DIR" + rmdir "$EFI_MOUNT_DIR" +} + +# Function to run QEMU +run_qemu() { + echo "Running QEMU..." + qemu-system-x86_64 \ + -bios "$QEMU_BIOS" \ + -display none \ + -serial stdio \ + -net none \ + -m 512M \ + -drive file="$EFI_DISK",index=0,media=disk,format=raw \ + -object rng-random,filename=/dev/urandom,id=rng0 \ + -device virtio-rng-pci,rng=rng0 +} + +# Main script +if [[ "$1" == "-u" ]]; then + update_script_paths + exit 0 +fi + +prompt_for_path QEMU_BIOS "$QEMU_BIOS" "The path to the QEMU BIOS is invalid or not set." + +if [ ! -f "$EFI_DISK" ]; then + create_efi_disk +fi + +populate_efi_disk +run_qemu + diff --git a/uefi/fips-ready-uefi/src/string.c b/uefi/fips-ready-uefi/src/string.c new file mode 100644 index 000000000..669bd4ac6 --- /dev/null +++ b/uefi/fips-ready-uefi/src/string.c @@ -0,0 +1,340 @@ +/* string.c + * + * Implementations of standard library functions to eliminate external dependencies. + * + * + * Copyright (C) 2021 wolfSSL Inc. + * + * This file is part of wolfSSL. + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfSLL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + +#include +#include +#include + + +int islower(int c) +{ + return (c >= 'a' && c <= 'z'); +} + +int isupper(int c) +{ + return (c >= 'A' && c <= 'Z'); +} + +int tolower(int c) +{ + char16_t wideChar[2] = { (char16_t)c, L'\0' }; + + StrLwr(wideChar); + + return (int)wideChar[0]; +} + +int toupper(int c) +{ + char16_t wideChar[2] = { (char16_t)c, L'\0' }; + + StrUpr(wideChar); + + return (int)wideChar[0]; +} + +int isalpha(int c) +{ + return (isupper(c) || islower(c)); +} + +char *strcat(char *dest, const char *src) +{ + size_t i = 0; + size_t j = strlen(dest); + + for (i = 0; i < strlen(src); i++) { + dest[j++] = src[i]; + } + dest[j] = '\0'; + + return dest; +} + +int strcmp(const char *s1, const char *s2) +{ + int diff = 0; + diff = strcmpa(s1, s2); + return diff; +} + +int strcasecmp(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 strncasecmp(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 *strncat(char *dest, const char *src, size_t n) { + size_t dest_len = strlen(dest); + size_t i; + + /* Copy at most n characters from src */ + for (i = 0; i < n && src[i] != '\0'; i++) { + dest[dest_len + i] = src[i]; + } + + /* Null-terminate the resulting string */ + dest[dest_len + i] = '\0'; + + return dest; +} + + +int strncmp(const char *s1, const char *s2, size_t n) +{ + int diff = 0; + + while (n > 0) { + diff = (unsigned char)*s1 - (unsigned char)*s2; + if (diff || !*s1) + break; + s1++; + s2++; + n--; + } + + return diff; +} + +char *strncpy(char *dst, const char *src, size_t n) +{ + size_t i; + + for (i = 0; i < n; i++) { + dst[i] = src[i]; + if (src[i] == '\0') + break; + } + + return dst; +} + +char *strcpy(char *dst, const char *src) +{ + size_t i = 0; + + while(1) { + dst[i] = src[i]; + if (src[i] == '\0') + break; + i++; + } + + return dst; +} + +int memcmp(const void *_s1, const void *_s2, size_t n) +{ + return CompareMem(_s1, _s2, n); +} + +void* memchr(void const *s, int c_in, size_t n) +{ + unsigned char c = (unsigned char)c_in; + unsigned char *char_ptr = (unsigned char*)s; + for (; n > 0; --n, ++char_ptr) { + if (*char_ptr == c) { + return (void*)char_ptr; + } + } + return NULL; +} + +size_t strlen(const char *s) +{ + return strlena(s); +} + + +size_t strnlen(const char *s, size_t maxlen) +{ + + size_t len = 0; + + while (len < maxlen && s[len] != '\0') { + len++; + } + + return len; + +} + +void *memmove(void *dst, const void *src, size_t n) +{ + int i; + if (dst == src) + return dst; + if (src < dst) { + const char *s = (const char *)src; + char *d = (char *)dst; + for (i = n - 1; i >= 0; i--) { + d[i] = s[i]; + } + return dst; + } else { + return memcpy(dst, src, n); + } +} + + +char* strchr(const char *str, int c) +{ + while (*str != '\0') { + if (*str == (char)c) { + return (char *)str; /* Return pointer to the character */ + } + str++; + } + + /* Check for the null terminator if c is '\0' */ + if (c == '\0') { + return (char *)str; + } + + return NULL; /* Character not found */ +} + + +/* Only needed in string.c */ +double pow(double base, int exp) { + double result = 1.0; + + /* Handle negative exponents */ + if (exp < 0) { + base = 1.0 / base; + exp = -exp; + } + + /* Iterative exponentiation */ + while (exp) { + if (exp % 2 == 1) { /* If the exponent is odd */ + result *= base; + } + base *= base; /* Square the base */ + exp /= 2; /* Reduce the exponent by half */ + } + + return result; +} + +double strtod(const char *str, char **endptr) { + double result = 0.0; + int sign = 1; + double fraction = 0.0; + int fractional_divisor = 1; + int has_fraction = 0; + + /* Skip leading whitespace */ + while (*str == ' ' || *str == '\t' || *str == '\n') { + str++; + } + + /* Handle sign */ + if (*str == '-') { + sign = -1; + str++; + } else if (*str == '+') { + str++; + } + + /* Convert integer part */ + while (*str >= '0' && *str <= '9') { + result = result * 10.0 + (*str - '0'); + str++; + } + + /* Check for fractional part */ + if (*str == '.') { + str++; + has_fraction = 1; + + /* Convert fractional part */ + while (*str >= '0' && *str <= '9') { + fraction = fraction * 10.0 + (*str - '0'); + fractional_divisor *= 10; + str++; + } + + result += fraction / fractional_divisor; + } + + /* Check for scientific notation */ + if (*str == 'e' || *str == 'E') { + str++; + int exp_sign = 1; + int exponent = 0; + + if (*str == '-') { + exp_sign = -1; + str++; + } else if (*str == '+') { + str++; + } + + while (*str >= '0' && *str <= '9') { + exponent = exponent * 10 + (*str - '0'); + str++; + } + + result *= pow(10, exp_sign * exponent); + } + + /* Set endptr if provided */ + if (endptr) { + *endptr = (char *)str; + } + + return sign * result; +} \ No newline at end of file diff --git a/uefi/fips-ready-uefi/src/utility_wolf.c b/uefi/fips-ready-uefi/src/utility_wolf.c new file mode 100644 index 000000000..0b100a936 --- /dev/null +++ b/uefi/fips-ready-uefi/src/utility_wolf.c @@ -0,0 +1,1447 @@ +#include +#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 WOLFSSL_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 = strlen(search); + size_t replaceLen = strlen(replace); + size_t tempIndex = 0; + size_t msgIndex = 0; + + while (msg[msgIndex] != '\0' && tempIndex < MSG_BUFFER_TMP - 1) { + /* Check if the search string matches at the current position */ + if (strncmp(&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 */ + memcpy(&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 = strlen(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 += strlen(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(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 = ((strlen(msg) + calculateBufferSize(msg, argsCpy) + MSG_BUFFER_TMP)); + + temp = (char*)XMALLOC(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 = ((strlen(msg)+calculateBufferSize(msg, argsCpy)+MSG_BUFFER_TMP)); + + temp = (char*)XMALLOC(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 = strlen(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, strlen(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_printf_debug("Before Wrapper\n"); + uefi_call_wrapper((*fPtr)->Flush, 1, *fPtr); + uefi_printf_debug("After Wrapper\n"); + + uefi_printf_debug("Leaving custom fflush\n"); + return 0; +} + +void exit(int n) +{ + Exit(n, 0, "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 = 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 memcpy on old buffer using n.... */ + CopyMem(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 WOLFSSL_NEED_DYNAMIC_PATH_FIX_UEFI + uefi_printf_wolfssl("Filename: %s\n", filename); + /* Malloc out temp buffer to needed size */ + temp = (char*)XMALLOC(strlen(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 WOLFSSL_NEED_DYNAMIC_TYPE_FIX_UEFI + filename_w = (char16_t*)XMALLOC(strlen(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 WOLFSSL_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_printf_debug("Before UEFI Wrapper\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); + uefi_printf_debug("After UEFI Wrapper\n"); + 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_printf_debug("Before UEFI Wrapper\n"); + uefi_call_wrapper(volume->Open, 5, volume, fPtr, filename_w, + EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE | \ + EFI_FILE_MODE_CREATE, 0); + uefi_printf_debug("After UEFI Wrapper\n"); + 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"); + uefi_printf_debug("Before UEFI Wrapper\n"); + status = uefi_call_wrapper(volume->Open, 5, volume, fPtr, + filename_w, EFI_FILE_MODE_READ, EFI_FILE_DIRECTORY); + uefi_printf_debug("After UEFI Wrapper\n"); + 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_printf_debug("Before Wrapper\n"); + uefi_call_wrapper((*fPtr)->Close, 1, *fPtr); + uefi_printf_debug("After Wrapper\n"); + + + 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; + + 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++) { + ret = ReadSimpleReadFile(stream, i, 1, 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 (strcmp(mode, "r") == 0 || strcmp(mode, "rb") == 0){ + option = READ; /* Read-only mode */ + } + else if (strcmp(mode, "w") == 0|| strcmp(mode, "wb") == 0) { + option = WRITE; /* Write-only mode */ + } + else if (strcmp(mode, "r+") == 0 || strcmp(mode, "w+") == 0 || + strcmp(mode, "rb+") == 0 || strcmp(mode, "wb+") == 0) { + option = READWRITE; /* Read-Write mode */ + } + else if (strcmp(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 */ + uefi_printf_debug("Before RNG Locate Call"); + 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 */ + } + uefi_printf_debug("After RNG Locate Call"); + + /* Generate a random number */ + uefi_printf_debug("Before Uefi Wrapper Call"); + 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 */ + } + uefi_printf_debug("After Uefi Wrapper Call"); + + 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; +} + +double current_time(int reset) +{ + (void)reset; + double seconds = 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 - /* Leap years */ + (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 */ + long total_seconds = + days_since_epoch * 86400 + + 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 = (double)total_seconds * 1000000 + (double)time_uefi.Nanosecond / 1000; +#else + seconds = (double)total_seconds + (double)time_uefi.Nanosecond / 1000000000; +#endif + + return seconds; +} + +/* 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(strlen(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* dest, const void* src, size_t len) +{ + CopyMem(dest, src, len); + return dest; +} + +void* uefi_memset_wolfssl(void *str, int c, size_t n) +{ + SetMem(str, n, (uint8_t)c); + return str; +} + + +/* 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 strncmp\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 strncmp\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 strncmp\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; +} + +unsigned int sleep(unsigned int seconds) +{ + unsigned int i = 0; + for (i = 0; i < (1000000 * seconds); i++) { + } + return seconds; +} \ No newline at end of file diff --git a/uefi/fips-ready-uefi/startup.nsh b/uefi/fips-ready-uefi/startup.nsh new file mode 100644 index 000000000..26fd77a49 --- /dev/null +++ b/uefi/fips-ready-uefi/startup.nsh @@ -0,0 +1,2 @@ +fs0: +wolfcrypt.efi diff --git a/uefi/fips-ready-uefi/user_settings.h b/uefi/fips-ready-uefi/user_settings.h new file mode 100644 index 000000000..80c412045 --- /dev/null +++ b/uefi/fips-ready-uefi/user_settings.h @@ -0,0 +1,573 @@ +#ifndef USER_H +#define USER_H + +/* Need for size_t type */ +#include + +#define WOLFCRYPT_ONLY +//#define HAVE_ENTROPY_MEMUSE +//#define ENTROPY_MEMUSE_FORCE_FAILURE +#define USE_FAST_MATH +#define WOLFSSL_SHA3 +#define HAVE_HASHDRBG +#define SINGLE_THREADED +#define XMALLOC_USER +#define NO_ASN_TIME +//#define NO_FILESYSTEM +//#define NO_INLINE +#define WOLFSSL_USE_ALIGN +#define NO_SIG_WRAPPER +#define NO_PWDBASED +#define WOLFSSL_DH_CONST /* No pow or log function avaliable */ +#define NO_ERROR_STRINGS +#define WOLFSSL_TLS13 +#if 1 + #define WOLFSSL_AESNI +#endif +/* only in example code not wolfssl proper */ +#define WOLFSSL_NEED_DYNAMIC_TYPE_FIX_UEFI +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 + +#if 1 + #define printf uefi_printf_wolfssl + #define fprintf uefi_fprintf_wolfssl + #define strerr uefi_strerr + #define vsnprintf uefi_vsnprintf_wolfssl + #define vprintf uefi_vprintf_wolfssl + #define snprintf uefi_snprintf_wolfssl + #define malloc uefi_malloc_wolfssl + #define free uefi_free_wolfssl + #define realloc uefi_realloc_wolfssl + #define memcpy uefi_memcpy_wolfssl + #define memset uefi_memset_wolfssl + #define strncmp uefi_strncmp_wolfssl + #define fflush uefi_wolfssl_fflush +#endif + +#if 0 + #define NO_CRYPT_BENCHMARK +#else + extern double current_time(int reset); + /* Allows custom "custom_time()" function to be used for benchmark */ + #define WOLFSSL_USER_CURRTIME + #define WOLFSSL_GMTIME + #define USER_TICKS + extern unsigned long uefi_time_wolfssl(unsigned long* timer); + #define XTIME uefi_time_wolfssl + #define WOLFSSL_NO_FLOAT_FMT + //#define CONFIG_LOG_MODE_IMMEDIATE + //#define NO_STDIO_FILESYSTEM + //#define WOLFSSL_NEED_DYNAMIC_PATH_FIX_UEFI + #define UEFI_BENCHMARK +#endif + +#define NO_MAIN_DRIVER +#define WOLFSSL_IGNORE_FILE_WARN +extern void fipsEntry(void); +#define NO_ATTRIBUTE_CONSTRUCTOR + +/* Only Matter for the test */ +#define CERT_PREFIX "\\" /* Assume everything needs is at the root of device */ +#define CERT_PATH_SEP "\\" + +//#define WOLFSSL_WOLFSSH +#define FP_MAX_BITS 16384 + +#if 1 /* If Static buffers are required */ + #undef USE_CERT_BUFFERS_2048 + #define USE_CERT_BUFFERS_2048 + + #undef USE_CERT_BUFFERS_1024 + #define USE_CERT_BUFFERS_1024 + + #undef USE_CERT_BUFFERS_256 + #define USE_CERT_BUFFERS_256 +#endif + +/* Essentially need */ +#if 0 + #undef WOLFSSL_NEED_DYNAMIC_TYPE_FIX_UEFI + #define WOLFSSL_NEED_DYNAMIC_TYPE_FIX_UEFI +#endif + +/* Debugging UEFI (for example code only not wolfSSL proper) */ +#if 0 + #undef WOLFSSL_UEFI_VERBOSE_DEBUG + #define WOLFSSL_UEFI_VERBOSE_DEBUG +#endif + +#undef HAVE_FIPS +#if 1 + + #define HAVE_FIPS + + #undef HAVE_FIPS_VERSION + #define HAVE_FIPS_VERSION 5 + + #undef HAVE_FIPS_VERSION_MINOR + #define HAVE_FIPS_VERSION_MINOR 2 + + #undef WC_RNG_SEED_CB + #define WC_RNG_SEED_CB + + #undef WOLFCRYPT_FIPS_CORE_HASH_VALUE + #define WOLFCRYPT_FIPS_CORE_HASH_VALUE A6A081C13719C5B6960A60CC4E2FCB231E60453430CBB92D546899FC9666C65B + +#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 + + #undef TFM_TIMING_RESISTANT + #define TFM_TIMING_RESISTANT + + +#endif + +/* Wolf Single Precision Math */ +#undef WOLFSSL_SP +#if 0 + #define WOLFSSL_SP_MATH_ALL +#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 + + #ifdef HAVE_FIPS + #undef HAVE_ECC_CDH + #define HAVE_ECC_CDH /* Enable cofactor support */ + + #undef NO_STRICT_ECDSA_LEN + #define NO_STRICT_ECDSA_LEN /* Do not force fixed len w/ FIPS */ + + #undef WOLFSSL_VALIDATE_ECC_IMPORT + #define WOLFSSL_VALIDATE_ECC_IMPORT /* Validate import */ + + #undef WOLFSSL_VALIDATE_ECC_KEYGEN + #define WOLFSSL_VALIDATE_ECC_KEYGEN /* Validate generated keys */ + + #undef WOLFSSL_ECDSA_SET_K + #define WOLFSSL_ECDSA_SET_K + + #define WOLFCRYPT_HAVE_SAKKE + + #endif + + /* 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 0 + #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 + + #ifdef HAVE_FIPS + #define WOLFSSL_VALIDATE_FFC_IMPORT + #define HAVE_FFDHE_Q + #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 +#if 0 + #if 1 + #undef WOLFSSL_DES_ECB + #define WOLFSSL_DES_ECB + #endif +#else + #define NO_DES3 +#endif + +/* ChaCha20 / Poly1305 */ +#undef HAVE_CHACHA +#undef HAVE_POLY1305 +#if 0 + #define HAVE_CHACHA + #define HAVE_POLY1305 + + /* Needed for Poly1305 */ + #undef HAVE_ONE_TIME_AUTH + #define HAVE_ONE_TIME_AUTH +#endif + +/* Curve25519 */ +#undef HAVE_CURVE25519 +#if 1 + #define HAVE_CURVE25519 + + /* Optionally use small math (less flash usage, but much slower) */ + #if 1 + #define CURVE25519_SMALL + #endif +#endif + +/* Ed25519 */ +#undef HAVE_ED25519 +#if 1 + #define HAVE_ED25519 /* ED25519 Requires SHA512 */ + + /* Optionally use small math (less flash usage, but much slower) */ + #if 1 + #define ED25519_SMALL + #endif +#endif + + +/* ------------------------------------------------------------------------- */ +/* 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 + /* not unrolled - ~2k smaller and ~25% slower */ + #define USE_SLOW_SHA256 + /* Sha224 */ + #if 1 + #define WOLFSSL_SHA224 + #endif +#else + #define NO_SHA256 +#endif + +/* Sha512 */ +#undef WOLFSSL_SHA512 +#if 1 + #define WOLFSSL_SHA512 + + #define WOLFSSL_NOSHA512_224 /* Not in FIPS mode */ + #define WOLFSSL_NOSHA512_256 /* Not in FIPS mode */ + + /* Sha384 */ + #undef WOLFSSL_SHA384 + #if 1 + #define WOLFSSL_SHA384 + #endif + + /* over twice as small, but 50% slower */ + #define USE_SLOW_SHA512 +#endif + +/* Sha3 */ +#undef WOLFSSL_SHA3 +#if 1 + #define WOLFSSL_SHA3 +#endif + +/* MD5 */ +#undef NO_MD5 +#if 0 + +#else + #define NO_MD5 +#endif + +/* 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 + +/* SHAKE 128/256 */ +#define WOLFSSL_SHAKE128 +#define WOLFSSL_SHAKE256 + + + + +/* 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 +#else + #define NO_RSA +#endif + + + + +/* ------------------------------------------------------------------------- */ +/* RNG */ +/* ------------------------------------------------------------------------- */ + +//#define WC_RNG_SEED_CB + +#if 0 /* the no RNG engine section */ + #define WOLFSSL_GENSEED_FORTEST +#endif + +/* 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 + + + +/* Section for FIPS validation testing only, disable for production */ +#if 0 + //#define NO_CAVP_TDES + //#define USE_NORMAL_PRINTF + //#define USE_NORMAL_SCAN + + //#define WORKING_WITH_AEGISOLVE + #define NO_MAIN_OPTEST_DRIVER + #define OPTEST_LOGGING_ENABLED + #define OPTEST_INVALID_LOGGING_ENABLED + #define OPTEST_RUNNING_ORGANIC + #define HAVE_FORCE_FIPS_FAILURE +// Defined above + #define DEBUG_FIPS_VERBOSE + #define DEBUG_WOLFSSL + + //#define FORCE_BUFFER_TEST + //#define DEEPLY_EMBEDDED + //#define USE_CERT_BUFFERS_2048 + //#define USE_CERT_BUFFERS_256 + //#define NO_WRITE_TEMP_FILES + //#define PROBLEMATIC_DEC_PRIM_VECTOR_FILE +#endif + +#endif /* USER_H */ \ No newline at end of file