[coreboot-gerrit] New patch to review for coreboot: tpm2: use pcr0 dependent nvram space policy definitions

Martin Roth (martinroth@google.com) gerrit at coreboot.org
Tue Jul 12 22:06:35 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/15635

-gerrit

commit ef0c2fa0e03405bd41165dd43bab903ce1bc7dd1
Author: Vadim Bendebury <vbendeb at chromium.org>
Date:   Sun Jul 3 15:24:23 2016 -0700

    tpm2: use pcr0 dependent nvram space policy definitions
    
    The TPM2 specification allows defining NV ram spaces in a manner
    that makes it impossible to remove the space until a certain PCR is in
    a certain state.
    
    This comes in handy when defining spaces for rollback counters: make
    their removal depend on PCR0 being in the default state. Then extend
    PCR0 to any value. This guarantees that the spaces can not be deleted.
    
    Also, there is no need t create firmware and kernel rollback spaces
    with different privileges: they both can be created with the same set of
    properties, the firmware space could be locked by the RO firmware, and
    the kernel space could be locked by the RW firmware thus providing
    necessary privilege levels.
    
    BRANCH=none
    BUG=chrome-os-partner:50645, chrome-os-partner:55063
    TEST=with the rest of the patches applied it is possible to boot into
          Chrome OS maintaining two rollback counter spaces in the TPM NV
          ram locked at different phases of the boot process.
    
    Change-Id: I889b2c4c4831ae01c093f33c09b4d98a11d758da
    Signed-off-by: Martin Roth <martinroth at chromium.org>
    Original-Commit-Id: 36317f5e85107b1b2e732a5bb2a38295120560cd
    Original-Change-Id: I69e5ada65a5f15a8c04be9def92a8e1f4b753d9a
    Original-Signed-off-by: Vadim Bendebury <vbendeb at chromium.org>
    Original-Reviewed-on: https://chromium-review.googlesource.com/358094
    Original-Reviewed-by: Aaron Durbin <adurbin at chromium.org>
    Original-Reviewed-by: Julius Werner <jwerner at chromium.org>
---
 src/include/tpm_lite/tlcl.h                        | 19 ++++-----------
 src/lib/tpm2_tlcl.c                                | 28 ++++++++++++++++------
 .../google/chromeos/vboot2/antirollback.c          |  2 --
 3 files changed, 25 insertions(+), 24 deletions(-)

diff --git a/src/include/tpm_lite/tlcl.h b/src/include/tpm_lite/tlcl.h
index c777ff9..1a4f638 100644
--- a/src/include/tpm_lite/tlcl.h
+++ b/src/include/tpm_lite/tlcl.h
@@ -67,22 +67,11 @@ uint32_t tlcl_define_space(uint32_t index, uint32_t perm, uint32_t size);
 #elif IS_ENABLED(CONFIG_TPM2)
 
 /*
- * This enum allows to communicate firmware privilege levels to the TPM layer,
- * which can map them into its own attributes.
+ * Define a TPM space. The define space command TPM command used by the tlcl
+ * layer is enforcing the policy which would not allow to delete the created
+ * space after any PCR0 change from its initial value.
  */
