Hi Michael,
On 09/26/2017 09:36 AM, Michael S. Tsirkin wrote:
...
> 8. libvirt launches the guest with "-S"
> 9. While creating the SEV guest qemu does the following
> i) create encryption context using GO's DH, session-info and guest policy
> (LAUNCH_START)
> ii) encrypts the guest bios (LAUNCH_UPDATE_DATA)
> iii) calls LAUNCH_MEASUREMENT to get the encrypted bios measurement
This part troubles me. This seems to mean that the guest being launched
must know what the measurement of the bios is going to be. This means
that the cloud provider can not update the bios without breaking guests.
Also, while in practice you typically can run an old bios image on a new
qemu instance, this is not really tested so would be very hard to
support properly in QEMU.
The guest itself does not need to know the measurement of the bios --
the SEV launch flow empowers the GO to validate the bootstrap code (bios)
before GO can provide a confidential information to the guest. Please note
that the validating of the measurement flow is optional. GO can ask cloud
provider to ignore the measurement all together and boot the SEV guest.
The measurement flow can be useful when GO decides to provide a custom
bios and want to know that his bios is used for booting the guest. In this
case, since the guest owner knows the initial contents of the guest at boot,
he can request the measurement from the cloud provider and compare it with
what the guest owner expects.
And this looks like a fundamental problem with the hash based
measurement that's in hardware. So below I suggest that we layer
some software on top to rely on the hash as little as possible.
> 10. By some interface we must propagate the measurement all the way to GO
> before libvirt starts the guest.
> 11. GO verifies the measurement and if measurement matches then it may
> give a secret blob -- which must be injected into the guest before
> libvirt starts the VM. If verification failed, GO will request cloud
> provider to destroy the VM.
> 12. After secret blob is injected into guest, we call LAUNCH_FINISH
> to destory the encryption context.
> 13. libvirt issues "continue" command to resume the guest boot.
>
> Please note that the measurement value is protected with transport
> encryption key (TIK) and it changes on each run. Similarly the secret blob
> provided by GO does not need to be protected using libvirt/qemu APIs. The
> secret is protected by TIK. From qemu and libvirt point of view these are
> blobs and must be passed as-is to the SEV FW.
So here's an alternative idea for starting guests:
How about building a minimal shim firmware that
runs on a single CPU and uses no hardware at all,
it just contains the secret blob.
That firmware just immediately stops and signals
hypervisor that it is ready to be run in the cloud.
Have user generate and start this shim firmware as a guest in a private
setup, then export it out using SEND_* commands.
Then instead of asking to launch guest, you ask provider
to load it with RECEIVE_* commands.
Unlike bios the shim firmware
can hopefully be static so supporting it across qemu
versions should be easy.
The shim firmware then loads bios from qemu, verifies
it in any way it sees fit (e.g. it could check a signature, version, etc:
it is not limited to a hardware hash anymore).
It then jumps to the bios.
While not exactly the same, there is some similarity
here with how people solved the issues around secureboot -
by using a shim.