[U-Boot] [PATCH 15/18] tpm: add TPM2_GetCapability command support

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


Add support for the TPM2_GetCapability command.

Change the command file and the help accordingly.

Signed-off-by: Miquel Raynal <miquel.raynal at bootlin.com>
---
 cmd/tpm.c     | 31 ++++++++++++++++++++-----------
 include/tpm.h | 14 +++++++-------
 lib/tpm.c     | 39 +++++++++++++++++++++++++++++++++++++--
 3 files changed, 64 insertions(+), 20 deletions(-)

diff --git a/cmd/tpm.c b/cmd/tpm.c
index 8630571b1a..7fcfbf8550 100644
--- a/cmd/tpm.c
+++ b/cmd/tpm.c
@@ -433,21 +433,30 @@ static int do_tpm_physical_set_deactivated(cmd_tbl_t *cmdtp, int flag,
 static int do_tpm_get_capability(cmd_tbl_t *cmdtp, int flag,
 		int argc, char * const argv[])
 {
-	uint32_t cap_area, sub_cap, rc;
-	void *cap;
+	u32 capability, property, rc;
+	u8 *data;
 	size_t count;
+	int i, j;
 
 	if (argc != 5)
 		return CMD_RET_USAGE;
-	cap_area = simple_strtoul(argv[1], NULL, 0);
-	sub_cap = simple_strtoul(argv[2], NULL, 0);
-	cap = (void *)simple_strtoul(argv[3], NULL, 0);
+	capability = simple_strtoul(argv[1], NULL, 0);
+	property = simple_strtoul(argv[2], NULL, 0);
+	data = (void *)simple_strtoul(argv[3], NULL, 0);
 	count = simple_strtoul(argv[4], NULL, 0);
 
-	rc = tpm_get_capability(cap_area, sub_cap, cap, count);
+	rc = tpm_get_capability(capability, property, data, count);
 	if (!rc) {
-		puts("capability information:\n");
-		print_byte_string(cap, count);
+		printf("Capabilities read from TPM:\n");
+		for (i = 0; i < count; i++) {
+			printf("Property 0x");
+			for (j = 0; j < 4; j++)
+				printf("%02x", data[(i * 8) + j]);
+			printf(": 0x");
+			for (j = 4; j < 8; j++)
+				printf("%02x", data[(i * 8) + j]);
+			printf("\n");
+		}
 	}
 
 	return report_return_code(rc);
@@ -998,9 +1007,9 @@ U_BOOT_CMD(tpm, CONFIG_SYS_MAXARGS, 1, do_tpm,
 "  tsc_physical_presence flags\n"
 "    - Set TPM device's Physical Presence flags to <flags>.\n"
 "The Capability Commands:\n"
-"  get_capability cap_area sub_cap addr count\n"
-"    - Read <count> bytes of TPM capability indexed by <cap_area> and\n"
-"      <sub_cap> to memory address <addr>.\n"
+"  get_capability <cap_area|capability> <sub_cap|property> <addr> <count>\n"
+"    - Read <count> bytes of TPM capability indexed by <cap_area|capability>\n"
+"      and <sub_cap|property> to memory address <addr>.\n"
 #if defined(CONFIG_TPM_FLUSH_RESOURCES) || defined(CONFIG_TPM_LIST_RESOURCES)
 "Resource management functions\n"
 #endif
diff --git a/include/tpm.h b/include/tpm.h
index 2df2ea3c5b..369119fc1b 100644
--- a/include/tpm.h
+++ b/include/tpm.h
@@ -628,17 +628,17 @@ uint32_t tpm_physical_set_deactivated(uint8_t state);
 
 /**
  * Issue a TPM_GetCapability command.  This implementation is limited
- * to query sub_cap index that is 4-byte wide.
+ * to query property index that is 4-byte wide.
  *
- * @param cap_area	partition of capabilities
- * @param sub_cap	further definition of capability, which is
+ * @param capability	partition of capabilities
+ * @param property	further definition of capability, which is
  *			limited to be 4-byte wide
- * @param cap		output buffer for capability information
- * @param count		size of ouput buffer
+ * @param buf		output buffer for capability information
+ * @param propertycount size of output buffer
  * @return return code of the operation
  */
-uint32_t tpm_get_capability(uint32_t cap_area, uint32_t sub_cap,
-		void *cap, size_t count);
+int tpm_get_capability(u32 capability, u32 property, void *buf,
+		       size_t property_count);
 
 /**
  * Issue a TPM_FlushSpecific command for a AUTH ressource.
diff --git a/lib/tpm.c b/lib/tpm.c
index 925b21e2d6..59f6cd6dba 100644
--- a/lib/tpm.c
+++ b/lib/tpm.c
@@ -789,8 +789,7 @@ uint32_t tpm_physical_set_deactivated(uint8_t state)
 	return tpm_sendrecv_command(buf, NULL, NULL);
 }
 
-uint32_t tpm_get_capability(uint32_t cap_area, uint32_t sub_cap,
-		void *cap, size_t count)
+int tpm1_get_capability(u32 cap_area, u32 sub_cap, void *cap, size_t count)
 {
 	const uint8_t command[22] = {
 		0x0, 0xc1,		/* TPM_TAG */
@@ -829,6 +828,42 @@ uint32_t tpm_get_capability(uint32_t cap_area, uint32_t sub_cap,
 	return 0;
 }
 
+int tpm2_get_capability(u32 capability, u32 property, void *buf,
+			size_t property_count)
+{
+	u8 command_v2[COMMAND_BUFFER_SIZE] = {
+		STRINGIFY16(TPM2_ST_NO_SESSIONS),	/* TAG */
+		STRINGIFY32(22),			/* Command size */
+		STRINGIFY32(TPM2_CC_GET_CAPABILITY),	/* Command code */
+
+		STRINGIFY32(capability),		/* Capability */
+		STRINGIFY32(property),			/* Property */
+		STRINGIFY32(property_count),		/* Property count */
+	};
+	u8 response[COMMAND_BUFFER_SIZE];
+	size_t response_len = COMMAND_BUFFER_SIZE;
+	int ret;
+
+	ret = tpm_sendrecv_command(command_v2, response, &response_len);
+	if (ret)
+		return ret;
+
+	memcpy(buf, &response[19], response_len - 19);
+
+	return 0;
+}
+
+int tpm_get_capability(u32 capability, u32 property, void *buf,
+		       size_t property_count)
+{
+	if (!is_tpmv2)
+		return tpm1_get_capability(capability, property, buf,
+					   property_count);
+	else
+		return tpm2_get_capability(capability, property, buf,
+					   property_count);
+}
+
 uint32_t tpm_get_permanent_flags(struct tpm_permanent_flags *pflags)
 {
 	const uint8_t command[22] = {
-- 
2.14.1



More information about the U-Boot mailing list