efi_loader: fix the return values on efi_tcg
A while back we moved the core functions of the EFI TCG protocol to the
TPM APIs in order for them to be used with bootm, booti etc.
Some prototypes changed from returning efi_status_t to int, which is more
appropriate for the non-EFI APIs. However, some of the EFI callsites never
changed and we ended up assigning the int value to efi_status_t.
This is unlikely to cause any problems, apart from returning invalid
values on failures and violating the EFI spec. Let's fix them
by looking at the new return code and map it to the proper EFI return
code on failures.
Fixes: commit 97707f12fdab ("tpm: Support boot measurements")
Fixes: commit d6b55a420cfc ("efi_loader: startup the tpm device when installing the protocol")
Reviewed-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
Signed-off-by: Ilias Apalodimas <ilias.apalodimas@linaro.org>
diff --git a/lib/efi_loader/efi_tcg2.c b/lib/efi_loader/efi_tcg2.c
index d56bd56..b4915ca 100644
--- a/lib/efi_loader/efi_tcg2.c
+++ b/lib/efi_loader/efi_tcg2.c
@@ -257,8 +257,8 @@
capability->protocol_version.major = 1;
capability->protocol_version.minor = 1;
- efi_ret = tcg2_platform_get_tpm2(&dev);
- if (efi_ret != EFI_SUCCESS) {
+ ret = tcg2_platform_get_tpm2(&dev);
+ if (ret) {
capability->supported_event_logs = 0;
capability->hash_algorithm_bitmap = 0;
capability->tpm_present_flag = false;
@@ -353,8 +353,7 @@
goto out;
}
- ret = tcg2_platform_get_tpm2(&dev);
- if (ret != EFI_SUCCESS) {
+ if (tcg2_platform_get_tpm2(&dev)) {
event_log_location = NULL;
event_log_last_entry = NULL;
*event_log_truncated = false;
@@ -389,7 +388,7 @@
void *new_efi = NULL;
u8 hash[TPM2_SHA512_DIGEST_SIZE];
struct udevice *dev;
- efi_status_t ret;
+ efi_status_t ret = EFI_SUCCESS;
u32 active;
int i;
@@ -404,12 +403,13 @@
goto out;
}
- ret = tcg2_platform_get_tpm2(&dev);
- if (ret != EFI_SUCCESS)
+ if (tcg2_platform_get_tpm2(&dev)) {
+ ret = EFI_DEVICE_ERROR;
goto out;
+ }
- ret = tcg2_get_active_pcr_banks(dev, &active);
- if (ret != EFI_SUCCESS) {
+ if (tcg2_get_active_pcr_banks(dev, &active)) {
+ ret = EFI_DEVICE_ERROR;
goto out;
}
@@ -473,12 +473,12 @@
IMAGE_DOS_HEADER *dos;
IMAGE_NT_HEADERS32 *nt;
struct efi_handler *handler;
+ int rc;
if (!is_tcg2_protocol_installed())
return EFI_SUCCESS;
- ret = tcg2_platform_get_tpm2(&dev);
- if (ret != EFI_SUCCESS)
+ if (tcg2_platform_get_tpm2(&dev))
return EFI_SECURITY_VIOLATION;
switch (handle->image_type) {
@@ -502,9 +502,9 @@
if (ret != EFI_SUCCESS)
return ret;
- ret = tcg2_pcr_extend(dev, pcr_index, &digest_list);
- if (ret != EFI_SUCCESS)
- return ret;
+ rc = tcg2_pcr_extend(dev, pcr_index, &digest_list);
+ if (rc)
+ return EFI_DEVICE_ERROR;
ret = efi_search_protocol(&handle->header,
&efi_guid_loaded_image_device_path, &handler);
@@ -574,9 +574,10 @@
struct efi_tcg2_event *efi_tcg_event)
{
struct udevice *dev;
- efi_status_t ret;
+ efi_status_t ret = EFI_SUCCESS;
u32 event_type, pcr_index, event_size;
struct tpml_digest_values digest_list;
+ int rc = 0;
EFI_ENTRY("%p, %llu, %llu, %llu, %p", this, flags, data_to_hash,
data_to_hash_len, efi_tcg_event);
@@ -586,9 +587,10 @@
goto out;
}
- ret = tcg2_platform_get_tpm2(&dev);
- if (ret != EFI_SUCCESS)
+ if (tcg2_platform_get_tpm2(&dev)) {
+ ret = EFI_DEVICE_ERROR;
goto out;
+ }
if (efi_tcg_event->size < efi_tcg_event->header.header_size +
sizeof(u32)) {
@@ -621,8 +623,10 @@
ret = tcg2_hash_pe_image((void *)(uintptr_t)data_to_hash,
data_to_hash_len, &digest_list);
} else {
- ret = tcg2_create_digest(dev, (u8 *)(uintptr_t)data_to_hash,
- data_to_hash_len, &digest_list);
+ rc = tcg2_create_digest(dev, (u8 *)(uintptr_t)data_to_hash,
+ data_to_hash_len, &digest_list);
+ if (rc)
+ ret = EFI_DEVICE_ERROR;
}
if (ret != EFI_SUCCESS)
@@ -631,9 +635,11 @@
pcr_index = efi_tcg_event->header.pcr_index;
event_type = efi_tcg_event->header.event_type;
- ret = tcg2_pcr_extend(dev, pcr_index, &digest_list);
- if (ret != EFI_SUCCESS)
+ rc = tcg2_pcr_extend(dev, pcr_index, &digest_list);
+ if (rc) {
+ ret = EFI_DEVICE_ERROR;
goto out;
+ }
if (flags & EFI_TCG2_EXTEND_ONLY) {
if (event_log.truncated)
@@ -672,7 +678,7 @@
u8 *output_param_block)
{
struct udevice *dev;
- efi_status_t ret;
+ efi_status_t ret = EFI_SUCCESS;
u32 rc;
size_t resp_buf_size = output_param_block_size;
@@ -684,9 +690,10 @@
goto out;
}
- ret = tcg2_platform_get_tpm2(&dev);
- if (ret != EFI_SUCCESS)
+ if (tcg2_platform_get_tpm2(&dev)) {
+ ret = EFI_DEVICE_ERROR;
goto out;
+ }
rc = tpm2_submit_command(dev, input_param_block,
output_param_block, &resp_buf_size);
@@ -714,19 +721,25 @@
u32 *active_pcr_banks)
{
struct udevice *dev;
- efi_status_t ret;
+ efi_status_t ret = EFI_INVALID_PARAMETER;
EFI_ENTRY("%p, %p", this, active_pcr_banks);
- if (!this || !active_pcr_banks) {
- ret = EFI_INVALID_PARAMETER;
+ if (!this || !active_pcr_banks)
goto out;
- }
- ret = tcg2_platform_get_tpm2(&dev);
- if (ret != EFI_SUCCESS)
+
+ if (tcg2_platform_get_tpm2(&dev))
+ goto out;
+
+ /*
+ * EFI_INVALID_PARAMETER does not convey the problem type.
+ * but that's what currently the spec specifies.
+ * EFI_DEVICE_ERROR would be better
+ */
+ if (tcg2_get_active_pcr_banks(dev, active_pcr_banks))
goto out;
- ret = tcg2_get_active_pcr_banks(dev, active_pcr_banks);
+ ret = EFI_SUCCESS;
out:
return EFI_EXIT(ret);
@@ -852,14 +865,15 @@
u32 event_type, u32 size, u8 event[])
{
struct tpml_digest_values digest_list;
- efi_status_t ret;
+ efi_status_t ret = EFI_DEVICE_ERROR;
+ int rc;
- ret = tcg2_create_digest(dev, event, size, &digest_list);
- if (ret != EFI_SUCCESS)
+ rc = tcg2_create_digest(dev, event, size, &digest_list);
+ if (rc)
goto out;
- ret = tcg2_pcr_extend(dev, pcr_index, &digest_list);
- if (ret != EFI_SUCCESS)
+ rc = tcg2_pcr_extend(dev, pcr_index, &digest_list);
+ if (rc)
goto out;
ret = tcg2_agile_log_append(pcr_index, event_type, &digest_list,
@@ -901,10 +915,10 @@
struct tcg2_event_log elog;
struct udevice *dev;
efi_status_t ret;
+ int rc;
- ret = tcg2_platform_get_tpm2(&dev);
- if (ret != EFI_SUCCESS)
- return ret;
+ if (tcg2_platform_get_tpm2(&dev))
+ return EFI_DEVICE_ERROR;
ret = efi_allocate_pool(EFI_BOOT_SERVICES_DATA, TPM2_EVENT_LOG_SIZE,
(void **)&event_log.buffer);
@@ -933,9 +947,11 @@
*/
elog.log = event_log.buffer;
elog.log_size = TPM2_EVENT_LOG_SIZE;
- ret = tcg2_log_prepare_buffer(dev, &elog, false);
- if (ret != EFI_SUCCESS)
+ rc = tcg2_log_prepare_buffer(dev, &elog, false);
+ if (rc) {
+ ret = (rc == -ENOBUFS) ? EFI_BUFFER_TOO_SMALL : EFI_DEVICE_ERROR;
goto free_pool;
+ }
event_log.pos = elog.log_position;
@@ -1306,8 +1322,7 @@
if (!is_tcg2_protocol_installed())
return EFI_SUCCESS;
- ret = tcg2_platform_get_tpm2(&dev);
- if (ret != EFI_SUCCESS)
+ if (tcg2_platform_get_tpm2(&dev))
return EFI_SECURITY_VIOLATION;
rsvmap_size = size_of_rsvmap(dtb);
@@ -1356,8 +1371,7 @@
if (tcg2_efi_app_invoked)
return EFI_SUCCESS;
- ret = tcg2_platform_get_tpm2(&dev);
- if (ret != EFI_SUCCESS)
+ if (tcg2_platform_get_tpm2(&dev))
return EFI_SECURITY_VIOLATION;
ret = tcg2_measure_boot_variable(dev);
@@ -1406,9 +1420,8 @@
if (!is_tcg2_protocol_installed())
return EFI_SUCCESS;
- ret = tcg2_platform_get_tpm2(&dev);
- if (ret != EFI_SUCCESS)
- return ret;
+ if (tcg2_platform_get_tpm2(&dev))
+ return EFI_SECURITY_VIOLATION;
ret = measure_event(dev, 4, EV_EFI_ACTION,
strlen(EFI_RETURNING_FROM_EFI_APPLICATION),
@@ -1437,9 +1450,10 @@
goto out;
}
- ret = tcg2_platform_get_tpm2(&dev);
- if (ret != EFI_SUCCESS)
+ if (tcg2_platform_get_tpm2(&dev)) {
+ ret = EFI_SECURITY_VIOLATION;
goto out;
+ }
ret = measure_event(dev, 5, EV_EFI_ACTION,
strlen(EFI_EXIT_BOOT_SERVICES_INVOCATION),
@@ -1469,9 +1483,8 @@
if (!is_tcg2_protocol_installed())
return EFI_SUCCESS;
- ret = tcg2_platform_get_tpm2(&dev);
- if (ret != EFI_SUCCESS)
- goto out;
+ if (tcg2_platform_get_tpm2(&dev))
+ return EFI_SECURITY_VIOLATION;
ret = measure_event(dev, 5, EV_EFI_ACTION,
strlen(EFI_EXIT_BOOT_SERVICES_INVOCATION),
@@ -1551,8 +1564,7 @@
if (!is_tcg2_protocol_installed())
return EFI_SUCCESS;
- ret = tcg2_platform_get_tpm2(&dev);
- if (ret != EFI_SUCCESS)
+ if (tcg2_platform_get_tpm2(&dev))
return EFI_SECURITY_VIOLATION;
ret = tcg2_measure_secure_boot_variable(dev);
@@ -1577,8 +1589,7 @@
struct efi_event *event;
u32 err;
- ret = tcg2_platform_get_tpm2(&dev);
- if (ret != EFI_SUCCESS) {
+ if (tcg2_platform_get_tpm2(&dev)) {
log_warning("Missing TPMv2 device for EFI_TCG_PROTOCOL\n");
return EFI_SUCCESS;
}
@@ -1586,6 +1597,7 @@
/* initialize the TPM as early as possible. */
err = tpm_auto_start(dev);
if (err) {
+ ret = EFI_DEVICE_ERROR;
log_err("TPM startup failed\n");
goto fail;
}