Unified Extensible Firmware Interface/Secure Boot
Secure Boot is a security feature found in the UEFI standard, designed to add a layer of protection to the pre-boot process: by maintaining a cryptographically signed list of binaries authorized or forbidden to run at boot, it helps in improving the confidence that the machine core boot components (boot manager, kernel, initramfs) have not been tampered with.
As such it can be seen as a continuation or complement to the efforts in securing one's computing environment, reducing the attack surface that other software security solutions such as system encryption cannot easily cover, while being totally distinct and not dependent on them. Secure Boot just stands on its own as a component of current security practices, with its own set of pros and cons.
Checking Secure Boot status
Before booting the OS
At this point, one has to look at the firmware setup. If the machine was booted and is running, in most cases it will have to be rebooted.
You may access the firmware configuration by pressing a special key during the boot process. The key to use depends on the firmware. It is usually one of Esc
, F2
, Del
or possibly another Fn
key. Sometimes the right key is displayed for a short while at the beginning of the boot process. The motherboard manual usually records it. You might want to press the key, and keep pressing it, immediately following powering on the machine, even before the screen actually displays anything.
After entering the firmware setup, be careful not to change any settings without prior intention. Usually there are navigation instructions, and short help for the settings, at the bottom of each setup screen. The setup itself might be composed of several pages. You will have to navigate to the correct place. The interesting setting might be simply denoted by secure boot, which can be set on or off.
After booting the OS
An easy way to check Secure Boot status on systems using systemd is to use systemd-boot:
Here we see that Secure Boot is enabled and enforced; other values are for Secure Boot and setup
for Setup Mode.
Another way to check whether the machine was booted with Secure Boot is to use this command:
$ od --address-radix=n --format=u1 /sys/firmware/efi/efivars/SecureBoot-*
If Secure Boot is enabled, this command returns as the final integer in a list of five, for example:
6 0 0 0 1
Note, however, that the kernel may be unaware of Secure Boot (even if it is enabled in the firmware) if an insufficiently capable boot loader is used. This can be verified by checking the kernel messages shortly after the system starts up:
# dmesg | grep -i secure
[ 0.013442] Secure boot disabled [ 0.013442] Secure boot could not be determined
The kernel messages will otherwise read .
Booting an installation medium
Secure Boot support was initially added in and later removed in . At that time prebootloader was replaced with , even though the latter uses unsigned EFI binaries. There has been no support for Secure Boot in the official installation medium ever since.
Archboot images provide a way to use secure boot on installation media.
Disabling Secure Boot
The Secure Boot feature can be disabled via the UEFI firmware interface. How to access the firmware configuration is described in #Before booting the OS.
If using a hotkey did not work and you can boot Windows, you can force a reboot into the firmware configuration in the following way (for Windows 10): Settings > Update & Security > Recovery > Advanced startup (Restart now) > Troubleshoot > Advanced options > UEFI Firmware settings > restart.
Note that some motherboards (this is the case in a Packard Bell laptop and recent Xiaomi laptops) only allow to disable secure boot if you have set an administrator password (that can be removed afterwards). See also Rod Smith's Disabling Secure Boot.
Remastering the installation image
One might want to remaster the Install ISO in a way described by previous topics of this article. For example, the signed EFI applications and from #PreLoader can be adopted to here. Another option would be to borrow the BOOTx64.EFI
(shim) and grubx64.efi
from installation media of another GNU+Linux distribution that supports Secure Boot and modify the GRUB configuration to one's needs. In this case, the authentication chain of Secure Boot in said distribution's installation media should end to the grubx64.efi
(for example Ubuntu) so that GRUB would boot the unsigned kernel and initramfs from archiso. Note that up to this point, the article assumed one can access the ESP of the machine. But when installing a machine that never had an OS before, there is no ESP present. You should explore other articles, for example Unified Extensible Firmware Interface#Create UEFI bootable USB from ISO, to learn how this situation should be handled.
Implementing Secure Boot
There are certain conditions making for an ideal setup of Secure boot:
- UEFI considered mostly trusted (despite having some well known criticisms and vulnerabilities) and necessarily protected by a strong password
- Default manufacturer/third party keys are not in use, as they have been shown to weaken the security model of Secure Boot by a great margin
- UEFI directly loads a user-signed EFISTUB combined kernel image (no boot manager), including microcode (if applicable) and initramfs so as to maintain throughout the boot process the chain of trust established by Secure Boot and reduce the attack surface
- Use of full drive encryption, so that the tools and files involved in the kernel image creation and signing process cannot be accessed and tampered with by someone having physical access to the machine.
- Some further improvements may be obtained by using a TPM, although tooling and support makes this harder to implement.
A simple and fully self-reliant setup is described in #Using your own keys, while #Using a signed boot loader makes use of intermediate tools signed by a third-party.
Using your own keys
Secure Boot implementations use these keys:
- Platform Key (PK)
- Top-level key.
- Key Exchange Key (KEK)
- Keys used to sign Signatures Database and Forbidden Signatures Database updates.
- Signature Database (db)
- Contains keys and/or hashes of allowed EFI binaries.
- Forbidden Signatures Database (dbx)
- Contains keys and/or hashes of denylisted EFI binaries.
See The Meaning of all the UEFI Keys for a more detailed explanation.
To use Secure Boot you need at least PK, KEK and db keys. While you can add multiple KEK, db and dbx certificates, only one Platform Key is allowed.
Once Secure Boot is in "User Mode" keys can only be updated by signing the update (using sign-efi-sig-list) with a higher level key. Platform key can be signed by itself.
Install efitools
Nearly all of the following sections require you to install the package.
Backing up current variables
Before creating new keys and modifying EFI variables, it is advisable to backup the current variables, so that they may be restored in case of error.
Run the following commands to backup all four of the principal Secure Boot variables:
$ efi-readvar -v PK -o old_PK.esl $ efi-readvar -v KEK -o old_KEK.esl $ efi-readvar -v db -o old_db.esl $ efi-readvar -v dbx -o old_dbx.esl
If you perform these commands on a new computer or motherboard, the variables you extract will most likely be the ones provided by Microsoft.
Manual process
To generate keys, perform the following steps.
You will need private keys and certificates in multiple formats:
- .key
- PEM format private keys for EFI binary and EFI signature list signing.
- .crt
- PEM format certificates for , and .
- .cer
- DER format certificates for firmware.
- .esl
- Certificates in an EFI Signature List for , , KeyTool and firmware.
- .auth
- Certificates in an EFI Signature List with an authentication header (i.e. a signed certificate update file) for , sbkeysync, KeyTool and firmware.
Create a GUID for owner identification:
$ uuidgen --random > GUID.txt
Platform key:
$ openssl req -newkey rsa:4096 -nodes -keyout PK.key -new -x509 -sha256 -days 3650 -subj "/CN=my Platform Key/" -out PK.crt $ openssl x509 -outform DER -in PK.crt -out PK.cer $ cert-to-efi-sig-list -g "$(< GUID.txt)" PK.crt PK.esl $ sign-efi-sig-list -g "$(< GUID.txt)" -k PK.key -c PK.crt PK PK.esl PK.auth
Sign an empty file to allow removing Platform Key when in "User Mode":
$ sign-efi-sig-list -g "$(< GUID.txt)" -c PK.crt -k PK.key PK /dev/null rm_PK.auth
Key Exchange Key:
$ openssl req -newkey rsa:4096 -nodes -keyout KEK.key -new -x509 -sha256 -days 3650 -subj "/CN=my Key Exchange Key/" -out KEK.crt $ openssl x509 -outform DER -in KEK.crt -out KEK.cer $ cert-to-efi-sig-list -g "$(< GUID.txt)" KEK.crt KEK.esl $ sign-efi-sig-list -g "$(< GUID.txt)" -k PK.key -c PK.crt KEK KEK.esl KEK.auth
Signature Database key:
$ openssl req -newkey rsa:4096 -nodes -keyout db.key -new -x509 -sha256 -days 3650 -subj "/CN=my Signature Database key/" -out db.crt $ openssl x509 -outform DER -in db.crt -out db.cer $ cert-to-efi-sig-list -g "$(< GUID.txt)" db.crt db.esl $ sign-efi-sig-list -g "$(< GUID.txt)" -k KEK.key -c KEK.crt db db.esl db.auth
Helper scripts
A helper/convenience script is offered by the author of the reference page on this topic (requires python). A mildly edited version is also packaged as .
In order to use it, simply create a folder in a secure location (e.g. if later use of sbupdate-gitAUR to automate unified kernel image creation and signing is planned) and run it:
# mkdir /etc/efi-keys # cd !$ # curl -L -O https://www.rodsbooks.com/efi-bootloaders/mkkeys.sh # chmod +x mkkeys.sh # ./mkkeys.sh Enter a Common Name to embed in the keys, e.g. "Secure Boot"
This will produce the required files in different formats.
Updating keys
Once Secure Boot is in "User Mode" any changes to KEK, db and dbx need to be signed with a higher level key.
For example, if you wanted to replace your db key with a new one:
- Create the new key,
- Convert it to EFI Signature List,
- Sign the EFI Signature List,
- Enroll the signed certificate update file.
$ cert-to-efi-sig-list -g "$(< GUID.txt)" new_db.crt new_db.esl $ sign-efi-sig-list -g "$(< GUID.txt)" -k KEK.key -c KEK.crt db new_db.esl new_db.auth
If instead of replacing your db key, you want to add another one to the Signature Database, you need to use the option -a
(see ):
$ sign-efi-sig-list -a -g "$(< GUID.txt)" -k KEK.key -c KEK.crt db new_db.esl new_db.auth
When is created, enroll it.
Signing EFI binaries
When Secure Boot is active (i.e. in "User Mode"), only signed EFI binaries (e.g. applications, drivers, unified kernel images) can be launched.
Manually with sbsigntools
Install to sign EFI binaries with .
To sign your kernel and boot manager use sbsign, e.g.:
# sbsign --key db.key --cert db.crt --output /boot/vmlinuz-linux /boot/vmlinuz-linux # sbsign --key db.key --cert db.crt --output esp/EFI/BOOT/BOOTx64.EFI esp/EFI/BOOT/BOOTx64.EFI
Signing the kernel with a pacman hook
You can also use mkinitcpio's pacman hook to sign the kernel on install and updates.
Copy to /etc/pacman.d/hooks/90-mkinitcpio-install.hook
and to .
In /etc/pacman.d/hooks/90-mkinitcpio-install.hook
, replace:
Exec = /usr/share/libalpm/scripts/mkinitcpio-install
with:
Exec = /usr/local/share/libalpm/scripts/mkinitcpio-install
In , replace:
install -Dm644 "${line}" "/boot/vmlinuz-${pkgbase}"
with:
sbsign --key /path/to/db.key --cert /path/to/db.crt --output "/boot/vmlinuz-${pkgbase}" "${line}"
If you are using systemd-boot, there is a dedicated pacman hook doing this task semi-automatically.
Fully automated unified kernel generation and signing with sbupdate
sbupdate is a tool made specifically to automate unified kernel image generation and signing on Arch Linux. It handles installation, removal and updates of kernels through pacman hooks.
Install sbupdate-gitAUR and configure it following the instructions given on the project's homepage.
OUT_DIR="EFI/Linux"
to get your signed kernel images directly recognized without needing configuration. See systemd-boot(7) § FILES and Systemd-boot#Adding loaders.Once configured, simply run as root for first-time image generation.
Putting firmware in "Setup Mode"
Secure Boot is in Setup Mode when the Platform Key is removed. To put firmware in Setup Mode, enter firmware setup utility and find an option to delete or clear certificates. How to enter the setup utility is described in #Before booting the OS.
Enrolling keys in firmware
Use one of the following methods to enroll db, KEK and PK certificates.
Using sbkeysync
Install . Create a directory with the following directory structure -
/etc/secureboot/keys ├── db ├── dbx ├── KEK └── PK
For example using:
# mkdir -p /etc/secureboot/keys/{db,dbx,KEK,PK}
Then copy each of the .auth files that were generated earlier into their respective locations (for example, into and so on).
If you want to verify the changes will make to the system's UEFI keystore, use:
# sbkeysync --pk --dry-run --verbose
Finally, use to enroll your keys.
# sbkeysync --verbose # sbkeysync --verbose --pk
On next boot the UEFI should be back in User Mode and enforcing Secure Boot policy.
Using firmware setup utility
Copy all *.cer
, *.esl
, files (except ) to a FAT formatted file system (you can use EFI system partition).
Launch firmware setup utility and enroll db, KEK and PK certificates. Firmwares have various different interfaces, see Replacing Keys Using Your Firmware's Setup Utility for example how to enroll keys.
If the used tool supports it prefer using .auth and .esl over .cer.
Using KeyTool
is in package, copy it to ESP. To use it after enrolling keys, sign it with .
# sbsign --key db.key --cert db.crt --output esp/KeyTool-signed.efi /usr/share/efitools/efi/KeyTool.efi
Launch using firmware setup utility, boot loader or UEFI Shell and enroll keys.
See Replacing Keys Using KeyTool for explanation of KeyTool menu options.
Microsoft Windows
It is usually not possible to boot Windows by signing its bootloader (EFI/Microsoft/Boot/bootmgfw.efi
) with a custom, personal key with Secure Boot Mode enabled, without enrolling the "Microsoft Windows Production PCA 2011" key in the UEFI Secure Boot variables:
- if contains a signature both from the "Microsoft Windows Production PCA 2011" and from your own Secure Boot DB key (so two signatures), then UEFI firmware implementations like INSYDE Corp. 4096.01 (UEFI Version 2.31, Version F.70, Release Date: 07/18/2016, BIOS Revision 15.112, Firmware Revision: 29.66) will not launch and will throw a security violation error (): UEFI firmware implementation like this can probably only read the first signature - not the second one. Only the certificate for the second signature is enrolled in the UEFI Secure Boot variables, so the Secure Boot verification fails.
- if the "Microsoft Windows Production PCA 2011" signature from the file is stripped/removed, and only a signature from your own Secure Boot DB key is added to the file, then UEFI will launch the file - but Windows will launch a recovery/repair environment: Windows complains that the Windows installation is broken (because the "Microsoft Windows Production PCA 2011" signature on file is missing).
So to dual boot with Windows,
- you either have to add the hash of to the list of allowed hashes in the variable; and you have to update the variable every time a Windows Update changes . This is very tedious, error-prone and not supported by Microsoft; and for example Bitlocker will not work properly anymore with this setup (Bitlocker will ask for your recovery password every time to decrypt your Windows partition).
- or you have to add Microsoft's certificates to the UEFI Secure Boot variables Microsoft has two certificates and one
KEK
certificate:- The Microsoft Windows Production PCA 2011 certificate must be included in the variable in order to allow the Windows Operating System to load.
- The Microsoft Corporation UEFI CA 2011 certificate aka the Microsoft 3rd Party UEFI CA certificate should be included in the variable in order to use third-party binaries like UEFI drivers, option ROMs, , etc.
- The Microsoft Corporation KEK CA 2011 certificate should be included in the
KEK
variable, in order to "enable revocation of bad images by updating the and potentially for updating to prepare for newer Windows signed images". However, Windows will also boot without the "Microsoft Corporation KEK CA 2011" certificate.
Create EFI Signature Lists from Microsoft's DER format certificates using Microsoft's GUID () and combine them in one file for simplicity:
$ sbsiglist --owner 77fa9abd-0359-4d32-bd60-28f4e78f784b --type x509 --output MS_Win_db.esl MicWinProPCA2011_2011-10-19.crt $ sbsiglist --owner 77fa9abd-0359-4d32-bd60-28f4e78f784b --type x509 --output MS_UEFI_db.esl MicCorUEFCA2011_2011-06-27.crt $ cat MS_Win_db.esl MS_UEFI_db.esl > MS_db.esl
Optional (for strict conformity with Microsoft UEFI Secure Boot requirements): Create an EFI Signature List from Microsoft's DER format KEK
certificate using Microsoft's GUID ():
$ sbsiglist --owner 77fa9abd-0359-4d32-bd60-28f4e78f784b --type x509 --output MS_Win_KEK.esl MicCorKEKCA2011_2011-06-24.crt
Sign a variable update with your KEK
. Use with option -a
to add not replace a certificate:
$ sign-efi-sig-list -a -g 77fa9abd-0359-4d32-bd60-28f4e78f784b -k KEK.key -c KEK.crt db MS_db.esl add_MS_db.auth
Optional (for strict conformity with Microsoft UEFI Secure Boot requirements): Sign a KEK
variable update with your . Use with option -a
to add not replace a KEK
certificate:
$ sign-efi-sig-list -a -g 77fa9abd-0359-4d32-bd60-28f4e78f784b -k PK.key -c PK.crt KEK MS_Win_KEK.esl add_MS_Win_KEK.auth
Follow #Enrolling keys in firmware to enroll add_MS_db.auth
and for strict conformity with Microsoft UEFI Secure Boot requirements into the UEFI Secure Boot Database variables.
Using a signed boot loader
Using a signed boot loader means using a boot loader signed with Microsoft's key. There are two known signed boot loaders: PreLoader and shim. Their purpose is to chainload other EFI binaries (usually boot loaders). Since Microsoft would never sign a boot loader that automatically launches any unsigned binary, PreLoader and shim use an allowlist called Machine Owner Key list, abbreviated MokList. If the SHA256 hash of the binary (Preloader and shim) or key the binary is signed with (shim) is in the MokList they execute it, if not they launch a key management utility which allows enrolling the hash or key.
PreLoader
When run, PreLoader tries to launch . If the hash of is not in MokList, PreLoader will launch . In HashTool you must enroll the hash of the EFI binaries you want to launch, that means your boot loader () and kernel.
refind-install
script can copy the rEFInd and PreLoader EFI binaries to the ESP. See rEFInd#Using PreLoader for instructions.Set up PreLoader
Install and copy and to the boot loader directory; for systemd-boot use:
# cp /usr/share/preloader-signed/{PreLoader,HashTool}.efi esp/EFI/systemd
Now copy over the boot loader binary and rename it to ; for systemd-boot use:
# cp esp/EFI/systemd/systemd-bootx64.efi esp/EFI/systemd/loader.efi
Finally, create a new NVRAM entry to boot :
# efibootmgr --unicode --disk /dev/sdX --part Y --create --label "PreLoader" --loader /EFI/systemd/PreLoader.efi
Replace with the drive letter and replace with the partition number of the EFI system partition.
This entry should be added to the list as the first to boot; check with the efibootmgr
command and adjust the boot-order if necessary.
Fallback
If there are problems booting the custom NVRAM entry, copy and to the default loader location booted automatically by UEFI systems:
# cp /usr/share/preloader-signed/HashTool.efi esp/EFI/BOOT/ # cp esp/EFI/systemd/systemd-bootx64.efi esp/EFI/BOOT/loader.efi
Copy over and rename it:
# cp /usr/share/preloader-signed/PreLoader.efi esp/EFI/BOOT/BOOTx64.EFI
For particularly intransigent UEFI implementations, copy to the default loader location used by Windows systems:
# mkdir -p esp/EFI/Microsoft/Boot # cp /usr/share/preloader-signed/PreLoader.efi esp/EFI/Microsoft/Boot/bootmgfw.efi
As before, copy and to .
When the system starts with Secure Boot enabled, follow the steps above to enroll and /vmlinuz-linux
(or whichever kernel image is being used).
How to use while booting?
A message will show up that says To use HashTool for enrolling the hash of and , follow these steps. These steps assume titles for a remastered archiso installation media. The exact titles you will get depends on your boot loader setup.
- Select OK
- In the HashTool main menu, select Enroll Hash, choose and confirm with Yes. Again, select Enroll Hash and to enter the archiso directory, then select and confirm with Yes. Then choose Exit to return to the boot device selection menu.
- In the boot device selection menu choose Arch Linux archiso x86_64 UEFI CD
Remove PreLoader
Uninstall and simply remove the copied files and revert configuration; for systemd-boot use:
# rm esp/EFI/systemd/{PreLoader,HashTool}.efi # rm esp/EFI/systemd/loader.efi # efibootmgr --unicode --bootnum N --delete-bootnum # bootctl update
Where is the NVRAM boot entry created for booting . Check with the efibootmgr command and adjust the boot-order if necessary.
Delete enrolled hash
Every entry of hashes enrolled in the MOK database eats up a little piece of space of NVRAM. You may want to delete useless hashes to free the space and to prevent outdated programs from booting.
Install and copy :
# cp /usr/share/efitools/efi/KeyTool.efi esp/EFI/systemd/KeyTool.efi
Manage to boot to Preloader and you will see the KeyTool entry. You can then edit hashes in the MOK database.
shim
When run, shim tries to launch grubx64.efi
. If MokList does not contain the hash of grubx64.efi
or the key it is signed with, shim will launch MokManager (). In MokManager you must enroll the hash of the EFI binaries you want to launch (your boot loader (grubx64.efi
) and kernel) or enroll the key they are signed with.
Set up shim
Install shim-signedAUR.
Rename your current boot loader to grubx64.efi
# mv esp/EFI/BOOT/BOOTx64.EFI esp/EFI/BOOT/grubx64.efi
Copy shim and MokManager to your boot loader directory on ESP; use previous filename of your boot loader as as the filename for :
# cp /usr/share/shim-signed/shimx64.efi esp/EFI/BOOT/BOOTx64.EFI # cp /usr/share/shim-signed/mmx64.efi esp/EFI/BOOT/
Finally, create a new NVRAM entry to boot BOOTx64.EFI
:
# efibootmgr --unicode --disk /dev/sdX --part Y --create --label "Shim" --loader /EFI/BOOT/BOOTx64.EFI
shim can authenticate binaries by Machine Owner Key or hash stored in MokList.
- Machine Owner Key (MOK)
- A key that a user generates and uses to sign EFI binaries.
- hash
- A SHA256 hash of an EFI binary.
Using hash is simpler, but each time you update your boot loader or kernel you will need to add their hashes in MokManager. With MOK you only need to add the key once, but you will have to sign the boot loader and kernel each time it updates.
shim with hash
If shim does not find the SHA256 hash of grubx64.efi
in MokList it will launch MokManager ().
In MokManager select Enroll hash from disk, find grubx64.efi
and add it to MokList. Repeat the steps and add your kernel . When done select Continue boot and your boot loader will launch and it will be capable launching the kernel.
shim with key
Install .
You will need:
- .key
- PEM format private key for EFI binary signing.
- .crt
- PEM format certificate for sbsign.
- .cer
- DER format certificate for MokManager.
Create a Machine Owner Key:
$ openssl req -newkey rsa:4096 -nodes -keyout MOK.key -new -x509 -sha256 -days 3650 -subj "/CN=my Machine Owner Key/" -out MOK.crt $ openssl x509 -outform DER -in MOK.crt -out MOK.cer
Sign your boot loader (named grubx64.efi
) and kernel:
# sbsign --key MOK.key --cert MOK.crt --output /boot/vmlinuz-linux /boot/vmlinuz-linux # sbsign --key MOK.key --cert MOK.crt --output esp/EFI/BOOT/grubx64.efi esp/EFI/BOOT/grubx64.efi
You will need to do this each time they are updated. You can automate the kernel signing with a pacman hook, e.g.:
Copy MOK.cer
to a FAT formatted file system (you can use EFI system partition).
Reboot and enable Secure Boot. If shim does not find the certificate grubx64.efi
is signed with in MokList it will launch MokManager ().
In MokManager select Enroll key from disk, find MOK.cer
and add it to MokList. When done select Continue boot and your boot loader will launch and it will be capable launching any binary signed with your Machine Owner Key.
shim with key and GRUB
GRUB can only be successfully booted in Secure Boot mode if its EFI binary includes all of the modules necessary to read the filesystem containing the vmlinuz and initramfs images.
Since GRUB version , loading modules in Secure Boot Mode via is no longer allowed, as this would violate the expectation to not sideload arbitrary code. If the GRUB modules are not embedded in the EFI binary, and GRUB tries to sideload/ them, GRUB will fail to boot with the message:
error: prohibited by secure boot policy
Ubuntu, according to its official build script, embeds the following GRUB modules in its signed GRUB EFI binary grubx64.efi
:
- the "basic" modules, necessary for booting from a CD or from a simple-partitioned disk:
all_video
, , , , , , ,efifwsetup
, , , , , , ,gfxterm
, , , ,help
, , , , , , ,linux
, , ,lsefimmap
, , , , , , , ,part_msdos
, , , , , , , ,search_fs_uuid
, , ,sleep
, , , , , , , ,zfscrypt
, - the "platform-specific" modules for x86_64-efi architecture, necessary for e.g.:
- : to play sounds during boot
cpuid
: to the CPU at boot- : to support UEFI booting
- : to support Measured Boot / Trusted Platform Modules
- the "advanced" modules, consisting of modules:
- : to boot from plain-mode encrypted disks
- : to support particular hashing and encryption algorithms
- : to boot from LUKS-encrypted disks:
- : to boot from LVM logical volume disks
- ,
mdraid1x
, , : to boot from RAID virtual disks
You must construct your list of GRUB modules in the form of a shell variable that we denote as . You can use the latest Ubuntu script as a starting point, and trim away modules that are not necessary on your system. Omitting modules will make the boot process relatively faster, and save some space on the ESP partition.
You also need a Secure Boot Advanced Targeting (SBAT) file/section included in the EFI binary, to improve the security; if GRUB is launched from the UEFI shim loader. This SBAT file/section contains metadata about the GRUB binary (version, maintainer, developer, upstream URL) and makes it easier for shim to block certain GRUB versions from being loaded if they have security vulnerabilities, as explained in the UEFI shim bootloader secure boot life-cycle improvements document from shim.
The first-stage UEFI bootloader shim will fail to launch grubx64.efi
if the SBAT section from grubx64.efi
is missing!
If GRUB is installed, a sample SBAT .csv file is provided under .
Reinstall GRUB using the provided file and all the needed and sign it:
# grub-install --target=x86_64-efi --efi-directory=esp --modules=${GRUB_MODULES} --sbat /usr/share/grub/sbat.csv # sbsign --key MOK.key --cert MOK.crt --output esp/EFI/GRUB/grubx64.efi esp/EFI/GRUB/grubx64.efi # cp esp/GRUB/grubx64.efi esp/boot/grubx64.efi
Reboot, select the key in MokManager, and Secure Boot should be working.
Remove shim
Uninstall shim-signedAUR, remove the copied shim and MokManager files and rename back your boot loader.
Protecting Secure Boot
The only way to prevent anyone with physical access to disable Secure Boot is to protect the firmware settings with a password.
Most UEFI firmwares provide such a feature, usually listed under the "Security" section in the firmware settings.
Tips and tricks
sbctl
sbctl is a user-friendly way of setting up secure boot and signing files.
Creating and enrolling keys
Before starting, go to your firmware settings and set secure boot mode to Setup mode. This is different for each device.
Once you log back in, check the secure boot status:
$ sbctl status
You should see that sbctl is not installed and secure boot is disabled.
Then create your custom secure boot keys:
# sbctl create-keys
Enroll your keys, with Microsoft's keys, to the UEFI:
# sbctl enroll-keys -m
Check the secure boot status again:
$ sbctl status
sbctl should be installed now, but secure boot will not work until the boot files have been signed with the keys you just created.
Signing
Check what files need to be signed for secure boot to work:
# sbctl verify
Now sign all the unsigned files. Usually the kernel and the boot loader need to be signed. For example:
# sbctl sign -s /boot/vmlinuz-linux # sbctl sign -s /boot/EFI/BOOT/BOOTX64.EFI
The files that need to be signed will depend on your system's layout, kernel and boot loader.
Now you are done! Reboot your system and turn secure boot back on in the firmware settings. If the boot loader and OS load, secure boot should be working. Check with:
$ sbctl status
Automatic signing with the pacman hook
sbctl comes with a pacman hook that automatically signs all new files whenever the Linux kernel, systemd or the boot loader is updated.
Sign the official ISO with custom keys
Support for Secure Boot using custom keys can be added to the official ISO by simply extracting the boot loader (BOOTx64.EFI
and ), kernel, UEFI shell, signing them and then repacking the ISO with the signed files.
First extract the relevant files and El Torito boot images:
option as used by mkarchiso makes the files on ISO 9660 read-only which persists after extracting them. Make the files writable so that they can be modified:
$ chmod +w BOOTx64.EFI BOOTIA32.EFI shellx64.efi shellia32.efi vmlinuz-linux
Sign the files using an enrolled db key and certificate:
$ sbsign --key db.key --cert db.crt --output BOOTx64.EFI BOOTx64.EFI $ sbsign --key db.key --cert db.crt --output BOOTIA32.EFI BOOTIA32.EFI $ sbsign --key db.key --cert db.crt --output shellx64.efi shellx64.efi $ sbsign --key db.key --cert db.crt --output shellia32.efi shellia32.efi $ sbsign --key db.key --cert db.crt --output vmlinuz-linux vmlinuz-linux
Copy the boot loader and UEFI shell to . It will be used as the EFI system partition and will be listed as an El Torito UEFI boot image. The size of is fixed, but there is 1 MiB free space added by mkarchiso for the purposes of rounding/alignment and to account for reserved sectors, so the size increase from the signatures should not be an issue.
$ mcopy -D oO -i eltorito_img2_uefi.img BOOTx64.EFI BOOTIA32.EFI ::/EFI/BOOT/ $ mcopy -D oO -i eltorito_img2_uefi.img shellx64.efi shellia32.efi ::/
Repack the ISO using the modified El Torito UEFI boot image and add the signed boot loader files, UEFI shell and kernel to ISO 9660:
Boot the resulting archlinux-YYYY.MM.DD-x86_64-Secure_Boot.iso
.
See also
- Understanding the UEFI Secure Boot Chain by tianocore
- Wikipedia:Unified Extensible Firmware Interface#Secure boot
- Dealing with Secure Boot by Rod Smith
- Controlling Secure Boot by Rod Smith
- UEFI secure booting (part 2) by Matthew Garrett
- UEFI Secure Boot by James Bottomley
- efitools README
- Will your computer's "Secure Boot" turn out to be "Restricted Boot"? — Free Software Foundation
- Free Software Foundation recommendations for free operating system distributions considering Secure Boot
- Intel's UEFI Secure Boot Tutorial
- Secure Boot, Signed Modules and Signed ELF Binaries
- National Security Agency docs: UEFI Defensive Practices Guidance and unclassified UEFI Secure Boot customization
- sbkeysync & maintaining uefi key databases by Jeremy Kerr
- Secure your boot process: UEFI + Secureboot + EFISTUB + Luks2 + lvm + Arch Linux (2020-07)
- How is hibernation supported, on machines with UEFI Secure Boot? (Security StackExchange)
- Authenticated Boot and Disk Encryption on Linux by Lennart Poettering (2021-09-23)