From patchwork Thu Mar 8 15:40:17 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Miquel Raynal X-Patchwork-Id: 883200 X-Patchwork-Delegate: sjg@chromium.org Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=lists.denx.de (client-ip=81.169.180.215; helo=lists.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=bootlin.com Received: from lists.denx.de (dione.denx.de [81.169.180.215]) by ozlabs.org (Postfix) with ESMTP id 3zxw154lmVz9shc for ; Fri, 9 Mar 2018 02:49:13 +1100 (AEDT) Received: by lists.denx.de (Postfix, from userid 105) id 3FDF1C21F68; Thu, 8 Mar 2018 15:44:45 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on lists.denx.de X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=RCVD_IN_DNSWL_BLOCKED autolearn=unavailable autolearn_force=no version=3.4.0 Received: from lists.denx.de (localhost [IPv6:::1]) by lists.denx.de (Postfix) with ESMTP id 60294C21F68; Thu, 8 Mar 2018 15:41:09 +0000 (UTC) Received: by lists.denx.de (Postfix, from userid 105) id 512C1C21EC9; Thu, 8 Mar 2018 15:40:56 +0000 (UTC) Received: from mail.bootlin.com (mail.bootlin.com [62.4.15.54]) by lists.denx.de (Postfix) with ESMTP id 5FB7CC21FD1 for ; Thu, 8 Mar 2018 15:40:49 +0000 (UTC) Received: by mail.bootlin.com (Postfix, from userid 110) id BFA5F207DA; Thu, 8 Mar 2018 16:40:47 +0100 (CET) Received: from localhost.localdomain (LStLambert-657-1-97-87.w90-63.abo.wanadoo.fr [90.63.216.87]) by mail.bootlin.com (Postfix) with ESMTPSA id B042520879; Thu, 8 Mar 2018 16:40:28 +0100 (CET) From: Miquel Raynal To: u-boot@lists.denx.de Date: Thu, 8 Mar 2018 16:40:17 +0100 Message-Id: <20180308154021.25255-15-miquel.raynal@bootlin.com> X-Mailer: git-send-email 2.14.1 In-Reply-To: <20180308154021.25255-1-miquel.raynal@bootlin.com> References: <20180308154021.25255-1-miquel.raynal@bootlin.com> Subject: [U-Boot] [PATCH 14/18] tpm: add TPM2_PCR_Read command support X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.18 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" Add support for the TPM2_PCR_Read command. Change the command file and the help accordingly. Signed-off-by: Miquel Raynal --- 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 with\n" " . 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 \n" -" pcr_read index addr count\n" -" - Read bytes from PCR to memory address .\n" " pcr_extend index \n" " - Add a new measurement to a PCR. Update PCR with\n" " . It must be a 20 byte digest for TPMv1 or a SHA256\n" " digest of 32 bytes for TPMv2.\n" +" pcr_read \n" +" - Read PCR to memory address (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] = {