Shim
Shim is an alternative method of managing accepted Secure Boot keys without touching the UEFI firmware settings
Configuration
The global secureboot
USE flag can be enabled to automatically sign any EFI executables installed by a package. To use this flag the SECUREBOOT_SIGN_KEY and SECUREBOOT_SIGN_CERT user variables must be set in make.conf and point to a valid PEM format OpenSSL key (or PKCS11 URI) and certificate respectively.
Generating keys
The procedure for generating a new OpenSSL key/certificate pair is documented on the Secure Boot page. Note that when shim is used only one key (called the Machine Owner Key) is required. Since Shim is already signed by the 3rd-party Microsoft certificate accepted by default on most motherboards there is no need to create and manage a Platform Key, Key Exchange Key, or the (forbidden) Signature Database.
The key that was used to sign the kernel modules (for source distribution kernel users, they are set by MODULES_SIGN_KEY and MODULES_SIGN_CERT environment variables in make.conf) may also be used as the Machine Owner Key to sign the boot files.
MODULE_SIGN_KEY requires the signing key and the corresponding certificate in the same file in PEM format. The file should look like this:
-----BEGIN PRIVATE KEY-----
...
-----END PRIVATE KEY-----
-----BEGIN CERTIFICATE-----
...
-----END CERTIFICATE-----
Installation
The sys-boot/shim package provides a pre-compiled version of shim distributed by Fedora and pre-signed with the 3rd-party Microsoft certificate. This Microsoft certificate is accepted by default on most UEFI-enabled motherboards, this allows users to delegate secure boot key management to shim without having to touch the firmware's default UEFI Secure Boot keys.
The sys-boot/mokutil package makes it possible to manage shim's Machine Owner Key (MOK) list from within the Linux operating system.
Install both with:
root #
emerge sys-boot/shim sys-boot/mokutil
Setup
For shim to be able to verify the signed boot files it must be loaded before the boot loader. Unfortunately the shim distributed by Fedora is hard coded to load GRUB. To use other boot loaders the boot loader EFI file may be renamed to grubx64.efi (where x64 will need to be adjusted for architectures other then amd64). The detailed process for each supported boot loader is outlined below.
After the steps for the chosen boot loader have been followed, the systems boot order must be adjusted to load shim first instead of the boot loader. Either use efibootmgr or the system's UEFI firmware interface.
Example if you have followed GRUB section, and if /dev/sda holds the EFI partition:
root #
efibootmgr --disk /dev/sda --part 1 --create -L "shim" -l '\EFI\Gentoo\shimx64.efi'
By default, at boot shimx64.efi loads grubx64.efi in the same directory. However, if an argument is passed to shim from the firmware, then it will attempt to load this argument first. To add such an argument, add -u '\EFI\path\to\my\bootloader.efi' to the above command.
GRUB
sys-boot/grub installs a prebuilt and signed stand-alone EFI executable if the secureboot USE flag is enabled. Copy it, Shim, and the MokManager to the same directory on the EFI System Partition. For example:
root #
cp /usr/share/shim/BOOTX64.EFI /efi/EFI/Gentoo/shimx64.efi
root #
cp /usr/share/shim/mmx64.efi /efi/EFI/Gentoo/mmx64.efi
root #
cp /usr/lib/grub/grub-x86_64.efi.signed /efi/EFI/Gentoo/grubx64.efi
Then register shim with the firmware:
root #
efibootmgr --disk /dev/sda --part 1 --create -L "GRUB via Shim" -l '\EFI\Gentoo\shimx64.efi'
Note that this prebuilt and signed stand-alone version of grub reads the grub.cfg from a different location then usual. Instead of the default /boot/grub/grub.cfg the config file should be in the same directory that the grub EFI executable is in, e.g. /efi/EFI/Gentoo/grub.cfg. When sys-kernel/installkernel is used to install the kernel and update the grub configuration then the GRUB_CFG environment variable may be used to override the usual location of the grub config file.
For example:
root #
grub-mkconfig -o /efi/EFI/Gentoo/grub.cfg
Or, via installkernel:
GRUB_CFG=/efi/EFI/Gentoo/grub.cfg
root #
env-update
systemd-boot
Systemd-boot is signed by portage when the secureboot USE flag is enabled. A postinst hook to automatically setup shim with systemd-boot, via renaming systemd-boot to grubx64.efi is available on the systemd-boot wiki page. Alternatively, if the firmware supports it, it is possible to create a boot entry to boot systemd-boot via shim:
root #
bootctl install --no-variables
root #
cp /usr/share/shim/BOOTX64.EFI /efi/EFI/systemd/shimx64.efi
root #
cp /usr/share/shim/mmx64.efi /efi/EFI/systemd/mmx64.efi
root #
efibootmgr --disk /dev/sda --part 1 --create --label "Systemd-boot via Shim" --loader '\EFI\systemd\shimx64.efi' --unicode '\EFI\systemd\systemd-bootx64.efi'
rEFInd
To setup rEFInd with shim:
root #
refind-install ... --shim /usr/share/shim/BOOTX64.EFI ...
The rEFInd efi file is signed by portage the secureboot USE flag is enabled.
Signing the kernel
The Distribution Kernels are automatically signed if USE=secureboot is enabled. If a manually configured and compiled kernel is used instead it must be manually signed using app-crypt/sbsigntools where SECUREBOOT_SIGN_KEY and SECUREBOOT_SIGN_CERT should be replaced with your respective key and certificate:
root #
sbsign --key ${SECUREBOOT_SIGN_KEY} --cert ${SECUREBOOT_SIGN_CERT} --output /boot/EFI/Gentoo/kernel-x.y.z-gentoo.efi /boot/EFI/Gentoo/kernel-x.y.z-gentoo.efi
If SECUREBOOT_SIGN_KEY is a PKCS11 URI the --engine pkcs11
argument has to be added.
app-crypt/sbctl can assist with automatically signing manually managed kernels.
Managing the MOK list
To successfully boot with Secure Boot enabled the used SECUREBOOT_SIGN_CERT should be added to the MOK list. Unfortunately while sbsign
requires keys and certificates in PEM format, the MOK list requires the certificate in DER format. Therefore the certificate must first be converted to DER format:
root #
openssl x509 -inform pem -in ${SECUREBOOT_SIGN_CERT} -outform der -out /boot/sbcert.der
An import request for shim can be generated with:
root #
mokutil --import /boot/sbcert.der
Next reboot, shim will find that there is a pending import request and launch MokManager. Enter the password and complete the import process.
Signed kernel modules
To successfully boot with Secure Boot enabled the kernel modules must be signed as well. The kernel build system automatically embeds the certificate that was used to sign the modules into the kernel image, as such it is not required to import this certificate into the MOK list. If however some kernel modules are signed with a different key then was used when building the kernel, then the accompanying certificate must also be imported into the MOK list. This situation may occur when a pre-compiled kernel binpkg was installed (e.g. sys-kernel/gentoo-kernel-bin) as well as one or more external third-party modules. The original key that was used for the kernel binpkg may not be available on this system, and as such the external third-party modules will have to be signed with a different key.
Valid signatures on modules can be enforced with the
module.sig_enforce=1
kernel command line argument. This is the default for sys-kernel/gentoo-kernel and sys-kernel/vanilla-kernel if the secureboot
USE flag is enabled, but it is not the default for sys-kernel/gentoo-kernel-bin.See also
- UEFI — a firmware standard for boot ROM designed to provide a stable API for interacting with system hardware. On x86 it replaced the legacy BIOS.
- Efibootmgr — a tool for managing UEFI boot entries.
- Secure Boot — an enhancement of the security of the pre-boot process of a UEFI system.
- EFI stub — describes EFI stub kernels, i.e. kernels directly executable from UEFI.