* Daniel P. Berrangé (berra...@redhat.com) wrote:
> On Mon, Jan 31, 2022 at 03:38:47PM +0200, Dov Murik wrote:
> > 
> > 
> > On 31/01/2022 13:44, Daniel P. Berrangé wrote:
> > > On Mon, Jan 31, 2022 at 11:15:39AM +0000, Dov Murik wrote:
> > >> Currently the responses of QMP commands query-sev-launch-measure and
> > >> query-sev-attestation-report return just the signed measurement. In
> > >> order to validate it, the Guest Owner must know the exact guest launch
> > >> digest, besides other host and guest properties which are included in
> > >> the measurement.
> > >>
> > >> The other host and guest details (SEV API major, SEV API minor, SEV
> > >> build, and guest policy) are all available via query-sev QMP command.
> > >> However, the launch digest is not available.  This makes checking the
> > >> measurement harder for the Guest Owner, as it has to iterate through all
> > >> allowed launch digests and compute the expected measurement.
> > > 
> > > So more specifically to validate the measurement, the guest owner is
> > > currently calculating:
> > > 
> > >    expected_measurement = HMAC(0x04 || API_MAJOR || API_MINOR || BUILD ||
> > >                                GCTX.POLICY || GCTX.LD || MNONCE; GCTX.TIK)
> > > 
> > > where GCTX.LD is
> > > 
> > >     SHA256(FIRMWARE-CODE || KERNEL-HASHES-TABLE || VMSA-FOREACH-VCPU)
> > > 
> > > and comparing expected_measurement to the actual measurement from
> > > query-sev-launch-measure.
> > > 
> > >> Add a new field debug-launch-digest to the response of
> > >> query-sev-launch-measure and query-sev-attestation-report which includes
> > >> the guest launch digest, which is the SHA256 of all initial memory added
> > >> to the guest via sev_launch_update_data().
> > > 
> > > So this new 'debug-launch-digest' field is returning GCTX.LD value
> > > above.
> > > 
> > 
> > Yes. Maybe rename it to gctx-ld ?
> > 
> > hmmm, except at the moment it doesn't include the VMSAs, because I don't
> > know an easy way to do it within QEMU :-( .  So the content of
> > debug-launch-digest is currently incorrect for SEV-ES guests.
> 
> Yes, that comes back to the problem we've discussed previously about
> how to determine the correct expected VMSA content which has no easy
> answer. 
> 
> 
> > The scenario we are encountering is that there's not one allowed
> > assignment to the parameters, but rather a more relaxed policy along the
> > lines of:
> > 
> > API_MAJOR.API_MINOR should be >= 12.34
> > BUILD should be >= 66
> > GCTX.POLICY should be 0x0 or 0x2
> > GCTX.LD can be one of these allowed OVMFs: {hash-a, hash-b, hash-c}
> > 
> > 
> > Having the values of API*, BUILD, POLICY from query-sev is very
> > comfortable for verifying they are in the allowed ranges.  But since the
> > Guest Owner doesn't have GCTX.LD, they have to compute the measurement
> > for each of the allowed OVMF images.  Once the values are known and
> > "allowed", then the HMAC must be computed to see that the signed
> > measurement does indeed match.
> 
> Ok, so the usage scenario is that the platform owner is deciding 
> which OVMF build in use, not the guest owner. That guest owner just
> knows that it is an OVMF build from a set of builds published by the
> platform owner. Good enough if you trust the cloud owner in general,
> but want confidence that their compute host isn't compromised. Would
> need  an independantly reproducible build, if you don't trust the
> cloud owner at all.
> 
> 
> Assuming we've got 5 possible OVMF builds, currently we would need
> to calculate 5 HMACs over the inpuot data.
> 
> With this extra piece of info, we only need to calculate 1 HMAC.
> 
> So this is enabling a performance optimization, that could indeed
> be used in a production deployment.  The HMAC ops are not exactly
> performance intensive though until we get to the point of choosing
> between a huge number of possible OVMFs.
> 
> If we can't get the VMSA info included, then the guest owner still
> needs a local copy of every possible OVMF binary that is valid. IOW
> this digest is essentially no more than a filename to identify which
> OVMF binary to calc the HMAC over.
> 
> > Note: I guess that adding the hashes of kernel/initrd/cmdline here might
> > help too (for direct boot with kernel-hashes=on), and maybe the hash of
> > OVMF itself (on its own).
> 
> IOW, I think there's only two scenarios that make sense
> 
> 1. The combined launch digest over firmware, kernel hashes
>    and VMSA state.
> 
> 2. Individual hashes for each of firmware, kernel hashes table and
>    VMSA state
> 
> I think we should assume that anyone who has access to SEV-ES hardware
> is likely to run in SEV-ES policy, not SEV policy. So without VMSA
> state I think that (1) is of quite limited usefulness. (2) would
> be nicer to allow optimization of picking which OVMF blob to use,
> as you wouldn't need to figure out the cross-product of very valid
> OVMF and every valid kernel hashes table - the latter probably isn't
> even a finite bounded set.

I agree (2) is what we want - it's effectively a manifest of everything
that's been hashed.

I'm half sure we can get the VMSA; we probably need to add a new KVM ioctl to
get it.

> > More generally: within space/network constraints, give the Guest Owner
> > all the information it needs to compute the launch measurement.  There's
> > a problem with OVMF there (we don't want to send the whole 4 MB over the
> > QMP response, but given its hash we can't "extend" it to include the
> > kernel-hashes struct).
> 
> Yeah its a shame we aren't just measuring the digest of each piece
> of information in  GCTX.LD, instead of measuring the raw information
> directly.
> 
> 
> I wonder if we're thinking of this at the wrong level though. Does
> it actually need to be QEMU providing this info to the guest owner ?
> 
> Guest owners aren't going to be interacting with QEMU / QMP directly,
> nor are they likely to be interacting with libvirt directly. Their
> way into the public cloud will be via some high level API. eg the
> OpenStack Nova REST API, or the IBM Cloud API (whatever that may
> be). This high level mgmt infra is likely what is deciding which
> of the 'N' possible OVMF builds to pick for a given VM launch. It
> could easily just expose the full OVMF data to the user via its
> own API regardless of what query-sev does.
> 
> Similarly if the cloud is choosing which kernel, out of N possible
> kernels to boot with, they could expose the raw kernel data somewhere
> in their API - we don't neccessarily need to expose that from QEMU.

It gets more interesting where it's the guest which picks the
kernel/initrd; imagine the setup where the cloud reads the kernel/initrd
from the guest disk and passes that to qemu; one of the update ideas
would be just to let the guest update from a repo at it's own pace;
so the attestor doesn't know whether to expect a new or old kernel
from the guest; but it does know it should be one of the approved
set of kernels.

Dave

> If we don't find a way to extract the VMSA data blob on the fly,
> then the cloud owner will need to public VMSA data somewhere out
> of band regardless.
> 
> 
> 
> > > Is that really compelling enough to justify adding this extra
> > > info to the QAPI commands ? IME of writing code to verify the SEV
> > > measurement, there were many little ways I screwed up at first
> > > and having this field would not have made a significant difference
> > > to my debugging efforts.
> > 
> > I think that adding the extra field is not that bad, even if it's useful
> > just for some cases.
> > 
> > I'll be glad to get rid of the launch_memory buffer in my implementation
> > and replace it with a SHA256-context variable (but found none in QEMU).
> >  Other than that I don't think the suggested addition is too bad (in
> > fact, I would add some more info like kernel hashes.).
> 
> Given we can't actually emit a valid GCTX.LD for SEV, my preference
> would be to just report the hashes of each piece of data that is a
> input to the GCTX.LD. eg report 'firmware-digest', 'kernel-digest',
> 'initrd-digest', 'cmdline-digest'.
> 
> They can use firmware-digest as a identifier to locate the raw
> firmware data blob.
> 
> They can use kernel-digest, initrd-digest, and cmdline-digest to
> compare against their list of expected kernel/initrd binaries, if
> the cloud owner controls them, and also to then build the kernl
> hashes table.
> 
> They still have to figure out the VMSAs separately somehow, or
> the cloud mgmt layer can use all of this info to expose the
> raw data in their own higher level API.
> 
> 
> Regards,
> Daniel
> -- 
> |: https://berrange.com      -o-    https://www.flickr.com/photos/dberrange :|
> |: https://libvirt.org         -o-            https://fstop138.berrange.com :|
> |: https://entangle-photo.org    -o-    https://www.instagram.com/dberrange :|
> 
-- 
Dr. David Alan Gilbert / dgilb...@redhat.com / Manchester, UK


Reply via email to