summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorTom Rini <[email protected]>2023-02-28 09:50:16 -0500
committerTom Rini <[email protected]>2023-02-28 09:50:16 -0500
commitf10905b4b7b9b6888e2532cdfb3536d2244676cb (patch)
tree6609cc57d553683eaed0ccfb9dca295af66ef29c /lib
parentc12fe739ea1ea9ba4ca289bd4e7b1293a9ccb256 (diff)
parenta11be4c303eabb142e074c7ca14b6ae0d293f0cb (diff)
Merge tag 'tpm-next-28022023' of https://source.denx.de/u-boot/custodians/u-boot-tpm into next
TPM auto startup and testing: Due to U-Boot's lazy binding we always relied on command line tools to initialize the TPM subsystem and devices. One exception is the EFI subsystem. When compiled with TCG2 measured boot support the TPM was automatically initialized. However that init was not complete. The TCG specs [0] (and specifically ยง12.3 Self-test modes) describe how self-tests on the device should be performed. This PR is adding an extra API function, that can be used to initialize the TPM2.0 properly. Simon added the equivalent for TPM1.2 and refactored the DM tests to include the new funtion. [0] https://trustedcomputinggroup.org/wp-content/uploads/TPM-Rev-2.0-Part-1-Architecture-01.07-2014-03-13.pdf
Diffstat (limited to 'lib')
-rw-r--r--lib/efi_loader/efi_tcg2.c2
-rw-r--r--lib/tpm-v1.c14
-rw-r--r--lib/tpm-v2.c17
-rw-r--r--lib/tpm_api.c21
4 files changed, 53 insertions, 1 deletions
diff --git a/lib/efi_loader/efi_tcg2.c b/lib/efi_loader/efi_tcg2.c
index 2dcc3171576..a83ae7a46cf 100644
--- a/lib/efi_loader/efi_tcg2.c
+++ b/lib/efi_loader/efi_tcg2.c
@@ -2495,7 +2495,7 @@ efi_status_t efi_tcg2_register(void)
}
/* initialize the TPM as early as possible. */
- err = tpm_startup(dev, TPM_ST_CLEAR);
+ err = tpm_auto_start(dev);
if (err) {
log_err("TPM startup failed\n");
goto fail;
diff --git a/lib/tpm-v1.c b/lib/tpm-v1.c
index d0e3ab1b21d..60a18ca5040 100644
--- a/lib/tpm-v1.c
+++ b/lib/tpm-v1.c
@@ -69,6 +69,20 @@ u32 tpm1_continue_self_test(struct udevice *dev)
return tpm_sendrecv_command(dev, command, NULL, NULL);
}
+u32 tpm1_auto_start(struct udevice *dev)
+{
+ u32 rc;
+
+ rc = tpm1_startup(dev, TPM_ST_CLEAR);
+ /* continue on if the TPM is already inited */
+ if (rc && rc != TPM_INVALID_POSTINIT)
+ return rc;
+
+ rc = tpm1_self_test_full(dev);
+
+ return rc;
+}
+
u32 tpm1_clear_and_reenable(struct udevice *dev)
{
u32 ret;
diff --git a/lib/tpm-v2.c b/lib/tpm-v2.c
index 697b982e079..9ab5b46df17 100644
--- a/lib/tpm-v2.c
+++ b/lib/tpm-v2.c
@@ -44,6 +44,23 @@ u32 tpm2_self_test(struct udevice *dev, enum tpm2_yes_no full_test)
return tpm_sendrecv_command(dev, command_v2, NULL, NULL);
}
+u32 tpm2_auto_start(struct udevice *dev)
+{
+ u32 rc;
+
+ rc = tpm2_self_test(dev, TPMI_YES);
+
+ if (rc == TPM2_RC_INITIALIZE) {
+ rc = tpm2_startup(dev, TPM2_SU_CLEAR);
+ if (rc)
+ return rc;
+
+ rc = tpm2_self_test(dev, TPMI_YES);
+ }
+
+ return rc;
+}
+
u32 tpm2_clear(struct udevice *dev, u32 handle, const char *pw,
const ssize_t pw_sz)
{
diff --git a/lib/tpm_api.c b/lib/tpm_api.c
index 7e8df8795ef..3ef5e811794 100644
--- a/lib/tpm_api.c
+++ b/lib/tpm_api.c
@@ -35,6 +35,27 @@ u32 tpm_startup(struct udevice *dev, enum tpm_startup_type mode)
}
}
+u32 tpm_auto_start(struct udevice *dev)
+{
+ u32 rc;
+
+ /*
+ * the tpm_init() will return -EBUSY if the init has already happened
+ * The selftest and startup code can run multiple times with no side
+ * effects
+ */
+ rc = tpm_init(dev);
+ if (rc && rc != -EBUSY)
+ return rc;
+
+ if (tpm_is_v1(dev))
+ return tpm1_auto_start(dev);
+ else if (tpm_is_v2(dev))
+ return tpm2_auto_start(dev);
+ else
+ return -ENOSYS;
+}
+
u32 tpm_resume(struct udevice *dev)
{
if (tpm_is_v1(dev))