Philipp Deppenwiese has uploaded this change for review. ( https://review.coreboot.org/28085
Change subject: security/tpm: Fix TPM 1.2 state machine issues ......................................................................
security/tpm: Fix TPM 1.2 state machine issues
* Add hard_reset mechanism and result checks for the ramstage TPM driver. * Move enabling TPM before activating otherwise it isn't successful.
More information can be found via the TCG specification.
Tested=Elgon
Change-Id: Ided110e0c1889b302e29acac6d8d2341f97eb10b Signed-off-by: Philipp Deppenwiese zaolin@das-labor.org --- M src/drivers/tpm/tpm.c M src/security/tpm/tspi/tspi.c 2 files changed, 24 insertions(+), 19 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/85/28085/1
diff --git a/src/drivers/tpm/tpm.c b/src/drivers/tpm/tpm.c index e4a81c3..e7c1165 100644 --- a/src/drivers/tpm/tpm.c +++ b/src/drivers/tpm/tpm.c @@ -17,6 +17,7 @@ #include <stddef.h> #include <bootstate.h> #include <security/tpm/tspi.h> +#include <reset.h>
#if IS_ENABLED(CONFIG_ARCH_X86) #include <arch/acpi.h> @@ -24,12 +25,15 @@
static void init_tpm_dev(void *unused) { + uint32_t result; #if IS_ENABLED(CONFIG_ARCH_X86) int s3resume = acpi_is_wakeup_s3(); - tpm_setup(s3resume); + result = tpm_setup(s3resume); #else - tpm_setup(false); + result = tpm_setup(false); #endif + if (result == TPM_E_MUST_REBOOT) + do_hard_reset(); }
BOOT_STATE_INIT_ENTRY(BS_DEV_INIT, BS_ON_ENTRY, init_tpm_dev, NULL); diff --git a/src/security/tpm/tspi/tspi.c b/src/security/tpm/tspi/tspi.c index 950e930..f3093e7 100644 --- a/src/security/tpm/tspi/tspi.c +++ b/src/security/tpm/tspi/tspi.c @@ -25,17 +25,31 @@ #if IS_ENABLED(CONFIG_TPM1) static uint32_t tpm1_invoke_state_machine(void) { - uint8_t disable; + uint8_t disabled; uint8_t deactivated; uint32_t result = TPM_SUCCESS;
/* Check that the TPM is enabled and activated. */ - result = tlcl_get_flags(&disable, &deactivated, NULL); + result = tlcl_get_flags(&disabled, &deactivated, NULL); if (result != TPM_SUCCESS) { printk(BIOS_ERR, "TPM: Can't read capabilities.\n"); return result; }
+ if (disabled) { + printk(BIOS_INFO, "TPM: disabled (%d)." + "Enabling...\n", disabled); + + result = tlcl_set_enable(); + if (result != TPM_SUCCESS) { + printk(BIOS_ERR, "TPM: Can't set enabled state.\n"); + return result; + } + + printk(BIOS_INFO, "TPM: Must reboot to re-enable\n"); + result = TPM_E_MUST_REBOOT; + } + if (!!deactivated != IS_ENABLED(CONFIG_TPM_DEACTIVATE)) { printk(BIOS_INFO, "TPM: Unexpected TPM deactivated state. Toggling...\n"); @@ -50,19 +64,6 @@ result = TPM_E_MUST_REBOOT; }
- if (disable && !deactivated) { - printk(BIOS_INFO, "TPM: disabled (%d). Enabling...\n", disable); - - result = tlcl_set_enable(); - if (result != TPM_SUCCESS) { - printk(BIOS_ERR, "TPM: Can't set enabled state.\n"); - return result; - } - - printk(BIOS_INFO, "TPM: Must reboot to re-enable\n"); - result = TPM_E_MUST_REBOOT; - } - return result; } #endif @@ -122,8 +123,8 @@ result = tlcl_physical_presence_cmd_enable(); if (result != TPM_SUCCESS) { printk( - BIOS_ERR, - "TPM: Can't enable physical presence command.\n"); + BIOS_ERR, + "TPM: Can't enable physical presence command.\n"); goto out; }