GRUB EFI for Confidential Computing
This is a proposed Change for Fedora Linux.
This document represents a proposed Change. As part of the Changes process, proposals are publicly announced in order to receive community feedback. This proposal will only be implemented if approved by the Fedora Engineering Steering Committee.
Summary
An independent separate incarnation (package) of the GRUB bootloader for UEFI only that contains a minimal number of built-in modules, and can quickly boot a Unified Kernel Image (UKI) using Bootloader Specification (BLS) files. It will be built separately from the main GRUB package, and does not replace it for general usage.
Owner
- Name: Leo Sandoval | lsandova@redhat.com
- Name: Marta Lewandowska | mlewando@redhat.com
Detailed Description
There is a need for a smaller, lighter version of the GRUB bootloader on UEFI to support booting sealed bootable container images, such as for Confidential Computing.
Since confidential VMs rely on remote attestation, TPM PCR values need to be stable and predictable over long periods of time. Updating the bootloader results in changes to PCRs, and should therefore be avoided if possible.
Additionally, Unified Kernel Images (UKIs) have become the preferred choice over the regular signed kernel because the whole payload is bundled and signed for Secure Boot, thus removing the vulnerability of the unsigned initramfs. They are used often in virtual environments, for confidential computing, and by CoreOS.
Taken together, the ideal bootloader for these types of environments should be small, light, and not get updated too often. The fewer modules are built-in, the smaller the attack surface, and the less frequent updates need to be. The resulting idea is to create a smaller version of GRUB, the supported bootloader in most Linux environments, for UEFI, which is built as a separate package from the main GRUB build, contains only the modules that are absolutely necessary for VMs, and natively supports UKI loading. This new package is not meant to be a replacement for GRUB for general use; rather itâs an additional package for specific applications.
A separate rpm that is still a part of the grub2 build is already available for x86_64 and aarch64 in Fedora Rawhide for testing. It is signed for Secure Boot with the GRUB key. In the future, it is expected to get its own Secure Boot signing key.
Work is in progress to add support for this new build of GRUB in bootupd to enable safe bootloader updates on bootable container systems: Add support for systemd-boot (and minimal GRUB2 builds) · Issue #1080 · coreos/bootupd · GitHub
Feedback
The original idea was to use systemd-boot for this application, but this was rejected for a number of reasons:
- While the systemd team can support sd-boot in its present form, they view any additional features as a no-go
- Although sd-boot is a light and trivial bootloader, it has not been widely tested or fuzzed, like GRUB has been
- Long term maintenance of more than one bootloader would result in a lack of parity and added technical debt
- Potential expansion to other architectures would necessitate a compatible bootloader anyway.
The new lighter GRUB build is already being tested by CoreOS, and is generally working as expected. Small changes are still being made, and suggestions for changes are welcome.
Benefit to Fedora
This change will create a minimal UEFI bootloader for virtual environments that can further be tailored for use in those environments. It will natively load UKIs, support Secure Boot, and be a part of a robust and tested bootloader used in many Linux environments.
Scope
-
Proposal owners: The bootloader engineering team needs to create a new GRUB package, separate from the core package that includes all the changes mentioned.
-
Other developers: CoreOS, who will be the main users, at least in the beginning, need to test, provide feedback, and perhaps change some of their workflows as needed.
-
Release engineering: #Releng issue number
-
Policies and guidelines: N/A (not needed for this Change)
-
Trademark approval: N/A (not needed for this Change)
-
Alignment with the Fedora Strategy:
Upgrade/compatibility impact
This is a new package, independent of the normal all-purpose GRUB, so unless a user installs it on purpose, there is no compatibility impact.
Early Testing (Optional)
This new package is designed specifically for VMs that run UEFI firmware, so an x86_64 or aarch64 VM is the environment to use.
Prepare the test environment:
- Install or create one or more UKIs
- Install
kernel-uki-virtand add a command line addon usingukify, see instructions below - Use
ukifyto create the UKI from scratch, see instructions below
- Install
- If booting with Secure Boot enabled, sign your add-on or UKI, and enroll your public key in the MOK, see instructions below.
If you will not sign your UKI/addon, donât forget to disable Secure Boot. - Create the
/boot/efi/loader/entriesdirectory - Create BLS entries in that directory for each UKI. Specify the path to the UKI using the
efikeyword, as you normally would uselinuxfor the kernel. A minimal BLS file only needs to have a title and the path to the UKI:
cat /boot/efi/loader/entries/7.0.10-200-UKI.fc45.x86_64.conf title Fedora 45 UKI (7.0.10-200.fc45.x86_64) efi /EFI/Linux/7.0.10-200.fc45.x86_64.efi
(If you donât feel like doing all of that, you can boot regular kernels instead):
Because this version of GRUB is intended for UKIs, it expects those UKIs to be on the EFI system partition, but it can load a regular kernel too, as long as itâs in the correct place. If you copy a kernel and its initrd from /boot to /boot/efi/EFI/Linux and that kernelâs BLS configuration file from /boot/loader/entries to /boot/efi/loader/entries (and edit it to reflect the correct paths), then it should simply boot as usual.
Test:
- Download the grub2-efi-x64-cc rpm, unpack it, and replace your regular grub efi with it:
cp ./usr/lib/efi/grub2/1:2.12-60.fc45/EFI/fedora/cc/grubx64-cc.efi /boot/efi/EFI/fedora/grubx64.efi
- Reboot your machine
You should see the GRUB menu with entries for each of the UKIs that you installed. If you press âeâ to edit an entry, you should see something like chainloader /path/to/UKI and when you execute any of the entries, they should successfully boot.
You can check the size of the efi, and see that it is smaller than the normal grubx64.efi.
Use the tpm2_pcrread command between reboots of different UKIs to see that the value of PCR8 does not change.
How to build your own UKI addon
The generic UKI that fedora ships has only console=tty0 console=ttyS0 on its kernel command line. In order for it to actually boot on your system, it needs more information, like the root filesystem UUID, which you can see if you # cat /proc/cmdline. Since the UKI already has the command line bundled, you need to create a command line addon containing the additional information. You can do this using the ukify command. First get the generic UKI by installing kernel-virt-uki and the command by installing systemd-ukify. Then something like this should work:
ukify build \ -cmdline â$(cat /proc/cmdline | cut -dâ â -f2-6)â \ âoutput set_root.unsigned.addon.efi
You then need to copy the addon to the UKIâs extra.d directory in /boot/efi/EFI/Linux/ if you want to only apply it to a single UKI, or create /boot/efi/loader/addons/ and copy it there, if you want it to work for all UKIs. (If you are planning to sign the addon, wait to move it until after you have signed it.)
How to build your own UKI
You can build your own UKI using kernels and initrds that you already have installed on your system once you have also installed systemd-ukify. Building one for the running kernel using the ukify command, looks like this:
ukify build \ âlinux /usr/lib/modules/$(uname -r)/vmlinuz \ âinitrd /boot/initramfs-$(uname -r).img \ âuname $(uname -r) \ âcmdline â$(cat /proc/cmdline | cut -dâ â -f2-6)â \ âoutput kernel-$(uname -r | rev | cut -dâ.â -f3-6 | rev)-UKI.efi \ âprofile âkernel $(uname -r | rev | cut -dâ.â -f3-6 | rev) UKI (Fedora $(cat /etc/os-release | grep VERSION_ID | sed -e âs/VERSION_ID=//gâ))â
You then need to copy the UKI to the correct directory. Typically this is /boot/efi/EFI/Linux/ but can be the directory of your choosing, as long as you specify that in the UKIâs BLS file. (If you are planning to sign the UKI, wait to move it until after you have signed it.)
How to sign for Secure Boot
Itâs actually possible to sign your UKI or addon during the ukify build, but this more generic procedure can be used to sign any artifact for Secure Boot.
Install openssl and pesign and generate your signing key:
openssl req -quiet -newkey rsa:4096 -nodes \ -keyout custom_db.key -new -x509 -sha256 -days 3650 \ -subj â/CN=UKI Signing key/â \ âoutform DER -out custom_db.der
In this case the key size is 4096 bit, uses RSA for encryption, and can be used for signing for 10 years.
Import the public key into the NSS database that pesign uses and give it a nickname:
certutil -A -t â,â -d /etc/pki/pesign -n \ âMy Secureboot Signerâ -i custom_db.der
Convert the public and private keys to PKCS12 format and import the result to enable signing using pesign:
openssl pkcs12 -export -out custom_db.pfx \ -inkey custom_db.key -in custom_db.der
pk12util -i custom_db.pfx \ -d/etc/pki/pesign -n âMy Secureboot Signerâ
Sign your UKI or addon with your private key:
pesign --certificate âMy Secureboot Signerâ \ âin set_root.unsigned.addon.efi \ âout set_root.addon.efi --sign
Move or copy the UKI or addon to the proper directory, see above.
Import your public key into the Machine Owner Key (MOK) database:
mokutil --import custom_db.der
You will be asked to create a password. You need to reboot the machine to complete the enrollment, and you will be asked for this password at that time.
After rebooting, you can check that your key is actually in the MOK database:
mokutil --list-enrolled
Dependencies
N/A as this is a new package.
Documentation
N/A (not a System Wide Change) or to be determined.
Release Notes
To be determined.
Last edited by @amoloney 2026-06-11T18:53:43Z
Last edited by @amoloney 2026-06-11T18:53:43Z