From patchwork Tue May 15 09:57:20 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Miquel Raynal X-Patchwork-Id: 913553 X-Patchwork-Delegate: trini@ti.com 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 40lYRf3HSqz9s08 for ; Tue, 15 May 2018 20:18:06 +1000 (AEST) Received: by lists.denx.de (Postfix, from userid 105) id 1E988C21EB4; Tue, 15 May 2018 10:08:33 +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_NONE 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 6FCE1C21FCB; Tue, 15 May 2018 09:58:00 +0000 (UTC) Received: by lists.denx.de (Postfix, from userid 105) id 80FD8C21F8E; Tue, 15 May 2018 09:57:47 +0000 (UTC) Received: from mail.bootlin.com (mail.bootlin.com [62.4.15.54]) by lists.denx.de (Postfix) with ESMTP id CFF2AC21EA1 for ; Tue, 15 May 2018 09:57:37 +0000 (UTC) Received: by mail.bootlin.com (Postfix, from userid 110) id 97F68208BC; Tue, 15 May 2018 11:57:36 +0200 (CEST) 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 4ABED20720; Tue, 15 May 2018 11:57:36 +0200 (CEST) From: Miquel Raynal To: Tom Rini , Simon Glass Date: Tue, 15 May 2018 11:57:20 +0200 Message-Id: <20180515095728.16572-25-miquel.raynal@bootlin.com> X-Mailer: git-send-email 2.14.1 In-Reply-To: <20180515095728.16572-1-miquel.raynal@bootlin.com> References: <20180515095728.16572-1-miquel.raynal@bootlin.com> Cc: u-boot@lists.denx.de, Bastian Fraune Subject: [U-Boot] [PATCH v4 24/32] tpm: add PCR authentication commands 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_SetAuthPolicy and TPM2_PCR_SetAuthValue commands. Change the command file and the help accordingly. Note: These commands could not be tested because the TPMs available do not support them, however they could be useful for someone else. The user is warned by the command help. Signed-off-by: Miquel Raynal Reviewed-by: Simon Glass Reviewed-by: Tom Rini --- cmd/tpm-v2.c | 48 ++++++++++++++++++++++++++ include/tpm-v2.h | 29 ++++++++++++++++ lib/tpm-v2.c | 100 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 177 insertions(+) diff --git a/cmd/tpm-v2.c b/cmd/tpm-v2.c index b52409846b..6d7d6cabbd 100644 --- a/cmd/tpm-v2.c +++ b/cmd/tpm-v2.c @@ -264,6 +264,43 @@ static int do_tpm_change_auth(cmd_tbl_t *cmdtp, int flag, int argc, oldpw, oldpw_sz)); } +static int do_tpm_pcr_setauthpolicy(cmd_tbl_t *cmdtp, int flag, int argc, + char * const argv[]) +{ + u32 index = simple_strtoul(argv[1], NULL, 0); + char *key = argv[2]; + const char *pw = (argc < 4) ? NULL : argv[3]; + const ssize_t pw_sz = pw ? strlen(pw) : 0; + + if (strlen(key) != TPM2_DIGEST_LEN) + return -EINVAL; + + if (argc < 3 || argc > 4) + return CMD_RET_USAGE; + + return report_return_code(tpm2_pcr_setauthpolicy(pw, pw_sz, index, + key)); +} + +static int do_tpm_pcr_setauthvalue(cmd_tbl_t *cmdtp, int flag, + int argc, char * const argv[]) +{ + u32 index = simple_strtoul(argv[1], NULL, 0); + char *key = argv[2]; + const ssize_t key_sz = strlen(key); + const char *pw = (argc < 4) ? NULL : argv[3]; + const ssize_t pw_sz = pw ? strlen(pw) : 0; + + if (strlen(key) != TPM2_DIGEST_LEN) + return -EINVAL; + + if (argc < 3 || argc > 4) + return CMD_RET_USAGE; + + return report_return_code(tpm2_pcr_setauthvalue(pw, pw_sz, index, + key, key_sz)); +} + static cmd_tbl_t tpm2_commands[] = { U_BOOT_CMD_MKENT(info, 0, 1, do_tpm_info, "", ""), U_BOOT_CMD_MKENT(init, 0, 1, do_tpm_init, "", ""), @@ -276,6 +313,10 @@ static cmd_tbl_t tpm2_commands[] = { U_BOOT_CMD_MKENT(dam_reset, 0, 1, do_tpm_dam_reset, "", ""), U_BOOT_CMD_MKENT(dam_parameters, 0, 1, do_tpm_dam_parameters, "", ""), U_BOOT_CMD_MKENT(change_auth, 0, 1, do_tpm_change_auth, "", ""), + U_BOOT_CMD_MKENT(pcr_setauthpolicy, 0, 1, + do_tpm_pcr_setauthpolicy, "", ""), + U_BOOT_CMD_MKENT(pcr_setauthvalue, 0, 1, + do_tpm_pcr_setauthvalue, "", ""), }; cmd_tbl_t *get_tpm_commands(unsigned int *size) @@ -338,4 +379,11 @@ U_BOOT_CMD(tpm, CONFIG_SYS_MAXARGS, 1, do_tpm, "Issue a TPMv2.x command", " : the hierarchy\n" " : new password for \n" " : optional previous password of \n" +"pcr_setauthpolicy|pcr_setauthvalue []\n" +" Change the to access PCR #.\n" +" hierarchy and may be empty.\n" +" /!\\WARNING: untested function, use at your own risks !\n" +" : index of the PCR\n" +" : secret to protect the access of PCR #\n" +" : optional password of the PLATFORM hierarchy\n" ); diff --git a/include/tpm-v2.h b/include/tpm-v2.h index 19f0ecd80b..b7820b405d 100644 --- a/include/tpm-v2.h +++ b/include/tpm-v2.h @@ -80,11 +80,13 @@ enum tpm2_command_codes { TPM2_CC_CLEAR = 0x0126, TPM2_CC_CLEARCONTROL = 0x0127, TPM2_CC_HIERCHANGEAUTH = 0x0129, + TPM2_CC_PCR_SETAUTHPOL = 0x012C, TPM2_CC_DAM_RESET = 0x0139, TPM2_CC_DAM_PARAMETERS = 0x013A, TPM2_CC_GET_CAPABILITY = 0x017A, TPM2_CC_PCR_READ = 0x017E, TPM2_CC_PCR_EXTEND = 0x0182, + TPM2_CC_PCR_SETAUTHVAL = 0x0183, }; /** @@ -230,4 +232,31 @@ u32 tpm2_dam_parameters(const char *pw, const ssize_t pw_sz, int tpm2_change_auth(u32 handle, const char *newpw, const ssize_t newpw_sz, const char *oldpw, const ssize_t oldpw_sz); +/** + * Issue a TPM_PCR_SetAuthPolicy command. + * + * @pw Platform password + * @pw_sz Length of the password + * @index Index of the PCR + * @digest New key to access the PCR + * + * @return code of the operation + */ +u32 tpm2_pcr_setauthpolicy(const char *pw, const ssize_t pw_sz, u32 index, + const char *key); + +/** + * Issue a TPM_PCR_SetAuthValue command. + * + * @pw Platform password + * @pw_sz Length of the password + * @index Index of the PCR + * @digest New key to access the PCR + * @key_sz Length of the new key + * + * @return code of the operation + */ +u32 tpm2_pcr_setauthvalue(const char *pw, const ssize_t pw_sz, u32 index, + const char *key, const ssize_t key_sz); + #endif /* __TPM_V2_H */ diff --git a/lib/tpm-v2.c b/lib/tpm-v2.c index 219f0ee941..2c2f4529b4 100644 --- a/lib/tpm-v2.c +++ b/lib/tpm-v2.c @@ -317,3 +317,103 @@ int tpm2_change_auth(u32 handle, const char *newpw, const ssize_t newpw_sz, return tpm_sendrecv_command(command_v2, NULL, NULL); } + +u32 tpm2_pcr_setauthpolicy(const char *pw, const ssize_t pw_sz, u32 index, + const char *key) +{ + u8 command_v2[COMMAND_BUFFER_SIZE] = { + tpm_u16(TPM2_ST_SESSIONS), /* TAG */ + tpm_u32(35 + pw_sz + TPM2_DIGEST_LEN), /* Length */ + tpm_u32(TPM2_CC_PCR_SETAUTHPOL), /* Command code */ + + /* HANDLE */ + tpm_u32(TPM2_RH_PLATFORM), /* TPM resource handle */ + + /* AUTH_SESSION */ + tpm_u32(9 + pw_sz), /* Authorization size */ + tpm_u32(TPM2_RS_PW), /* session handle */ + tpm_u16(0), /* Size of */ + /* (if any) */ + 0, /* Attributes: Cont/Excl/Rst */ + tpm_u16(pw_sz) /* Size of */ + /* STRING(pw) (if any) */ + + /* TPM2B_AUTH (TPM2B_DIGEST) */ + /* tpm_u16(TPM2_DIGEST_LEN) Digest size length */ + /* STRING(key) Digest buffer (PCR key) */ + + /* TPMI_ALG_HASH */ + /* tpm_u16(TPM2_ALG_SHA256) Algorithm of the hash */ + + /* TPMI_DH_PCR */ + /* tpm_u32(index), PCR Index */ + }; + unsigned int offset = 27; + int ret; + + /* + * Fill the command structure starting from the first buffer: + * - the password (if any) + * - the PCR key length + * - the PCR key + * - the hash algorithm + * - the PCR index + */ + ret = pack_byte_string(command_v2, sizeof(command_v2), "swswd", + offset, pw, pw_sz, + offset + pw_sz, TPM2_DIGEST_LEN, + offset + pw_sz + 2, key, TPM2_DIGEST_LEN, + offset + pw_sz + 2 + TPM2_DIGEST_LEN, + TPM2_ALG_SHA256, + offset + pw_sz + 4 + TPM2_DIGEST_LEN, index); + offset += pw_sz + 2 + TPM2_DIGEST_LEN + 2 + 4; + if (ret) + return TPM_LIB_ERROR; + + return tpm_sendrecv_command(command_v2, NULL, NULL); +} + +u32 tpm2_pcr_setauthvalue(const char *pw, const ssize_t pw_sz, u32 index, + const char *key, const ssize_t key_sz) +{ + u8 command_v2[COMMAND_BUFFER_SIZE] = { + tpm_u16(TPM2_ST_SESSIONS), /* TAG */ + tpm_u32(33 + pw_sz + TPM2_DIGEST_LEN), /* Length */ + tpm_u32(TPM2_CC_PCR_SETAUTHVAL), /* Command code */ + + /* HANDLE */ + tpm_u32(index), /* Handle (PCR Index) */ + + /* AUTH_SESSION */ + tpm_u32(9 + pw_sz), /* Authorization size */ + tpm_u32(TPM2_RS_PW), /* session handle */ + tpm_u16(0), /* Size of */ + /* (if any) */ + 0, /* Attributes: Cont/Excl/Rst */ + tpm_u16(pw_sz), /* Size of */ + /* STRING(pw) (if any) */ + + /* TPM2B_DIGEST */ + /* tpm_u16(key_sz) Key length */ + /* STRING(key) Key */ + }; + unsigned int offset = 27; + int ret; + + /* + * Fill the command structure starting from the first buffer: + * - the password (if any) + * - the number of digests, 1 in our case + * - the algorithm, sha256 in our case + * - the digest (64 bytes) + */ + ret = pack_byte_string(command_v2, sizeof(command_v2), "sws", + offset, pw, pw_sz, + offset + pw_sz, key_sz, + offset + pw_sz + 2, key, key_sz); + offset += pw_sz + 2 + key_sz; + if (ret) + return TPM_LIB_ERROR; + + return tpm_sendrecv_command(command_v2, NULL, NULL); +}