From patchwork Tue Oct 15 20:58:36 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jarkko Sakkinen X-Patchwork-Id: 13837070 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 3404C1F80DD; Tue, 15 Oct 2024 20:58:53 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1729025934; cv=none; b=VCe1A3k2VX1y/5F7o0JQsRYvYQXBfsm0vKd//kijbo4JK/qkLexmawS3hlDnlRNHANECR8UJKTQYs6Oj/r748IYlYDSQIqQy9a1W32by/d/0DD2e7m55FiQnrVncdXCjjjWp0nvNznoIwkFbELMknUjb+5qECmt0XM5Zupuz8HQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1729025934; c=relaxed/simple; bh=OdfbPphNVRToS+4L7iWif22RAzWjckEAkN41WHeGg50=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=UKd0c3k/AbpxwMXw9Gg6SDFDfFgX2c/jmrBDIlplu1MSZSa7wIX1FiwPzPEr9EBp58se3xRA7NiEz1V15X8WE4mdPsyRN9pfITxdOQ5Po3hN9xkJ8AYc0082X5GwvTcZxU5pCkffYSAuAKsmfCHDjJGcXIMN/YZc8OXp1/vZSYo= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=rpSk/pWW; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="rpSk/pWW" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 38F55C4CEC6; Tue, 15 Oct 2024 20:58:53 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1729025933; bh=OdfbPphNVRToS+4L7iWif22RAzWjckEAkN41WHeGg50=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=rpSk/pWW0GDNpTpxzpLph+2NXw9KHKsaY1unOGf+3SFCoq6Rw9rgx5etGj1h0uTy0 WT6jIOY5wwV0r+3J5hOa3DEVhvgYKT8IfmBIsKJwcmMDZYtjLt1c8Jef6lzrX0Glvl vHrUlHvyv8R9kjvD0ZvueV8oa+MvmB8aYbf4zn1g5sdgL/D56ASk87LZ8ER+v6aXvF dAXsMOpjEZYDvEDMm0Jyu3z4Ep7PialQRyNtbkdKRKVV54MBWFdnVjIbNByibA52f+ zfspTtTa5B+nNNw/BTcWKvb8ZS/t1hEpNHGslTgDVmHwCqqyDZbCMBCIHIVVwektxS gX35w2B2jxpag== From: Jarkko Sakkinen To: Peter Huewe , Jarkko Sakkinen , Jason Gunthorpe , James Bottomley Cc: Stefan Berger , stable@vger.kernel.org, linux-integrity@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v6 1/5] tpm: Return on tpm2_create_null_primary() failure Date: Tue, 15 Oct 2024 23:58:36 +0300 Message-ID: <20241015205842.117300-2-jarkko@kernel.org> X-Mailer: git-send-email 2.47.0 In-Reply-To: <20241015205842.117300-1-jarkko@kernel.org> References: <20241015205842.117300-1-jarkko@kernel.org> Precedence: bulk X-Mailing-List: linux-integrity@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 tpm2_sessions_init() does not ignore the result of tpm2_create_null_primary(). Address this by returning -ENODEV to the caller. Given that upper layers cannot help healing the situation further, deal with the TPM error here by Cc: stable@vger.kernel.org # v6.10+ Fixes: d2add27cf2b8 ("tpm: Add NULL primary creation") Signed-off-by: Jarkko Sakkinen --- v6: - Address: https://lore.kernel.org/linux-integrity/69c893e7-6b87-4daa-80db-44d1120e80fe@linux.ibm.com/ as TPM RC is taken care of at the call site. Add also the missing documentation for the return values. v5: - Do not print klog messages on error, as tpm2_save_context() already takes care of this. v4: - Fixed up stable version. v3: - Handle TPM and POSIX error separately and return -ENODEV always back to the caller. v2: - Refined the commit message. --- drivers/char/tpm/tpm2-sessions.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/char/tpm/tpm2-sessions.c b/drivers/char/tpm/tpm2-sessions.c index 511c67061728..253639767c1e 100644 --- a/drivers/char/tpm/tpm2-sessions.c +++ b/drivers/char/tpm/tpm2-sessions.c @@ -1347,6 +1347,11 @@ static int tpm2_create_null_primary(struct tpm_chip *chip) * * Derive and context save the null primary and allocate memory in the * struct tpm_chip for the authorizations. + * + * Return: + * * 0 - OK + * * -errno - A system error + * * TPM_RC - A TPM error */ int tpm2_sessions_init(struct tpm_chip *chip) { @@ -1354,7 +1359,7 @@ int tpm2_sessions_init(struct tpm_chip *chip) rc = tpm2_create_null_primary(chip); if (rc) - dev_err(&chip->dev, "TPM: security failed (NULL seed derivation): %d\n", rc); + return rc; chip->auth = kmalloc(sizeof(*chip->auth), GFP_KERNEL); if (!chip->auth) From patchwork Tue Oct 15 20:58:37 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jarkko Sakkinen X-Patchwork-Id: 13837071 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 3C5BA1F80DD; Tue, 15 Oct 2024 20:58:58 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1729025939; cv=none; b=L5N0iW0waY+LR3rlpdN5QfxOpxNq+RGyffdOhXJp1G3CwLrRh/ms62yIxnDodr84OPSp30I7hZruUsIpjmDCM1E0ApNQFcSDDAy8GdQQ5Wthn/4obKg3r7bvc0s9nWUthV07xX1dZV7/zZRyLcd4eZG3kGYDtReEc5/xl7ag3+4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1729025939; c=relaxed/simple; bh=eldE9A77XPppw7dIFi4hvn84XWAs9Hpi5aCEiES7OhI=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=IEMMhqAqEht+guIKAnhpdnNqkHIxVq/Uq32EHDLV17msL8UZ3CD3hVmmtg4T8gTkhkOuSwH+BpZeZiLf3uQTMS9qtO29CTDNunR6zFwX7r7f7iZPxEEUhxLy8dVMdHsv2t8o8Z/qUd8ao/rQ/RIcH0CrG40U6zRBoFdJ5TF3bBk= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=EN3RLaGF; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="EN3RLaGF" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 556D6C4CEC7; Tue, 15 Oct 2024 20:58:58 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1729025938; bh=eldE9A77XPppw7dIFi4hvn84XWAs9Hpi5aCEiES7OhI=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=EN3RLaGFxAnYU1k4ESJFMyO2pvuRBGG4Qr0VJafZRQJKS8ueEvBfjwFPv4C8KR3M5 JQzI3JrfsMNKXCoAtujbpKHp25HQaNV+zHzuhd0Bnf+Ofq5E+lv/4owPC1EtDwVU7l W8sEiB9pt/HCXPNMDqK14mx0iRVHkYW4hoixBFUHePH0fHzmfzy+9eyNLJFBwmIeV9 2QYHC7zrLWKaqKAgW3iuXbvkfHEoAXtX1r+QEjhyF4remjPrcbJN03wEQrM2SzWxde chW1sguAH9eqcxaoniqcnBnFVUK4goFTfYH32IIf7D+siKpVjmlDVXAHoMyfch/dmD 1gf5F7ksU/Q/Q== From: Jarkko Sakkinen To: Peter Huewe , Jarkko Sakkinen , Jason Gunthorpe , James Bottomley Cc: Stefan Berger , stable@vger.kernel.org, linux-integrity@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v6 2/5] tpm: Implement tpm2_load_null() rollback Date: Tue, 15 Oct 2024 23:58:37 +0300 Message-ID: <20241015205842.117300-3-jarkko@kernel.org> X-Mailer: git-send-email 2.47.0 In-Reply-To: <20241015205842.117300-1-jarkko@kernel.org> References: <20241015205842.117300-1-jarkko@kernel.org> Precedence: bulk X-Mailing-List: linux-integrity@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 tpm2_load_null() has weak and broken error handling: - The return value of tpm2_create_primary() is ignored. - Leaks TPM return codes from tpm2_load_context() to the caller. - If the key name comparison succeeds returns previous error instead of zero to the caller. Implement a proper error rollback. Cc: stable@vger.kernel.org # v6.10+ Fixes: eb24c9788cd9 ("tpm: disable the TPM if NULL name changes") Signed-off-by: Jarkko Sakkinen --- v6: - Address Stefan's remark: https://lore.kernel.org/linux-integrity/def4ec2d-584b-405f-9d5e-99267013c3c0@linux.ibm.com/ v5: - Fix the TPM error code leak from tpm2_load_context(). v4: - No changes. v3: - Update log messages. Previously the log message incorrectly stated on load failure that integrity check had been failed, even tho the check is done *after* the load operation. v2: - Refined the commit message. - Reverted tpm2_create_primary() changes. They are not required if tmp_null_key is used as the parameter. --- drivers/char/tpm/tpm2-sessions.c | 43 +++++++++++++++++--------------- 1 file changed, 23 insertions(+), 20 deletions(-) diff --git a/drivers/char/tpm/tpm2-sessions.c b/drivers/char/tpm/tpm2-sessions.c index 253639767c1e..1215c53f0ae7 100644 --- a/drivers/char/tpm/tpm2-sessions.c +++ b/drivers/char/tpm/tpm2-sessions.c @@ -915,33 +915,36 @@ static int tpm2_parse_start_auth_session(struct tpm2_auth *auth, static int tpm2_load_null(struct tpm_chip *chip, u32 *null_key) { - int rc; unsigned int offset = 0; /* dummy offset for null seed context */ u8 name[SHA256_DIGEST_SIZE + 2]; + u32 tmp_null_key; + int rc; rc = tpm2_load_context(chip, chip->null_key_context, &offset, - null_key); - if (rc != -EINVAL) - return rc; + &tmp_null_key); + if (rc != -EINVAL) { + if (!rc) + *null_key = tmp_null_key; + goto err; + } - /* an integrity failure may mean the TPM has been reset */ - dev_err(&chip->dev, "NULL key integrity failure!\n"); - /* check the null name against what we know */ - tpm2_create_primary(chip, TPM2_RH_NULL, NULL, name); - if (memcmp(name, chip->null_key_name, sizeof(name)) == 0) - /* name unchanged, assume transient integrity failure */ - return rc; - /* - * Fatal TPM failure: the NULL seed has actually changed, so - * the TPM must have been illegally reset. All in-kernel TPM - * operations will fail because the NULL primary can't be - * loaded to salt the sessions, but disable the TPM anyway so - * userspace programmes can't be compromised by it. - */ - dev_err(&chip->dev, "NULL name has changed, disabling TPM due to interference\n"); + rc = tpm2_create_primary(chip, TPM2_RH_NULL, &tmp_null_key, name); + if (rc) + goto err; + + /* Return the null key if the name has not been changed: */ + if (memcmp(name, chip->null_key_name, sizeof(name)) == 0) { + *null_key = tmp_null_key; + return 0; + } + + /* Deduce from the name change TPM interference: */ + dev_err(&chip->dev, "the null key integrity check failedh\n"); + tpm2_flush_context(chip, tmp_null_key); chip->flags |= TPM_CHIP_FLAG_DISABLE; - return rc; +err: + return rc ? -ENODEV : 0; } /** From patchwork Tue Oct 15 20:58:38 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jarkko Sakkinen X-Patchwork-Id: 13837072 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 5D81A1F80DD; Tue, 15 Oct 2024 20:59:04 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1729025944; cv=none; b=Du8yh+YjmO2ECiklmwceKnMTLxK+xZs1eyTJY5y5CO4aOA27/qqQzizN3nydXdB/iYacgB+K/SK9OLw8y3g1D7jAChL/Ljwl7q8xIZkJ1Pym3FPny4gyySgZlHY3P2bPNAtsfeZxbMQVTAw8mSL+tNokFl9OUwzqXjX1/96F9Sg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1729025944; c=relaxed/simple; bh=WOAZ1cOENdTzj6fIHUXz2Oh6IW2eR1Terhcpne1vvII=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=cmC9wH3CRNBmc/keunsevK8ymF/Ai8eny5LgqOtNuBBkHXvPYi/6HpfIpi2z49ctKjoJkfGR4jM6mcgRDsm5xOIdlx2IPH4Ec1OmsImXEPcnepzDg+kIhmr3323wq3sRpXSJ13TWQ5LpOgK7IWMjHfj6Zxq1WdTFhwBUxAAzpVQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=I+MCfSYC; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="I+MCfSYC" Received: by smtp.kernel.org (Postfix) with ESMTPSA id D19CAC4CEC7; Tue, 15 Oct 2024 20:59:03 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1729025944; bh=WOAZ1cOENdTzj6fIHUXz2Oh6IW2eR1Terhcpne1vvII=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=I+MCfSYCfWWsdmuCOoXs0uUxJoD8vV5SVPcGfuh1/+HnHARy/XgYMrN4tdxNrdNNr 2Vp4RDHqeyUTtY9nbTBUpdlgQ1GhhK8pC3pM8fNYk3WVkH7mJVc3OrAfmtQ33Ozfw4 quKxFeds6yM8VK4Ymkys7MSU1+YOV76P8J6+1cNX9NakCVW2HWHJG5gBGEjnas7iyi hw3i7Bn9L99X81MgARfVxTjky/R0WQMEKhHVbRb6ssl6jN770SMfTje9nvPj3gyFCi zN7nIsXky2ju4Vg+njyd+njh8l6UV11+reeyy95dM8+DDmMGEfgmNytv+iYDmsGncp eNfz3nleVgu1w== From: Jarkko Sakkinen To: Peter Huewe , Jarkko Sakkinen , Jason Gunthorpe , James Bottomley Cc: Stefan Berger , stable@vger.kernel.org, Pengyu Ma , linux-integrity@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v6 3/5] tpm: flush the null key only when /dev/tpm0 is accessed Date: Tue, 15 Oct 2024 23:58:38 +0300 Message-ID: <20241015205842.117300-4-jarkko@kernel.org> X-Mailer: git-send-email 2.47.0 In-Reply-To: <20241015205842.117300-1-jarkko@kernel.org> References: <20241015205842.117300-1-jarkko@kernel.org> Precedence: bulk X-Mailing-List: linux-integrity@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Instead of flushing and reloading the null key for every single auth session, flush it only when: 1. User space needs to access /dev/tpm{rm}0. 2. When going to sleep. 3. When unregistering the chip. This removes the need to load and swap the null key between TPM and regular memory per transaction, when the user space is not using the chip. Cc: stable@vger.kernel.org # v6.10+ Fixes: d2add27cf2b8 ("tpm: Add NULL primary creation") Tested-by: Pengyu Ma Signed-off-by: Jarkko Sakkinen --- v5: - No changes. v4: - Changed to bug fix as not having the patch there is a major hit to bootup times. v3: - Unchanged. v2: - Refined the commit message. - Added tested-by from Pengyu Ma . - Removed spurious pr_info() statement. --- drivers/char/tpm/tpm-chip.c | 13 +++++++++++++ drivers/char/tpm/tpm-dev-common.c | 7 +++++++ drivers/char/tpm/tpm-interface.c | 9 +++++++-- drivers/char/tpm/tpm2-cmd.c | 3 +++ drivers/char/tpm/tpm2-sessions.c | 17 ++++++++++++++--- include/linux/tpm.h | 2 ++ 6 files changed, 46 insertions(+), 5 deletions(-) diff --git a/drivers/char/tpm/tpm-chip.c b/drivers/char/tpm/tpm-chip.c index 854546000c92..0ea00e32f575 100644 --- a/drivers/char/tpm/tpm-chip.c +++ b/drivers/char/tpm/tpm-chip.c @@ -674,6 +674,19 @@ EXPORT_SYMBOL_GPL(tpm_chip_register); */ void tpm_chip_unregister(struct tpm_chip *chip) { +#ifdef CONFIG_TCG_TPM2_HMAC + int rc; + + rc = tpm_try_get_ops(chip); + if (!rc) { + if (chip->flags & TPM_CHIP_FLAG_TPM2) { + tpm2_flush_context(chip, chip->null_key); + chip->null_key = 0; + } + tpm_put_ops(chip); + } +#endif + tpm_del_legacy_sysfs(chip); if (tpm_is_hwrng_enabled(chip)) hwrng_unregister(&chip->hwrng); diff --git a/drivers/char/tpm/tpm-dev-common.c b/drivers/char/tpm/tpm-dev-common.c index c3fbbf4d3db7..4bc07963e260 100644 --- a/drivers/char/tpm/tpm-dev-common.c +++ b/drivers/char/tpm/tpm-dev-common.c @@ -27,6 +27,13 @@ static ssize_t tpm_dev_transmit(struct tpm_chip *chip, struct tpm_space *space, struct tpm_header *header = (void *)buf; ssize_t ret, len; +#ifdef CONFIG_TCG_TPM2_HMAC + if (chip->flags & TPM_CHIP_FLAG_TPM2) { + tpm2_flush_context(chip, chip->null_key); + chip->null_key = 0; + } +#endif + ret = tpm2_prepare_space(chip, space, buf, bufsiz); /* If the command is not implemented by the TPM, synthesize a * response with a TPM2_RC_COMMAND_CODE return for user-space. diff --git a/drivers/char/tpm/tpm-interface.c b/drivers/char/tpm/tpm-interface.c index 5da134f12c9a..bfa47d48b0f2 100644 --- a/drivers/char/tpm/tpm-interface.c +++ b/drivers/char/tpm/tpm-interface.c @@ -379,10 +379,15 @@ int tpm_pm_suspend(struct device *dev) rc = tpm_try_get_ops(chip); if (!rc) { - if (chip->flags & TPM_CHIP_FLAG_TPM2) + if (chip->flags & TPM_CHIP_FLAG_TPM2) { +#ifdef CONFIG_TCG_TPM2_HMAC + tpm2_flush_context(chip, chip->null_key); + chip->null_key = 0; +#endif tpm2_shutdown(chip, TPM2_SU_STATE); - else + } else { rc = tpm1_pm_suspend(chip, tpm_suspend_pcr); + } tpm_put_ops(chip); } diff --git a/drivers/char/tpm/tpm2-cmd.c b/drivers/char/tpm/tpm2-cmd.c index 1e856259219e..aba024cbe7c5 100644 --- a/drivers/char/tpm/tpm2-cmd.c +++ b/drivers/char/tpm/tpm2-cmd.c @@ -364,6 +364,9 @@ void tpm2_flush_context(struct tpm_chip *chip, u32 handle) struct tpm_buf buf; int rc; + if (!handle) + return; + rc = tpm_buf_init(&buf, TPM2_ST_NO_SESSIONS, TPM2_CC_FLUSH_CONTEXT); if (rc) { dev_warn(&chip->dev, "0x%08x was not flushed, out of memory\n", diff --git a/drivers/char/tpm/tpm2-sessions.c b/drivers/char/tpm/tpm2-sessions.c index 1215c53f0ae7..9ffd3da35d21 100644 --- a/drivers/char/tpm/tpm2-sessions.c +++ b/drivers/char/tpm/tpm2-sessions.c @@ -920,11 +920,19 @@ static int tpm2_load_null(struct tpm_chip *chip, u32 *null_key) u32 tmp_null_key; int rc; + /* fast path */ + if (chip->null_key) { + *null_key = chip->null_key; + return 0; + } + rc = tpm2_load_context(chip, chip->null_key_context, &offset, &tmp_null_key); if (rc != -EINVAL) { - if (!rc) + if (!rc) { + chip->null_key = tmp_null_key; *null_key = tmp_null_key; + } goto err; } @@ -934,6 +942,7 @@ static int tpm2_load_null(struct tpm_chip *chip, u32 *null_key) /* Return the null key if the name has not been changed: */ if (memcmp(name, chip->null_key_name, sizeof(name)) == 0) { + chip->null_key = tmp_null_key; *null_key = tmp_null_key; return 0; } @@ -1006,7 +1015,6 @@ int tpm2_start_auth_session(struct tpm_chip *chip) tpm_buf_append_u16(&buf, TPM_ALG_SHA256); rc = tpm_transmit_cmd(chip, &buf, 0, "start auth session"); - tpm2_flush_context(chip, null_key); if (rc == TPM2_RC_SUCCESS) rc = tpm2_parse_start_auth_session(auth, &buf); @@ -1338,7 +1346,10 @@ static int tpm2_create_null_primary(struct tpm_chip *chip) rc = tpm2_save_context(chip, null_key, chip->null_key_context, sizeof(chip->null_key_context), &offset); - tpm2_flush_context(chip, null_key); + if (rc) + tpm2_flush_context(chip, null_key); + else + chip->null_key = null_key; } return rc; diff --git a/include/linux/tpm.h b/include/linux/tpm.h index 587b96b4418e..28a932aa0416 100644 --- a/include/linux/tpm.h +++ b/include/linux/tpm.h @@ -205,6 +205,8 @@ struct tpm_chip { #ifdef CONFIG_TCG_TPM2_HMAC /* details for communication security via sessions */ + /* loaded null key */ + u32 null_key; /* saved context for NULL seed */ u8 null_key_context[TPM2_MAX_CONTEXT_SIZE]; /* name of NULL seed */ From patchwork Tue Oct 15 20:58:39 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jarkko Sakkinen X-Patchwork-Id: 13837073 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 7D2421FAF1E; Tue, 15 Oct 2024 20:59:09 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1729025949; cv=none; b=sb6/zWUHGeBx2E7Q63mQuoDocg8XONx9XPir3zDJpk5wSGvCwgUNINfJ84lNYaz72JmvFRLOG48TVQrSYgwwzieXTlgPYu2iZ9HKOASwo4K/l+fVtlBCjSbkD2eYulQ2JBW0WUNVeZYuzZmS3cBs/YUsIaxvvSjRSqPJwuAmjFw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1729025949; c=relaxed/simple; bh=HVmqjNwE1s1T52eo30gcOIIZ+wVijjkBrMi4ctYK0/M=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=TpirnGByw0EZJ1fhsJh2HLjIwoJryBGjLLGUy91fkYFKY+QCTLrJAI/kGmeUtqfCR/m5qtmCRLhk2O6zwBAKLP+Hmw0dLSxkyv9LTYQg3vTFCTvVNQ4hk1ath1UPWKWNeuLLZZwx5VOwvYvENZQW5wnKR+lEeUshTzuSPA0UGOU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=f0Jdu5E4; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="f0Jdu5E4" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 90B95C4CEC6; Tue, 15 Oct 2024 20:59:08 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1729025949; bh=HVmqjNwE1s1T52eo30gcOIIZ+wVijjkBrMi4ctYK0/M=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=f0Jdu5E4KGysXlyBOyl6FXzMpY05Vj0S46dJWdSPYO4teQY4DiDN6igy2PINyLID4 8ON9cQOGA+qFsPNNiEwpm5RSWlu10ZznofbFpcpwU863o9wksnkxcdZ888wpvtgXiK i2GSzYNnscfUYMSucR/+HzCI0Eek3d6+xrp8COdQDnOL9pn42NPbcbCDKaSKks3Jaj v9WOX0Rp2vBZsAH7YYPZZK6sf30E2lP16IHugKolEf/Aro92KmdAf5lrK/nyF0x3se wtXjnWZe2AwMZFZ6Uq8IoR1y4QFLnVqxOrxyrwVeH95mZg0V5VexfW/r6atEC5vnDQ rCZp4dyTBcl4g== From: Jarkko Sakkinen To: Peter Huewe , Jarkko Sakkinen , Jason Gunthorpe , Ard Biesheuvel , James Bottomley Cc: Stefan Berger , stable@vger.kernel.org, linux-integrity@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v6 4/5] tpm: Allocate chip->auth in tpm2_start_auth_session() Date: Tue, 15 Oct 2024 23:58:39 +0300 Message-ID: <20241015205842.117300-5-jarkko@kernel.org> X-Mailer: git-send-email 2.47.0 In-Reply-To: <20241015205842.117300-1-jarkko@kernel.org> References: <20241015205842.117300-1-jarkko@kernel.org> Precedence: bulk X-Mailing-List: linux-integrity@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Move allocation of chip->auth to tpm2_start_auth_session() so that the field can be used as flag to tell whether auth session is active or not. Cc: stable@vger.kernel.org # v6.10+ Fixes: 699e3efd6c64 ("tpm: Add HMAC session start and end functions") Signed-off-by: Jarkko Sakkinen --- v5: - No changes. v4: - Change to bug. v3: - No changes. v2: - A new patch. --- drivers/char/tpm/tpm2-sessions.c | 43 +++++++++++++++++++------------- 1 file changed, 25 insertions(+), 18 deletions(-) diff --git a/drivers/char/tpm/tpm2-sessions.c b/drivers/char/tpm/tpm2-sessions.c index 9ffd3da35d21..78d344607b53 100644 --- a/drivers/char/tpm/tpm2-sessions.c +++ b/drivers/char/tpm/tpm2-sessions.c @@ -484,7 +484,8 @@ static void tpm2_KDFe(u8 z[EC_PT_SZ], const char *str, u8 *pt_u, u8 *pt_v, sha256_final(&sctx, out); } -static void tpm_buf_append_salt(struct tpm_buf *buf, struct tpm_chip *chip) +static void tpm_buf_append_salt(struct tpm_buf *buf, struct tpm_chip *chip, + struct tpm2_auth *auth) { struct crypto_kpp *kpp; struct kpp_request *req; @@ -543,7 +544,7 @@ static void tpm_buf_append_salt(struct tpm_buf *buf, struct tpm_chip *chip) sg_set_buf(&s[0], chip->null_ec_key_x, EC_PT_SZ); sg_set_buf(&s[1], chip->null_ec_key_y, EC_PT_SZ); kpp_request_set_input(req, s, EC_PT_SZ*2); - sg_init_one(d, chip->auth->salt, EC_PT_SZ); + sg_init_one(d, auth->salt, EC_PT_SZ); kpp_request_set_output(req, d, EC_PT_SZ); crypto_kpp_compute_shared_secret(req); kpp_request_free(req); @@ -554,8 +555,7 @@ static void tpm_buf_append_salt(struct tpm_buf *buf, struct tpm_chip *chip) * This works because KDFe fully consumes the secret before it * writes the salt */ - tpm2_KDFe(chip->auth->salt, "SECRET", x, chip->null_ec_key_x, - chip->auth->salt); + tpm2_KDFe(auth->salt, "SECRET", x, chip->null_ec_key_x, auth->salt); out: crypto_free_kpp(kpp); @@ -854,6 +854,8 @@ int tpm_buf_check_hmac_response(struct tpm_chip *chip, struct tpm_buf *buf, /* manually close the session if it wasn't consumed */ tpm2_flush_context(chip, auth->handle); memzero_explicit(auth, sizeof(*auth)); + kfree(auth); + chip->auth = NULL; } else { /* reset for next use */ auth->session = TPM_HEADER_SIZE; @@ -882,6 +884,8 @@ void tpm2_end_auth_session(struct tpm_chip *chip) tpm2_flush_context(chip, auth->handle); memzero_explicit(auth, sizeof(*auth)); + kfree(auth); + chip->auth = NULL; } EXPORT_SYMBOL(tpm2_end_auth_session); @@ -970,25 +974,29 @@ static int tpm2_load_null(struct tpm_chip *chip, u32 *null_key) */ int tpm2_start_auth_session(struct tpm_chip *chip) { + struct tpm2_auth *auth; struct tpm_buf buf; - struct tpm2_auth *auth = chip->auth; - int rc; u32 null_key; + int rc; - if (!auth) { - dev_warn_once(&chip->dev, "auth session is not active\n"); + if (chip->auth) { + dev_warn_once(&chip->dev, "auth session is active\n"); return 0; } + auth = kzalloc(sizeof(*auth), GFP_KERNEL); + if (!auth) + return -ENOMEM; + rc = tpm2_load_null(chip, &null_key); if (rc) - goto out; + goto err; auth->session = TPM_HEADER_SIZE; rc = tpm_buf_init(&buf, TPM2_ST_NO_SESSIONS, TPM2_CC_START_AUTH_SESS); if (rc) - goto out; + goto err; /* salt key handle */ tpm_buf_append_u32(&buf, null_key); @@ -1000,7 +1008,7 @@ int tpm2_start_auth_session(struct tpm_chip *chip) tpm_buf_append(&buf, auth->our_nonce, sizeof(auth->our_nonce)); /* append encrypted salt and squirrel away unencrypted in auth */ - tpm_buf_append_salt(&buf, chip); + tpm_buf_append_salt(&buf, chip, auth); /* session type (HMAC, audit or policy) */ tpm_buf_append_u8(&buf, TPM2_SE_HMAC); @@ -1021,10 +1029,13 @@ int tpm2_start_auth_session(struct tpm_chip *chip) tpm_buf_destroy(&buf); - if (rc) - goto out; + if (rc == TPM2_RC_SUCCESS) { + chip->auth = auth; + return 0; + } - out: +err: + kfree(auth); return rc; } EXPORT_SYMBOL(tpm2_start_auth_session); @@ -1375,10 +1386,6 @@ int tpm2_sessions_init(struct tpm_chip *chip) if (rc) return rc; - chip->auth = kmalloc(sizeof(*chip->auth), GFP_KERNEL); - if (!chip->auth) - return -ENOMEM; - return rc; } EXPORT_SYMBOL(tpm2_sessions_init); From patchwork Tue Oct 15 20:58:40 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jarkko Sakkinen X-Patchwork-Id: 13837074 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id C569B1FBF49; Tue, 15 Oct 2024 20:59:14 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1729025954; cv=none; b=VDQF1ZlT1hHLCSNJu8Q58O1iB5bV4AOen1n96cgUo98OgNMn54XE0jODUejzw7OOg0A84bhmBUijtJj620ecrtX0vNfk8+YKDDKYKuXnSUCToTvh2ds/x+8unpVAIwdpSIdfgkLNdsDb4J6/dNN7AM49O0WJdNF5k6HA7FMUtzs= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1729025954; c=relaxed/simple; bh=Uhi67Z9bObKORkUfO8nLiAvjlzLJE8SomXQr8tKtJRQ=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=oSDc27wjM473uaQRW5RfHXygen2xWselwe9AYtU+Nr3GyNNy6aioQVTMZTvsVf6fD8prObBx2kgx5F6uz3qjc1689dPRVeX20P2Q/jHMND59yw6MRaA1vF9AYlVclx/HKnHYSo7Wv41Ba6as8+U1u8cuvhE3V8qLze3GZyIGSVA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=WXRVOvr0; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="WXRVOvr0" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 7777EC4CEC6; Tue, 15 Oct 2024 20:59:13 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1729025954; bh=Uhi67Z9bObKORkUfO8nLiAvjlzLJE8SomXQr8tKtJRQ=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=WXRVOvr0cKMen2bJMSl87/dTaexDOxxYhbZxY/RTVGin9JJOyCXg46Y5A0GbmkXWH TiyS5QOql0DNOLYHC8AMG+XTg64+TxJRYBRX7jyW7dajXB8X9s48+/iR5vadkBtmTE RBtp0vvW8or6WAkvHyeSlAv4JsOH0Tb8xHxgW8j15mrEdrf4EW7qmflj83oVI1DvYD ALRWcDb2iw5XEfeN5KJ/eCkqn0/pXZkiU2Vl7WIgLv/XEKChTkr3oRhxDbVFEJXICu QYuG/oP9I0L6Eq06MCy63Ug/Wv0PniG6ALwy+1xK/Dwm/ChM8ScCPryaIjZohX1inS /lsRe5zwTtMTw== From: Jarkko Sakkinen To: Peter Huewe , Jarkko Sakkinen , Jason Gunthorpe Cc: Stefan Berger , Pengyu Ma , stable@vger.kernel.org, linux-integrity@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v6 5/5] tpm: flush the auth session only when /dev/tpm0 is open Date: Tue, 15 Oct 2024 23:58:40 +0300 Message-ID: <20241015205842.117300-6-jarkko@kernel.org> X-Mailer: git-send-email 2.47.0 In-Reply-To: <20241015205842.117300-1-jarkko@kernel.org> References: <20241015205842.117300-1-jarkko@kernel.org> Precedence: bulk X-Mailing-List: linux-integrity@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Instead of flushing and reloading the auth session for every single transaction, keep the session open unless /dev/tpm0 is used. In practice this means applying TPM2_SA_CONTINUE_SESSION to the session attributes. Flush the session always when /dev/tpm0 is written. Reported-by: Pengyu Ma Closes: https://bugzilla.kernel.org/show_bug.cgi?id=219229 Cc: stable@vger.kernel.org # v6.10+ Fixes: 7ca110f2679b ("tpm: Address !chip->auth in tpm_buf_append_hmac_session*()") Tested-by: Pengyu Ma Signed-off-by: Jarkko Sakkinen --- v5: - No changes. v4: - Changed as bug. v3: - Refined the commit message. - Removed the conditional for applying TPM2_SA_CONTINUE_SESSION only when /dev/tpm0 is open. It is not required as the auth session is flushed, not saved. v2: - A new patch. --- drivers/char/tpm/tpm-chip.c | 1 + drivers/char/tpm/tpm-dev-common.c | 1 + drivers/char/tpm/tpm-interface.c | 1 + drivers/char/tpm/tpm2-sessions.c | 3 +++ 4 files changed, 6 insertions(+) diff --git a/drivers/char/tpm/tpm-chip.c b/drivers/char/tpm/tpm-chip.c index 0ea00e32f575..7a6bb30d1f32 100644 --- a/drivers/char/tpm/tpm-chip.c +++ b/drivers/char/tpm/tpm-chip.c @@ -680,6 +680,7 @@ void tpm_chip_unregister(struct tpm_chip *chip) rc = tpm_try_get_ops(chip); if (!rc) { if (chip->flags & TPM_CHIP_FLAG_TPM2) { + tpm2_end_auth_session(chip); tpm2_flush_context(chip, chip->null_key); chip->null_key = 0; } diff --git a/drivers/char/tpm/tpm-dev-common.c b/drivers/char/tpm/tpm-dev-common.c index 4bc07963e260..c6fdeb4feaef 100644 --- a/drivers/char/tpm/tpm-dev-common.c +++ b/drivers/char/tpm/tpm-dev-common.c @@ -29,6 +29,7 @@ static ssize_t tpm_dev_transmit(struct tpm_chip *chip, struct tpm_space *space, #ifdef CONFIG_TCG_TPM2_HMAC if (chip->flags & TPM_CHIP_FLAG_TPM2) { + tpm2_end_auth_session(chip); tpm2_flush_context(chip, chip->null_key); chip->null_key = 0; } diff --git a/drivers/char/tpm/tpm-interface.c b/drivers/char/tpm/tpm-interface.c index bfa47d48b0f2..2363018fa8fb 100644 --- a/drivers/char/tpm/tpm-interface.c +++ b/drivers/char/tpm/tpm-interface.c @@ -381,6 +381,7 @@ int tpm_pm_suspend(struct device *dev) if (!rc) { if (chip->flags & TPM_CHIP_FLAG_TPM2) { #ifdef CONFIG_TCG_TPM2_HMAC + tpm2_end_auth_session(chip); tpm2_flush_context(chip, chip->null_key); chip->null_key = 0; #endif diff --git a/drivers/char/tpm/tpm2-sessions.c b/drivers/char/tpm/tpm2-sessions.c index 78d344607b53..844cfc338f33 100644 --- a/drivers/char/tpm/tpm2-sessions.c +++ b/drivers/char/tpm/tpm2-sessions.c @@ -333,6 +333,9 @@ void tpm_buf_append_hmac_session(struct tpm_chip *chip, struct tpm_buf *buf, } #ifdef CONFIG_TCG_TPM2_HMAC + /* The first write to /dev/tpm{rm0} will flush the session. */ + attributes |= TPM2_SA_CONTINUE_SESSION; + /* * The Architecture Guide requires us to strip trailing zeros * before computing the HMAC