Chapter 22. Signing a kernel and modules for Secure Boot


Enhance system security by using signed kernels and kernel modules. On UEFI-based systems with Secure Boot enabled, self-sign privately built kernels or modules and import the public key into target systems.

If Secure Boot is enabled, all of the following components have to be signed with a private key and authenticated with the corresponding public key:

  • UEFI operating system boot loader
  • The Red Hat Enterprise Linux kernel
  • All kernel modules

If any of these components are not signed and authenticated, the system cannot finish the booting process.

Red Hat Enterprise Linux includes:

  • Signed boot loaders
  • Signed kernels
  • Signed kernel modules

In addition, the signed first-stage boot loader (shim) and the signed kernel include embedded Red Hat public keys. These signed executable binaries and embedded keys enable Red Hat Enterprise Linux to install, boot, and run with the Microsoft UEFI Secure Boot Certification Authority keys. These keys are provided by the UEFI firmware on systems that support UEFI Secure Boot.

Note
  • Not all UEFI-based systems include support for Secure Boot.
  • The build system, where you build and sign your kernel module, does not need to have UEFI Secure Boot enabled and does not even need to be a UEFI-based system.

22.1. Prerequisites

  • To be able to sign externally built kernel modules, install the utilities from the following packages:

    # dnf install pesign openssl kernel-devel mokutil keyutils
    Copy to Clipboard Toggle word wrap
    Expand
    Table 22.1. Required utilities
    UtilityProvided by packageUsed onPurpose

    efikeygen

    pesign

    Build system

    Generates public and private X.509 key pair

    openssl

    openssl

    Build system

    Exports the unencrypted private key

    sign-file

    kernel-devel

    Build system

    Executable file used to sign a kernel module with the private key

    mokutil

    mokutil

    Target system

    Optional utility used to manually enroll the public key

    keyctl

    keyutils

    Target system

    Optional utility used to display public keys in the system keyring

22.2. What is UEFI Secure Boot

With the Unified Extensible Firmware Interface (UEFI) Secure Boot technology, you can prevent the execution of the kernel-space code that is not signed by a trusted key. The system boot loader is signed with a cryptographic key. The database of public keys in the firmware authorizes the process of signing the key.

You can subsequently verify a signature in the next-stage boot loader and the kernel.

UEFI Secure Boot establishes a chain of trust from the firmware to the signed drivers and kernel modules as follows:

  • An UEFI private key signs, and a public key authenticates the shim first-stage boot loader. A certificate authority (CA) in turn signs the public key. The CA is stored in the firmware database.
  • The shim file contains the Red Hat public key Red Hat Secure Boot (CA key 1) to authenticate the GRUB boot loader and the kernel.
  • The kernel in turn contains public keys to authenticate drivers and modules.

Secure Boot is the boot path validation component of the UEFI specification. The specification defines:

  • Programming interface for cryptographically protected UEFI variables in non-volatile storage.
  • Storing the trusted X.509 root certificates in UEFI variables.
  • Validation of UEFI applications such as boot loaders and drivers.
  • Procedures to revoke known-bad certificates and application hashes.

UEFI Secure Boot helps in the detection of unauthorized changes but does not:

  • Prevent installation or removal of second-stage boot loaders.
  • Require explicit user confirmation of such changes.
  • Stop boot path manipulations. Signatures are verified during booting but not when the boot loader is installed or updated.

If the boot loader or the kernel are not signed by a system trusted key, Secure Boot prevents them from starting.

22.3. UEFI Secure Boot support

You can install and run Red Hat Enterprise Linux 10 on systems with enabled UEFI Secure Boot if the kernel and all the loaded drivers are signed with a trusted key. Red Hat provides kernels and drivers that are signed and authenticated by the applicable Red Hat keys.

If you want to load externally built kernels or drivers, you must sign them as well.

Restrictions imposed by UEFI Secure Boot
  • The system only runs the kernel-mode code after its signature has been properly authenticated.
  • GRUB module loading is disabled because there is no infrastructure for signing and verification of GRUB modules. Allowing module loading would run untrusted code within the security perimeter defined by Secure Boot.
  • Red Hat provides a signed GRUB binary that has all supported modules on Red Hat Enterprise Linux.

Review the requirements for authenticating kernel modules with X.509 keys. The kernel validates module signatures against trusted keyrings, such as .builtin_trusted_keys and .platform, to enforce security policies based on the UEFI Secure Boot configuration.

