Secure boot with QEMU and UEFI#
https://www.labbott.name/blog/2016/09/15/secure-ish-boot-with-qemu/
(Edit 9/21: I've gotten some feedback and clarifications about a few steps and also updated the wiki. Thanks to the OVMF developers!)
Despite having too many machines in my possession, none of the x86 machines I have are currently set up to boot with UEFI. This put a real damper on my plans to poke at secure boot. Fortunately, there is virtualization technology to solve this problem. I really like being able to boot kernels directly without a full VM image. There are some instructions for getting started but they are a bit incomplete for what I wanted to do. This is what I used to get secure boot working (or at least detected) in QEMU. I make no guarantees about it actually being secure or signed correctly but it's a starting point for experiments.
The secure boot firmware is available as part of the standard Fedora package.
1$ sudo dnf install edk2-ovmfYou need to tell QEMU to pick up the firmware and emulate a file for storing EFI variables. The firmware used here is going to be OVMF_CODE.secboot.fd.
1$ cp /usr/share/edk2/ovmf/OVMF_VARS.fd my_vars.fdThis creates a copy of the base variables file for modification and use. The options you need to append to QEMU are (with some comments in #)
1# required machine type
2-machine q35,smm=on,accel=kvm
3# Due to the way some of the models work in edk2, we need to disable
4# s3 resume. Without this option, qemu will appear to silently hang
5# althouh it emits an error message on the ovmf_log
6-global ICH9-LPC.disable_s3=1
7# Secure!
8-global driver=cfi.pflash01,property=secure,value=on
9# Point to the firmware
10-drive if=pflash,format=raw,unit=0,file=/usr/share/edk2/ovmf/OVMF_CODE.secboot.fd,readonly=on
11# Point to your copy of the variables
12- drive if=pflash,format=raw,file=/home/labbott/my\_vars.fdI added these to the existing command I had for QEMU. I bumped the memory on the KVM command line to 500 as well (-m 500). If all goes well, you should be able to boot a kernel and have it detect EFI (dmesg | grep EFI) with this setup.
To actually enable secure boot, we need to run an EFI program to load a set of certificates. The default Fedora build provides a nice .iso with the UEFI shell and EFI application built in, /usr/share/edk2/ovmf/UefiShell.iso. Add -hda /usr/share/edk2/ovmf/UefiShell.iso to your QEMU command and remove the -kernel and -initrd options. If all goes well, you should be dropped into the UEFI shell. You can now run the command to add keys
1Shell> FS0:
2FS0:\> EnrollDefaultKeys.efiYour vars file should now be all set up for secure boot. If you boot with a -kernel and -initrd option, you should be able to boot a kernel and have it detect secure boot (dmesg | grep Secure).
Booting your own kernels isn't too difficult. If you take a tree that has secure boot patches in it, make sure the following set of options is enabled
1CONFIG_SYSTEM_DATA_VERIFICATION=y
2CONFIG_SYSTEM_BLACKLIST_KEYRING=y
3CONFIG_MODULE_SIG=y
4CONFIG_MODULE_SIG_ALL=y
5CONFIG_MODULE_SIG_UEFI=y
6CONFIG_MODULE_SIG_SHA256=y
7CONFIG_MODULE_SIG_HASH="sha256"
8CONFIG_ASN1=y
9CONFIG_EFI_STUB=y
10CONFIG_EFI_SECURE_BOOT_SIG_ENFORCE=y
11CONFIG_ASYMMETRIC_KEY_TYPE=y
12CONFIG_ASYMMETRIC_PUBLIC_KEY_SUBTYPE=y
13CONFIG_X509_CERTIFICATE_PARSER=y
14CONFIG_PKCS7_MESSAGE_PARSER=y
15CONFIG_SIGNED_PE_FILE_VERIFICATION=y
16CONFIG_EFI_SIGNATURE_LIST_PARSER=y
17CONFIG_MODULE_SIG_KEY="certs/signing_key.pem"
18CONFIG_SYSTEM_TRUSTED_KEYRING=y
19CONFIG_SYSTEM_TRUSTED_KEYS=""This will be enough for the kernel to detect that secure boot is enabled and let you experiment with things. You can even issue your own pesign command
1$ pesign -c 'Red Hat Test Certificate' --certdir /etc/pki/pesign-rh-test -i arch/x86/boot/bzImage -o vmlinuz.signed -s