From patchwork Wed May 2 08:59:24 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Miquel Raynal X-Patchwork-Id: 907399 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 40bXTz0TNgz9s21 for ; Wed, 2 May 2018 19:07:18 +1000 (AEST) Received: by lists.denx.de (Postfix, from userid 105) id B2C68C21C2F; Wed, 2 May 2018 09:02: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_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 7B99FC21E08; Wed, 2 May 2018 08:59:52 +0000 (UTC) Received: by lists.denx.de (Postfix, from userid 105) id 549AEC21D8A; Wed, 2 May 2018 08:59:39 +0000 (UTC) Received: from mail.bootlin.com (mail.bootlin.com [62.4.15.54]) by lists.denx.de (Postfix) with ESMTP id 7AF65C21D8E for ; Wed, 2 May 2018 08:59:39 +0000 (UTC) Received: by mail.bootlin.com (Postfix, from userid 110) id 8B75520A2C; Wed, 2 May 2018 10:59:38 +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 52A3B20A21; Wed, 2 May 2018 10:59:38 +0200 (CEST) From: Miquel Raynal To: Tom Rini , Simon Glass Date: Wed, 2 May 2018 10:59:24 +0200 Message-Id: <20180502085934.29292-16-miquel.raynal@bootlin.com> X-Mailer: git-send-email 2.14.1 In-Reply-To: <20180502085934.29292-1-miquel.raynal@bootlin.com> References: <20180502085934.29292-1-miquel.raynal@bootlin.com> Cc: u-boot@lists.denx.de, Bastian Fraune Subject: [U-Boot] [PATCH v3 15/25] tpm: add TPM2_HierarchyChangeAuth 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_HierarchyChangeAuth command. Change the command file and the help accordingly. Signed-off-by: Miquel Raynal Reviewed-by: Simon Glass --- cmd/tpm-v2.c | 59 ++++++++++++++++++++++++++++++++++++++++++++------------ include/tpm-v2.h | 14 ++++++++++++++ lib/tpm-v2.c | 44 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 105 insertions(+), 12 deletions(-) diff --git a/cmd/tpm-v2.c b/cmd/tpm-v2.c index 48fb883e01..6e338b7f0c 100644 --- a/cmd/tpm-v2.c +++ b/cmd/tpm-v2.c @@ -194,6 +194,36 @@ static int do_tpm_dam_parameters(cmd_tbl_t *cmdtp, int flag, int argc, lockout_recovery)); } +static int do_tpm_change_auth(cmd_tbl_t *cmdtp, int flag, int argc, + char *const argv[]) +{ + u32 handle; + const char *newpw = argv[2]; + const char *oldpw = (argc == 3) ? NULL : argv[3]; + const ssize_t newpw_sz = strlen(newpw); + const ssize_t oldpw_sz = oldpw ? strlen(oldpw) : 0; + + if (argc < 3 || argc > 4) + return CMD_RET_USAGE; + + if (newpw_sz > TPM2_DIGEST_LEN || oldpw_sz > TPM2_DIGEST_LEN) + return -EINVAL; + + if (!strcasecmp("TPM2_RH_LOCKOUT", argv[1])) + handle = TPM2_RH_LOCKOUT; + else if (!strcasecmp("TPM2_RH_ENDORSEMENT", argv[1])) + handle = TPM2_RH_ENDORSEMENT; + else if (!strcasecmp("TPM2_RH_OWNER", argv[1])) + handle = TPM2_RH_OWNER; + else if (!strcasecmp("TPM2_RH_PLATFORM", argv[1])) + handle = TPM2_RH_PLATFORM; + else + return CMD_RET_USAGE; + + return report_return_code(tpm2_change_auth(handle, newpw, newpw_sz, + oldpw, oldpw_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, "", ""), @@ -205,6 +235,7 @@ static cmd_tbl_t tpm2_commands[] = { U_BOOT_CMD_MKENT(get_capability, 0, 1, do_tpm_get_capability, "", ""), 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, "", ""), }; cmd_tbl_t *get_tpm_commands(unsigned int *size) @@ -251,16 +282,20 @@ U_BOOT_CMD(tpm, CONFIG_SYS_MAXARGS, 1, do_tpm, "Issue a TPMv2.x command", " : property\n" " : address to store entries of 4 bytes\n" " : number of entries to retrieve\n" -" dam_reset_counter []\n" -" - If the TPM is not in a LOCKOUT state, reset the internal error\n" -" counter (TPMv2 only)\n" -" dam_set_parameters []\n" -" - If the TPM is not in a LOCKOUT state, set the dictionary attack\n" -" parameters:\n" -" * maxTries: maximum number of failures before lockout.\n" -" 0 means always locking.\n" -" * recoveryTime: time before decrementation of the error counter,\n" -" 0 means no lockout.\n" -" * lockoutRecovery: time of a lockout (before the next try)\n" -" 0 means a reboot is needed.\n" +"dam_reset []\n" +" If the TPM is not in a LOCKOUT state, reset the internal error counter.\n" +" : optional password\n" +"dam_parameters []\n" +" If the TPM is not in a LOCKOUT state, set the DAM parameters\n" +" : maximum number of failures before lockout,\n" +" 0 means always locking\n" +" : time before decrement of the error counter,\n" +" 0 means no lockout\n" +" : time of a lockout (before the next try),\n" +" 0 means a reboot is needed\n" +" : optional password of the LOCKOUT hierarchy\n" +"change_auth []\n" +" : the hierarchy\n" +" : new password for \n" +" : optional previous password of \n" ); diff --git a/include/tpm-v2.h b/include/tpm-v2.h index ee97cf28e4..a632ebdbeb 100644 --- a/include/tpm-v2.h +++ b/include/tpm-v2.h @@ -215,4 +215,18 @@ u32 tpm2_dam_parameters(const char *pw, const ssize_t pw_sz, unsigned int max_tries, unsigned int recovery_time, unsigned int lockout_recovery); +/** + * Issue a TPM2_HierarchyChangeAuth command. + * + * @param handle Handle + * @param newpw New password + * @param newpw_sz Length of the new password + * @param oldpw Old password + * @param oldpw_sz Length of the old password + * + * @return return code of the operation + */ +int tpm2_change_auth(u32 handle, const char *newpw, const ssize_t newpw_sz, + const char *oldpw, const ssize_t oldpw_sz); + #endif /* __TPM_V2_H */ diff --git a/lib/tpm-v2.c b/lib/tpm-v2.c index 0e279fe606..d2bc6e4e51 100644 --- a/lib/tpm-v2.c +++ b/lib/tpm-v2.c @@ -266,3 +266,47 @@ u32 tpm2_dam_parameters(const char *pw, const ssize_t pw_sz, return tpm_sendrecv_command(command_v2, NULL, NULL); } + +int tpm2_change_auth(u32 handle, const char *newpw, const ssize_t newpw_sz, + const char *oldpw, const ssize_t oldpw_sz) +{ + unsigned int offset = 27; + u8 command_v2[COMMAND_BUFFER_SIZE] = { + tpm_u16(TPM2_ST_SESSIONS), /* TAG */ + tpm_u32(offset + oldpw_sz + 2 + newpw_sz), /* Length */ + tpm_u32(TPM2_CC_HIERCHANGEAUTH), /* Command code */ + + /* HANDLE */ + tpm_u32(handle), /* TPM resource handle */ + + /* AUTH_SESSION */ + tpm_u32(9 + oldpw_sz), /* Authorization size */ + tpm_u32(TPM2_RS_PW), /* Session handle */ + tpm_u16(0), /* Size of */ + /* (if any) */ + 0, /* Attributes: Cont/Excl/Rst */ + tpm_u16(oldpw_sz) /* Size of */ + /* STRING(oldpw) (if any) */ + + /* TPM2B_AUTH (TPM2B_DIGEST) */ + /* tpm_u16(newpw_sz) Digest size, new pw length */ + /* STRING(newpw) Digest buffer, new pw */ + }; + int ret; + + /* + * Fill the command structure starting from the first buffer: + * - the old password (if any) + * - size of the new password + * - new password + */ + ret = pack_byte_string(command_v2, sizeof(command_v2), "sws", + offset, oldpw, oldpw_sz, + offset + oldpw_sz, newpw_sz, + offset + oldpw_sz + 2, newpw, newpw_sz); + offset += oldpw_sz + 2 + newpw_sz; + if (ret) + return TPM_LIB_ERROR; + + return tpm_sendrecv_command(command_v2, NULL, NULL); +}