GRUB EFI for Confidential Computing
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
Current status
- Targeted release: Fedora Linux 45
- Last updated: 2026-08-11
- Announced
- Discussion thread
- FESCo issue: #3626
- Tracker bug: #2499989
- Release notes tracker: #415
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 String 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: https://github.com/coreos/bootupd/issues/1080
Feedback
The original idea was to use systemd-boot for this application, but this was rejected for a number of reasons:
- 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, for example
# cat 7.2.0-0.rc6.260807gf9a2394a2348.52.fc45.x86_64.conf title Fedora 45 UKI (7.2.0-0.rc6.260807gf9a2394a2348.52.fc45.x86_64) efi /EFI/Linux/75123dfdea684b34b07d5df913fe2af3-7.2.0-0.rc6.260807gf9a2394a2348.52.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.
cp /boot/vmlinux-$(uname -r) /boot/efi/EFI/Linux
Test:
- Download the grub2-efi-x64-cc rpm, unpack it, and replace your regular grub efi with it:
# curl -O https://kojipkgs.fedoraproject.org//packages/grub2/2.12/74.fc45/x86_64/grub2-efi-x64-cc-2.12-74.fc45.x86_64.rpm # rpm2cpio grub2-efi-x64-cc-2.12-74.fc45.x86_64.rpm | cpio -idmv # cp ./usr/lib/efi/grub2/1:2.12-74.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.
Use the tpm2_pcrread command between reboots of different UKIs to see that the value of PCR8 does not change. Note that TPM PCR measurements are only available when SB is on.
How to build your own UKI addon
The generic UKI, the one installed through kernel-uki-virt, 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-uki-virt and the command by installing systemd-ukify. Then something like this should work:
# ukify build \ --cmdline "'$(cat /proc/cmdline | cut -d' ' -f2-)'" \ --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-)'" \ --output kernel-$(uname -r)-UKI.efi \ --profile "kernel $(uname -r) 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.
