[PATCH v4 00/17] module: Introduce hash-based integrity checking

Thomas Weißschuh posted 17 patches 3 weeks, 3 days ago
.gitignore                                   |   2 +
Documentation/kbuild/reproducible-builds.rst |   5 +-
Makefile                                     |   8 +-
arch/powerpc/kernel/ima_arch.c               |   3 +-
include/asm-generic/vmlinux.lds.h            |  11 +
include/linux/module.h                       |  20 +-
include/linux/module_hashes.h                |  25 ++
include/linux/module_signature.h             |   5 +-
kernel/module/Kconfig                        |  29 +-
kernel/module/Makefile                       |   1 +
kernel/module/hashes.c                       |  92 ++++++
kernel/module/hashes_root.c                  |   6 +
kernel/module/internal.h                     |  13 +-
kernel/module/main.c                         |  68 +++-
kernel/module/signing.c                      |  83 +----
kernel/module_signature.c                    |  49 ++-
scripts/.gitignore                           |   1 +
scripts/Makefile                             |   3 +
scripts/Makefile.lib                         |  32 ++
scripts/Makefile.modfinal                    |  28 +-
scripts/Makefile.modinst                     |  46 +--
scripts/Makefile.vmlinux                     |   6 +
scripts/link-vmlinux.sh                      |  20 +-
scripts/modules-merkle-tree.c                | 467 +++++++++++++++++++++++++++
security/integrity/ima/ima_efi.c             |   6 +-
security/integrity/ima/ima_modsig.c          |  28 +-
security/lockdown/Kconfig                    |   2 +-
27 files changed, 884 insertions(+), 175 deletions(-)
[PATCH v4 00/17] module: Introduce hash-based integrity checking
Posted by Thomas Weißschuh 3 weeks, 3 days ago
The current signature-based module integrity checking has some drawbacks
in combination with reproducible builds. Either the module signing key
is generated at build time, which makes the build unreproducible, or a
static signing key is used, which precludes rebuilds by third parties
and makes the whole build and packaging process much more complicated.

The goal is to reach bit-for-bit reproducibility. Excluding certain
parts of the build output from the reproducibility analysis would be
error-prone and force each downstream consumer to introduce new tooling.

Introduce a new mechanism to ensure only well-known modules are loaded
by embedding a merkle tree root of all modules built as part of the full
kernel build into vmlinux.

Interest has been proclaimed by NixOS, Arch Linux, Proxmox, SUSE and the
general reproducible builds community.

Compatibility with IMA modsig is not provided yet. It is still unclear
to me if it should be hooked up transparently without any changes to the
policy or it should require new policy options.

Further improvements:
* Use MODULE_SIG_HASH for configuration
* UAPI for discovery?

Signed-off-by: Thomas Weißschuh <linux@weissschuh.net>
---
Changes in v4:
- Use as Merkle tree over a linera list of hashes.
- Provide compatibilith with INSTALL_MOD_STRIP
- Rework commit messages.
- Use vmlinux.unstripped over plain "vmlinux".
- Link to v3: https://lore.kernel.org/r/20250429-module-hashes-v3-0-00e9258def9e@weissschuh.net

Changes in v3:
- Rebase on v6.15-rc1
- Use openssl to calculate hash
- Avoid warning if no modules are built
- Simplify module_integrity_check() a bit
- Make incompatibility with INSTALL_MOD_STRIP explicit
- Update docs
- Add IMA cleanups
- Link to v2: https://lore.kernel.org/r/20250120-module-hashes-v2-0-ba1184e27b7f@weissschuh.net

Changes in v2:
- Drop RFC state
- Mention interested parties in cover letter
- Expand Kconfig description
- Add compatibility with CONFIG_MODULE_SIG
- Parallelize module-hashes.sh
- Update Documentation/kbuild/reproducible-builds.rst
- Link to v1: https://lore.kernel.org/r/20241225-module-hashes-v1-0-d710ce7a3fd1@weissschuh.net

---
Coiby Xu (1):
      module: Only declare set_module_sig_enforced when CONFIG_MODULE_SIG=y

