Insmod causes key rejected by service

I am running AlmaLinux 9 (RedHat 9 clone) and have compiled a new kernel module. I am running in a VM with UEFI and secure boot enabled. When I insert the module I get the following error:

insmod: ERROR: could not insert module npreal2.mod: Key was rejected by service

From other posts I concluded it was related to UEFI/secure boot. So I disabled secure boot and then insmod reports:

insmod: ERROR: could not insert module npreal2.mod: Invalid module format

I tried recompiling with secure mode off then insmod worked, but I then have to leave secure boot disabled. How can I make this module work with secure boot?

There is a post on github about creating your own MOK keys, but that seems to be DKMS specific.

Asked By: TSG

||

Now (after a discussion in the comments) that you have a working but unsigned npreal2.ko kernel module, we can try tackling Secure Boot.

First, you need to create a X.509 key pair (a public key and a corresponding secret key) to use as a MOK. To do that, first create a minimal OpenSSL configuration file, as e.g. ~/x509.genkey:

[ req ]
default_bits = 4096
distinguished_name = req_distinguished_name
prompt = no
x509_extensions = myexts

[ req_distinguished_name ]
O = ModuleType
CN = ModuleType module signing key

[ myexts ]
basicConstraints=critical,CA:FALSE
keyUsage=digitalSignature
subjectKeyIdentifier=hash
authorityKeyIdentifier=keyid

The CN = line defines the name your MOK is primarily identifiable with, so type whatever you want in there. The O = line would be the place for the name of your organization, but you can omit the entire line if you wish.

Now you can generate your key pair:

openssl req -x509 -new -nodes -utf8 -sha256 -days 36500 
    -batch -config x509.genkey -outform DER 
    -out signing_key.x509 
    -keyout signing_key.priv

This command creates a key pair that is nominally valid for 10 years from the time of creation; if you want to change that, change the -days parameter.

Now you should have two files:

  • signing_key.x509 is the public key, which you will register as your MOK (Machine Owner’s Key)
  • signing_key.priv is the corresponding private key, which you will need to sign any kernel modules you build yourself. This private key is not passphrase-protected, so keep it secure.

To enroll signing_key.x509 as the MOK, make sure that the mokutil package has been installed, and then run:

sudo mokutil --import signing_key.x509

This command will ask you to set a one-time password for the key enrollment process. Once you do that, the first phase of the MOK enrollment is done. To complete the MOK enrollment, you’ll need to reboot.

When you reboot, the shimx64.efi will detect that you have initiated a MOK enrollment process, and will display a blue screen with a simple text-based menu, with options to either Enroll MOK or Continue boot.

Select Enroll MOK to begin the second phase of the MOK enrollment. It will then give you a chance to view the hash and the CN = line of the key you’re about to enroll, then a yes/no confirmation, and finally the one-time password you set in the first enrollment phase above. If the enrollment is successful, that password should never be needed again. Select "Reboot" in the blue-screen menu to go back to Linux.

(The second phase of the enrollment process happens during reboot to ensure that only someone with physical-equivalent access to the system will be able to complete the process, and the password ensures that the key you’re enrolling is the one you selected in the first phase, and not one inserted by some malware.)

To verify that the key enrollment was successful, you can run sudo keyctl list %:.platform as root: it should display all Secure Boot keys the system recognizes, including your MOK, the distribution’s key embedded in the shimx64.efi, and the manufacturer’s and Microsoft’s keys from the firmware.

Alternatively, you can run sudo mokutil -l for a more verbose listing of the distribution’s key and your MOK.

Now you are ready for signing your kernel module:

/usr/src/kernels/$(uname -r)/scripts/sign-file sha256 
    ~/signing_key.priv 
    ~/signing_key.x509 
    /some/where/npreal2.ko   # adjust the paths as needed

To confirm signing, run sudo modinfo ./npreal2.ko: it should include a signer: line with the CN = name of your MOK, and a long signature: block with hexadecimal numbers.

And of course, now you should be able to load the module with sudo insmod npreal2.ko with Secure Boot enabled!

Source: https://www.redhat.com/sysadmin/secure-boot-systemtap

Answered By: telcoM
Categories: Answers Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.