* [PATCH] tpm_tis: Check for an error after exhausting send retires
From: Jacqueline Wong @ 2026-04-10 21:13 UTC (permalink / raw)
To: peterhuewe, jarkko
Cc: jgg, Alexander.Steffen, linux-integrity, linux-kernel,
axelrasmussen, Jordan Hand
From: Jordan Hand <jhand@google.com>
tpm_tis_send_main() will attempt to retry sending data TPM_RETRY times.
Currently, if those retries are exhausted, the driver will attempt to
call execute. The TPM will be in the wrong state, leading to the
operation simply timing out.
Instead, if there is still an error after retries are exhausted, return
that error immediately.
Additionally, add logging to more easily determine reason for transmit
failure.
Fixes: 280db21e153d8 ("tpm_tis: Resend command to recover from data transfer errors")
Signed-off-by: Jordan Hand <jhand@google.com>
---
drivers/char/tpm/tpm_tis_core.c | 11 ++++++++++-
1 file changed, 10 insertions(+), 1 deletion(-)
diff --git a/drivers/char/tpm/tpm_tis_core.c b/drivers/char/tpm/tpm_tis_core.c
index e2a1769081b1..b78937841879 100644
--- a/drivers/char/tpm/tpm_tis_core.c
+++ b/drivers/char/tpm/tpm_tis_core.c
@@ -471,6 +471,8 @@ static int tpm_tis_send_data(struct tpm_chip *chip, const u8 *buf, size_t len)
status = tpm_tis_status(chip);
if (!itpm && (status & TPM_STS_DATA_EXPECT) == 0) {
rc = -EIO;
+ dev_err(&chip->dev, "TPM_STS_DATA_EXPECT should be set. sts = 0x%08x\n",
+ status);
goto out_err;
}
}
@@ -491,6 +493,8 @@ static int tpm_tis_send_data(struct tpm_chip *chip, const u8 *buf, size_t len)
status = tpm_tis_status(chip);
if (!itpm && (status & TPM_STS_DATA_EXPECT) != 0) {
rc = -EIO;
+ dev_err(&chip->dev, "TPM_STS_DATA_EXPECT should be unset. sts = 0x%08x\n",
+ status);
goto out_err;
}
@@ -552,11 +556,16 @@ static int tpm_tis_send_main(struct tpm_chip *chip, const u8 *buf, size_t len)
break;
else if (rc != -EAGAIN && rc != -EIO)
/* Data transfer failed, not recoverable */
- return rc;
+ goto out_err;
usleep_range(priv->timeout_min, priv->timeout_max);
}
+ if (rc == -EAGAIN || rc == -EIO) {
+ dev_err(&chip->dev, "Exhausted tpm_tis_send_data retries\n");
+ goto out_err;
+ }
+
/* go and do it */
rc = tpm_tis_write8(priv, TPM_STS(priv->locality), TPM_STS_GO);
if (rc < 0)
--
2.53.0.1213.gd9a14994de-goog
^ permalink raw reply related
* ima: audit log emitted from ima_collect_measurement when SIGKILL interrupts reads from slow-read filesystems
From: Danny Hu @ 2026-04-10 18:54 UTC (permalink / raw)
To: linux-integrity
Cc: zohar, roberto.sassu, dmitry.kasatkin, Sahil Gupta,
Pierre De Abreu, Julien Gomes, Kunal Bharathi
When IMA appraisal/measurement is enabled for executables, an
AUDIT_INTEGRITY_DATA (type=1800) audit message is emitted from
ima_collect_measurement() if a process receives SIGKILL while reading
a file from a slow-read filesystem.
Configuration:
- IMA policy configured: measure func=BPRM_CHECK mask=MAY_EXEC
- stacked overlayfs with git binary on squashfs (compressed, read-only
filesystem on flash storage)
- Kernel version 6.12.68
Steps to reproduce:
$ echo 3 > /proc/sys/vm/drop_caches; timeout --signal=KILL 0.05s git
Killed
$ dmesg | tail -n 1
audit: type=1800 audit(1775843687.948:10): pid=14049 uid=0
auid=72198551 ses=2 op=collect_data cause=failed comm="timeout"
name="git" dev="overlay" ino=11529215046068473654 res=0 errno=0
The drop_caches evicts both the page cache (forcing squashfs to
re-read and decompress from flash on the next access) and the inode
cache (forcing IMA to re-hash). The timeout command execs git and
sends SIGKILL after 50ms.
During that window, IMA is reading the file page by page in
integrity_kernel_read. Since the page cache is cold, the squashfs read
path must decompress blocks from flash storage. This IO operation
causes the kernel to check for signals and return -EINTR. This
propagates up through integrity_kernel_rea to ima_calc_file_hash and
finally ima_collect_measurement, which logs the collect_data failure.
The log is more commonly observed during boot, when the page cache is
cold and all binaries must be read from flash for the first time. Many
services may start and stop concurrently, and any process that
receives SIGKILL while IMA is reading the file from flash for the
first time will produce this audit message.
I believe this log is spurious because the process is being killed;
therefore, an interrupted file read is the expected outcome. The audit
message in this case does not indicate any integrity violations as the
file has not been tampered with. Lastly, the log's presence can
mislead administrators or monitoring tools into believing a security
event occurred when it was only an expected process kill.
Questions for the IMA maintainers:
1. Is this the intended behavior? Should ima_collect_measurement still
emit the audit log when the failure is due to a fatal signal?
2. If not, could a potential fix be to skip the generation of the
audit log in ima_collect_measurement (result == -EINTR &&
fatal_signal_pending(current))?
Thanks,
Danny
^ permalink raw reply
* Re: [PATCH v3] KEYS: trusted: Debugging as a feature
From: Srish Srinivasan @ 2026-04-10 17:33 UTC (permalink / raw)
To: Jarkko Sakinen, linux-integrity, keyrings
Cc: Nayna Jain, James Bottomley, Mimi Zohar, David Howells,
Paul Moore, James Morris, Serge E. Hallyn, Ahmad Fatoum,
Pengutronix Kernel Team, linux-kernel, linux-security-module
In-Reply-To: <20260409160752.988713-1-jarkko@kernel.org>
On 4/9/26 9:37 PM, Jarkko Sakinen wrote:
> From: Jarkko Sakkinen <jarkko@kernel.org>
>
> TPM_DEBUG, and other similar flags, are a non-standard way to specify a
> feature in Linux kernel. Introduce CONFIG_TRUSTED_KEYS_DEBUG for trusted
> keys, and use it to replace these ad-hoc feature flags.
>
> Given that trusted keys debug dumps can contain sensitive data, harden the
> feature as follows:
>
> 1. In the Kconfig description postulate that pr_debug() statements must be
> used.
> 2. Use pr_debug() statements in TPM 1.x driver to print the protocol dump.
> 3. Require trusted.debug=1 on the kernel command line (default: 0) to
> activate dumps at runtime, even when CONFIG_TRUSTED_KEYS_DEBUG=y.
>
> Traces, when actually needed, can be easily enabled by providing
> trusted.dyndbg='+p' and trusted.debug=1 in the kernel command-line.
>
> Cc: Srish Srinivasan <ssrish@linux.ibm.com>
> Reported-by: Nayna Jain <nayna@linux.ibm.com>
> Closes: https://lore.kernel.org/all/7f8b8478-5cd8-4d97-bfd0-341fd5cf10f9@linux.ibm.com/
> Signed-off-by: Jarkko Sakkinen <jarkko@kernel.org>
Tested on PKWM and emulated TPM backends.
Tested-by: Srish Srinivasan <ssrish@linux.ibm.com>
> ---
> v3:
> - Add kernel-command line option for enabling the traces.
> - Add safety information to the Kconfig entry.
> v2:
> - Implement for all trusted keys backends.
> - Add HAVE_TRUSTED_KEYS_DEBUG as it is a good practice despite full
> coverage.
> ---
> include/keys/trusted-type.h | 21 ++++++-----
> security/keys/trusted-keys/Kconfig | 23 ++++++++++++
> security/keys/trusted-keys/trusted_caam.c | 7 ++--
> security/keys/trusted-keys/trusted_core.c | 6 ++++
> security/keys/trusted-keys/trusted_tpm1.c | 44 +++++++++++++----------
> 5 files changed, 71 insertions(+), 30 deletions(-)
>
> diff --git a/include/keys/trusted-type.h b/include/keys/trusted-type.h
> index 03527162613f..9f9940482da4 100644
> --- a/include/keys/trusted-type.h
> +++ b/include/keys/trusted-type.h
> @@ -83,18 +83,21 @@ struct trusted_key_source {
>
> extern struct key_type key_type_trusted;
>
> -#define TRUSTED_DEBUG 0
> +#ifdef CONFIG_TRUSTED_KEYS_DEBUG
> +extern bool trusted_debug;
>
> -#if TRUSTED_DEBUG
> static inline void dump_payload(struct trusted_key_payload *p)
> {
> - pr_info("key_len %d\n", p->key_len);
> - print_hex_dump(KERN_INFO, "key ", DUMP_PREFIX_NONE,
> - 16, 1, p->key, p->key_len, 0);
> - pr_info("bloblen %d\n", p->blob_len);
> - print_hex_dump(KERN_INFO, "blob ", DUMP_PREFIX_NONE,
> - 16, 1, p->blob, p->blob_len, 0);
> - pr_info("migratable %d\n", p->migratable);
> + if (!trusted_debug)
> + return;
> +
> + pr_debug("key_len %d\n", p->key_len);
> + print_hex_dump_debug("key ", DUMP_PREFIX_NONE,
> + 16, 1, p->key, p->key_len, 0);
> + pr_debug("bloblen %d\n", p->blob_len);
> + print_hex_dump_debug("blob ", DUMP_PREFIX_NONE,
> + 16, 1, p->blob, p->blob_len, 0);
> + pr_debug("migratable %d\n", p->migratable);
> }
> #else
> static inline void dump_payload(struct trusted_key_payload *p)
> diff --git a/security/keys/trusted-keys/Kconfig b/security/keys/trusted-keys/Kconfig
> index 9e00482d886a..c1ae7db1f612 100644
> --- a/security/keys/trusted-keys/Kconfig
> +++ b/security/keys/trusted-keys/Kconfig
> @@ -1,10 +1,29 @@
> config HAVE_TRUSTED_KEYS
> bool
>
> +config HAVE_TRUSTED_KEYS_DEBUG
> + bool
> +
> +config TRUSTED_KEYS_DEBUG
> + bool "Debug trusted keys"
> + depends on HAVE_TRUSTED_KEYS_DEBUG
> + default n
> + help
> + Trusted keys backends and core code that support debug traces can
> + opt-in that feature here. Traces must only use debug level output, as
> + sensitive data may pass by. In the kernel-command line traces can be
> + enabled via trusted.dyndbg='+p'.
> +
> + SAFETY: Debug dumps are inactive at runtime until trusted.debug=1 is
> + set on the kernel command-line. Use at your utmost consideration when
> + enabling this feature on a production build. The general advice is not
> + to do this.
> +
> config TRUSTED_KEYS_TPM
> bool "TPM-based trusted keys"
> depends on TCG_TPM >= TRUSTED_KEYS
> default y
> + select HAVE_TRUSTED_KEYS_DEBUG
> select CRYPTO_HASH_INFO
> select CRYPTO_LIB_SHA1
> select CRYPTO_LIB_UTILS
> @@ -23,6 +42,7 @@ config TRUSTED_KEYS_TEE
> bool "TEE-based trusted keys"
> depends on TEE >= TRUSTED_KEYS
> default y
> + select HAVE_TRUSTED_KEYS_DEBUG
> select HAVE_TRUSTED_KEYS
> help
> Enable use of the Trusted Execution Environment (TEE) as trusted
> @@ -33,6 +53,7 @@ config TRUSTED_KEYS_CAAM
> depends on CRYPTO_DEV_FSL_CAAM_JR >= TRUSTED_KEYS
> select CRYPTO_DEV_FSL_CAAM_BLOB_GEN
> default y
> + select HAVE_TRUSTED_KEYS_DEBUG
> select HAVE_TRUSTED_KEYS
> help
> Enable use of NXP's Cryptographic Accelerator and Assurance Module
> @@ -42,6 +63,7 @@ config TRUSTED_KEYS_DCP
> bool "DCP-based trusted keys"
> depends on CRYPTO_DEV_MXS_DCP >= TRUSTED_KEYS
> default y
> + select HAVE_TRUSTED_KEYS_DEBUG
> select HAVE_TRUSTED_KEYS
> help
> Enable use of NXP's DCP (Data Co-Processor) as trusted key backend.
> @@ -50,6 +72,7 @@ config TRUSTED_KEYS_PKWM
> bool "PKWM-based trusted keys"
> depends on PSERIES_PLPKS >= TRUSTED_KEYS
> default y
> + select HAVE_TRUSTED_KEYS_DEBUG
> select HAVE_TRUSTED_KEYS
> help
> Enable use of IBM PowerVM Key Wrapping Module (PKWM) as a trusted key backend.
> diff --git a/security/keys/trusted-keys/trusted_caam.c b/security/keys/trusted-keys/trusted_caam.c
> index 601943ce0d60..6a33dbf2a7f5 100644
> --- a/security/keys/trusted-keys/trusted_caam.c
> +++ b/security/keys/trusted-keys/trusted_caam.c
> @@ -28,10 +28,13 @@ static const match_table_t key_tokens = {
> {opt_err, NULL}
> };
>
> -#ifdef CAAM_DEBUG
> +#ifdef CONFIG_TRUSTED_KEYS_DEBUG
> static inline void dump_options(const struct caam_pkey_info *pkey_info)
> {
> - pr_info("key encryption algo %d\n", pkey_info->key_enc_algo);
> + if (!trusted_debug)
> + return;
> +
> + pr_debug("key encryption algo %d\n", pkey_info->key_enc_algo);
> }
> #else
> static inline void dump_options(const struct caam_pkey_info *pkey_info)
> diff --git a/security/keys/trusted-keys/trusted_core.c b/security/keys/trusted-keys/trusted_core.c
> index 9046123d94de..9ce2459d14b4 100644
> --- a/security/keys/trusted-keys/trusted_core.c
> +++ b/security/keys/trusted-keys/trusted_core.c
> @@ -31,6 +31,12 @@ static char *trusted_rng = "default";
> module_param_named(rng, trusted_rng, charp, 0);
> MODULE_PARM_DESC(rng, "Select trusted key RNG");
>
> +#ifdef CONFIG_TRUSTED_KEYS_DEBUG
> +bool trusted_debug;
> +module_param_named(debug, trusted_debug, bool, 0);
> +MODULE_PARM_DESC(debug, "Enable trusted keys debug traces (default: 0)");
> +#endif
> +
> static char *trusted_key_source;
> module_param_named(source, trusted_key_source, charp, 0);
> MODULE_PARM_DESC(source, "Select trusted keys source (tpm, tee, caam, dcp or pkwm)");
> diff --git a/security/keys/trusted-keys/trusted_tpm1.c b/security/keys/trusted-keys/trusted_tpm1.c
> index c865c97aa1b4..b9fa2b4205cf 100644
> --- a/security/keys/trusted-keys/trusted_tpm1.c
> +++ b/security/keys/trusted-keys/trusted_tpm1.c
> @@ -46,38 +46,44 @@ enum {
> SRK_keytype = 4
> };
>
> -#define TPM_DEBUG 0
> -
> -#if TPM_DEBUG
> +#ifdef CONFIG_TRUSTED_KEYS_DEBUG
> static inline void dump_options(struct trusted_key_options *o)
> {
> - pr_info("sealing key type %d\n", o->keytype);
> - pr_info("sealing key handle %0X\n", o->keyhandle);
> - pr_info("pcrlock %d\n", o->pcrlock);
> - pr_info("pcrinfo %d\n", o->pcrinfo_len);
> - print_hex_dump(KERN_INFO, "pcrinfo ", DUMP_PREFIX_NONE,
> - 16, 1, o->pcrinfo, o->pcrinfo_len, 0);
> + if (!trusted_debug)
> + return;
> +
> + pr_debug("sealing key type %d\n", o->keytype);
> + pr_debug("sealing key handle %0X\n", o->keyhandle);
> + pr_debug("pcrlock %d\n", o->pcrlock);
> + pr_debug("pcrinfo %d\n", o->pcrinfo_len);
> + print_hex_dump_debug("pcrinfo ", DUMP_PREFIX_NONE,
> + 16, 1, o->pcrinfo, o->pcrinfo_len, 0);
> }
>
> static inline void dump_sess(struct osapsess *s)
> {
> - print_hex_dump(KERN_INFO, "trusted-key: handle ", DUMP_PREFIX_NONE,
> - 16, 1, &s->handle, 4, 0);
> - pr_info("secret:\n");
> - print_hex_dump(KERN_INFO, "", DUMP_PREFIX_NONE,
> - 16, 1, &s->secret, SHA1_DIGEST_SIZE, 0);
> - pr_info("trusted-key: enonce:\n");
> - print_hex_dump(KERN_INFO, "", DUMP_PREFIX_NONE,
> - 16, 1, &s->enonce, SHA1_DIGEST_SIZE, 0);
> + if (!trusted_debug)
> + return;
> +
> + print_hex_dump_debug("trusted-key: handle ", DUMP_PREFIX_NONE,
> + 16, 1, &s->handle, 4, 0);
> + pr_debug("secret:\n");
> + print_hex_dump_debug("", DUMP_PREFIX_NONE,
> + 16, 1, &s->secret, SHA1_DIGEST_SIZE, 0);
> + pr_debug("trusted-key: enonce:\n");
> + print_hex_dump_debug("", DUMP_PREFIX_NONE,
> + 16, 1, &s->enonce, SHA1_DIGEST_SIZE, 0);
> }
>
> static inline void dump_tpm_buf(unsigned char *buf)
> {
> int len;
>
> - pr_info("\ntpm buffer\n");
> + if (!trusted_debug)
> + return;
> + pr_debug("\ntpm buffer\n");
> len = LOAD32(buf, TPM_SIZE_OFFSET);
> - print_hex_dump(KERN_INFO, "", DUMP_PREFIX_NONE, 16, 1, buf, len, 0);
> + print_hex_dump_debug("", DUMP_PREFIX_NONE, 16, 1, buf, len, 0);
> }
> #else
> static inline void dump_options(struct trusted_key_options *o)
^ permalink raw reply
* Re: [PATCH v1] tpm: restore timeout for key creation commands
From: Paul Menzel @ 2026-04-10 6:49 UTC (permalink / raw)
To: Baoli Zhang
Cc: Peter Huewe, Jarkko Sakkinen, Jason Gunthorpe, Serge Hallyn,
Lili Li, linux-integrity, linux-kernel
In-Reply-To: <20260410014940.3557934-1-baoli.zhang@linux.intel.com>
Dear Baoli,
Thank you for your patch. Some formalities:
Am 10.04.26 um 03:49 schrieb Baoli.Zhang:
> After the per-command duration map was introduced, TPM2 key creation
> commands (`CREATE_PRIMARY`, `CREATE`, `CREATE_LOADED`) were limited to
> 30 seconds.
>
> On some platforms this is not sufficient and key creation can time out.
> Commit 207696b17f38 ("tpm: use a map for tpm2_calc_ordinal_duration()")
> inadvertently reduced these command timeouts from 300 seconds to 30
> seconds. Restore them to 300 seconds to avoid spurious failures.
Please document such a platform.
> Fixes: 207696b17f38 ("tpm: use a map for tpm2_calc_ordinal_duration()")
>
> Signed-off-by: Baoli.Zhang <baoli.zhang@linux.intel.com>
It’d be great if you remove the dot from your name:
git config --global user.name "Baoli Zhang"
> Co-developed-by: lili.li <lili.li@intel.com>
Same here. Maybe spell it Lili Li?
git commit --amend --author="BaoliZhang
<baoli.zhang@linux.intel.com>" -s
> ---
> drivers/char/tpm/tpm2-cmd.c | 6 +++---
> 1 file changed, 3 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/char/tpm/tpm2-cmd.c b/drivers/char/tpm/tpm2-cmd.c
> index 3a77be7ebf4aa..430022f695f24 100644
> --- a/drivers/char/tpm/tpm2-cmd.c
> +++ b/drivers/char/tpm/tpm2-cmd.c
> @@ -71,9 +71,9 @@ static const struct {
> {TPM2_CC_HIERARCHY_CHANGE_AUTH, 2000},
> {TPM2_CC_GET_CAPABILITY, 750},
> {TPM2_CC_NV_READ, 2000},
> - {TPM2_CC_CREATE_PRIMARY, 30000},
> - {TPM2_CC_CREATE, 30000},
> - {TPM2_CC_CREATE_LOADED, 30000},
> + {TPM2_CC_CREATE_PRIMARY, 300000},
> + {TPM2_CC_CREATE, 300000},
> + {TPM2_CC_CREATE_LOADED, 300000},
> };
>
> /**
^ permalink raw reply
* [PATCH v1] tpm: restore timeout for key creation commands
From: Baoli.Zhang @ 2026-04-10 1:49 UTC (permalink / raw)
To: Peter Huewe, Jarkko Sakkinen, Jason Gunthorpe, Serge Hallyn
Cc: Baoli.Zhang, lili . li, linux-integrity, linux-kernel
After the per-command duration map was introduced, TPM2 key creation
commands (`CREATE_PRIMARY`, `CREATE`, `CREATE_LOADED`) were limited to
30 seconds.
On some platforms this is not sufficient and key creation can time out.
Commit 207696b17f38 ("tpm: use a map for tpm2_calc_ordinal_duration()")
inadvertently reduced these command timeouts from 300 seconds to 30
seconds. Restore them to 300 seconds to avoid spurious failures.
Fixes: 207696b17f38 ("tpm: use a map for tpm2_calc_ordinal_duration()")
Signed-off-by: Baoli.Zhang <baoli.zhang@linux.intel.com>
Co-developed-by: lili.li <lili.li@intel.com>
---
drivers/char/tpm/tpm2-cmd.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/char/tpm/tpm2-cmd.c b/drivers/char/tpm/tpm2-cmd.c
index 3a77be7ebf4aa..430022f695f24 100644
--- a/drivers/char/tpm/tpm2-cmd.c
+++ b/drivers/char/tpm/tpm2-cmd.c
@@ -71,9 +71,9 @@ static const struct {
{TPM2_CC_HIERARCHY_CHANGE_AUTH, 2000},
{TPM2_CC_GET_CAPABILITY, 750},
{TPM2_CC_NV_READ, 2000},
- {TPM2_CC_CREATE_PRIMARY, 30000},
- {TPM2_CC_CREATE, 30000},
- {TPM2_CC_CREATE_LOADED, 30000},
+ {TPM2_CC_CREATE_PRIMARY, 300000},
+ {TPM2_CC_CREATE, 300000},
+ {TPM2_CC_CREATE_LOADED, 300000},
};
/**
--
2.43.0
^ permalink raw reply related
* [PATCH] tpm: Use kfree_sensitive() to free auth session in tpm_dev_release()
From: Gunnar Kudrjavets @ 2026-04-09 17:20 UTC (permalink / raw)
To: peterhuewe, jarkko
Cc: jgg, James.Bottomley, ardb, linux-integrity, linux-kernel,
Justinien Bouron
tpm_dev_release() uses plain kfree() to free chip->auth, which contains
sensitive cryptographic material including HMAC session keys, nonces,
and passphrase data (struct tpm2_auth).
Every other code path that frees this structure uses kfree_sensitive()
to zero the memory before releasing it: both tpm2_end_auth_session()
and tpm_buf_check_hmac_response() do so. The tpm_dev_release() path
is the only one that does not, leaving key material in freed slab
memory until it is eventually overwritten.
Use kfree_sensitive() for consistency with the rest of the driver and
to ensure session keys are scrubbed during device teardown.
Fixes: 699e3efd6c64 ("tpm: Add HMAC session start and end functions")
Signed-off-by: Gunnar Kudrjavets <gunnarku@amazon.com>
Reviewed-by: Justinien Bouron <jbouron@amazon.com>
---
drivers/char/tpm/tpm-chip.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/char/tpm/tpm-chip.c b/drivers/char/tpm/tpm-chip.c
index 082b910ddf0d..17d9d71774ec 100644
--- a/drivers/char/tpm/tpm-chip.c
+++ b/drivers/char/tpm/tpm-chip.c
@@ -247,7 +247,7 @@ static void tpm_dev_release(struct device *dev)
kfree(chip->work_space.context_buf);
kfree(chip->work_space.session_buf);
#ifdef CONFIG_TCG_TPM2_HMAC
- kfree(chip->auth);
+ kfree_sensitive(chip->auth);
#endif
kfree(chip);
}
base-commit: 03e5553f5fb99cb47c315e167a604a9c69e6f724
--
2.47.3
^ permalink raw reply related
* [PATCH v3] KEYS: trusted: Debugging as a feature
From: Jarkko Sakinen @ 2026-04-09 16:07 UTC (permalink / raw)
To: linux-integrity, keyrings
Cc: Jarkko Sakkinen, Srish Srinivasan, Nayna Jain, James Bottomley,
Mimi Zohar, David Howells, Paul Moore, James Morris,
Serge E. Hallyn, Ahmad Fatoum, Pengutronix Kernel Team,
linux-kernel, linux-security-module
From: Jarkko Sakkinen <jarkko@kernel.org>
TPM_DEBUG, and other similar flags, are a non-standard way to specify a
feature in Linux kernel. Introduce CONFIG_TRUSTED_KEYS_DEBUG for trusted
keys, and use it to replace these ad-hoc feature flags.
Given that trusted keys debug dumps can contain sensitive data, harden the
feature as follows:
1. In the Kconfig description postulate that pr_debug() statements must be
used.
2. Use pr_debug() statements in TPM 1.x driver to print the protocol dump.
3. Require trusted.debug=1 on the kernel command line (default: 0) to
activate dumps at runtime, even when CONFIG_TRUSTED_KEYS_DEBUG=y.
Traces, when actually needed, can be easily enabled by providing
trusted.dyndbg='+p' and trusted.debug=1 in the kernel command-line.
Cc: Srish Srinivasan <ssrish@linux.ibm.com>
Reported-by: Nayna Jain <nayna@linux.ibm.com>
Closes: https://lore.kernel.org/all/7f8b8478-5cd8-4d97-bfd0-341fd5cf10f9@linux.ibm.com/
Signed-off-by: Jarkko Sakkinen <jarkko@kernel.org>
---
v3:
- Add kernel-command line option for enabling the traces.
- Add safety information to the Kconfig entry.
v2:
- Implement for all trusted keys backends.
- Add HAVE_TRUSTED_KEYS_DEBUG as it is a good practice despite full
coverage.
---
include/keys/trusted-type.h | 21 ++++++-----
security/keys/trusted-keys/Kconfig | 23 ++++++++++++
security/keys/trusted-keys/trusted_caam.c | 7 ++--
security/keys/trusted-keys/trusted_core.c | 6 ++++
security/keys/trusted-keys/trusted_tpm1.c | 44 +++++++++++++----------
5 files changed, 71 insertions(+), 30 deletions(-)
diff --git a/include/keys/trusted-type.h b/include/keys/trusted-type.h
index 03527162613f..9f9940482da4 100644
--- a/include/keys/trusted-type.h
+++ b/include/keys/trusted-type.h
@@ -83,18 +83,21 @@ struct trusted_key_source {
extern struct key_type key_type_trusted;
-#define TRUSTED_DEBUG 0
+#ifdef CONFIG_TRUSTED_KEYS_DEBUG
+extern bool trusted_debug;
-#if TRUSTED_DEBUG
static inline void dump_payload(struct trusted_key_payload *p)
{
- pr_info("key_len %d\n", p->key_len);
- print_hex_dump(KERN_INFO, "key ", DUMP_PREFIX_NONE,
- 16, 1, p->key, p->key_len, 0);
- pr_info("bloblen %d\n", p->blob_len);
- print_hex_dump(KERN_INFO, "blob ", DUMP_PREFIX_NONE,
- 16, 1, p->blob, p->blob_len, 0);
- pr_info("migratable %d\n", p->migratable);
+ if (!trusted_debug)
+ return;
+
+ pr_debug("key_len %d\n", p->key_len);
+ print_hex_dump_debug("key ", DUMP_PREFIX_NONE,
+ 16, 1, p->key, p->key_len, 0);
+ pr_debug("bloblen %d\n", p->blob_len);
+ print_hex_dump_debug("blob ", DUMP_PREFIX_NONE,
+ 16, 1, p->blob, p->blob_len, 0);
+ pr_debug("migratable %d\n", p->migratable);
}
#else
static inline void dump_payload(struct trusted_key_payload *p)
diff --git a/security/keys/trusted-keys/Kconfig b/security/keys/trusted-keys/Kconfig
index 9e00482d886a..c1ae7db1f612 100644
--- a/security/keys/trusted-keys/Kconfig
+++ b/security/keys/trusted-keys/Kconfig
@@ -1,10 +1,29 @@
config HAVE_TRUSTED_KEYS
bool
+config HAVE_TRUSTED_KEYS_DEBUG
+ bool
+
+config TRUSTED_KEYS_DEBUG
+ bool "Debug trusted keys"
+ depends on HAVE_TRUSTED_KEYS_DEBUG
+ default n
+ help
+ Trusted keys backends and core code that support debug traces can
+ opt-in that feature here. Traces must only use debug level output, as
+ sensitive data may pass by. In the kernel-command line traces can be
+ enabled via trusted.dyndbg='+p'.
+
+ SAFETY: Debug dumps are inactive at runtime until trusted.debug=1 is
+ set on the kernel command-line. Use at your utmost consideration when
+ enabling this feature on a production build. The general advice is not
+ to do this.
+
config TRUSTED_KEYS_TPM
bool "TPM-based trusted keys"
depends on TCG_TPM >= TRUSTED_KEYS
default y
+ select HAVE_TRUSTED_KEYS_DEBUG
select CRYPTO_HASH_INFO
select CRYPTO_LIB_SHA1
select CRYPTO_LIB_UTILS
@@ -23,6 +42,7 @@ config TRUSTED_KEYS_TEE
bool "TEE-based trusted keys"
depends on TEE >= TRUSTED_KEYS
default y
+ select HAVE_TRUSTED_KEYS_DEBUG
select HAVE_TRUSTED_KEYS
help
Enable use of the Trusted Execution Environment (TEE) as trusted
@@ -33,6 +53,7 @@ config TRUSTED_KEYS_CAAM
depends on CRYPTO_DEV_FSL_CAAM_JR >= TRUSTED_KEYS
select CRYPTO_DEV_FSL_CAAM_BLOB_GEN
default y
+ select HAVE_TRUSTED_KEYS_DEBUG
select HAVE_TRUSTED_KEYS
help
Enable use of NXP's Cryptographic Accelerator and Assurance Module
@@ -42,6 +63,7 @@ config TRUSTED_KEYS_DCP
bool "DCP-based trusted keys"
depends on CRYPTO_DEV_MXS_DCP >= TRUSTED_KEYS
default y
+ select HAVE_TRUSTED_KEYS_DEBUG
select HAVE_TRUSTED_KEYS
help
Enable use of NXP's DCP (Data Co-Processor) as trusted key backend.
@@ -50,6 +72,7 @@ config TRUSTED_KEYS_PKWM
bool "PKWM-based trusted keys"
depends on PSERIES_PLPKS >= TRUSTED_KEYS
default y
+ select HAVE_TRUSTED_KEYS_DEBUG
select HAVE_TRUSTED_KEYS
help
Enable use of IBM PowerVM Key Wrapping Module (PKWM) as a trusted key backend.
diff --git a/security/keys/trusted-keys/trusted_caam.c b/security/keys/trusted-keys/trusted_caam.c
index 601943ce0d60..6a33dbf2a7f5 100644
--- a/security/keys/trusted-keys/trusted_caam.c
+++ b/security/keys/trusted-keys/trusted_caam.c
@@ -28,10 +28,13 @@ static const match_table_t key_tokens = {
{opt_err, NULL}
};
-#ifdef CAAM_DEBUG
+#ifdef CONFIG_TRUSTED_KEYS_DEBUG
static inline void dump_options(const struct caam_pkey_info *pkey_info)
{
- pr_info("key encryption algo %d\n", pkey_info->key_enc_algo);
+ if (!trusted_debug)
+ return;
+
+ pr_debug("key encryption algo %d\n", pkey_info->key_enc_algo);
}
#else
static inline void dump_options(const struct caam_pkey_info *pkey_info)
diff --git a/security/keys/trusted-keys/trusted_core.c b/security/keys/trusted-keys/trusted_core.c
index 9046123d94de..9ce2459d14b4 100644
--- a/security/keys/trusted-keys/trusted_core.c
+++ b/security/keys/trusted-keys/trusted_core.c
@@ -31,6 +31,12 @@ static char *trusted_rng = "default";
module_param_named(rng, trusted_rng, charp, 0);
MODULE_PARM_DESC(rng, "Select trusted key RNG");
+#ifdef CONFIG_TRUSTED_KEYS_DEBUG
+bool trusted_debug;
+module_param_named(debug, trusted_debug, bool, 0);
+MODULE_PARM_DESC(debug, "Enable trusted keys debug traces (default: 0)");
+#endif
+
static char *trusted_key_source;
module_param_named(source, trusted_key_source, charp, 0);
MODULE_PARM_DESC(source, "Select trusted keys source (tpm, tee, caam, dcp or pkwm)");
diff --git a/security/keys/trusted-keys/trusted_tpm1.c b/security/keys/trusted-keys/trusted_tpm1.c
index c865c97aa1b4..b9fa2b4205cf 100644
--- a/security/keys/trusted-keys/trusted_tpm1.c
+++ b/security/keys/trusted-keys/trusted_tpm1.c
@@ -46,38 +46,44 @@ enum {
SRK_keytype = 4
};
-#define TPM_DEBUG 0
-
-#if TPM_DEBUG
+#ifdef CONFIG_TRUSTED_KEYS_DEBUG
static inline void dump_options(struct trusted_key_options *o)
{
- pr_info("sealing key type %d\n", o->keytype);
- pr_info("sealing key handle %0X\n", o->keyhandle);
- pr_info("pcrlock %d\n", o->pcrlock);
- pr_info("pcrinfo %d\n", o->pcrinfo_len);
- print_hex_dump(KERN_INFO, "pcrinfo ", DUMP_PREFIX_NONE,
- 16, 1, o->pcrinfo, o->pcrinfo_len, 0);
+ if (!trusted_debug)
+ return;
+
+ pr_debug("sealing key type %d\n", o->keytype);
+ pr_debug("sealing key handle %0X\n", o->keyhandle);
+ pr_debug("pcrlock %d\n", o->pcrlock);
+ pr_debug("pcrinfo %d\n", o->pcrinfo_len);
+ print_hex_dump_debug("pcrinfo ", DUMP_PREFIX_NONE,
+ 16, 1, o->pcrinfo, o->pcrinfo_len, 0);
}
static inline void dump_sess(struct osapsess *s)
{
- print_hex_dump(KERN_INFO, "trusted-key: handle ", DUMP_PREFIX_NONE,
- 16, 1, &s->handle, 4, 0);
- pr_info("secret:\n");
- print_hex_dump(KERN_INFO, "", DUMP_PREFIX_NONE,
- 16, 1, &s->secret, SHA1_DIGEST_SIZE, 0);
- pr_info("trusted-key: enonce:\n");
- print_hex_dump(KERN_INFO, "", DUMP_PREFIX_NONE,
- 16, 1, &s->enonce, SHA1_DIGEST_SIZE, 0);
+ if (!trusted_debug)
+ return;
+
+ print_hex_dump_debug("trusted-key: handle ", DUMP_PREFIX_NONE,
+ 16, 1, &s->handle, 4, 0);
+ pr_debug("secret:\n");
+ print_hex_dump_debug("", DUMP_PREFIX_NONE,
+ 16, 1, &s->secret, SHA1_DIGEST_SIZE, 0);
+ pr_debug("trusted-key: enonce:\n");
+ print_hex_dump_debug("", DUMP_PREFIX_NONE,
+ 16, 1, &s->enonce, SHA1_DIGEST_SIZE, 0);
}
static inline void dump_tpm_buf(unsigned char *buf)
{
int len;
- pr_info("\ntpm buffer\n");
+ if (!trusted_debug)
+ return;
+ pr_debug("\ntpm buffer\n");
len = LOAD32(buf, TPM_SIZE_OFFSET);
- print_hex_dump(KERN_INFO, "", DUMP_PREFIX_NONE, 16, 1, buf, len, 0);
+ print_hex_dump_debug("", DUMP_PREFIX_NONE, 16, 1, buf, len, 0);
}
#else
static inline void dump_options(struct trusted_key_options *o)
--
2.39.5
^ permalink raw reply related
* Re: [PATCH v2] KEYS: trusted: Debugging as a feature
From: Nayna Jain @ 2026-04-09 0:41 UTC (permalink / raw)
To: Jarkko Sakkinen
Cc: linux-integrity, keyrings, Srish Srinivasan, James Bottomley,
Mimi Zohar, David Howells, Paul Moore, James Morris,
Serge E. Hallyn, Ahmad Fatoum, Pengutronix Kernel Team, open list,
open list:SECURITY SUBSYSTEM
In-Reply-To: <adYRURAJfNCu0FYB@kernel.org>
On 4/8/26 4:26 AM, Jarkko Sakkinen wrote:
> On Mon, Apr 06, 2026 at 10:42:00PM -0400, Nayna Jain wrote:
>> On 3/24/26 7:00 AM, Jarkko Sakkinen wrote:
>>> TPM_DEBUG, and other similar flags, are a non-standard way to specify a
>>> feature in Linux kernel. Introduce CONFIG_TRUSTED_KEYS_DEBUG for
>>> trusted keys, and use it to replace these ad-hoc feature flags.
>>>
>>> Given that trusted keys debug dumps can contain sensitive data, harden
>>> the feature as follows:
>>>
>>> 1. In the Kconfig description postulate that pr_debug() statements must be
>>> used.
>>> 2. Use pr_debug() statements in TPM 1.x driver to print the protocol dump.
>>>
>>> Traces, when actually needed, can be easily enabled by providing
>>> trusted.dyndbg='+p' in the kernel command-line.
>>>
>>> Cc: Srish Srinivasan <ssrish@linux.ibm.com>
>>> Reported-by: Nayna Jain <nayna@linux.ibm.com>
>>> Closes: https://lore.kernel.org/all/7f8b8478-5cd8-4d97-bfd0-341fd5cf10f9@linux.ibm.com/
>>> Signed-off-by: Jarkko Sakkinen <jarkko@kernel.org>
>>> ---
>>> v2:
>>> - Implement for all trusted keys backends.
>>> - Add HAVE_TRUSTED_KEYS_DEBUG as it is a good practice despite full
>>> coverage.
>>> ---
>>> include/keys/trusted-type.h | 18 +++++-------
>>> security/keys/trusted-keys/Kconfig | 19 ++++++++++++
>>> security/keys/trusted-keys/trusted_caam.c | 4 +--
>>> security/keys/trusted-keys/trusted_tpm1.c | 36 +++++++++++------------
>>> 4 files changed, 46 insertions(+), 31 deletions(-)
>>>
>>> diff --git a/include/keys/trusted-type.h b/include/keys/trusted-type.h
>>> index 03527162613f..620a1f890b6b 100644
>>> --- a/include/keys/trusted-type.h
>>> +++ b/include/keys/trusted-type.h
>>> @@ -83,18 +83,16 @@ struct trusted_key_source {
>>> extern struct key_type key_type_trusted;
>>> -#define TRUSTED_DEBUG 0
>>> -
>>> -#if TRUSTED_DEBUG
>>> +#ifdef CONFIG_TRUSTED_KEYS_DEBUG
>>> static inline void dump_payload(struct trusted_key_payload *p)
>>> {
>>> - pr_info("key_len %d\n", p->key_len);
>>> - print_hex_dump(KERN_INFO, "key ", DUMP_PREFIX_NONE,
>>> - 16, 1, p->key, p->key_len, 0);
>>> - pr_info("bloblen %d\n", p->blob_len);
>>> - print_hex_dump(KERN_INFO, "blob ", DUMP_PREFIX_NONE,
>>> - 16, 1, p->blob, p->blob_len, 0);
>>> - pr_info("migratable %d\n", p->migratable);
>>> + pr_debug("key_len %d\n", p->key_len);
>>> + print_hex_dump_debug("key ", DUMP_PREFIX_NONE,
>>> + 16, 1, p->key, p->key_len, 0);
>>> + pr_debug("bloblen %d\n", p->blob_len);
>>> + print_hex_dump_debug("blob ", DUMP_PREFIX_NONE,
>>> + 16, 1, p->blob, p->blob_len, 0);
>>> + pr_debug("migratable %d\n", p->migratable);
>>> }
>>> #else
>>> static inline void dump_payload(struct trusted_key_payload *p)
>>> diff --git a/security/keys/trusted-keys/Kconfig b/security/keys/trusted-keys/Kconfig
>>> index 9e00482d886a..2ad9ba0e03f1 100644
>>> --- a/security/keys/trusted-keys/Kconfig
>>> +++ b/security/keys/trusted-keys/Kconfig
>>> @@ -1,10 +1,25 @@
>>> config HAVE_TRUSTED_KEYS
>>> bool
>>> +config HAVE_TRUSTED_KEYS_DEBUG
>>> + bool
>>> +
>>> +config TRUSTED_KEYS_DEBUG
>>> + bool "Debug trusted keys"
>>> + depends on HAVE_TRUSTED_KEYS_DEBUG
>>> + default n
>>> + help
>>> + Trusted keys backends and core code that support debug dumps
>>> + can opt-in that feature here. Dumps must only use DEBUG
>>> + level output, as sensitive data may pass by. In the
>>> + kernel-command line traces can be enabled via
>>> + trusted.dyndbg='+p'.
>> Would it be good idea to add an explicit note/warning:
>>
>>
>> NOTE: This option is intended for debugging purposes only. Do not enable on
>> production systems as debug output may expose sensitive cryptographic
>> material.
>> If you are unsure, say N.
>>
>> Apart from this, looks good to me.
>>
>> Reviewed-by: Nayna Jain <nayna@linux.ibm.com>
> Thank, I'll add your tag but would you mind quickly screening v3 again
> where I add "trusted.debug=0|1". And yes, your suggestion about extra
> warning makes sense.
Sure Jarkko.. However, I don't see v3 version in my inbox or in
linux-integrity. Or you are about to post it soon.
>
> Let's make this safe as possible. Mistakes do happen... and then those
> measures pay off :-)
Yes agree.
>
> BR, Jarkko
Thanks & Regards,
- Nayna
^ permalink raw reply
* [PATCH v2 0/2] Add support for ML-DSA signature for EVM and IMA
From: Stefan Berger @ 2026-04-08 17:41 UTC (permalink / raw)
To: linux-integrity, linux-security-module
Cc: linux-kernel, zohar, roberto.sassu, ebiggers, Stefan Berger
Based on IMA sigv3 type of signatures, add support for ML-DSA signature
for EVM and IMA. Use the existing ML-DSA hashless signing mode (pure mode).
Stefan
v2:
- Dropped 1/3
- Using "none" as hash_algo in 2/2
Stefan Berger (2):
integrity: Refactor asymmetric_verify for reusability
integrity: Add support for sigv3 verification using ML-DSA keys
security/integrity/digsig_asymmetric.c | 126 +++++++++++++++++++++----
1 file changed, 107 insertions(+), 19 deletions(-)
base-commit: 82bbd447199ff1441031d2eaf9afe041550cf525
--
2.53.0
^ permalink raw reply
* [PATCH v2 2/2] integrity: Add support for sigv3 verification using ML-DSA keys
From: Stefan Berger @ 2026-04-08 17:41 UTC (permalink / raw)
To: linux-integrity, linux-security-module
Cc: linux-kernel, zohar, roberto.sassu, ebiggers, Stefan Berger
In-Reply-To: <20260408174154.139606-1-stefanb@linux.ibm.com>
Add support for sigv3 signature verification using ML-DSA in pure mode.
When a sigv3 signature is verified, first check whether the key to use
for verification is an ML-DSA key and therefore uses a hashless signature
verification scheme. The hashless signature verification method uses the
ima_file_id structure directly for signature verification rather than
its digest.
Suggested-by: Eric Biggers <ebiggers@kernel.org>
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
---
v2: Set hash_algo in public_key_signature to "none"
---
security/integrity/digsig_asymmetric.c | 84 ++++++++++++++++++++++++--
1 file changed, 79 insertions(+), 5 deletions(-)
diff --git a/security/integrity/digsig_asymmetric.c b/security/integrity/digsig_asymmetric.c
index e29ed73f15cd..c80cb2b117a6 100644
--- a/security/integrity/digsig_asymmetric.c
+++ b/security/integrity/digsig_asymmetric.c
@@ -190,17 +190,91 @@ static int calc_file_id_hash(enum evm_ima_xattr_type type,
return rc;
}
+/*
+ * asymmetric_verify_v3_hashless - Use hashless signature verification on sigv3
+ * @key: The key to use for signature verification
+ * @pk: The associated public key
+ * @encoding: The encoding the key type uses
+ * @sig: The signature
+ * @siglen: The length of the xattr signature
+ * @algo: The hash algorithm
+ * @digest: The file digest
+ *
+ * Create an ima_file_id structure and use it for signature verification
+ * directly. This can be used for ML-DSA in pure mode for example.
+ */
+static int asymmetric_verify_v3_hashless(struct key *key,
+ const struct public_key *pk,
+ const char *encoding,
+ const char *sig, int siglen,
+ u8 algo,
+ const u8 *digest)
+{
+ struct signature_v2_hdr *hdr = (struct signature_v2_hdr *)sig;
+ struct ima_file_id file_id = {
+ .hash_type = hdr->type,
+ .hash_algorithm = algo,
+ };
+ size_t digest_size = hash_digest_size[algo];
+ struct public_key_signature pks = {
+ .m = (u8 *)&file_id,
+ .m_size = sizeof(file_id) - (HASH_MAX_DIGESTSIZE - digest_size),
+ .s = hdr->sig,
+ .s_size = siglen - sizeof(*hdr),
+ .pkey_algo = pk->pkey_algo,
+ .hash_algo = "none",
+ .encoding = encoding,
+ };
+ int ret;
+
+ if (hdr->type != IMA_VERITY_DIGSIG &&
+ hdr->type != EVM_IMA_XATTR_DIGSIG &&
+ hdr->type != EVM_XATTR_PORTABLE_DIGSIG)
+ return -EINVAL;
+
+ if (pks.s_size != be16_to_cpu(hdr->sig_size))
+ return -EBADMSG;
+
+ memcpy(file_id.hash, digest, digest_size);
+
+ ret = verify_signature(key, &pks);
+ pr_debug("%s() = %d\n", __func__, ret);
+ return ret;
+}
+
int asymmetric_verify_v3(struct key *keyring, const char *sig, int siglen,
const char *data, int datalen, u8 algo)
{
struct signature_v2_hdr *hdr = (struct signature_v2_hdr *)sig;
struct ima_max_digest_data hash;
+ const struct public_key *pk;
+ struct key *key;
int rc;
- rc = calc_file_id_hash(hdr->type, algo, data, &hash);
- if (rc)
- return -EINVAL;
+ if (siglen <= sizeof(*hdr))
+ return -EBADMSG;
+
+ key = request_asymmetric_key(keyring, be32_to_cpu(hdr->keyid));
+ if (IS_ERR(key))
+ return PTR_ERR(key);
- return asymmetric_verify(keyring, sig, siglen, hash.digest,
- hash.hdr.length);
+ pk = asymmetric_key_public_key(key);
+ if (!strncmp(pk->pkey_algo, "mldsa", 5)) {
+ rc = asymmetric_verify_v3_hashless(key, pk, "raw",
+ sig, siglen, algo, data);
+ } else {
+ rc = calc_file_id_hash(hdr->type, algo, data, &hash);
+ if (rc) {
+ rc = -EINVAL;
+ goto err_exit;
+ }
+
+ rc = asymmetric_verify_common(key, pk, sig, siglen, hash.digest,
+ hash.hdr.length);
+ }
+
+err_exit:
+ key_put(key);
+
+ return rc;
}
--
2.53.0
^ permalink raw reply related
* [PATCH v2 1/2] integrity: Refactor asymmetric_verify for reusability
From: Stefan Berger @ 2026-04-08 17:41 UTC (permalink / raw)
To: linux-integrity, linux-security-module
Cc: linux-kernel, zohar, roberto.sassu, ebiggers, Stefan Berger
In-Reply-To: <20260408174154.139606-1-stefanb@linux.ibm.com>
Refactor asymmetric_verify for reusability. Have it call
asymmetric_verify_common with the signature verification key and the
public_key structure as parameters. sigv3 support for ML-DSA will need to
check the public key type first to decide how to do the signature
verification and therefore will have these parameters available for
calling asymmetric_verify_common.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
---
security/integrity/digsig_asymmetric.c | 42 +++++++++++++++++---------
1 file changed, 28 insertions(+), 14 deletions(-)
diff --git a/security/integrity/digsig_asymmetric.c b/security/integrity/digsig_asymmetric.c
index 6e68ec3becbd..e29ed73f15cd 100644
--- a/security/integrity/digsig_asymmetric.c
+++ b/security/integrity/digsig_asymmetric.c
@@ -79,18 +79,15 @@ static struct key *request_asymmetric_key(struct key *keyring, uint32_t keyid)
return key;
}
-int asymmetric_verify(struct key *keyring, const char *sig,
- int siglen, const char *data, int datalen)
+static int asymmetric_verify_common(const struct key *key,
+ const struct public_key *pk,
+ const char *sig, int siglen,
+ const char *data, int datalen)
{
- struct public_key_signature pks;
struct signature_v2_hdr *hdr = (struct signature_v2_hdr *)sig;
- const struct public_key *pk;
- struct key *key;
+ struct public_key_signature pks;
int ret;
- if (siglen <= sizeof(*hdr))
- return -EBADMSG;
-
siglen -= sizeof(*hdr);
if (siglen != be16_to_cpu(hdr->sig_size))
@@ -99,15 +96,10 @@ int asymmetric_verify(struct key *keyring, const char *sig,
if (hdr->hash_algo >= HASH_ALGO__LAST)
return -ENOPKG;
- key = request_asymmetric_key(keyring, be32_to_cpu(hdr->keyid));
- if (IS_ERR(key))
- return PTR_ERR(key);
-
memset(&pks, 0, sizeof(pks));
pks.hash_algo = hash_algo_name[hdr->hash_algo];
- pk = asymmetric_key_public_key(key);
pks.pkey_algo = pk->pkey_algo;
if (!strcmp(pk->pkey_algo, "rsa")) {
pks.encoding = "pkcs1";
@@ -127,11 +119,33 @@ int asymmetric_verify(struct key *keyring, const char *sig,
pks.s_size = siglen;
ret = verify_signature(key, &pks);
out:
- key_put(key);
pr_debug("%s() = %d\n", __func__, ret);
return ret;
}
+int asymmetric_verify(struct key *keyring, const char *sig,
+ int siglen, const char *data, int datalen)
+{
+ struct signature_v2_hdr *hdr = (struct signature_v2_hdr *)sig;
+ const struct public_key *pk;
+ struct key *key;
+ int ret;
+
+ if (siglen <= sizeof(*hdr))
+ return -EBADMSG;
+
+ key = request_asymmetric_key(keyring, be32_to_cpu(hdr->keyid));
+ if (IS_ERR(key))
+ return PTR_ERR(key);
+ pk = asymmetric_key_public_key(key);
+
+ ret = asymmetric_verify_common(key, pk, sig, siglen, data, datalen);
+
+ key_put(key);
+
+ return ret;
+}
+
/*
* calc_file_id_hash - calculate the hash of the ima_file_id struct data
* @type: xattr type [enum evm_ima_xattr_type]
--
2.53.0
^ permalink raw reply related
* Re: [PATCH 1/3] crypto: public_key: Remove check for valid hash_algo for ML-DSA keys
From: Stefan Berger @ 2026-04-08 17:25 UTC (permalink / raw)
To: Eric Biggers
Cc: linux-integrity, linux-security-module, linux-kernel, zohar,
roberto.sassu, David Howells, Lukas Wunner, Ignat Korchagin,
keyrings, linux-crypto
In-Reply-To: <20260406165350.GD2971@sol>
On 4/6/26 12:53 PM, Eric Biggers wrote:
> On Sun, Apr 05, 2026 at 07:12:22PM -0400, Stefan Berger wrote:
>> Remove the check for the hash_algo since ML-DSA is only used in pure mode
>> and there is no relevance of a hash_algo for the input data.
>>
>> Cc: David Howells <dhowells@redhat.com>
>> Cc: Lukas Wunner <lukas@wunner.de>
>> Cc: Ignat Korchagin <ignat@linux.win>
>> Cc: keyrings@vger.kernel.org
>> Cc: linux-crypto@vger.kernel.org
>> Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
>> ---
>> crypto/asymmetric_keys/public_key.c | 5 -----
>> 1 file changed, 5 deletions(-)
>>
>> diff --git a/crypto/asymmetric_keys/public_key.c b/crypto/asymmetric_keys/public_key.c
>> index 09a0b83d5d77..df6918a77ab8 100644
>> --- a/crypto/asymmetric_keys/public_key.c
>> +++ b/crypto/asymmetric_keys/public_key.c
>> @@ -147,11 +147,6 @@ software_key_determine_akcipher(const struct public_key *pkey,
>> strcmp(pkey->pkey_algo, "mldsa87") == 0) {
>> if (strcmp(encoding, "raw") != 0)
>> return -EINVAL;
>> - if (!hash_algo)
>> - return -EINVAL;
>> - if (strcmp(hash_algo, "none") != 0 &&
>> - strcmp(hash_algo, "sha512") != 0)
>> - return -EINVAL;
>
> Does this broaden which hash algorithms are accepted for CMS signatures
> that use ML-DSA and contain signed attributes?
Right... dropping this patch and using the "none" route now.
>
> - Eric
>
^ permalink raw reply
* Re: [PATCH] tpm2-sessions: Fix missing tpm_buf_destroy() in tpm2_read_public()
From: Paul Menzel @ 2026-04-08 17:01 UTC (permalink / raw)
To: Gunnar Kudrjavets
Cc: peterhuewe, jarkko, jgg, noodles, linux-integrity, linux-kernel,
Justinien Bouron
In-Reply-To: <20260408164359.24968-1-gunnarku@amazon.com>
Dear Gunnar,
Thank you for your patch.
Am 08.04.26 um 18:43 schrieb Gunnar Kudrjavets:
> tpm2_read_public() calls tpm_buf_init() but fails to call
> tpm_buf_destroy() on two exit paths, leaking a page allocation:
>
> 1. When name_size() returns an error (unrecognized hash algorithm),
> the function returns directly without destroying the buffer.
>
> 2. On the success path, the buffer is never destroyed before
> returning.
>
> All other error paths in the function correctly call
> tpm_buf_destroy() before returning.
>
> Fix both by adding the missing tpm_buf_destroy() calls.
>
> Fixes: bda1cbf73c6e ("tpm2-sessions: Fix tpm2_read_public range checks")
> Signed-off-by: Gunnar Kudrjavets <gunnarku@amazon.com>
> Reviewed-by: Justinien Bouron <jbouron@amazon.com>
> ---
> drivers/char/tpm/tpm2-sessions.c | 5 ++++-
> 1 file changed, 4 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/char/tpm/tpm2-sessions.c b/drivers/char/tpm/tpm2-sessions.c
> index 09df6353ef04..f7c6c043fef4 100644
> --- a/drivers/char/tpm/tpm2-sessions.c
> +++ b/drivers/char/tpm/tpm2-sessions.c
> @@ -203,8 +203,10 @@ static int tpm2_read_public(struct tpm_chip *chip, u32 handle, void *name)
> rc = tpm_buf_read_u16(&buf, &offset);
> name_size_alg = name_size(&buf.data[offset]);
>
> - if (name_size_alg < 0)
> + if (name_size_alg < 0) {
> + tpm_buf_destroy(&buf);
> return name_size_alg;
> + }
>
> if (rc != name_size_alg) {
> tpm_buf_destroy(&buf);
> @@ -217,6 +219,7 @@ static int tpm2_read_public(struct tpm_chip *chip, u32 handle, void *name)
> }
>
> memcpy(name, &buf.data[offset], rc);
> + tpm_buf_destroy(&buf);
> return name_size_alg;
> }
> #endif /* CONFIG_TCG_TPM2_HMAC */
>
> base-commit: 03e5553f5fb99cb47c315e167a604a9c69e6f724
Reviewed-by: Paul Menzel <pmenzel@molgen.mpg.de>
Kind regards,
Paul
^ permalink raw reply
* [PATCH] tpm2-sessions: Fix missing tpm_buf_destroy() in tpm2_read_public()
From: Gunnar Kudrjavets @ 2026-04-08 16:43 UTC (permalink / raw)
To: peterhuewe, jarkko
Cc: jgg, noodles, gunnarku, linux-integrity, linux-kernel,
Justinien Bouron
tpm2_read_public() calls tpm_buf_init() but fails to call
tpm_buf_destroy() on two exit paths, leaking a page allocation:
1. When name_size() returns an error (unrecognized hash algorithm),
the function returns directly without destroying the buffer.
2. On the success path, the buffer is never destroyed before
returning.
All other error paths in the function correctly call
tpm_buf_destroy() before returning.
Fix both by adding the missing tpm_buf_destroy() calls.
Fixes: bda1cbf73c6e ("tpm2-sessions: Fix tpm2_read_public range checks")
Signed-off-by: Gunnar Kudrjavets <gunnarku@amazon.com>
Reviewed-by: Justinien Bouron <jbouron@amazon.com>
---
drivers/char/tpm/tpm2-sessions.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/drivers/char/tpm/tpm2-sessions.c b/drivers/char/tpm/tpm2-sessions.c
index 09df6353ef04..f7c6c043fef4 100644
--- a/drivers/char/tpm/tpm2-sessions.c
+++ b/drivers/char/tpm/tpm2-sessions.c
@@ -203,8 +203,10 @@ static int tpm2_read_public(struct tpm_chip *chip, u32 handle, void *name)
rc = tpm_buf_read_u16(&buf, &offset);
name_size_alg = name_size(&buf.data[offset]);
- if (name_size_alg < 0)
+ if (name_size_alg < 0) {
+ tpm_buf_destroy(&buf);
return name_size_alg;
+ }
if (rc != name_size_alg) {
tpm_buf_destroy(&buf);
@@ -217,6 +219,7 @@ static int tpm2_read_public(struct tpm_chip *chip, u32 handle, void *name)
}
memcpy(name, &buf.data[offset], rc);
+ tpm_buf_destroy(&buf);
return name_size_alg;
}
#endif /* CONFIG_TCG_TPM2_HMAC */
base-commit: 03e5553f5fb99cb47c315e167a604a9c69e6f724
--
2.47.3
^ permalink raw reply related
* Re: [PATCH] tpm: Fix auth session leak in tpm2_get_random() error path
From: Jarkko Sakkinen @ 2026-04-08 9:00 UTC (permalink / raw)
To: Gunnar Kudrjavets
Cc: peterhuewe, jgg, noodles, linux-integrity, linux-kernel,
Justinien Bouron
In-Reply-To: <20260402181156.29396-1-gunnarku@amazon.com>
On Thu, Apr 02, 2026 at 06:11:39PM +0000, Gunnar Kudrjavets wrote:
> When tpm_buf_fill_hmac_session() fails inside the do-while loop in
> tpm2_get_random(), the function returns directly after destroying the
> buffer, without ending the auth session via tpm2_end_auth_session().
>
> This leaks the TPM auth session resource. All other error paths within
> the loop correctly reach the 'out' label which calls both
> tpm_buf_destroy() and tpm2_end_auth_session().
>
> Fix this by replacing the early return with a goto to the existing 'out'
> label, which already handles both cleanup operations. The redundant
> tpm_buf_destroy() call is removed since 'out' takes care of it.
>
> Fixes: 6e9722e9a7bf ("tpm2-sessions: Fix out of range indexing in name_size")
> Signed-off-by: Gunnar Kudrjavets <gunnarku@amazon.com>
> Reviewed-by: Justinien Bouron <jbouron@amazon.com>
> ---
> drivers/char/tpm/tpm2-cmd.c | 6 ++----
> 1 file changed, 2 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/char/tpm/tpm2-cmd.c b/drivers/char/tpm/tpm2-cmd.c
> index e00f668f8c84..b11e6fa8b740 100644
> --- a/drivers/char/tpm/tpm2-cmd.c
> +++ b/drivers/char/tpm/tpm2-cmd.c
> @@ -295,10 +295,8 @@ int tpm2_get_random(struct tpm_chip *chip, u8 *dest, size_t max)
> }
> tpm_buf_append_u16(&buf, num_bytes);
> err = tpm_buf_fill_hmac_session(chip, &buf);
> - if (err) {
> - tpm_buf_destroy(&buf);
> - return err;
> - }
> + if (err)
> + goto out;
>
> err = tpm_transmit_cmd(chip, &buf,
> offsetof(struct tpm2_get_random_out,
>
> base-commit: 7f2a32c0e87814f0e7852b17fa9f10321f882c36
> --
> 2.47.3
>
Reviewed-by: Jarkko Sakkinen <jarkko@kernel.org>
BR, Jarkko
^ permalink raw reply
* Re: [PATCH 4/4] tpm: Move TPM common base definitions to the command header
From: Jarkko Sakkinen @ 2026-04-08 8:45 UTC (permalink / raw)
To: Alec Brown
Cc: linux-kernel@vger.kernel.org, linux-integrity@vger.kernel.org,
peterhuewe@gmx.de, jarkko.sakkinen@iki.fi, jgg@ziepe.ca,
Ross Philipson, dpsmith@apertussolutions.com, Daniel Kiper,
Kanth Ghatraju, trenchboot-devel@googlegroups.com,
ardb@kernel.org
In-Reply-To: <IA1PR10MB68309FDA0D5450AB2FC0B5BFBC56A@IA1PR10MB6830.namprd10.prod.outlook.com>
On Thu, Mar 26, 2026 at 07:54:36PM +0000, Alec Brown wrote:
> On Mon, Mar 23, 2026 at 1:42 AM, Jarkko Sakkinen <jarkko@kernel.org> wrote:
> > On Tue, Mar 17, 2026 at 04:03:35PM +0000, Alec Brown wrote:
> > > From: Ross Philipson <ross.philipson@oracle.com>
> > >
> > > From: Ross Philipson <ross.philipson@oracle.com>
> > >
> > > These are top level definitions shared by both TPM 1 and 2 family
> > > chips. This includes core definitions like TPM localities, common
> > > crypto algorithm IDs, and the base TPM command header.
> > >
> > > Signed-off-by: Daniel P. Smith <dpsmith@apertussolutions.com>
> > > Signed-off-by: Ross Philipson <ross.philipson@oracle.com>
> > > Signed-off-by: Alec Brown <alec.r.brown@oracle.com>
> > > ---
> > > include/linux/tpm.h | 50 +--------------------
> > > include/linux/tpm_command.h | 89
> > > +++++++++++++++++++++++++++++++++++++
> > > 2 files changed, 90 insertions(+), 49 deletions(-)
> > >
> > > diff --git a/include/linux/tpm.h b/include/linux/tpm.h index
> > > 92957452f7a7..a282b7045a24 100644
> > > --- a/include/linux/tpm.h
> > > +++ b/include/linux/tpm.h
> > > @@ -27,49 +27,12 @@
> > >
> > > #include "tpm_command.h"
> > >
> > > -#define TPM_DIGEST_SIZE 20 /* Max TPM v1.2 PCR size */
> > > -
> > > -#define TPM2_MAX_DIGEST_SIZE SHA512_DIGEST_SIZE
> > > -#define TPM2_MAX_PCR_BANKS 8
> > > -
> > > struct tpm_chip;
> > > struct trusted_key_payload;
> > > struct trusted_key_options;
> > > /* opaque structure, holds auth session parameters like the session
> > > key */ struct tpm2_auth;
> > >
> > > -/* if you add a new hash to this, increment TPM_MAX_HASHES below */
> > > -enum tpm_algorithms {
> > > - TPM_ALG_ERROR = 0x0000,
> > > - TPM_ALG_SHA1 = 0x0004,
> > > - TPM_ALG_AES = 0x0006,
> > > - TPM_ALG_KEYEDHASH = 0x0008,
> > > - TPM_ALG_SHA256 = 0x000B,
> > > - TPM_ALG_SHA384 = 0x000C,
> > > - TPM_ALG_SHA512 = 0x000D,
> > > - TPM_ALG_NULL = 0x0010,
> > > - TPM_ALG_SM3_256 = 0x0012,
> > > - TPM_ALG_ECC = 0x0023,
> > > - TPM_ALG_CFB = 0x0043,
> > > -};
> > > -
> > > -/*
> > > - * maximum number of hashing algorithms a TPM can have. This is
> > > - * basically a count of every hash in tpm_algorithms above
> > > - */
> > > -#define TPM_MAX_HASHES 5
> > > -
> > > -struct tpm_digest {
> > > - u16 alg_id;
> > > - u8 digest[TPM2_MAX_DIGEST_SIZE];
> > > -} __packed;
> > > -
> > > -struct tpm_bank_info {
> > > - u16 alg_id;
> > > - u16 digest_size;
> > > - u16 crypto_id;
> > > -};
> > > -
> > > enum TPM_OPS_FLAGS {
> > > TPM_OPS_AUTO_STARTUP = BIT(0),
> > > };
> > > @@ -127,7 +90,7 @@ struct tpm_chip_seqops {
> > > const struct seq_operations *seqops; };
> > >
> > > -/* fixed define for the curve we use which is NIST_P256 */
> > > +/* Fixed define for the curve we use which is NIST_P256 */
> > > #define EC_PT_SZ 32
> > >
> > > /*
> > > @@ -209,8 +172,6 @@ struct tpm_chip {
> > > #endif
> > > };
> > >
> > > -#define TPM_HEADER_SIZE 10
> > > -
> > > static inline enum tpm2_mso_type tpm2_handle_mso(u32 handle) {
> > > return handle >> 24;
> > > @@ -239,15 +200,6 @@ enum tpm_chip_flags {
> > >
> > > #define to_tpm_chip(d) container_of(d, struct tpm_chip, dev)
> > >
> > > -struct tpm_header {
> > > - __be16 tag;
> > > - __be32 length;
> > > - union {
> > > - __be32 ordinal;
> > > - __be32 return_code;
> > > - };
> > > -} __packed;
> > > -
> > > enum tpm_buf_flags {
> > > /* the capacity exceeded: */
> > > TPM_BUF_OVERFLOW = BIT(0),
> > > diff --git a/include/linux/tpm_command.h b/include/linux/tpm_command.h
> > > index ee76fcd5ecef..25a247254140 100644
> > > --- a/include/linux/tpm_command.h
> > > +++ b/include/linux/tpm_command.h
> > > @@ -431,4 +431,93 @@ struct tpm2_context {
> > > __be16 blob_size;
> > > } __packed;
> > >
> > > +/************************************************/
> > > +/* TPM Common Defs */
> > > +/************************************************/
One nit I just noticed here: let's use kernel standard block comments.
E.g.
/*
* Common definitions for TPM.
*/
> > > +
> > > +#define TPM_DIGEST_SIZE 20 /* Max TPM v1.2 PCR size */
> > > +#define TPM_BUFSIZE 4096
> > > +
> > > +/*
> > > + * SHA-512 is, as of today, the largest digest in the TCG algorithm repository.
> > > + */
> > > +#define TPM2_MAX_DIGEST_SIZE SHA512_DIGEST_SIZE
> > > +
> > > +/*
> > > + * A TPM name digest i.e., TPMT_HA, is a concatenation of TPM_ALG_ID
> > > +of the
> > > + * name algorithm and hash of TPMT_PUBLIC.
> > > + */
> > > +#define TPM2_MAX_NAME_SIZE (TPM2_MAX_DIGEST_SIZE + 2)
> > > +
> > > +/*
> > > + * Fixed define for the size of a name. This is actually HASHALG
> > > +size
> > > + * plus 2, so 32 for SHA256
> > > + */
> > > +#define TPM2_NULL_NAME_SIZE 34
> > > +
> > > +/*
> > > + * The maximum number of PCR banks.
> > > + */
> > > +#define TPM2_MAX_PCR_BANKS 8
> > > +
> > > +/* If you add a new hash to this, increment TPM_MAX_HASHES below */
> > > +enum tpm_algorithms {
> > > + TPM_ALG_ERROR = 0x0000,
> > > + TPM_ALG_SHA1 = 0x0004,
> > > + TPM_ALG_AES = 0x0006,
> > > + TPM_ALG_KEYEDHASH = 0x0008,
> > > + TPM_ALG_SHA256 = 0x000B,
> > > + TPM_ALG_SHA384 = 0x000C,
> > > + TPM_ALG_SHA512 = 0x000D,
> > > + TPM_ALG_NULL = 0x0010,
> > > + TPM_ALG_SM3_256 = 0x0012,
> > > + TPM_ALG_ECC = 0x0023,
> > > + TPM_ALG_CFB = 0x0043,
> > > +};
> > > +
> > > +/*
> > > + * The locality (0 - 4) for a TPM, as defined in section 3.2 of the
> > > + * Client Platform Profile Specification.
> > > + */
> > > +enum tpm_localities {
> > > + TPM_LOCALITY_0 = 0, /* Static RTM */
> > > + TPM_LOCALITY_1 = 1, /* Dynamic OS */
> > > + TPM_LOCALITY_2 = 2, /* DRTM Environment */
> > > + TPM_LOCALITY_3 = 3, /* Aux Components */
> > > + TPM_LOCALITY_4 = 4, /* CPU DRTM Establishment */
> > > + TPM_MAX_LOCALITY = TPM_LOCALITY_4
> > > +};
> > > +
> > > +/*
> > > + * Structure to represent active PCR algorithm banks usable by the
> > > + * TPM chip.
> > > + */
> > > +struct tpm_bank_info {
> > > + u16 alg_id;
> > > + u16 digest_size;
> > > + u16 crypto_id;
> > > +};
> > > +
> > > +/*
> > > + * Maximum number of hashing algorithms a TPM can have. This is
> > > + * basically a count of every hash in tpm_algorithms above */
> > > +#define TPM_MAX_HASHES 5
> > > +
> > > +struct tpm_digest {
> > > + u16 alg_id;
> > > + u8 digest[TPM2_MAX_DIGEST_SIZE];
> > > +} __packed;
> > > +
> > > +#define TPM_HEADER_SIZE 10
> > > +
> > > +struct tpm_header {
> > > + __be16 tag;
> > > + __be32 length;
> > > + union {
> > > + __be32 ordinal;
> > > + __be32 return_code;
> > > + };
> > > +} __packed;
> > > +
> > > #endif
> > > --
> > > 2.47.3
> > >
> >
> > Yep, all looks great and clean to me but exactly for that reason
> > this needs to the truth serum :-)
> >
> > BR, Jarkko
>
> Thanks for taking a look! Glad to hear the patches are looking good!
>
> Alec Brown
BR, Jarkko
^ permalink raw reply
* Re: [PATCH v3] tpm: i2c: atmel: fix block comment formatting
From: Jarkko Sakkinen @ 2026-04-08 8:38 UTC (permalink / raw)
To: Ethan Luna
Cc: peterhuewe, jgg, nicolas.ferre, claudiu.beznea, linux-integrity,
linux-arm-kernel, linux-kernel
In-Reply-To: <20260324154354.6268-1-trunixcodes@zohomail.com>
On Tue, Mar 24, 2026 at 08:39:49AM -0700, Ethan Luna wrote:
> Multiple block comments in tpm_i2c_atmel.c placed the closing '*/' on the
> same line as the comment text. This violates the kernel's preferred
> comment style, which requires the closing delimiter to appear on its
> line.
>
> Fix the formatting to improve readability and resolve checkpatch
> warnings.
>
> Signed-off-by: Ethan Luna <trunixcodes@zohomail.com>
> ---
>
> V1 -> V2: Fixed block comment formatting consistently across all multi-line comments
> V2 -> V3: Fixed trailing whitespaces consistently across all multi-line comments
>
> v1: https://lore.kernel.org/all/20260322193112.27010-1-trunixcodes@zohomail.com/
> v2: https://lore.kernel.org/all/20260323134200.7766-1-trunixcodes@zohomail.com/
>
> drivers/char/tpm/tpm_i2c_atmel.c | 34 +++++++++++++++++++++-----------
> 1 file changed, 23 insertions(+), 11 deletions(-)
>
> diff --git a/drivers/char/tpm/tpm_i2c_atmel.c b/drivers/char/tpm/tpm_i2c_atmel.c
> index 4f229656a8e2..9fd73049821f 100644
> --- a/drivers/char/tpm/tpm_i2c_atmel.c
> +++ b/drivers/char/tpm/tpm_i2c_atmel.c
> @@ -31,9 +31,11 @@
>
> struct priv_data {
> size_t len;
> - /* This is the amount we read on the first try. 25 was chosen to fit a
> + /*
> + * This is the amount we read on the first try. 25 was chosen to fit a
> * fair number of read responses in the buffer so a 2nd retry can be
> - * avoided in small message cases. */
> + * avoided in small message cases.
> + */
> u8 buffer[sizeof(struct tpm_header) + 25];
> };
>
> @@ -58,7 +60,9 @@ static int i2c_atmel_send(struct tpm_chip *chip, u8 *buf, size_t bufsiz,
> if (status < 0)
> return status;
>
> - /* The upper layer does not support incomplete sends. */
> + /*
> + * The upper layer does not support incomplete sends.
> + */
> if (status != len)
> return -E2BIG;
>
> @@ -76,9 +80,11 @@ static int i2c_atmel_recv(struct tpm_chip *chip, u8 *buf, size_t count)
> if (priv->len == 0)
> return -EIO;
>
> - /* Get the message size from the message header, if we didn't get the
> + /*
> + * Get the message size from the message header, if we didn't get the
> * whole message in read_status then we need to re-read the
> - * message. */
> + * message.
> + */
> expected_len = be32_to_cpu(hdr->length);
> if (expected_len > count)
> return -ENOMEM;
> @@ -111,15 +117,19 @@ static u8 i2c_atmel_read_status(struct tpm_chip *chip)
> struct i2c_client *client = to_i2c_client(chip->dev.parent);
> int rc;
>
> - /* The TPM fails the I2C read until it is ready, so we do the entire
> + /*
> + * The TPM fails the I2C read until it is ready, so we do the entire
> * transfer here and buffer it locally. This way the common code can
> - * properly handle the timeouts. */
> + * properly handle the timeouts.
> + */
> priv->len = 0;
> memset(priv->buffer, 0, sizeof(priv->buffer));
>
>
> - /* Once the TPM has completed the command the command remains readable
> - * until another command is issued. */
> + /*
> + * Once the TPM has completed the command the command remains readable
> + * until another command is issued.
> + */
> rc = i2c_master_recv(client, priv->buffer, sizeof(priv->buffer));
> dev_dbg(&chip->dev,
> "%s: sts=%d", __func__, rc);
> @@ -172,9 +182,11 @@ static int i2c_atmel_probe(struct i2c_client *client)
>
> dev_set_drvdata(&chip->dev, priv);
>
> - /* There is no known way to probe for this device, and all version
> + /*
> + * There is no known way to probe for this device, and all version
> * information seems to be read via TPM commands. Thus we rely on the
> - * TPM startup process in the common code to detect the device. */
> + * TPM startup process in the common code to detect the device.
> + */
>
> return tpm_chip_register(chip);
> }
> --
> 2.53.0
>
Thank you.
Reviewed-by: Jarkko Sakkinen <jarkko@kernel.org>
Applied.
BR, Jarkko
^ permalink raw reply
* Re: [RFC 2/4] tpm_crb: Add new wrapper function to invoke start method
From: Jarkko Sakkinen @ 2026-04-08 8:36 UTC (permalink / raw)
To: Arun Menon; +Cc: linux-kernel, linux-integrity, Jason Gunthorpe, Peter Huewe
In-Reply-To: <acKG6EQ_tXO8eqfj@fedora>
On Tue, Mar 24, 2026 at 06:13:20PM +0530, Arun Menon wrote:
>
> On Tue, Mar 24, 2026 at 12:42:19PM +0200, Jarkko Sakkinen wrote:
> > On Tue, Mar 24, 2026 at 12:48:01PM +0530, Arun Menon wrote:
> > > - Extract start invocation code into a separate function called
> > > crb_trigger_tpm. This will be helpful in repeatedly calling the
> > > start method with different bits set to toggle between start,
> > > nextChunk or crbRspRetry behaviours.
> > > - Based on the bit set, we signal the TPM to consume
> > > contents of the command/response buffer.
> > > - No functional change intended.
> >
> > Please write a proper commit message, which is not a task list.
>
> Yes, I shall do that. Thank you for taking a look.
Yeah, and now is good time to improve cosmetic details like this.
I rather take closer look at code when I can run it as I'm not LLM
coding agent, I need to run to understand cannot hallucinate it :-)
BR, Jarkko
^ permalink raw reply
* Re: [RFC 0/4] tpm_crb: Add command and response buffer chunking support
From: Jarkko Sakkinen @ 2026-04-08 8:34 UTC (permalink / raw)
To: Arun Menon; +Cc: linux-kernel, linux-integrity, Jason Gunthorpe, Peter Huewe
In-Reply-To: <acKGZ33ItHvMkQ_5@fedora>
On Tue, Mar 24, 2026 at 06:11:11PM +0530, Arun Menon wrote:
> Hi Jarkko,
>
> On Tue, Mar 24, 2026 at 12:41:26PM +0200, Jarkko Sakkinen wrote:
> > On Tue, Mar 24, 2026 at 12:47:59PM +0530, Arun Menon wrote:
> > > The new version of TCG TPM v185 (currently under review [1]) supports
> > > sending data/commands in chunks for the CRB (Command Response Buffer)
> > > interface. This is in line with the initiative to support PQC algorithms.
> > >
> > > This series implements the logic to send and receive larger TPM
> > > cmd/rsp between the linux guest and the TPM backend in chunks.
> > > Currently, the TPM CRB driver is limited by the physical size of the
> > > MMIO window. When userspace attempts to send a payload that exceeds this
> > > size, the driver rejects it.
> > >
> > > This series introduces chunking support. The driver now checks the CRB
> > > interface capability for CRB_INTF_CAP_CRB_CHUNK. If supported by the
> > > backend, the driver will slice oversized commands into MMIO-sized
> > > chunks, signalling the backend via CRB_START_NEXT_CHUNK, and finalizing
> > > with CRB_START_INVOKE. Responses are also read back in a similar chunked
> > > manner.
> > >
> > > If the backend does not support chunking, the driver retains its legacy
> > > behaviour and enforces the standard size limits.
> > >
> > > This feature also requires the QEMU to interpret the data in chunks and
> > > forward it to the TPM backend and subsequently dispatch the TPM response
> > > in chunks back to the linux guest. This is implemented in [2]
> > >
> > > [1] https://trustedcomputinggroup.org/wp-content/uploads/PC-Client-Specific-Platform-TPM-Profile-for-TPM-2p0-v1p07_rc1_121225.pdf
> > > [2] https://lore.kernel.org/qemu-devel/20260319135316.37412-1-armenon@redhat.com/
> > >
> > > Arun Menon (4):
> > > tpm_crb: Add definition of TPM CRB chunking fields
> > > tpm_crb: Add new wrapper function to invoke start method
> > > tpm_crb: Implement command and response chunking logic
> > > tpm: Increase TPM_BUFSIZE to 64kB for chunking support
> > >
> > > drivers/char/tpm/tpm.h | 2 +-
> > > drivers/char/tpm/tpm_crb.c | 194 ++++++++++++++++++++++++++-----------
> > > 2 files changed, 137 insertions(+), 59 deletions(-)
> > >
> > > --
> > > 2.53.0
> > >
> >
> > When QEMU has the feature available?
>
> The QEMU patches are in review at the moment,
> here is the link: https://lore.kernel.org/qemu-devel/20260319135316.37412-1-armenon@redhat.com/
> Hoping to have them merged soon.
Right, and additional question: what about swtpm?
For both, to give detailed review, good enough is their main branch
(i.e. as long as upstream accepts them I can use them).
>
> >
> > BR, Jarkko
> >
>
> Regards,
> Arun Menon
>
BR, Jarkko
^ permalink raw reply
* Re: [PATCH v2] KEYS: trusted: Debugging as a feature
From: Jarkko Sakkinen @ 2026-04-08 8:29 UTC (permalink / raw)
To: Nayna Jain
Cc: linux-integrity, keyrings, Srish Srinivasan, James Bottomley,
Mimi Zohar, David Howells, Paul Moore, James Morris,
Serge E. Hallyn, Ahmad Fatoum, Pengutronix Kernel Team, open list,
open list:SECURITY SUBSYSTEM
In-Reply-To: <adYRURAJfNCu0FYB@kernel.org>
On Wed, Apr 08, 2026 at 11:27:01AM +0300, Jarkko Sakkinen wrote:
> On Mon, Apr 06, 2026 at 10:42:00PM -0400, Nayna Jain wrote:
> >
> > On 3/24/26 7:00 AM, Jarkko Sakkinen wrote:
> > > TPM_DEBUG, and other similar flags, are a non-standard way to specify a
> > > feature in Linux kernel. Introduce CONFIG_TRUSTED_KEYS_DEBUG for
> > > trusted keys, and use it to replace these ad-hoc feature flags.
> > >
> > > Given that trusted keys debug dumps can contain sensitive data, harden
> > > the feature as follows:
> > >
> > > 1. In the Kconfig description postulate that pr_debug() statements must be
> > > used.
> > > 2. Use pr_debug() statements in TPM 1.x driver to print the protocol dump.
> > >
> > > Traces, when actually needed, can be easily enabled by providing
> > > trusted.dyndbg='+p' in the kernel command-line.
> > >
> > > Cc: Srish Srinivasan <ssrish@linux.ibm.com>
> > > Reported-by: Nayna Jain <nayna@linux.ibm.com>
> > > Closes: https://lore.kernel.org/all/7f8b8478-5cd8-4d97-bfd0-341fd5cf10f9@linux.ibm.com/
> > > Signed-off-by: Jarkko Sakkinen <jarkko@kernel.org>
> > > ---
> > > v2:
> > > - Implement for all trusted keys backends.
> > > - Add HAVE_TRUSTED_KEYS_DEBUG as it is a good practice despite full
> > > coverage.
> > > ---
> > > include/keys/trusted-type.h | 18 +++++-------
> > > security/keys/trusted-keys/Kconfig | 19 ++++++++++++
> > > security/keys/trusted-keys/trusted_caam.c | 4 +--
> > > security/keys/trusted-keys/trusted_tpm1.c | 36 +++++++++++------------
> > > 4 files changed, 46 insertions(+), 31 deletions(-)
> > >
> > > diff --git a/include/keys/trusted-type.h b/include/keys/trusted-type.h
> > > index 03527162613f..620a1f890b6b 100644
> > > --- a/include/keys/trusted-type.h
> > > +++ b/include/keys/trusted-type.h
> > > @@ -83,18 +83,16 @@ struct trusted_key_source {
> > > extern struct key_type key_type_trusted;
> > > -#define TRUSTED_DEBUG 0
> > > -
> > > -#if TRUSTED_DEBUG
> > > +#ifdef CONFIG_TRUSTED_KEYS_DEBUG
> > > static inline void dump_payload(struct trusted_key_payload *p)
> > > {
> > > - pr_info("key_len %d\n", p->key_len);
> > > - print_hex_dump(KERN_INFO, "key ", DUMP_PREFIX_NONE,
> > > - 16, 1, p->key, p->key_len, 0);
> > > - pr_info("bloblen %d\n", p->blob_len);
> > > - print_hex_dump(KERN_INFO, "blob ", DUMP_PREFIX_NONE,
> > > - 16, 1, p->blob, p->blob_len, 0);
> > > - pr_info("migratable %d\n", p->migratable);
> > > + pr_debug("key_len %d\n", p->key_len);
> > > + print_hex_dump_debug("key ", DUMP_PREFIX_NONE,
> > > + 16, 1, p->key, p->key_len, 0);
> > > + pr_debug("bloblen %d\n", p->blob_len);
> > > + print_hex_dump_debug("blob ", DUMP_PREFIX_NONE,
> > > + 16, 1, p->blob, p->blob_len, 0);
> > > + pr_debug("migratable %d\n", p->migratable);
> > > }
> > > #else
> > > static inline void dump_payload(struct trusted_key_payload *p)
> > > diff --git a/security/keys/trusted-keys/Kconfig b/security/keys/trusted-keys/Kconfig
> > > index 9e00482d886a..2ad9ba0e03f1 100644
> > > --- a/security/keys/trusted-keys/Kconfig
> > > +++ b/security/keys/trusted-keys/Kconfig
> > > @@ -1,10 +1,25 @@
> > > config HAVE_TRUSTED_KEYS
> > > bool
> > > +config HAVE_TRUSTED_KEYS_DEBUG
> > > + bool
> > > +
> > > +config TRUSTED_KEYS_DEBUG
> > > + bool "Debug trusted keys"
> > > + depends on HAVE_TRUSTED_KEYS_DEBUG
> > > + default n
> > > + help
> > > + Trusted keys backends and core code that support debug dumps
> > > + can opt-in that feature here. Dumps must only use DEBUG
> > > + level output, as sensitive data may pass by. In the
> > > + kernel-command line traces can be enabled via
> > > + trusted.dyndbg='+p'.
> >
> > Would it be good idea to add an explicit note/warning:
> >
> >
> > NOTE: This option is intended for debugging purposes only. Do not enable on
> > production systems as debug output may expose sensitive cryptographic
> > material.
> > If you are unsure, say N.
> >
> > Apart from this, looks good to me.
> >
> > Reviewed-by: Nayna Jain <nayna@linux.ibm.com>
>
> Thank, I'll add your tag but would you mind quickly screening v3 again
> where I add "trusted.debug=0|1". And yes, your suggestion about extra
> warning makes sense.
>
> Let's make this safe as possible. Mistakes do happen... and then those
> measures pay off :-)
E.g., in 2026 world perfectly realistic scenario is "agentic devops
team" (unfortunately), which might debug trusted keys issue, and leave
debug flag on. Thus, both warning you suggested and also boot option
for good measure do actually leverage risks involved.
BR, Jarkko
^ permalink raw reply
* Re: [PATCH v2] KEYS: trusted: Debugging as a feature
From: Jarkko Sakkinen @ 2026-04-08 8:26 UTC (permalink / raw)
To: Nayna Jain
Cc: linux-integrity, keyrings, Srish Srinivasan, James Bottomley,
Mimi Zohar, David Howells, Paul Moore, James Morris,
Serge E. Hallyn, Ahmad Fatoum, Pengutronix Kernel Team, open list,
open list:SECURITY SUBSYSTEM
In-Reply-To: <afc489d2-a62f-4604-8e56-219311b46516@linux.ibm.com>
On Mon, Apr 06, 2026 at 10:42:00PM -0400, Nayna Jain wrote:
>
> On 3/24/26 7:00 AM, Jarkko Sakkinen wrote:
> > TPM_DEBUG, and other similar flags, are a non-standard way to specify a
> > feature in Linux kernel. Introduce CONFIG_TRUSTED_KEYS_DEBUG for
> > trusted keys, and use it to replace these ad-hoc feature flags.
> >
> > Given that trusted keys debug dumps can contain sensitive data, harden
> > the feature as follows:
> >
> > 1. In the Kconfig description postulate that pr_debug() statements must be
> > used.
> > 2. Use pr_debug() statements in TPM 1.x driver to print the protocol dump.
> >
> > Traces, when actually needed, can be easily enabled by providing
> > trusted.dyndbg='+p' in the kernel command-line.
> >
> > Cc: Srish Srinivasan <ssrish@linux.ibm.com>
> > Reported-by: Nayna Jain <nayna@linux.ibm.com>
> > Closes: https://lore.kernel.org/all/7f8b8478-5cd8-4d97-bfd0-341fd5cf10f9@linux.ibm.com/
> > Signed-off-by: Jarkko Sakkinen <jarkko@kernel.org>
> > ---
> > v2:
> > - Implement for all trusted keys backends.
> > - Add HAVE_TRUSTED_KEYS_DEBUG as it is a good practice despite full
> > coverage.
> > ---
> > include/keys/trusted-type.h | 18 +++++-------
> > security/keys/trusted-keys/Kconfig | 19 ++++++++++++
> > security/keys/trusted-keys/trusted_caam.c | 4 +--
> > security/keys/trusted-keys/trusted_tpm1.c | 36 +++++++++++------------
> > 4 files changed, 46 insertions(+), 31 deletions(-)
> >
> > diff --git a/include/keys/trusted-type.h b/include/keys/trusted-type.h
> > index 03527162613f..620a1f890b6b 100644
> > --- a/include/keys/trusted-type.h
> > +++ b/include/keys/trusted-type.h
> > @@ -83,18 +83,16 @@ struct trusted_key_source {
> > extern struct key_type key_type_trusted;
> > -#define TRUSTED_DEBUG 0
> > -
> > -#if TRUSTED_DEBUG
> > +#ifdef CONFIG_TRUSTED_KEYS_DEBUG
> > static inline void dump_payload(struct trusted_key_payload *p)
> > {
> > - pr_info("key_len %d\n", p->key_len);
> > - print_hex_dump(KERN_INFO, "key ", DUMP_PREFIX_NONE,
> > - 16, 1, p->key, p->key_len, 0);
> > - pr_info("bloblen %d\n", p->blob_len);
> > - print_hex_dump(KERN_INFO, "blob ", DUMP_PREFIX_NONE,
> > - 16, 1, p->blob, p->blob_len, 0);
> > - pr_info("migratable %d\n", p->migratable);
> > + pr_debug("key_len %d\n", p->key_len);
> > + print_hex_dump_debug("key ", DUMP_PREFIX_NONE,
> > + 16, 1, p->key, p->key_len, 0);
> > + pr_debug("bloblen %d\n", p->blob_len);
> > + print_hex_dump_debug("blob ", DUMP_PREFIX_NONE,
> > + 16, 1, p->blob, p->blob_len, 0);
> > + pr_debug("migratable %d\n", p->migratable);
> > }
> > #else
> > static inline void dump_payload(struct trusted_key_payload *p)
> > diff --git a/security/keys/trusted-keys/Kconfig b/security/keys/trusted-keys/Kconfig
> > index 9e00482d886a..2ad9ba0e03f1 100644
> > --- a/security/keys/trusted-keys/Kconfig
> > +++ b/security/keys/trusted-keys/Kconfig
> > @@ -1,10 +1,25 @@
> > config HAVE_TRUSTED_KEYS
> > bool
> > +config HAVE_TRUSTED_KEYS_DEBUG
> > + bool
> > +
> > +config TRUSTED_KEYS_DEBUG
> > + bool "Debug trusted keys"
> > + depends on HAVE_TRUSTED_KEYS_DEBUG
> > + default n
> > + help
> > + Trusted keys backends and core code that support debug dumps
> > + can opt-in that feature here. Dumps must only use DEBUG
> > + level output, as sensitive data may pass by. In the
> > + kernel-command line traces can be enabled via
> > + trusted.dyndbg='+p'.
>
> Would it be good idea to add an explicit note/warning:
>
>
> NOTE: This option is intended for debugging purposes only. Do not enable on
> production systems as debug output may expose sensitive cryptographic
> material.
> If you are unsure, say N.
>
> Apart from this, looks good to me.
>
> Reviewed-by: Nayna Jain <nayna@linux.ibm.com>
Thank, I'll add your tag but would you mind quickly screening v3 again
where I add "trusted.debug=0|1". And yes, your suggestion about extra
warning makes sense.
Let's make this safe as possible. Mistakes do happen... and then those
measures pay off :-)
BR, Jarkko
^ permalink raw reply
* Re: [PATCH v2] KEYS: trusted: Debugging as a feature
From: Jarkko Sakkinen @ 2026-04-08 8:24 UTC (permalink / raw)
To: Srish Srinivasan
Cc: linux-integrity, keyrings, Nayna Jain, James Bottomley,
Mimi Zohar, David Howells, Paul Moore, James Morris,
Serge E. Hallyn, Ahmad Fatoum, Pengutronix Kernel Team, open list,
open list:SECURITY SUBSYSTEM
In-Reply-To: <0ce8d850-9ca7-4327-a6be-d1cb84925915@linux.ibm.com>
On Thu, Mar 26, 2026 at 10:34:58PM +0530, Srish Srinivasan wrote:
>
> On 3/24/26 4:30 PM, Jarkko Sakkinen wrote:
> > TPM_DEBUG, and other similar flags, are a non-standard way to specify a
> > feature in Linux kernel. Introduce CONFIG_TRUSTED_KEYS_DEBUG for
> > trusted keys, and use it to replace these ad-hoc feature flags.
> >
> > Given that trusted keys debug dumps can contain sensitive data, harden
> > the feature as follows:
> >
> > 1. In the Kconfig description postulate that pr_debug() statements must be
> > used.
> > 2. Use pr_debug() statements in TPM 1.x driver to print the protocol dump.
> >
> > Traces, when actually needed, can be easily enabled by providing
> > trusted.dyndbg='+p' in the kernel command-line.
> >
> > Cc: Srish Srinivasan <ssrish@linux.ibm.com>
> > Reported-by: Nayna Jain <nayna@linux.ibm.com>
> > Closes: https://lore.kernel.org/all/7f8b8478-5cd8-4d97-bfd0-341fd5cf10f9@linux.ibm.com/
> > Signed-off-by: Jarkko Sakkinen <jarkko@kernel.org>
>
>
> Tested on PKWM and emulated TPM backends.
>
> Tested-by: Srish Srinivasan <ssrish@linux.ibm.com>
Thank you!
As it is uprised as a feature (like it should as ad-hoc compilation
flags are harmful), this also requires a boot flag so that "I know
what I'm doing" is addressed.
I'll send one more round with a flag 'trusted.debug=0|1'. These extra
steps protect production kernels for reasonable measure.
BR, Jarkko
^ permalink raw reply
* Re: [PATCH v5 2/3] ima: trim N IMA event log records
From: Roberto Sassu @ 2026-04-07 16:19 UTC (permalink / raw)
To: steven chen, linux-integrity
Cc: zohar, roberto.sassu, dmitry.kasatkin, eric.snowberg, corbet,
serge, paul, jmorris, linux-security-module, anirudhve,
gregorylumen, nramas, sushring, linux-doc
In-Reply-To: <20260401172956.4581-3-chenste@linux.microsoft.com>
On Wed, 2026-04-01 at 10:29 -0700, steven chen wrote:
> Trim N entries of the IMA event logs. Do not clean the hash table.
The very first change of this patch is the kernel option
ima_flush_htable option that I introduced for my use case.
At the bottom of this patch you actually check the ima_flush_htable
boolean, and delete the measurements entries without disconnecting them
from the hash table, so the digest lookup is done on freed memory.
Next, you duplicated my changes regarding the measurements list
counter. But instead of removing the old counter from the hash table,
you keep incrementing both, but use the new one.
In ima_log_trim_open(), you use again my duplicated code to manage
exclusive write/concurrent read scheme for the measurement interfaces.
However, for read, if the process does not have CAP_SYS_ADMIN it falls
back calling _ima_measurements_open(). Not sure it was intended.
And, in ima_log_trim_release(), you check again CAP_SYS_ADMIN which is
redundant, you would not reach this code if the same requirements were
not met at open time. You also return an error on close().
In ima_log_trim_write(), you do manual string to number conversion for
your first number and use kstrtoul() for the second.
The measurements lists and the associated counter are atomically
updated in ima_add_digest_entry(), but not atomically accessed in
ima_delete_event_log(). Also, the measurements list is traversed
without _rcu variant or lock.
While this trimming scheme aims at minimizing the kernel space and user
space delay, it also introduces the following problem. If two agents
perform a TPM quote that include a different number of entries, there
is no guarantee that the one willing to trim less entries wins. Which
means that, one agent could end up not seeing the most recent entries,
as they were already trimmed by the other agent.
My solution is not affected by this problem, since there will be only
one process collecting all the measurements in user space and exposing
them to the agents.
Also, I didn't understand why T and ima_measure_users have to be
preserved on soft reboots. Especially ima_measure_users reflects the
state of open files for a particular kernel, but on soft reboot a new
kernel is booted.
I personally will not endorse a solution based on the ima_trim_log
interface. I could accept trimming N even more efficiently than we
currently do with a lockless walk to determine the cutting position in
ima_queue_stage(), so that we don't need to splice back entries to the
measurement list. This would be a replacement of patch 11 in my patch
set, but this would be as far as I would like to go.
Roberto
> The values saved in hash table were already used.
>
> Provide a userspace interface ima_trim_log:
> When read this interface, it returns total number T of entries trimmed
> since system boot up.
> When write to this interface need to provide two numbers T:N to let
> kernel to trim N entries of IMA event logs.
>
> Kernel measurement list lock time performance improvement by not
> clean the hash table.
>
> when kernel get log trim request T:N
> - Get the T, compare with the total trimmed number
> - if equal, then do trim N and change T to T+N
> - else return error
>
> Signed-off-by: steven chen <chenste@linux.microsoft.com>
> ---
> .../admin-guide/kernel-parameters.txt | 4 +
> security/integrity/ima/ima.h | 4 +-
> security/integrity/ima/ima_fs.c | 198 +++++++++++++++++-
> security/integrity/ima/ima_kexec.c | 2 +-
> security/integrity/ima/ima_queue.c | 96 +++++++++
> 5 files changed, 296 insertions(+), 8 deletions(-)
>
> diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt
> index e92c0056e4e0..cd1a1d0bf0e2 100644
> --- a/Documentation/admin-guide/kernel-parameters.txt
> +++ b/Documentation/admin-guide/kernel-parameters.txt
> @@ -2197,6 +2197,10 @@
> Use the canonical format for the binary runtime
> measurements, instead of host native format.
>
> + ima_flush_htable [IMA]
> + Flush the measurement list hash table when trim all
> + or a part of it for deletion.
> +
> ima_hash= [IMA]
> Format: { md5 | sha1 | rmd160 | sha256 | sha384
> | sha512 | ... }
> diff --git a/security/integrity/ima/ima.h b/security/integrity/ima/ima.h
> index e3d71d8d56e3..5cbee3a295a0 100644
> --- a/security/integrity/ima/ima.h
> +++ b/security/integrity/ima/ima.h
> @@ -243,11 +243,13 @@ void ima_post_key_create_or_update(struct key *keyring, struct key *key,
> const void *payload, size_t plen,
> unsigned long flags, bool create);
> #endif
> -
> +extern atomic_long_t ima_number_entries;
> #ifdef CONFIG_IMA_KEXEC
> void ima_measure_kexec_event(const char *event_name);
> +long ima_delete_event_log(long req_val);
> #else
> static inline void ima_measure_kexec_event(const char *event_name) {}
> +static inline long ima_delete_event_log(long req_val) { return 0; }
> #endif
>
> /*
> diff --git a/security/integrity/ima/ima_fs.c b/security/integrity/ima/ima_fs.c
> index 87045b09f120..8e26e0f34311 100644
> --- a/security/integrity/ima/ima_fs.c
> +++ b/security/integrity/ima/ima_fs.c
> @@ -21,6 +21,9 @@
> #include <linux/rcupdate.h>
> #include <linux/parser.h>
> #include <linux/vmalloc.h>
> +#include <linux/ktime.h>
> +#include <linux/timekeeping.h>
> +#include <linux/ima.h>
>
> #include "ima.h"
>
> @@ -38,6 +41,17 @@ __setup("ima_canonical_fmt", default_canonical_fmt_setup);
>
> static int valid_policy = 1;
>
> +#define IMA_LOG_TRIM_REQ_NUM_LENGTH 15
> +#define IMA_LOG_TRIM_REQ_TOTAL_LENGTH 32
> +atomic_long_t ima_number_entries = ATOMIC_LONG_INIT(0);
> +static long trimcount;
> +/* mutex protects atomicity of trimming measurement list
> + * and also protects atomicity the measurement list read
> + * write operation.
> + */
> +static DEFINE_MUTEX(ima_measure_lock);
> +static long ima_measure_users;
> +
> static ssize_t ima_show_htable_value(char __user *buf, size_t count,
> loff_t *ppos, atomic_long_t *val)
> {
> @@ -64,8 +78,7 @@ static ssize_t ima_show_measurements_count(struct file *filp,
> char __user *buf,
> size_t count, loff_t *ppos)
> {
> - return ima_show_htable_value(buf, count, ppos, &ima_htable.len);
> -
> + return ima_show_htable_value(buf, count, ppos, &ima_number_entries);
> }
>
> static const struct file_operations ima_measurements_count_ops = {
> @@ -202,16 +215,77 @@ static const struct seq_operations ima_measurments_seqops = {
> .show = ima_measurements_show
> };
>
> +/*
> + * _ima_measurements_open - open the IMA measurements file
> + * @inode: inode of the file being opened
> + * @file: file being opened
> + * @seq_ops: sequence operations for the file
> + *
> + * Returns 0 on success, or negative error code.
> + * Implements mutual exclusion between readers and writer
> + * of the measurements file. Multiple readers are allowed,
> + * but writer get exclusive access only no other readers/writers.
> + * Readers is not allowed when there is a writer.
> + */
> +static int _ima_measurements_open(struct inode *inode, struct file *file,
> + const struct seq_operations *seq_ops)
> +{
> + bool write = !!(file->f_mode & FMODE_WRITE);
> + int ret;
> +
> + if (write && !capable(CAP_SYS_ADMIN))
> + return -EPERM;
> +
> + mutex_lock(&ima_measure_lock);
> + if ((write && ima_measure_users != 0) ||
> + (!write && ima_measure_users < 0)) {
> + mutex_unlock(&ima_measure_lock);
> + return -EBUSY;
> + }
> +
> + ret = seq_open(file, seq_ops);
> + if (ret < 0) {
> + mutex_unlock(&ima_measure_lock);
> + return ret;
> + }
> +
> + if (write)
> + ima_measure_users--;
> + else
> + ima_measure_users++;
> +
> + mutex_unlock(&ima_measure_lock);
> + return ret;
> +}
> +
> static int ima_measurements_open(struct inode *inode, struct file *file)
> {
> - return seq_open(file, &ima_measurments_seqops);
> + return _ima_measurements_open(inode, file, &ima_measurments_seqops);
> +}
> +
> +static int ima_measurements_release(struct inode *inode, struct file *file)
> +{
> + bool write = !!(file->f_mode & FMODE_WRITE);
> + int ret;
> +
> + mutex_lock(&ima_measure_lock);
> + ret = seq_release(inode, file);
> + if (!ret) {
> + if (!write)
> + ima_measure_users--;
> + else
> + ima_measure_users++;
> + }
> +
> + mutex_unlock(&ima_measure_lock);
> + return ret;
> }
>
> static const struct file_operations ima_measurements_ops = {
> .open = ima_measurements_open,
> .read = seq_read,
> .llseek = seq_lseek,
> - .release = seq_release,
> + .release = ima_measurements_release,
> };
>
> void ima_print_digest(struct seq_file *m, u8 *digest, u32 size)
> @@ -279,14 +353,114 @@ static const struct seq_operations ima_ascii_measurements_seqops = {
>
> static int ima_ascii_measurements_open(struct inode *inode, struct file *file)
> {
> - return seq_open(file, &ima_ascii_measurements_seqops);
> + return _ima_measurements_open(inode, file, &ima_ascii_measurements_seqops);
> }
>
> static const struct file_operations ima_ascii_measurements_ops = {
> .open = ima_ascii_measurements_open,
> .read = seq_read,
> .llseek = seq_lseek,
> - .release = seq_release,
> + .release = ima_measurements_release,
> +};
> +
> +static int ima_log_trim_open(struct inode *inode, struct file *file)
> +{
> + bool write = !!(file->f_mode & FMODE_WRITE);
> +
> + if (!write && capable(CAP_SYS_ADMIN))
> + return 0;
> + else if (!capable(CAP_SYS_ADMIN))
> + return -EPERM;
> +
> + return _ima_measurements_open(inode, file, &ima_measurments_seqops);
> +}
> +
> +static ssize_t ima_log_trim_read(struct file *file, char __user *buf, size_t size, loff_t *ppos)
> +{
> + char tmpbuf[IMA_LOG_TRIM_REQ_NUM_LENGTH];
> + ssize_t len;
> +
> + len = scnprintf(tmpbuf, sizeof(tmpbuf), "%li\n", trimcount);
> + return simple_read_from_buffer(buf, size, ppos, tmpbuf, len);
> +}
> +
> +static ssize_t ima_log_trim_write(struct file *file,
> + const char __user *buf, size_t datalen, loff_t *ppos)
> +{
> + char tmpbuf[IMA_LOG_TRIM_REQ_TOTAL_LENGTH];
> + char *p = tmpbuf;
> + long count, ret, val = 0, max = LONG_MAX;
> +
> + if (*ppos > 0 || datalen > IMA_LOG_TRIM_REQ_TOTAL_LENGTH || datalen < 2) {
> + ret = -EINVAL;
> + goto out;
> + }
> +
> + if (copy_from_user(tmpbuf, buf, datalen) != 0) {
> + ret = -EFAULT;
> + goto out;
> + }
> +
> + p = tmpbuf;
> +
> + while (*p && *p != ':') {
> + if (!isdigit((unsigned char)*p))
> + return -EINVAL;
> +
> + /* digit value */
> + int d = *p - '0';
> +
> + /* overflow check: val * 10 + d > max -> (val > (max - d) / 10) */
> + if (val > (max - d) / 10)
> + return -ERANGE;
> +
> + val = val * 10 + d;
> + p++;
> + }
> +
> + if (*p != ':')
> + return -EINVAL;
> +
> + /* verify trim count matches */
> + if (val != trimcount)
> + return -EINVAL;
> +
> + p++; /* skip ':' */
> + ret = kstrtoul(p, 0, &count);
> +
> + if (ret < 0)
> + goto out;
> +
> + ret = ima_delete_event_log(count);
> +
> + if (ret < 0)
> + goto out;
> +
> + trimcount += ret;
> +
> + ret = datalen;
> +out:
> + return ret;
> +}
> +
> +static int ima_log_trim_release(struct inode *inode, struct file *file)
> +{
> + bool write = !!(file->f_mode & FMODE_WRITE);
> +
> + if (!write && capable(CAP_SYS_ADMIN))
> + return 0;
> + else if (!capable(CAP_SYS_ADMIN))
> + return -EPERM;
> +
> + return ima_measurements_release(inode, file);
> +}
> +
> +static const struct file_operations ima_log_trim_ops = {
> + .open = ima_log_trim_open,
> + .read = ima_log_trim_read,
> + .write = ima_log_trim_write,
> + .llseek = generic_file_llseek,
> + .release = ima_log_trim_release
> };
>
> static ssize_t ima_read_policy(char *path)
> @@ -528,6 +702,18 @@ int __init ima_fs_init(void)
> goto out;
> }
>
> + if (IS_ENABLED(CONFIG_IMA_LOG_TRIMMING)) {
> + dentry = securityfs_create_file("ima_trim_log",
> + S_IRUSR | S_IRGRP | S_IWUSR | S_IWGRP,
> + ima_dir, NULL, &ima_log_trim_ops);
> + if (IS_ERR(dentry)) {
> + ret = PTR_ERR(dentry);
> + goto out;
> + }
> + }
> +
> + trimcount = 0;
> +
> dentry = securityfs_create_file("runtime_measurements_count",
> S_IRUSR | S_IRGRP, ima_dir, NULL,
> &ima_measurements_count_ops);
> diff --git a/security/integrity/ima/ima_kexec.c b/security/integrity/ima/ima_kexec.c
> index 7362f68f2d8b..bee997683e03 100644
> --- a/security/integrity/ima/ima_kexec.c
> +++ b/security/integrity/ima/ima_kexec.c
> @@ -41,7 +41,7 @@ void ima_measure_kexec_event(const char *event_name)
> int n;
>
> buf_size = ima_get_binary_runtime_size();
> - len = atomic_long_read(&ima_htable.len);
> + len = atomic_long_read(&ima_number_entries);
>
> n = scnprintf(ima_kexec_event, IMA_KEXEC_EVENT_LEN,
> "kexec_segment_size=%lu;ima_binary_runtime_size=%lu;"
> diff --git a/security/integrity/ima/ima_queue.c b/security/integrity/ima/ima_queue.c
> index 590637e81ad1..07225e19b9b5 100644
> --- a/security/integrity/ima/ima_queue.c
> +++ b/security/integrity/ima/ima_queue.c
> @@ -22,6 +22,14 @@
>
> #define AUDIT_CAUSE_LEN_MAX 32
>
> +bool ima_flush_htable;
> +static int __init ima_flush_htable_setup(char *str)
> +{
> + ima_flush_htable = true;
> + return 1;
> +}
> +__setup("ima_flush_htable", ima_flush_htable_setup);
> +
> /* pre-allocated array of tpm_digest structures to extend a PCR */
> static struct tpm_digest *digests;
>
> @@ -114,6 +122,7 @@ static int ima_add_digest_entry(struct ima_template_entry *entry,
> list_add_tail_rcu(&qe->later, &ima_measurements);
>
> atomic_long_inc(&ima_htable.len);
> + atomic_long_inc(&ima_number_entries);
> if (update_htable) {
> key = ima_hash_key(entry->digests[ima_hash_algo_idx].digest);
> hlist_add_head_rcu(&qe->hnext, &ima_htable.queue[key]);
> @@ -220,6 +229,93 @@ int ima_add_template_entry(struct ima_template_entry *entry, int violation,
> return result;
> }
>
> +/**
> + * ima_delete_event_log - delete IMA event entry
> + * @num_records: number of records to delete
> + *
> + * delete num_records entries off the measurement list.
> + * Returns num_records, or negative error code.
> + */
> +long ima_delete_event_log(long num_records)
> +{
> + long len, cur = num_records, tmp_len = 0;
> + struct ima_queue_entry *qe, *qe_tmp;
> + LIST_HEAD(ima_measurements_to_delete);
> + struct list_head *list_ptr;
> +
> + if (!IS_ENABLED(CONFIG_IMA_LOG_TRIMMING))
> + return -EOPNOTSUPP;
> +
> + if (num_records <= 0)
> + return num_records;
> +
> + list_ptr = &ima_measurements;
> +
> + len = atomic_long_read(&ima_number_entries);
> +
> + if (num_records <= len) {
> + list_for_each_entry(qe, list_ptr, later) {
> + if (cur > 0) {
> + tmp_len += get_binary_runtime_size(qe->entry);
> + --cur;
> + }
> + if (cur == 0) {
> + qe_tmp = qe;
> + break;
> + }
> + }
> + }
> + else {
> + return -ENOENT;
> + }
> +
> +
> + mutex_lock(&ima_extend_list_mutex);
> + len = atomic_long_read(&ima_number_entries);
> +
> + if (num_records == len) {
> + list_replace(&ima_measurements, &ima_measurements_to_delete);
> + INIT_LIST_HEAD(&ima_measurements);
> + atomic_long_set(&ima_number_entries, 0);
> + list_ptr = &ima_measurements_to_delete;
> + }
> + else {
> + __list_cut_position(&ima_measurements_to_delete, &ima_measurements,
> + &qe_tmp->later);
> + atomic_long_sub(num_records, &ima_number_entries);
> + if (IS_ENABLED(CONFIG_IMA_KEXEC))
> + binary_runtime_size -= tmp_len;
> + }
> +
> + mutex_unlock(&ima_extend_list_mutex);
> +
> + if (ima_flush_htable)
> + synchronize_rcu();
> +
> + list_for_each_entry_safe(qe, qe_tmp, &ima_measurements_to_delete, later) {
> + /*
> + * Ok because after list delete qe is only accessed by
> + * ima_lookup_digest_entry().
> + */
> + for (int i = 0; i < qe->entry->template_desc->num_fields; i++) {
> + kfree(qe->entry->template_data[i].data);
> + qe->entry->template_data[i].data = NULL;
> + qe->entry->template_data[i].len = 0;
> + }
> +
> + list_del(&qe->later);
> +
> + /* No leak if !ima_flush_htable, referenced by ima_htable. */
> + if (ima_flush_htable) {
> + kfree(qe->entry->digests);
> + kfree(qe->entry);
> + kfree(qe);
> + }
> + }
> +
> + return num_records;
> +}
> +
> int ima_restore_measurement_entry(struct ima_template_entry *entry)
> {
> int result = 0;
^ permalink raw reply
* [PATCH] evm: zero-initialize the evm_xattrs read buffer
From: Pengpeng Hou @ 2026-04-07 6:09 UTC (permalink / raw)
To: Mimi Zohar, Roberto Sassu
Cc: Dmitry Kasatkin, Eric Snowberg, Paul Moore, James Morris,
Serge Hallyn, linux-integrity, linux-security-module,
linux-kernel, pengpeng
evm_read_xattrs() allocates size + 1 bytes, fills them from the list of
enabled xattrs and then passes strlen(temp) to simple_read_from_buffer().
When no configured xattrs are enabled, the fill loop stores nothing and
temp[0] remains uninitialized, so strlen() reads beyond initialized
memory.
Use kzalloc() so the empty-list case stays a valid empty C string.
Signed-off-by: Pengpeng Hou <pengpeng@iscas.ac.cn>
---
security/integrity/evm/evm_secfs.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/security/integrity/evm/evm_secfs.c b/security/integrity/evm/evm_secfs.c
index acd840461902..03d376fa36c2 100644
--- a/security/integrity/evm/evm_secfs.c
+++ b/security/integrity/evm/evm_secfs.c
@@ -145,7 +145,7 @@ static ssize_t evm_read_xattrs(struct file *filp, char __user *buf,
size += strlen(xattr->name) + 1;
}
- temp = kmalloc(size + 1, GFP_KERNEL);
+ temp = kzalloc(size + 1, GFP_KERNEL);
if (!temp) {
mutex_unlock(&xattr_list_mutex);
return -ENOMEM;
--
2.50.1 (Apple Git-155)
^ permalink raw reply related
* Re: [PATCH v2] KEYS: trusted: Debugging as a feature
From: Nayna Jain @ 2026-04-07 2:42 UTC (permalink / raw)
To: Jarkko Sakkinen, linux-integrity
Cc: keyrings, Srish Srinivasan, James Bottomley, Mimi Zohar,
David Howells, Paul Moore, James Morris, Serge E. Hallyn,
Ahmad Fatoum, Pengutronix Kernel Team, open list,
open list:SECURITY SUBSYSTEM
In-Reply-To: <20260324110043.67248-1-jarkko@kernel.org>
On 3/24/26 7:00 AM, Jarkko Sakkinen wrote:
> TPM_DEBUG, and other similar flags, are a non-standard way to specify a
> feature in Linux kernel. Introduce CONFIG_TRUSTED_KEYS_DEBUG for
> trusted keys, and use it to replace these ad-hoc feature flags.
>
> Given that trusted keys debug dumps can contain sensitive data, harden
> the feature as follows:
>
> 1. In the Kconfig description postulate that pr_debug() statements must be
> used.
> 2. Use pr_debug() statements in TPM 1.x driver to print the protocol dump.
>
> Traces, when actually needed, can be easily enabled by providing
> trusted.dyndbg='+p' in the kernel command-line.
>
> Cc: Srish Srinivasan <ssrish@linux.ibm.com>
> Reported-by: Nayna Jain <nayna@linux.ibm.com>
> Closes: https://lore.kernel.org/all/7f8b8478-5cd8-4d97-bfd0-341fd5cf10f9@linux.ibm.com/
> Signed-off-by: Jarkko Sakkinen <jarkko@kernel.org>
> ---
> v2:
> - Implement for all trusted keys backends.
> - Add HAVE_TRUSTED_KEYS_DEBUG as it is a good practice despite full
> coverage.
> ---
> include/keys/trusted-type.h | 18 +++++-------
> security/keys/trusted-keys/Kconfig | 19 ++++++++++++
> security/keys/trusted-keys/trusted_caam.c | 4 +--
> security/keys/trusted-keys/trusted_tpm1.c | 36 +++++++++++------------
> 4 files changed, 46 insertions(+), 31 deletions(-)
>
> diff --git a/include/keys/trusted-type.h b/include/keys/trusted-type.h
> index 03527162613f..620a1f890b6b 100644
> --- a/include/keys/trusted-type.h
> +++ b/include/keys/trusted-type.h
> @@ -83,18 +83,16 @@ struct trusted_key_source {
>
> extern struct key_type key_type_trusted;
>
> -#define TRUSTED_DEBUG 0
> -
> -#if TRUSTED_DEBUG
> +#ifdef CONFIG_TRUSTED_KEYS_DEBUG
> static inline void dump_payload(struct trusted_key_payload *p)
> {
> - pr_info("key_len %d\n", p->key_len);
> - print_hex_dump(KERN_INFO, "key ", DUMP_PREFIX_NONE,
> - 16, 1, p->key, p->key_len, 0);
> - pr_info("bloblen %d\n", p->blob_len);
> - print_hex_dump(KERN_INFO, "blob ", DUMP_PREFIX_NONE,
> - 16, 1, p->blob, p->blob_len, 0);
> - pr_info("migratable %d\n", p->migratable);
> + pr_debug("key_len %d\n", p->key_len);
> + print_hex_dump_debug("key ", DUMP_PREFIX_NONE,
> + 16, 1, p->key, p->key_len, 0);
> + pr_debug("bloblen %d\n", p->blob_len);
> + print_hex_dump_debug("blob ", DUMP_PREFIX_NONE,
> + 16, 1, p->blob, p->blob_len, 0);
> + pr_debug("migratable %d\n", p->migratable);
> }
> #else
> static inline void dump_payload(struct trusted_key_payload *p)
> diff --git a/security/keys/trusted-keys/Kconfig b/security/keys/trusted-keys/Kconfig
> index 9e00482d886a..2ad9ba0e03f1 100644
> --- a/security/keys/trusted-keys/Kconfig
> +++ b/security/keys/trusted-keys/Kconfig
> @@ -1,10 +1,25 @@
> config HAVE_TRUSTED_KEYS
> bool
>
> +config HAVE_TRUSTED_KEYS_DEBUG
> + bool
> +
> +config TRUSTED_KEYS_DEBUG
> + bool "Debug trusted keys"
> + depends on HAVE_TRUSTED_KEYS_DEBUG
> + default n
> + help
> + Trusted keys backends and core code that support debug dumps
> + can opt-in that feature here. Dumps must only use DEBUG
> + level output, as sensitive data may pass by. In the
> + kernel-command line traces can be enabled via
> + trusted.dyndbg='+p'.
Would it be good idea to add an explicit note/warning:
NOTE: This option is intended for debugging purposes only. Do not enable
on production systems as debug output may expose sensitive cryptographic
material.
If you are unsure, say N.
Apart from this, looks good to me.
Reviewed-by: Nayna Jain <nayna@linux.ibm.com>
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox