qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: "Dr. David Alan Gilbert" <dgilbert@redhat.com>
To: "Michael S. Tsirkin" <mst@redhat.com>
Cc: Brijesh Singh <brijesh.singh@amd.com>,
	libvir-list@redhat.com, "Lendacky,
	Thomas" <Thomas.Lendacky@amd.com>,
	"Relph, Richard" <Richard.Relph@amd.com>,
	qemu-devel@nongnu.org
Subject: Re: [Qemu-devel] libvirt/QEMU/SEV interaction
Date: Wed, 27 Sep 2017 12:06:27 +0100	[thread overview]
Message-ID: <20170927110626.GA2395@work-vm> (raw)
In-Reply-To: <20170926170901-mutt-send-email-mst@kernel.org>

* Michael S. Tsirkin (mst@redhat.com) 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@redhat.com / Manchester, UK

  reply	other threads:[~2017-09-27 11:06 UTC|newest]

Thread overview: 36+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-09-08 11:57 [Qemu-devel] libvirt/QEMU/SEV interaction Brijesh Singh
2017-09-08 13:15 ` Daniel P. Berrange
2017-09-08 13:45   ` Relph, Richard
2017-09-08 14:52     ` Daniel P. Berrange
2017-09-08 15:48       ` Brijesh Singh
2017-09-08 15:51         ` Daniel P. Berrange
2017-09-08 16:10           ` Brijesh Singh
2017-09-08 16:11           ` Laszlo Ersek
2017-10-18  4:21         ` Michael S. Tsirkin
2017-10-18 19:18           ` Dr. David Alan Gilbert
2017-10-19  1:35             ` Michael S. Tsirkin
2017-10-20 14:26               ` Richard Relph
2017-09-18  9:43       ` [Qemu-devel] [libvirt] " Erik Skultety
2017-09-18  9:47         ` Daniel P. Berrange
2017-09-18 12:41           ` Richard Relph
2017-09-18 13:51             ` Erik Skultety
2017-09-26 14:36 ` [Qemu-devel] " Michael S. Tsirkin
2017-09-27 11:06   ` Dr. David Alan Gilbert [this message]
2017-09-27 13:39   ` Brijesh Singh
2017-09-27 16:12     ` Michael S. Tsirkin
2017-09-27 19:06       ` Richard Relph
2017-09-29 19:34         ` Michael S. Tsirkin
2017-09-29 19:48           ` Richard Relph
2017-09-29 20:07             ` Richard Relph
2017-09-29 21:35               ` Michael S. Tsirkin
2017-10-01  2:54               ` Michael S. Tsirkin
2017-10-01  2:59               ` Michael S. Tsirkin
2017-09-29 21:16             ` Michael S. Tsirkin
2017-09-29 22:15               ` Laszlo Ersek
2017-10-02  9:15               ` Daniel P. Berrange
2017-10-02  9:11             ` Daniel P. Berrange
2017-09-29 21:58         ` Laszlo Ersek
2017-10-01  0:09           ` Brijesh Singh
2017-10-01  9:17             ` Laszlo Ersek
2017-10-01  9:56               ` Laszlo Ersek
2017-10-03 16:03                 ` Brijesh Singh

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20170927110626.GA2395@work-vm \
    --to=dgilbert@redhat.com \
    --cc=Richard.Relph@amd.com \
    --cc=Thomas.Lendacky@amd.com \
    --cc=brijesh.singh@amd.com \
    --cc=libvir-list@redhat.com \
    --cc=mst@redhat.com \
    --cc=qemu-devel@nongnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).