↑ arvau

Super User / How to install a windows guest in qemu/kvm with secure boot enabled

My host machine is archlinux and I am using virt-manager as a frontend of qemu.

I just have no idea about how to enabling secure boot for windows qemu guests. I have tried using the OVMF_CODE.secboot.fd but it didn't help. I have little knowledge about how to make my own key or get Microsoft key or something like that.

Can anybody show me how to do it? Thanks a lot for any advice.

Super User / How to install a windows guest in qemu/kvm with secure boot enabled

I have figured out how to do that and I would like to share the process.

It mainly consists of two steps, obtaining the keys and inserting it into ovmf firmware.

Obtaining the key

Generate Platform Key

PK can be generated by openssl. use the following command to sign your own PK. Note that PKpriv.key is the private key and you should preserve it carefully.

$ openssl req -newkey rsa:2048 -nodes -keyout PKpriv.key -x509 -days 365 -out PK.crt
$ openssl x509 -in PK.crt -outform der -out PK.der

Download KEK and DB

You need to download KEK and DB from Microsoft Database:

  1. Microsoft Corporation KEK CA 2011

  2. Microsoft Windows Production CA 2011

Insert UEFI keys

Make an img file in fat32 form containing the keys

$ dd if=/dev/zero of=keys.img bs=4M count=1
$ mkfs.vfat keys.img
# losetup /dev/loopX keys.img
# mount /dev/loopX /mnt
# cp PK.der /mnt/PK.der
# cp MicCorKEKCA2011_2011-06-24.crt /mnt/KEK.crt
# cp MicWinProPCA2011_2011-10-19.crt /mnt/DB.crt
# umount /dev/loopX
# losetup -d /dev/loopX

Insert the keys

Start a virtual machine with the img file as a storage device. Enter UEFI configuration menu and Go to secure boot configuration (Device Manager / Secure Boot Configuration / Secure Boot Mode) and change from “Standard Mode” to “Custom Mode”. After change to “Custom Mode”, “Custom Secure Boot Options” will show up, click and enter. PK Options / Enroll PK / Enroll PK Using File and do the same for KEK and DB. ommit Changes and Exit

After import PK, KEK and DB, the secure boot state is now “Enabled”.

References

  1. https://projectacrn.github.io/1.6/tutorials/waag-secure-boot.html

  2. https://www.linux.org/threads/create-img-files.11174/

Super User / How to install a windows guest in qemu/kvm with secure boot enabled

You need to install edk2-ovmf, then find the path for the correspond files. For Arch Linux you can use pacman -Ql edk2-ovmf. Choose the x64 version. Be careful the two files are different, one is OVME_CODE.secboot.fd (the firmware code); another one is OVMF_VARS.fd (variables used by the firmware and Operating Systems), like a configuration database.

-drive if=pflash,format=raw,readonly=on,file=/usr/share/edk2-ovmf/x64/OVMF_CODE.secboot.fd \
-drive if=pflash,format=raw,file=/copy/of/OVMF_VARS.fd \

Add these two options you'll get UEFI and the secure boot feature. I tested on latest Arch Linux x86_64 6.4.4-arch1-1 and QEMU emulator version 8.0.2.

I wrote a script to install Windows 11 on QEMU:

#!/bin/bash   
              
# Libtpms-based TPM emulator
tpm_path=/home/user/Documents/qemu-disks/Windows11Support/
swtpm socket --tpm2 --tpmstate dir="${tpm_path}" --ctrl type=unixio,path="${tpm_path}/swtpm-sock" &
              
iso_path=/home/user/Documents/Win11_22H2_English_x64v2.iso
disk_path=/home/user/Documents/qemu-disks/Windows11
ovmf_code=/usr/share/edk2/x64/OVMF_CODE.secboot.fd
ovmf_vars=/home/user/Documents/qemu-disks/Windows11Support/OVMF_VARS.fd
virtio_path=/home/user/Documents/qemu-disks/Windows11Support/virtio-win-0.1.229.iso
keys_path=/home/user/Downloads/UEFIKeys
  
  # these options for install OSs and systems
  #-drive file="${iso_path}",index=2,media=cdrom \
  #-drive file="${virtio_path}",index=3,media=cdrom \

                                                                                                                                                                           
qemu-system-x86_64 \
  -enable-kvm \
  -smp 8 \    
  -m 16G \    
  -name Windows11 \
  -machine q35 \
  -vga none \ 
  -usb -device usb-tablet \
  -device virtio-vga \
  -nic user,model=virtio-net-pci \
  -cpu host,hv_relaxed,hv_spinlocks=0x1fff,hv_vapic,hv_time \
  -drive if=pflash,format=raw,readonly=on,file="${ovmf_code}" \
  -drive if=pflash,format=raw,file="${ovmf_vars}" \
  -chardev socket,id=chrtpm,path="${tpm_path}/swtpm-sock" \
  -tpmdev emulator,id=tpm0,chardev=chrtpm \
  -device tpm-tis,tpmdev=tpm0 \
  -drive file="${disk_path}",index=0,media=disk,if=virtio,format=raw \
  $@          

This for Trusted Platform Module Emulator:

  -chardev socket,id=chrtpm,path="${tpm_path}/swtpm-sock" \
  -tpmdev emulator,id=tpm0,chardev=chrtpm \
  -device tpm-tis,tpmdev=tpm0 \

$@ let you add more options when you run the scripts. All other options you can find meanings by check man qemu-system-x86_64.

For more information check QEMU - ArchWiKi.