diff options
| author | Tom Rini <[email protected]> | 2023-02-28 09:50:16 -0500 |
|---|---|---|
| committer | Tom Rini <[email protected]> | 2023-02-28 09:50:16 -0500 |
| commit | f10905b4b7b9b6888e2532cdfb3536d2244676cb (patch) | |
| tree | 6609cc57d553683eaed0ccfb9dca295af66ef29c /lib | |
| parent | c12fe739ea1ea9ba4ca289bd4e7b1293a9ccb256 (diff) | |
| parent | a11be4c303eabb142e074c7ca14b6ae0d293f0cb (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.c | 2 | ||||
| -rw-r--r-- | lib/tpm-v1.c | 14 | ||||
| -rw-r--r-- | lib/tpm-v2.c | 17 | ||||
| -rw-r--r-- | lib/tpm_api.c | 21 |
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)) |