In Red Hat Enterprise Linux 10, when a kernel module is loaded, the kernel checks the signature of the module against the public X.509 keys from the kernel system keyring (.builtin_trusted_keys) and the kernel platform keyring (.platform). The .platform keyring provides keys from third-party platform providers and custom public keys. The keys from the kernel system .blacklist keyring are excluded from verification.

You need to meet certain conditions to load kernel modules on systems with enabled UEFI Secure Boot functionality:

  • If UEFI Secure Boot is enabled or if the module.sig_enforce kernel parameter has been specified:

    • You can only load those signed kernel modules whose signatures were authenticated against keys from the system keyring (.builtin_trusted_keys) or the platform keyring (.platform).
    • The public key must not be on the system revoked keys keyring (.blacklist).
  • If UEFI Secure Boot is disabled and the module.sig_enforce kernel parameter has not been specified:

    • You can load unsigned kernel modules and signed kernel modules without a public key.
  • If the system is not UEFI-based or if UEFI Secure Boot is disabled:

    • Only the keys embedded in the kernel are loaded onto .builtin_trusted_keys and .platform.
    • You have no ability to augment that set of keys without rebuilding the kernel.
Expand
Table 22.2. Kernel module authentication requirements for loading
Module signedPublic key found and signature validUEFI Secure Boot statesig_enforceModule loadKernel tainted

Unsigned

-

Not enabled

Not enabled

Succeeds

Yes

Not enabled

Enabled

Fails

-

Enabled

-

Fails

-

Signed

No

Not enabled

Not enabled

Succeeds

Yes

Not enabled

Enabled

Fails

-

Enabled

-

Fails

-

Signed

Yes

Not enabled

Not enabled

Succeeds

No

Not enabled

Enabled

Succeeds

No

Enabled

-

Succeeds

No

22.5. Sources for public keys

Review the sources of X.509 keys that the kernel loads into system keyrings during boot. The kernel uses these keys, derived from persistent stores like the UEFI database and the Machine Owner Key (MOK) list, to verify the integrity of modules and binaries.

  • The system keyring (.builtin_trusted_keys)
  • The .platform keyring
  • The system .blacklist keyring
Expand
Table 22.3. Sources for system keyrings
Source of X.509 keysUser can add keysUEFI Secure Boot stateKeys loaded during boot

Embedded in kernel

No

-

.builtin_trusted_keys

UEFI db

Limited

Not enabled

No

Enabled

.platform

Embedded in the shim boot loader

No

Not enabled

No

Enabled

.platform

Machine Owner Key (MOK) list

Yes

Not enabled

No

Enabled

.platform

.builtin_trusted_keys
  • A keyring that is built on boot.
  • Provides trusted public keys.
  • root privileges are required to view the keys.
.platform
  • A keyring that is built on boot.
  • Provides keys from third-party platform providers and custom public keys.
  • root privileges are required to view the keys.
.blacklist
  • A keyring with X.509 keys which have been revoked.
  • A module signed by a key from .blacklist will fail authentication even if your public key is in .builtin_trusted_keys.
  • root privileges are required to view the keys.
UEFI Secure Boot db
  • A signature database.
  • Stores keys (hashes) of UEFI applications, UEFI drivers, and boot loaders.
  • The keys can be loaded on the machine.
UEFI Secure Boot dbx
  • A revoked signature database.
  • Prevents keys from getting loaded.
  • The revoked keys from this database are added to the .blacklist keyring.

22.6. Generating a public and private key pair

To use a custom kernel or modules on a Secure Boot system, generate an X.509 key pair. Sign the kernel or modules with the private key, and enroll the public key in the Machine Owner Key (MOK) list for validation.

Prerequisites

  • You have root permissions on the system.

Procedure

  • Create an X.509 public and private key pair.

    • If you only want to sign custom kernel modules:

      # efikeygen --dbdir /etc/pki/pesign \
                  --self-sign \
                  --module \
                  --common-name 'CN=Organization signing key' \
                  --nickname 'Custom Secure Boot key'
      Copy to Clipboard Toggle word wrap
    • If you want to sign custom kernel:

      # efikeygen --dbdir /etc/pki/pesign \
                  --self-sign \
                  --kernel \
                  --common-name 'CN=Organization signing key' \
                  --nickname 'Custom Secure Boot key'
      Copy to Clipboard Toggle word wrap
    • When the RHEL system is running FIPS mode:

      # efikeygen --dbdir /etc/pki/pesign \
                  --self-sign \
                  --kernel \
                  --common-name 'CN=Organization signing key' \
                  --nickname 'Custom Secure Boot key' \
                  --token 'NSS FIPS 140-2 Certificate DB'
      Copy to Clipboard Toggle word wrap
      Note

      In FIPS mode, you must use the --token option so that efikeygen finds the default "NSS Certificate DB" token in the PKI database.

      The public and private keys are now stored in the /etc/pki/pesign/ directory. See the openssl(1) man page on your system for more information.

      Important

      It is a good security practice to sign the kernel and the kernel modules within the validity period of its signing key. However, the sign-file utility does not warn you and the key will be usable in Red Hat Enterprise Linux 10 regardless of the validity dates.

22.7. Example output of system keyrings

You can display information about the keys on the system keyrings using the keyctl utility from the keyutils package.

Keyrings output

The following is a shortened example output of .builtin_trusted_keys, .platform, and .blacklist keyrings from a Red Hat Enterprise Linux 10 system where UEFI Secure Boot is enabled.

# keyctl list %:.builtin_trusted_keys
6 keys in keyring:
...asymmetric: Red Hat Enterprise Linux Driver Update Program (key 3): bf57f3e87...
...asymmetric: Red Hat Secure Boot (CA key 1): 4016841644ce3a810408050766e8f8a29...
...asymmetric: Microsoft Corporation UEFI CA 2011: 13adbf4309bd82709c8cd54f316ed...
...asymmetric: Microsoft Windows Production PCA 2011: a92902398e16c49778cd90f99e...
...asymmetric: Red Hat Enterprise Linux kernel signing key: 4249689eefc77e95880b...
...asymmetric: Red Hat Enterprise Linux kpatch signing key: 4d38fd864ebe18c5f0b7...

# keyctl list %:.platform
4 keys in keyring:
...asymmetric: VMware, Inc.: 4ad8da0472073...
...asymmetric: Red Hat Secure Boot CA 5: cc6fafe72...
...asymmetric: Microsoft Windows Production PCA 2011: a929f298e1...
...asymmetric: Microsoft Corporation UEFI CA 2011: 13adbf4e0bd82...

# keyctl list %:.blacklist
4 keys in keyring:
...blacklist: bin:f5ff83a...
...blacklist: bin:0dfdbec...
...blacklist: bin:38f1d22...
...blacklist: bin:51f831f...
Copy to Clipboard Toggle word wrap

The .builtin_trusted_keys keyring in the example shows the addition of two keys from the UEFI Secure Boot db keys and the Red Hat Secure Boot (CA key 1), which is embedded in the shim boot loader.

Kernel console output

The following example shows the kernel console output. The messages identify the keys with an UEFI Secure Boot related source. These include UEFI Secure Boot db, embedded shim, and MOK list.

# dmesg | grep -E 'integrity.*cert'
[1.512966] integrity: Loading X.509 certificate: UEFI:db
[1.513027] integrity: Loaded X.509 cert 'Microsoft Windows Production PCA 2011: a929023...
[1.513028] integrity: Loading X.509 certificate: UEFI:db
[1.513057] integrity: Loaded X.509 cert 'Microsoft Corporation UEFI CA 2011: 13adbf4309...
[1.513298] integrity: Loading X.509 certificate: UEFI:MokListRT (MOKvar table)
[1.513549] integrity: Loaded X.509 cert 'Red Hat Secure Boot CA 5: cc6fa5e72868ba494e93...
Copy to Clipboard Toggle word wrap

See keyctl(1) and dmesg(1) man pages on your system for more information.

To access the kernel or kernel modules, you must authenticate your public key and enroll it in the target system’s platform keyring (.platform). On UEFI Secure Boot systems, the kernel imports keys from the db database while excluding revoked keys from the dbx database.

The Machine Owner Key (MOK) facility allows expanding the UEFI Secure Boot key database. When booting RHEL 10 on UEFI-enabled systems with Secure Boot enabled, keys on the MOK list are added to the platform keyring (.platform), along with the keys from the Secure Boot database. The list of MOK keys is stored securely and persistently in the same way, but it is a separate facility from the Secure Boot databases.

The MOK facility is supported by shim, MokManager, GRUB, and the mokutil utility that enables secure key management and authentication for UEFI-based systems.

Note

To get the authentication service of your kernel module on your systems, consider requesting your system vendor to incorporate your public key into the UEFI Secure Boot key database in their factory firmware image.

Prerequisites

Procedure

  1. Export your public key to the sb_cert.cer file:

    # certutil -d /etc/pki/pesign \
               -n 'Custom Secure Boot key' \
               -Lr \
               > sb_cert.cer
    Copy to Clipboard Toggle word wrap
  2. Import your public key into the MOK list:

    # mokutil --import sb_cert.cer
    Copy to Clipboard Toggle word wrap
  3. Enter a new password for this MOK enrollment request.
  4. Reboot the machine.

    The shim boot loader notices the pending MOK key enrollment request and it launches MokManager.efi to enable you to complete the enrollment from the UEFI console.

  5. Choose Enroll MOK, enter the password you previously associated with this request when prompted, and confirm the enrollment.

    Your public key is added to the MOK list, which is persistent.

    Once a key is on the MOK list, it will be automatically propagated to the .platform keyring on this and subsequent boots when UEFI Secure Boot is enabled.

22.9. Signing a kernel with the private key

To enhance system security on UEFI Secure Boot systems, load a kernel signed with a private key.

Prerequisites

Procedure

  • On the x64 architecture:

    1. Create a signed image:

      # pesign --certificate 'Custom Secure Boot key' \
               --in vmlinuz-version \
               --sign \
               --out vmlinuz-version.signed
      Copy to Clipboard Toggle word wrap

      Replace version with the version suffix of your vmlinuz file, and Custom Secure Boot key with the name that you chose earlier.

    2. Optional: Check the signatures:

      # pesign --show-signature \
               --in vmlinuz-version.signed
      Copy to Clipboard Toggle word wrap
    3. Overwrite the unsigned image with the signed image:

      # mv vmlinuz-version.signed vmlinuz-version
      Copy to Clipboard Toggle word wrap
  • On the 64-bit ARM architecture:

    1. Decompress the vmlinuz file:

      # zcat vmlinuz-version > vmlinux-version
      Copy to Clipboard Toggle word wrap
    2. Create a signed image:

      # pesign --certificate 'Custom Secure Boot key' \
               --in vmlinux-version \
               --sign \
               --out vmlinux-version.signed
      Copy to Clipboard Toggle word wrap
    3. Optional: Check the signatures:

      # pesign --show-signature \
               --in vmlinux-version.signed
      Copy to Clipboard Toggle word wrap
    4. Compress the vmlinux file:

      # gzip --to-stdout vmlinux-version.signed > vmlinuz-version
      Copy to Clipboard Toggle word wrap
    5. Remove the uncompressed vmlinux file:

      # rm vmlinux-version*
      Copy to Clipboard Toggle word wrap

22.10. Signing a GRUB build with the private key

To use a custom GRUB build on a UEFI Secure Boot system, sign it with a private key. This is required for custom builds or if the Microsoft trust anchor is removed.

Prerequisites

Procedure

  • On the x64 architecture:

    1. Create a signed GRUB EFI binary:

      # pesign --in /boot/efi/EFI/redhat/grubx64.efi \
               --out /boot/efi/EFI/redhat/grubx64.efi.signed \
               --certificate 'Custom Secure Boot key' \
               --sign
      Copy to Clipboard Toggle word wrap

      Replace Custom Secure Boot key with the name that you chose earlier.

    2. Optional: Check the signatures:

      # pesign --in /boot/efi/EFI/redhat/grubx64.efi.signed \
               --show-signature
      Copy to Clipboard Toggle word wrap
    3. Overwrite the unsigned binary with the signed binary:

      # mv /boot/efi/EFI/redhat/grubx64.efi.signed \
           /boot/efi/EFI/redhat/grubx64.efi
      Copy to Clipboard Toggle word wrap
      Warning

      When overwriting the grub binary, your system might fail to boot normally and you might require reinstalling the grub from the system image.

  • On the 64-bit ARM architecture:

    1. Create a signed GRUB EFI binary:

      # pesign --in /boot/efi/EFI/redhat/grubaa64.efi \
               --out /boot/efi/EFI/redhat/grubaa64.efi.signed \
               --certificate 'Custom Secure Boot key' \
               --sign
      Copy to Clipboard Toggle word wrap

      Replace Custom Secure Boot key with the name that you chose earlier.

    2. Optional: Check the signatures:

      # pesign --in /boot/efi/EFI/redhat/grubaa64.efi.signed \
               --show-signature
      Copy to Clipboard Toggle word wrap
    3. Overwrite the unsigned binary with the signed binary:

      # mv /boot/efi/EFI/redhat/grubaa64.efi.signed \
           /boot/efi/EFI/redhat/grubaa64.efi
      Copy to Clipboard Toggle word wrap