Thomas Weißschuh (16):
      powerpc/ima: Drop unnecessary check for CONFIG_MODULE_SIG
      ima: efi: Drop unnecessary check for CONFIG_MODULE_SIG/CONFIG_KEXEC_SIG
      module: Make mod_verify_sig() static
      module: Switch load_info::len to size_t
      kbuild: add stamp file for vmlinux BTF data
      kbuild: generate module BTF based on vmlinux.unstripped
      module: Deduplicate signature extraction
      module: Make module loading policy usable without MODULE_SIG
      module: Move integrity checks into dedicated function
      module: Move lockdown check into generic module loader
      module: Move signature splitting up
      module: Report signature type to users
      lockdown: Make the relationship to MODULE_SIG a dependency
      module: Introduce hash-based integrity checking
      kbuild: move handling of module stripping to Makefile.lib
      kbuild: make CONFIG_MODULE_HASHES compatible with module stripping

 .gitignore                                   |   2 +
 Documentation/kbuild/reproducible-builds.rst |   5 +-
 Makefile                                     |   8 +-
 arch/powerpc/kernel/ima_arch.c               |   3 +-
 include/asm-generic/vmlinux.lds.h            |  11 +
 include/linux/module.h                       |  20 +-
 include/linux/module_hashes.h                |  25 ++
 include/linux/module_signature.h             |   5 +-
 kernel/module/Kconfig                        |  29 +-
 kernel/module/Makefile                       |   1 +
 kernel/module/hashes.c                       |  92 ++++++
 kernel/module/hashes_root.c                  |   6 +
 kernel/module/internal.h                     |  13 +-
 kernel/module/main.c                         |  68 +++-
 kernel/module/signing.c                      |  83 +----
 kernel/module_signature.c                    |  49 ++-
 scripts/.gitignore                           |   1 +
 scripts/Makefile                             |   3 +
 scripts/Makefile.lib                         |  32 ++
 scripts/Makefile.modfinal                    |  28 +-
 scripts/Makefile.modinst                     |  46 +--
 scripts/Makefile.vmlinux                     |   6 +
 scripts/link-vmlinux.sh                      |  20 +-
 scripts/modules-merkle-tree.c                | 467 +++++++++++++++++++++++++++
 security/integrity/ima/ima_efi.c             |   6 +-
 security/integrity/ima/ima_modsig.c          |  28 +-
 security/lockdown/Kconfig                    |   2 +-
 27 files changed, 884 insertions(+), 175 deletions(-)
---
base-commit: 8f0b4cce4481fb22653697cced8d0d04027cb1e8
change-id: 20241225-module-hashes-7a50a7cc2a30

Best regards,
-- 
Thomas Weißschuh <linux@weissschuh.net>

Re: [PATCH v4 00/17] module: Introduce hash-based integrity checking
Posted by Mihai-Drosi Câju 6 days, 20 hours ago
> The current signature-based module integrity checking has some drawbacks
in combination with reproducible builds. Either the module signing key
is generated at build time, which makes the build unreproducible, or a
static signing key is used, which precludes rebuilds by third parties
and makes the whole build and packaging process much more complicated.

I think there is a middle ground where the module signing key is generated
using a key derivation function that has as an input a deterministic value
on the build host, such as /etc/machine-id . The problem with this approach
is that only hosts knowing the value will be able to reproduce the build.

Maybe this is a solution to NixOS secret management? Introduce minimal
impurity as a cryptographic seed and derive the rest of the secrets using
something like Argon2(seed, key_uuid).

There might be another approach to code integrity rather than step-by-step
reproducibility. One may exploit the very cryptographic primitives that make
reproducibility hard to ensure that reproducibility is most  likely valid.

For example, the module signing issue, the build host publishes four artifacts:
* The source-code
* The compiled and signed binary
* The build environment
* Its public key

Now, we don't need to sign with the private key to know that building the source
code using the specific build environment and signing the result with the private
key will result in the claimed binary. We can just compile and verify with the
public key.

So a traditional workflow would be:
compiled_module + module_signature == module

In this case we build the module, sign it with whatever key, distribute the
builds and the private key to whoever wants to reproduce the build. Or we build
locally and the key stays with the end-user.

While the cryptographic approach would be:
verify(compiled_code, module.signature) is True

In this case we distribute the builds, source code and the public key. While
everyone can ensure that the compiled code is the result of the build
environment and source code. The signature is verified using cryptographic
means.

As long as no one cracks RSA or an algorithm of our choosing/has an absurd
amount of luck, the cryptographic approach would be just as good as the traditional
approach at ensuring that a program has stopped with a certain output.
Re: [PATCH v4 00/17] module: Introduce hash-based integrity checking
Posted by David Howells 5 days, 11 hours ago
Mihai-Drosi Câju <mcaju95@gmail.com> wrote:

