[coreboot-gerrit] Patch set updated for coreboot: vboot2: tpm2 factory initialization.

Martin Roth (martinroth@google.com) gerrit at coreboot.org
Thu Jul 7 20:59:07 CEST 2016


Martin Roth (martinroth at google.com) just uploaded a new patch set to gerrit, which you can find at https://review.coreboot.org/15571

-gerrit

commit 3f1ccfd259886c38eaba41b7abe55a4b07d5dfd4
Author: Vadim Bendebury <vbendeb at chromium.org>
Date:   Mon Jun 6 12:12:34 2016 -0700

    vboot2: tpm2 factory initialization.
    
    This patch adds a TPM2 specific path in the vboot2 initialization
    sequence when the device is turned on in the factory for the first
    time, namely two secure NVRAM spaces are created, with different
    access privileges.
    
    The higher privilege space can be modified only be the RO firmware,
    and the lower privilege space can be modified by both RO and RW
    firmware.
    
    The API is being modified to hide the TPM implementation details from
    the caller.
    
    Some functions previously exported as global are in fact not used
    anywhere else, they are being defined static.
    
    BRANCH=none
    BUG=chrome-os-partner:50645
    TEST=when this code is enabled the two secure spaces are successfully
         created during factory initialization.
    
    Original-Commit-Id: 5f082d6a9b095c3efc283b7a49eac9b4f2bcb6ec
    Original-Change-Id: I917b2f74dfdbd214d7f651ce3d4b80f4a18def20
    Original-Signed-off-by: Vadim Bendebury <vbendeb at chromium.org>
    Original-Reviewed-on: https://chromium-review.googlesource.com/353916
    Original-Reviewed-by: Bill Richardson <wfrichar at chromium.org>
    Original-Reviewed-by: Darren Krahn <dkrahn at chromium.org>
    
    squashed:
    
    mock tpm: drop unused functions
    
    safe_write() and safe_define_space() functions are defined in
    secdata_mock.c, but not used in mocked TPM mode.
    
    The actual functions have been redefined as static recently and their
    declarations were removed from src/include/antirollback.h, which now
    causes compilation problems when CONFIG_VBOOT2_MOCK_SECDATA is
    defined.
    
    Dropping the functions from secdata_mock.c solves the problem.
    
    BRANCH=none
    BUG=none
    TEST=compilation in mock secdata mode does not fail any more.
    
    Original-Commit-Id: c6d7824f52534ecd3b02172cb9078f03e318cb2b
    Original-Change-Id: Ia781ce99630d759469d2bded40952ed21830e611
    Original-Signed-off-by: Vadim Bendebury <vbendeb at chromium.org>
    Original-Reviewed-on: https://chromium-review.googlesource.com/356291
    Original-Tested-by: Caesar Wang <wxt at rock-chips.com>
    Original-Reviewed-by: Aaron Durbin <adurbin at chromium.org>
    Original-Reviewed-by: Randall Spangler <rspangler at chromium.org>
    
    Change-Id: Icb686c5f9129067eb4bb3ea10bbb85a075b29955
    Signed-off-by: Martin Roth <martinroth at chromium.org>
---
 src/include/antirollback.h                         |  16 --
 .../google/chromeos/vboot2/antirollback.c          | 187 +++++++++++++++------
 .../google/chromeos/vboot2/secdata_mock.c          |  10 --
 3 files changed, 131 insertions(+), 82 deletions(-)

