From 431b8a2e75a71a0b1f47d47d3f045b1e3efbce53 Mon Sep 17 00:00:00 2001 From: Peter Jones Date: Mon, 31 Jul 2017 13:10:41 -0400 Subject: [PATCH] Make fallback aware of tpm measurements, and reboot if tpm is used. Since booting the entry with fallback in the stack of things that got measured will result in all the wrong PCR values, in the cases where TPM is present and enabled, use ->Reset() instead of loading the Boot#### variable and executing its target. Signed-off-by: Peter Jones --- Makefile | 2 +- fallback.c | 9 ++++++- tpm.c | 72 ++++++++++++++++++++++++++++++++++++++++++++---------- tpm.h | 1 + 4 files changed, 69 insertions(+), 15 deletions(-) diff --git a/Makefile b/Makefile index fb5ab27..219d0c0 100644 --- a/Makefile +++ b/Makefile @@ -108,7 +108,7 @@ KEYS = shim_cert.h ocsp.* ca.* shim.crt shim.csr shim.p12 shim.pem shim.key shim ORIG_SOURCES = shim.c shim.h netboot.c include/PeImage.h include/wincert.h include/console.h replacements.c replacements.h tpm.c tpm.h version.h MOK_OBJS = MokManager.o PasswordCrypt.o crypt_blowfish.o ORIG_MOK_SOURCES = MokManager.c shim.h include/console.h PasswordCrypt.c PasswordCrypt.h crypt_blowfish.c crypt_blowfish.h -FALLBACK_OBJS = fallback.o +FALLBACK_OBJS = fallback.o tpm.o ORIG_FALLBACK_SRCS = fallback.c ifneq ($(origin ENABLE_HTTPBOOT), undefined) diff --git a/fallback.c b/fallback.c index 09749bb..9b64077 100644 --- a/fallback.c +++ b/fallback.c @@ -12,6 +12,7 @@ #include "ucs2.h" #include "variables.h" +#include "tpm.h" EFI_LOADED_IMAGE *this_image = NULL; @@ -904,7 +905,13 @@ efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *systab) return rc; } - try_start_first_option(image); + rc = fallback_should_prefer_reset(); + if (EFI_ERROR(rc)) { + VerbosePrint(L"tpm not present, starting the first image\n"); + try_start_first_option(image); + } else { + VerbosePrint(L"tpm present, resetting system\n"); + } Print(L"Reset System\n"); diff --git a/tpm.c b/tpm.c index 9fac27b..05b3c6f 100644 --- a/tpm.c +++ b/tpm.c @@ -119,6 +119,44 @@ static EFI_STATUS trigger_tcg2_final_events_table(efi_tpm2_protocol_t *tpm2, &start, &end, &truncated); } +static EFI_STATUS tpm_locate_protocol(efi_tpm_protocol_t **tpm, + efi_tpm2_protocol_t **tpm2, + BOOLEAN *old_caps_p, + EFI_TCG2_BOOT_SERVICE_CAPABILITY *capsp) +{ + EFI_STATUS status; + + *tpm = NULL; + *tpm2 = NULL; + status = LibLocateProtocol(&tpm2_guid, (VOID **)tpm2); + /* TPM 2.0 */ + if (status == EFI_SUCCESS) { + BOOLEAN old_caps; + EFI_TCG2_BOOT_SERVICE_CAPABILITY caps; + + status = tpm2_get_caps(*tpm2, &caps, &old_caps); + if (EFI_ERROR(status)) + return status; + + if (tpm2_present(&caps, old_caps)) { + if (old_caps_p) + *old_caps_p = old_caps; + if (capsp) + memcpy(capsp, &caps, sizeof(caps)); + return EFI_SUCCESS; + } + } else { + status = LibLocateProtocol(&tpm_guid, (VOID **)tpm); + if (EFI_ERROR(status)) + return status; + + if (tpm_present(*tpm)) + return EFI_SUCCESS; + } + + return EFI_NOT_FOUND; +} + static EFI_STATUS tpm_log_event_raw(EFI_PHYSICAL_ADDRESS buf, UINTN size, UINT8 pcr, const CHAR8 *log, UINTN logsize, UINT32 type, CHAR8 *hash) @@ -126,22 +164,16 @@ static EFI_STATUS tpm_log_event_raw(EFI_PHYSICAL_ADDRESS buf, UINTN size, EFI_STATUS status; efi_tpm_protocol_t *tpm; efi_tpm2_protocol_t *tpm2; + BOOLEAN old_caps; + EFI_TCG2_BOOT_SERVICE_CAPABILITY caps; - status = LibLocateProtocol(&tpm2_guid, (VOID **)&tpm2); - /* TPM 2.0 */ - if (status == EFI_SUCCESS) { - BOOLEAN old_caps; + status = tpm_locate_protocol(&tpm, &tpm2, &old_caps, &caps); + if (EFI_ERROR(status)) { + return status; + } else if (tpm2) { EFI_TCG2_EVENT *event; - EFI_TCG2_BOOT_SERVICE_CAPABILITY caps; EFI_TCG2_EVENT_LOG_BITMAP supported_logs; - status = tpm2_get_caps(tpm2, &caps, &old_caps); - if (status != EFI_SUCCESS) - return EFI_SUCCESS; - - if (!tpm2_present(&caps, old_caps)) - return EFI_SUCCESS; - supported_logs = tpm2_get_supported_logs(tpm2, &caps, old_caps); status = trigger_tcg2_final_events_table(tpm2, supported_logs); @@ -176,7 +208,7 @@ static EFI_STATUS tpm_log_event_raw(EFI_PHYSICAL_ADDRESS buf, UINTN size, } FreePool(event); return status; - } else { + } else if (tpm) { TCG_PCR_EVENT *event; UINT32 eventnum = 0; EFI_PHYSICAL_ADDRESS lastevent; @@ -221,6 +253,7 @@ static EFI_STATUS tpm_log_event_raw(EFI_PHYSICAL_ADDRESS buf, UINTN size, return EFI_SUCCESS; } + EFI_STATUS tpm_log_event(EFI_PHYSICAL_ADDRESS buf, UINTN size, UINT8 pcr, const CHAR8 *description) { @@ -344,3 +377,16 @@ EFI_STATUS tpm_measure_variable(CHAR16 *VarName, EFI_GUID VendorGuid, UINTN VarS return tpm_record_data_measurement(VarName, VendorGuid, VarSize, VarData); } + +EFI_STATUS +fallback_should_prefer_reset(void) +{ + EFI_STATUS status; + efi_tpm_protocol_t *tpm; + efi_tpm2_protocol_t *tpm2; + + status = tpm_locate_protocol(&tpm, &tpm2, NULL, NULL); + if (EFI_ERROR(status)) + return EFI_NOT_FOUND; + return EFI_SUCCESS; +} diff --git a/tpm.h b/tpm.h index e3c2b92..d11b545 100644 --- a/tpm.h +++ b/tpm.h @@ -8,6 +8,7 @@ EFI_STATUS tpm_log_event(EFI_PHYSICAL_ADDRESS buf, UINTN size, UINT8 pcr, const CHAR8 *description); +EFI_STATUS fallback_should_prefer_reset(void); EFI_STATUS tpm_log_pe(EFI_PHYSICAL_ADDRESS buf, UINTN size, UINT8 *sha1hash, UINT8 pcr);