uefi: add wolfcrypt uefi example
parent
93f4e79b18
commit
9bd1d64f6e
10
README.md
10
README.md
|
@ -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
|
||||
|
|
|
@ -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
|
|
@ -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:\>
|
||||
```
|
|
@ -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;
|
||||
}
|
|
@ -0,0 +1,2 @@
|
|||
fs0:
|
||||
wolfcrypt.efi
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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__)
|
Loading…
Reference in New Issue