Received: by 2002:a05:6a10:8c0a:0:0:0:0 with SMTP id go10csp917653pxb; Wed, 3 Mar 2021 21:00:23 -0800 (PST) X-Google-Smtp-Source: ABdhPJzYPkvnQPejigPv4mcoThMl6bvCE+8CCtFm3EgolS1kcL6tc7/TR94aRncGvgRQFTW6PunB X-Received: by 2002:aa7:c5c4:: with SMTP id h4mr2301915eds.375.1614834022926; Wed, 03 Mar 2021 21:00:22 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1614834022; cv=none; d=google.com; s=arc-20160816; b=ry12XZsF/JHhqnO/qeZ6enf5i8oSA4BPyNF+7519KtIV93jWLC3Ls2Gt4bcDxvaumh fTFha4n5iqR8JIMwmkZHNl7nlzgus5u6Me6RIDBMM4wF61kVr3yVQNzpc+bojNCio9sz AhfQYMC9oLUXgnxLR6HLhL9Fj8BB+/6zq6CDdnPsYgF+5WqWALgc/CBQQsEDK9MXV2dr PUnAKstWhqLIwkb4jcgyJOM8++prTheADMZ5N5fcuWouT7wJuxpjR1CbG2W1o5oHDor2 9etNQXmFC9RBL9HcjZ3Sm+yqCYxCAbgGBICxGFXEy0FIznrC93LkPIAYUmZB2iaed8St XmGg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :user-agent:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=CZ6n/y46cTcQoxKCENKaylbHHYJRDgOQ+wOLDYRnMaw=; b=ENkjADNj1TQ9mm6n5WXsmdkH0ZuWzTJlYiv1+u+VNo5xLFN68fiaiGxorme+xdltdO id3YSu5OkathY+vbEO2O3JsOOehxOFg+lxIFvEYeKift3YJQ60SI2YXum7GYjB0RidbH Jn7/E6pLiwnfJdqDPco08d1RX/1UcY6RK1+FNVR+Q/TFItd+7PYJt6/HCp8h2mIDBmtC BhJuwQ1QUpJnWcnQB9+AaGSXEPtMIsIy0Vr5SxletAW8HiwB81kq3tVy7CffhYo9wZ7Y H/uu87WgLeI2YFpq3qT1FXqNA4U7Lx6374bM15fOzGwzbN3YyRv+SPZ+X11ZLdIs0awS lYug== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b=WinYKxzR; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linuxfoundation.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id p8si18038401edj.93.2021.03.03.20.59.57; Wed, 03 Mar 2021 21:00:22 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b=WinYKxzR; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linuxfoundation.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S242262AbhCBCeb (ORCPT + 99 others); Mon, 1 Mar 2021 21:34:31 -0500 Received: from mail.kernel.org ([198.145.29.99]:55164 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S241808AbhCATrF (ORCPT ); Mon, 1 Mar 2021 14:47:05 -0500 Received: by mail.kernel.org (Postfix) with ESMTPSA id 1BF8264EE2; Mon, 1 Mar 2021 17:28:49 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=linuxfoundation.org; s=korg; t=1614619730; bh=gIrkr9f+g407ocE3V1plKh5srxdKOJERSnGXU0ad9DU=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=WinYKxzRkpF1jshWX/1xnePkxyRGDsWVkesEWLJLzHtLQ7zQ2gGPXezjcFvel2jRa 1QDQNaijzZS3ZAB3nVf2+v26Clp5Ve8WP6eDvRJkd6ES6uDyjPUFURvJY1PvNVkgAW 9hIbsMsqDJepP0rJaTasHONXUR22M0Rm03H8tla8= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, "James E.J. Bottomley" , David Howells , Mimi Zohar , Sumit Garg , Jarkko Sakkinen Subject: [PATCH 5.10 530/663] KEYS: trusted: Reserve TPM for seal and unseal operations Date: Mon, 1 Mar 2021 17:12:58 +0100 Message-Id: <20210301161208.070553311@linuxfoundation.org> X-Mailer: git-send-email 2.30.1 In-Reply-To: <20210301161141.760350206@linuxfoundation.org> References: <20210301161141.760350206@linuxfoundation.org> User-Agent: quilt/0.66 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Jarkko Sakkinen commit 8c657a0590de585b1115847c17b34a58025f2f4b upstream. When TPM 2.0 trusted keys code was moved to the trusted keys subsystem, the operations were unwrapped from tpm_try_get_ops() and tpm_put_ops(), which are used to take temporarily the ownership of the TPM chip. The ownership is only taken inside tpm_send(), but this is not sufficient, as in the key load TPM2_CC_LOAD, TPM2_CC_UNSEAL and TPM2_FLUSH_CONTEXT need to be done as a one single atom. Take the TPM chip ownership before sending anything with tpm_try_get_ops() and tpm_put_ops(), and use tpm_transmit_cmd() to send TPM commands instead of tpm_send(), reverting back to the old behaviour. Fixes: 2e19e10131a0 ("KEYS: trusted: Move TPM2 trusted keys code") Reported-by: "James E.J. Bottomley" Cc: stable@vger.kernel.org Cc: David Howells Cc: Mimi Zohar Cc: Sumit Garg Acked-by Sumit Garg Tested-by: Mimi Zohar Signed-off-by: Jarkko Sakkinen Signed-off-by: Greg Kroah-Hartman --- drivers/char/tpm/tpm.h | 4 ---- include/linux/tpm.h | 5 ++++- security/keys/trusted-keys/trusted_tpm2.c | 22 ++++++++++++++++++---- 3 files changed, 22 insertions(+), 9 deletions(-) --- a/drivers/char/tpm/tpm.h +++ b/drivers/char/tpm/tpm.h @@ -164,8 +164,6 @@ extern const struct file_operations tpmr extern struct idr dev_nums_idr; ssize_t tpm_transmit(struct tpm_chip *chip, u8 *buf, size_t bufsiz); -ssize_t tpm_transmit_cmd(struct tpm_chip *chip, struct tpm_buf *buf, - size_t min_rsp_body_length, const char *desc); int tpm_get_timeouts(struct tpm_chip *); int tpm_auto_startup(struct tpm_chip *chip); @@ -194,8 +192,6 @@ static inline void tpm_msleep(unsigned i int tpm_chip_start(struct tpm_chip *chip); void tpm_chip_stop(struct tpm_chip *chip); struct tpm_chip *tpm_find_get_ops(struct tpm_chip *chip); -__must_check int tpm_try_get_ops(struct tpm_chip *chip); -void tpm_put_ops(struct tpm_chip *chip); struct tpm_chip *tpm_chip_alloc(struct device *dev, const struct tpm_class_ops *ops); --- a/include/linux/tpm.h +++ b/include/linux/tpm.h @@ -397,6 +397,10 @@ static inline u32 tpm2_rc_value(u32 rc) #if defined(CONFIG_TCG_TPM) || defined(CONFIG_TCG_TPM_MODULE) extern int tpm_is_tpm2(struct tpm_chip *chip); +extern __must_check int tpm_try_get_ops(struct tpm_chip *chip); +extern void tpm_put_ops(struct tpm_chip *chip); +extern ssize_t tpm_transmit_cmd(struct tpm_chip *chip, struct tpm_buf *buf, + size_t min_rsp_body_length, const char *desc); extern int tpm_pcr_read(struct tpm_chip *chip, u32 pcr_idx, struct tpm_digest *digest); extern int tpm_pcr_extend(struct tpm_chip *chip, u32 pcr_idx, @@ -410,7 +414,6 @@ static inline int tpm_is_tpm2(struct tpm { return -ENODEV; } - static inline int tpm_pcr_read(struct tpm_chip *chip, int pcr_idx, struct tpm_digest *digest) { --- a/security/keys/trusted-keys/trusted_tpm2.c +++ b/security/keys/trusted-keys/trusted_tpm2.c @@ -83,6 +83,12 @@ int tpm2_seal_trusted(struct tpm_chip *c if (rc) return rc; + rc = tpm_buf_init(&buf, TPM2_ST_SESSIONS, TPM2_CC_CREATE); + if (rc) { + tpm_put_ops(chip); + return rc; + } + tpm_buf_append_u32(&buf, options->keyhandle); tpm2_buf_append_auth(&buf, TPM2_RS_PW, NULL /* nonce */, 0, @@ -130,7 +136,7 @@ int tpm2_seal_trusted(struct tpm_chip *c goto out; } - rc = tpm_send(chip, buf.data, tpm_buf_length(&buf)); + rc = tpm_transmit_cmd(chip, &buf, 4, "sealing data"); if (rc) goto out; @@ -157,6 +163,7 @@ out: rc = -EPERM; } + tpm_put_ops(chip); return rc; } @@ -211,7 +218,7 @@ static int tpm2_load_cmd(struct tpm_chip goto out; } - rc = tpm_send(chip, buf.data, tpm_buf_length(&buf)); + rc = tpm_transmit_cmd(chip, &buf, 4, "loading blob"); if (!rc) *blob_handle = be32_to_cpup( (__be32 *) &buf.data[TPM_HEADER_SIZE]); @@ -260,7 +267,7 @@ static int tpm2_unseal_cmd(struct tpm_ch options->blobauth /* hmac */, TPM_DIGEST_SIZE); - rc = tpm_send(chip, buf.data, tpm_buf_length(&buf)); + rc = tpm_transmit_cmd(chip, &buf, 6, "unsealing"); if (rc > 0) rc = -EPERM; @@ -304,12 +311,19 @@ int tpm2_unseal_trusted(struct tpm_chip u32 blob_handle; int rc; - rc = tpm2_load_cmd(chip, payload, options, &blob_handle); + rc = tpm_try_get_ops(chip); if (rc) return rc; + rc = tpm2_load_cmd(chip, payload, options, &blob_handle); + if (rc) + goto out; + rc = tpm2_unseal_cmd(chip, payload, options, blob_handle); tpm2_flush_context(chip, blob_handle); +out: + tpm_put_ops(chip); + return rc; }