Signed Linux custom kernel deb creation how-to

Recent PCs with secure-boot enabled require a signed Linux kernel by recognized entities to properly operate: this could be boring if you need, for example, to run custom kernels built from sources. For Debian-based distributions, if you don’t want to adopt strong solutions (e.g. disable secure-boot or disable validation in shim), it is possible to easily create a deb package with inside a self signed Linux kernel, using MOK (Machine Owner’s Key).

Signed Linux

Secure Boot in a (small) nuthsell

The whole secure boot process is composed of multiple steps: summarizing a lot, it all starts with the hardware that is manufactured with the so called Platform Key (PK), used to verify the UEFI firmware, specifically the Key Exchange Key (KEK) database. This database holds the public keys to authorize modifications of two other databases: whitelist database (DB) and blacklist database (DBX).

DB and DBX have the public keys for allowing/not allowing the execution of a firmware component or other software. One example of other software is the bootloader to start an operating system. The bootloader is allowed to run only if the public key inside DB is matched with the private key with wich the bootloader has been signed.

As it easy to understand, the major operating system vendor (Microsoft, which is also a Certification Authority) has all the needed keys loaded, so that Microsoft signed software can run without issues: at the same time, custom built binaries won’t run by default and a bit more work is required.

Entering shim and MOK

The idea to simplify Secure Boot systems deployment with Linux brought to shim. Pasting an extract from the Debian wiki:

shim is a simple software package that is designed to work as a first-stage bootloader on UEFI systems.

It was developed by a group of Linux developers from various distros, working together to make SB work using Free Software. It is a common piece of code that is safe, well-understood and audited so that it can be trusted and signed using platform keys. This means that Microsoft (or other potential firmware CA providers) only have to worry about signing shim, and not all of the other programs that distro vendors might want to support.

Shim then becomes the root of trust for all the other distro-provided UEFI programs. It embeds a further distro-specific CA key that is itself used for signing further programs (e.g. Linux, GRUB, fwupdate). This allows for a clean delegation of trust – the distros are then responsible for signing the rest of their packages.

The most important thing that shim brings for users making their own builds is to allow the machine owner to add his own set of keys (Machine Owner Key, MOK): the user can then sign his binaries with one of the keys available in the MOK list and Secure Boot will allow its execution.

Now we know what should be done to allow a custom kernel inside a deb package to run:

  • Create a pair of keys
  • Enroll them in the MOK list
  • Sign the kernel inside the deb

Creating the keys for a signed Linux kernel

Cryptographic keypairs are required to generate and check signatures: by default, during a kernel build, a keypair is created in order to sign kernel modules. The used parameters are inside certs/x509.genkey that, if it doesn’t exist, is created starting from certs/default_x509.genkey.

Since we want to customize the keypairs, let’s start creating certs/x509.genkey from certs/default_x509.genkey

$ cp certs/default_x509.genkey certs/x509.genkey

Then, open the file with your preferred text editor and start editing section [ req_distinguished_name ]. The values depend on the purpose of the certificate, but, for this example, let’s just customize the CommonName (CN), OrganizationName (O) and emailAddress fields:

O = paldan.altervista.org
CN = paldan
emailAddress = [email protected]

If needed, additional fields can be added: an useful guide is available at openssl site.

Signed Linux kernel creation

Now, it’s possible to configure and build the kernel whose vmlinuz image and modules is to be signed with the created key.

Since we want a deb package, we can directly use the target for that:

$ make -j$(nproc) deb-pkg LOCALVERSION=-test-sb

Note that, if you are using the configuration of a kernel provided by your distribution, you should check before building that inside .config the following entries are empty:

CONFIG_SYSTEM_TRUSTED_KEYS
CONFIG_SYSTEM_REVOCATION_KEYS

so that the kernel is forced to create the keys.

Once built the kernel, the private key and certificate can be found inside directory certs, in PEM format (signing_key.pem).

For enrolling the MOK key, it is needed a certificate in DER format. To get that it’s possible to use the tool extract-cert, found inside the certs directory:

$ ./certs/extract-cert ./certs/signing_key.pem ./certs/MOK.der

We can now enroll the key using the tool mokutil:

$ sudo mokutil --import ./certs/MOK.der

A password is required: the same password will be requested in the MOK manager once the system is rebooted. To verify that the key has been properly enrolled type:

$ sudo mokutil --list-new

and check for the presence of the new key.

Reboot the PC and follow the steps in the MOK manager to add the new key, using the password chosen in the previous step.

Once enrolled the key, it’s time to sign the vmlinux inside the debian package. Extract the deb result of the build with the Linux image:

$ sudo dpkg-deb -R <name>.deb extracted-files/

Sign vmlinuz using sbsign:

$ sudo sbsign --key certs/signing_key.pem --cert certs/signing_key.pem extracted-files/boot/ --output extracted-files/boot/.signed

This will create a new signed vmlinuz: remove the unsigned one and restore the original name of the signed one:

$ sudo rm extracted-files/boot/
$ sudo mv extracted-files/boot/.signed extracted-files/boot/

Recreate the deb package:

$ dpkg-deb -b extracted-files/ .deb

and you are finally ready to install the deb package with the signed kernel in a secure boot enabled system.

Una risposta a “Signed Linux custom kernel deb creation how-to”

I commenti sono chiusi.