From fc4368fed53837e00d303600d8b628cb0392b629 Mon Sep 17 00:00:00 2001 From: Peter Jones Date: Thu, 23 Jul 2020 20:29:52 -0400 Subject: [PATCH 60/62] Improve debug output some Signed-off-by: Peter Jones 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 */ #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 -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