22.11. Signing kernel modules with the private key

To enhance security on UEFI Secure Boot systems, load kernel modules signed with a private key.

Your signed kernel module is also loadable on systems where UEFI Secure Boot is disabled or on a non-UEFI system. As a result, you do not need to provide both, a signed and unsigned version of your kernel module.

Prerequisites

Procedure

  1. Export your public key to the sb_cert.cer file:

    # certutil -d /etc/pki/pesign \
               -n 'Custom Secure Boot key' \
               -Lr \
               > sb_cert.cer
    Copy to Clipboard Toggle word wrap
  2. Extract the key from the NSS database as a PKCS #12 file:

    # pk12util -o sb_cert.p12 \
               -n 'Custom Secure Boot key' \
               -d /etc/pki/pesign
    Copy to Clipboard Toggle word wrap
  3. When the previous command prompts, enter a new password that encrypts the private key.
  4. Export the unencrypted private key:

    # openssl pkcs12 \
             -in sb_cert.p12 \
             -out sb_cert.priv \
             -nocerts \
             -noenc
    Copy to Clipboard Toggle word wrap
    Important

    Keep the unencrypted private key secure.

  5. Sign your kernel module. The following command appends the signature directly to the ELF image in your kernel module file:

    # /usr/src/kernels/$(uname -r)/scripts/sign-file \
              sha256 \
              sb_cert.priv \
              sb_cert.cer \
              my_module.ko
    Copy to Clipboard Toggle word wrap

    Your kernel module is now ready for loading.

    Important

    In Red Hat Enterprise Linux 10, the validity dates of the key pair matter. The key does not expire, but the kernel module must be signed within the validity period of its signing key. The sign-file utility will not warn you of this.

    For example, a key that is only valid in 2021 can be used to authenticate a kernel module signed in 2021 with that key. However, users cannot use that key to sign a kernel module in 2022.

Verification

  1. Display information about the kernel module’s signature:

    # modinfo my_module.ko | grep signer
    Copy to Clipboard Toggle word wrap
      signer:         Your Name Key
    Copy to Clipboard Toggle word wrap

    Check that the signature lists your name as entered during generation.

    Note

    The appended signature is not contained in an ELF image section and is not a formal part of the ELF image. Therefore, utilities such as readelf cannot display the signature on your kernel module.

  2. Load the module:

    # insmod my_module.ko
    Copy to Clipboard Toggle word wrap
  3. Remove (unload) the module:

    # modprobe -r my_module.ko
    Copy to Clipboard Toggle word wrap

22.12. Loading signed kernel modules

To load signed kernel modules, ensure your public key is enrolled in the platform keyring and Machine Owner Key (MOK) list, then use the modprobe command.

Prerequisites

Procedure

  1. Verify that your public keys are on the platform keyring:

    # keyctl list %:.platform
    Copy to Clipboard Toggle word wrap
  2. Copy the kernel module into the extra/ directory of the kernel that you want:

    # cp my_module.ko /lib/modules/$(uname -r)/extra/
    Copy to Clipboard Toggle word wrap
  3. Update the modular dependency list:

    # depmod -a
    Copy to Clipboard Toggle word wrap
  4. Load the kernel module:

    # modprobe -v my_module
    Copy to Clipboard Toggle word wrap
  5. Optional: To load the module on boot, add it to the /etc/modules-loaded.d/my_module.conf file:

    # echo "my_module" > /etc/modules-load.d/my_module.conf
    Copy to Clipboard Toggle word wrap

Verification

  • Verify that the module was successfully loaded:

    # lsmod | grep my_module
    Copy to Clipboard Toggle word wrap
Red Hat logoGithubredditYoutubeTwitter

Learn

Try, buy, & sell

Communities

About Red Hat Documentation

We help Red Hat users innovate and achieve their goals with our products and services with content they can trust. Explore our recent updates.

Making open source more inclusive

Red Hat is committed to replacing problematic language in our code, documentation, and web properties. For more details, see the Red Hat Blog.

About Red Hat

We deliver hardened solutions that make it easier for enterprises to work across platforms and environments, from the core datacenter to the network edge.

Theme

© 2026 Red Hat
Back to top