[U-Boot] [PATCH 13/18] tpm: add TPM2_PCR_Extend command support

Miquel Raynal miquel.raynal at bootlin.com
Thu Mar 8 15:40:16 UTC 2018


Add support for the TPM2_PCR_Extend command.

Change the command file and the help accordingly.

Signed-off-by: Miquel Raynal <miquel.raynal at bootlin.com>
---
 cmd/tpm.c     | 18 ++++++++++++++++++
 include/tpm.h | 18 ++++++++++++++++++
 lib/tpm.c     | 41 +++++++++++++++++++++++++++++++++++++++++
 3 files changed, 77 insertions(+)

diff --git a/cmd/tpm.c b/cmd/tpm.c
index 93dcd1a65c..3f284f0adf 100644
--- a/cmd/tpm.c
+++ b/cmd/tpm.c
@@ -349,6 +349,18 @@ static int do_tpm_pcr_event(cmd_tbl_t *cmdtp, int flag,
 	return report_return_code(rc);
 }
 
+static int do_tpm_pcr_extend(cmd_tbl_t *cmdtp, int flag,
+			     int argc, char * const argv[])
+{
+	u32 index = simple_strtoul(argv[1], NULL, 0);
+	void *digest = (void *)simple_strtoul(argv[2], NULL, 0);
+
+	if (argc != 3)
+		return CMD_RET_USAGE;
+
+	return report_return_code(tpm2_pcr_extend(index, digest));
+}
+
 static int do_tpm_pcr_read(cmd_tbl_t *cmdtp, int flag,
 		int argc, char * const argv[])
 {
@@ -890,6 +902,8 @@ static cmd_tbl_t tpm_commands[] = {
 			 do_tpm_nv_write_value, "", ""),
 	U_BOOT_CMD_MKENT(pcr_event, 0, 1,
 			 do_tpm_pcr_event, "", ""),
+	U_BOOT_CMD_MKENT(pcr_extend, 0, 1,
+			 do_tpm_pcr_extend, "", ""),
 	U_BOOT_CMD_MKENT(pcr_read, 0, 1,
 			 do_tpm_pcr_read, "", ""),
 	U_BOOT_CMD_MKENT(tsc_physical_presence, 0, 1,
@@ -1026,6 +1040,10 @@ U_BOOT_CMD(tpm, CONFIG_SYS_MAXARGS, 1, do_tpm,
 "      digest of 32 bytes for TPMv2. Value of the PCR is given at <digest_out>\n"
 "  pcr_read index addr count\n"
 "    - Read <count> bytes from PCR <index> to memory address <addr>.\n"
+"  pcr_extend index <digest_in>\n"
+"    - Add a new measurement to a PCR.  Update PCR <index> with\n"
+"      <digest_in>. It must be a 20 byte digest for TPMv1 or a SHA256\n"
+"      digest of 32 bytes for TPMv2.\n"
 #ifdef CONFIG_TPM_AUTH_SESSIONS
 "Authorization Sessions\n"
 "  oiap\n"
diff --git a/include/tpm.h b/include/tpm.h
index a863ac6196..b88ad4b2f4 100644
--- a/include/tpm.h
+++ b/include/tpm.h
@@ -76,6 +76,14 @@ enum tpm2_return_codes {
 	TPM2_RC_LOCKOUT		= 0x0921,
 };
 
+enum tpm_algorithms {
+	TPM2_ALG_XOR		= 0x0A,
+	TPM2_ALG_SHA256		= 0x0B,
+	TPM2_ALG_SHA384		= 0x0C,
+	TPM2_ALG_SHA512		= 0x0D,
+	TPM2_ALG_NULL		= 0x10,
+};
+
 enum tpm_physical_presence {
 	TPM_PHYSICAL_PRESENCE_HW_DISABLE	= 0x0200,
 	TPM_PHYSICAL_PRESENCE_CMD_DISABLE	= 0x0100,
@@ -548,6 +556,16 @@ uint32_t tpm_nv_write_value(uint32_t index, const void *data, uint32_t length);
  */
 int tpm_pcr_event(u32 index, const void *in_digest, void *out_digest);
 
+/**
+ * Issue a TPM_PCR_Extend command.
+ *
+ * @param index		Index of the PCR
+ * @param digest	Value representing the event to be recorded
+ *
+ * @return return code of the operation
+ */
+int tpm2_pcr_extend(u32 index, const uint8_t *digest);
+
 /**
  * Issue a TPM_PCRRead command.
  *
diff --git a/lib/tpm.c b/lib/tpm.c
index 07e2490af2..e74530d538 100644
--- a/lib/tpm.c
+++ b/lib/tpm.c
@@ -527,6 +527,47 @@ int tpm_pcr_event(u32 index, const void *in_digest, void *out_digest)
 	return 0;
 }
 
+int tpm2_pcr_extend(u32 index, const uint8_t *digest)
+{
+	u8 command_v2[COMMAND_BUFFER_SIZE] = {
+		STRINGIFY16(TPM2_ST_SESSIONS),	/* TAG */
+		STRINGIFY32(33 + TPM2_DIGEST_LENGTH), /* Command size */
+		STRINGIFY32(TPM2_CC_PCR_EXTEND), /* Command code */
+
+		/* HANDLE */
+		STRINGIFY32(index),		/* Handle (PCR Index) */
+
+		/* AUTH_SESSION */
+		STRINGIFY32(9),			/* Authorization size */
+		STRINGIFY32(TPM2_RS_PW),	/* Session handle */
+		STRINGIFY16(0),			/* Size of <nonce> */
+						/* <nonce> (if any) */
+		0,				/* Attributes: Cont/Excl/Rst */
+		STRINGIFY16(0),			/* Size of <hmac/password> */
+						/* <hmac/password> (if any) */
+		STRINGIFY32(1),			/* Count (number of hashes) */
+		STRINGIFY16(TPM2_ALG_SHA256),	/* Algorithm of the hash */
+		/* STRING(digest)		   Digest */
+	};
+	unsigned int offset = 33;
+	int ret;
+
+	if (!is_tpmv2)
+		return TPM_LIB_ERROR;
+
+	/*
+	 * Fill the command structure starting from the first buffer:
+	 *     - the digest
+	 */
+	ret = pack_byte_string(command_v2, sizeof(command_v2), "s",
+			       offset, digest, TPM2_DIGEST_LENGTH);
+	offset += TPM2_DIGEST_LENGTH;
+	if (ret)
+		return TPM_LIB_ERROR;
+
+	return tpm_sendrecv_command(command_v2,	NULL, NULL);
+}
+
 uint32_t tpm_pcr_read(uint32_t index, void *data, size_t count)
 {
 	const uint8_t command[14] = {
-- 
2.14.1



More information about the U-Boot mailing list