> > The current signature-based module integrity checking has some drawbacks
> in combination with reproducible builds. Either the module signing key
> is generated at build time, which makes the build unreproducible, or a
> static signing key is used, which precludes rebuilds by third parties
> and makes the whole build and packaging process much more complicated.

There is another issue too: If you have a static private key that you use to
sign modules (and probably other things), someone will likely give you a GPL
request to get it.

One advantage of using a transient key every build and deleting it after is
that no one has the key.

One other thing to remember: security is *meant* to get in the way.  That's
the whole point of it.

However, IANAL.

David
Re: [PATCH v4 00/17] module: Introduce hash-based integrity checking
Posted by James Bottomley 3 days, 20 hours ago
On Sun, 2026-02-01 at 17:09 +0000, David Howells wrote:
> Mihai-Drosi Câju <mcaju95@gmail.com> wrote:
> 
> > > The current signature-based module integrity checking has some
> > > drawbacks
> > in combination with reproducible builds. Either the module signing
> > key is generated at build time, which makes the build
> > unreproducible, or a static signing key is used, which precludes
> > rebuilds by third parties and makes the whole build and packaging
> > process much more complicated.
> 
> There is another issue too: If you have a static private key that you
> use to sign modules (and probably other things), someone will likely
> give you a GPL request to get it.

The SFC just lost that exact point in the Vizio trial, so I think
you're wrong on this under US law at least.  There's no general ability
under GPLv2 to demand long lived signing keys.

Regards,

James
Re: [PATCH v4 00/17] module: Introduce hash-based integrity checking
Posted by David Howells 3 days, 20 hours ago
James Bottomley <James.Bottomley@HansenPartnership.com> wrote:

> > There is another issue too: If you have a static private key that you
> > use to sign modules (and probably other things), someone will likely
> > give you a GPL request to get it.
> 
> The SFC just lost that exact point in the Vizio trial, so I think
> you're wrong on this under US law at least.  There's no general ability
> under GPLv2 to demand long lived signing keys.

Cool :-).  I just know that I've been sent GPL requests for kernel keys.

David
Re: [PATCH v4 00/17] module: Introduce hash-based integrity checking
Posted by Eric Biggers 5 days, 8 hours ago
On Sun, Feb 01, 2026 at 05:09:48PM +0000, David Howells wrote:
> Mihai-Drosi Câju <mcaju95@gmail.com> wrote:
> 
> > > The current signature-based module integrity checking has some drawbacks
> > in combination with reproducible builds. Either the module signing key
> > is generated at build time, which makes the build unreproducible, or a
> > static signing key is used, which precludes rebuilds by third parties
> > and makes the whole build and packaging process much more complicated.
> 
> There is another issue too: If you have a static private key that you use to
> sign modules (and probably other things), someone will likely give you a GPL
> request to get it.
> 
> One advantage of using a transient key every build and deleting it after is
> that no one has the key.
> 
> One other thing to remember: security is *meant* to get in the way.  That's
> the whole point of it.
> 
> However, IANAL.
> 
> David

It sounds like hash-based module authentication is just better, then.
If the full set of authentic modules is known at kernel build time, then
signatures are unnecessary to verify their authenticity: a list of
hashes built into the kernel image is perfectly sufficient.

(This patchset actually gets a little fancy and makes it a Merkle tree
root.  But it could be simplified to just a list of hashes.)

With that being the case, why is there still effort being put into
adding more features to module signing?  I would think efforts should be
focused on hash-based module authentication, i.e. this patchset.

- Eric
Re: [PATCH v4 00/17] module: Introduce hash-based integrity checking
Posted by David Howells 4 days, 19 hours ago
Eric Biggers <ebiggers@kernel.org> wrote:

> With that being the case, why is there still effort being put into
> adding more features to module signing?  I would think efforts should be
> focused on hash-based module authentication, i.e. this patchset.

Because it's not just signing of modules and it's not just modules built with
the kernel.  Also a hash table just of module hashes built into the core
kernel image will increase the size of the kernel by around a third of a meg
(on Fedora 43 and assuming SHA512) with uncompressible data.

David
Re: [PATCH v4 00/17] module: Introduce hash-based integrity checking
Posted by Eric Biggers 4 days, 9 hours ago
On Mon, Feb 02, 2026 at 09:21:19AM +0000, David Howells wrote:
> Eric Biggers <ebiggers@kernel.org> wrote:
> 
> > With that being the case, why is there still effort being put into
> > adding more features to module signing?  I would think efforts should be
> > focused on hash-based module authentication, i.e. this patchset.
> 
> Because it's not just signing of modules