diff --git a/src/include/antirollback.h b/src/include/antirollback.h
index 5ba36f7..f088ee2 100644
--- a/src/include/antirollback.h
+++ b/src/include/antirollback.h
@@ -63,22 +63,6 @@ uint32_t tpm_extend_pcr(struct vb2_context *ctx, int pcr,
 uint32_t tpm_clear_and_reenable(void);
 
 /**
- * Like tlcl_write(), but checks for write errors due to hitting the 64-write
- * limit and clears the TPM when that happens.  This can only happen when the
- * TPM is unowned, so it is OK to clear it (and we really have no choice).
- * This is not expected to happen frequently, but it could happen.
- */
-uint32_t safe_write(uint32_t index, const void *data, uint32_t length);
-
-/**
- * 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.
- */
-uint32_t safe_define_space(uint32_t index, uint32_t perm, uint32_t size);
-
-/**
  * Perform one-time initializations.
  *
  * Create the NVRAM spaces, and set their initial values as needed.  Sets the
diff --git a/src/vendorcode/google/chromeos/vboot2/antirollback.c b/src/vendorcode/google/chromeos/vboot2/antirollback.c
index fbc6d42..621758a 100644
--- a/src/vendorcode/google/chromeos/vboot2/antirollback.c
+++ b/src/vendorcode/google/chromeos/vboot2/antirollback.c
@@ -10,8 +10,8 @@
 #include <stdlib.h>
 #include <string.h>
 #include <tpm_lite/tlcl.h>
-#include <tpm_lite/tss_constants.h>
 #include <vb2_api.h>
+#include <console/console.h>
 
 #ifndef offsetof
 #define offsetof(A,B) __builtin_offsetof(A,B)
@@ -36,6 +36,8 @@
 	} while (0)
 
 
+static uint32_t safe_write(uint32_t index, const void *data, uint32_t length);
+
 uint32_t tpm_extend_pcr(struct vb2_context *ctx, int pcr,
 			enum vb2_pcr_digest which_digest)
 {
@@ -52,38 +54,6 @@ uint32_t tpm_extend_pcr(struct vb2_context *ctx, int pcr,
 	return tlcl_extend(pcr, buffer, NULL);
 }
 
-uint32_t tpm_clear_and_reenable(void)
-{
-	VBDEBUG("TPM: Clear and re-enable\n");
-	RETURN_ON_FAILURE(tlcl_force_clear());
-	RETURN_ON_FAILURE(tlcl_set_enable());
-	RETURN_ON_FAILURE(tlcl_set_deactivated(0));
-
-	return TPM_SUCCESS;
-}
-
-uint32_t safe_write(uint32_t index, const void *data, uint32_t length)
-{
-	uint32_t result = tlcl_write(index, data, length);
-	if (result == TPM_E_MAXNVWRITES) {
-		RETURN_ON_FAILURE(tpm_clear_and_reenable());
-		return tlcl_write(index, data, length);
-	} else {
-		return result;
-	}
-}
-
-uint32_t safe_define_space(uint32_t index, uint32_t perm, uint32_t size)
-{
-	uint32_t result = tlcl_define_space(index, perm, size);
-	if (result == TPM_E_MAXNVWRITES) {
-		RETURN_ON_FAILURE(tpm_clear_and_reenable());
-		return tlcl_define_space(index, perm, size);
-	} else {
-		return result;
-	}
-}
-
 static uint32_t read_space_firmware(struct vb2_context *ctx)
 {
 	int attempts = 3;
@@ -135,33 +105,110 @@ static uint32_t write_secdata(uint32_t index,
 	return TPM_E_CORRUPTED_STATE;
 }
 
-uint32_t factory_initialize_tpm(struct vb2_context *ctx)
+/*
+ * This is derived from rollback_index.h of vboot_reference. see struct
+ * RollbackSpaceKernel for details.
+ */
+static const uint8_t secdata_kernel[] = {
+	0x02,
+	0x4C, 0x57, 0x52, 0x47,
+	0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00,
+	0xE8,
+};
+
+#if IS_ENABLED(CONFIG_TPM2)
+
+/* Nothing special in the TPM2 path yet. */
+static uint32_t safe_write(uint32_t index, const void *data, uint32_t length)
 {
-	TPM_PERMANENT_FLAGS pflags;
-	uint32_t result;
-	/* this is derived from rollback_index.h of vboot_reference. see struct
-	 * RollbackSpaceKernel for details. */
-	static const uint8_t secdata_kernel[] = {
-			0x02,
-			0x4C, 0x57, 0x52, 0x47,
-			0x00, 0x00, 0x00, 0x00,
-			0x00, 0x00, 0x00,
-			0xE8,
-	};
+	return tlcl_write(index, data, length);
+}
 
-	VBDEBUG("TPM: factory initialization\n");
+static uint32_t set_firmware_space(const void *firmware_blob)
+{
+	RETURN_ON_FAILURE(tlcl_define_space(FIRMWARE_NV_INDEX,
+					    high_privilege,
+					    VB2_SECDATA_SIZE));
+	RETURN_ON_FAILURE(safe_write(FIRMWARE_NV_INDEX, firmware_blob,
+				     VB2_SECDATA_SIZE));
+	return TPM_SUCCESS;
+}
 
-	/*
-	 * Do a full test.  This only happens the first time the device is
-	 * turned on in the factory, so performance is not an issue.  This is
-	 * almost certainly not necessary, but it gives us more confidence
-	 * about some code paths below that are difficult to
-	 * test---specifically the ones that set lifetime flags, and are only
-	 * executed once per physical TPM.
-	 */
-	result = tlcl_self_test_full();
-	if (result != TPM_SUCCESS)
+static uint32_t set_kernel_space(const void *kernel_blob)
+{
+	RETURN_ON_FAILURE(tlcl_define_space(KERNEL_NV_INDEX,
+					    low_privilege,
+					    sizeof(secdata_kernel)));
+	RETURN_ON_FAILURE(safe_write(KERNEL_NV_INDEX, kernel_blob,
+				     sizeof(secdata_kernel)));
+	return TPM_SUCCESS;
+}
+
+static uint32_t _factory_initialize_tpm(struct vb2_context *ctx)
+{
+	RETURN_ON_FAILURE(set_firmware_space(ctx->secdata));
+	RETURN_ON_FAILURE(set_kernel_space(secdata_kernel));
+	return TPM_SUCCESS;
+}
+
+uint32_t tpm_clear_and_reenable(void)
+{
+	VBDEBUG("TPM: Clear and re-enable\n");
+	return TPM_SUCCESS;
+}
+
+#else
+
+uint32_t tpm_clear_and_reenable(void)
+{
+	VBDEBUG("TPM: Clear and re-enable\n");
+	RETURN_ON_FAILURE(tlcl_force_clear());
+	RETURN_ON_FAILURE(tlcl_set_enable());
+	RETURN_ON_FAILURE(tlcl_set_deactivated(0));
+
+	return TPM_SUCCESS;
+}
+
+/**
+ * Like tlcl_write(), but checks for write errors due to hitting the 64-write
+ * limit and clears the TPM when that happens.  This can only happen when the
+ * TPM is unowned, so it is OK to clear it (and we really have no choice).
+ * This is not expected to happen frequently, but it could happen.
+ */
+
+static uint32_t safe_write(uint32_t index, const void *data, uint32_t length)
+{
+	uint32_t result = tlcl_write(index, data, length);
+	if (result == TPM_E_MAXNVWRITES) {
+		RETURN_ON_FAILURE(tpm_clear_and_reenable());
+		return tlcl_write(index, data, length);
+	} else {
 		return result;
+	}
+}
+
+/**
+ * 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 uint32_t safe_define_space(uint32_t index, uint32_t perm, uint32_t size)
+{
+	uint32_t result = tlcl_define_space(index, perm, size);
+	if (result == TPM_E_MAXNVWRITES) {
+		RETURN_ON_FAILURE(tpm_clear_and_reenable());
+		return tlcl_define_space(index, perm, size);
+	} else {
+		return result;
+	}
+}
+
+static uint32_t _factory_initialize_tpm(struct vb2_context *ctx)
+{
+	TPM_PERMANENT_FLAGS pflags;
+	uint32_t result;
 
 	result = tlcl_get_permanent_flags(&pflags);
 	if (result != TPM_SUCCESS)
@@ -215,6 +262,34 @@ uint32_t factory_initialize_tpm(struct vb2_context *ctx)
 	RETURN_ON_FAILURE(write_secdata(FIRMWARE_NV_INDEX,
 					ctx->secdata,
 					VB2_SECDATA_SIZE));
+	return TPM_SUCCESS;
+}
+#endif
+
+uint32_t factory_initialize_tpm(struct vb2_context *ctx)
+{
+	uint32_t result;
+
+	/* Defines and sets vb2 secdata space */
+	vb2api_secdata_create(ctx);
+
+	VBDEBUG("TPM: factory initialization\n");
+
+	/*
+	 * Do a full test.  This only happens the first time the device is
+	 * turned on in the factory, so performance is not an issue.  This is
+	 * almost certainly not necessary, but it gives us more confidence
+	 * about some code paths below that are difficult to
+	 * test---specifically the ones that set lifetime flags, and are only
+	 * executed once per physical TPM.
+	 */
+	result = tlcl_self_test_full();
+	if (result != TPM_SUCCESS)
+		return result;
+
+	result = _factory_initialize_tpm(ctx);
+	if (result != TPM_SUCCESS)
+		return result;
 
 	VBDEBUG("TPM: factory initialization successful\n");
 
diff --git a/src/vendorcode/google/chromeos/vboot2/secdata_mock.c b/src/vendorcode/google/chromeos/vboot2/secdata_mock.c
index 3bd4b17..03616c1 100644
--- a/src/vendorcode/google/chromeos/vboot2/secdata_mock.c
+++ b/src/vendorcode/google/chromeos/vboot2/secdata_mock.c
@@ -21,16 +21,6 @@ uint32_t tpm_clear_and_reenable(void)
 	return TPM_SUCCESS;
 }
 
-uint32_t safe_write(uint32_t index, const void *data, uint32_t length)
-{
-	return TPM_SUCCESS;
-}
-
-uint32_t safe_define_space(uint32_t index, uint32_t perm, uint32_t size)
-{
-	return TPM_SUCCESS;
-}
-
 uint32_t antirollback_read_space_firmware(struct vb2_context *ctx)
 {
 	vb2api_secdata_create(ctx);



More information about the coreboot-gerrit mailing list