summaryrefslogtreecommitdiff
path: root/tpm.c
diff options
context:
space:
mode:
authorJavier Martinez Canillas <javierm@redhat.com>2017-06-15 15:16:06 +0200
committerPeter Jones <pjones@redhat.com>2017-06-15 11:30:22 -0400
commit55c65546e46a78edbe41e88cb4ccbd2522e09625 (patch)
treebc85070e49593ce0ab0a7c235ed15e1d0e7e8c85 /tpm.c
parent0baa915056b6dc3dbea51c045e1e3ef8a0d86a08 (diff)
downloadefi-boot-shim-55c65546e46a78edbe41e88cb4ccbd2522e09625.tar.gz
efi-boot-shim-55c65546e46a78edbe41e88cb4ccbd2522e09625.zip
shim/tpm: Avoid passing an usupported event log format to GetEventLogs()
The TCG EFI Protocol Specification for family "2.0" mentions that not all TPM2 chips may support the EFI_TCG2_EVENT_LOG_FORMAT_TCG_2 (crypto agile) log format. So instead of always use this log format, the GetCapability() function should be used to determine which format is supported by the TPM. For example, the Intel PTT firmware based TPM found in Lenovo Thinkapd X1 Carbon (4th gen), only supports SHA-1 (EFI_TCG2_EVENT_LOG_FORMAT_TCG_1_2) log format. So a call to GetEventLog() using the crypto agile format was returning EFI_INVALID_PARAMETER, making tpm_log_event() function to fail. This was preventing shim to correctly measure the second stage bootloader: $ tpm2_listpcrs -L 0x04:9 Bank/Algorithm: TPM_ALG_SHA1(0x0004) PCR_09: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 After passing a supported log format to GetEventLog(), it succeeds and so shim is able to call the HashLogExtendEvent() EFI function correctly: $ tpm2_listpcrs -L 0x04:9 Bank/Algorithm: TPM_ALG_SHA1(0x0004) PCR_09: 07 5a 7e d3 75 64 ad 91 1a 34 17 17 c2 34 10 2b 58 5b de b7 Signed-off-by: Javier Martinez Canillas <javierm@redhat.com>
Diffstat (limited to 'tpm.c')
-rw-r--r--tpm.c30
1 files changed, 25 insertions, 5 deletions
diff --git a/tpm.c b/tpm.c
index 2ca58454..b2f9c460 100644
--- a/tpm.c
+++ b/tpm.c
@@ -73,6 +73,17 @@ static BOOLEAN tpm2_present(efi_tpm2_protocol_t *tpm,
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
@@ -81,15 +92,21 @@ static BOOLEAN tpm2_present(efi_tpm2_protocol_t *tpm,
* 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)
+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;
- return uefi_call_wrapper(tpm2->get_event_log, 5, tpm2,
- EFI_TCG2_EVENT_LOG_FORMAT_TCG_2, &start,
- &end, &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,
@@ -105,6 +122,7 @@ EFI_STATUS tpm_log_event(EFI_PHYSICAL_ADDRESS buf, UINTN size, UINT8 pcr,
BOOLEAN old_caps;
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)
@@ -113,7 +131,9 @@ EFI_STATUS tpm_log_event(EFI_PHYSICAL_ADDRESS buf, UINTN size, UINT8 pcr,
if (!tpm2_present(tpm2, &caps, old_caps))
return EFI_SUCCESS;
- status = trigger_tcg2_final_events_table(tpm2);
+ 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;