efi_loader: efi_tcg2_register returns appropriate error
This commit modify efi_tcg2_register() to return the
appropriate error.
With this fix, sandbox will not boot because efi_tcg2_register()
fails due to some missing feature in GetCapabilities.
So disable sandbox if EFI_TCG2_PROTOCOL is enabled.
UEFI secure boot variable measurement is not directly related
to TCG2 protocol installation, tcg2_measure_secure_boot_variable()
is moved to the separate function.
Signed-off-by: Masahisa Kojima <masahisa.kojima@linaro.org>
Reviewed-by: Ilias Apalodimas <ilias.apalodimas@linaro.org>
diff --git a/lib/efi_loader/Kconfig b/lib/efi_loader/Kconfig
index 700dc83..24f9a2b 100644
--- a/lib/efi_loader/Kconfig
+++ b/lib/efi_loader/Kconfig
@@ -308,6 +308,8 @@
bool "EFI_TCG2_PROTOCOL support"
default y
depends on TPM_V2
+ # Sandbox TPM currently fails on GetCapabilities needed for TCG2
+ depends on !SANDBOX
select SHA1
select SHA256
select SHA384
diff --git a/lib/efi_loader/efi_setup.c b/lib/efi_loader/efi_setup.c
index 1aba71c..49172e3 100644
--- a/lib/efi_loader/efi_setup.c
+++ b/lib/efi_loader/efi_setup.c
@@ -241,6 +241,10 @@
ret = efi_tcg2_register();
if (ret != EFI_SUCCESS)
goto out;
+
+ ret = efi_tcg2_do_initial_measurement();
+ if (ret == EFI_SECURITY_VIOLATION)
+ goto out;
}
/* Secure boot */
diff --git a/lib/efi_loader/efi_tcg2.c b/lib/efi_loader/efi_tcg2.c
index 5f71b18..bdfd9a3 100644
--- a/lib/efi_loader/efi_tcg2.c
+++ b/lib/efi_loader/efi_tcg2.c
@@ -153,6 +153,15 @@
return 0;
}
+static bool is_tcg2_protocol_installed(void)
+{
+ struct efi_handler *handler;
+ efi_status_t ret;
+
+ ret = efi_search_protocol(efi_root, &efi_guid_tcg2_protocol, &handler);
+ return ret == EFI_SUCCESS;
+}
+
static u32 tcg_event_final_size(struct tpml_digest_values *digest_list)
{
u32 len;
@@ -1664,6 +1673,14 @@
event_log.buffer = NULL;
efi_free_pool(event_log.final_buffer);
event_log.final_buffer = NULL;
+
+ if (!is_tcg2_protocol_installed())
+ return;
+
+ ret = efi_remove_protocol(efi_root, &efi_guid_tcg2_protocol,
+ (void *)&efi_tcg2_protocol);
+ if (ret != EFI_SUCCESS)
+ log_err("Failed to remove EFI TCG2 protocol\n");
}
/**
@@ -2346,11 +2363,36 @@
}
/**
+ * efi_tcg2_do_initial_measurement() - do initial measurement
+ *
+ * Return: status code
+ */
+efi_status_t efi_tcg2_do_initial_measurement(void)
+{
+ efi_status_t ret;
+ struct udevice *dev;
+
+ if (!is_tcg2_protocol_installed())
+ return EFI_SUCCESS;
+
+ ret = platform_get_tpm2_device(&dev);
+ if (ret != EFI_SUCCESS)
+ return EFI_SECURITY_VIOLATION;
+
+ ret = tcg2_measure_secure_boot_variable(dev);
+ if (ret != EFI_SUCCESS)
+ goto out;
+
+out:
+ return ret;
+}
+
+/**
* efi_tcg2_register() - register EFI_TCG2_PROTOCOL
*
* If a TPM2 device is available, the TPM TCG2 Protocol is registered
*
- * Return: An error status is only returned if adding the protocol fails.
+ * Return: status code
*/
efi_status_t efi_tcg2_register(void)
{
@@ -2373,8 +2415,10 @@
}
ret = efi_init_event_log();
- if (ret != EFI_SUCCESS)
+ if (ret != EFI_SUCCESS) {
+ tcg2_uninit();
goto fail;
+ }
ret = efi_add_protocol(efi_root, &efi_guid_tcg2_protocol,
(void *)&efi_tcg2_protocol);
@@ -2391,24 +2435,9 @@
goto fail;
}
- ret = tcg2_measure_secure_boot_variable(dev);
- if (ret != EFI_SUCCESS) {
- tcg2_uninit();
- goto fail;
- }
-
return ret;
fail:
log_err("Cannot install EFI_TCG2_PROTOCOL\n");
- /*
- * Return EFI_SUCCESS and don't stop the EFI subsystem.
- * That's done for 2 reasons
- * - If the protocol is not installed the PCRs won't be extended. So
- * someone later in the boot flow will notice that and take the
- * necessary actions.
- * - The TPM sandbox is limited and we won't be able to run any efi
- * related tests with TCG2 enabled
- */
- return EFI_SUCCESS;
+ return ret;
}