qemu-discuss
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Bitlocker-tripping hardware change with 5.2.0?


From: Michael Weiser
Subject: Re: Bitlocker-tripping hardware change with 5.2.0?
Date: Sun, 20 Dec 2020 14:25:18 +0100

Hi Stefan,

On Sat, Dec 19, 2020 at 11:02:29PM -0500, Stefan Berger wrote:

> The whole purpose of measured/trusted boot is to reflect some known
> measurement values of a known BIOS in the TPM PCRs. Unfortunately this bites
> with sealing to those values and the rather fast development of QEMU.
> Updates of QEMU on the host platform then become a recovery event inside the
> VM, which is unfortunate, but this is when measured/trusted boot actually
> 'does its job'.

Thank you! This was a cruicial hint at exactly the right time: I was at
a point of severe head-scratching where I had gotten git bisect to work
but it was telling me that stock v5.1.0 compiled from git source also
showed the problem while my system-installed version wasn't.

The difference indeed is in the firmware blobs used: Compiled from
source, qemu uses the firmware files in the pc-bios subdirectory of the
build directory while my system's qemu looks into /usr/share/qemu where
bios{,-256k}.bin and vgabios-qxl.bin are provided by a different package
(seabios).

With that knowledge, I was able to make the git-compiled v5.1.0 qemu
behave the same as the one installed in the system by providing -L
/usr/share/qemu to it.

qemu v5.2.0 compiled from git source also does not drop into BitLocker
recovery when pointed at the unchanged system-installed qemu-5.1.0
/usr/share/qemu directory. This negates the suspicion that some change
in qemu proper carries over into the VM.

strace shows the following files being opened by qemu when starting my
testing VM:

bios.bin
bios-256k.bin
efi-e1000e.rom
vgabios-qxl.bin
kvmvapic.bin

Since bios{,-256k}.bin and vgabios-qxl.bin are provided by the seabios
package and therefore (in my particular case) stable across an update
from qemu-5.1.0 to 5.2.0 and kvmvapic.bin is identical in 5.1.0 and
5.2.0, this left only efi-e1000e.rom as reason for Bitlocker recovery
upon upgrade.

And indeed, reverting efi-e1000e.rom to the 5.1.0 version after
upgrading my system qemu made the Bitlocker recovery go away.

Armed with that knowledge, I was able to provide qemu with a VM-specific
firmware path from within libvirtd xml following documentation at
https://libvirt.org/drvqemu.html#qemucommand:

--- win10-bitlocker.xml.bak     2020-12-20 13:28:09.361141043 +0100
+++ win10-bitlocker.xml 2020-12-20 13:29:22.098750216 +0100
@@ -5,7 +5,7 @@
 or other application using the libvirt API.
 -->

-<domain type='kvm'>
+<domain type='kvm' xmlns:qemu='http://libvirt.org/schemas/domain/qemu/1.0'>
   <name>win10-bitlocker</name>
   <uuid>bf566263-35e3-4dba-af8c-8ca85dba6a85</uuid>
   <metadata>
@@ -141,4 +141,8 @@
       <address type='pci' domain='0x0000' bus='0x04' slot='0x00'
function='0x0'/>
     </memballoon>
   </devices>
+  <qemu:commandline>
+    <qemu:arg value='-L'/>
+    <qemu:arg 
value='/home/user/.config/libvirt/qemu/firmware/bf566263-35e3-4dba-af8c-8ca85dba6a85'/>
+  </qemu:commandline>
 </domain>

# ls -la 
/home/user/.config/libvirt/qemu/firmware/bf566263-35e3-4dba-af8c-8ca85dba6a85
total 680
drwxr-xr-x 2 user group   4096 Dec 20 13:26 .
drwxr-xr-x 3 user group   4096 Dec 20 13:25 ..
-rw-r--r-- 1 user group 262144 Dec 20 13:25 bios-256k.bin
-rw-r--r-- 1 user group 131072 Dec 20 13:25 bios.bin
-rw-r--r-- 1 user group 240128 Dec 20 13:25 efi-e1000e.rom
-rw-r--r-- 1 user group   9216 Dec 20 13:26 kvmvapic.bin
-rw-r--r-- 1 user group  38912 Dec 20 13:25 vgabios-qxl.bin

Assuming I keep the virtual hardware specification stable
also (e.g. pc-q35-5.1) and don't add/remove devices, this should work
almost indefinitly, shouldn't it?

> >     For giggles I did enter the recovery key of the testing VM when
> >     prompted. It did boot up and showed Bitlocker enabled. After rebooting
> >     it prompted for the recovery key again. I entered it again, it booted
> >     again and I turned off Bitlocker (decrypted the disk). After
> >     re-enabling
> >     Bitlocker (re-encrypting the disk) and rebooting again it now does not
> >     prompt for the recovery key again.
> Does Bitlocker not allow you to accept a configuration change (= PCR value
> change) and it internally (presumably) then seals the secreted against those
> new values so upon the next reboot it works again? Do you really need to go
> through the whole re-encryption process? It sounds like unattractive even
> for a physical machine firmware update...

Indeed, upon retesting multiple times it seems that entering the
recovery key does actually also accept the firmware change. So there
must have been some user error on my part on the first try.

On closer look there is also the option of suspending Bitlocker
protection for a number of boots[1]. The data stays encrypted but
encryption keys are made available to the bootloader in the clear. Upon
resumption, Bitlocker silently re-measures the system and thus accepts
changes. When using the Control Panel applet[2], there's no option to
enter the number of boots and it's reactivated immediately after the
next boot.

I did a quick test of that: A change is accepted on the next boot and
recovery stays silent on following boots but an additional change at a
later time drops me back into recovery again. So it seems to work as
advertised.

So, suspending Bitlocker in every "bitlockered" VM before a qemu
upgrade, the user should never see any recovery screen. I would be
certain to forget about that every second time and end up needing to
downgrade qemu (and in my case possibly also the seabios package) again.

[1] 
https://docs.microsoft.com/en-us/powershell/module/bitlocker/suspend-bitlocker
[2] 
https://www.top-password.com/blog/wp-content/uploads/2019/02/suspend-bitlocker-protection.png

@Marc-Andre: Re: git bisect: It seems "git bisect v5.2.0 v5.1.0" does
something different than "git checkout v5.2.0 && git bisect start && git
bisect bad && git bisect good v5.1.0". With the latter command sequence
(and switching back to an out-of-source build), git bisect worked just
fine, including parallel build. I'm not too happy with that explanation
myself and would rather write this off to some additional layer 8
problem in the process.
-- 
Thanks,
Michael



reply via email to

[Prev in Thread] Current Thread [Next in Thread]