Sign Kernel Modules to Verify Authenticity¶
About This Task¶
Depending on your system configuration, it may be necessary to to sign kernel driver modules using Machine Owner Keys (MOK) for the kernel to recognize or load them for use.
Kernel Module Signing Overview¶
eLxr 12 includes support for signing out-of-tree kernel modules, including standalone and Dynamic Kernel Module System (DKMS), which support the automatic rebuilding of kernel modules when the kernel is updated.
Support begins in the kernel driver source itself. For kernel modules, such as the hello-world kernel module used in this tutorial, signing is enabled in the kernel source hello-world/debian/rules file using the WITH_MOD_SIGN ?= 1 option. Once set, it runs the following command at the end of the file to sign the module using the private and public keys:
/usr/lib/linux-kbuild-*/scripts/sign-file sha256 $(privkey) $(pubkey) \
./debian/$(pkg_name)/lib/modules/$(kversion)/extra/$(kmod_name)/$(kmod_name).ko
The keys for signing are included, or placed in the kernel module source in the <kernel_mod>/debian/certs directory. For example, the hello-world kernel module includes the following files:
signing_key.pem - private signing key
signing_key.x509 - public signing key
For in-tree kernel modules, signing is managed by the kernel itself. For out-of-tree modules with their own separate source code, MOK signing keys are used. Note that MOK keys are independent of Secure Boot keys, which only work in the EFI environment. For signing to be successful with out-of tree kernel modules, the public signing key must be enrolled in MOK. For details, see Create Machine Owner Keys (MOK).
Once you build the kernel module as described in Obtain Driver Source and Build the Kernel Module Packages, and install the kernel module packages as described in Install and Verify the Kernel Module Packages, the module will install itself automatically. With the signing keys enrolled in MOK, the cryptographic signatures will match and the kernel module will be allowed to run. If there are any issues related to kernel module signing, you will receive the following error:
modprobe: ERROR: could not insert 'hello_world': Key was rejected by service
Out-of-Tree Kernel Modules, Secure Boot, and Real-time Kernels¶
The preempt-rt kernel disables access to the EFI by default. As a result, MOK and the key signature verification necessary for Secure Boot to operate successfully will not work. It will not even be possible to enroll MOK keys. To use an out-of-tree kernel module in a Secure Boot system, you must add efi=runtime to the kernel command line at the beginning of the boot process. Without this boot setting, you will be prompted to create new Secure Boot keys each time the system starts up.
Before You Begin¶
To complete the kernel module signing procedures in this tutorial, ensure the following:
You must have an eLxr Server 12 development host setup with sudo privileges. For details, see eLxr Quick Start: Quick Start Overview.
You must set up Secure Boot on your eLxr 12 development host. This ensure the EFI runtime includes the necessary keys to boot the operating system. For details, see eLxr Quick Start: Enabling Secure Boot in eLxr 12.
You must have successfully built and installed the kernel driver module packages as described in Install and Verify the Kernel Module Packages.
Note
These examples assume you will be using different kernel modules with the steps provided.
Create Machine Owner Keys (MOK)¶
MOK keys are different than EFI runtime (Secure Boot) keys. They are one method the kernel uses to verify whether a kernel module is signed, and therefore safe to run on the system.
If you are running the preempt-rt kernel, ensure that your eLxr 12 system is running with the efi=runtime option included in the kernel command line. This is required for enrolling MOK keys.
Create a directory for your MOK keys and navigate to it.
# mkdir -p elxr-keys && cd elxr-keys
Create a private (MOK.priv) and public (MOK.der) key pair.
# openssl req -new -x509 -newkey rsa:2048 -keyout MOK.priv -outform DER -out MOK.der -days 36500 -subj "/CN=eLxr test/" -nodes
Create a MOK.pem certificate version of the public key (MOK.der) for use in signing kernel modules.
# openssl x509 -inform der -in MOK.der -out MOK.pem
(Optional) Rename the keys to match the examples in this tutorial.
Rename the public key certificate.
# mv MOK.pem signing_key.x509
Rename the private key.
# mv MOK.priv signing_key.pem
Rename the public key in der format.
# mv MOK.der signing_key.der
Import the signing_key.x509 public key certificate.
# mokutil --import ./signing_key.der
You will be prompted to enter a password for the key twice. Retain this password to enroll the key in a future step.
Reboot the target.
At the Shim UEFI Management screen, press any key to enroll the key you created in the previous step. If you do not begin the enrollment withing the given timeframe, the system will boot and you will need to restart it to enroll your key(s).
At the Perform MOK Management screen, select Enroll MOK, then press ENTER.
At the Enroll MOK screen, choose Continue, then press ENTER.
At the Enroll the key(s)? screen, select Yes, then press ENTER.
Enter the password used to create the key, then press ENTER.
At the Perform MOK Management screen, select Reboot, then press ENTER.
Once the system boots, log in and use mokutil to check the key enrollment.
# mokutil --list-enrolled [key 1] SHA1 Fingerprint: 1e:12:25:4b:fa:6f:f3:d5:eb:59:e3:cf:ac:e4:12:f9:86:fb:b8:7c Certificate: Data: Version: 1 (0x2) Serial Number: 66:d9:34:71:55:0f:a9:4c:a5:65:63:01:98:1e:05:a6:27:8a:20:4f Signature Algorithm: sha256WithRSAEncryption Issuer: CN=eLxr test Validity Not Before: Mar 23 02:24:39 2026 GMT Not After : Feb 28 02:24:39 2126 GMT Subject: CN=eLxr test Subject Public Key Info:
This output is typical to show how the enrolled public key displays. Since the SHA1 fingerprint is hardware-specific, expect your output to be different.
Signing Kernel Modules Not Supplied by the eLxr Project¶
Similar to the hello-world kernel module, you must ensure that the signing keys are enrolled in your system. This procedure assumes that you have the signing_key.x509 public key enrolled in MOK.
Copy your MOK keys from Create Machine Owner Keys (MOK) into your kernel module’s debian/certs source folder.
Build the kernel module to create the .deb package.
For details, see Obtain Driver Source and Build the Kernel Module Packages.
Install the kernel module package.
For details, see Install and Verify the Kernel Module Packages.
Use modprobe to launch the kernel module and verify operation.
# lsmod |grep <kernel_mod> <kernel_mod> 16384 0
In this example, the output reflects the kernel module name and process ID. The modprobe command verifies the authenticity of the module prior to running it in the kernel.
Signing DKMS Kernel Modules¶
This procedure assumes that you have created the signing_key.x509 public key and signing_key.pem from Create Machine Owner Keys (MOK).
For a sample DKMS kernel module, see https://gitlab.com/elxr/kernel/dpdk-kmods. Use this source as a guideline for creating your own modules.
Install the dkms package.
# sudo apt-get install -y dkms
Copy the signing_key.pem and signing_key.x509 keys to the /var/lib/dkms/ directory and rename them.
# cp <path_to_elxr-keys>/signing_key.x509 /var/lib/dkms/mok.pub # cp <path_to_elxr-keys>/debian/certs/signing_key.pem /var/lib/dkms/mok.key
Install the kernel module package.
# sudo apt-get install -y <dkms_kernel_mod>
Insert the module to verify that it loads successfully.
# modprobe <dkms_kernel_mod> # lsmod |grep <dkms_kernel_mod> <dkms_kernel_mod> 20480
Similar to the non-DKMS kernel module, the output reflects the kernel module name and process ID. The modprobe command verifies the authenticity of the module prior to running it in the kernel.