* Michael S. Tsirkin (mst@xxxxxxxxxx) wrote: > On Fri, Sep 08, 2017 at 06:57:30AM -0500, Brijesh Singh wrote: > > Hi All, > > Sorry if below comment doesn't make sense, I might be misunderstanding > something basic about SEV. Also sorry about the delay, I've been on > vacation. > > > > (sorry for the long message) > > > > CPUs from AMD EPYC family supports Secure Encrypted Virtualization (SEV) > > feature - the feature allows running encrypted VMs. To enable the feature, > > I have been submitting patches to Linux kernel [1], Qemu [2] and OVMF [3]. > > We have been making some good progress in getting patches accepted upstream > > in Linux and OVMF trees. SEV builds upon SME (Secure Memory Encryption) > > feature -- SME support just got pulled into 4.14 merge window. The base > > SEV patches are accepted in OVMF tree -- now we have SEV aware guest BIOS. > > I am getting ready to take off "RFC" tag from remaining patches to get them > > reviewed and accepted. > > > > The boot flow for launching an SEV guest is a bit different from a typical > > guest launch. In order to launch SEV guest from virt-manager or other > > high-level VM management tools, we need to design and implement new > > interface between libvirt and qemu, and probably add new APIs in libvirt > > to be used by VM management tools. I am new to the libvirt and need some > > expert advice while designing this interface. A pictorial representation > > for a SEV guest launch flow is available in SEV Spec Appendix A [4]. > > > > A typical flow looks like this: > > > > 1. Guest owner (GO) asks the cloud provider to launch SEV guest. > > 2. VM tool asks libvirt to provide its Platform Diffie-Hellman (PDH) key. > > 3. libvirt opens /dev/sev device to get its PDH and return the blob to the > > caller. > > 4. VM tool gives its PDH to GO. > > 5. GO provides its DH key, session-info and guest policy. > > 6. VM tool somehow communicates the GO provided information to libvirt. > > 7. libvirt adds "sev-guest" object in its xml file with all the information > > obtained from #5 > > > > (currently my xml file looks like this) > > > > <qemu:arg value='-object'> > > <qemu:arg > > value='sev-guest,id=sev0,policy=<GO_policy>,dh-key-file=<filename>,session-file=<filename>/> > > <qemu:arg value='-machine'/> > > <qemu:arg value='memory-encryption=sev0'/> > > > > 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. > > > 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. I think the normal way to solve this is that the Distro would provide a list of the signatures, and the GO would check the bios measurement against that list. The GO needs to keep that list up to date; either directly downloading it from the Distro or a copy signed by the Distro. Dave > > > 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. > > Thanks! > > > > Questions: > > a) Do we need to add a new set of APIs in libvirt to return the PDH from > > libvirt and VM tool ? Or can we use some pre-existing APIs to pass the > > opaque blobs ? (this is mainly for step 3 and 6) > > b) do we need to define a new xml tag to for memory-encryption ? or just > > use the qemu:args tag ? (step 6) > > c) what existing communicate interface can be used between libvirt and qemu > > to get the measurement ? can we add a new qemu monitor command > > 'get_sev_measurement' to get the measurement ? (step 10) > > d) how to pass the secret blob from libvirt to qemu ? should we consider > > adding a new object (sev-guest-secret) -- libvirt can add the object through > > qemu monitor. > > > > > > [1] https://marc.info/?l=kvm&m=150092661105069&w=2 > > [2] https://marc.info/?l=qemu-devel&m=148901186615642&w=2 > > [3] https://lists.01.org/pipermail/edk2-devel/2017-July/012220.html > > [4] http://support.amd.com/TechDocs/55766_SEV-KM%20API_Specification.pdf > > > > Thanks > > > > Brijesh > > > -- Dr. David Alan Gilbert / dgilbert@xxxxxxxxxx / Manchester, UK -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list