Skip to content

Commit

Permalink
uefi: add wolfcrypt uefi example
Browse files Browse the repository at this point in the history
  • Loading branch information
rizlik committed Feb 20, 2024
1 parent 93f4e79 commit 9bd1d64
Show file tree
Hide file tree
Showing 7 changed files with 518 additions and 0 deletions.
10 changes: 10 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -370,6 +370,16 @@ Please see the [utasker/README.md](utasker/README.md) for further usage and
details.


<br />

#### UEFI (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
details.


<br />

## Notes
Expand Down
53 changes: 53 additions & 0 deletions uefi/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
BUILD_DIR=./build
CRYPTO_SRC=./wolfssl/wolfcrypt/src
WOLFSSL_REPO=https://github.com/wolfSSL/wolfssl
CFLAGS=-fpie -ffreestanding -fno-stack-protector -fno-stack-check -fshort-wchar -mno-red-zone -maccumulate-outgoing-args -static-libgcc -nostdlib
# enable user settings
CFLAGS+= -DWOLFSSL_USER_SETTINGS
CFLAGS+=-I./wolfssl/ -I. -I/usr/include/efi
CFLAGS+=-ggdb
CC=gcc
LD=ld
LDFLAGS_START=-static -pie --no-dynamic-linker -Bsymbolic -L/usr/lib -L/usr/lib/gcc/x86_64-pc-linux-gnu/13.2.1/ -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

_OBJS=sha256.o sha3.o misc.o coding.o hmac.o rsa.o random.o wolfmath.o \
integer.o tfm.o asm.o cpuid.o memory.o logging.o wc_port.o asn.o hash.o \
main.o test.o error.o string.o aes.o wc_encrypt.o

OBJS=$(addprefix $(BUILD_DIR)/,$(_OBJS))

$(shell mkdir -p $(BUILD_DIR))

all: wolfcrypt.efi

.PHONY: clone_repo

clone_repo:
@if [ ! -d $(CRYPTO_SRC) ]; then \
git clone $(WOLFSSL_REPO); \
fi

create_build_dir:
@if [ ! -d $(BUILD_DIR) ]; then mkdir $(BUILD_DIR); fi

$(BUILD_DIR)/wolfcrypt.elf: clone_repo $(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)/test.o: $(CRYPTO_SRC)/../test/test.c
$(CC) $(CFLAGS) -c $? -o $@

$(BUILD_DIR)/main.o: main.c
$(CC) $(CFLAGS) -c $? -o $@

$(BUILD_DIR)/string.o: string.c
$(CC) $(CFLAGS) -c $? -o $@

$(BUILD_DIR)/%.o: $(CRYPTO_SRC)/%.c
$(CC) $(CFLAGS) -c $? -o $@

clean:
rm -rf $(BUILD_DIR) wolfcrypt.efi
96 changes: 96 additions & 0 deletions uefi/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
wolfcrypt UEFI Example Applications
===================================

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
```

## 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:\>
```
106 changes: 106 additions & 0 deletions uefi/main.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@

#include <efi.h>
#include <efilib.h>
#include <wolfssl/wolfcrypt/logging.h>
#include <wolfssl/wolfcrypt/test/test.h>

#define STR_SIZE 512

#ifndef WAIT_FOR_GDB
#define WAIT_FOR_GDB 0
#endif

#define uefi_printf(_f_, ...) Print(L##_f_, ##__VA_ARGS__)

void char8_to_char16(const char* str8, wchar_t* str16)
{
size_t i;
size_t size_str8 = strlen(str8);
for (i = 0; i < size_str8; ++i) {
str16[i] = (wchar_t)str8[i];
}
str16[i] = '\0';
}

void logging_cb(const int logLevel, const char *const logMessage)
{
wchar_t str16[STR_SIZE];
char8_to_char16(logMessage, str16);
uefi_printf("%s", str16);
}

void *XMALLOC(size_t n, void* heap, int type)
{
return AllocateZeroPool(n);
}

void *XREALLOC(void *p, size_t n, void* heap, int type)
{
FreePool(p);
p = NULL;
return AllocateZeroPool(n);
}

void XFREE(void *p, void* heap, int type)
{
return FreePool(p);
}

/* TODO: remove dependencies in random.c to open/read/close */
int open (const char *__file, int __oflag)
{
uefi_printf("open\n");
return -1;
}

ssize_t read (int __fd, void *__buf, size_t __nbytes)
{
uefi_printf("read\n");
return -1;
}

int close(int __fd)
{
uefi_printf("close\n");
return -1;
}

EFI_STATUS
EFIAPI
efi_main (EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable)
{
EFI_LOADED_IMAGE *loaded_image = NULL;
volatile int debug = 1;
EFI_STATUS status;
int ret;

InitializeLib(ImageHandle, SystemTable);
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

ret = wolfcrypt_test(NULL);
Print(L"ret: %d\n", ret);

return EFI_SUCCESS;
}
2 changes: 2 additions & 0 deletions uefi/startup.nsh
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
fs0:
wolfcrypt.efi
Loading

0 comments on commit 9bd1d64

Please sign in to comment.