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 <pjones@redhat.com>
This commit is contained in:
Peter Jones 2017-07-31 13:10:41 -04:00
parent 2d82a3899b
commit 431b8a2e75
4 changed files with 69 additions and 15 deletions

View File

@ -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)

View File

@ -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");

72
tpm.c
View File

@ -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;
}

1
tpm.h
View File

@ -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);