summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/Makefile42
-rw-r--r--lib/configtable.c3
-rw-r--r--lib/console.c23
-rw-r--r--lib/execute.c4
-rw-r--r--lib/print_crypto.c7
-rw-r--r--lib/security_policy.c4
-rw-r--r--lib/shell.c3
-rw-r--r--lib/simple_file.c8
-rw-r--r--lib/string.c284
-rw-r--r--lib/variables.c127
10 files changed, 444 insertions, 61 deletions
diff --git a/lib/Makefile b/lib/Makefile
index 573c52bd..6d83f789 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -1,9 +1,45 @@
TARGET = lib.a
-LIBFILES = $(foreach x,$(wildcard *.c),$(patsubst %.c,%.o,$(x)))
+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 8675fad1..66e97f63 100644
--- a/lib/configtable.c
+++ b/lib/configtable.c
@@ -4,9 +4,6 @@
*
* read some platform configuration tables
*/
-#include <efi.h>
-#include <efilib.h>
-
#include "shim.h"
void *
diff --git a/lib/console.c b/lib/console.c
index 05f7ec16..c310d213 100644
--- a/lib/console.c
+++ b/lib/console.c
@@ -3,11 +3,6 @@
* Copyright 2012 <James.Bottomley@HansenPartnership.com>
* Copyright 2013 Red Hat Inc. <pjones@redhat.com>
*/
-#include <efi.h>
-#include <efilib.h>
-#include <stdarg.h>
-#include <stdbool.h>
-
#include "shim.h"
static UINT8 console_text_mode = 0;
@@ -88,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)
@@ -116,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;
}
@@ -572,7 +567,7 @@ console_mode_handle(VOID)
/* 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"},
diff --git a/lib/execute.c b/lib/execute.c
index f57a6321..642f94a3 100644
--- a/lib/execute.c
+++ b/lib/execute.c
@@ -3,10 +3,6 @@
* Copyright 2012 <James.Bottomley@HansenPartnership.com>
* Code Copyright 2012 Red Hat, Inc <mjg@redhat.com>
*/
-
-#include <efi.h>
-#include <efilib.h>
-
#include "shim.h"
EFI_STATUS
diff --git a/lib/print_crypto.c b/lib/print_crypto.c
index 1bab0a6c..ccdb65b1 100644
--- a/lib/print_crypto.c
+++ b/lib/print_crypto.c
@@ -2,11 +2,6 @@
/*
* Copyright 2019 SUSE LLC <glin@suse.com>
*/
-
-#include <efi.h>
-#include <efilib.h>
-#include <stdarg.h>
-
#include "shim.h"
#include <Library/BaseCryptLib.h>
@@ -15,7 +10,7 @@
#include <console.h>
static int
-print_errors_cb(const char *str, size_t len, void *u)
+print_errors_cb(const char *str, size_t len, void *u UNUSED)
{
console_print(L"%a", str);
diff --git a/lib/security_policy.c b/lib/security_policy.c
index 6a9b13ed..6c42cc14 100644
--- a/lib/security_policy.c
+++ b/lib/security_policy.c
@@ -4,10 +4,6 @@
*
* Install and remove a platform security2 override policy
*/
-
-#include <efi.h>
-#include <efilib.h>
-
#include "shim.h"
#if defined(OVERRIDE_SECURITY_POLICY)
diff --git a/lib/shell.c b/lib/shell.c
index 87f279d6..146d9a21 100644
--- a/lib/shell.c
+++ b/lib/shell.c
@@ -4,9 +4,6 @@
*
* 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 384b20ec..5fd3e1a6 100644
--- a/lib/simple_file.c
+++ b/lib/simple_file.c
@@ -2,10 +2,6 @@
/*
* Copyright 2012 <James.Bottomley@HansenPartnership.com>
*/
-
-#include <efi.h>
-#include <efilib.h>
-
#include "shim.h"
EFI_STATUS
@@ -66,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];
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 0431d4a2..f606e248 100644
--- a/lib/variables.c
+++ b/lib/variables.c
@@ -10,24 +10,27 @@
* Copyright (c) 2011 - 2012, Intel Corporation. All rights reserved.<BR>
*
*/
-#include <efi.h>
-#include <efilib.h>
-
#include "shim.h"
EFI_STATUS
-fill_esl(const uint8_t *data, const size_t data_len,
- const EFI_GUID *type, const EFI_GUID *owner,
+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)
{
EFI_SIGNATURE_LIST *sl;
EFI_SIGNATURE_DATA *sd;
size_t needed = 0;
+ size_t data_len = howmany * sig_size;
+
+ dprint(L"fill_esl: first_sig=0x%llx, data_len=%lu\n", first_sig, data_len);
+
+ if ((out && !first_sig) || !howmany || !type || !sig_size || !outlen)
+ return EFI_INVALID_PARAMETER;
- if (!data || !data_len || !type || !outlen)
+ if (howmany > (UINT32_MAX - sizeof(EFI_SIGNATURE_LIST)) / sig_size)
return EFI_INVALID_PARAMETER;
- needed = sizeof(EFI_SIGNATURE_LIST) + sizeof(EFI_GUID) + data_len;
+ needed = sizeof(EFI_SIGNATURE_LIST) + data_len;
if (!out || *outlen < needed) {
*outlen = needed;
return EFI_BUFFER_TOO_SMALL;
@@ -38,27 +41,70 @@ fill_esl(const uint8_t *data, const size_t data_len,
sl->SignatureHeaderSize = 0;
sl->SignatureType = *type;
- sl->SignatureSize = sizeof(EFI_GUID) + data_len;
+ sl->SignatureSize = sig_size;
sl->SignatureListSize = needed;
sd = (EFI_SIGNATURE_DATA *)(out + sizeof(EFI_SIGNATURE_LIST));
- if (owner)
- sd->SignatureOwner = *owner;
-
- CopyMem(sd->SignatureData, data, data_len);
+ CopyMem(sd, first_sig, data_len);
return EFI_SUCCESS;
}
EFI_STATUS
-variable_create_esl(const uint8_t *data, const size_t data_len,
- const EFI_GUID *type, const EFI_GUID *owner,
+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;
+
+ 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(data, data_len, type, owner, NULL, outlen);
+ 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;
@@ -66,7 +112,8 @@ variable_create_esl(const uint8_t *data, const size_t data_len,
if (!*out)
return EFI_OUT_OF_RESOURCES;
- return fill_esl(data, data_len, type, owner, *out, outlen);
+ return fill_esl_with_one_signature(data, data_len, type, owner, *out,
+ outlen);
}
EFI_STATUS
@@ -156,8 +203,9 @@ SetSecureVariable(const CHAR16 * const var, UINT8 *Data, UINTN len,
if (createtimebased) {
size_t ds;
- efi_status = variable_create_esl(Data, len, &X509_GUID, NULL,
- (uint8_t **)&Cert, &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);
@@ -227,6 +275,9 @@ get_variable_attr(const CHAR16 * const var, UINT8 **data, UINTN *len,
{
EFI_STATUS efi_status;
+ if (!len)
+ return EFI_INVALID_PARAMETER;
+
*len = 0;
efi_status = gRT->GetVariable((CHAR16 *)var, &owner, NULL, len, NULL);
@@ -236,6 +287,9 @@ get_variable_attr(const CHAR16 * const var, UINT8 **data, UINTN *len,
return efi_status;
}
+ if (!data)
+ return EFI_INVALID_PARAMETER;
+
/*
* Add three zero pad bytes; at least one correctly aligned UCS-2
* character.
@@ -260,6 +314,43 @@ get_variable(const CHAR16 * const var, UINT8 **data, UINTN *len, EFI_GUID owner)
}
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;