From: Jarkko Sakkinen <jarkko@kernel.org>
To: linux-integrity@vger.kernel.org
Cc: James.Bottomley@HansenPartnership.com, roberto.sassu@huawei.com,
mapengyu@gmail.com, Jarkko Sakkinen <jarkko@kernel.org>,
Peter Huewe <peterhuewe@gmx.de>, Jason Gunthorpe <jgg@ziepe.ca>,
Stefan Berger <stefanb@linux.ibm.com>,
Ard Biesheuvel <ardb@kernel.org>,
linux-kernel@vger.kernel.org (open list)
Subject: [PATCH 4/4] tpm: flush the session null key only when required
Date: Sun, 15 Sep 2024 21:04:46 +0300 [thread overview]
Message-ID: <20240915180448.2030115-5-jarkko@kernel.org> (raw)
In-Reply-To: <20240915180448.2030115-1-jarkko@kernel.org>
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.
Signed-off-by: Jarkko Sakkinen <jarkko@kernel.org>
---
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 | 23 +++++++++++++++++++----
include/linux/tpm.h | 2 ++
6 files changed, 51 insertions(+), 6 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 34ce0d9d4577..8d7b708ce566 100644
--- a/drivers/char/tpm/tpm2-sessions.c
+++ b/drivers/char/tpm/tpm2-sessions.c
@@ -855,10 +855,21 @@ 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,
- null_key);
- if (rc != -EINVAL)
+ &tmp_null_key);
+ if (rc != -EINVAL) {
+ if (!rc) {
+ chip->null_key = tmp_null_key;
+ *null_key = tmp_null_key;
+ }
return rc;
+ }
/* an integrity failure may mean the TPM has been reset */
dev_err(&chip->dev, "NULL key integrity failure!\n");
@@ -869,6 +880,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;
}
@@ -946,7 +958,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);
@@ -1275,7 +1286,11 @@ 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);
+ pr_info("%s: rc=0x%08x\n", __func__, rc);
+ 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 e93ee8d936a9..4eb39db80e05 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 */
--
2.46.0
next prev parent reply other threads:[~2024-09-15 18:05 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-09-15 18:04 [PATCH 0/4] tpm: lazy flush for the session null key Jarkko Sakkinen
2024-09-15 18:04 ` [PATCH 1/4] tpm: remove file header documentation from tpm2-sessions.c Jarkko Sakkinen
2024-09-15 18:04 ` [PATCH 2/4] tpm: address tpm2_create_null_primary() return value Jarkko Sakkinen
2024-09-15 18:04 ` [PATCH 3/4] tpm: address tpm2_create_primary() failure Jarkko Sakkinen
2024-09-15 18:04 ` Jarkko Sakkinen [this message]
2024-09-15 18:12 ` [PATCH 0/4] tpm: lazy flush for the session null key Jarkko Sakkinen
[not found] ` <CALSz7m0ehXM+dU3z0xYPLQkHbyfyMjoCOoMLdBgRcUu1pnT_ww@mail.gmail.com>
2024-09-16 2:33 ` Pengyu Ma
2024-09-16 5:16 ` Jarkko Sakkinen
2024-09-16 5:53 ` Pengyu Ma
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20240915180448.2030115-5-jarkko@kernel.org \
--to=jarkko@kernel.org \
--cc=James.Bottomley@HansenPartnership.com \
--cc=ardb@kernel.org \
--cc=jgg@ziepe.ca \
--cc=linux-integrity@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=mapengyu@gmail.com \
--cc=peterhuewe@gmx.de \
--cc=roberto.sassu@huawei.com \
--cc=stefanb@linux.ibm.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox