Add support for the TPM2_PCR_Extend command.

Change the command file and the help accordingly.

Signed-off-by: Miquel Raynal <miquel.ray...@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 46250a86cf..0cde8695b9 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] = {
+               U16_TO_ARRAY(TPM2_ST_SESSIONS), /* TAG */
+               U32_TO_ARRAY(33 + TPM2_DIGEST_LENGTH), /* Length */
+               U32_TO_ARRAY(TPM2_CC_PCR_EXTEND), /* Command code */
+
+               /* HANDLE */
+               U32_TO_ARRAY(index),            /* Handle (PCR Index) */
+
+               /* AUTH_SESSION */
+               U32_TO_ARRAY(9),                /* Authorization size */
+               U32_TO_ARRAY(TPM2_RS_PW),       /* Session handle */
+               U16_TO_ARRAY(0),                /* Size of <nonce> */
+                                               /* <nonce> (if any) */
+               0,                              /* Attributes: Cont/Excl/Rst */
+               U16_TO_ARRAY(0),                /* Size of <hmac/password> */
+                                               /* <hmac/password> (if any) */
+               U32_TO_ARRAY(1),                /* Count (number of hashes) */
+               U16_TO_ARRAY(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

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

Reply via email to