-
Notifications
You must be signed in to change notification settings - Fork 2.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[RfC] OvmfPkg/AmdSev: add support for systemd-boot and secure boot #6537
base: master
Are you sure you want to change the base?
Conversation
This allow adding the systemd-boot bootloader to OVMF firmware images. Signed-off-by: Gerd Hoffmann <[email protected]>
Signed-off-by: Gerd Hoffmann <[email protected]>
Signed-off-by: Gerd Hoffmann <[email protected]>
The AmdSev build includes a pre-build binary of the grub boot loader. This patch allows to include systemd-boot instead. Use '-D SD_BOOT_ENABLE=TRUE' build option to include systemd-boot instead of grub. Signed-off-by: Gerd Hoffmann <[email protected]>
Add secure boot option to AmdSev build. The EFI variable store lives in normal memory and is not protected against manipulation at runtime (due to lack of SMM mode emulation support in CC modes). The variable store is not persistent though, it will be re-initialized from the firmware image on reset, so manipulations can not compromise secure boot on next boot. This is similar to the IntelTdx build variant. Signed-off-by: Gerd Hoffmann <[email protected]>
Temporary debug patch (the amdsev build crashes when running under svsm). Signed-off-by: Gerd Hoffmann <[email protected]>
Paging @osteffenrh @tlendacky @berrange @vittyvk @poettering for comments. |
Tested it: works. Can we have a way to specify the location of the sdboot efi file? So we don't always need to install it system-wide. Also, I still get
even with |
IMO getting rid of grub in all things CVM is certainly a good idea :-) What I'm wondering is what's the difference between including sd-boot and including shim. If we want to have boot menu in the change, then sd-boot can be loaded (and measured) from ESP as well. You'll have to use BOOTX64.CSV or rename sd-boot binary to grubx64.efi (sic!) but it is possible. As an advantage, including shim will provide working SBAT mechanism. Also, if we want to rely on measured boot, we need a trusted vTPM. It's OK if our vTPM is stateless and implemented as part of firmware which gets into launch measurements but it's not OK if the vTPM is implemented outside of the guest. Finally, would it be possible to make the mechanism flexible? E.g. make it possible to include a 'virtuial ESP' in the firmware and this 'virtual ESP' can have anything, e.g. full shim -> sd-boot -> UKI chain. This way we can get reliable launch measurements covering everything without the need to have a vTPM. I understand this is a significant change to the idea of the PR, basically, I'm wondering if such 'flexible' approach would make sense or not. |
Conceptually there were significant issues with the embedded grub idea. When you further consider grub as a specific impl it gets worse, because Thus overall I tend to view the embedded grub as "neat trick" but not
Considering sd-boot instead of grub addresses some of the big issues If the proposal is for sd-boot to simply load UKIs off the (unencrypted) |
One significant difference is that shim -> UKI requires a working EFI variable store (which we don't have right now for qemu CVMs). sd-boot -> UKI works without that.
edk2 has a pseudo filesystem used for direct kernel boot (i.e.
It's RfC for a reason. Let ideas and comments flow ;) |
That essentially boils down to the question what the long-term fate of the AmdSev build should be. Do we actually need that? If we allow the AmdSev build simply fetch the bootloader from disk the gap to the standard OVMF build just became a bit smaller. As far I know the remaining differences are:
The OvmfPkg code base has envolved quite a bit since the initial merge of the AmdSev code. There are ways to easily check what mode OVMF runs in (via |
Also adding @fitzthum |
The design choices in the AmdSev build were to a significant extent dictated by limitations of the SEV/SEV-ES technology it was initially targetting. I'd consider SEV/SEV-ES to be dead-end technologies, so we should primarily be thinking about what choices make most sense in a SEV-SNP context. I think the ideal would be to consider the AmdSev build to be a legacy /and/or niche thing mostly just for SEV/SEV-ES (or minimalizst SEV-SNP without SVSM), and aim for SEV-SNP w/ SVSM to use a normal OVMF build feature set. |
Do you mean a persistent variable store? Because EFI variable store should work under CVMs, it is just in memory and not persistent for SNP. |
For certain definitions of "work" :-) eg With shim, if it finds no boot entries, it'll populate boot entries based on the CSV file in the ESP, and then trigger a machine reset, expecting that the boot entries it just wrote will still exist. We can't do resets in CVMs without re-creating the QEMU VM, and thus loosing the boot entries shim just wrote. So basically shim ends in a forever boot loop. IOW, from POV of real world application expectations, 'working EFI var store', implies a var store that is persistent across cold boots. |
Slightly tangential to the PR, but hopefully useful: Measured direct boot, and the AmdSev package is still useful for SNP (we use it for confidential containers, for instance), but there is a path to getting rid of the AmdSev package. The AmdSev package was created partly out of a faulty assumption that the measured direct boot approach could only work with a separate firmware build. The idea was that this alternate firmware build would guarantee a secure startup or it would crash and that since it was a separate build the measurement of the binary would guarantee this behavior. While this works, it could potentially also work with a standard OVMF build. A few months ago I revised the measured direct boot code a little bit so that it is simply triggered when the kernel hashes table exists. If the table exists, the firmware will crash if the measurements do not match. If the table does not exist, the boot will continue as normal. The existence of the hash table changes the measurement, which is enough to prove the properties of the boot to a verifier. Currently this is only supported in the AmdSev package, but it seems like it would work fine in OVMF, which would open the door to removing AmdSev. The question is how we could provide similar TCB guarantees with OVMF, such as not exposing the shell. |
IIUC, shim uses the varstore for two purposes. First so "fallback" can writing boot entries & trigger a reboot to launch the real shim & OS boot image. Second so that it can write out the distro's secureboot certs, which are needed to verify the bootloader / old kernel images / UKIs. It seems like we still need shim to be there to provide the distro secureboot certs that 'sd-boot' will need in order to verify the UKI. The only way around that is to have something on the host, either be told what certs to pre-enroll, or probe the disk image to auto-detect the certs. If the latter, then that thing on the host could alternatively locate the BOOT CSV file, pre-populate the boot entry(s), and then shim can work as normal. Or if it is told the distro, it doesn't need the BOOT CSV file, it can just blindly populate |
If OVMF can detect that it is within a confidential VM with CPUID, then it could auto-disable the shell. |
Yes. Kernel update process for the Fedora UKI cloud image linked in the description depends on persistent |
There is a workaround for that: The reset thing can be configured with an EFI variable. But, yes, that is one of the extra loops you have to hoop through if the variable store is not persistent. |
The instructions above do the former (enroll fedora cert into db). |
The approach taken by OvmfPkg/IntelTdx is to split the DXE firmware volume into two, and the binaries in the second firmware volume are not loaded in case CC is active. So everything you don't want use in a CC guest is moved over. The shell is the obvious first candidate. The network stack too. But also things like VirtioRngDxe (in a CC guest you want use RngDxe instead because that uses the rdrand cpu instruction instead of asking the host for randon numbers). I think it makes sense to reuse the idea for the normal OVMF build. |
Signed-off-by: Gerd Hoffmann <[email protected]>
|
||
[Binaries.AA64] | ||
PE32|/usr/lib/systemd/boot/efi/systemd-bootaa64.efi|* | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@kraxel Can you also add support for Binaries.LOONGARCH64 (systemd-bootloongarch64.efi)? I will be able to do platform testing for you, Tks !
Description
The AmdSev build variant is a restrictively configured firmware build
for confidential computing. It will not load efi binaries from
storage devices or network. It is intended to be used in one of two
operating modes instead:
Direct kernel boot. The hashes of kernel + initrd are passed to the
firmware in a special page (and that page is part of the launch
measurement). This makes sure the VM actually runs what it is
supposed to run, and there is proof for that.
Launch the grub boot loader included in the firmware image. The idea
is that grub supports booting from encrypted storage, so the
filesystem encryption can be used to ensure the integrity of the
confidential virtual machine.
The former works fine, the latter never really took off and is kind-of
stuck in research experiment stage. Meanwile the world is moving into
another direction: Instead of booting from encrypted filesystems use
UKIs (unified kernel image) and secure boot and measured boot to ensure
integrity of linux kernel and initrd.
This patch series offers a alternative approach: It allows to compile
in the systemd-boot bootloader instead of grub. systemd-boot supports
loading UKIs from the ESP. One of the advantages of a UKI is that the
secure boot signature covers both kernel and initrd (instead of only the
kernel in traditional setups), thereby plugging one of the big holes in
linux secure boot support.
The patch series also adds secure boot support to the AmdSev build.
Known issues
SBAT revocation does not work. It is handled by shim.efi on linux
systems, which is not present in the boot path here.
Testing instructions
Install systemd-boot. On Fedora
dnf install -y systemd-boot-unsigned
can be used.
Compile
OvmfPkg/AmdSev/AmdSevX64.dsc
with-D SECURE_BOOT_ENABLE=TRUE
and-D SD_BOOT_ENABLE=TRUE
.Fetch the Fedora 41 UKI cloud image.
Set a root password for the image:
Install virt-firmware.
Available on PyPI, your linux distro might also have packages.
Enroll the secure boot keys to the firmware image, make sure to add
the fedora secure boot signing keys:
Boot:
Login, use
bootctl
to verify secure boot is active.