uefi: add wolfcrypt uefi example

pull/423/head
Marco Oliverio 2024-02-20 14:44:13 +01:00
parent 93f4e79b18
commit 9bd1d64f6e
7 changed files with 518 additions and 0 deletions

View File

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

53
uefi/Makefile 100644
View File

@ -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
uefi/README.md 100644
View File

@ -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
uefi/main.c 100644
View File

@ -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
uefi/startup.nsh 100644
View File

@ -0,0 +1,2 @@
fs0:
wolfcrypt.efi

227
uefi/string.c 100644
View File

@ -0,0 +1,227 @@
/* 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 <stddef.h>
#include <string.h>
int islower(int c)
{
return (c >= 'a' && c <= 'z');
}
int isupper(int c)
{
return (c >= 'A' && c <= 'Z');
}
int tolower(int c)
{
return isupper(c) ? c - 'A' + 'a' : c;
}
int toupper(int c)
{
return islower(c) ? c - 'a' + 'A' : c;
}
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;
while (!diff && *s1) {
diff = (int)*s1 - (int)*s2;
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 i = 0;
size_t j = strlen(dest);
for (i = 0; i < strlen(src); i++) {
if (j >= (n - 1)) {
break;
}
dest[j++] = src[i];
}
dest[j] = '\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)
{
int diff = 0;
const unsigned char *s1 = (const unsigned char *)_s1;
const unsigned char *s2 = (const unsigned char *)_s2;
while (!diff && n) {
diff = (int)*s1 - (int)*s2;
s1++;
s2++;
n--;
}
return diff;
}
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)
{
size_t i = 0;
while (s[i] != 0)
i++;
return i;
}
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);
}
}

View File

@ -0,0 +1,24 @@
#define WOLFCRYPT_ONLY
#define HAVE_ENTROPY_MEMUSE
#define ENTROPY_MEMUSE_FORCE_FAILURE
#define USE_FAST_MATH
#define FP_MAX_BITS 8192
#define WOLFSSL_SHA3
#define HAVE_HASHDRBG
#define SINGLE_THREADED
#define XMALLOC_USER
#define NO_MD5
#define NO_SHA
#define NO_PKCS8
#define NO_PKCS12
#define NO_DSA
#define NO_ASN_TIME
#define NO_FILESYSTEM
#define NO_INLINE
#define NO_DH
#define NO_DES3
#define NO_MD4
#define NO_SIG_WRAPPER
#define NO_PWDBASED
#define NO_ERROR_STRINGS
#define XPRINTF(_f_, ...) Print(L##_f_, ##__VA_ARGS__)