452 строки
14 KiB
Diff
452 строки
14 KiB
Diff
From fc4368fed53837e00d303600d8b628cb0392b629 Mon Sep 17 00:00:00 2001
|
|
From: Peter Jones <pjones@redhat.com>
|
|
Date: Thu, 23 Jul 2020 20:29:52 -0400
|
|
Subject: [PATCH 60/62] Improve debug output some
|
|
|
|
Signed-off-by: Peter Jones <pjones@redhat.com>
|
|
Upstream: pr#213
|
|
---
|
|
errlog.c | 26 ++++++-
|
|
shim.c | 36 ++++++++--
|
|
include/console.h | 3 +
|
|
include/hexdump.h | 172 ++++++++++++++++++++++++++++------------------
|
|
shim.h | 5 +-
|
|
5 files changed, 164 insertions(+), 78 deletions(-)
|
|
|
|
diff --git a/errlog.c b/errlog.c
|
|
index 6669c800233..08f7a82a6b2 100644
|
|
--- a/errlog.c
|
|
+++ b/errlog.c
|
|
@@ -3,12 +3,28 @@
|
|
* Copyright 2017 Peter Jones <pjones@redhat.com>
|
|
*/
|
|
#include "shim.h"
|
|
+#include "hexdump.h"
|
|
|
|
static CHAR16 **errs = NULL;
|
|
static UINTN nerrs = 0;
|
|
|
|
EFI_STATUS
|
|
-VLogError(const char *file, int line, const char *func, CHAR16 *fmt, va_list args)
|
|
+vdprint_(const CHAR16 *fmt, const char *file, int line, const char *func, va_list args)
|
|
+{
|
|
+ va_list args2;
|
|
+ EFI_STATUS efi_status = EFI_SUCCESS;
|
|
+
|
|
+ if (verbose) {
|
|
+ va_copy(args2, args);
|
|
+ console_print(L"%a:%d:%a() ", file, line, func);
|
|
+ efi_status = VPrint(fmt, args2);
|
|
+ va_end(args2);
|
|
+ }
|
|
+ return efi_status;
|
|
+}
|
|
+
|
|
+EFI_STATUS
|
|
+VLogError(const char *file, int line, const char *func, const CHAR16 *fmt, va_list args)
|
|
{
|
|
va_list args2;
|
|
CHAR16 **newerrs;
|
|
@@ -35,7 +51,7 @@ VLogError(const char *file, int line, const char *func, CHAR16 *fmt, va_list arg
|
|
}
|
|
|
|
EFI_STATUS
|
|
-LogError_(const char *file, int line, const char *func, CHAR16 *fmt, ...)
|
|
+LogError_(const char *file, int line, const char *func, const CHAR16 *fmt, ...)
|
|
{
|
|
va_list args;
|
|
EFI_STATUS efi_status;
|
|
@@ -47,6 +63,12 @@ LogError_(const char *file, int line, const char *func, CHAR16 *fmt, ...)
|
|
return efi_status;
|
|
}
|
|
|
|
+VOID
|
|
+LogHexdump_(const char *file, int line, const char *func, const void *data, size_t sz)
|
|
+{
|
|
+ hexdumpat(file, line, func, data, sz, 0);
|
|
+}
|
|
+
|
|
VOID
|
|
PrintErrors(VOID)
|
|
{
|
|
diff --git a/shim.c b/shim.c
|
|
index d10a1ba1cac..9248642bd57 100644
|
|
--- a/shim.c
|
|
+++ b/shim.c
|
|
@@ -34,6 +34,7 @@
|
|
*/
|
|
|
|
#include "shim.h"
|
|
+#include "hexdump.h"
|
|
#if defined(ENABLE_SHIM_CERT)
|
|
#include "shim_cert.h"
|
|
#endif /* defined(ENABLE_SHIM_CERT) */
|
|
@@ -373,12 +374,18 @@ static BOOLEAN verify_x509(UINT8 *Cert, UINTN CertSize)
|
|
* and 64KB. For convenience, assume the number of value bytes
|
|
* is 2, i.e. the second byte is 0x82.
|
|
*/
|
|
- if (Cert[0] != 0x30 || Cert[1] != 0x82)
|
|
+ if (Cert[0] != 0x30 || Cert[1] != 0x82) {
|
|
+ dprint(L"cert[0:1] is [%02x%02x], should be [%02x%02x]\n",
|
|
+ Cert[0], Cert[1], 0x30, 0x82);
|
|
return FALSE;
|
|
+ }
|
|
|
|
length = Cert[2]<<8 | Cert[3];
|
|
- if (length != (CertSize - 4))
|
|
+ if (length != (CertSize - 4)) {
|
|
+ dprint(L"Cert length is %ld, expecting %ld\n",
|
|
+ length, CertSize);
|
|
return FALSE;
|
|
+ }
|
|
|
|
return TRUE;
|
|
}
|
|
@@ -426,19 +433,23 @@ static CHECK_STATUS check_db_cert_in_ram(EFI_SIGNATURE_LIST *CertList,
|
|
EFI_SIGNATURE_DATA *Cert;
|
|
UINTN CertSize;
|
|
BOOLEAN IsFound = FALSE;
|
|
+ int i = 0;
|
|
|
|
while ((dbsize > 0) && (dbsize >= CertList->SignatureListSize)) {
|
|
if (CompareGuid (&CertList->SignatureType, &EFI_CERT_TYPE_X509_GUID) == 0) {
|
|
Cert = (EFI_SIGNATURE_DATA *) ((UINT8 *) CertList + sizeof (EFI_SIGNATURE_LIST) + CertList->SignatureHeaderSize);
|
|
CertSize = CertList->SignatureSize - sizeof(EFI_GUID);
|
|
+ dprint(L"trying to verify cert %d (%s)\n", i++, dbname);
|
|
if (verify_x509(Cert->SignatureData, CertSize)) {
|
|
if (verify_eku(Cert->SignatureData, CertSize)) {
|
|
+ drain_openssl_errors();
|
|
IsFound = AuthenticodeVerify (data->CertData,
|
|
data->Hdr.dwLength - sizeof(data->Hdr),
|
|
Cert->SignatureData,
|
|
CertSize,
|
|
hash, SHA256_DIGEST_SIZE);
|
|
if (IsFound) {
|
|
+ dprint(L"AuthenticodeVerify() succeeded: %d\n", IsFound);
|
|
tpm_measure_variable(dbname, guid, CertSize, Cert->SignatureData);
|
|
drain_openssl_errors();
|
|
return DATA_FOUND;
|
|
@@ -447,7 +458,9 @@ static CHECK_STATUS check_db_cert_in_ram(EFI_SIGNATURE_LIST *CertList,
|
|
}
|
|
}
|
|
} else if (verbose) {
|
|
- console_notify(L"Not a DER encoding x.509 Certificate");
|
|
+ console_print(L"Not a DER encoded x.509 Certificate");
|
|
+ dprint(L"cert:\n");
|
|
+ dhexdumpat(Cert->SignatureData, CertSize, 0);
|
|
}
|
|
}
|
|
|
|
@@ -641,7 +654,7 @@ static EFI_STATUS check_whitelist (WIN_CERTIFICATE_EFI_PKCS *cert,
|
|
verification_method = VERIFIED_BY_CERT;
|
|
update_verification_method(VERIFIED_BY_CERT);
|
|
return EFI_SUCCESS;
|
|
- } else {
|
|
+ } else if (cert) {
|
|
LogError(L"check_db_cert(db, sha256hash) != DATA_FOUND\n");
|
|
}
|
|
}
|
|
@@ -666,7 +679,7 @@ static EFI_STATUS check_whitelist (WIN_CERTIFICATE_EFI_PKCS *cert,
|
|
verification_method = VERIFIED_BY_CERT;
|
|
update_verification_method(VERIFIED_BY_CERT);
|
|
return EFI_SUCCESS;
|
|
- } else {
|
|
+ } else if (cert) {
|
|
LogError(L"check_db_cert(vendor_db, sha256hash) != DATA_FOUND\n");
|
|
}
|
|
#endif
|
|
@@ -685,7 +698,7 @@ static EFI_STATUS check_whitelist (WIN_CERTIFICATE_EFI_PKCS *cert,
|
|
verification_method = VERIFIED_BY_CERT;
|
|
update_verification_method(VERIFIED_BY_CERT);
|
|
return EFI_SUCCESS;
|
|
- } else {
|
|
+ } else if (cert) {
|
|
LogError(L"check_db_cert(MokList, sha256hash) != DATA_FOUND\n");
|
|
}
|
|
|
|
@@ -993,6 +1006,11 @@ static EFI_STATUS generate_hash (char *data, unsigned int datasize_in,
|
|
goto done;
|
|
}
|
|
|
|
+ dprint(L"sha1 authenticode hash:\n");
|
|
+ dhexdumpat(sha1hash, SHA1_DIGEST_SIZE, 0);
|
|
+ dprint(L"sha256 authenticode hash:\n");
|
|
+ dhexdumpat(sha256hash, SHA256_DIGEST_SIZE, 0);
|
|
+
|
|
done:
|
|
if (SectionHeader)
|
|
FreePool(SectionHeader);
|
|
@@ -1155,6 +1173,7 @@ static EFI_STATUS verify_buffer (char *data, int datasize,
|
|
if (EFI_ERROR(ret_efi_status)) {
|
|
dprint(L"check_whitelist: %r\n", ret_efi_status);
|
|
if (ret_efi_status != EFI_NOT_FOUND) {
|
|
+ dprint(L"check_whitelist(): %r\n", ret_efi_status);
|
|
PrintErrors();
|
|
ClearErrors();
|
|
crypterr(ret_efi_status);
|
|
@@ -1803,6 +1822,7 @@ static EFI_STATUS load_image (EFI_LOADED_IMAGE *li, void **data,
|
|
|
|
device = li->DeviceHandle;
|
|
|
|
+ dprint(L"attempting to load %s\n", PathName);
|
|
/*
|
|
* Open the device
|
|
*/
|
|
@@ -2778,6 +2798,10 @@ efi_main (EFI_HANDLE passed_image_handle, EFI_SYSTEM_TABLE *passed_systab)
|
|
*/
|
|
InitializeLib(image_handle, systab);
|
|
|
|
+ dprint(L"vendor_authorized:0x%08lx vendor_authorized_size:%lu\n",
|
|
+ __FILE__, __LINE__, __func__, vendor_authorized, vendor_authorized_size);
|
|
+ dprint(L"vendor_deauthorized:0x%08lx vendor_deauthorized_size:%lu\n",
|
|
+ __FILE__, __LINE__, __func__, vendor_deauthorized, vendor_deauthorized_size);
|
|
init_openssl();
|
|
|
|
/*
|
|
diff --git a/include/console.h b/include/console.h
|
|
index 810bf13a1f1..ac6fdf61d18 100644
|
|
--- a/include/console.h
|
|
+++ b/include/console.h
|
|
@@ -85,6 +85,9 @@ extern UINT32 verbose;
|
|
__dprint_ret; \
|
|
})
|
|
#define dprint(fmt, ...) dprint_(L"%a:%d:%a() " fmt, __FILE__, __LINE__, __func__, ##__VA_ARGS__)
|
|
+extern EFI_STATUS
|
|
+vdprint_(const CHAR16 *fmt, const char *file, int line, const char *func, va_list args);
|
|
+#define vdprint(fmt, ...) vdprint_(fmt, __FILE__, __LINE__, __func__, ##__VA_ARGS__)
|
|
|
|
extern EFI_STATUS print_crypto_errors(EFI_STATUS rc, char *file, const char *func, int line);
|
|
#define crypterr(rc) print_crypto_errors((rc), __FILE__, __func__, __LINE__)
|
|
diff --git a/include/hexdump.h b/include/hexdump.h
|
|
index d337b571d8d..f3f3ac284a3 100644
|
|
--- a/include/hexdump.h
|
|
+++ b/include/hexdump.h
|
|
@@ -1,104 +1,140 @@
|
|
#ifndef STATIC_HEXDUMP_H
|
|
#define STATIC_HEXDUMP_H
|
|
|
|
-static int
|
|
-__attribute__((__unused__))
|
|
-isprint(char c)
|
|
-{
|
|
- if (c < 0x20)
|
|
- return 0;
|
|
- if (c > 0x7e)
|
|
- return 0;
|
|
- return 1;
|
|
-}
|
|
+#include <stdint.h>
|
|
|
|
-static UINTN
|
|
-__attribute__((__unused__))
|
|
-format_hex(UINT8 *data, UINTN size, CHAR16 *buf)
|
|
+static inline unsigned long UNUSED
|
|
+prepare_hex(const void *data, size_t size, char *buf, int position)
|
|
{
|
|
- UINTN sz = (UINTN)data % 16;
|
|
- CHAR16 hexchars[] = L"0123456789abcdef";
|
|
+ char hexchars[] = "0123456789abcdef";
|
|
int offset = 0;
|
|
- UINTN i;
|
|
- UINTN j;
|
|
+ unsigned long i;
|
|
+ unsigned long j;
|
|
+ unsigned long ret;
|
|
|
|
- for (i = 0; i < sz; i++) {
|
|
- buf[offset++] = L' ';
|
|
- buf[offset++] = L' ';
|
|
- buf[offset++] = L' ';
|
|
+ unsigned long before = (position % 16);
|
|
+ unsigned long after = (before+size >= 16) ? 0 : 16 - (before+size);
|
|
+
|
|
+ for (i = 0; i < before; i++) {
|
|
+ buf[offset++] = 'X';
|
|
+ buf[offset++] = 'X';
|
|
+ buf[offset++] = ' ';
|
|
if (i == 7)
|
|
- buf[offset++] = L' ';
|
|
+ buf[offset++] = ' ';
|
|
}
|
|
- for (j = sz; j < 16 && j < size; j++) {
|
|
- UINT8 d = data[j-sz];
|
|
+ for (j = 0; j < 16 - after - before; j++) {
|
|
+ uint8_t d = ((uint8_t *)data)[j];
|
|
buf[offset++] = hexchars[(d & 0xf0) >> 4];
|
|
buf[offset++] = hexchars[(d & 0x0f)];
|
|
- if (j != 15)
|
|
- buf[offset++] = L' ';
|
|
- if (j == 7)
|
|
- buf[offset++] = L' ';
|
|
+ if (i+j != 15)
|
|
+ buf[offset++] = ' ';
|
|
+ if (i+j == 7)
|
|
+ buf[offset++] = ' ';
|
|
}
|
|
- for (i = j; i < 16; i++) {
|
|
- buf[offset++] = L' ';
|
|
- buf[offset++] = L' ';
|
|
- if (i != 15)
|
|
- buf[offset++] = L' ';
|
|
- if (i == 7)
|
|
- buf[offset++] = L' ';
|
|
+ ret = 16 - after - before;
|
|
+ j += i;
|
|
+ for (i = 0; i < after; i++) {
|
|
+ buf[offset++] = 'X';
|
|
+ buf[offset++] = 'X';
|
|
+ if (i+j != 15)
|
|
+ buf[offset++] = ' ';
|
|
+ if (i+j == 7)
|
|
+ buf[offset++] = ' ';
|
|
}
|
|
- buf[offset] = L'\0';
|
|
- return j - sz;
|
|
+ buf[offset] = '\0';
|
|
+ return ret;
|
|
}
|
|
|
|
-static void
|
|
-__attribute__((__unused__))
|
|
-format_text(UINT8 *data, UINTN size, CHAR16 *buf)
|
|
+#define isprint(c) ((c) >= 0x20 && (c) <= 0x7e)
|
|
+
|
|
+static inline void UNUSED
|
|
+prepare_text(const void *data, size_t size, char *buf, int position)
|
|
{
|
|
- UINTN sz = (UINTN)data % 16;
|
|
int offset = 0;
|
|
- UINTN i;
|
|
- UINTN j;
|
|
+ unsigned long i;
|
|
+ unsigned long j;
|
|
|
|
- for (i = 0; i < sz; i++)
|
|
- buf[offset++] = L' ';
|
|
- buf[offset++] = L'|';
|
|
- for (j = sz; j < 16 && j < size; j++) {
|
|
- if (isprint(data[j-sz]))
|
|
- buf[offset++] = data[j-sz];
|
|
+ unsigned long before = position % 16;
|
|
+ unsigned long after = (before+size > 16) ? 0 : 16 - (before+size);
|
|
+
|
|
+ if (size == 0) {
|
|
+ buf[0] = '\0';
|
|
+ return;
|
|
+ }
|
|
+ for (i = 0; i < before; i++)
|
|
+ buf[offset++] = 'X';
|
|
+ buf[offset++] = '|';
|
|
+ for (j = 0; j < 16 - after - before; j++) {
|
|
+ if (isprint(((uint8_t *)data)[j]))
|
|
+ buf[offset++] = ((uint8_t *)data)[j];
|
|
else
|
|
- buf[offset++] = L'.';
|
|
+ buf[offset++] = '.';
|
|
}
|
|
- buf[offset++] = L'|';
|
|
- for (i = j; i < 16; i++)
|
|
- buf[offset++] = L' ';
|
|
- buf[offset] = L'\0';
|
|
+ buf[offset++] = size > 0 ? '|' : 'X';
|
|
+ buf[offset] = '\0';
|
|
}
|
|
|
|
-static void
|
|
-__attribute__((__unused__))
|
|
-hexdump(UINT8 *data, UINTN size)
|
|
+/*
|
|
+ * variadic hexdump formatted
|
|
+ * think of it as: printf("%s%s\n", vformat(fmt, ap), hexdump(data,size));
|
|
+ */
|
|
+static inline void UNUSED
|
|
+vhexdumpf(const char *file, int line, const char *func, const CHAR16 * const fmt, const void *data, unsigned long size, size_t at, va_list ap)
|
|
{
|
|
- UINTN display_offset = (UINTN)data & 0xffffffff;
|
|
- UINTN offset = 0;
|
|
- //console_print(L"hexdump: data=0x%016x size=0x%x\n", data, size);
|
|
+ unsigned long display_offset = at;
|
|
+ unsigned long offset = 0;
|
|
|
|
while (offset < size) {
|
|
- CHAR16 hexbuf[49];
|
|
- CHAR16 txtbuf[19];
|
|
- UINTN sz;
|
|
+ char hexbuf[49];
|
|
+ char txtbuf[19];
|
|
+ unsigned long sz;
|
|
|
|
- sz = format_hex(data+offset, size-offset, hexbuf);
|
|
+ sz = prepare_hex(data+offset, size-offset, hexbuf,
|
|
+ (unsigned long)data+offset);
|
|
if (sz == 0)
|
|
return;
|
|
- msleep(200000);
|
|
|
|
- format_text(data+offset, size-offset, txtbuf);
|
|
- console_print(L"%08x %s %s\n", display_offset, hexbuf, txtbuf);
|
|
- msleep(200000);
|
|
+ prepare_text(data+offset, size-offset, txtbuf,
|
|
+ (unsigned long)data+offset);
|
|
+ if (fmt && fmt[0] != 0)
|
|
+ vdprint_(fmt, file, line, func, ap);
|
|
+ dprint_(L"%a:%d:%a() %08lx %a %a\n", file, line, func, display_offset, hexbuf, txtbuf);
|
|
|
|
display_offset += sz;
|
|
offset += sz;
|
|
}
|
|
}
|
|
|
|
+/*
|
|
+ * hexdump formatted
|
|
+ * think of it as: printf("%s%s", format(fmt, ...), hexdump(data,size)[lineN]);
|
|
+ */
|
|
+static inline void UNUSED
|
|
+hexdumpf(const char *file, int line, const char *func, const CHAR16 * const fmt, const void *data, unsigned long size, size_t at, ...)
|
|
+{
|
|
+ va_list ap;
|
|
+
|
|
+ va_start(ap, at);
|
|
+ vhexdumpf(file, line, func, fmt, data, size, at, ap);
|
|
+ va_end(ap);
|
|
+}
|
|
+
|
|
+static inline void UNUSED
|
|
+hexdump(const char *file, int line, const char *func, const void *data, unsigned long size)
|
|
+{
|
|
+ hexdumpf(file, line, func, L"", data, size, (intptr_t)data);
|
|
+}
|
|
+
|
|
+static inline void UNUSED
|
|
+hexdumpat(const char *file, int line, const char *func, const void *data, unsigned long size, size_t at)
|
|
+{
|
|
+ hexdumpf(file, line, func, L"", data, size, at);
|
|
+}
|
|
+
|
|
+#define LogHexdump(data, sz) LogHexdump_(__FILE__, __LINE__, __func__, data, sz)
|
|
+#define dhexdump(data, sz) hexdump(__FILE__, __LINE__, __func__, data, sz)
|
|
+#define dhexdumpat(data, sz, at) hexdumpat(__FILE__, __LINE__, __func__, data, sz, at)
|
|
+#define dhexdumpf(fmt, data, sz, at, ...) hexdumpf(__FILE__, __LINE__, __func__, fmt, data, sz, at, ##__VA_ARGS__)
|
|
+
|
|
#endif /* STATIC_HEXDUMP_H */
|
|
+// vim:fenc=utf-8:tw=75:noet
|
|
diff --git a/shim.h b/shim.h
|
|
index c1d7e7c7197..0b3ad4f2d20 100644
|
|
--- a/shim.h
|
|
+++ b/shim.h
|
|
@@ -182,8 +182,9 @@ typedef struct _SHIM_LOCK {
|
|
|
|
extern EFI_STATUS shim_init(void);
|
|
extern void shim_fini(void);
|
|
-extern EFI_STATUS LogError_(const char *file, int line, const char *func, CHAR16 *fmt, ...);
|
|
-extern EFI_STATUS VLogError(const char *file, int line, const char *func, CHAR16 *fmt, va_list args);
|
|
+extern EFI_STATUS LogError_(const char *file, int line, const char *func, const CHAR16 *fmt, ...);
|
|
+extern EFI_STATUS VLogError(const char *file, int line, const char *func, const CHAR16 *fmt, va_list args);
|
|
+extern VOID LogHexdump_(const char *file, int line, const char *func, const void *data, size_t sz);
|
|
extern VOID PrintErrors(VOID);
|
|
extern VOID ClearErrors(VOID);
|
|
extern EFI_STATUS start_image(EFI_HANDLE image_handle, CHAR16 *ImagePath);
|
|
--
|
|
2.26.2
|
|
|