Add support for the TPM2_GetCapability command.

Change the command file and the help accordingly.

Signed-off-by: Miquel Raynal <miquel.ray...@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

_______________________________________________
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot

Reply via email to