summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/Makefile42
-rw-r--r--lib/configtable.c22
-rw-r--r--lib/console.c218
-rw-r--r--lib/execute.c42
-rw-r--r--lib/guid.c8
-rw-r--r--lib/print_crypto.c32
-rw-r--r--lib/security_policy.c18
-rw-r--r--lib/shell.c6
-rw-r--r--lib/simple_file.c17
-rw-r--r--lib/string.c284
-rw-r--r--lib/variables.c199
11 files changed, 709 insertions, 179 deletions
diff --git a/lib/Makefile b/lib/Makefile
index db5ff711..6d83f789 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -1,9 +1,45 @@
TARGET = lib.a
-LIBFILES = simple_file.o guid.o console.o execute.o configtable.o shell.o variables.o security_policy.o
+LIBFILES_UNSORTED := $(foreach x,$(wildcard *.c),$(patsubst %.c,%.o,$(x)))
+LIBFILES := $(sort $(LIBFILES_UNSORTED))
-EFI_INCLUDES = -I$(EFI_INCLUDE) -I$(EFI_INCLUDE)/$(ARCH) -I$(EFI_INCLUDE)/protocol -I$(TOPDIR)/../include \
- -I$(TOPDIR)/CryptLib/Include/openssl/
+CRYPTDIR = $(TOPDIR)/Cryptlib
+
+INCLUDES = $(EFI_INCLUDES) \
+ -I$(TOPDIR)/include \
+ -I$(CRYPTDIR)/Include/openssl/ \
+ -I$(CRYPTDIR)/Include/ \
+ -I$(CRYPTDIR) \
+ -I$(TOPDIR) \
+ -isystem $(TOPDIR)/include/system \
+ -isystem $(shell $(CC) -print-file-name=include)
+
+CLANG_BUGS = $(if $(findstring gcc,$(CC)),-maccumulate-outgoing-args,)
+
+ifeq ($(ARCH),x86_64)
+FEATUREFLAGS += -m64 -mno-mmx -mno-sse -mno-red-zone -nostdinc $(CLANG_BUGS)
+DEFINES += -DMDE_CPU_X64
+endif
+ifeq ($(ARCH),ia32)
+FEATUREFLAGS += -m32 -mno-mmx -mno-sse -mno-red-zone -nostdinc $(CLANG_BUGS)
+DEFINES += -DMDE_CPU_IA32
+endif
+ifeq ($(ARCH),aarch64)
+DEFINES += -DMDE_CPU_AARCH64
+endif
+ifeq ($(ARCH),arm)
+DEFINES += -DMDE_CPU_ARM
+endif
+
+LDFLAGS = -nostdlib -znocombreloc
+
+
+CFLAGS = $(FEATUREFLAGS) \
+ $(OPTIMIZATIONS) \
+ $(WARNFLAGS) \
+ $(WERRFLAGS) \
+ $(INCLUDES) \
+ $(DEFINES)
lib.a: $(LIBFILES)
$(AR) rcs lib.a $(LIBFILES)
diff --git a/lib/configtable.c b/lib/configtable.c
index df047f0e..66e97f63 100644
--- a/lib/configtable.c
+++ b/lib/configtable.c
@@ -1,13 +1,9 @@
+// SPDX-License-Identifier: BSD-2-Clause-Patent
/*
* Copyright 2013 <James.Bottomley@HansenPartnership.com>
*
- * see COPYING file
- *
* read some platform configuration tables
*/
-#include <efi.h>
-#include <efilib.h>
-
#include "shim.h"
void *
@@ -50,22 +46,22 @@ configtable_find_image(const EFI_DEVICE_PATH *DevicePath)
/* print what we have for debugging */
UINT8 *d = (UINT8 *)e; // + sizeof(UINT32)*2;
console_print(L"Data: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n",
- d[0], d[1], d[2], d[3], d[4], d[5], d[6], d[7], d[8], d[9], d[10], d[11], d[12], d[13], d[14], d[15]);
+ d[0], d[1], d[2], d[3], d[4], d[5], d[6], d[7], d[8], d[9], d[10], d[11], d[12], d[13], d[14], d[15]);
d += 16;
console_print(L"Data: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n",
- d[0], d[1], d[2], d[3], d[4], d[5], d[6], d[7], d[8], d[9], d[10], d[11], d[12], d[13], d[14], d[15]);
+ d[0], d[1], d[2], d[3], d[4], d[5], d[6], d[7], d[8], d[9], d[10], d[11], d[12], d[13], d[14], d[15]);
d += 16;
console_print(L"Data: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n",
- d[0], d[1], d[2], d[3], d[4], d[5], d[6], d[7], d[8], d[9], d[10], d[11], d[12], d[13], d[14], d[15]);
+ d[0], d[1], d[2], d[3], d[4], d[5], d[6], d[7], d[8], d[9], d[10], d[11], d[12], d[13], d[14], d[15]);
d += 16;
console_print(L"Data: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n",
- d[0], d[1], d[2], d[3], d[4], d[5], d[6], d[7], d[8], d[9], d[10], d[11], d[12], d[13], d[14], d[15]);
+ d[0], d[1], d[2], d[3], d[4], d[5], d[6], d[7], d[8], d[9], d[10], d[11], d[12], d[13], d[14], d[15]);
d += 16;
console_print(L"Data: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n",
- d[0], d[1], d[2], d[3], d[4], d[5], d[6], d[7], d[8], d[9], d[10], d[11], d[12], d[13], d[14], d[15]);
+ d[0], d[1], d[2], d[3], d[4], d[5], d[6], d[7], d[8], d[9], d[10], d[11], d[12], d[13], d[14], d[15]);
d += 16;
console_print(L"Data: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n",
- d[0], d[1], d[2], d[3], d[4], d[5], d[6], d[7], d[8], d[9], d[10], d[11], d[12], d[13], d[14], d[15]);
+ d[0], d[1], d[2], d[3], d[4], d[5], d[6], d[7], d[8], d[9], d[10], d[11], d[12], d[13], d[14], d[15]);
#endif
CHAR16 *name = (CHAR16 *)(e->Data);
int skip = 0;
@@ -94,12 +90,12 @@ configtable_find_image(const EFI_DEVICE_PATH *DevicePath)
console_print(L"Device Path Size %d\n", Size);
#endif
if (Size > e->InfoSize) {
- /* parse error; the platform obviously has a
+ /* parse error; the platform obviously has a
* corrupted image table; bail */
console_print(L"Image Execution Information table corrupt\n");
break;
}
-
+
if (CompareMem(dp, (void *)DevicePath, Size) == 0) {
#ifdef DEBUG_CONFIG
console_print(L"***FOUND\n");
diff --git a/lib/console.c b/lib/console.c
index 3aee41cd..c310d213 100644
--- a/lib/console.c
+++ b/lib/console.c
@@ -1,14 +1,8 @@
+// SPDX-License-Identifier: BSD-2-Clause-Patent
/*
* Copyright 2012 <James.Bottomley@HansenPartnership.com>
* Copyright 2013 Red Hat Inc. <pjones@redhat.com>
- *
- * see COPYING file
*/
-#include <efi.h>
-#include <efilib.h>
-#include <stdarg.h>
-#include <stdbool.h>
-
#include "shim.h"
static UINT8 console_text_mode = 0;
@@ -89,27 +83,27 @@ VOID console_fini(VOID)
setup_console(0);
}
-UINTN
+UINTN EFIAPI
console_print(const CHAR16 *fmt, ...)
{
- va_list args;
+ ms_va_list args;
UINTN ret;
if (!console_text_mode)
setup_console(1);
- va_start(args, fmt);
+ ms_va_start(args, fmt);
ret = VPrint(fmt, args);
- va_end(args);
+ ms_va_end(args);
return ret;
}
-UINTN
+UINTN EFIAPI
console_print_at(UINTN col, UINTN row, const CHAR16 *fmt, ...)
{
SIMPLE_TEXT_OUTPUT_INTERFACE *co = ST->ConOut;
- va_list args;
+ ms_va_list args;
UINTN ret;
if (!console_text_mode)
@@ -117,9 +111,9 @@ console_print_at(UINTN col, UINTN row, const CHAR16 *fmt, ...)
co->SetCursorPosition(co, col, row);
- va_start(args, fmt);
+ ms_va_start(args, fmt);
ret = VPrint(fmt, args);
- va_end(args);
+ ms_va_end(args);
return ret;
}
@@ -214,7 +208,7 @@ console_print_box_at(CHAR16 *str_arr[], int highlight,
if (col < 0)
col = 0;
- CopyMem(Line + col + 1, s, min(len, size_cols - 2)*2);
+ CopyMem(Line + col + 1, s, MIN(len, size_cols - 2)*2);
}
if (line >= 0 && line == highlight)
co->SetAttribute(co, EFI_LIGHTGRAY |
@@ -409,12 +403,171 @@ console_notify(CHAR16 *string)
console_alertbox(str_arr);
}
-#define ARRAY_SIZE(a) (sizeof (a) / sizeof ((a)[0]))
+void
+console_save_and_set_mode(SIMPLE_TEXT_OUTPUT_MODE * SavedMode)
+{
+ SIMPLE_TEXT_OUTPUT_INTERFACE *co = ST->ConOut;
+
+ if (!SavedMode) {
+ console_print(L"Invalid parameter: SavedMode\n");
+ return;
+ }
+
+ CopyMem(SavedMode, co->Mode, sizeof(SIMPLE_TEXT_OUTPUT_MODE));
+ co->EnableCursor(co, FALSE);
+ co->SetAttribute(co, EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE);
+}
+
+void
+console_restore_mode(SIMPLE_TEXT_OUTPUT_MODE * SavedMode)
+{
+ SIMPLE_TEXT_OUTPUT_INTERFACE *co = ST->ConOut;
+
+ co->EnableCursor(co, SavedMode->CursorVisible);
+ co->SetCursorPosition(co, SavedMode->CursorColumn,
+ SavedMode->CursorRow);
+ co->SetAttribute(co, SavedMode->Attribute);
+}
+
+int
+console_countdown(CHAR16* title, const CHAR16* message, int timeout)
+{
+ SIMPLE_TEXT_OUTPUT_INTERFACE *co = ST->ConOut;
+ SIMPLE_INPUT_INTERFACE *ci = ST->ConIn;
+ SIMPLE_TEXT_OUTPUT_MODE SavedMode;
+ EFI_INPUT_KEY key;
+ EFI_STATUS efi_status;
+ UINTN cols, rows;
+ CHAR16 *titles[2];
+ int wait = 10000000;
+
+ console_save_and_set_mode(&SavedMode);
+
+ titles[0] = title;
+ titles[1] = NULL;
+
+ console_print_box_at(titles, -1, 0, 0, -1, -1, 1, 1);
+
+ co->QueryMode(co, co->Mode->Mode, &cols, &rows);
+
+ console_print_at((cols - StrLen(message)) / 2, rows / 2, message);
+ while (1) {
+ if (timeout > 1)
+ console_print_at(2, rows - 3,
+ L"Booting in %d seconds ",
+ timeout);
+ else if (timeout)
+ console_print_at(2, rows - 3,
+ L"Booting in %d second ",
+ timeout);
+
+ efi_status = WaitForSingleEvent(ci->WaitForKey, wait);
+ if (efi_status != EFI_TIMEOUT) {
+ /* Clear the key in the queue */
+ ci->ReadKeyStroke(ci, &key);
+ break;
+ }
+
+ timeout--;
+ if (!timeout)
+ break;
+ }
+
+ console_restore_mode(&SavedMode);
+
+ return timeout;
+}
+
+#define HORIZONTAL_MAX_OK 1920
+#define VERTICAL_MAX_OK 1080
+#define COLUMNS_MAX_OK 200
+#define ROWS_MAX_OK 100
+
+void
+console_mode_handle(VOID)
+{
+ SIMPLE_TEXT_OUTPUT_INTERFACE *co = ST->ConOut;
+ EFI_GRAPHICS_OUTPUT_PROTOCOL *gop;
+ EFI_GUID gop_guid = EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID;
+ EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *Info;
+
+ UINTN mode_set;
+ UINTN rows = 0, columns = 0;
+ EFI_STATUS efi_status = EFI_SUCCESS;
+
+ efi_status = gBS->LocateProtocol(&gop_guid, NULL, (void **)&gop);
+ if (EFI_ERROR(efi_status)) {
+ console_error(L"Locate graphic output protocol fail", efi_status);
+ return;
+ }
+
+ Info = gop->Mode->Info;
+
+ /*
+ * Start verifying if we are in a resolution larger than Full HD
+ * (1920x1080). If we're not, assume we're in a good mode and do not
+ * try to change it.
+ */
+ if (Info->HorizontalResolution <= HORIZONTAL_MAX_OK &&
+ Info->VerticalResolution <= VERTICAL_MAX_OK) {
+ /* keep original mode and return */
+ return;
+ }
+
+ efi_status = co->QueryMode(co, co->Mode->Mode, &columns, &rows);
+ if (EFI_ERROR(efi_status)) {
+ console_error(L"Console query mode fail", efi_status);
+ return;
+ }
+
+ /*
+ * Verify current console output to check if the character columns and
+ * rows in a good mode.
+ */
+ if (columns <= COLUMNS_MAX_OK && rows <= ROWS_MAX_OK) {
+ /* keep original mode and return */
+ return;
+ }
+
+ if (!console_text_mode)
+ setup_console(1);
+
+ co->Reset(co, TRUE);
+
+ /*
+ * If we reached here, then we have a high resolution screen and the
+ * text too small. Try to switch to a better mode. Mode number 2 is
+ * first non standard mode, which is provided by the device
+ * manufacturer, so it should be a good mode.
+ */
+ if (co->Mode->MaxMode > 2)
+ mode_set = 2;
+ else
+ mode_set = 0;
+
+ efi_status = co->SetMode(co, mode_set);
+ if (EFI_ERROR(efi_status) && mode_set != 0) {
+ /*
+ * Set to 0 mode which is required that all output devices
+ * support at least 80x25 text mode.
+ */
+ mode_set = 0;
+ efi_status = co->SetMode(co, mode_set);
+ }
+
+ co->ClearScreen(co);
+
+ if (EFI_ERROR(efi_status)) {
+ console_error(L"Console set mode fail", efi_status);
+ }
+
+ return;
+}
/* Copy of gnu-efi-3.0 with the added secure boot strings */
static struct {
EFI_STATUS Code;
- WCHAR *Desc;
+ CHAR16 *Desc;
} error_table[] = {
{ EFI_SUCCESS, L"Success"},
{ EFI_LOAD_ERROR, L"Load Error"},
@@ -445,7 +598,7 @@ static struct {
{ EFI_SECURITY_VIOLATION, L"Security Violation"},
// warnings
- { EFI_WARN_UNKOWN_GLYPH, L"Warning Unknown Glyph"},
+ { EFI_WARN_UNKNOWN_GLYPH, L"Warning Unknown Glyph"},
{ EFI_WARN_DELETE_FAILURE, L"Warning Delete Failure"},
{ EFI_WARN_WRITE_FAILURE, L"Warning Write Failure"},
{ EFI_WARN_BUFFER_TOO_SMALL, L"Warning Buffer Too Small"},
@@ -523,33 +676,6 @@ setup_verbosity(VOID)
setup_console(-1);
}
-/* Included here because they mess up the definition of va_list and friends */
-#include <Library/BaseCryptLib.h>
-#include <openssl/err.h>
-#include <openssl/crypto.h>
-
-static int
-print_errors_cb(const char *str, size_t len, void *u)
-{
- console_print(L"%a", str);
-
- return len;
-}
-
-EFI_STATUS
-print_crypto_errors(EFI_STATUS efi_status,
- char *file, const char *func, int line)
-{
- if (!(verbose && EFI_ERROR(efi_status)))
- return efi_status;
-
- console_print(L"SSL Error: %a:%d %a(): %r\n", file, line, func,
- efi_status);
- ERR_print_errors_cb(print_errors_cb, NULL);
-
- return efi_status;
-}
-
VOID
msleep(unsigned long msecs)
{
diff --git a/lib/execute.c b/lib/execute.c
index 3aff28ad..642f94a3 100644
--- a/lib/execute.c
+++ b/lib/execute.c
@@ -1,46 +1,8 @@
+// SPDX-License-Identifier: BSD-2-Clause-Patent
/*
* Copyright 2012 <James.Bottomley@HansenPartnership.com>
- *
- * see COPYING file
- *
- * --
- *
- * generate_path is a cut and paste from
- *
- * git://github.com/mjg59/shim.git
- *
* Code Copyright 2012 Red Hat, Inc <mjg@redhat.com>
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the
- * distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
- * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
- * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
- * OF THE POSSIBILITY OF SUCH DAMAGE.
- *
*/
-
-#include <efi.h>
-#include <efilib.h>
-
#include "shim.h"
EFI_STATUS
@@ -83,7 +45,7 @@ generate_path(CHAR16* name, EFI_LOADED_IMAGE *li, EFI_DEVICE_PATH **path, CHAR16
if (name[0] != '\\')
StrCat(*PathName, L"\\");
StrCat(*PathName, name);
-
+
*path = FileDevicePath(li->DeviceHandle, *PathName);
error:
diff --git a/lib/guid.c b/lib/guid.c
index 57c02fbe..143e0bbd 100644
--- a/lib/guid.c
+++ b/lib/guid.c
@@ -1,8 +1,4 @@
-/*
- * Copyright 2012 <James.Bottomley@HansenPartnership.com>
- *
- * see COPYING file
- */
+// SPDX-License-Identifier: BSD-2-Clause-Patent
#include "shim.h"
@@ -36,4 +32,6 @@ EFI_GUID EFI_SECURE_BOOT_DB_GUID = { 0xd719b2cb, 0x3d3a, 0x4596, { 0xa3, 0xbc,
EFI_GUID EFI_SIMPLE_FILE_SYSTEM_GUID = SIMPLE_FILE_SYSTEM_PROTOCOL;
EFI_GUID SECURITY_PROTOCOL_GUID = { 0xA46423E3, 0x4617, 0x49f1, {0xB9, 0xFF, 0xD1, 0xBF, 0xA9, 0x11, 0x58, 0x39 } };
EFI_GUID SECURITY2_PROTOCOL_GUID = { 0x94ab2f58, 0x1438, 0x4ef1, {0x91, 0x52, 0x18, 0x94, 0x1a, 0x3a, 0x0e, 0x68 } };
+
EFI_GUID SHIM_LOCK_GUID = {0x605dab50, 0xe046, 0x4300, {0xab, 0xb6, 0x3d, 0xd8, 0x10, 0xdd, 0x8b, 0x23 } };
+EFI_GUID MOK_VARIABLE_STORE = {0xc451ed2b, 0x9694, 0x45d3, {0xba, 0xba, 0xed, 0x9f, 0x89, 0x88, 0xa3, 0x89} };
diff --git a/lib/print_crypto.c b/lib/print_crypto.c
new file mode 100644
index 00000000..ccdb65b1
--- /dev/null
+++ b/lib/print_crypto.c
@@ -0,0 +1,32 @@
+// SPDX-License-Identifier: BSD-2-Clause-Patent
+/*
+ * Copyright 2019 SUSE LLC <glin@suse.com>
+ */
+#include "shim.h"
+
+#include <Library/BaseCryptLib.h>
+#include <openssl/err.h>
+#include <openssl/crypto.h>
+#include <console.h>
+
+static int
+print_errors_cb(const char *str, size_t len, void *u UNUSED)
+{
+ console_print(L"%a", str);
+
+ return len;
+}
+
+EFI_STATUS
+print_crypto_errors(EFI_STATUS efi_status,
+ char *file, const char *func, int line)
+{
+ if (!(verbose && EFI_ERROR(efi_status)))
+ return efi_status;
+
+ console_print(L"SSL Error: %a:%d %a(): %r\n", file, line, func,
+ efi_status);
+ ERR_print_errors_cb(print_errors_cb, NULL);
+
+ return efi_status;
+}
diff --git a/lib/security_policy.c b/lib/security_policy.c
index 211f1cfd..6c42cc14 100644
--- a/lib/security_policy.c
+++ b/lib/security_policy.c
@@ -1,22 +1,12 @@
+// SPDX-License-Identifier: BSD-2-Clause-Patent
/*
* Copyright 2012 <James.Bottomley@HansenPartnership.com>
*
- * see COPYING file
- *
* Install and remove a platform security2 override policy
*/
-
-#include <efi.h>
-#include <efilib.h>
-
#include "shim.h"
-#include <variables.h>
-#include <simple_file.h>
-#include <errors.h>
-
#if defined(OVERRIDE_SECURITY_POLICY)
-#include <security_policy.h>
/*
* See the UEFI Platform Initialization manual (Vol2: DXE) for this
@@ -60,7 +50,7 @@ extern EFI_STATUS thunk_security_policy_authentication(
const EFI_SECURITY_PROTOCOL *This,
UINT32 AuthenticationStatus,
const EFI_DEVICE_PATH_PROTOCOL *DevicePath
- )
+ )
__attribute__((unused));
extern EFI_STATUS thunk_security2_policy_authentication(
@@ -69,7 +59,7 @@ extern EFI_STATUS thunk_security2_policy_authentication(
VOID *FileBuffer,
UINTN FileSize,
BOOLEAN BootPolicy
- )
+ )
__attribute__((unused));
static __attribute__((used)) EFI_STATUS
@@ -112,7 +102,7 @@ security_policy_authentication (
)
{
EFI_STATUS efi_status, fail_status;
- EFI_DEVICE_PATH *DevPath
+ EFI_DEVICE_PATH *DevPath
= DuplicateDevicePath((EFI_DEVICE_PATH *)DevicePathConst),
*OrigDevPath = DevPath;
EFI_HANDLE h;
diff --git a/lib/shell.c b/lib/shell.c
index e46e7fd2..146d9a21 100644
--- a/lib/shell.c
+++ b/lib/shell.c
@@ -1,13 +1,9 @@
+// SPDX-License-Identifier: BSD-2-Clause-Patent
/*
* Copyright 2012 <James.Bottomley@HansenPartnership.com>
*
- * see COPYING file
- *
* misc shell helper functions
*/
-#include <efi.h>
-#include <efilib.h>
-
#include "shim.h"
EFI_STATUS
diff --git a/lib/simple_file.c b/lib/simple_file.c
index 3bf92ed8..5fd3e1a6 100644
--- a/lib/simple_file.c
+++ b/lib/simple_file.c
@@ -1,12 +1,7 @@
+// SPDX-License-Identifier: BSD-2-Clause-Patent
/*
* Copyright 2012 <James.Bottomley@HansenPartnership.com>
- *
- * see COPYING file
*/
-
-#include <efi.h>
-#include <efilib.h>
-
#include "shim.h"
EFI_STATUS
@@ -67,8 +62,8 @@ simple_file_open(EFI_HANDLE image, CHAR16 *name, EFI_FILE **file, UINT64 mode)
}
EFI_STATUS
-simple_dir_read_all_by_handle(EFI_HANDLE image, EFI_FILE *file, CHAR16* name, EFI_FILE_INFO **entries,
- int *count)
+simple_dir_read_all_by_handle(EFI_HANDLE image UNUSED, EFI_FILE *file,
+ CHAR16* name, EFI_FILE_INFO **entries, int *count)
{
EFI_STATUS efi_status;
char buf[4096];
@@ -403,10 +398,10 @@ simple_file_selector(EFI_HANDLE * im, CHAR16 ** title, CHAR16 * name,
filter = L"";
if (!*im) {
EFI_HANDLE h;
- CHAR16 *volname;
+ CHAR16 *volname = NULL;
- simple_volume_selector(title, &volname, &h);
- if (!volname)
+ efi_status = simple_volume_selector(title, &volname, &h);
+ if (EFI_ERROR(efi_status) || !volname)
return;
FreePool(volname);
*im = h;
diff --git a/lib/string.c b/lib/string.c
new file mode 100644
index 00000000..d941cd56
--- /dev/null
+++ b/lib/string.c
@@ -0,0 +1,284 @@
+// SPDX-License-Identifier: BSD-2-Clause-Patent
+/*
+ * string.c - implementations we need for string finctions
+ */
+#define SHIM_STRING_C_
+#include "shim.h"
+
+#ifdef SHIM_UNIT_TEST
+#define strlen shim_strlen
+#ifdef strcmp
+#undef strcmp
+#endif
+#define strcmp shim_strcmp
+#ifdef strncmp
+#undef strncmp
+#endif
+#define strncmp shim_strncmp
+#define strncasecmp shim_strncasecmp
+#define strcasecmp shim_strcasecmp
+#define strrchr shim_strrchr
+#define strlen shim_strlen
+#define strnlen shim_strnlen
+#define strcpy shim_strcpy
+#ifdef strncpy
+#undef strncpy
+#endif
+#define strncpy shim_strncpy
+#ifdef strdup
+#undef strdup
+#endif
+#define strdup shim_strdup
+#ifdef strndup
+#undef strndup
+#endif
+#define strndup shim_strndup
+#ifdef stpcpy
+#undef stpcpy
+#endif
+#define stpcpy shim_stpcpy
+#define strchrnul shim_strchrnul
+#ifdef strchr
+#undef strchr
+#endif
+#define strchr shim_strchr
+#endif
+
+size_t
+strlen(const char *s1)
+{
+ size_t len;
+
+ for (len = 0; *s1; s1 += 1, len += 1)
+ ;
+ return len;
+}
+
+int
+strcmp(const char *s1p, const char *s2p)
+{
+ const uint8_t *s1 = (const uint8_t *)s1p;
+ const uint8_t *s2 = (const uint8_t *)s2p;
+
+ while (*s1) {
+ if (*s1 != *s2) {
+ break;
+ }
+
+ s1 += 1;
+ s2 += 1;
+ }
+
+ return *s1 - *s2;
+}
+
+int
+strncmp(const char *s1p, const char *s2p, size_t len)
+{
+ const uint8_t *s1 = (const uint8_t *)s1p;
+ const uint8_t *s2 = (const uint8_t *)s2p;
+
+ while (*s1 && len) {
+ if (*s1 != *s2) {
+ break;
+ }
+
+ s1 += 1;
+ s2 += 1;
+ len -= 1;
+ }
+
+ return len ? *s1 - *s2 : 0;
+}
+
+/* Based on AsciiStriCmp() in edk2 MdePkg/Library/BaseLib/String.c */
+int
+strncasecmp(const char *s1p, const char *s2p, size_t n)
+{
+ const uint8_t *s1 = (const uint8_t *)s1p;
+ const uint8_t *s2 = (const uint8_t *)s2p;
+
+ while (*s1 && n) {
+ if (toupper(*s1) != toupper(*s2)) {
+ break;
+ }
+
+ s1 += 1;
+ s2 += 1;
+ n -= 1;
+ }
+
+ return n ? *s1 - *s2 : 0;
+}
+
+/* Based on AsciiStriCmp() in edk2 MdePkg/Library/BaseLib/String.c */
+int
+strcasecmp(const char *str1, const char *str2)
+{
+ uint8_t c1, c2;
+
+ c1 = toupper(*str1);
+ c2 = toupper(*str2);
+ while ((*str1 != '\0') && (c1 == c2)) {
+ str1++;
+ str2++;
+ c1 = toupper(*str1);
+ c2 = toupper(*str2);
+ }
+
+ return c1 - c2;
+}
+
+/* Scan a string for the last occurrence of a character */
+char *
+strrchr(const char *str, int c)
+{
+ char *save;
+
+ for (save = NULL;; ++str) {
+ if (*str == c) {
+ save = (char *)str;
+ }
+ if (*str == 0) {
+ return (save);
+ }
+ }
+}
+
+NONNULL(1)
+size_t
+strnlen(const char *s, size_t n)
+{
+ size_t i;
+ for (i = 0; i < n; i++)
+ if (s[i] == '\0')
+ break;
+ return i;
+}
+
+RETURNS_NONNULL NONNULL(1, 2)
+char *
+strcpy(char *dest, const char *src)
+{
+ size_t i;
+
+ for (i = 0; src[i] != '\0'; i++)
+ dest[i] = src[i];
+
+ dest[i] = '\0';
+ return dest;
+}
+
+RETURNS_NONNULL NONNULL(1, 2)
+char *
+strncpy(char *dest, const char *src, size_t n)
+{
+ size_t i;
+
+ for (i = 0; i < n && src[i] != '\0'; i++)
+ dest[i] = src[i];
+ if (i < n)
+ dest[i] = '\0';
+
+ return dest;
+}
+
+RETURNS_NONNULL NONNULL(1, 2)
+char *
+strcat(char *dest, const char *src)
+{
+ size_t dest_len = strlen(dest);
+ size_t i;
+
+ for (i = 0; src[i] != '\0'; i++)
+ dest[dest_len + i] = src[i];
+ dest[dest_len + i] = '\0';
+
+ return dest;
+}
+
+NONNULL(1)
+char *
+strdup(const char *const src)
+{
+ size_t len;
+ char *news = NULL;
+
+ len = strlen(src);
+ news = AllocateZeroPool(len + 1);
+ if (news)
+ strncpy(news, src, len);
+ return news;
+}
+
+NONNULL(1)
+char *
+strndup(const char *const src, const size_t srcmax)
+{
+ size_t len;
+ char *news = NULL;
+
+ len = strnlen(src, srcmax);
+ news = AllocateZeroPool(len + 1);
+ if (news)
+ strncpy(news, src, len);
+ return news;
+}
+
+RETURNS_NONNULL NONNULL(1, 2)
+char *
+stpcpy(char *dest, const char *const src)
+{
+ size_t i = 0;
+ for (i = 0; src[i]; i++)
+ dest[i] = src[i];
+ dest[i] = '\000';
+ return &dest[i];
+}
+
+RETURNS_NONNULL NONNULL(1)
+char *
+strchrnul(const char *s, int c)
+{
+ unsigned int i;
+
+ for (i = 0; s[i] != '\000' && s[i] != c; i++)
+ ;
+
+ return (char *)&s[i];
+}
+
+NONNULL(1)
+char *
+strchr(const char *s, int c)
+{
+ const char *s1;
+
+ s1 = strchrnul(s, c);
+ if (!s1 || s1[0] == '\000')
+ return NULL;
+
+ return (char *)s1;
+}
+
+char *
+translate_slashes(char *out, const char *str)
+{
+ int i;
+ int j;
+ if (str == NULL || out == NULL)
+ return NULL;
+
+ for (i = 0, j = 0; str[i] != '\0'; i++, j++) {
+ if (str[i] == '\\') {
+ out[j] = '/';
+ if (str[i + 1] == '\\')
+ i++;
+ } else
+ out[j] = str[i];
+ }
+ out[j] = '\0';
+ return out;
+}
+
+// vim:fenc=utf-8:tw=75:noet
diff --git a/lib/variables.c b/lib/variables.c
index 9c2e7d0a..f606e248 100644
--- a/lib/variables.c
+++ b/lib/variables.c
@@ -1,54 +1,119 @@
+// SPDX-License-Identifier: BSD-2-Clause-Patent
/*
* Copyright 2012 <James.Bottomley@HansenPartnership.com>
*
- * see COPYING file
- *
* Portions of this file are a direct cut and paste from Tianocore
* (http://tianocore.sf.net)
*
* SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigImpl.c
*
* Copyright (c) 2011 - 2012, Intel Corporation. All rights reserved.<BR>
- * This program and the accompanying materials
- * are licensed and made available under the terms and conditions of the BSD License
- * which accompanies this distribution. The full text of the license may be found
- * at
- * http://opensource.org/licenses/bsd-license.php
- *
- * THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
- * WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
*
*/
-#include <efi.h>
-#include <efilib.h>
-
#include "shim.h"
EFI_STATUS
-variable_create_esl(void *cert, int cert_len, EFI_GUID *type, EFI_GUID *owner,
- void **out, int *outlen)
+fill_esl(const EFI_SIGNATURE_DATA *first_sig, const size_t howmany,
+ const EFI_GUID *type, const UINT32 sig_size,
+ uint8_t *out, size_t *outlen)
{
- *outlen = cert_len + sizeof(EFI_SIGNATURE_LIST) + sizeof(EFI_GUID);
+ EFI_SIGNATURE_LIST *sl;
+ EFI_SIGNATURE_DATA *sd;
+ size_t needed = 0;
+ size_t data_len = howmany * sig_size;
- *out = AllocateZeroPool(*outlen);
- if (!*out)
- return EFI_OUT_OF_RESOURCES;
+ dprint(L"fill_esl: first_sig=0x%llx, data_len=%lu\n", first_sig, data_len);
- EFI_SIGNATURE_LIST *sl = *out;
+ if ((out && !first_sig) || !howmany || !type || !sig_size || !outlen)
+ return EFI_INVALID_PARAMETER;
+
+ if (howmany > (UINT32_MAX - sizeof(EFI_SIGNATURE_LIST)) / sig_size)
+ return EFI_INVALID_PARAMETER;
+
+ needed = sizeof(EFI_SIGNATURE_LIST) + data_len;
+ if (!out || *outlen < needed) {
+ *outlen = needed;
+ return EFI_BUFFER_TOO_SMALL;
+ }
+
+ *outlen = needed;
+ sl = (EFI_SIGNATURE_LIST *)out;
sl->SignatureHeaderSize = 0;
sl->SignatureType = *type;
- sl->SignatureSize = cert_len + sizeof(EFI_GUID);
- sl->SignatureListSize = *outlen;
+ sl->SignatureSize = sig_size;
+ sl->SignatureListSize = needed;
- EFI_SIGNATURE_DATA *sd = *out + sizeof(EFI_SIGNATURE_LIST);
+ sd = (EFI_SIGNATURE_DATA *)(out + sizeof(EFI_SIGNATURE_LIST));
+ CopyMem(sd, first_sig, data_len);
- if (owner)
- sd->SignatureOwner = *owner;
+ return EFI_SUCCESS;
+}
- CopyMem(sd->SignatureData, cert, cert_len);
+EFI_STATUS
+fill_esl_with_one_signature(const uint8_t *data, const uint32_t data_len,
+ const EFI_GUID *type, const EFI_GUID *owner,
+ uint8_t *out, size_t *outlen)
+{
+ EFI_STATUS efi_status;
+ EFI_SIGNATURE_DATA *sd = NULL;
+ UINT32 sig_size = sizeof(EFI_SIGNATURE_DATA) - 1 + data_len;
- return EFI_SUCCESS;
+ if (data_len > UINT32_MAX - sizeof(EFI_SIGNATURE_DATA) + 1)
+ return EFI_INVALID_PARAMETER;
+
+ if (out) {
+ sd = AllocateZeroPool(sig_size);
+ if (owner)
+ CopyMem(sd, owner, sizeof(EFI_GUID));
+ CopyMem(sd->SignatureData, data, data_len);
+ }
+
+ efi_status = fill_esl(sd, 1, type, sig_size, out, outlen);
+
+ if (out)
+ FreePool(sd);
+ return efi_status;
+}
+
+EFI_STATUS
+variable_create_esl(const EFI_SIGNATURE_DATA *first_sig, const size_t howmany,
+ const EFI_GUID *type, const UINT32 sig_size,
+ uint8_t **out, size_t *outlen)
+{
+ EFI_STATUS efi_status;
+
+ *outlen = 0;
+ efi_status = fill_esl(first_sig, howmany, type, sig_size, NULL, outlen);
+ if (efi_status != EFI_BUFFER_TOO_SMALL)
+ return efi_status;
+
+ *out = AllocateZeroPool(*outlen);
+ if (!*out)
+ return EFI_OUT_OF_RESOURCES;
+
+ return fill_esl(first_sig, howmany, type, sig_size, *out, outlen);
+}
+
+EFI_STATUS
+variable_create_esl_with_one_signature(const uint8_t* data, const size_t data_len,
+ const EFI_GUID *type, const EFI_GUID *owner,
+ uint8_t **out, size_t *outlen)
+{
+ EFI_STATUS efi_status;
+
+ *outlen = 0;
+ efi_status = fill_esl_with_one_signature(data, data_len, type, owner,
+ NULL, outlen);
+ if (efi_status != EFI_BUFFER_TOO_SMALL)
+ return efi_status;
+
+ *out = AllocateZeroPool(*outlen);
+ if (!*out)
+ return EFI_OUT_OF_RESOURCES;
+
+ return fill_esl_with_one_signature(data, data_len, type, owner, *out,
+ outlen);
}
EFI_STATUS
@@ -123,8 +188,8 @@ CreateTimeBasedPayload(IN OUT UINTN * DataSize, IN OUT UINT8 ** Data)
}
EFI_STATUS
-SetSecureVariable(CHAR16 *var, UINT8 *Data, UINTN len, EFI_GUID owner,
- UINT32 options, int createtimebased)
+SetSecureVariable(const CHAR16 * const var, UINT8 *Data, UINTN len,
+ EFI_GUID owner, UINT32 options, int createtimebased)
{
EFI_SIGNATURE_LIST *Cert;
UINTN DataSize;
@@ -137,9 +202,10 @@ SetSecureVariable(CHAR16 *var, UINT8 *Data, UINTN len, EFI_GUID owner,
return EFI_SECURITY_VIOLATION;
if (createtimebased) {
- int ds;
- efi_status = variable_create_esl(Data, len, &X509_GUID, NULL,
- (void **)&Cert, &ds);
+ size_t ds;
+ efi_status = variable_create_esl_with_one_signature(
+ Data, len, &X509_GUID, NULL,
+ (uint8_t **)&Cert, &ds);
if (EFI_ERROR(efi_status)) {
console_print(L"Failed to create %s certificate %d\n",
var, efi_status);
@@ -159,7 +225,7 @@ SetSecureVariable(CHAR16 *var, UINT8 *Data, UINTN len, EFI_GUID owner,
return efi_status;
}
- efi_status = gRT->SetVariable(var, &owner,
+ efi_status = gRT->SetVariable((CHAR16 *)var, &owner,
EFI_VARIABLE_NON_VOLATILE |
EFI_VARIABLE_RUNTIME_ACCESS |
EFI_VARIABLE_BOOTSERVICE_ACCESS |
@@ -204,39 +270,87 @@ SETOSIndicationsAndReboot(UINT64 indications)
}
EFI_STATUS
-get_variable_attr(CHAR16 *var, UINT8 **data, UINTN *len, EFI_GUID owner,
- UINT32 *attributes)
+get_variable_attr(const CHAR16 * const var, UINT8 **data, UINTN *len,
+ EFI_GUID owner, UINT32 *attributes)
{
EFI_STATUS efi_status;
+ if (!len)
+ return EFI_INVALID_PARAMETER;
+
*len = 0;
- efi_status = gRT->GetVariable(var, &owner, NULL, len, NULL);
+ efi_status = gRT->GetVariable((CHAR16 *)var, &owner, NULL, len, NULL);
if (efi_status != EFI_BUFFER_TOO_SMALL) {
if (!EFI_ERROR(efi_status)) /* this should never happen */
return EFI_PROTOCOL_ERROR;
return efi_status;
}
- *data = AllocateZeroPool(*len);
+ if (!data)
+ return EFI_INVALID_PARAMETER;
+
+ /*
+ * Add three zero pad bytes; at least one correctly aligned UCS-2
+ * character.
+ */
+ *data = AllocateZeroPool(*len + 3);
if (!*data)
return EFI_OUT_OF_RESOURCES;
- efi_status = gRT->GetVariable(var, &owner, attributes, len, *data);
+ efi_status = gRT->GetVariable((CHAR16 *)var, &owner, attributes, len, *data);
if (EFI_ERROR(efi_status)) {
FreePool(*data);
*data = NULL;
}
+
return efi_status;
}
EFI_STATUS
-get_variable(CHAR16 *var, UINT8 **data, UINTN *len, EFI_GUID owner)
+get_variable(const CHAR16 * const var, UINT8 **data, UINTN *len, EFI_GUID owner)
{
return get_variable_attr(var, data, len, owner, NULL);
}
EFI_STATUS
+get_variable_size(const CHAR16 * const var, EFI_GUID owner, UINTN *lenp)
+{
+ UINTN len = 0;
+ EFI_STATUS efi_status;
+
+ efi_status = get_variable_attr(var, NULL, &len, owner, NULL);
+ if (EFI_ERROR(efi_status)) {
+ if (efi_status == EFI_BUFFER_TOO_SMALL) {
+ *lenp = len;
+ return EFI_SUCCESS;
+ } else if (efi_status == EFI_NOT_FOUND) {
+ *lenp = 0;
+ return EFI_SUCCESS;
+ }
+ return efi_status;
+ }
+ /*
+ * who knows what this means, but...
+ */
+ *lenp = len;
+ return efi_status;
+}
+
+EFI_STATUS
+set_variable(CHAR16 *var, EFI_GUID owner, UINT32 attributes,
+ UINTN datasize, void *data)
+{
+ return gRT->SetVariable(var, &owner, attributes, datasize, data);
+}
+
+EFI_STATUS
+del_variable(CHAR16 *var, EFI_GUID owner)
+{
+ return set_variable(var, owner, 0, 0, "");
+}
+
+EFI_STATUS
find_in_esl(UINT8 *Data, UINTN DataSize, UINT8 *key, UINTN keylen)
{
EFI_SIGNATURE_LIST *CertList;
@@ -254,7 +368,8 @@ find_in_esl(UINT8 *Data, UINTN DataSize, UINT8 *key, UINTN keylen)
}
EFI_STATUS
-find_in_variable_esl(CHAR16* var, EFI_GUID owner, UINT8 *key, UINTN keylen)
+find_in_variable_esl(const CHAR16 * const var, EFI_GUID owner, UINT8 *key,
+ UINTN keylen)
{
UINTN DataSize = 0;
UINT8 *Data = NULL;
@@ -305,7 +420,7 @@ variable_is_secureboot(void)
}
EFI_STATUS
-variable_enroll_hash(CHAR16 *var, EFI_GUID owner,
+variable_enroll_hash(const CHAR16 * const var, EFI_GUID owner,
UINT8 hash[SHA256_DIGEST_SIZE])
{
EFI_STATUS efi_status;
@@ -330,7 +445,7 @@ variable_enroll_hash(CHAR16 *var, EFI_GUID owner,
efi_status = SetSecureVariable(var, sig, sizeof(sig), owner,
EFI_VARIABLE_APPEND_WRITE, 0);
else
- efi_status = gRT->SetVariable(var, &owner,
+ efi_status = gRT->SetVariable((CHAR16 *)var, &owner,
EFI_VARIABLE_NON_VOLATILE |
EFI_VARIABLE_BOOTSERVICE_ACCESS |
EFI_VARIABLE_APPEND_WRITE,