diff options
author | 2017-12-07 21:07:53 +0100 | |
---|---|---|
committer | 2017-12-07 21:07:53 +0100 | |
commit | bfdf8c3bb86f3dbc8e30e7a0a44d2df0c0c05171 (patch) | |
tree | 7dde8678069339327133d9e6492b674e26054c03 /src/boot/efi/measure.c | |
parent | Merge pull request #7572 from poettering/taint-manager (diff) | |
download | systemd-bfdf8c3bb86f3dbc8e30e7a0a44d2df0c0c05171.tar.gz systemd-bfdf8c3bb86f3dbc8e30e7a0a44d2df0c0c05171.tar.bz2 systemd-bfdf8c3bb86f3dbc8e30e7a0a44d2df0c0c05171.zip |
boot/efi: fixup TPM V2 measuring and logging (#7568)
Honor the log format and use packed event structures.
Fixes https://github.com/systemd/systemd/issues/7118
Diffstat (limited to 'src/boot/efi/measure.c')
-rw-r--r-- | src/boot/efi/measure.c | 81 |
1 files changed, 58 insertions, 23 deletions
diff --git a/src/boot/efi/measure.c b/src/boot/efi/measure.c index f43039b1b..94823587e 100644 --- a/src/boot/efi/measure.c +++ b/src/boot/efi/measure.c @@ -27,6 +27,11 @@ typedef struct _TCG_VERSION { UINT8 RevMinor; } TCG_VERSION; +typedef struct tdEFI_TCG2_VERSION { + UINT8 Major; + UINT8 Minor; +} EFI_TCG2_VERSION; + typedef struct _TCG_BOOT_SERVICE_CAPABILITY { UINT8 Size; struct _TCG_VERSION StructureVersion; @@ -36,6 +41,18 @@ typedef struct _TCG_BOOT_SERVICE_CAPABILITY { BOOLEAN TPMDeactivatedFlag; } TCG_BOOT_SERVICE_CAPABILITY; +typedef struct tdTREE_BOOT_SERVICE_CAPABILITY { + UINT8 Size; + EFI_TCG2_VERSION StructureVersion; + EFI_TCG2_VERSION ProtocolVersion; + UINT32 HashAlgorithmBitmap; + UINT32 SupportedEventLogs; + BOOLEAN TrEEPresentFlag; + UINT16 MaxCommandSize; + UINT16 MaxResponseSize; + UINT32 ManufacturerID; +} TREE_BOOT_SERVICE_CAPABILITY; + typedef UINT32 TCG_ALGORITHM_ID; #define TCG_ALG_SHA 0x00000004 // The SHA1 algorithm @@ -99,11 +116,6 @@ typedef struct _EFI_TCG { typedef struct tdEFI_TCG2_PROTOCOL EFI_TCG2_PROTOCOL; -typedef struct tdEFI_TCG2_VERSION { - UINT8 Major; - UINT8 Minor; -} EFI_TCG2_VERSION; - typedef UINT32 EFI_TCG2_EVENT_LOG_BITMAP; typedef UINT32 EFI_TCG2_EVENT_LOG_FORMAT; typedef UINT32 EFI_TCG2_EVENT_ALGORITHM_BITMAP; @@ -132,13 +144,13 @@ typedef struct { UINT16 HeaderVersion; UINT32 PCRIndex; UINT32 EventType; -} EFI_TCG2_EVENT_HEADER; +} __attribute__ ((packed)) EFI_TCG2_EVENT_HEADER; typedef struct tdEFI_TCG2_EVENT { UINT32 Size; EFI_TCG2_EVENT_HEADER Header; UINT8 Event[1]; -} EFI_TCG2_EVENT; +} __attribute__ ((packed)) EFI_TCG2_EVENT; typedef EFI_STATUS(EFIAPI * EFI_TCG2_GET_CAPABILITY) (IN EFI_TCG2_PROTOCOL * This, IN OUT EFI_TCG2_BOOT_SERVICE_CAPABILITY * ProtocolCapability); @@ -218,22 +230,21 @@ static EFI_STATUS tpm1_measure_to_pcr_and_event_log(const EFI_TCG *tcg, UINT32 p * internal switch through calling get_event_log() in order to allow * to retrieve the logs from OS runtime. */ -static EFI_STATUS trigger_tcg2_final_events_table(const EFI_TCG2 *tcg) +static EFI_STATUS trigger_tcg2_final_events_table(const EFI_TCG2 *tcg, EFI_TCG2_EVENT_LOG_FORMAT log_fmt) { return uefi_call_wrapper(tcg->GetEventLog, 5, (EFI_TCG2 *) tcg, - EFI_TCG2_EVENT_LOG_FORMAT_TCG_2, NULL, - NULL, NULL); + log_fmt, 0, 0, 0); } static EFI_STATUS tpm2_measure_to_pcr_and_event_log(const EFI_TCG2 *tcg, UINT32 pcrindex, const EFI_PHYSICAL_ADDRESS buffer, - UINT64 buffer_size, const CHAR16 *description) { + UINT64 buffer_size, const CHAR16 *description, EFI_TCG2_EVENT_LOG_FORMAT log_fmt) { EFI_STATUS status; EFI_TCG2_EVENT *tcg_event; UINTN desc_len; static BOOLEAN triggered = FALSE; if (triggered == FALSE) { - status = trigger_tcg2_final_events_table(tcg); + status = trigger_tcg2_final_events_table(tcg, log_fmt); if (EFI_ERROR(status)) return status; @@ -247,7 +258,7 @@ static EFI_STATUS tpm2_measure_to_pcr_and_event_log(const EFI_TCG2 *tcg, UINT32 if (tcg_event == NULL) return EFI_OUT_OF_RESOURCES; - tcg_event->Size = sizeof(EFI_TCG2_EVENT) - sizeof(tcg_event->Event) + desc_len + 1; + tcg_event->Size = sizeof(*tcg_event) - sizeof(tcg_event->Event) + desc_len + 1; tcg_event->Header.HeaderSize = sizeof(EFI_TCG2_EVENT_HEADER); tcg_event->Header.HeaderVersion = EFI_TCG2_EVENT_HEADER_VERSION; tcg_event->Header.PCRIndex = pcrindex; @@ -255,7 +266,7 @@ static EFI_STATUS tpm2_measure_to_pcr_and_event_log(const EFI_TCG2 *tcg, UINT32 CopyMem((VOID *) tcg_event->Event, (VOID *) description, desc_len); - status = uefi_call_wrapper(tcg->HashLogExtendEvent, 5, (EFI_TCG2 *) tcg, 0, buffer, buffer_size, tcg_event); + status = uefi_call_wrapper(tcg->HashLogExtendEvent, 5, (EFI_TCG2 *) tcg, 0, buffer, (UINT64) buffer_size, tcg_event); uefi_call_wrapper(BS->FreePool, 1, tcg_event); @@ -294,24 +305,31 @@ static EFI_TCG * tcg1_interface_check(void) { return tcg; } -static EFI_TCG2 * tcg2_interface_check(void) { +static EFI_TCG2 * tcg2_interface_check(EFI_TCG2_BOOT_SERVICE_CAPABILITY *caps) { EFI_GUID tpm2_guid = EFI_TCG2_PROTOCOL_GUID; EFI_STATUS status; EFI_TCG2 *tcg; - EFI_TCG2_BOOT_SERVICE_CAPABILITY capability; status = LibLocateProtocol(&tpm2_guid, (void **) &tcg); if (EFI_ERROR(status)) return NULL; - capability.Size = (UINT8) sizeof(capability); - status = uefi_call_wrapper(tcg->GetCapability, 2, tcg, &capability); + caps->Size = (UINT8) sizeof(EFI_TCG2_BOOT_SERVICE_CAPABILITY); + status = uefi_call_wrapper(tcg->GetCapability, 2, tcg, caps); if (EFI_ERROR(status)) return NULL; - if (!capability.TPMPresentFlag) + if (caps->StructureVersion.Major == 1 && + caps->StructureVersion.Minor == 0) { + TCG_BOOT_SERVICE_CAPABILITY *caps_1_0; + caps_1_0 = (TCG_BOOT_SERVICE_CAPABILITY *)caps; + if (caps_1_0->TPMPresentFlag) + return tcg; + } + + if (!caps->TPMPresentFlag) return NULL; return tcg; @@ -320,10 +338,27 @@ static EFI_TCG2 * tcg2_interface_check(void) { EFI_STATUS tpm_log_event(UINT32 pcrindex, const EFI_PHYSICAL_ADDRESS buffer, UINTN buffer_size, const CHAR16 *description) { EFI_TCG *tpm1; EFI_TCG2 *tpm2; - - tpm2 = tcg2_interface_check(); - if (tpm2) - return tpm2_measure_to_pcr_and_event_log(tpm2, pcrindex, buffer, buffer_size, description); + EFI_TCG2_BOOT_SERVICE_CAPABILITY caps; + + tpm2 = tcg2_interface_check(&caps); + if (tpm2) { + EFI_TCG2_EVENT_LOG_BITMAP supported_logs; + EFI_TCG2_EVENT_LOG_FORMAT log_fmt; + + if (caps.StructureVersion.Major == 1 && + caps.StructureVersion.Minor == 0) + supported_logs = ((TREE_BOOT_SERVICE_CAPABILITY *)&caps)->SupportedEventLogs; + else + supported_logs = caps.SupportedEventLogs; + + if (supported_logs & EFI_TCG2_EVENT_LOG_FORMAT_TCG_2) + log_fmt = EFI_TCG2_EVENT_LOG_FORMAT_TCG_2; + else + log_fmt = EFI_TCG2_EVENT_LOG_FORMAT_TCG_1_2; + + uefi_call_wrapper(BS->Stall, 1, 2000 * 1000); + return tpm2_measure_to_pcr_and_event_log(tpm2, pcrindex, buffer, buffer_size, description, log_fmt); + } tpm1 = tcg1_interface_check(); if (tpm1) |