-enum privilege_level {
-	high_privilege = 1,
-	low_privilege
-};
-
-/*
- * Define a TPM space. Privilege level describes who can modify the space
- * (high_privilege - the RO code only, low_privilege - ether RO or RW. The
- * privilege level needs to be dropped below low_privilege before starting the
- * kernel.
- */
-uint32_t tlcl_define_space(uint32_t space_index,
-			   enum privilege_level priv_level, size_t space_size);
+uint32_t tlcl_define_space(uint32_t space_index, size_t space_size);
 #endif
 
 /**
diff --git a/src/lib/tpm2_tlcl.c b/src/lib/tpm2_tlcl.c
index c352a2c..8412ed0 100644
--- a/src/lib/tpm2_tlcl.c
+++ b/src/lib/tpm2_tlcl.c
@@ -248,11 +248,20 @@ uint32_t tlcl_write(uint32_t index, const void *data, uint32_t length)
 	return TPM_SUCCESS;
 }
 
-uint32_t tlcl_define_space(uint32_t space_index,
-			   enum privilege_level priv_level, size_t space_size)
+uint32_t tlcl_define_space(uint32_t space_index, size_t space_size)
 {
 	struct tpm2_nv_define_space_cmd nvds_cmd;
 	struct tpm2_response *response;
+	/*
+	 * This policy digest was obtained using TPM2_PolicyPCR selecting only
+	 * PCR_0 with a value of all zeros.
+	 */
+	static const uint8_t pcr0_unchanged_policy[] = {
+		0x09, 0x93, 0x3C, 0xCE, 0xEB, 0xB4, 0x41, 0x11,
+		0x18, 0x81, 0x1D, 0xD4, 0x47, 0x78, 0x80, 0x08,
+		0x88, 0x86, 0x62, 0x2D, 0xD7, 0x79, 0x94, 0x46,
+		0x62, 0x26, 0x68, 0x8E, 0xEE, 0xE6, 0x6A, 0xA1
+	};
 
 	/* Prepare the define space command structure. */
 	memset(&nvds_cmd, 0, sizeof(nvds_cmd));
@@ -261,16 +270,21 @@ uint32_t tlcl_define_space(uint32_t space_index,
 	nvds_cmd.publicInfo.nvIndex = HR_NV_INDEX + space_index;
 	nvds_cmd.publicInfo.nameAlg = TPM_ALG_SHA256;
 
-	/* Attributes common for all privilege levels. */
+	/* Attributes common for all NV ram spaces used by firmware. */
 	nvds_cmd.publicInfo.attributes.TPMA_NV_PPWRITE = 1;
 	nvds_cmd.publicInfo.attributes.TPMA_NV_AUTHREAD = 1;
 	nvds_cmd.publicInfo.attributes.TPMA_NV_PPREAD = 1;
 	nvds_cmd.publicInfo.attributes.TPMA_NV_PLATFORMCREATE = 1;
+	nvds_cmd.publicInfo.attributes.TPMA_NV_WRITE_STCLEAR = 1;
+	nvds_cmd.publicInfo.attributes.TPMA_NV_POLICY_DELETE = 1;
 
-	if (priv_level == high_privilege) {
-		nvds_cmd.publicInfo.attributes.TPMA_NV_WRITE_STCLEAR = 1;
-		nvds_cmd.publicInfo.attributes.TPMA_NV_POLICY_DELETE = 1;
-	}
+	/*
+	 * Use policy digest based on default pcr0 value. This makes sure that
+	 * the space can not be deleted as soon as PCR0 value has been
+	 * extended from default.
+	 */
+	nvds_cmd.publicInfo.authPolicy.t.buffer = pcr0_unchanged_policy;
+	nvds_cmd.publicInfo.authPolicy.t.size = sizeof(pcr0_unchanged_policy);
 
 	response = tpm_process_command(TPM2_NV_DefineSpace, &nvds_cmd);
 	printk(BIOS_INFO, "%s: response is %x\n",
diff --git a/src/vendorcode/google/chromeos/vboot2/antirollback.c b/src/vendorcode/google/chromeos/vboot2/antirollback.c
index 621758a..bce2ca1 100644
--- a/src/vendorcode/google/chromeos/vboot2/antirollback.c
+++ b/src/vendorcode/google/chromeos/vboot2/antirollback.c
@@ -128,7 +128,6 @@ static uint32_t safe_write(uint32_t index, const void *data, uint32_t length)
 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));
@@ -138,7 +137,6 @@ static uint32_t set_firmware_space(const void *firmware_blob)
 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)));



More information about the coreboot-gerrit mailing list