Commit 6b032619 authored by Matthew Garrett's avatar Matthew Garrett Committed by Jarkko Sakkinen

efi: Attempt to get the TCG2 event log in the boot stub

Right now we only attempt to obtain the SHA1-only event log. The
protocol also supports a crypto agile log format, which contains digests
for all algorithms in use. Attempt to obtain this first, and fall back
to obtaining the older format if the system doesn't support it. This is
lightly complicated by the event sizes being variable (as we don't know
in advance which algorithms are in use), and the interface giving us
back a pointer to the start of the final entry rather than a pointer to
the end of the log - as a result, we need to parse the final entry to
figure out its length in order to know how much data to copy up to the
OS.
Signed-off-by: default avatarMatthew Garrett <mjg59@google.com>
Acked-by: default avatarArd Biesheuvel <ard.biesheuvel@linaro.org>
Reviewed-by: default avatarBartosz Szczepanek <bsz@semihalf.com>
Tested-by: default avatarBartosz Szczepanek <bsz@semihalf.com>
Reviewed-by: default avatarJarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
Tested-by: default avatarJarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
Signed-off-by: default avatarJarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
parent fe7eb023
...@@ -57,7 +57,7 @@ void efi_enable_reset_attack_mitigation(efi_system_table_t *sys_table_arg) ...@@ -57,7 +57,7 @@ void efi_enable_reset_attack_mitigation(efi_system_table_t *sys_table_arg)
#endif #endif
static void efi_retrieve_tpm2_eventlog_1_2(efi_system_table_t *sys_table_arg) void efi_retrieve_tpm2_eventlog(efi_system_table_t *sys_table_arg)
{ {
efi_guid_t tcg2_guid = EFI_TCG2_PROTOCOL_GUID; efi_guid_t tcg2_guid = EFI_TCG2_PROTOCOL_GUID;
efi_guid_t linux_eventlog_guid = LINUX_EFI_TPM_EVENT_LOG_GUID; efi_guid_t linux_eventlog_guid = LINUX_EFI_TPM_EVENT_LOG_GUID;
...@@ -67,6 +67,7 @@ static void efi_retrieve_tpm2_eventlog_1_2(efi_system_table_t *sys_table_arg) ...@@ -67,6 +67,7 @@ static void efi_retrieve_tpm2_eventlog_1_2(efi_system_table_t *sys_table_arg)
unsigned long first_entry_addr, last_entry_addr; unsigned long first_entry_addr, last_entry_addr;
size_t log_size, last_entry_size; size_t log_size, last_entry_size;
efi_bool_t truncated; efi_bool_t truncated;
int version = EFI_TCG2_EVENT_LOG_FORMAT_TCG_2;
void *tcg2_protocol = NULL; void *tcg2_protocol = NULL;
status = efi_call_early(locate_protocol, &tcg2_guid, NULL, status = efi_call_early(locate_protocol, &tcg2_guid, NULL,
...@@ -74,14 +75,20 @@ static void efi_retrieve_tpm2_eventlog_1_2(efi_system_table_t *sys_table_arg) ...@@ -74,14 +75,20 @@ static void efi_retrieve_tpm2_eventlog_1_2(efi_system_table_t *sys_table_arg)
if (status != EFI_SUCCESS) if (status != EFI_SUCCESS)
return; return;
status = efi_call_proto(efi_tcg2_protocol, get_event_log, tcg2_protocol, status = efi_call_proto(efi_tcg2_protocol, get_event_log,
EFI_TCG2_EVENT_LOG_FORMAT_TCG_1_2, tcg2_protocol, version, &log_location,
&log_location, &log_last_entry, &truncated); &log_last_entry, &truncated);
if (status != EFI_SUCCESS)
return;
if (!log_location) if (status != EFI_SUCCESS || !log_location) {
version = EFI_TCG2_EVENT_LOG_FORMAT_TCG_1_2;
status = efi_call_proto(efi_tcg2_protocol, get_event_log,
tcg2_protocol, version, &log_location,
&log_last_entry, &truncated);
if (status != EFI_SUCCESS || !log_location)
return; return;
}
first_entry_addr = (unsigned long) log_location; first_entry_addr = (unsigned long) log_location;
/* /*
...@@ -96,8 +103,23 @@ static void efi_retrieve_tpm2_eventlog_1_2(efi_system_table_t *sys_table_arg) ...@@ -96,8 +103,23 @@ static void efi_retrieve_tpm2_eventlog_1_2(efi_system_table_t *sys_table_arg)
* We need to calculate its size to deduce the full size of * We need to calculate its size to deduce the full size of
* the logs. * the logs.
*/ */
if (version == EFI_TCG2_EVENT_LOG_FORMAT_TCG_2) {
/*
* The TCG2 log format has variable length entries,
* and the information to decode the hash algorithms
* back into a size is contained in the first entry -
* pass a pointer to the final entry (to calculate its
* size) and the first entry (so we know how long each
* digest is)
*/
last_entry_size =
__calc_tpm2_event_size((void *)last_entry_addr,
(void *)(long)log_location,
false);
} else {
last_entry_size = sizeof(struct tcpa_event) + last_entry_size = sizeof(struct tcpa_event) +
((struct tcpa_event *) last_entry_addr)->event_size; ((struct tcpa_event *) last_entry_addr)->event_size;
}
log_size = log_last_entry - log_location + last_entry_size; log_size = log_last_entry - log_location + last_entry_size;
} }
...@@ -114,7 +136,7 @@ static void efi_retrieve_tpm2_eventlog_1_2(efi_system_table_t *sys_table_arg) ...@@ -114,7 +136,7 @@ static void efi_retrieve_tpm2_eventlog_1_2(efi_system_table_t *sys_table_arg)
memset(log_tbl, 0, sizeof(*log_tbl) + log_size); memset(log_tbl, 0, sizeof(*log_tbl) + log_size);
log_tbl->size = log_size; log_tbl->size = log_size;
log_tbl->version = EFI_TCG2_EVENT_LOG_FORMAT_TCG_1_2; log_tbl->version = version;
memcpy(log_tbl->log, (void *) first_entry_addr, log_size); memcpy(log_tbl->log, (void *) first_entry_addr, log_size);
status = efi_call_early(install_configuration_table, status = efi_call_early(install_configuration_table,
...@@ -126,9 +148,3 @@ static void efi_retrieve_tpm2_eventlog_1_2(efi_system_table_t *sys_table_arg) ...@@ -126,9 +148,3 @@ static void efi_retrieve_tpm2_eventlog_1_2(efi_system_table_t *sys_table_arg)
err_free: err_free:
efi_call_early(free_pool, log_tbl); efi_call_early(free_pool, log_tbl);
} }
void efi_retrieve_tpm2_eventlog(efi_system_table_t *sys_table_arg)
{
/* Only try to retrieve the logs in 1.2 format. */
efi_retrieve_tpm2_eventlog_1_2(sys_table_arg);
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment