Linux Integrity Measurement development
 help / color / mirror / Atom feed
* [PATCH v2 0/2] vfs: follow-on fixes for i_ino widening
From: Jeff Layton @ 2026-03-13 18:44 UTC (permalink / raw)
  To: Ryusuke Konishi, Viacheslav Dubeyko, Christian Brauner,
	Mimi Zohar, Roberto Sassu, Dmitry Kasatkin, Eric Snowberg,
	Paul Moore, James Morris, Serge E. Hallyn
  Cc: linux-nilfs, linux-kernel, linux-integrity, linux-security-module,
	Jeff Layton, kernel test robot

Just some patches to fix follow-on issues reported after the
inode->i_ino widening series. Christian, could you toss these
onto the vfs-7.1.kino branch?

Signed-off-by: Jeff Layton <jlayton@kernel.org>
---
Changes in v2:
- rename variable in nilfs2 patch from "rem" to "index"
- reword comment and commit log for better accuracy in EVM patch

---
Jeff Layton (2):
      nilfs2: fix 64-bit division operations in nilfs_bmap_find_target_in_group()
      EVM: add comment describing why ino field is still unsigned long

 fs/nilfs2/bmap.c                    | 9 ++++++---
 security/integrity/evm/evm_crypto.c | 6 ++++++
 2 files changed, 12 insertions(+), 3 deletions(-)
---
base-commit: 9840bb66e7e5dffd72b03201318f154a10b06b4a
change-id: 20260310-iino-u64-424fa570d850

Best regards,
-- 
Jeff Layton <jlayton@kernel.org>


^ permalink raw reply

* [PATCH v2 0/2] vfs: follow-on fixes for i_ino widening
From: Jeff Layton @ 2026-03-13 18:45 UTC (permalink / raw)
  To: Ryusuke Konishi, Viacheslav Dubeyko, Christian Brauner,
	Mimi Zohar, Roberto Sassu, Dmitry Kasatkin, Eric Snowberg,
	Paul Moore, James Morris, Serge E. Hallyn
  Cc: linux-nilfs, linux-kernel, linux-integrity, linux-security-module,
	linux-fsdevel, Jeff Layton, kernel test robot

Just some patches to fix follow-on issues reported after the
inode->i_ino widening series. Christian, could you toss these
onto the vfs-7.1.kino branch?

Signed-off-by: Jeff Layton <jlayton@kernel.org>
---
Changes in v2:
- rename variable in nilfs2 patch from "rem" to "index"
- reword comment and commit log for better accuracy in EVM patch

---
Jeff Layton (2):
      nilfs2: fix 64-bit division operations in nilfs_bmap_find_target_in_group()
      EVM: add comment describing why ino field is still unsigned long

 fs/nilfs2/bmap.c                    | 9 ++++++---
 security/integrity/evm/evm_crypto.c | 6 ++++++
 2 files changed, 12 insertions(+), 3 deletions(-)
---
base-commit: 9840bb66e7e5dffd72b03201318f154a10b06b4a
change-id: 20260310-iino-u64-424fa570d850

Best regards,
-- 
Jeff Layton <jlayton@kernel.org>


^ permalink raw reply

* [PATCH v2 1/2] nilfs2: fix 64-bit division operations in nilfs_bmap_find_target_in_group()
From: Jeff Layton @ 2026-03-13 18:45 UTC (permalink / raw)
  To: Ryusuke Konishi, Viacheslav Dubeyko, Christian Brauner,
	Mimi Zohar, Roberto Sassu, Dmitry Kasatkin, Eric Snowberg,
	Paul Moore, James Morris, Serge E. Hallyn
  Cc: linux-nilfs, linux-kernel, linux-integrity, linux-security-module,
	linux-fsdevel, Jeff Layton, kernel test robot
In-Reply-To: <20260313-iino-u64-v2-0-f9abda2464d5@kernel.org>

With the change to make inode->i_ino a u64, the build started failing on
32-bit ARM with:

    ERROR: modpost: "__aeabi_uldivmod" [fs/nilfs2/nilfs2.ko] undefined!

Fix this by using the 64-bit division interfaces in
nilfs_bmap_find_target_in_group().

Fixes: 998a59d371c2 ("treewide: fix missed i_ino format specifier conversions")
Reported-by: kernel test robot <lkp@intel.com>
Closes: https://lore.kernel.org/oe-kbuild-all/202603100602.KPxiClIO-lkp@intel.com/
Reviewed-by: Viacheslav Dubeyko <slava@dubeyko.com>
Acked-by: Ryusuke Konishi <konishi.ryusuke@gmail.com>
Signed-off-by: Jeff Layton <jlayton@kernel.org>
---
 fs/nilfs2/bmap.c | 9 ++++++---
 1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/fs/nilfs2/bmap.c b/fs/nilfs2/bmap.c
index 824f2bd91c167965ec3a660202b6e6c5f1fe007e..abcf5252578ad24f694bfccf525893674bfcb4bc 100644
--- a/fs/nilfs2/bmap.c
+++ b/fs/nilfs2/bmap.c
@@ -455,11 +455,14 @@ __u64 nilfs_bmap_find_target_in_group(const struct nilfs_bmap *bmap)
 {
 	struct inode *dat = nilfs_bmap_get_dat(bmap);
 	unsigned long entries_per_group = nilfs_palloc_entries_per_group(dat);
-	unsigned long group = bmap->b_inode->i_ino / entries_per_group;
+	unsigned long group;
+	u32 index;
+
+	group = div_u64(bmap->b_inode->i_ino, entries_per_group);
+	div_u64_rem(bmap->b_inode->i_ino, NILFS_BMAP_GROUP_DIV, &index);
 
 	return group * entries_per_group +
-		(bmap->b_inode->i_ino % NILFS_BMAP_GROUP_DIV) *
-		(entries_per_group / NILFS_BMAP_GROUP_DIV);
+	       index * (entries_per_group / NILFS_BMAP_GROUP_DIV);
 }
 
 static struct lock_class_key nilfs_bmap_dat_lock_key;

-- 
2.53.0


^ permalink raw reply related

* [PATCH v2 2/2] EVM: add comment describing why ino field is still unsigned long
From: Jeff Layton @ 2026-03-13 18:45 UTC (permalink / raw)
  To: Ryusuke Konishi, Viacheslav Dubeyko, Christian Brauner,
	Mimi Zohar, Roberto Sassu, Dmitry Kasatkin, Eric Snowberg,
	Paul Moore, James Morris, Serge E. Hallyn
  Cc: linux-nilfs, linux-kernel, linux-integrity, linux-security-module,
	linux-fsdevel, Jeff Layton
In-Reply-To: <20260313-iino-u64-v2-0-f9abda2464d5@kernel.org>

Mimi pointed out that we didn't widen the inode number field in struct
h_misc alongside the inode->i_ino widening. While we could make an
equivalent change there, that would require EVM resigning on all 32-bit
hosts.

Instead, leave the field as an unsigned long. This should have no effect
on 64-bit hosts, and allow things to continue working on 32-bit hosts in
the cases where the i_ino fits in 32-bits.

Add a comment explaining why it's being left as unsigned long.

Cc: Mimi Zohar <zohar@linux.ibm.com>
Signed-off-by: Jeff Layton <jlayton@kernel.org>
---
 security/integrity/evm/evm_crypto.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/security/integrity/evm/evm_crypto.c b/security/integrity/evm/evm_crypto.c
index c0ca4eedb0fe5d5c30f45f515a4bc90248ec64ea..1c41af2f91a60a714878ff93b554c90e45546503 100644
--- a/security/integrity/evm/evm_crypto.c
+++ b/security/integrity/evm/evm_crypto.c
@@ -144,6 +144,12 @@ static void hmac_add_misc(struct shash_desc *desc, struct inode *inode,
 			  char type, char *digest)
 {
 	struct h_misc {
+		/*
+		 * Although inode->i_ino is now u64, this field remains
+		 * unsigned long to allow existing HMAC and signatures from
+		 * 32-bit hosts to continue working when i_ino hasn't changed
+		 * and fits in a u32.
+		 */
 		unsigned long ino;
 		__u32 generation;
 		uid_t uid;

-- 
2.53.0


^ permalink raw reply related

* Re: [PATCH v2 2/2] EVM: add comment describing why ino field is still unsigned long
From: Mimi Zohar @ 2026-03-13 19:50 UTC (permalink / raw)
  To: Jeff Layton, Ryusuke Konishi, Viacheslav Dubeyko,
	Christian Brauner, Roberto Sassu, Dmitry Kasatkin, Eric Snowberg,
	Paul Moore, James Morris, Serge E. Hallyn
  Cc: linux-nilfs, linux-kernel, linux-integrity, linux-security-module,
	linux-fsdevel
In-Reply-To: <20260313-iino-u64-v2-2-f9abda2464d5@kernel.org>

On Fri, 2026-03-13 at 14:45 -0400, Jeff Layton wrote:
> Mimi pointed out that we didn't widen the inode number field in struct
> h_misc alongside the inode->i_ino widening. While we could make an
> equivalent change there, that would require EVM resigning on all 32-bit
> hosts.
> 
> Instead, leave the field as an unsigned long. This should have no effect
> on 64-bit hosts, and allow things to continue working on 32-bit hosts in
> the cases where the i_ino fits in 32-bits.
> 
> Add a comment explaining why it's being left as unsigned long.
> 
> Cc: Mimi Zohar <zohar@linux.ibm.com>
> Signed-off-by: Jeff Layton <jlayton@kernel.org>

Thanks, Jeff.

Reviewed-by: Mimi Zohar <zohar@linux.ibm.com>


> ---
>  security/integrity/evm/evm_crypto.c | 6 ++++++
>  1 file changed, 6 insertions(+)
> 
> diff --git a/security/integrity/evm/evm_crypto.c b/security/integrity/evm/evm_crypto.c
> index c0ca4eedb0fe5d5c30f45f515a4bc90248ec64ea..1c41af2f91a60a714878ff93b554c90e45546503 100644
> --- a/security/integrity/evm/evm_crypto.c
> +++ b/security/integrity/evm/evm_crypto.c
> @@ -144,6 +144,12 @@ static void hmac_add_misc(struct shash_desc *desc, struct inode *inode,
>  			  char type, char *digest)
>  {
>  	struct h_misc {
> +		/*
> +		 * Although inode->i_ino is now u64, this field remains
> +		 * unsigned long to allow existing HMAC and signatures from
> +		 * 32-bit hosts to continue working when i_ino hasn't changed
> +		 * and fits in a u32.
> +		 */
>  		unsigned long ino;
>  		__u32 generation;
>  		uid_t uid;

^ permalink raw reply

* Re: [PATCH v2 1/2] nilfs2: fix 64-bit division operations in nilfs_bmap_find_target_in_group()
From: David Laight @ 2026-03-14 12:47 UTC (permalink / raw)
  To: Jeff Layton
  Cc: Ryusuke Konishi, Viacheslav Dubeyko, Christian Brauner,
	Mimi Zohar, Roberto Sassu, Dmitry Kasatkin, Eric Snowberg,
	Paul Moore, James Morris, Serge E. Hallyn, linux-nilfs,
	linux-kernel, linux-integrity, linux-security-module,
	linux-fsdevel, kernel test robot
In-Reply-To: <20260313-iino-u64-v2-1-f9abda2464d5@kernel.org>

On Fri, 13 Mar 2026 14:45:20 -0400
Jeff Layton <jlayton@kernel.org> wrote:

> With the change to make inode->i_ino a u64, the build started failing on
> 32-bit ARM with:
> 
>     ERROR: modpost: "__aeabi_uldivmod" [fs/nilfs2/nilfs2.ko] undefined!
> 
> Fix this by using the 64-bit division interfaces in
> nilfs_bmap_find_target_in_group().
> 
> Fixes: 998a59d371c2 ("treewide: fix missed i_ino format specifier conversions")
> Reported-by: kernel test robot <lkp@intel.com>
> Closes: https://lore.kernel.org/oe-kbuild-all/202603100602.KPxiClIO-lkp@intel.com/
> Reviewed-by: Viacheslav Dubeyko <slava@dubeyko.com>
> Acked-by: Ryusuke Konishi <konishi.ryusuke@gmail.com>
> Signed-off-by: Jeff Layton <jlayton@kernel.org>
> ---
>  fs/nilfs2/bmap.c | 9 ++++++---
>  1 file changed, 6 insertions(+), 3 deletions(-)
> 
> diff --git a/fs/nilfs2/bmap.c b/fs/nilfs2/bmap.c
> index 824f2bd91c167965ec3a660202b6e6c5f1fe007e..abcf5252578ad24f694bfccf525893674bfcb4bc 100644
> --- a/fs/nilfs2/bmap.c
> +++ b/fs/nilfs2/bmap.c
> @@ -455,11 +455,14 @@ __u64 nilfs_bmap_find_target_in_group(const struct nilfs_bmap *bmap)
>  {
>  	struct inode *dat = nilfs_bmap_get_dat(bmap);
>  	unsigned long entries_per_group = nilfs_palloc_entries_per_group(dat);
> -	unsigned long group = bmap->b_inode->i_ino / entries_per_group;

Are you sure entries_per_group can be more than 32 bits?
It looks like something that will be the same size on 32 and 64bit.

> +	unsigned long group;
> +	u32 index;
> +
> +	group = div_u64(bmap->b_inode->i_ino, entries_per_group);

You don't need the full 64 by 64 divide.
IIRC there are both div_u64_u32() and div_u64_ulong().

> +	div_u64_rem(bmap->b_inode->i_ino, NILFS_BMAP_GROUP_DIV, &index);

NILFD_BMAP_GROUP_DIV is 8 (and probably has to be a power of 2).
So:
	index = bmap->b_inode->i_ino & (NILFS_BMAP_GROUP_DIV - 1);
is the same and likely much faster to calculate.
(The compiler will have done that optimisation before.)

	David


>  
>  	return group * entries_per_group +
> -		(bmap->b_inode->i_ino % NILFS_BMAP_GROUP_DIV) *
> -		(entries_per_group / NILFS_BMAP_GROUP_DIV);
> +	       index * (entries_per_group / NILFS_BMAP_GROUP_DIV);
>  }
>  
>  static struct lock_class_key nilfs_bmap_dat_lock_key;
> 


^ permalink raw reply

* Re: [PATCH v2 1/2] nilfs2: fix 64-bit division operations in nilfs_bmap_find_target_in_group()
From: Jeff Layton @ 2026-03-14 12:59 UTC (permalink / raw)
  To: David Laight
  Cc: Ryusuke Konishi, Viacheslav Dubeyko, Christian Brauner,
	Mimi Zohar, Roberto Sassu, Dmitry Kasatkin, Eric Snowberg,
	Paul Moore, James Morris, Serge E. Hallyn, linux-nilfs,
	linux-kernel, linux-integrity, linux-security-module,
	linux-fsdevel, kernel test robot
In-Reply-To: <20260314124748.1ccdf93b@pumpkin>

On Sat, 2026-03-14 at 12:47 +0000, David Laight wrote:
> On Fri, 13 Mar 2026 14:45:20 -0400
> Jeff Layton <jlayton@kernel.org> wrote:
> 
> > With the change to make inode->i_ino a u64, the build started failing on
> > 32-bit ARM with:
> > 
> >     ERROR: modpost: "__aeabi_uldivmod" [fs/nilfs2/nilfs2.ko] undefined!
> > 
> > Fix this by using the 64-bit division interfaces in
> > nilfs_bmap_find_target_in_group().
> > 
> > Fixes: 998a59d371c2 ("treewide: fix missed i_ino format specifier conversions")
> > Reported-by: kernel test robot <lkp@intel.com>
> > Closes: https://lore.kernel.org/oe-kbuild-all/202603100602.KPxiClIO-lkp@intel.com/
> > Reviewed-by: Viacheslav Dubeyko <slava@dubeyko.com>
> > Acked-by: Ryusuke Konishi <konishi.ryusuke@gmail.com>
> > Signed-off-by: Jeff Layton <jlayton@kernel.org>
> > ---
> >  fs/nilfs2/bmap.c | 9 ++++++---
> >  1 file changed, 6 insertions(+), 3 deletions(-)
> > 
> > diff --git a/fs/nilfs2/bmap.c b/fs/nilfs2/bmap.c
> > index 824f2bd91c167965ec3a660202b6e6c5f1fe007e..abcf5252578ad24f694bfccf525893674bfcb4bc 100644
> > --- a/fs/nilfs2/bmap.c
> > +++ b/fs/nilfs2/bmap.c
> > @@ -455,11 +455,14 @@ __u64 nilfs_bmap_find_target_in_group(const struct nilfs_bmap *bmap)
> >  {
> >  	struct inode *dat = nilfs_bmap_get_dat(bmap);
> >  	unsigned long entries_per_group = nilfs_palloc_entries_per_group(dat);
> > -	unsigned long group = bmap->b_inode->i_ino / entries_per_group;
> 
> Are you sure entries_per_group can be more than 32 bits?
> It looks like something that will be the same size on 32 and 64bit.
> 

I'm not sure of anything here. I'm just want to get this to compile on
all arches. FWIW, I'm not looking to optimize anything in this patch.

> > +	unsigned long group;
> > +	u32 index;
> > +
> > +	group = div_u64(bmap->b_inode->i_ino, entries_per_group);
> 
> You don't need the full 64 by 64 divide.
> IIRC there are both div_u64_u32() and div_u64_ulong().
>
> > +	div_u64_rem(bmap->b_inode->i_ino, NILFS_BMAP_GROUP_DIV, &index);
> 
> NILFD_BMAP_GROUP_DIV is 8 (and probably has to be a power of 2).
> So:
> 	index = bmap->b_inode->i_ino & (NILFS_BMAP_GROUP_DIV - 1);
> is the same and likely much faster to calculate.
> (The compiler will have done that optimisation before.)
> 
> 

That all sounds reasonable to me. At this point though, it would be
better if the NILFS2 folks stepped in with how they'd prefer this be
done.

> 
> >  
> >  	return group * entries_per_group +
> > -		(bmap->b_inode->i_ino % NILFS_BMAP_GROUP_DIV) *
> > -		(entries_per_group / NILFS_BMAP_GROUP_DIV);
> > +	       index * (entries_per_group / NILFS_BMAP_GROUP_DIV);
> >  }
> >  
> >  static struct lock_class_key nilfs_bmap_dat_lock_key;
> > 

-- 
Jeff Layton <jlayton@kernel.org>

^ permalink raw reply

* Re: [PATCH] ima: remove buggy support for asynchronous hashes
From: Eric Biggers @ 2026-03-14 18:25 UTC (permalink / raw)
  To: Mimi Zohar
  Cc: linux-integrity, Roberto Sassu, Dmitry Kasatkin, linux-crypto,
	linux-kernel
In-Reply-To: <1c5f16f0913bae48bf2f24feaaaf3525ecdf4c97.camel@linux.ibm.com>

On Thu, Mar 12, 2026 at 07:29:05PM -0400, Mimi Zohar wrote:
> On Wed, 2026-03-11 at 22:39 -0700, Eric Biggers wrote:
> > IMA computes hashes using the crypto_shash or crypto_ahash API.  The
> > latter is used only when ima.ahash_minsize is set on the command line,
> > and its purpose is ostensibly to make the hash computation faster.
> > 
> > However, going off the CPU to a crypto engine and back again is actually
> > quite slow, especially compared with the acceleration that is built into
> > modern CPUs and the kernel now enables by default for most algorithms.
> > Typical performance results for SHA-256 on a modern platform can be
> > found at https://lore.kernel.org/linux-crypto/20250615184638.GA1480@sol/
> > 
> > Partly for this reason, several other kernel subsystems have already
> > dropped support for the crypto_ahash API.
> 
> The performance benefit was the ability of reading and filling a buffer from 
> disk, which was slow, while the other buffer was sent to the crypto engine.

On normal filesystems, sequential reads from a file already kick off
async readahead.  So the hashing and disk reads can already happen
concurrently anyway.

- Eric

^ permalink raw reply

* Re: [PATCH v2 1/2] nilfs2: fix 64-bit division operations in nilfs_bmap_find_target_in_group()
From: Ryusuke Konishi @ 2026-03-16 18:06 UTC (permalink / raw)
  To: David Laight, Jeff Layton
  Cc: Viacheslav Dubeyko, Christian Brauner, Mimi Zohar, Roberto Sassu,
	Dmitry Kasatkin, Eric Snowberg, Paul Moore, James Morris,
	Serge E. Hallyn, linux-nilfs, linux-kernel, linux-integrity,
	linux-security-module, linux-fsdevel, kernel test robot
In-Reply-To: <361258925536e2280ce62c5e49531af5c42aa491.camel@kernel.org>

On Sat, Mar 14, 2026 at 9:59 PM Jeff Layton wrote:
>
> On Sat, 2026-03-14 at 12:47 +0000, David Laight wrote:
> > On Fri, 13 Mar 2026 14:45:20 -0400
> > Jeff Layton <jlayton@kernel.org> wrote:
> >
> > > With the change to make inode->i_ino a u64, the build started failing on
> > > 32-bit ARM with:
> > >
> > >     ERROR: modpost: "__aeabi_uldivmod" [fs/nilfs2/nilfs2.ko] undefined!
> > >
> > > Fix this by using the 64-bit division interfaces in
> > > nilfs_bmap_find_target_in_group().
> > >
> > > Fixes: 998a59d371c2 ("treewide: fix missed i_ino format specifier conversions")
> > > Reported-by: kernel test robot <lkp@intel.com>
> > > Closes: https://lore.kernel.org/oe-kbuild-all/202603100602.KPxiClIO-lkp@intel.com/
> > > Reviewed-by: Viacheslav Dubeyko <slava@dubeyko.com>
> > > Acked-by: Ryusuke Konishi <konishi.ryusuke@gmail.com>
> > > Signed-off-by: Jeff Layton <jlayton@kernel.org>
> > > ---
> > >  fs/nilfs2/bmap.c | 9 ++++++---
> > >  1 file changed, 6 insertions(+), 3 deletions(-)
> > >
> > > diff --git a/fs/nilfs2/bmap.c b/fs/nilfs2/bmap.c
> > > index 824f2bd91c167965ec3a660202b6e6c5f1fe007e..abcf5252578ad24f694bfccf525893674bfcb4bc 100644
> > > --- a/fs/nilfs2/bmap.c
> > > +++ b/fs/nilfs2/bmap.c
> > > @@ -455,11 +455,14 @@ __u64 nilfs_bmap_find_target_in_group(const struct nilfs_bmap *bmap)
> > >  {
> > >     struct inode *dat = nilfs_bmap_get_dat(bmap);
> > >     unsigned long entries_per_group = nilfs_palloc_entries_per_group(dat);
> > > -   unsigned long group = bmap->b_inode->i_ino / entries_per_group;
> >
> > Are you sure entries_per_group can be more than 32 bits?
> > It looks like something that will be the same size on 32 and 64bit.
> >
>
> I'm not sure of anything here. I'm just want to get this to compile on
> all arches. FWIW, I'm not looking to optimize anything in this patch.
>
> > > +   unsigned long group;
> > > +   u32 index;
> > > +
> > > +   group = div_u64(bmap->b_inode->i_ino, entries_per_group);
> >
> > You don't need the full 64 by 64 divide.
> > IIRC there are both div_u64_u32() and div_u64_ulong().

Isn't the type of divisor in div_u64() u32?
Since entries_per_group cannot exceed 32 bits according to the current
specification, I think using div_u64() is fine.

> >
> > > +   div_u64_rem(bmap->b_inode->i_ino, NILFS_BMAP_GROUP_DIV, &index);
> >
> > NILFD_BMAP_GROUP_DIV is 8 (and probably has to be a power of 2).
> > So:
> >       index = bmap->b_inode->i_ino & (NILFS_BMAP_GROUP_DIV - 1);
> > is the same and likely much faster to calculate.
> > (The compiler will have done that optimisation before.)
> >
> >
>
> That all sounds reasonable to me. At this point though, it would be
> better if the NILFS2 folks stepped in with how they'd prefer this be
> done.

Yes, indeed.  It seems that the application of optimizations will
change, so this proposed correction is better.

Since NILFS_BMAP_GROUP_DIV is a fixed constant and cannot be anything
other than a power of 2, could you please adopt this proposed
correction with the following comment?

#define NILFS_BMAP_GROUP_DIV    8  /* must be a power of 2 */

Thanks,
Ryusuke Konishi

>
> >
> > >
> > >     return group * entries_per_group +
> > > -           (bmap->b_inode->i_ino % NILFS_BMAP_GROUP_DIV) *
> > > -           (entries_per_group / NILFS_BMAP_GROUP_DIV);
> > > +          index * (entries_per_group / NILFS_BMAP_GROUP_DIV);
> > >  }
> > >
> > >  static struct lock_class_key nilfs_bmap_dat_lock_key;
> > >
>
> --
> Jeff Layton <jlayton@kernel.org>

^ permalink raw reply

* Re: [PATCH v2 1/2] nilfs2: fix 64-bit division operations in nilfs_bmap_find_target_in_group()
From: Jeff Layton @ 2026-03-16 18:50 UTC (permalink / raw)
  To: Ryusuke Konishi, David Laight
  Cc: Viacheslav Dubeyko, Christian Brauner, Mimi Zohar, Roberto Sassu,
	Dmitry Kasatkin, Eric Snowberg, Paul Moore, James Morris,
	Serge E. Hallyn, linux-nilfs, linux-kernel, linux-integrity,
	linux-security-module, linux-fsdevel, kernel test robot
In-Reply-To: <CAKFNMomRoq+rxF2HzzTpWhju+GCm3p3fjhm7e9mmvZKdsJHwZA@mail.gmail.com>

On Tue, 2026-03-17 at 03:06 +0900, Ryusuke Konishi wrote:
> On Sat, Mar 14, 2026 at 9:59 PM Jeff Layton wrote:
> > 
> > On Sat, 2026-03-14 at 12:47 +0000, David Laight wrote:
> > > On Fri, 13 Mar 2026 14:45:20 -0400
> > > Jeff Layton <jlayton@kernel.org> wrote:
> > > 
> > > > With the change to make inode->i_ino a u64, the build started failing on
> > > > 32-bit ARM with:
> > > > 
> > > >     ERROR: modpost: "__aeabi_uldivmod" [fs/nilfs2/nilfs2.ko] undefined!
> > > > 
> > > > Fix this by using the 64-bit division interfaces in
> > > > nilfs_bmap_find_target_in_group().
> > > > 
> > > > Fixes: 998a59d371c2 ("treewide: fix missed i_ino format specifier conversions")
> > > > Reported-by: kernel test robot <lkp@intel.com>
> > > > Closes: https://lore.kernel.org/oe-kbuild-all/202603100602.KPxiClIO-lkp@intel.com/
> > > > Reviewed-by: Viacheslav Dubeyko <slava@dubeyko.com>
> > > > Acked-by: Ryusuke Konishi <konishi.ryusuke@gmail.com>
> > > > Signed-off-by: Jeff Layton <jlayton@kernel.org>
> > > > ---
> > > >  fs/nilfs2/bmap.c | 9 ++++++---
> > > >  1 file changed, 6 insertions(+), 3 deletions(-)
> > > > 
> > > > diff --git a/fs/nilfs2/bmap.c b/fs/nilfs2/bmap.c
> > > > index 824f2bd91c167965ec3a660202b6e6c5f1fe007e..abcf5252578ad24f694bfccf525893674bfcb4bc 100644
> > > > --- a/fs/nilfs2/bmap.c
> > > > +++ b/fs/nilfs2/bmap.c
> > > > @@ -455,11 +455,14 @@ __u64 nilfs_bmap_find_target_in_group(const struct nilfs_bmap *bmap)
> > > >  {
> > > >     struct inode *dat = nilfs_bmap_get_dat(bmap);
> > > >     unsigned long entries_per_group = nilfs_palloc_entries_per_group(dat);
> > > > -   unsigned long group = bmap->b_inode->i_ino / entries_per_group;
> > > 
> > > Are you sure entries_per_group can be more than 32 bits?
> > > It looks like something that will be the same size on 32 and 64bit.
> > > 
> > 
> > I'm not sure of anything here. I'm just want to get this to compile on
> > all arches. FWIW, I'm not looking to optimize anything in this patch.
> > 
> > > > +   unsigned long group;
> > > > +   u32 index;
> > > > +
> > > > +   group = div_u64(bmap->b_inode->i_ino, entries_per_group);
> > > 
> > > You don't need the full 64 by 64 divide.
> > > IIRC there are both div_u64_u32() and div_u64_ulong().
> 
> Isn't the type of divisor in div_u64() u32?
> Since entries_per_group cannot exceed 32 bits according to the current
> specification, I think using div_u64() is fine.
> 

Yep, it is:

static inline u64 div_u64(u64 dividend, u32 divisor)                  


> > > 
> > > > +   div_u64_rem(bmap->b_inode->i_ino, NILFS_BMAP_GROUP_DIV, &index);
> > > 
> > > NILFD_BMAP_GROUP_DIV is 8 (and probably has to be a power of 2).
> > > So:
> > >       index = bmap->b_inode->i_ino & (NILFS_BMAP_GROUP_DIV - 1);
> > > is the same and likely much faster to calculate.
> > > (The compiler will have done that optimisation before.)
> > > 
> > > 
> > 
> > That all sounds reasonable to me. At this point though, it would be
> > better if the NILFS2 folks stepped in with how they'd prefer this be
> > done.
> 
> Yes, indeed.  It seems that the application of optimizations will
> change, so this proposed correction is better.
> 
> Since NILFS_BMAP_GROUP_DIV is a fixed constant and cannot be anything
> other than a power of 2, could you please adopt this proposed
> correction with the following comment?
> 
> #define NILFS_BMAP_GROUP_DIV    8  /* must be a power of 2 */
> 

Even better, lets use a compile-time assertion:

    BUILD_BUG_ON_NOT_POWER_OF_TWO(NILFS_BMAP_GROUP_DIV);

I'll send a respin.

Thanks!
-- 
Jeff Layton <jlayton@kernel.org>

^ permalink raw reply

* [PATCH v3 0/2] vfs: follow-on fixes for i_ino widening
From: Jeff Layton @ 2026-03-16 19:02 UTC (permalink / raw)
  To: Ryusuke Konishi, Viacheslav Dubeyko, Christian Brauner,
	Mimi Zohar, Roberto Sassu, Dmitry Kasatkin, Eric Snowberg,
	Paul Moore, James Morris, Serge E. Hallyn
  Cc: David Laight, linux-nilfs, linux-kernel, linux-integrity,
	linux-security-module, linux-fsdevel, Jeff Layton,
	kernel test robot

Just some patches to fix follow-on issues reported after the
inode->i_ino widening series. Christian, could you toss these
onto the vfs-7.1.kino branch?

Signed-off-by: Jeff Layton <jlayton@kernel.org>
---
Changes in v3:
- nilfs2: find index with bitwise & operation instead of div_u64_rem()
- add compile-time assertion that NILFS_BMAP_GROUP_DIV is power of two
- Link to v2: https://lore.kernel.org/r/20260313-iino-u64-v2-0-f9abda2464d5@kernel.org

Changes in v2:
- rename variable in nilfs2 patch from "rem" to "index"
- reword comment and commit log for better accuracy in EVM patch

---
Jeff Layton (2):
      EVM: add comment describing why ino field is still unsigned long
      nilfs2: fix 64-bit division operations in nilfs_bmap_find_target_in_group()

 fs/nilfs2/bmap.c                    | 15 +++++++++++----
 security/integrity/evm/evm_crypto.c |  6 ++++++
 2 files changed, 17 insertions(+), 4 deletions(-)
---
base-commit: 9840bb66e7e5dffd72b03201318f154a10b06b4a
change-id: 20260310-iino-u64-424fa570d850

Best regards,
-- 
Jeff Layton <jlayton@kernel.org>


^ permalink raw reply

* [PATCH v3 1/2] EVM: add comment describing why ino field is still unsigned long
From: Jeff Layton @ 2026-03-16 19:02 UTC (permalink / raw)
  To: Ryusuke Konishi, Viacheslav Dubeyko, Christian Brauner,
	Mimi Zohar, Roberto Sassu, Dmitry Kasatkin, Eric Snowberg,
	Paul Moore, James Morris, Serge E. Hallyn
  Cc: David Laight, linux-nilfs, linux-kernel, linux-integrity,
	linux-security-module, linux-fsdevel, Jeff Layton
In-Reply-To: <20260316-iino-u64-v3-0-d1076b8f7a20@kernel.org>

Mimi pointed out that we didn't widen the inode number field in struct
h_misc alongside the inode->i_ino widening. While we could make an
equivalent change there, that would require EVM resigning on all 32-bit
hosts.

Instead, leave the field as an unsigned long. This should have no effect
on 64-bit hosts, and allow things to continue working on 32-bit hosts in
the cases where the i_ino fits in 32-bits.

Add a comment explaining why it's being left as unsigned long.

Reviewed-by: Mimi Zohar <zohar@linux.ibm.com>
Signed-off-by: Jeff Layton <jlayton@kernel.org>
---
 security/integrity/evm/evm_crypto.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/security/integrity/evm/evm_crypto.c b/security/integrity/evm/evm_crypto.c
index c0ca4eedb0fe5d5c30f45f515a4bc90248ec64ea..1c41af2f91a60a714878ff93b554c90e45546503 100644
--- a/security/integrity/evm/evm_crypto.c
+++ b/security/integrity/evm/evm_crypto.c
@@ -144,6 +144,12 @@ static void hmac_add_misc(struct shash_desc *desc, struct inode *inode,
 			  char type, char *digest)
 {
 	struct h_misc {
+		/*
+		 * Although inode->i_ino is now u64, this field remains
+		 * unsigned long to allow existing HMAC and signatures from
+		 * 32-bit hosts to continue working when i_ino hasn't changed
+		 * and fits in a u32.
+		 */
 		unsigned long ino;
 		__u32 generation;
 		uid_t uid;

-- 
2.53.0


^ permalink raw reply related

* [PATCH v3 2/2] nilfs2: fix 64-bit division operations in nilfs_bmap_find_target_in_group()
From: Jeff Layton @ 2026-03-16 19:02 UTC (permalink / raw)
  To: Ryusuke Konishi, Viacheslav Dubeyko, Christian Brauner,
	Mimi Zohar, Roberto Sassu, Dmitry Kasatkin, Eric Snowberg,
	Paul Moore, James Morris, Serge E. Hallyn
  Cc: David Laight, linux-nilfs, linux-kernel, linux-integrity,
	linux-security-module, linux-fsdevel, Jeff Layton,
	kernel test robot
In-Reply-To: <20260316-iino-u64-v3-0-d1076b8f7a20@kernel.org>

With the change to make inode->i_ino a u64, the build started failing on
32-bit ARM with:

    ERROR: modpost: "__aeabi_uldivmod" [fs/nilfs2/nilfs2.ko] undefined!

Fix this by using udiv_u64() for the division.

For finding the index into the group, switch to using a bitwise &
operation since that's more efficient. With this change however,
NILFS_BMAP_GROUP_DIV must be a power of two, so add a compile-time
assertion for that.

Fixes: 998a59d371c2 ("treewide: fix missed i_ino format specifier conversions")
Reported-by: kernel test robot <lkp@intel.com>
Closes: https://lore.kernel.org/oe-kbuild-all/202603100602.KPxiClIO-lkp@intel.com/
Reviewed-by: Viacheslav Dubeyko <slava@dubeyko.com>
Acked-by: Ryusuke Konishi <konishi.ryusuke@gmail.com>
Signed-off-by: Jeff Layton <jlayton@kernel.org>
---
 fs/nilfs2/bmap.c | 15 +++++++++++----
 1 file changed, 11 insertions(+), 4 deletions(-)

diff --git a/fs/nilfs2/bmap.c b/fs/nilfs2/bmap.c
index 824f2bd91c167965ec3a660202b6e6c5f1fe007e..5f0f1f283af0208e1879e2e84b0b5b9629fd6b8a 100644
--- a/fs/nilfs2/bmap.c
+++ b/fs/nilfs2/bmap.c
@@ -450,18 +450,25 @@ __u64 nilfs_bmap_find_target_seq(const struct nilfs_bmap *bmap, __u64 key)
 		return NILFS_BMAP_INVALID_PTR;
 }
 
-#define NILFS_BMAP_GROUP_DIV	8
+#define NILFS_BMAP_GROUP_DIV	8	/* must be power of 2 */
+
 __u64 nilfs_bmap_find_target_in_group(const struct nilfs_bmap *bmap)
 {
 	struct inode *dat = nilfs_bmap_get_dat(bmap);
 	unsigned long entries_per_group = nilfs_palloc_entries_per_group(dat);
-	unsigned long group = bmap->b_inode->i_ino / entries_per_group;
+	unsigned long group;
+	u32 index;
+
+	BUILD_BUG_ON_NOT_POWER_OF_2(NILFS_BMAP_GROUP_DIV);
+
+	group = div_u64(bmap->b_inode->i_ino, entries_per_group);
+	index = bmap->b_inode->i_ino & (NILFS_BMAP_GROUP_DIV - 1);
 
 	return group * entries_per_group +
-		(bmap->b_inode->i_ino % NILFS_BMAP_GROUP_DIV) *
-		(entries_per_group / NILFS_BMAP_GROUP_DIV);
+	       index * (entries_per_group / NILFS_BMAP_GROUP_DIV);
 }
 
+
 static struct lock_class_key nilfs_bmap_dat_lock_key;
 static struct lock_class_key nilfs_bmap_mdt_lock_key;
 

-- 
2.53.0


^ permalink raw reply related

* Re: [PATCH v2 1/2] keys/trusted_keys: clean up debug message logging in the tpm backend
From: Srish Srinivasan @ 2026-03-17  3:14 UTC (permalink / raw)
  To: Nayna Jain, linux-integrity, keyrings, Jarkko Sakkinen
  Cc: James.Bottomley, jarkko, zohar, stefanb, linux-kernel,
	linux-security-module
In-Reply-To: <7f8b8478-5cd8-4d97-bfd0-341fd5cf10f9@linux.ibm.com>


On 3/10/26 4:15 AM, Nayna Jain wrote:
>
> On 2/20/26 1:34 PM, Srish Srinivasan wrote:
>> The TPM trusted-keys backend uses a local TPM_DEBUG guard and pr_info()
>> for logging debug information.
>>
>> Replace pr_info() with pr_debug(), and use KERN_DEBUG for 
>> print_hex_dump().
>> Remove TPM_DEBUG.
>>
>> No functional change intended.
> There is functional change here.  This change allows secret and nonce 
> in the function dump_sess() to be logged to kernel logs when dynamic 
> debug is enabled. Previously, it was possible only in the debug builds 
> and not the production builds at runtime. With this change, it is 
> always there in production build. This can result in possible attack.


Hi Jarkko,
Could you please let us know your thoughts on this one?

And Nayna,
thanks for bringing this up.

thanks,
Srish.


>
> Instead of doing this change, I think add a comment to prevent this 
> sort of change in the future.
>
> Thanks & Regards,
>
>     - Nayna
>
>>
>> Signed-off-by: Srish Srinivasan <ssrish@linux.ibm.com>
>> Reviewed-by: Stefan Berger <stefanb@linux.ibm.com>
>> ---
>>   security/keys/trusted-keys/trusted_tpm1.c | 40 +++++++----------------
>>   1 file changed, 12 insertions(+), 28 deletions(-)
>>
>> diff --git a/security/keys/trusted-keys/trusted_tpm1.c 
>> b/security/keys/trusted-keys/trusted_tpm1.c
>> index c865c97aa1b4..216caef97ffc 100644
>> --- a/security/keys/trusted-keys/trusted_tpm1.c
>> +++ b/security/keys/trusted-keys/trusted_tpm1.c
>> @@ -46,28 +46,25 @@ enum {
>>       SRK_keytype = 4
>>   };
>>   -#define TPM_DEBUG 0
>> -
>> -#if TPM_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,
>> +    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(KERN_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,
>> +    print_hex_dump(KERN_DEBUG, "trusted-key: handle ", 
>> DUMP_PREFIX_NONE,
>>                  16, 1, &s->handle, 4, 0);
>> -    pr_info("secret:\n");
>> -    print_hex_dump(KERN_INFO, "", DUMP_PREFIX_NONE,
>> +    pr_debug("secret:\n");
>> +    print_hex_dump(KERN_DEBUG, "", 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,
>> +    pr_debug("trusted-key: enonce:\n");
>> +    print_hex_dump(KERN_DEBUG, "", DUMP_PREFIX_NONE,
>>                  16, 1, &s->enonce, SHA1_DIGEST_SIZE, 0);
>>   }
>>   @@ -75,23 +72,10 @@ static inline void dump_tpm_buf(unsigned char 
>> *buf)
>>   {
>>       int len;
>>   -    pr_info("\ntpm buffer\n");
>> +    pr_debug("\ntpm buffer\n");
>>       len = LOAD32(buf, TPM_SIZE_OFFSET);
>> -    print_hex_dump(KERN_INFO, "", DUMP_PREFIX_NONE, 16, 1, buf, len, 
>> 0);
>> -}
>> -#else
>> -static inline void dump_options(struct trusted_key_options *o)
>> -{
>> -}
>> -
>> -static inline void dump_sess(struct osapsess *s)
>> -{
>> -}
>> -
>> -static inline void dump_tpm_buf(unsigned char *buf)
>> -{
>> +    print_hex_dump(KERN_DEBUG, "", DUMP_PREFIX_NONE, 16, 1, buf, 
>> len, 0);
>>   }
>> -#endif
>>     static int TSS_rawhmac(unsigned char *digest, const unsigned char 
>> *key,
>>                  unsigned int keylen, ...)

^ permalink raw reply

* [zohar-integrity:next-integrity.ima-sigv3-support-1 13/15] security/integrity/evm/evm_main.c:270:6: error: too many arguments to function call, expected 5, have 6
From: kernel test robot @ 2026-03-17  9:16 UTC (permalink / raw)
  To: Mimi Zohar; +Cc: llvm, oe-kbuild-all, linux-integrity

tree:   https://git.kernel.org/pub/scm/linux/kernel/git/zohar/linux-integrity.git next-integrity.ima-sigv3-support-1
head:   9037cd4a36eb9554fb5968a4c1a990d44843190b
commit: d45011bbc88d112e7eea4dbb9a1b3b0081d0b30a [13/15] ima: Define asymmetric_verify_v3() to verify IMA sigv3 signatures
config: i386-buildonly-randconfig-005-20260317 (https://download.01.org/0day-ci/archive/20260317/202603171719.U8qaT87C-lkp@intel.com/config)
compiler: clang version 20.1.8 (https://github.com/llvm/llvm-project 87f0227cb60147a26a1eeb4fb06e3b505e9c7261)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20260317/202603171719.U8qaT87C-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202603171719.U8qaT87C-lkp@intel.com/

All errors (new ones prefixed by >>):

>> security/integrity/evm/evm_main.c:270:6: error: too many arguments to function call, expected 5, have 6
     267 |                 rc = integrity_digsig_verify(INTEGRITY_KEYRING_EVM,
         |                      ~~~~~~~~~~~~~~~~~~~~~~~
     268 |                                         (const char *)xattr_data, xattr_len,
     269 |                                         digest.digest, digest.hdr.length,
     270 |                                         digest.hdr.algo);
         |                                         ^~~~~~~~~~~~~~~
   security/integrity/evm/../integrity.h:143:19: note: 'integrity_digsig_verify' declared here
     143 | static inline int integrity_digsig_verify(const unsigned int id,
         |                   ^                       ~~~~~~~~~~~~~~~~~~~~~~
     144 |                                           const char *sig, int siglen,
         |                                           ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     145 |                                           const char *digest, int digestlen)
         |                                           ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   1 error generated.


vim +270 security/integrity/evm/evm_main.c

   172	
   173	/*
   174	 * evm_verify_hmac - calculate and compare the HMAC with the EVM xattr
   175	 *
   176	 * Compute the HMAC on the dentry's protected set of extended attributes
   177	 * and compare it against the stored security.evm xattr.
   178	 *
   179	 * For performance:
   180	 * - use the previously retrieved xattr value and length to calculate the
   181	 *   HMAC.)
   182	 * - cache the verification result in the iint, when available.
   183	 *
   184	 * Returns integrity status
   185	 */
   186	static enum integrity_status evm_verify_hmac(struct dentry *dentry,
   187						     const char *xattr_name,
   188						     char *xattr_value,
   189						     size_t xattr_value_len)
   190	{
   191		struct evm_ima_xattr_data *xattr_data = NULL;
   192		struct signature_v2_hdr *hdr;
   193		enum integrity_status evm_status = INTEGRITY_PASS;
   194		struct evm_digest digest;
   195		struct inode *inode = d_backing_inode(dentry);
   196		struct evm_iint_cache *iint = evm_iint_inode(inode);
   197		int rc, xattr_len, evm_immutable = 0;
   198	
   199		if (iint && (iint->evm_status == INTEGRITY_PASS ||
   200			     iint->evm_status == INTEGRITY_PASS_IMMUTABLE))
   201			return iint->evm_status;
   202	
   203		/*
   204		 * On unsupported filesystems without EVM_INIT_X509 enabled, skip
   205		 * signature verification.
   206		 */
   207		if (!(evm_initialized & EVM_INIT_X509) &&
   208		    is_unsupported_hmac_fs(dentry))
   209			return INTEGRITY_UNKNOWN;
   210	
   211		/* if status is not PASS, try to check again - against -ENOMEM */
   212	
   213		/* first need to know the sig type */
   214		rc = vfs_getxattr_alloc(&nop_mnt_idmap, dentry, XATTR_NAME_EVM,
   215					(char **)&xattr_data, 0, GFP_NOFS);
   216		if (rc <= 0) {
   217			evm_status = INTEGRITY_FAIL;
   218			if (rc == -ENODATA) {
   219				rc = evm_find_protected_xattrs(dentry);
   220				if (rc > 0)
   221					evm_status = INTEGRITY_NOLABEL;
   222				else if (rc == 0)
   223					evm_status = INTEGRITY_NOXATTRS; /* new file */
   224			} else if (rc == -EOPNOTSUPP) {
   225				evm_status = INTEGRITY_UNKNOWN;
   226			}
   227			goto out;
   228		}
   229	
   230		xattr_len = rc;
   231	
   232		/* check value type */
   233		switch (xattr_data->type) {
   234		case EVM_XATTR_HMAC:
   235			if (xattr_len != sizeof(struct evm_xattr)) {
   236				evm_status = INTEGRITY_FAIL;
   237				goto out;
   238			}
   239	
   240			digest.hdr.algo = HASH_ALGO_SHA1;
   241			rc = evm_calc_hmac(dentry, xattr_name, xattr_value,
   242					   xattr_value_len, &digest, iint);
   243			if (rc)
   244				break;
   245			rc = crypto_memneq(xattr_data->data, digest.digest,
   246					   SHA1_DIGEST_SIZE);
   247			if (rc)
   248				rc = -EINVAL;
   249			break;
   250		case EVM_XATTR_PORTABLE_DIGSIG:
   251			evm_immutable = 1;
   252			fallthrough;
   253		case EVM_IMA_XATTR_DIGSIG:
   254			/* accept xattr with non-empty signature field */
   255			if (xattr_len <= sizeof(struct signature_v2_hdr)) {
   256				evm_status = INTEGRITY_FAIL;
   257				goto out;
   258			}
   259	
   260			hdr = (struct signature_v2_hdr *)xattr_data;
   261			digest.hdr.algo = hdr->hash_algo;
   262			rc = evm_calc_hash(dentry, xattr_name, xattr_value,
   263					   xattr_value_len, xattr_data->type, &digest,
   264					   iint);
   265			if (rc)
   266				break;
   267			rc = integrity_digsig_verify(INTEGRITY_KEYRING_EVM,
   268						(const char *)xattr_data, xattr_len,
   269						digest.digest, digest.hdr.length,
 > 270						digest.hdr.algo);
   271			if (!rc) {
   272				if (xattr_data->type == EVM_XATTR_PORTABLE_DIGSIG) {
   273					if (iint)
   274						iint->flags |= EVM_IMMUTABLE_DIGSIG;
   275					evm_status = INTEGRITY_PASS_IMMUTABLE;
   276				} else if (!IS_RDONLY(inode) &&
   277					   !(inode->i_sb->s_readonly_remount) &&
   278					   !IS_IMMUTABLE(inode) &&
   279					   !is_unsupported_hmac_fs(dentry)) {
   280					evm_update_evmxattr(dentry, xattr_name,
   281							    xattr_value,
   282							    xattr_value_len);
   283				}
   284			}
   285			break;
   286		default:
   287			rc = -EINVAL;
   288			break;
   289		}
   290	
   291		if (rc) {
   292			if (rc == -ENODATA)
   293				evm_status = INTEGRITY_NOXATTRS;
   294			else if (evm_immutable)
   295				evm_status = INTEGRITY_FAIL_IMMUTABLE;
   296			else
   297				evm_status = INTEGRITY_FAIL;
   298		}
   299		pr_debug("digest: (%d) [%*phN]\n", digest.hdr.length, digest.hdr.length,
   300			  digest.digest);
   301	out:
   302		if (iint)
   303			iint->evm_status = evm_status;
   304		kfree(xattr_data);
   305		return evm_status;
   306	}
   307	

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki

^ permalink raw reply

* [zohar-integrity:next-integrity.ima-sigv3-support-1 13/15] security/integrity/evm/evm_main.c:267:22: error: too many arguments to function 'integrity_digsig_verify'
From: kernel test robot @ 2026-03-17 12:02 UTC (permalink / raw)
  To: Mimi Zohar; +Cc: oe-kbuild-all, linux-integrity

tree:   https://git.kernel.org/pub/scm/linux/kernel/git/zohar/linux-integrity.git next-integrity.ima-sigv3-support-1
head:   9037cd4a36eb9554fb5968a4c1a990d44843190b
commit: d45011bbc88d112e7eea4dbb9a1b3b0081d0b30a [13/15] ima: Define asymmetric_verify_v3() to verify IMA sigv3 signatures
config: i386-randconfig-006-20260317 (https://download.01.org/0day-ci/archive/20260317/202603171952.z3Qgv7vC-lkp@intel.com/config)
compiler: gcc-14 (Debian 14.2.0-19) 14.2.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20260317/202603171952.z3Qgv7vC-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202603171952.z3Qgv7vC-lkp@intel.com/

All errors (new ones prefixed by >>):

   security/integrity/evm/evm_main.c: In function 'evm_verify_hmac':
>> security/integrity/evm/evm_main.c:267:22: error: too many arguments to function 'integrity_digsig_verify'
     267 |                 rc = integrity_digsig_verify(INTEGRITY_KEYRING_EVM,
         |                      ^~~~~~~~~~~~~~~~~~~~~~~
   In file included from security/integrity/evm/evm.h:18,
                    from security/integrity/evm/evm_main.c:28:
   security/integrity/evm/../integrity.h:143:19: note: declared here
     143 | static inline int integrity_digsig_verify(const unsigned int id,
         |                   ^~~~~~~~~~~~~~~~~~~~~~~


vim +/integrity_digsig_verify +267 security/integrity/evm/evm_main.c

cd708c938f055c Mimi Zohar            2023-12-18  172  
66dbc325afcef9 Mimi Zohar            2011-03-15  173  /*
66dbc325afcef9 Mimi Zohar            2011-03-15  174   * evm_verify_hmac - calculate and compare the HMAC with the EVM xattr
66dbc325afcef9 Mimi Zohar            2011-03-15  175   *
66dbc325afcef9 Mimi Zohar            2011-03-15  176   * Compute the HMAC on the dentry's protected set of extended attributes
7102ebcd65c1cd Mimi Zohar            2011-05-12  177   * and compare it against the stored security.evm xattr.
7102ebcd65c1cd Mimi Zohar            2011-05-12  178   *
7102ebcd65c1cd Mimi Zohar            2011-05-12  179   * For performance:
ceb5faef848b2f Tanya Agarwal         2025-01-24  180   * - use the previously retrieved xattr value and length to calculate the
66dbc325afcef9 Mimi Zohar            2011-03-15  181   *   HMAC.)
7102ebcd65c1cd Mimi Zohar            2011-05-12  182   * - cache the verification result in the iint, when available.
66dbc325afcef9 Mimi Zohar            2011-03-15  183   *
66dbc325afcef9 Mimi Zohar            2011-03-15  184   * Returns integrity status
66dbc325afcef9 Mimi Zohar            2011-03-15  185   */
66dbc325afcef9 Mimi Zohar            2011-03-15  186  static enum integrity_status evm_verify_hmac(struct dentry *dentry,
66dbc325afcef9 Mimi Zohar            2011-03-15  187  					     const char *xattr_name,
66dbc325afcef9 Mimi Zohar            2011-03-15  188  					     char *xattr_value,
75a323e604fc77 Roberto Sassu         2024-02-15  189  					     size_t xattr_value_len)
66dbc325afcef9 Mimi Zohar            2011-03-15  190  {
15647eb3985ef3 Dmitry Kasatkin       2011-09-01  191  	struct evm_ima_xattr_data *xattr_data = NULL;
5feeb61183dde9 Matthew Garrett       2018-06-08  192  	struct signature_v2_hdr *hdr;
566be59ab86c0e Mimi Zohar            2011-08-22  193  	enum integrity_status evm_status = INTEGRITY_PASS;
5feeb61183dde9 Matthew Garrett       2018-06-08  194  	struct evm_digest digest;
75a323e604fc77 Roberto Sassu         2024-02-15  195  	struct inode *inode = d_backing_inode(dentry);
75a323e604fc77 Roberto Sassu         2024-02-15  196  	struct evm_iint_cache *iint = evm_iint_inode(inode);
cdef685be5b4ae Roberto Sassu         2021-05-14  197  	int rc, xattr_len, evm_immutable = 0;
66dbc325afcef9 Mimi Zohar            2011-03-15  198  
50b977481fce90 Matthew Garrett       2017-11-07  199  	if (iint && (iint->evm_status == INTEGRITY_PASS ||
50b977481fce90 Matthew Garrett       2017-11-07  200  		     iint->evm_status == INTEGRITY_PASS_IMMUTABLE))
24e0198efe0df5 Dmitry Kasatkin       2011-05-06  201  		return iint->evm_status;
66dbc325afcef9 Mimi Zohar            2011-03-15  202  
47add87ad18147 Stefan Berger         2024-02-23  203  	/*
47add87ad18147 Stefan Berger         2024-02-23  204  	 * On unsupported filesystems without EVM_INIT_X509 enabled, skip
47add87ad18147 Stefan Berger         2024-02-23  205  	 * signature verification.
47add87ad18147 Stefan Berger         2024-02-23  206  	 */
5e2e4d0ea5c2c8 Stefan Berger         2024-02-23  207  	if (!(evm_initialized & EVM_INIT_X509) &&
5e2e4d0ea5c2c8 Stefan Berger         2024-02-23  208  	    is_unsupported_hmac_fs(dentry))
cd708c938f055c Mimi Zohar            2023-12-18  209  		return INTEGRITY_UNKNOWN;
cd708c938f055c Mimi Zohar            2023-12-18  210  
6d38ca01c0c2d6 Dmitry Kasatkin       2011-05-06  211  	/* if status is not PASS, try to check again - against -ENOMEM */
6d38ca01c0c2d6 Dmitry Kasatkin       2011-05-06  212  
15647eb3985ef3 Dmitry Kasatkin       2011-09-01  213  	/* first need to know the sig type */
4609e1f18e19c3 Christian Brauner     2023-01-13  214  	rc = vfs_getxattr_alloc(&nop_mnt_idmap, dentry, XATTR_NAME_EVM,
c7c7a1a18af4c3 Tycho Andersen        2021-01-21  215  				(char **)&xattr_data, 0, GFP_NOFS);
15647eb3985ef3 Dmitry Kasatkin       2011-09-01  216  	if (rc <= 0) {
1f1009791b2e81 Dmitry Kasatkin       2014-08-15  217  		evm_status = INTEGRITY_FAIL;
1f1009791b2e81 Dmitry Kasatkin       2014-08-15  218  		if (rc == -ENODATA) {
15647eb3985ef3 Dmitry Kasatkin       2011-09-01  219  			rc = evm_find_protected_xattrs(dentry);
15647eb3985ef3 Dmitry Kasatkin       2011-09-01  220  			if (rc > 0)
15647eb3985ef3 Dmitry Kasatkin       2011-09-01  221  				evm_status = INTEGRITY_NOLABEL;
15647eb3985ef3 Dmitry Kasatkin       2011-09-01  222  			else if (rc == 0)
15647eb3985ef3 Dmitry Kasatkin       2011-09-01  223  				evm_status = INTEGRITY_NOXATTRS; /* new file */
1f1009791b2e81 Dmitry Kasatkin       2014-08-15  224  		} else if (rc == -EOPNOTSUPP) {
1f1009791b2e81 Dmitry Kasatkin       2014-08-15  225  			evm_status = INTEGRITY_UNKNOWN;
15647eb3985ef3 Dmitry Kasatkin       2011-09-01  226  		}
566be59ab86c0e Mimi Zohar            2011-08-22  227  		goto out;
566be59ab86c0e Mimi Zohar            2011-08-22  228  	}
66dbc325afcef9 Mimi Zohar            2011-03-15  229  
b1aaab22e263d0 Dmitry Kasatkin       2013-10-10  230  	xattr_len = rc;
15647eb3985ef3 Dmitry Kasatkin       2011-09-01  231  
15647eb3985ef3 Dmitry Kasatkin       2011-09-01  232  	/* check value type */
15647eb3985ef3 Dmitry Kasatkin       2011-09-01  233  	switch (xattr_data->type) {
15647eb3985ef3 Dmitry Kasatkin       2011-09-01  234  	case EVM_XATTR_HMAC:
650b29dbdf2caf Thiago Jung Bauermann 2019-06-11  235  		if (xattr_len != sizeof(struct evm_xattr)) {
b4bfec7f4a8642 Seth Forshee          2016-08-01  236  			evm_status = INTEGRITY_FAIL;
b4bfec7f4a8642 Seth Forshee          2016-08-01  237  			goto out;
b4bfec7f4a8642 Seth Forshee          2016-08-01  238  		}
5feeb61183dde9 Matthew Garrett       2018-06-08  239  
5feeb61183dde9 Matthew Garrett       2018-06-08  240  		digest.hdr.algo = HASH_ALGO_SHA1;
15647eb3985ef3 Dmitry Kasatkin       2011-09-01  241  		rc = evm_calc_hmac(dentry, xattr_name, xattr_value,
a652aa59068bd7 Stefan Berger         2024-02-23  242  				   xattr_value_len, &digest, iint);
15647eb3985ef3 Dmitry Kasatkin       2011-09-01  243  		if (rc)
15647eb3985ef3 Dmitry Kasatkin       2011-09-01  244  			break;
650b29dbdf2caf Thiago Jung Bauermann 2019-06-11  245  		rc = crypto_memneq(xattr_data->data, digest.digest,
5feeb61183dde9 Matthew Garrett       2018-06-08  246  				   SHA1_DIGEST_SIZE);
15647eb3985ef3 Dmitry Kasatkin       2011-09-01  247  		if (rc)
15647eb3985ef3 Dmitry Kasatkin       2011-09-01  248  			rc = -EINVAL;
15647eb3985ef3 Dmitry Kasatkin       2011-09-01  249  		break;
50b977481fce90 Matthew Garrett       2017-11-07  250  	case EVM_XATTR_PORTABLE_DIGSIG:
cdef685be5b4ae Roberto Sassu         2021-05-14  251  		evm_immutable = 1;
cdef685be5b4ae Roberto Sassu         2021-05-14  252  		fallthrough;
cdef685be5b4ae Roberto Sassu         2021-05-14  253  	case EVM_IMA_XATTR_DIGSIG:
455b6c9112eff8 Roberto Sassu         2020-09-04  254  		/* accept xattr with non-empty signature field */
455b6c9112eff8 Roberto Sassu         2020-09-04  255  		if (xattr_len <= sizeof(struct signature_v2_hdr)) {
455b6c9112eff8 Roberto Sassu         2020-09-04  256  			evm_status = INTEGRITY_FAIL;
455b6c9112eff8 Roberto Sassu         2020-09-04  257  			goto out;
455b6c9112eff8 Roberto Sassu         2020-09-04  258  		}
455b6c9112eff8 Roberto Sassu         2020-09-04  259  
5feeb61183dde9 Matthew Garrett       2018-06-08  260  		hdr = (struct signature_v2_hdr *)xattr_data;
5feeb61183dde9 Matthew Garrett       2018-06-08  261  		digest.hdr.algo = hdr->hash_algo;
15647eb3985ef3 Dmitry Kasatkin       2011-09-01  262  		rc = evm_calc_hash(dentry, xattr_name, xattr_value,
a652aa59068bd7 Stefan Berger         2024-02-23  263  				   xattr_value_len, xattr_data->type, &digest,
a652aa59068bd7 Stefan Berger         2024-02-23  264  				   iint);
15647eb3985ef3 Dmitry Kasatkin       2011-09-01  265  		if (rc)
15647eb3985ef3 Dmitry Kasatkin       2011-09-01  266  			break;
15647eb3985ef3 Dmitry Kasatkin       2011-09-01 @267  		rc = integrity_digsig_verify(INTEGRITY_KEYRING_EVM,
b1aaab22e263d0 Dmitry Kasatkin       2013-10-10  268  					(const char *)xattr_data, xattr_len,
d45011bbc88d11 Mimi Zohar            2026-03-10  269  					digest.digest, digest.hdr.length,
d45011bbc88d11 Mimi Zohar            2026-03-10  270  					digest.hdr.algo);
15647eb3985ef3 Dmitry Kasatkin       2011-09-01  271  		if (!rc) {
50b977481fce90 Matthew Garrett       2017-11-07  272  			if (xattr_data->type == EVM_XATTR_PORTABLE_DIGSIG) {
50b977481fce90 Matthew Garrett       2017-11-07  273  				if (iint)
50b977481fce90 Matthew Garrett       2017-11-07  274  					iint->flags |= EVM_IMMUTABLE_DIGSIG;
50b977481fce90 Matthew Garrett       2017-11-07  275  				evm_status = INTEGRITY_PASS_IMMUTABLE;
70946c4ac2a9e0 Sascha Hauer          2018-03-01  276  			} else if (!IS_RDONLY(inode) &&
70946c4ac2a9e0 Sascha Hauer          2018-03-01  277  				   !(inode->i_sb->s_readonly_remount) &&
47add87ad18147 Stefan Berger         2024-02-23  278  				   !IS_IMMUTABLE(inode) &&
5e2e4d0ea5c2c8 Stefan Berger         2024-02-23  279  				   !is_unsupported_hmac_fs(dentry)) {
c2baec7ffaf6a2 Dmitry Kasatkin       2014-10-01  280  				evm_update_evmxattr(dentry, xattr_name,
c2baec7ffaf6a2 Dmitry Kasatkin       2014-10-01  281  						    xattr_value,
15647eb3985ef3 Dmitry Kasatkin       2011-09-01  282  						    xattr_value_len);
15647eb3985ef3 Dmitry Kasatkin       2011-09-01  283  			}
50b977481fce90 Matthew Garrett       2017-11-07  284  		}
15647eb3985ef3 Dmitry Kasatkin       2011-09-01  285  		break;
15647eb3985ef3 Dmitry Kasatkin       2011-09-01  286  	default:
15647eb3985ef3 Dmitry Kasatkin       2011-09-01  287  		rc = -EINVAL;
15647eb3985ef3 Dmitry Kasatkin       2011-09-01  288  		break;
15647eb3985ef3 Dmitry Kasatkin       2011-09-01  289  	}
15647eb3985ef3 Dmitry Kasatkin       2011-09-01  290  
cdef685be5b4ae Roberto Sassu         2021-05-14  291  	if (rc) {
cdef685be5b4ae Roberto Sassu         2021-05-14  292  		if (rc == -ENODATA)
cdef685be5b4ae Roberto Sassu         2021-05-14  293  			evm_status = INTEGRITY_NOXATTRS;
cdef685be5b4ae Roberto Sassu         2021-05-14  294  		else if (evm_immutable)
cdef685be5b4ae Roberto Sassu         2021-05-14  295  			evm_status = INTEGRITY_FAIL_IMMUTABLE;
cdef685be5b4ae Roberto Sassu         2021-05-14  296  		else
cdef685be5b4ae Roberto Sassu         2021-05-14  297  			evm_status = INTEGRITY_FAIL;
cdef685be5b4ae Roberto Sassu         2021-05-14  298  	}
87ac3d002d567f Mimi Zohar            2021-05-13  299  	pr_debug("digest: (%d) [%*phN]\n", digest.hdr.length, digest.hdr.length,
87ac3d002d567f Mimi Zohar            2021-05-13  300  		  digest.digest);
7102ebcd65c1cd Mimi Zohar            2011-05-12  301  out:
7102ebcd65c1cd Mimi Zohar            2011-05-12  302  	if (iint)
7102ebcd65c1cd Mimi Zohar            2011-05-12  303  		iint->evm_status = evm_status;
15647eb3985ef3 Dmitry Kasatkin       2011-09-01  304  	kfree(xattr_data);
7102ebcd65c1cd Mimi Zohar            2011-05-12  305  	return evm_status;
66dbc325afcef9 Mimi Zohar            2011-03-15  306  }
66dbc325afcef9 Mimi Zohar            2011-03-15  307  

:::::: The code at line 267 was first introduced by commit
:::::: 15647eb3985ef30dfd657038924dc85c03026733 evm: digital signature verification support

:::::: TO: Dmitry Kasatkin <dmitry.kasatkin@intel.com>
:::::: CC: Dmitry Kasatkin <dmitry.kasatkin@intel.com>

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki

^ permalink raw reply

* Re: [PATCH] ima: remove buggy support for asynchronous hashes
From: Dmitry Kasatkin @ 2026-03-17 14:13 UTC (permalink / raw)
  To: Eric Biggers
  Cc: Mimi Zohar, linux-integrity, Roberto Sassu, linux-crypto,
	linux-kernel
In-Reply-To: <20260314182501.GA40504@quark>

On Sat, 14 Mar 2026 at 20:25, Eric Biggers <ebiggers@kernel.org> wrote:
>
> On Thu, Mar 12, 2026 at 07:29:05PM -0400, Mimi Zohar wrote:
> > On Wed, 2026-03-11 at 22:39 -0700, Eric Biggers wrote:
> > > IMA computes hashes using the crypto_shash or crypto_ahash API.  The
> > > latter is used only when ima.ahash_minsize is set on the command line,
> > > and its purpose is ostensibly to make the hash computation faster.
> > >
> > > However, going off the CPU to a crypto engine and back again is actually
> > > quite slow, especially compared with the acceleration that is built into
> > > modern CPUs and the kernel now enables by default for most algorithms.
> > > Typical performance results for SHA-256 on a modern platform can be
> > > found at https://lore.kernel.org/linux-crypto/20250615184638.GA1480@sol/
> > >
> > > Partly for this reason, several other kernel subsystems have already
> > > dropped support for the crypto_ahash API.
> >
> > The performance benefit was the ability of reading and filling a buffer from
> > disk, which was slow, while the other buffer was sent to the crypto engine.
>
> On normal filesystems, sequential reads from a file already kick off
> async readahead.  So the hashing and disk reads can already happen
> concurrently anyway.
>
> - Eric

I think this is fine. It was developed to be used on OMAP processors a
long time ago.
It can go away..

Ack

^ permalink raw reply

* Re: [PATCH v3 0/2] vfs: follow-on fixes for i_ino widening
From: Christian Brauner @ 2026-03-17 14:39 UTC (permalink / raw)
  To: Jeff Layton
  Cc: Christian Brauner, David Laight, linux-nilfs, linux-kernel,
	linux-integrity, linux-security-module, linux-fsdevel,
	kernel test robot, Ryusuke Konishi, Viacheslav Dubeyko,
	Mimi Zohar, Roberto Sassu, Dmitry Kasatkin, Eric Snowberg,
	Paul Moore, James Morris, Serge E. Hallyn
In-Reply-To: <20260316-iino-u64-v3-0-d1076b8f7a20@kernel.org>

On Mon, 16 Mar 2026 15:02:21 -0400, Jeff Layton wrote:
> Just some patches to fix follow-on issues reported after the
> inode->i_ino widening series. Christian, could you toss these
> onto the vfs-7.1.kino branch?

Applied to the vfs-7.1.kino branch of the vfs/vfs.git tree.
Patches in the vfs-7.1.kino branch should appear in linux-next soon.

Please report any outstanding bugs that were missed during review in a
new review to the original patch series allowing us to drop it.

It's encouraged to provide Acked-bys and Reviewed-bys even though the
patch has now been applied. If possible patch trailers will be updated.

Note that commit hashes shown below are subject to change due to rebase,
trailer updates or similar. If in doubt, please check the listed branch.

tree:   https://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs.git
branch: vfs-7.1.kino

[1/2] EVM: add comment describing why ino field is still unsigned long
      https://git.kernel.org/vfs/vfs/c/bef5b11087ce
[2/2] nilfs2: fix 64-bit division operations in nilfs_bmap_find_target_in_group()
      https://git.kernel.org/vfs/vfs/c/81359c146fba

^ permalink raw reply

* [PATCH 4/4] tpm: Move TPM common base definitions to the command header
From: Alec Brown @ 2026-03-17 16:03 UTC (permalink / raw)
  To: linux-kernel, linux-integrity, jarkko
  Cc: peterhuewe, jarkko.sakkinen, jgg, ross.philipson, dpsmith,
	daniel.kiper, kanth.ghatraju, trenchboot-devel, ardb,
	alec.r.brown
In-Reply-To: <20260317160613.2899129-1-alec.r.brown@oracle.com>

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                              */
+/************************************************/
+
+#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


^ permalink raw reply related

* [PATCH 0/4] Reorganize TPM public headers
From: Alec Brown @ 2026-03-17 16:03 UTC (permalink / raw)
  To: linux-kernel, linux-integrity, jarkko
  Cc: peterhuewe, jarkko.sakkinen, jgg, ross.philipson, dpsmith,
	daniel.kiper, kanth.ghatraju, trenchboot-devel, ardb,
	alec.r.brown

This patch series reorganizes various TPM definitions into tpm_command.h and
groups them corresponding to the TCG specification for TPM1 and TPM2. The
purpose in reorganizing these definitions is to assist the TPM driver usability
in pre-boot environments. This series is related to Jarkko Sakkinen's work
streamlining TPM2 HMAC sessions but can be applied independently of his
patches.

Ross Philipson (4):
      tpm: Initial step to reorganize TPM public headers
      tpm: Move TPM1 specific definitions to the command header
      tpm: Move TPM2 specific definitions to the command header
      tpm: Move TPM common base definitions to the command header

 drivers/char/tpm/tpm-buf.c                |   1 -
 drivers/char/tpm/tpm.h                    | 179 ----------
 drivers/char/tpm/tpm1-cmd.c               |  19 +-
 drivers/char/tpm/tpm2-cmd.c               |  30 --
 drivers/char/tpm/tpm2-space.c             |  13 -
 include/keys/trusted_tpm.h                |   1 -
 include/linux/tpm.h                       | 195 +----------
 include/linux/tpm_command.h               | 520 +++++++++++++++++++++++++++++-
 security/keys/trusted-keys/trusted_tpm1.c |   1 -
 security/keys/trusted-keys/trusted_tpm2.c |   1 -
 10 files changed, 510 insertions(+), 450 deletions(-)


^ permalink raw reply

* [PATCH 1/4] tpm: Initial step to reorganize TPM public headers
From: Alec Brown @ 2026-03-17 16:03 UTC (permalink / raw)
  To: linux-kernel, linux-integrity, jarkko
  Cc: peterhuewe, jarkko.sakkinen, jgg, ross.philipson, dpsmith,
	daniel.kiper, kanth.ghatraju, trenchboot-devel, ardb,
	alec.r.brown
In-Reply-To: <20260317160613.2899129-1-alec.r.brown@oracle.com>

From: Ross Philipson <ross.philipson@oracle.com>

From: Ross Philipson <ross.philipson@oracle.com>

Consolidate TPM1 constants in tpm_command.h and remove duplicate
constants from tpm1-cmd.c.

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>
---
 drivers/char/tpm/tpm-buf.c                |  1 -
 drivers/char/tpm/tpm1-cmd.c               | 14 +-------
 include/keys/trusted_tpm.h                |  1 -
 include/linux/tpm.h                       |  2 ++
 include/linux/tpm_command.h               | 43 ++++++++++++++++-------
 security/keys/trusted-keys/trusted_tpm1.c |  1 -
 security/keys/trusted-keys/trusted_tpm2.c |  1 -
 7 files changed, 33 insertions(+), 30 deletions(-)

diff --git a/drivers/char/tpm/tpm-buf.c b/drivers/char/tpm/tpm-buf.c
index dc882fc9fa9e..4c4f450630df 100644
--- a/drivers/char/tpm/tpm-buf.c
+++ b/drivers/char/tpm/tpm-buf.c
@@ -3,7 +3,6 @@
  * Handling of TPM command and other buffers.
  */
 
-#include <linux/tpm_command.h>
 #include <linux/module.h>
 #include <linux/tpm.h>
 
diff --git a/drivers/char/tpm/tpm1-cmd.c b/drivers/char/tpm/tpm1-cmd.c
index b49a790f1bd5..664ca1fff2e8 100644
--- a/drivers/char/tpm/tpm1-cmd.c
+++ b/drivers/char/tpm/tpm1-cmd.c
@@ -22,8 +22,6 @@
 
 #include "tpm.h"
 
-#define TPM_MAX_ORDINAL 243
-
 /*
  * Array with one entry per ordinal defining the maximum amount
  * of time the chip could take to return the result.  The ordinal
@@ -308,9 +306,6 @@ unsigned long tpm1_calc_ordinal_duration(struct tpm_chip *chip, u32 ordinal)
 		return duration;
 }
 
-#define TPM_ORD_STARTUP 153
-#define TPM_ST_CLEAR 1
-
 /**
  * tpm1_startup() - turn on the TPM
  * @chip: TPM chip to use
@@ -459,7 +454,6 @@ int tpm1_get_timeouts(struct tpm_chip *chip)
 	return 0;
 }
 
-#define TPM_ORD_PCR_EXTEND 20
 int tpm1_pcr_extend(struct tpm_chip *chip, u32 pcr_idx, const u8 *hash,
 		    const char *log_msg)
 {
@@ -478,7 +472,6 @@ int tpm1_pcr_extend(struct tpm_chip *chip, u32 pcr_idx, const u8 *hash,
 	return rc;
 }
 
-#define TPM_ORD_GET_CAP 101
 ssize_t tpm1_getcap(struct tpm_chip *chip, u32 subcap_id, cap_t *cap,
 		    const char *desc, size_t min_cap_length)
 {
@@ -511,7 +504,6 @@ ssize_t tpm1_getcap(struct tpm_chip *chip, u32 subcap_id, cap_t *cap,
 }
 EXPORT_SYMBOL_GPL(tpm1_getcap);
 
-#define TPM_ORD_GET_RANDOM 70
 struct tpm1_get_random_out {
 	__be32 rng_data_len;
 	u8 rng_data[TPM_MAX_RNG_DATA];
@@ -580,13 +572,12 @@ int tpm1_get_random(struct tpm_chip *chip, u8 *dest, size_t max)
 	return rc;
 }
 
-#define TPM_ORD_PCRREAD 21
 int tpm1_pcr_read(struct tpm_chip *chip, u32 pcr_idx, u8 *res_buf)
 {
 	struct tpm_buf buf;
 	int rc;
 
-	rc = tpm_buf_init(&buf, TPM_TAG_RQU_COMMAND, TPM_ORD_PCRREAD);
+	rc = tpm_buf_init(&buf, TPM_TAG_RQU_COMMAND, TPM_ORD_PCR_READ);
 	if (rc)
 		return rc;
 
@@ -609,7 +600,6 @@ int tpm1_pcr_read(struct tpm_chip *chip, u32 pcr_idx, u8 *res_buf)
 	return rc;
 }
 
-#define TPM_ORD_CONTINUE_SELFTEST 83
 /**
  * tpm1_continue_selftest() - run TPM's selftest
  * @chip: TPM chip to use
@@ -726,8 +716,6 @@ int tpm1_auto_startup(struct tpm_chip *chip)
 	return rc;
 }
 
-#define TPM_ORD_SAVESTATE 152
-
 /**
  * tpm1_pm_suspend() - pm suspend handler
  * @chip: TPM chip to use.
diff --git a/include/keys/trusted_tpm.h b/include/keys/trusted_tpm.h
index 0fadc6a4f166..3a0fa3bc8454 100644
--- a/include/keys/trusted_tpm.h
+++ b/include/keys/trusted_tpm.h
@@ -3,7 +3,6 @@
 #define __TRUSTED_TPM_H
 
 #include <keys/trusted-type.h>
-#include <linux/tpm_command.h>
 
 extern struct trusted_key_ops trusted_key_tpm_ops;
 
diff --git a/include/linux/tpm.h b/include/linux/tpm.h
index 202da079d500..18dcf0ef46f6 100644
--- a/include/linux/tpm.h
+++ b/include/linux/tpm.h
@@ -25,6 +25,8 @@
 #include <crypto/hash_info.h>
 #include <crypto/aes.h>
 
+#include "tpm_command.h"
+
 #define TPM_DIGEST_SIZE 20	/* Max TPM v1.2 PCR size */
 
 #define TPM2_MAX_DIGEST_SIZE	SHA512_DIGEST_SIZE
diff --git a/include/linux/tpm_command.h b/include/linux/tpm_command.h
index f5c03e9c3913..9a8991b8801d 100644
--- a/include/linux/tpm_command.h
+++ b/include/linux/tpm_command.h
@@ -2,28 +2,45 @@
 #ifndef __LINUX_TPM_COMMAND_H__
 #define __LINUX_TPM_COMMAND_H__
 
+/************************************************/
+/* TPM 1 Family Chips                           */
+/************************************************/
+
 /*
- * TPM Command constants from specifications at
- * http://www.trustedcomputinggroup.org
+ * TPM 1.2 Main Specification
+ * https://trustedcomputinggroup.org/resource/tpm-main-specification/
  */
 
+#define TPM_MAX_ORDINAL	243
+
 /* Command TAGS */
-#define TPM_TAG_RQU_COMMAND             193
-#define TPM_TAG_RQU_AUTH1_COMMAND       194
-#define TPM_TAG_RQU_AUTH2_COMMAND       195
-#define TPM_TAG_RSP_COMMAND             196
-#define TPM_TAG_RSP_AUTH1_COMMAND       197
-#define TPM_TAG_RSP_AUTH2_COMMAND       198
+enum tpm_command_tags {
+	TPM_TAG_RQU_COMMAND		= 193,
+	TPM_TAG_RQU_AUTH1_COMMAND	= 194,
+	TPM_TAG_RQU_AUTH2_COMMAND	= 195,
+	TPM_TAG_RSP_COMMAND		= 196,
+	TPM_TAG_RSP_AUTH1_COMMAND	= 197,
+	TPM_TAG_RSP_AUTH2_COMMAND	= 198,
+};
 
 /* Command Ordinals */
-#define TPM_ORD_GETRANDOM               70
-#define TPM_ORD_OSAP                    11
-#define TPM_ORD_OIAP                    10
-#define TPM_ORD_SEAL                    23
-#define TPM_ORD_UNSEAL                  24
+enum tpm_command_ordinals {
+	TPM_ORD_CONTINUE_SELFTEST	= 83,
+	TPM_ORD_GET_CAP			= 101,
+	TPM_ORD_GET_RANDOM		= 70,
+	TPM_ORD_PCR_EXTEND		= 20,
+	TPM_ORD_PCR_READ		= 21,
+	TPM_ORD_OSAP			= 11,
+	TPM_ORD_OIAP			= 10,
+	TPM_ORD_SAVESTATE		= 152,
+	TPM_ORD_SEAL			= 23,
+	TPM_ORD_STARTUP			= 153,
+	TPM_ORD_UNSEAL			= 24,
+};
 
 /* Other constants */
 #define SRKHANDLE                       0x40000000
 #define TPM_NONCE_SIZE                  20
+#define TPM_ST_CLEAR			1
 
 #endif
diff --git a/security/keys/trusted-keys/trusted_tpm1.c b/security/keys/trusted-keys/trusted_tpm1.c
index 636acb66a4f6..10f79a8c2d35 100644
--- a/security/keys/trusted-keys/trusted_tpm1.c
+++ b/security/keys/trusted-keys/trusted_tpm1.c
@@ -17,7 +17,6 @@
 #include <keys/trusted-type.h>
 #include <linux/key-type.h>
 #include <linux/tpm.h>
-#include <linux/tpm_command.h>
 
 #include <keys/trusted_tpm.h>
 
diff --git a/security/keys/trusted-keys/trusted_tpm2.c b/security/keys/trusted-keys/trusted_tpm2.c
index a7ea4a1c3bed..56eb8e20780a 100644
--- a/security/keys/trusted-keys/trusted_tpm2.c
+++ b/security/keys/trusted-keys/trusted_tpm2.c
@@ -9,7 +9,6 @@
 #include <linux/string.h>
 #include <linux/err.h>
 #include <linux/tpm.h>
-#include <linux/tpm_command.h>
 
 #include <keys/trusted-type.h>
 #include <keys/trusted_tpm.h>
-- 
2.47.3


^ permalink raw reply related

* [PATCH 2/4] tpm: Move TPM1 specific definitions to the command header
From: Alec Brown @ 2026-03-17 16:03 UTC (permalink / raw)
  To: linux-kernel, linux-integrity, jarkko
  Cc: peterhuewe, jarkko.sakkinen, jgg, ross.philipson, dpsmith,
	daniel.kiper, kanth.ghatraju, trenchboot-devel, ardb,
	alec.r.brown
In-Reply-To: <20260317160613.2899129-1-alec.r.brown@oracle.com>

From: Ross Philipson <ross.philipson@oracle.com>

From: Ross Philipson <ross.philipson@oracle.com>

Gather all the TPM1 definitions and structures in the internal header
file drivers/char/tpm/tpm.h into the command header. In addition, bring
in the single RNG structure from tpm-interface.c.

The definitions moved to these files correspond to the TCG specification
for TPM 1 family:

TPM 1.2 Main Specification
 -  https://trustedcomputinggroup.org/resource/tpm-main-specification/

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>
---
 drivers/char/tpm/tpm.h      | 102 --------------------------------
 drivers/char/tpm/tpm1-cmd.c |   5 --
 include/linux/tpm_command.h | 115 ++++++++++++++++++++++++++++++++++++
 3 files changed, 115 insertions(+), 107 deletions(-)

diff --git a/drivers/char/tpm/tpm.h b/drivers/char/tpm/tpm.h
index 02c07fef41ba..1a9a46a921fe 100644
--- a/drivers/char/tpm/tpm.h
+++ b/drivers/char/tpm/tpm.h
@@ -51,105 +51,9 @@ enum tpm_addr {
 	TPM_ADDR = 0x4E,
 };
 
-#define TPM_WARN_RETRY          0x800
-#define TPM_WARN_DOING_SELFTEST 0x802
-#define TPM_ERR_DEACTIVATED     0x6
-#define TPM_ERR_DISABLED        0x7
-#define TPM_ERR_FAILEDSELFTEST  0x1C
-#define TPM_ERR_INVALID_POSTINIT 38
-
-#define TPM_TAG_RQU_COMMAND 193
-
 /* TPM2 specific constants. */
 #define TPM2_SPACE_BUFFER_SIZE		16384 /* 16 kB */
 
-struct	stclear_flags_t {
-	__be16	tag;
-	u8	deactivated;
-	u8	disableForceClear;
-	u8	physicalPresence;
-	u8	physicalPresenceLock;
-	u8	bGlobalLock;
-} __packed;
-
-struct tpm1_version {
-	u8 major;
-	u8 minor;
-	u8 rev_major;
-	u8 rev_minor;
-} __packed;
-
-struct tpm1_version2 {
-	__be16 tag;
-	struct tpm1_version version;
-} __packed;
-
-struct	timeout_t {
-	__be32	a;
-	__be32	b;
-	__be32	c;
-	__be32	d;
-} __packed;
-
-struct duration_t {
-	__be32	tpm_short;
-	__be32	tpm_medium;
-	__be32	tpm_long;
-} __packed;
-
-struct permanent_flags_t {
-	__be16	tag;
-	u8	disable;
-	u8	ownership;
-	u8	deactivated;
-	u8	readPubek;
-	u8	disableOwnerClear;
-	u8	allowMaintenance;
-	u8	physicalPresenceLifetimeLock;
-	u8	physicalPresenceHWEnable;
-	u8	physicalPresenceCMDEnable;
-	u8	CEKPUsed;
-	u8	TPMpost;
-	u8	TPMpostLock;
-	u8	FIPS;
-	u8	operator;
-	u8	enableRevokeEK;
-	u8	nvLocked;
-	u8	readSRKPub;
-	u8	tpmEstablished;
-	u8	maintenanceDone;
-	u8	disableFullDALogicInfo;
-} __packed;
-
-typedef union {
-	struct	permanent_flags_t perm_flags;
-	struct	stclear_flags_t	stclear_flags;
-	__u8	owned;
-	__be32	num_pcrs;
-	struct tpm1_version version1;
-	struct tpm1_version2 version2;
-	__be32	manufacturer_id;
-	struct timeout_t  timeout;
-	struct duration_t duration;
-} cap_t;
-
-enum tpm_capabilities {
-	TPM_CAP_FLAG = 4,
-	TPM_CAP_PROP = 5,
-	TPM_CAP_VERSION_1_1 = 0x06,
-	TPM_CAP_VERSION_1_2 = 0x1A,
-};
-
-enum tpm_sub_capabilities {
-	TPM_CAP_PROP_PCR = 0x101,
-	TPM_CAP_PROP_MANUFACTURER = 0x103,
-	TPM_CAP_FLAG_PERM = 0x108,
-	TPM_CAP_FLAG_VOL = 0x109,
-	TPM_CAP_PROP_OWNER = 0x111,
-	TPM_CAP_PROP_TIS_TIMEOUT = 0x115,
-	TPM_CAP_PROP_TIS_DURATION = 0x120,
-};
-
 enum tpm2_pt_props {
 	TPM2_PT_NONE = 0x00000000,
 	TPM2_PT_GROUP = 0x00000100,
@@ -224,12 +128,6 @@ enum tpm2_pt_props {
 	TPM2_PT_AUDIT_COUNTER_1 = TPM2_PT_VAR + 20,
 };
 
-/* 128 bytes is an arbitrary cap. This could be as large as TPM_BUFSIZE - 18
- * bytes, but 128 is still a relatively large number of random bytes and
- * anything much bigger causes users of struct tpm_cmd_t to start getting
- * compiler warnings about stack frame size. */
-#define TPM_MAX_RNG_DATA	128
-
 extern const struct class tpm_class;
 extern const struct class tpmrm_class;
 extern dev_t tpm_devt;
diff --git a/drivers/char/tpm/tpm1-cmd.c b/drivers/char/tpm/tpm1-cmd.c
index 664ca1fff2e8..96f189b5fd6f 100644
--- a/drivers/char/tpm/tpm1-cmd.c
+++ b/drivers/char/tpm/tpm1-cmd.c
@@ -504,11 +504,6 @@ ssize_t tpm1_getcap(struct tpm_chip *chip, u32 subcap_id, cap_t *cap,
 }
 EXPORT_SYMBOL_GPL(tpm1_getcap);
 
-struct tpm1_get_random_out {
-	__be32 rng_data_len;
-	u8 rng_data[TPM_MAX_RNG_DATA];
-} __packed;
-
 /**
  * tpm1_get_random() - get random bytes from the TPM's RNG
  * @chip:	a &struct tpm_chip instance
diff --git a/include/linux/tpm_command.h b/include/linux/tpm_command.h
index 9a8991b8801d..20b634591fb1 100644
--- a/include/linux/tpm_command.h
+++ b/include/linux/tpm_command.h
@@ -38,6 +38,121 @@ enum tpm_command_ordinals {
 	TPM_ORD_UNSEAL			= 24,
 };
 
+enum tpm_capabilities {
+	TPM_CAP_FLAG		= 4,
+	TPM_CAP_PROP		= 5,
+	TPM_CAP_VERSION_1_1	= 0x06,
+	TPM_CAP_VERSION_1_2	= 0x1A,
+};
+
+enum tpm_sub_capabilities {
+	TPM_CAP_PROP_PCR		= 0x101,
+	TPM_CAP_PROP_MANUFACTURER	= 0x103,
+	TPM_CAP_FLAG_PERM		= 0x108,
+	TPM_CAP_FLAG_VOL		= 0x109,
+	TPM_CAP_PROP_OWNER		= 0x111,
+	TPM_CAP_PROP_TIS_TIMEOUT	= 0x115,
+	TPM_CAP_PROP_TIS_DURATION	= 0x120,
+};
+
+/* Return Codes */
+enum tpm_return_codes {
+	TPM_BASE_MASK			= 0,
+	TPM_NON_FATAL_MASK		= 0x00000800,
+	TPM_SUCCESS			= TPM_BASE_MASK + 0,
+	TPM_ERR_DEACTIVATED		= TPM_BASE_MASK + 6,
+	TPM_ERR_DISABLED		= TPM_BASE_MASK + 7,
+	TPM_ERR_FAIL			= TPM_BASE_MASK + 9,
+	TPM_ERR_FAILEDSELFTEST		= TPM_BASE_MASK + 28,
+	TPM_ERR_INVALID_POSTINIT	= TPM_BASE_MASK + 38,
+	TPM_ERR_INVALID_FAMILY		= TPM_BASE_MASK + 55,
+	TPM_WARN_RETRY			= TPM_BASE_MASK + TPM_NON_FATAL_MASK + 0,
+	TPM_WARN_DOING_SELFTEST		= TPM_BASE_MASK + TPM_NON_FATAL_MASK + 2,
+};
+
+struct	stclear_flags_t {
+	__be16 tag;
+	u8 deactivated;
+	u8 disableForceClear;
+	u8 physicalPresence;
+	u8 physicalPresenceLock;
+	u8 bGlobalLock;
+} __packed;
+
+struct tpm1_version {
+	u8 major;
+	u8 minor;
+	u8 rev_major;
+	u8 rev_minor;
+} __packed;
+
+struct tpm1_version2 {
+	__be16 tag;
+	struct tpm1_version version;
+} __packed;
+
+struct	timeout_t {
+	__be32 a;
+	__be32 b;
+	__be32 c;
+	__be32 d;
+} __packed;
+
+struct duration_t {
+	__be32 tpm_short;
+	__be32 tpm_medium;
+	__be32 tpm_long;
+} __packed;
+
+struct permanent_flags_t {
+	__be16 tag;
+	u8 disable;
+	u8 ownership;
+	u8 deactivated;
+	u8 readPubek;
+	u8 disableOwnerClear;
+	u8 allowMaintenance;
+	u8 physicalPresenceLifetimeLock;
+	u8 physicalPresenceHWEnable;
+	u8 physicalPresenceCMDEnable;
+	u8 CEKPUsed;
+	u8 TPMpost;
+	u8 TPMpostLock;
+	u8 FIPS;
+	u8 operator;
+	u8 enableRevokeEK;
+	u8 nvLocked;
+	u8 readSRKPub;
+	u8 tpmEstablished;
+	u8 maintenanceDone;
+	u8 disableFullDALogicInfo;
+} __packed;
+
+typedef union {
+	struct permanent_flags_t perm_flags;
+	struct stclear_flags_t stclear_flags;
+	__u8 owned;
+	__be32 num_pcrs;
+	struct tpm1_version version1;
+	struct tpm1_version2 version2;
+	__be32 manufacturer_id;
+	struct timeout_t timeout;
+	struct duration_t duration;
+} cap_t;
+
+/*
+ * 128 bytes is an arbitrary cap. This could be as large as TPM_BUFSIZE - 18
+ * bytes, but 128 is still a relatively large number of random bytes and
+ * anything much bigger causes users of struct tpm_cmd_t to start getting
+ * compiler warnings about stack frame size.
+ */
+#define TPM_MAX_RNG_DATA		128
+
+struct tpm1_get_random_out {
+	__be32 rng_data_len;
+	u8 rng_data[TPM_MAX_RNG_DATA];
+} __packed;
+
 /* Other constants */
 #define SRKHANDLE                       0x40000000
 #define TPM_NONCE_SIZE                  20
-- 
2.47.3


^ permalink raw reply related

* [PATCH 3/4] tpm: Move TPM2 specific definitions to the command header
From: Alec Brown @ 2026-03-17 16:03 UTC (permalink / raw)
  To: linux-kernel, linux-integrity, jarkko
  Cc: peterhuewe, jarkko.sakkinen, jgg, ross.philipson, dpsmith,
	daniel.kiper, kanth.ghatraju, trenchboot-devel, ardb,
	alec.r.brown
In-Reply-To: <20260317160613.2899129-1-alec.r.brown@oracle.com>

From: Ross Philipson <ross.philipson@oracle.com>

From: Ross Philipson <ross.philipson@oracle.com>

Gather all the TPM2 definitions and structures in the internal header
file drivers/char/tpm/tpm.h into the command header, including:
 - Command codes, return codes and definitions from the public and
internal tpm.h files.
 - Structures defined in numerous TPM driver C modules.

The definitions moved to these files correspond to the TCG specification
for TPM 2 family:

TPM 2.0 Library
 - https://trustedcomputinggroup.org/resource/tpm-library-specification/

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>
---
 drivers/char/tpm/tpm.h        |  77 ----------
 drivers/char/tpm/tpm2-cmd.c   |  30 ----
 drivers/char/tpm/tpm2-space.c |  13 --
 include/linux/tpm.h           | 145 ------------------
 include/linux/tpm_command.h   | 273 ++++++++++++++++++++++++++++++++++
 5 files changed, 273 insertions(+), 265 deletions(-)

diff --git a/drivers/char/tpm/tpm.h b/drivers/char/tpm/tpm.h
index 1a9a46a921fe..147e57c0e7bb 100644
--- a/drivers/char/tpm/tpm.h
+++ b/drivers/char/tpm/tpm.h
@@ -51,83 +51,6 @@ enum tpm_addr {
 	TPM_ADDR = 0x4E,
 };
 
-/* TPM2 specific constants. */
-#define TPM2_SPACE_BUFFER_SIZE		16384 /* 16 kB */
-
-enum tpm2_pt_props {
-	TPM2_PT_NONE = 0x00000000,
-	TPM2_PT_GROUP = 0x00000100,
-	TPM2_PT_FIXED = TPM2_PT_GROUP * 1,
-	TPM2_PT_FAMILY_INDICATOR = TPM2_PT_FIXED + 0,
-	TPM2_PT_LEVEL = TPM2_PT_FIXED + 1,
-	TPM2_PT_REVISION = TPM2_PT_FIXED + 2,
-	TPM2_PT_DAY_OF_YEAR = TPM2_PT_FIXED + 3,
-	TPM2_PT_YEAR = TPM2_PT_FIXED + 4,
-	TPM2_PT_MANUFACTURER = TPM2_PT_FIXED + 5,
-	TPM2_PT_VENDOR_STRING_1 = TPM2_PT_FIXED + 6,
-	TPM2_PT_VENDOR_STRING_2 = TPM2_PT_FIXED + 7,
-	TPM2_PT_VENDOR_STRING_3 = TPM2_PT_FIXED + 8,
-	TPM2_PT_VENDOR_STRING_4 = TPM2_PT_FIXED + 9,
-	TPM2_PT_VENDOR_TPM_TYPE = TPM2_PT_FIXED + 10,
-	TPM2_PT_FIRMWARE_VERSION_1 = TPM2_PT_FIXED + 11,
-	TPM2_PT_FIRMWARE_VERSION_2 = TPM2_PT_FIXED + 12,
-	TPM2_PT_INPUT_BUFFER = TPM2_PT_FIXED + 13,
-	TPM2_PT_HR_TRANSIENT_MIN = TPM2_PT_FIXED + 14,
-	TPM2_PT_HR_PERSISTENT_MIN = TPM2_PT_FIXED + 15,
-	TPM2_PT_HR_LOADED_MIN = TPM2_PT_FIXED + 16,
-	TPM2_PT_ACTIVE_SESSIONS_MAX = TPM2_PT_FIXED + 17,
-	TPM2_PT_PCR_COUNT = TPM2_PT_FIXED + 18,
-	TPM2_PT_PCR_SELECT_MIN = TPM2_PT_FIXED + 19,
-	TPM2_PT_CONTEXT_GAP_MAX = TPM2_PT_FIXED + 20,
-	TPM2_PT_NV_COUNTERS_MAX = TPM2_PT_FIXED + 22,
-	TPM2_PT_NV_INDEX_MAX = TPM2_PT_FIXED + 23,
-	TPM2_PT_MEMORY = TPM2_PT_FIXED + 24,
-	TPM2_PT_CLOCK_UPDATE = TPM2_PT_FIXED + 25,
-	TPM2_PT_CONTEXT_HASH = TPM2_PT_FIXED + 26,
-	TPM2_PT_CONTEXT_SYM = TPM2_PT_FIXED + 27,
-	TPM2_PT_CONTEXT_SYM_SIZE = TPM2_PT_FIXED + 28,
-	TPM2_PT_ORDERLY_COUNT = TPM2_PT_FIXED + 29,
-	TPM2_PT_MAX_COMMAND_SIZE = TPM2_PT_FIXED + 30,
-	TPM2_PT_MAX_RESPONSE_SIZE = TPM2_PT_FIXED + 31,
-	TPM2_PT_MAX_DIGEST = TPM2_PT_FIXED + 32,
-	TPM2_PT_MAX_OBJECT_CONTEXT = TPM2_PT_FIXED + 33,
-	TPM2_PT_MAX_SESSION_CONTEXT = TPM2_PT_FIXED + 34,
-	TPM2_PT_PS_FAMILY_INDICATOR = TPM2_PT_FIXED + 35,
-	TPM2_PT_PS_LEVEL = TPM2_PT_FIXED + 36,
-	TPM2_PT_PS_REVISION = TPM2_PT_FIXED + 37,
-	TPM2_PT_PS_DAY_OF_YEAR = TPM2_PT_FIXED + 38,
-	TPM2_PT_PS_YEAR = TPM2_PT_FIXED + 39,
-	TPM2_PT_SPLIT_MAX = TPM2_PT_FIXED + 40,
-	TPM2_PT_TOTAL_COMMANDS = TPM2_PT_FIXED + 41,
-	TPM2_PT_LIBRARY_COMMANDS = TPM2_PT_FIXED + 42,
-	TPM2_PT_VENDOR_COMMANDS = TPM2_PT_FIXED + 43,
-	TPM2_PT_NV_BUFFER_MAX = TPM2_PT_FIXED + 44,
-	TPM2_PT_MODES = TPM2_PT_FIXED + 45,
-	TPM2_PT_MAX_CAP_BUFFER = TPM2_PT_FIXED + 46,
-	TPM2_PT_VAR = TPM2_PT_GROUP * 2,
-	TPM2_PT_PERMANENT = TPM2_PT_VAR + 0,
-	TPM2_PT_STARTUP_CLEAR = TPM2_PT_VAR + 1,
-	TPM2_PT_HR_NV_INDEX = TPM2_PT_VAR + 2,
-	TPM2_PT_HR_LOADED = TPM2_PT_VAR + 3,
-	TPM2_PT_HR_LOADED_AVAIL = TPM2_PT_VAR + 4,
-	TPM2_PT_HR_ACTIVE = TPM2_PT_VAR + 5,
-	TPM2_PT_HR_ACTIVE_AVAIL = TPM2_PT_VAR + 6,
-	TPM2_PT_HR_TRANSIENT_AVAIL = TPM2_PT_VAR + 7,
-	TPM2_PT_HR_PERSISTENT = TPM2_PT_VAR + 8,
-	TPM2_PT_HR_PERSISTENT_AVAIL = TPM2_PT_VAR + 9,
-	TPM2_PT_NV_COUNTERS = TPM2_PT_VAR + 10,
-	TPM2_PT_NV_COUNTERS_AVAIL = TPM2_PT_VAR + 11,
-	TPM2_PT_ALGORITHM_SET = TPM2_PT_VAR + 12,
-	TPM2_PT_LOADED_CURVES = TPM2_PT_VAR + 13,
-	TPM2_PT_LOCKOUT_COUNTER = TPM2_PT_VAR + 14,
-	TPM2_PT_MAX_AUTH_FAIL = TPM2_PT_VAR + 15,
-	TPM2_PT_LOCKOUT_INTERVAL = TPM2_PT_VAR + 16,
-	TPM2_PT_LOCKOUT_RECOVERY = TPM2_PT_VAR + 17,
-	TPM2_PT_NV_WRITE_RECOVERY = TPM2_PT_VAR + 18,
-	TPM2_PT_AUDIT_COUNTER_0 = TPM2_PT_VAR + 19,
-	TPM2_PT_AUDIT_COUNTER_1 = TPM2_PT_VAR + 20,
-};
-
 extern const struct class tpm_class;
 extern const struct class tpmrm_class;
 extern dev_t tpm_devt;
diff --git a/drivers/char/tpm/tpm2-cmd.c b/drivers/char/tpm/tpm2-cmd.c
index 3a77be7ebf4a..1fa3e8a43c79 100644
--- a/drivers/char/tpm/tpm2-cmd.c
+++ b/drivers/char/tpm/tpm2-cmd.c
@@ -94,17 +94,6 @@ unsigned long tpm2_calc_ordinal_duration(u32 ordinal)
 	return msecs_to_jiffies(TPM2_DURATION_DEFAULT);
 }
 
-struct tpm2_pcr_read_out {
-	__be32	update_cnt;
-	__be32	pcr_selects_cnt;
-	__be16	hash_alg;
-	u8	pcr_select_size;
-	u8	pcr_select[TPM2_PCR_SELECT_MIN];
-	__be32	digests_cnt;
-	__be16	digest_size;
-	u8	digest[];
-} __packed;
-
 /**
  * tpm2_pcr_read() - read a PCR value
  * @chip:	TPM chip to use.
@@ -238,11 +227,6 @@ int tpm2_pcr_extend(struct tpm_chip *chip, u32 pcr_idx,
 	return rc;
 }
 
-struct tpm2_get_random_out {
-	__be16 size;
-	u8 buffer[TPM_MAX_RNG_DATA];
-} __packed;
-
 /**
  * tpm2_get_random() - get random bytes from the TPM RNG
  *
@@ -366,14 +350,6 @@ void tpm2_flush_context(struct tpm_chip *chip, u32 handle)
 }
 EXPORT_SYMBOL_GPL(tpm2_flush_context);
 
-struct tpm2_get_cap_out {
-	u8 more_data;
-	__be32 subcap_id;
-	__be32 property_cnt;
-	__be32 property_id;
-	__be32 value;
-} __packed;
-
 /**
  * tpm2_get_tpm_pt() - get value of a TPM_CAP_TPM_PROPERTIES type property
  * @chip:		a &tpm_chip instance
@@ -541,12 +517,6 @@ static int tpm2_init_bank_info(struct tpm_chip *chip, u32 bank_index)
 	return tpm2_pcr_read(chip, 0, &digest, &bank->digest_size);
 }
 
-struct tpm2_pcr_selection {
-	__be16  hash_alg;
-	u8  size_of_select;
-	u8  pcr_select[3];
-} __packed;
-
 ssize_t tpm2_get_pcr_allocation(struct tpm_chip *chip)
 {
 	struct tpm2_pcr_selection pcr_selection;
diff --git a/drivers/char/tpm/tpm2-space.c b/drivers/char/tpm/tpm2-space.c
index 60354cd53b5c..7c1c0a174a2b 100644
--- a/drivers/char/tpm/tpm2-space.c
+++ b/drivers/char/tpm/tpm2-space.c
@@ -15,19 +15,6 @@
 #include <linux/unaligned.h>
 #include "tpm.h"
 
-enum tpm2_handle_types {
-	TPM2_HT_HMAC_SESSION	= 0x02000000,
-	TPM2_HT_POLICY_SESSION	= 0x03000000,
-	TPM2_HT_TRANSIENT	= 0x80000000,
-};
-
-struct tpm2_context {
-	__be64 sequence;
-	__be32 saved_handle;
-	__be32 hierarchy;
-	__be16 blob_size;
-} __packed;
-
 static void tpm2_flush_sessions(struct tpm_chip *chip, struct tpm_space *space)
 {
 	int i;
diff --git a/include/linux/tpm.h b/include/linux/tpm.h
index 18dcf0ef46f6..92957452f7a7 100644
--- a/include/linux/tpm.h
+++ b/include/linux/tpm.h
@@ -38,12 +38,6 @@ struct trusted_key_options;
 /* opaque structure, holds auth session parameters like the session key */
 struct tpm2_auth;
 
-enum tpm2_session_types {
-	TPM2_SE_HMAC	= 0x00,
-	TPM2_SE_POLICY	= 0x01,
-	TPM2_SE_TRIAL	= 0x02,
-};
-
 /* if you add a new hash to this, increment TPM_MAX_HASHES below */
 enum tpm_algorithms {
 	TPM_ALG_ERROR		= 0x0000,
@@ -65,11 +59,6 @@ enum tpm_algorithms {
  */
 #define TPM_MAX_HASHES	5
 
-enum tpm2_curves {
-	TPM2_ECC_NONE		= 0x0000,
-	TPM2_ECC_NIST_P256	= 0x0003,
-};
-
 struct tpm_digest {
 	u16 alg_id;
 	u8 digest[TPM2_MAX_DIGEST_SIZE];
@@ -222,122 +211,11 @@ struct tpm_chip {
 
 #define TPM_HEADER_SIZE		10
 
-enum tpm2_const {
-	TPM2_PLATFORM_PCR       =     24,
-	TPM2_PCR_SELECT_MIN     = ((TPM2_PLATFORM_PCR + 7) / 8),
-};
-
-enum tpm2_timeouts {
-	TPM2_TIMEOUT_A          =    750,
-	TPM2_TIMEOUT_B          =   4000,
-	TPM2_TIMEOUT_C          =    200,
-	TPM2_TIMEOUT_D          =     30,
-};
-
-enum tpm2_durations {
-	TPM2_DURATION_SHORT     =     20,
-	TPM2_DURATION_LONG      =   2000,
-	TPM2_DURATION_DEFAULT   = 120000,
-};
-
-enum tpm2_structures {
-	TPM2_ST_NO_SESSIONS	= 0x8001,
-	TPM2_ST_SESSIONS	= 0x8002,
-	TPM2_ST_CREATION	= 0x8021,
-};
-
-/* Indicates from what layer of the software stack the error comes from */
-#define TSS2_RC_LAYER_SHIFT	 16
-#define TSS2_RESMGR_TPM_RC_LAYER (11 << TSS2_RC_LAYER_SHIFT)
-
-enum tpm2_return_codes {
-	TPM2_RC_SUCCESS		= 0x0000,
-	TPM2_RC_HASH		= 0x0083, /* RC_FMT1 */
-	TPM2_RC_HANDLE		= 0x008B,
-	TPM2_RC_INTEGRITY	= 0x009F,
-	TPM2_RC_INITIALIZE	= 0x0100, /* RC_VER1 */
-	TPM2_RC_FAILURE		= 0x0101,
-	TPM2_RC_DISABLED	= 0x0120,
-	TPM2_RC_UPGRADE		= 0x012D,
-	TPM2_RC_COMMAND_CODE    = 0x0143,
-	TPM2_RC_TESTING		= 0x090A, /* RC_WARN */
-	TPM2_RC_REFERENCE_H0	= 0x0910,
-	TPM2_RC_RETRY		= 0x0922,
-	TPM2_RC_SESSION_MEMORY	= 0x0903,
-};
-
-enum tpm2_command_codes {
-	TPM2_CC_FIRST		        = 0x011F,
-	TPM2_CC_HIERARCHY_CONTROL       = 0x0121,
-	TPM2_CC_HIERARCHY_CHANGE_AUTH   = 0x0129,
-	TPM2_CC_CREATE_PRIMARY          = 0x0131,
-	TPM2_CC_SEQUENCE_COMPLETE       = 0x013E,
-	TPM2_CC_SELF_TEST	        = 0x0143,
-	TPM2_CC_STARTUP		        = 0x0144,
-	TPM2_CC_SHUTDOWN	        = 0x0145,
-	TPM2_CC_NV_READ                 = 0x014E,
-	TPM2_CC_CREATE		        = 0x0153,
-	TPM2_CC_LOAD		        = 0x0157,
-	TPM2_CC_SEQUENCE_UPDATE         = 0x015C,
-	TPM2_CC_UNSEAL		        = 0x015E,
-	TPM2_CC_CONTEXT_LOAD	        = 0x0161,
-	TPM2_CC_CONTEXT_SAVE	        = 0x0162,
-	TPM2_CC_FLUSH_CONTEXT	        = 0x0165,
-	TPM2_CC_READ_PUBLIC		= 0x0173,
-	TPM2_CC_START_AUTH_SESS		= 0x0176,
-	TPM2_CC_VERIFY_SIGNATURE        = 0x0177,
-	TPM2_CC_GET_CAPABILITY	        = 0x017A,
-	TPM2_CC_GET_RANDOM	        = 0x017B,
-	TPM2_CC_PCR_READ	        = 0x017E,
-	TPM2_CC_PCR_EXTEND	        = 0x0182,
-	TPM2_CC_EVENT_SEQUENCE_COMPLETE = 0x0185,
-	TPM2_CC_HASH_SEQUENCE_START     = 0x0186,
-	TPM2_CC_CREATE_LOADED           = 0x0191,
-	TPM2_CC_LAST		        = 0x0193, /* Spec 1.36 */
-};
-
-enum tpm2_permanent_handles {
-	TPM2_RH_NULL		= 0x40000007,
-	TPM2_RS_PW		= 0x40000009,
-};
-
-/* Most Significant Octet for key types  */
-enum tpm2_mso_type {
-	TPM2_MSO_NVRAM		= 0x01,
-	TPM2_MSO_SESSION	= 0x02,
-	TPM2_MSO_POLICY		= 0x03,
-	TPM2_MSO_PERMANENT	= 0x40,
-	TPM2_MSO_VOLATILE	= 0x80,
-	TPM2_MSO_PERSISTENT	= 0x81,
-};
-
 static inline enum tpm2_mso_type tpm2_handle_mso(u32 handle)
 {
 	return handle >> 24;
 }
 
-enum tpm2_capabilities {
-	TPM2_CAP_HANDLES	= 1,
-	TPM2_CAP_COMMANDS	= 2,
-	TPM2_CAP_PCRS		= 5,
-	TPM2_CAP_TPM_PROPERTIES = 6,
-};
-
-enum tpm2_properties {
-	TPM_PT_TOTAL_COMMANDS	= 0x0129,
-};
-
-enum tpm2_startup_types {
-	TPM2_SU_CLEAR	= 0x0000,
-	TPM2_SU_STATE	= 0x0001,
-};
-
-enum tpm2_cc_attrs {
-	TPM2_CC_ATTR_CHANDLES	= 25,
-	TPM2_CC_ATTR_RHANDLE	= 28,
-	TPM2_CC_ATTR_VENDOR	= 29,
-};
-
 #define TPM_VID_INTEL    0x8086
 #define TPM_VID_WINBOND  0x1050
 #define TPM_VID_STM      0x104A
@@ -389,29 +267,6 @@ struct tpm_buf {
 	u8 handles;
 };
 
-enum tpm2_object_attributes {
-	TPM2_OA_FIXED_TPM		= BIT(1),
-	TPM2_OA_ST_CLEAR		= BIT(2),
-	TPM2_OA_FIXED_PARENT		= BIT(4),
-	TPM2_OA_SENSITIVE_DATA_ORIGIN	= BIT(5),
-	TPM2_OA_USER_WITH_AUTH		= BIT(6),
-	TPM2_OA_ADMIN_WITH_POLICY	= BIT(7),
-	TPM2_OA_NO_DA			= BIT(10),
-	TPM2_OA_ENCRYPTED_DUPLICATION	= BIT(11),
-	TPM2_OA_RESTRICTED		= BIT(16),
-	TPM2_OA_DECRYPT			= BIT(17),
-	TPM2_OA_SIGN			= BIT(18),
-};
-
-enum tpm2_session_attributes {
-	TPM2_SA_CONTINUE_SESSION	= BIT(0),
-	TPM2_SA_AUDIT_EXCLUSIVE		= BIT(1),
-	TPM2_SA_AUDIT_RESET		= BIT(3),
-	TPM2_SA_DECRYPT			= BIT(5),
-	TPM2_SA_ENCRYPT			= BIT(6),
-	TPM2_SA_AUDIT			= BIT(7),
-};
-
 struct tpm2_hash {
 	unsigned int crypto_id;
 	unsigned int tpm_id;
diff --git a/include/linux/tpm_command.h b/include/linux/tpm_command.h
index 20b634591fb1..ee76fcd5ecef 100644
--- a/include/linux/tpm_command.h
+++ b/include/linux/tpm_command.h
@@ -158,4 +158,277 @@ struct tpm1_get_random_out {
 #define TPM_NONCE_SIZE                  20
 #define TPM_ST_CLEAR			1
 
+/************************************************/
+/* TPM 2 Family Chips                           */
+/************************************************/
+
+/*
+ * TPM 2.0 Library
+ * https://trustedcomputinggroup.org/resource/tpm-library-specification/
+ */
+
+/* TPM2 specific constants. */
+#define TPM2_SPACE_BUFFER_SIZE		16384 /* 16 kB */
+
+enum tpm2_session_types {
+	TPM2_SE_HMAC	= 0x00,
+	TPM2_SE_POLICY	= 0x01,
+	TPM2_SE_TRIAL	= 0x02,
+};
+
+enum tpm2_timeouts {
+	TPM2_TIMEOUT_A		= 750,
+	TPM2_TIMEOUT_B		= 4000,
+	TPM2_TIMEOUT_C		= 200,
+	TPM2_TIMEOUT_D		= 30,
+	TPM2_DURATION_SHORT	= 20,
+	TPM2_DURATION_MEDIUM	= 750,
+	TPM2_DURATION_LONG	= 2000,
+	TPM2_DURATION_LONG_LONG	= 300000,
+	TPM2_DURATION_DEFAULT	= 120000,
+};
+
+enum tpm2_structures {
+	TPM2_ST_NO_SESSIONS	= 0x8001,
+	TPM2_ST_SESSIONS	= 0x8002,
+	TPM2_ST_CREATION	= 0x8021,
+};
+
+/* Indicates from what layer of the software stack the error comes from */
+#define TSS2_RC_LAYER_SHIFT	 16
+#define TSS2_RESMGR_TPM_RC_LAYER (11 << TSS2_RC_LAYER_SHIFT)
+
+enum tpm2_return_codes {
+	TPM2_RC_SUCCESS		= 0x0000,
+	TPM2_RC_HASH		= 0x0083, /* RC_FMT1 */
+	TPM2_RC_HANDLE		= 0x008B,
+	TPM2_RC_INTEGRITY	= 0x009F,
+	TPM2_RC_INITIALIZE	= 0x0100, /* RC_VER1 */
+	TPM2_RC_FAILURE		= 0x0101,
+	TPM2_RC_DISABLED	= 0x0120,
+	TPM2_RC_UPGRADE		= 0x012D,
+	TPM2_RC_COMMAND_CODE	= 0x0143,
+	TPM2_RC_TESTING		= 0x090A, /* RC_WARN */
+	TPM2_RC_REFERENCE_H0	= 0x0910,
+	TPM2_RC_RETRY		= 0x0922,
+	TPM2_RC_SESSION_MEMORY	= 0x0903,
+};
+
+enum tpm2_command_codes {
+	TPM2_CC_FIRST			= 0x011F,
+	TPM2_CC_HIERARCHY_CONTROL	= 0x0121,
+	TPM2_CC_HIERARCHY_CHANGE_AUTH	= 0x0129,
+	TPM2_CC_CREATE_PRIMARY		= 0x0131,
+	TPM2_CC_SEQUENCE_COMPLETE	= 0x013E,
+	TPM2_CC_SELF_TEST		= 0x0143,
+	TPM2_CC_STARTUP			= 0x0144,
+	TPM2_CC_SHUTDOWN		= 0x0145,
+	TPM2_CC_NV_READ			= 0x014E,
+	TPM2_CC_CREATE			= 0x0153,
+	TPM2_CC_LOAD			= 0x0157,
+	TPM2_CC_SEQUENCE_UPDATE		= 0x015C,
+	TPM2_CC_UNSEAL			= 0x015E,
+	TPM2_CC_CONTEXT_LOAD		= 0x0161,
+	TPM2_CC_CONTEXT_SAVE		= 0x0162,
+	TPM2_CC_FLUSH_CONTEXT		= 0x0165,
+	TPM2_CC_READ_PUBLIC		= 0x0173,
+	TPM2_CC_START_AUTH_SESS		= 0x0176,
+	TPM2_CC_VERIFY_SIGNATURE	= 0x0177,
+	TPM2_CC_GET_CAPABILITY		= 0x017A,
+	TPM2_CC_GET_RANDOM		= 0x017B,
+	TPM2_CC_PCR_READ		= 0x017E,
+	TPM2_CC_PCR_EXTEND		= 0x0182,
+	TPM2_CC_EVENT_SEQUENCE_COMPLETE	= 0x0185,
+	TPM2_CC_HASH_SEQUENCE_START	= 0x0186,
+	TPM2_CC_CREATE_LOADED		= 0x0191,
+	TPM2_CC_LAST			= 0x0193, /* Spec 1.36 */
+};
+
+enum tpm2_capabilities {
+	TPM2_CAP_HANDLES	= 1,
+	TPM2_CAP_COMMANDS	= 2,
+	TPM2_CAP_PCRS		= 5,
+	TPM2_CAP_TPM_PROPERTIES = 6,
+};
+
+enum tpm2_properties {
+	TPM_PT_TOTAL_COMMANDS	= 0x0129,
+};
+
+enum tpm2_startup_types {
+	TPM2_SU_CLEAR		= 0x0000,
+	TPM2_SU_STATE		= 0x0001,
+};
+
+enum tpm2_cc_attrs {
+	TPM2_CC_ATTR_CHANDLES	= 25,
+	TPM2_CC_ATTR_RHANDLE	= 28,
+	TPM2_CC_ATTR_VENDOR	= 29,
+};
+
+enum tpm2_permanent_handles {
+	TPM2_RH_NULL		= 0x40000007,
+	TPM2_RS_PW		= 0x40000009,
+};
+
+/* Most Significant Octet for key types  */
+enum tpm2_mso_type {
+	TPM2_MSO_NVRAM		= 0x01,
+	TPM2_MSO_SESSION	= 0x02,
+	TPM2_MSO_POLICY		= 0x03,
+	TPM2_MSO_PERMANENT	= 0x40,
+	TPM2_MSO_VOLATILE	= 0x80,
+	TPM2_MSO_PERSISTENT	= 0x81,
+};
+
+enum tpm2_curves {
+	TPM2_ECC_NONE		= 0x0000,
+	TPM2_ECC_NIST_P256	= 0x0003,
+};
+
+enum tpm2_object_attributes {
+	TPM2_OA_FIXED_TPM		= BIT(1),
+	TPM2_OA_ST_CLEAR		= BIT(2),
+	TPM2_OA_FIXED_PARENT		= BIT(4),
+	TPM2_OA_SENSITIVE_DATA_ORIGIN	= BIT(5),
+	TPM2_OA_USER_WITH_AUTH		= BIT(6),
+	TPM2_OA_ADMIN_WITH_POLICY	= BIT(7),
+	TPM2_OA_NO_DA			= BIT(10),
+	TPM2_OA_ENCRYPTED_DUPLICATION	= BIT(11),
+	TPM2_OA_RESTRICTED		= BIT(16),
+	TPM2_OA_DECRYPT			= BIT(17),
+	TPM2_OA_SIGN			= BIT(18),
+};
+
+enum tpm2_session_attributes {
+	TPM2_SA_CONTINUE_SESSION	= BIT(0),
+	TPM2_SA_AUDIT_EXCLUSIVE		= BIT(1),
+	TPM2_SA_AUDIT_RESET		= BIT(3),
+	TPM2_SA_DECRYPT			= BIT(5),
+	TPM2_SA_ENCRYPT			= BIT(6),
+	TPM2_SA_AUDIT			= BIT(7),
+};
+
+enum tpm2_pcr_select {
+	TPM2_PLATFORM_PCR	= 24,
+	TPM2_PCR_SELECT_MIN	= ((TPM2_PLATFORM_PCR + 7) / 8),
+};
+
+enum tpm2_handle_types {
+	TPM2_HT_HMAC_SESSION	= 0x02000000,
+	TPM2_HT_POLICY_SESSION	= 0x03000000,
+	TPM2_HT_TRANSIENT	= 0x80000000,
+};
+
+enum tpm2_pt_props {
+	TPM2_PT_NONE			= 0x00000000,
+	TPM2_PT_GROUP			= 0x00000100,
+	TPM2_PT_FIXED			= TPM2_PT_GROUP * 1,
+	TPM2_PT_FAMILY_INDICATOR	= TPM2_PT_FIXED + 0,
+	TPM2_PT_LEVEL		= TPM2_PT_FIXED + 1,
+	TPM2_PT_REVISION	= TPM2_PT_FIXED + 2,
+	TPM2_PT_DAY_OF_YEAR	= TPM2_PT_FIXED + 3,
+	TPM2_PT_YEAR		= TPM2_PT_FIXED + 4,
+	TPM2_PT_MANUFACTURER	= TPM2_PT_FIXED + 5,
+	TPM2_PT_VENDOR_STRING_1	= TPM2_PT_FIXED + 6,
+	TPM2_PT_VENDOR_STRING_2	= TPM2_PT_FIXED + 7,
+	TPM2_PT_VENDOR_STRING_3	= TPM2_PT_FIXED + 8,
+	TPM2_PT_VENDOR_STRING_4	= TPM2_PT_FIXED + 9,
+	TPM2_PT_VENDOR_TPM_TYPE	= TPM2_PT_FIXED + 10,
+	TPM2_PT_FIRMWARE_VERSION_1	= TPM2_PT_FIXED + 11,
+	TPM2_PT_FIRMWARE_VERSION_2	= TPM2_PT_FIXED + 12,
+	TPM2_PT_INPUT_BUFFER		= TPM2_PT_FIXED + 13,
+	TPM2_PT_HR_TRANSIENT_MIN	= TPM2_PT_FIXED + 14,
+	TPM2_PT_HR_PERSISTENT_MIN	= TPM2_PT_FIXED + 15,
+	TPM2_PT_HR_LOADED_MIN		= TPM2_PT_FIXED + 16,
+	TPM2_PT_ACTIVE_SESSIONS_MAX	= TPM2_PT_FIXED + 17,
+	TPM2_PT_PCR_COUNT	= TPM2_PT_FIXED + 18,
+	TPM2_PT_PCR_SELECT_MIN	= TPM2_PT_FIXED + 19,
+	TPM2_PT_CONTEXT_GAP_MAX	= TPM2_PT_FIXED + 20,
+	TPM2_PT_NV_COUNTERS_MAX	= TPM2_PT_FIXED + 22,
+	TPM2_PT_NV_INDEX_MAX	= TPM2_PT_FIXED + 23,
+	TPM2_PT_MEMORY		= TPM2_PT_FIXED + 24,
+	TPM2_PT_CLOCK_UPDATE	= TPM2_PT_FIXED + 25,
+	TPM2_PT_CONTEXT_HASH	= TPM2_PT_FIXED + 26,
+	TPM2_PT_CONTEXT_SYM	= TPM2_PT_FIXED + 27,
+	TPM2_PT_CONTEXT_SYM_SIZE	= TPM2_PT_FIXED + 28,
+	TPM2_PT_ORDERLY_COUNT		= TPM2_PT_FIXED + 29,
+	TPM2_PT_MAX_COMMAND_SIZE	= TPM2_PT_FIXED + 30,
+	TPM2_PT_MAX_RESPONSE_SIZE	= TPM2_PT_FIXED + 31,
+	TPM2_PT_MAX_DIGEST		= TPM2_PT_FIXED + 32,
+	TPM2_PT_MAX_OBJECT_CONTEXT	= TPM2_PT_FIXED + 33,
+	TPM2_PT_MAX_SESSION_CONTEXT	= TPM2_PT_FIXED + 34,
+	TPM2_PT_PS_FAMILY_INDICATOR	= TPM2_PT_FIXED + 35,
+	TPM2_PT_PS_LEVEL	= TPM2_PT_FIXED + 36,
+	TPM2_PT_PS_REVISION	= TPM2_PT_FIXED + 37,
+	TPM2_PT_PS_DAY_OF_YEAR	= TPM2_PT_FIXED + 38,
+	TPM2_PT_PS_YEAR		= TPM2_PT_FIXED + 39,
+	TPM2_PT_SPLIT_MAX	= TPM2_PT_FIXED + 40,
+	TPM2_PT_TOTAL_COMMANDS	= TPM2_PT_FIXED + 41,
+	TPM2_PT_LIBRARY_COMMANDS	= TPM2_PT_FIXED + 42,
+	TPM2_PT_VENDOR_COMMANDS		= TPM2_PT_FIXED + 43,
+	TPM2_PT_NV_BUFFER_MAX		= TPM2_PT_FIXED + 44,
+	TPM2_PT_MODES			= TPM2_PT_FIXED + 45,
+	TPM2_PT_MAX_CAP_BUFFER		= TPM2_PT_FIXED + 46,
+	TPM2_PT_VAR		= TPM2_PT_GROUP * 2,
+	TPM2_PT_PERMANENT	= TPM2_PT_VAR + 0,
+	TPM2_PT_STARTUP_CLEAR	= TPM2_PT_VAR + 1,
+	TPM2_PT_HR_NV_INDEX	= TPM2_PT_VAR + 2,
+	TPM2_PT_HR_LOADED	= TPM2_PT_VAR + 3,
+	TPM2_PT_HR_LOADED_AVAIL	= TPM2_PT_VAR + 4,
+	TPM2_PT_HR_ACTIVE	= TPM2_PT_VAR + 5,
+	TPM2_PT_HR_ACTIVE_AVAIL	= TPM2_PT_VAR + 6,
+	TPM2_PT_HR_TRANSIENT_AVAIL	= TPM2_PT_VAR + 7,
+	TPM2_PT_HR_PERSISTENT		= TPM2_PT_VAR + 8,
+	TPM2_PT_HR_PERSISTENT_AVAIL	= TPM2_PT_VAR + 9,
+	TPM2_PT_NV_COUNTERS		= TPM2_PT_VAR + 10,
+	TPM2_PT_NV_COUNTERS_AVAIL	= TPM2_PT_VAR + 11,
+	TPM2_PT_ALGORITHM_SET		= TPM2_PT_VAR + 12,
+	TPM2_PT_LOADED_CURVES		= TPM2_PT_VAR + 13,
+	TPM2_PT_LOCKOUT_COUNTER		= TPM2_PT_VAR + 14,
+	TPM2_PT_MAX_AUTH_FAIL		= TPM2_PT_VAR + 15,
+	TPM2_PT_LOCKOUT_INTERVAL	= TPM2_PT_VAR + 16,
+	TPM2_PT_LOCKOUT_RECOVERY	= TPM2_PT_VAR + 17,
+	TPM2_PT_NV_WRITE_RECOVERY	= TPM2_PT_VAR + 18,
+	TPM2_PT_AUDIT_COUNTER_0	= TPM2_PT_VAR + 19,
+	TPM2_PT_AUDIT_COUNTER_1	= TPM2_PT_VAR + 20,
+};
+
+struct tpm2_pcr_read_out {
+	__be32 update_cnt;
+	__be32 pcr_selects_cnt;
+	__be16 hash_alg;
+	u8 pcr_select_size;
+	u8 pcr_select[TPM2_PCR_SELECT_MIN];
+	__be32 digests_cnt;
+	__be16 digest_size;
+	u8 digest[];
+} __packed;
+
+struct tpm2_get_random_out {
+	__be16 size;
+	u8 buffer[TPM_MAX_RNG_DATA];
+} __packed;
+
+struct tpm2_get_cap_out {
+	u8 more_data;
+	__be32 subcap_id;
+	__be32 property_cnt;
+	__be32 property_id;
+	__be32 value;
+} __packed;
+
+struct tpm2_pcr_selection {
+	__be16 hash_alg;
+	u8 size_of_select;
+	u8 pcr_select[3];
+} __packed;
+
+struct tpm2_context {
+	__be64 sequence;
+	__be32 saved_handle;
+	__be32 hierarchy;
+	__be16 blob_size;
+} __packed;
+
 #endif
-- 
2.47.3


^ permalink raw reply related

* Re: [PATCH v3 1/3] ima: Remove ima_h_table structure
From: Mimi Zohar @ 2026-03-17 19:15 UTC (permalink / raw)
  To: Roberto Sassu, corbet, skhan, dmitry.kasatkin, eric.snowberg,
	paul, jmorris, serge
  Cc: linux-doc, linux-kernel, linux-integrity, linux-security-module,
	gregorylumen, chenste, nramas, Roberto Sassu
In-Reply-To: <20260311171956.2317781-1-roberto.sassu@huaweicloud.com>

On Wed, 2026-03-11 at 18:19 +0100, Roberto Sassu wrote:
> From: Roberto Sassu <roberto.sassu@huawei.com>
> 
> With the upcoming change of dynamically allocating and replacing the hash
> table, we would need to keep the counters for number of measurements
> entries and violations.
> 
> Since anyway, those counters don't belong there, remove the ima_h_table
> structure instead and move the counters and the hash table as a separate
> variables.

There's no cover letter or motivation in this patch description for needing to
"dynamically allocating or replacing the existing hash table."

Saying that the htable, number of records in the measurement list, and violation
counter don't belong grouped together is insufficient.  There must have been a
valid reason for why they were grouped together originally (e.g. never removed
or reset).

Please provide a motivation for removing the ima_h_table struct and its usage
and defining them independently of each other.

thanks,

Mimi

^ permalink raw reply

* Re: [PATCH v3 3/3] ima: Add support for staging measurements for deletion
From: Mimi Zohar @ 2026-03-17 21:03 UTC (permalink / raw)
  To: Roberto Sassu, corbet, skhan, dmitry.kasatkin, eric.snowberg,
	paul, jmorris, serge
  Cc: linux-doc, linux-kernel, linux-integrity, linux-security-module,
	gregorylumen, chenste, nramas, Roberto Sassu
In-Reply-To: <20260311171956.2317781-3-roberto.sassu@huaweicloud.com>

Hi Roberto,

On Wed, 2026-03-11 at 18:19 +0100, Roberto Sassu wrote:
> From: Roberto Sassu <roberto.sassu@huawei.com>
> 
> Introduce the ability of staging the IMA measurement list for deletion.
> Staging means moving the current content of the measurement list to a
> separate location, and allowing users to read and delete it. This causes
> the measurement list to be atomically truncated before new measurements can
> be added.

I really like this design of atomically moving and subsequently deleting the
measurement list.  However this is a solution, not the motivation for the patch.
Please include the motivation for the patch, before describing the solution.

> Staging can be done only once at a time. In the event of kexec(),
> staging is reverted and staged entries will be carried over to the new
> kernel.

> 
> Staged measurements can be deleted entirely, or partially, with the
> non-deleted ones added back to the IMA measurements list. 

This patch description is really long, which is an indication that the patch
needs to be split up.  Adding support for partially deleting the measurement
list records, by prepending the remaining measurement records, should be a
separate patch.

> This allows the
> remote attestation agents to easily separate the measurements that where
> verified (staged and deleted) from those that weren't due to the race
> between taking a TPM quote and reading the measurements list.
> 
> User space is responsible to concatenate the staged IMA measurements list
> portions (excluding the measurements added back to the IMA measurements
> list) following the temporal order in which the operations were done,
> together with the current measurement list. Then, it can send the collected
> data to the remote verifiers.

This belongs in a Documentation patch. 

> 
> The benefit of staging and deleting is the ability to free precious kernel
> memory, 

This is the motivation for the patch.

> in exchange of delegating user space to reconstruct the full
> measurement list from the chunks. No trust needs to be given to user space,
> since the integrity of the measurement list is protected by the TPM.

Agreed the measurement list, itself, is protected by the TPM.  However, relying
on userspace to reassemble the chunks is another concern. Support for staging
and deleting the measurement list should be configurable.  Defining a Kconfig
should be part of this initial patch.

> By default, staging the measurements list does not alter the hash table.
> When staging and deleting are done, IMA is still able to detect collisions
> on the staged and later deleted measurement entries, by keeping the entry
> digests (only template data are freed).
> 
> However, since during the measurements list serialization only the SHA1
> digest is passed, and since there are no template data to recalculate the
> other digests from, the hash table is currently not populated with digests
> from staged/deleted entries after kexec().
> 
> Introduce the new kernel option ima_flush_htable to decide whether or not
> the digests of staged measurement entries are flushed from the hash table,
> when they are deleted. Flushing the hash table is supported only when
> deleting all the staged measurements, since in that case the old hash table
> can be quickly swapped with a blank one (otherwise entries would have to be
> removed one by one for partial deletion).

Allowing the hash table to be deleted would be an example of another patch.

> 
> Then, introduce ascii_runtime_measurements_<algo>_staged and
> binary_runtime_measurements_<algo>_staged interfaces to stage and delete
> the measurements. Use 'echo A > <IMA interface>' and
> 'echo D > <IMA interface>' to respectively stage and delete the entire
> measurements list. Use 'echo N > <IMA interface>', with N between 1 and
> ULONG_MAX - 1, to delete the selected staged portion of the measurements
> list.
> 
> The ima_measure_users counter (protected by the ima_measure_mutex mutex)
> has been introduced to protect access to the measurements list and the
> staged part. The open method of all the measurement interfaces has been
> extended to allow only one writer at a time or, in alternative, multiple
> readers. The write permission is used to stage and delete the measurements,
> the read permission to read them. Write requires also the CAP_SYS_ADMIN
> capability.

Yes, this is part of the initial patch that adds support for staging the
measurement list.

> 
> Finally, introduce the binary_lists enum and make binary_runtime_size
> and ima_num_entries as arrays, to keep track of their values for the
> current IMA measurements list (BINARY), current list plus staged
> measurements (BINARY_STAGED) and the cumulative list since IMA
> initialization (BINARY_FULL).
> 
> Use BINARY in ima_show_measurements_count(), BINARY_STAGED in
> ima_add_kexec_buffer() and BINARY_FULL in ima_measure_kexec_event().
> 
> It should be noted that the BINARY_FULL counter is not passed through
> kexec. Thus, the number of entries included in the kexec critical data
> records refers to the entries since the previous kexec records.
> 
> Note: This code derives from the Alt-IMA Huawei project, whose license is
>       GPL-2.0 OR MIT.
> 
> Link: https://github.com/linux-integrity/linux/issues/1
> Signed-off-by: Roberto Sassu <roberto.sassu@huawei.com>

The design looks good.  As I mentioned above, this patch description is quite
long, which is an indication that the patch needs to be split up.  One method of
breaking it up would be:

- (Basic) support for staging measurements for deletion (based on a Kconfig)
- Support for removing the hash table
- Support for deleting N measurement records (and pre-pending the remaining
measurement records)
- Adding documentation

thanks,

Mimi

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox