summaryrefslogtreecommitdiff
path: root/tpm.c
diff options
context:
space:
mode:
authorMathieu Trudel-Lapierre <mathieu.trudel-lapierre@canonical.com>2017-08-07 17:34:45 -0400
committerMathieu Trudel-Lapierre <mathieu.trudel-lapierre@canonical.com>2017-08-07 17:34:45 -0400
commitf4173af1ad45a270a5d8b2283f8018582484a553 (patch)
tree08a4e5efd254b4acdc3e524f1624e2c6be972e7b /tpm.c
parent62f0afa2ecead02b1258dabab8097ca278a22f8f (diff)
downloadefi-boot-shim-f4173af1ad45a270a5d8b2283f8018582484a553.tar.gz
efi-boot-shim-f4173af1ad45a270a5d8b2283f8018582484a553.zip
New upstream version 12+1501864225.b586175
Diffstat (limited to 'tpm.c')
-rw-r--r--tpm.c99
1 files changed, 80 insertions, 19 deletions
diff --git a/tpm.c b/tpm.c
index 71bcf9b9..c37cc484 100644
--- a/tpm.c
+++ b/tpm.c
@@ -35,32 +35,79 @@ static BOOLEAN tpm_present(efi_tpm_protocol_t *tpm)
return TRUE;
}
-static BOOLEAN tpm2_present(efi_tpm2_protocol_t *tpm)
+static EFI_STATUS tpm2_get_caps(efi_tpm2_protocol_t *tpm,
+ EFI_TCG2_BOOT_SERVICE_CAPABILITY *caps,
+ BOOLEAN *old_caps)
{
EFI_STATUS status;
- EFI_TCG2_BOOT_SERVICE_CAPABILITY caps;
- EFI_TCG2_BOOT_SERVICE_CAPABILITY_1_0 *caps_1_0;
- caps.Size = (UINT8)sizeof(caps);
+ caps->Size = (UINT8)sizeof(*caps);
- status = uefi_call_wrapper(tpm->get_capability, 2, tpm, &caps);
+ status = uefi_call_wrapper(tpm->get_capability, 2, tpm, caps);
if (status != EFI_SUCCESS)
- return FALSE;
+ return status;
- if (caps.StructureVersion.Major == 1 &&
- caps.StructureVersion.Minor == 0) {
- caps_1_0 = (EFI_TCG2_BOOT_SERVICE_CAPABILITY_1_0 *)&caps;
- if (caps_1_0->TPMPresentFlag)
- return TRUE;
- } else {
- if (caps.TPMPresentFlag)
+ if (caps->StructureVersion.Major == 1 &&
+ caps->StructureVersion.Minor == 0)
+ *old_caps = TRUE;
+
+ return EFI_SUCCESS;
+}
+
+static BOOLEAN tpm2_present(EFI_TCG2_BOOT_SERVICE_CAPABILITY *caps,
+ BOOLEAN old_caps)
+{
+ TREE_BOOT_SERVICE_CAPABILITY *caps_1_0;
+
+ if (old_caps) {
+ caps_1_0 = (TREE_BOOT_SERVICE_CAPABILITY *)caps;
+ if (caps_1_0->TrEEPresentFlag)
return TRUE;
}
+ if (caps->TPMPresentFlag)
+ return TRUE;
+
return FALSE;
}
+static inline EFI_TCG2_EVENT_LOG_BITMAP
+tpm2_get_supported_logs(efi_tpm2_protocol_t *tpm,
+ EFI_TCG2_BOOT_SERVICE_CAPABILITY *caps,
+ BOOLEAN old_caps)
+{
+ if (old_caps)
+ return ((TREE_BOOT_SERVICE_CAPABILITY *)caps)->SupportedEventLogs;
+
+ return caps->SupportedEventLogs;
+}
+
+/*
+ * According to TCG EFI Protocol Specification for TPM 2.0 family,
+ * all events generated after the invocation of EFI_TCG2_GET_EVENT_LOG
+ * shall be stored in an instance of an EFI_CONFIGURATION_TABLE aka
+ * EFI TCG 2.0 final events table. Hence, it is necessary to trigger the
+ * 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(efi_tpm2_protocol_t *tpm2,
+ EFI_TCG2_EVENT_LOG_BITMAP supported_logs)
+{
+ EFI_TCG2_EVENT_LOG_FORMAT log_fmt;
+ EFI_PHYSICAL_ADDRESS start;
+ EFI_PHYSICAL_ADDRESS end;
+ BOOLEAN truncated;
+
+ 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;
+
+ return uefi_call_wrapper(tpm2->get_event_log, 5, tpm2, log_fmt,
+ &start, &end, &truncated);
+}
+
EFI_STATUS tpm_log_event(EFI_PHYSICAL_ADDRESS buf, UINTN size, UINT8 pcr,
const CHAR8 *description)
{
@@ -71,11 +118,26 @@ EFI_STATUS tpm_log_event(EFI_PHYSICAL_ADDRESS buf, UINTN size, UINT8 pcr,
status = LibLocateProtocol(&tpm2_guid, (VOID **)&tpm2);
/* TPM 2.0 */
if (status == EFI_SUCCESS) {
+ BOOLEAN old_caps;
EFI_TCG2_EVENT *event;
+ EFI_TCG2_BOOT_SERVICE_CAPABILITY caps;
+ EFI_TCG2_EVENT_LOG_BITMAP supported_logs;
- if (!tpm2_present(tpm2))
+ 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);
+ if (EFI_ERROR(status)) {
+ perror(L"Unable to trigger tcg2 final events table: %r\n", status);
+ return status;
+ }
+
event = AllocatePool(sizeof(*event) + strlen(description) + 1);
if (!event) {
perror(L"Unable to allocate event structure\n");
@@ -85,7 +147,7 @@ EFI_STATUS tpm_log_event(EFI_PHYSICAL_ADDRESS buf, UINTN size, UINT8 pcr,
event->Header.HeaderSize = sizeof(EFI_TCG2_EVENT_HEADER);
event->Header.HeaderVersion = 1;
event->Header.PCRIndex = pcr;
- event->Header.EventType = 0x0d;
+ event->Header.EventType = EV_IPL;
event->Size = sizeof(*event) - sizeof(event->Event) + strlen(description) + 1;
memcpy(event->Event, description, strlen(description) + 1);
status = uefi_call_wrapper(tpm2->hash_log_extend_event, 5, tpm2,
@@ -94,7 +156,7 @@ EFI_STATUS tpm_log_event(EFI_PHYSICAL_ADDRESS buf, UINTN size, UINT8 pcr,
return status;
} else {
TCG_PCR_EVENT *event;
- UINT32 algorithm, eventnum = 0;
+ UINT32 eventnum = 0;
EFI_PHYSICAL_ADDRESS lastevent;
status = LibLocateProtocol(&tpm_guid, (VOID **)&tpm);
@@ -113,11 +175,10 @@ EFI_STATUS tpm_log_event(EFI_PHYSICAL_ADDRESS buf, UINTN size, UINT8 pcr,
}
event->PCRIndex = pcr;
- event->EventType = 0x0d;
+ event->EventType = EV_IPL;
event->EventSize = strlen(description) + 1;
- algorithm = 0x00000004;
status = uefi_call_wrapper(tpm->log_extend_event, 7, tpm, buf,
- (UINT64)size, algorithm, event,
+ (UINT64)size, TPM_ALG_SHA, event,
&eventnum, &lastevent);
FreePool(event);
return status;