aboutsummaryrefslogtreecommitdiff
path: root/src/security/vboot/secdata_tpm1.c
diff options
context:
space:
mode:
authorSergii Dmytruk <sergii.dmytruk@3mdeb.com>2024-03-21 21:06:49 +0200
committerMartin L Roth <gaumless@gmail.com>2024-03-28 15:20:11 +0000
commitefc615e239004c604a2c907ee36fa21dc6adaf58 (patch)
treecfd1338e626f72472222880e70489a36798710de /src/security/vboot/secdata_tpm1.c
parent47e9e8cde1810ee9f249027b14ee9f82a7a52d84 (diff)
security/vboot: extract secdata_tpm{1,2}.c
Most of the original secdata_tpm.c was TPM2-specific implementation. Just moving the code around, with trivial tweaks: - drop now unnecessary #ifdef directives from _factory_initialize_tpm() - drop leading underscore from _factory_initialize_tpm{1,2}() (external identifiers should not start with an underscore in C) - drop unused <security/vboot/tpm_common.h> include and sub-includes of tss.h which should be considered its part (so this isn't an indirect inclusion) - fixed formatting of RETURN_ON_FAILURE() which didn't have slashes aligned no matter what tab width was used Change-Id: I0090b748d7d3b2d76a941b87b5885682fd81c4fc Signed-off-by: Sergii Dmytruk <sergii.dmytruk@3mdeb.com> Reviewed-on: https://review.coreboot.org/c/coreboot/+/81415 Reviewed-by: Julius Werner <jwerner@chromium.org> Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Diffstat (limited to 'src/security/vboot/secdata_tpm1.c')
-rw-r--r--src/security/vboot/secdata_tpm1.c83
1 files changed, 83 insertions, 0 deletions
diff --git a/src/security/vboot/secdata_tpm1.c b/src/security/vboot/secdata_tpm1.c
new file mode 100644
index 0000000000..b66b939718
--- /dev/null
+++ b/src/security/vboot/secdata_tpm1.c
@@ -0,0 +1,83 @@
+/* SPDX-License-Identifier: BSD-3-Clause */
+
+#include <security/tpm/tspi.h>
+#include <security/tpm/tss.h>
+#include <security/vboot/antirollback.h>
+#include <vb2_api.h>
+
+#include "secdata_tpm_private.h"
+
+/**
+ * Similarly to safe_write(), this ensures we don't fail a DefineSpace because
+ * we hit the TPM write limit. This is even less likely to happen than with
+ * writes because we only define spaces once at initialization, but we'd
+ * rather be paranoid about this.
+ */
+static tpm_result_t safe_define_space(uint32_t index, uint32_t perm, uint32_t size)
+{
+ tpm_result_t rc = tlcl1_define_space(index, perm, size);
+ if (rc == TPM_MAXNVWRITES) {
+ RETURN_ON_FAILURE(tpm_clear_and_reenable());
+ return tlcl1_define_space(index, perm, size);
+ } else {
+ return rc;
+ }
+}
+
+tpm_result_t factory_initialize_tpm1(struct vb2_context *ctx)
+{
+ TPM_PERMANENT_FLAGS pflags;
+ tpm_result_t rc;
+
+ vb2api_secdata_firmware_create(ctx);
+ vb2api_secdata_kernel_create_v0(ctx);
+
+ rc = tlcl1_get_permanent_flags(&pflags);
+ if (rc != TPM_SUCCESS)
+ return rc;
+
+ /*
+ * TPM may come from the factory without physical presence finalized.
+ * Fix if necessary.
+ */
+ VBDEBUG("TPM: physicalPresenceLifetimeLock=%d\n",
+ pflags.physicalPresenceLifetimeLock);
+ if (!pflags.physicalPresenceLifetimeLock) {
+ VBDEBUG("TPM: Finalizing physical presence\n");
+ RETURN_ON_FAILURE(tlcl_finalize_physical_presence());
+ }
+
+ /*
+ * The TPM will not enforce the NV authorization restrictions until the
+ * execution of a TPM_NV_DefineSpace with the handle of
+ * TPM_NV_INDEX_LOCK. Here we create that space if it doesn't already
+ * exist. */
+ VBDEBUG("TPM: nvLocked=%d\n", pflags.nvLocked);
+ if (!pflags.nvLocked) {
+ VBDEBUG("TPM: Enabling NV locking\n");
+ RETURN_ON_FAILURE(tlcl1_set_nv_locked());
+ }
+
+ /* Clear TPM owner, in case the TPM is already owned for some reason. */
+ VBDEBUG("TPM: Clearing owner\n");
+ RETURN_ON_FAILURE(tpm_clear_and_reenable());
+
+ /* Define and write secdata_kernel space. */
+ RETURN_ON_FAILURE(safe_define_space(KERNEL_NV_INDEX,
+ TPM_NV_PER_PPWRITE,
+ VB2_SECDATA_KERNEL_SIZE_V02));
+ RETURN_ON_FAILURE(safe_write(KERNEL_NV_INDEX,
+ ctx->secdata_kernel,
+ VB2_SECDATA_KERNEL_SIZE_V02));
+
+ /* Define and write secdata_firmware space. */
+ RETURN_ON_FAILURE(safe_define_space(FIRMWARE_NV_INDEX,
+ TPM_NV_PER_GLOBALLOCK |
+ TPM_NV_PER_PPWRITE,
+ VB2_SECDATA_FIRMWARE_SIZE));
+ RETURN_ON_FAILURE(safe_write(FIRMWARE_NV_INDEX,
+ ctx->secdata_firmware,
+ VB2_SECDATA_FIRMWARE_SIZE));
+
+ return TPM_SUCCESS;
+}