Module signing is indeed about the signing of modules.

> and it's not just modules built with the kernel.

Could you give more details on this use case and why it needs
signatures, as opposed to e.g. loading an additional Merkle tree root
into the kernel to add to the set of allowed modules?

> Also a hash table just of module hashes built into the core
> kernel image will increase the size of the kernel by around a third of a meg
> (on Fedora 43 and assuming SHA512) with uncompressible data.

This patchset already optimizes it to use Merkle tree proofs instead.
While I'm a bit skeptical of the complexity myself (and distros
shouldn't be shipping such an excessively large number of modules in the
first place), if it's indeed needed it's already been solved.  It's
still much simpler than the PKCS#7 signature mess.

- Eric
Re: [PATCH v4 00/17] module: Introduce hash-based integrity checking
Posted by David Howells 4 days, 9 hours ago
Eric Biggers <ebiggers@kernel.org> wrote:

> On Mon, Feb 02, 2026 at 09:21:19AM +0000, David Howells wrote:
> > Eric Biggers <ebiggers@kernel.org> wrote:
> > 
> > > With that being the case, why is there still effort being put into
> > > adding more features to module signing?  I would think efforts should be
> > > focused on hash-based module authentication, i.e. this patchset.
> > 
> > Because it's not just signing of modules
> 
> Module signing is indeed about the signing of modules.

The signature verification stuff in the kernel isn't just used for modules.
kexec, for instance; wifi restriction database for another.

> > and it's not just modules built with the kernel.
> 
> Could you give more details on this use case and why it needs
> signatures, as opposed to e.g. loading an additional Merkle tree root
> into the kernel to add to the set of allowed modules?

Because we don't want to, for example, include all the nvidia drivers in our
kernel SRPM.

David
Re: [PATCH v4 00/17] module: Introduce hash-based integrity checking
Posted by Eric Biggers 4 days, 9 hours ago
On Mon, Feb 02, 2026 at 06:38:51PM +0000, David Howells wrote:
> > Could you give more details on this use case and why it needs
> > signatures, as opposed to e.g. loading an additional Merkle tree root
> > into the kernel to add to the set of allowed modules?
> 
> Because we don't want to, for example, include all the nvidia drivers in our
> kernel SRPM.

That doesn't answer my question.  Are you trying to say these modules
need to be built later *and* signed using the original signing key?

- Eric
Re: [PATCH v4 00/17] module: Introduce hash-based integrity checking
Posted by Thomas Weißschuh 5 days, 12 hours ago
Hi Mihai-Drosi,

thanks for taking an interest into these patches!

On 2026-01-31 09:36:36+0200, Mihai-Drosi Câju wrote:
> > The current signature-based module integrity checking has some drawbacks
> > in combination with reproducible builds. Either the module signing key
> > is generated at build time, which makes the build unreproducible, or a
> > static signing key is used, which precludes rebuilds by third parties
> > and makes the whole build and packaging process much more complicated.
> 
> I think there is a middle ground where the module signing key is generated
> using a key derivation function that has as an input a deterministic value
> on the build host, such as /etc/machine-id . The problem with this approach
> is that only hosts knowing the value will be able to reproduce the build.

The goal is to make the distro kernel packages rebuildable by the
general public. Any involvement of secret values will break this goal.

> Maybe this is a solution to NixOS secret management? Introduce minimal
> impurity as a cryptographic seed and derive the rest of the secrets using
> something like Argon2(seed, key_uuid).

I am not familiar with NixOS and its secret management.
This patchset serves a wider audience.

> There might be another approach to code integrity rather than step-by-step
> reproducibility. One may exploit the very cryptographic primitives that make
> reproducibility hard to ensure that reproducibility is most  likely valid.
> 
> For example, the module signing issue, the build host publishes four artifacts:
> * The source-code
> * The compiled and signed binary
> * The build environment
> * Its public key
> 
> Now, we don't need to sign with the private key to know that building the source
> code using the specific build environment and signing the result with the private
> key will result in the claimed binary. We can just compile and verify with the
> public key.

This could work if the goal is only to verify the reproducibility of a
single, signed-en-bloc artifact. But we also need to handle vmlinux which
contains the corresponding public key. It would need different handling.
We can add some special logic to strip that public key before
comparision. But then vmlinux might be compressed or wrapped in some
other format. Another whole collection of special logic.

(...)


Thomas