Add support for the TPM2_PCR_Read command. Change the command file and the help accordingly.
Signed-off-by: Miquel Raynal <miquel.ray...@bootlin.com> --- cmd/tpm.c | 23 ++++++++++++++--------- include/tpm.h | 4 ++-- lib/tpm.c | 56 +++++++++++++++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 71 insertions(+), 12 deletions(-) diff --git a/cmd/tpm.c b/cmd/tpm.c index 3f284f0adf..8630571b1a 100644 --- a/cmd/tpm.c +++ b/cmd/tpm.c @@ -362,21 +362,25 @@ static int do_tpm_pcr_extend(cmd_tbl_t *cmdtp, int flag, } static int do_tpm_pcr_read(cmd_tbl_t *cmdtp, int flag, - int argc, char * const argv[]) + int argc, char * const argv[]) { - uint32_t index, count, rc; + bool is_tpmv2 = (tpm_get_specification() == 2); + u32 index, rc; + unsigned int updates; void *data; - if (argc != 4) + if (argc != 3) return CMD_RET_USAGE; + index = simple_strtoul(argv[1], NULL, 0); data = (void *)simple_strtoul(argv[2], NULL, 0); - count = simple_strtoul(argv[3], NULL, 0); - rc = tpm_pcr_read(index, data, count); + rc = tpm_pcr_read(index, data, &updates); if (!rc) { - puts("Named PCR content:\n"); - print_byte_string(data, count); + printf("Named PCR %u content (known updates: %d):\n", index, + is_tpmv2 ? updates : -1); + print_byte_string(data, !is_tpmv2 ? TPM1_DIGEST_LENGTH : + TPM2_DIGEST_LENGTH); } return report_return_code(rc); @@ -1038,12 +1042,13 @@ U_BOOT_CMD(tpm, CONFIG_SYS_MAXARGS, 1, do_tpm, " - 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. 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" +" pcr_read <index> <digest_in>\n" +" - Read PCR <index> to memory address <digest_in> (20B with TPMv1, 64B with\n" +" TPMv2).\n" #ifdef CONFIG_TPM_AUTH_SESSIONS "Authorization Sessions\n" " oiap\n" diff --git a/include/tpm.h b/include/tpm.h index b88ad4b2f4..2df2ea3c5b 100644 --- a/include/tpm.h +++ b/include/tpm.h @@ -571,10 +571,10 @@ int tpm2_pcr_extend(u32 index, const uint8_t *digest); * * @param index index of the PCR * @param data output buffer for contents of the named PCR - * @param count size of output buffer + * @param updates optional out parameter: number of updates for this PCR * @return return code of the operation */ -uint32_t tpm_pcr_read(uint32_t index, void *data, size_t count); +int tpm_pcr_read(u32 index, void *data, unsigned int *updates); /** * Issue a TSC_PhysicalPresence command. TPM physical presence flag diff --git a/lib/tpm.c b/lib/tpm.c index e74530d538..925b21e2d6 100644 --- a/lib/tpm.c +++ b/lib/tpm.c @@ -568,7 +568,7 @@ int tpm2_pcr_extend(u32 index, const uint8_t *digest) return tpm_sendrecv_command(command_v2, NULL, NULL); } -uint32_t tpm_pcr_read(uint32_t index, void *data, size_t count) +int tpm1_pcr_read(u32 index, void *data) { const uint8_t command[14] = { 0x0, 0xc1, 0x0, 0x0, 0x0, 0xe, 0x0, 0x0, 0x0, 0x15, @@ -596,6 +596,60 @@ uint32_t tpm_pcr_read(uint32_t index, void *data, size_t count) return 0; } +int tpm2_pcr_read(u32 index, void *data, unsigned int *updates) +{ + u8 command_v2[COMMAND_BUFFER_SIZE] = { + STRINGIFY16(TPM2_ST_NO_SESSIONS), /* TAG */ + STRINGIFY32(20), /* Command size */ + STRINGIFY32(TPM2_CC_PCR_READ), /* Command code */ + + /* TPML_PCR_SELECTION */ + STRINGIFY32(1), /* Number of selections */ + STRINGIFY16(TPM2_ALG_SHA256), /* Algorithm of the hash */ + 3, /* Array size for selection */ + /* STRINGIFY32(bitmap(index) << 8) Selected PCR bitmap */ + }; + size_t response_len = COMMAND_BUFFER_SIZE; + u8 response[COMMAND_BUFFER_SIZE]; + unsigned int counter = 0; + u8 pcr_sel[3] = {}; + int ret; + + if (!is_tpmv2) + return TPM_LIB_ERROR; + + if (index >= 24) + return TPM_LIB_ERROR; + + pcr_sel[index / 8] = BIT(index % 8); + if (pack_byte_string(command_v2, COMMAND_BUFFER_SIZE, "bbb", + 17, pcr_sel[0], 18, pcr_sel[1], 19, pcr_sel[2])) + return TPM_LIB_ERROR; + + ret = tpm_sendrecv_command(command_v2, response, &response_len); + if (ret) + return ret; + + if (unpack_byte_string(response, response_len, "ds", + 10, &counter, + response_len - TPM2_DIGEST_LENGTH, data, + TPM2_DIGEST_LENGTH)) + return TPM_LIB_ERROR; + + if (updates) + *updates = counter; + + return 0; +} + +int tpm_pcr_read(u32 index, void *data, unsigned int *updates) +{ + if (!is_tpmv2) + return tpm1_pcr_read(index, data); + else + return tpm2_pcr_read(index, data, updates); +} + uint32_t tpm_tsc_physical_presence(uint16_t presence) { const uint8_t command[12] = { -- 2.14.1 _______________________________________________ U-Boot mailing list U-Boot@lists.denx.de https://lists.denx.de/listinfo/u-boot