With CONFIG_TPM_PCR_ALLOCATE, active banks with unsupported algorithms
are only deactivated by tcg2_log_prepare_buffer() or, as a fallback,
when a PCR is extended. Users of the TPM which do not go through
tcg2_measurement_init() or the EFI TCG2 protocol therefore only notice
the unsupported banks when measuring, e.g.

  tcg2_create_digest: unsupported algorithm 28
  Cannot extend PCRs if all the TPM enabled algorithms are not supported

Deactivate them in tpm2_startup() already, before anything gets
measured, but only if the TPM was actually started there, i.e.
TPM2_Startup(TPM2_SU_CLEAR) succeeded. This also covers
tpm2_auto_start(), which calls tpm2_startup() if the TPM was not
started yet.

If TPM2_Startup returns TPM2_RC_INITIALIZE, an earlier boot stage (e.g.
SPL or TF-A) has already started the TPM and is expected to take care
of the banks. With an event log, tcg2_log_prepare_buffer() still aligns
them afterwards. The fallback in tpm2_pcr_extend() remains for the case
that the earlier stage supports more algorithms than U-Boot.
TPM2_SU_STATE, used by tpm_resume(), is left alone.

If the deactivation fails, e.g. because the TPM refuses the allocation
or no supported bank would remain active, return an error. With
CONFIG_TPM_PCR_ALLOCATE enabled, U-Boot is expected to manage the banks,
so fail early instead of at the first PCR extend.

Signed-off-by: Tycho Kirchner <[email protected]>
---
 lib/tpm-v2.c | 13 +++++++++++++
 1 file changed, 13 insertions(+)

diff --git a/lib/tpm-v2.c b/lib/tpm-v2.c
index 18ec9eb960d..6370b97a7d4 100644
--- a/lib/tpm-v2.c
+++ b/lib/tpm-v2.c
@@ -201,6 +201,19 @@ u32 tpm2_startup(struct udevice *dev, bool bon, enum 
tpm2_startup_types mode)
        if ((ret && ret != TPM2_RC_INITIALIZE) || !bon)
                return ret;
 
+       /*
+        * Only the boot stage which actually starts the TPM deactivates active
+        * banks with unsupported algorithms. On success, this resets the board.
+        */
+       if (IS_ENABLED(CONFIG_TPM_PCR_ALLOCATE) && !ret &&
+           mode == TPM2_SU_CLEAR) {
+               ret = tpm2_activate_banks(dev, 0);
+               if (ret) {
+                       log_err("TPM: failed to deactivate unsupported 
banks\n");
+                       return ret;
+               }
+       }
+
        return tpm2_update_active_banks(dev);
 }
 
-- 
2.47.3

Reply via email to