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.
|
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 />
|
<br />
|
||||||
|
|
||||||
## Notes
|
## 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