All of lore.kernel.org
 help / color / mirror / Atom feed
* Interactive launch over QMP socket?
@ 2021-02-10 18:01 Connor Kuehl
  2021-02-10 18:14 ` James Bottomley
                   ` (2 more replies)
  0 siblings, 3 replies; 12+ messages in thread
From: Connor Kuehl @ 2021-02-10 18:01 UTC (permalink / raw)
  To: qemu-devel; +Cc: jejb, npmccallum, dgilbert

Hello,

Does QEMU have an internal API which would allow VM construction to wait 
at a *very specific point* until specific data/QMP message(s) are 
supplied via the QMP socket?

For some additional context: QEMU supports launching AMD SEV-protected 
guests; in short: encrypted virtual machines. Guest owners may 
participate in attestation to cryptographically verify their assumptions 
about the guest's initial state, the host's platform, and the host 
platform owner's identity. If the guest owner is satisfied with the 
attestation process, a secret can be safely injected into the guest's 
address space over a secure channel.

Attestation is an unavoidably interactive process.

It appears that QEMU already exposes most of the API required to perform 
this attestation remotely with a guest owner over QMP, with only one 
exception: starting the attestation session. It looks like the session 
components (policy, session-file, and dh-cert-file) are supplied via 
command line arguments to QEMU and don't have a message type in the QMP 
spec:

	-object 
sev-guest,id=sev0,cbitpos=47,reduced-phys-bits=1,policy=0x1,session-file=blah.session,dh-cert-file=guest_owner.cert

I would like to add a message type to QMP which allows guest owners to 
supply this data over a socket and _not_ require these components a 
priori via command line arguments. In doing so, this would allow for a 
100% remote attestation process over the socket. However, I'm not sure 
how to express this interactive "waiting" for this data to become 
available with internal APIs (assuming it's not supplied as a command 
line argument).

For example, in order to accomplish a 100% remote attestation:

Somewhere in between sev_guest_init() and sev_launch_start(), the guest 
owner may send the following messages:

1. "query-sev" to collect important information about the platform state

2. "query-sev-capabilities" to independently verify the platform 
certificate chain and derive a shared secret for establishing a secure 
channel with the AMD SP.

3. "sev-launch-start" this is the only message that I think is missing 
from the QMP message types for remote attestation. This is how the guest 
owner would deliver the session components over the socket instead of as 
command line arguments.

Then, sometime before the VM is launched and is running, the guest owner 
may send:

4. "query-sev-launch-measure" to compare its measurement against the AMD 
SP's measurement

5. "sev-inject-launch-secret" if happy with attestation, securely 
deliver secrets

6. Guest owner could send a "cont" command and the VM can launch

Any advice on how to accomplish adding this degree of interaction to 
supplying inputs to specific parts of the launch process this is greatly 
appreciated.

Thank you,

Connor

QEMU QMP Reference Manual: 
https://qemu.readthedocs.io/en/latest/interop/qemu-qmp-ref.html



^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: Interactive launch over QMP socket?
  2021-02-10 18:01 Interactive launch over QMP socket? Connor Kuehl
@ 2021-02-10 18:14 ` James Bottomley
  2021-02-10 18:46   ` Connor Kuehl
  2021-02-22 11:40 ` Kevin Wolf
  2021-02-22 12:18 ` Daniel P. Berrangé
  2 siblings, 1 reply; 12+ messages in thread
From: James Bottomley @ 2021-02-10 18:14 UTC (permalink / raw)
  To: Connor Kuehl, qemu-devel; +Cc: npmccallum, dgilbert

On Wed, 2021-02-10 at 12:01 -0600, Connor Kuehl wrote:
> Hello,
> 
> Does QEMU have an internal API which would allow VM construction to
> wait at a *very specific point* until specific data/QMP message(s)
> are supplied via the QMP socket?

Yes, the -S flag tells qemu to pause before starting the VM but after
setting it up.  It's the flag I use for SEV.

> For some additional context: QEMU supports launching AMD SEV-
> protected guests; in short: encrypted virtual machines. Guest owners
> may participate in attestation to cryptographically verify their
> assumptions about the guest's initial state, the host's platform, and
> the host platform owner's identity. If the guest owner is satisfied
> with the attestation process, a secret can be safely injected into
> the guest's address space over a secure channel.
> 
> Attestation is an unavoidably interactive process.
> 
> It appears that QEMU already exposes most of the API required to
> perform this attestation remotely with a guest owner over QMP, with
> only one exception: starting the attestation session. It looks like
> the session  components (policy, session-file, and dh-cert-file) are
> supplied via command line arguments to QEMU and don't have a message
> type in the QMP spec:
> 
> 	-object 
> sev-guest,id=sev0,cbitpos=47,reduced-phys-bits=1,policy=0x1,session-
> file=blah.session,dh-cert-file=guest_owner.cert
> 
> I would like to add a message type to QMP which allows guest owners
> to supply this data over a socket and _not_ require these components
> a priori via command line arguments. In doing so, this would allow
> for a 100% remote attestation process over the socket. However, I'm
> not sure how to express this interactive "waiting" for this data to
> become available with internal APIs (assuming it's not supplied as a
> command  line argument).

Well, I never understood why qemu can't deduce the value of cbitpos ...
it even errors out if you get it wrong.  However, other things like the
policy and the session file have to be present at start of day. 
They're not things that can be passed in after qemu starts building the
machine image because they need to be present to begin building it.

> For example, in order to accomplish a 100% remote attestation:
> 
> Somewhere in between sev_guest_init() and sev_launch_start(), the
> guest owner may send the following messages:
> 
> 1. "query-sev" to collect important information about the platform
> state
> 
> 2. "query-sev-capabilities" to independently verify the platform 
> certificate chain and derive a shared secret for establishing a
> secure channel with the AMD SP.
> 
> 3. "sev-launch-start" this is the only message that I think is
> missing from the QMP message types for remote attestation. This is
> how the guest owner would deliver the session components over the
> socket instead of as command line arguments.

The patch for remote attestation (which was only recently added to the
PSP protocol) is here:

https://lore.kernel.org/kvm/20210105163943.30510-1-brijesh.singh@amd.com/

> Then, sometime before the VM is launched and is running, the guest
> owner may send:
> 
> 4. "query-sev-launch-measure" to compare its measurement against the
> AMD SP's measurement
> 
> 5. "sev-inject-launch-secret" if happy with attestation, securely 
> deliver secrets
> 
> 6. Guest owner could send a "cont" command and the VM can launch
> 
> Any advice on how to accomplish adding this degree of interaction to 
> supplying inputs to specific parts of the launch process this is
> greatly appreciated.

I've attached the python script I use to launch sev guests.  However,
it doesn't include the launch bundle because that has to have already
been passed in when qemu was started.

James

---
#!/usr/bin/python3
##
# Python script to inject a secret disk password into a paused SEV VM
#  (to pause the VM start with -S option)
#
# This assumes you've already created the launch bundle using sev-tool
# from https://github.com/AMDESE/sev-tool.git
#
# sev-tool --generate_launch_blob
#
# creates several files, the only one this script needs is the TIK and TEK
# keys which are stored in tmp_tk.bin
#
# Once TIK/TEK are known, the script will probe the VM for the sev
# parameters needed to calculate the launch measure, retrieve the launch
# measure and verify against the measure calculated from the OVMF hash
# and if that matches create the secret bundle and inject it
#
# Tables and chapters refer to the amd 55766.pdf document
#
# https://www.amd.com/system/files/TechDocs/55766_SEV-KM_API_Specification.pdf
##
import sys
import os 
import base64
import hmac
import hashlib
from argparse import ArgumentParser
from uuid import UUID
from Crypto.Cipher import AES
from Crypto.Util import Counter
from git.qemu.python.qemu import qmp

if __name__ == "__main__":
    parser = ArgumentParser(description='Inject secret into SEV')
    parser.add_argument('--tiktek-file',
                        help='file where sev-tool stored the TIK/TEK combination, defaults to tmp_tk.bin',
                        default='tmp_tk.bin')
    parser.add_argument('--passwd',
                        help='Disk Password',
                        required=True)
    parser.add_argument('--ovmf-hash',
                        help='hash of OVMF firmware blob in hex')
    parser.add_argument('--ovmf-file',
                        help='location of OVMF file to calculate hash from')
    parser.add_argument('--socket',
                        help='Socket to connect to QMP on, defaults to localhost:6550',
                        default='localhost:6550')
    args = parser.parse_args()

    if (args.ovmf_file):
        fh = open (args.ovmf_file, 'rb')
        h = hashlib.sha256(fh.read())
        ovmf_hash = h.digest()
    elif (args.ovmf_hash):
        ovmf_hash = bytearray.fromhex(args.ovmf_hash)
    else:
        parser.error('one of --ovmf-hash or -ovmf-file must be specified')

    if (args.socket[0] == '/'):
        socket = args.socket
    elif (':' in args.socket):
        s = args.socket.split(':')
        socket = (s[0], int(s[1]))
    else:
        parse.error('--socket must be <host>:<port> or /path/to/unix')

    fh=open(args.tiktek_file, 'rb')
    tiktek=bytearray(fh.read())
    fh.close()

    ##
    #  tiktek file is just two binary aes128 keys
    ##
    TEK=tiktek[0:16]
    TIK=tiktek[16:32]

    disk_secret = args.passwd

    Qmp = qmp.QEMUMonitorProtocol(address=socket);
    Qmp.connect()
    caps = Qmp.command('query-sev')
    print('SEV query found API={api-major}.{api-minor} build={build-id} policy={policy}'.format(**caps))
    h = hmac.new(TIK, digestmod='sha256');

    ##
    # calculated per section 6.5.2
    ##
    h.update(bytes([0x04]))
    h.update(caps['api-major'].to_bytes(1,byteorder='little'))
    h.update(caps['api-minor'].to_bytes(1,byteorder='little'))
    h.update(caps['build-id'].to_bytes(1,byteorder='little'))
    h.update(caps['policy'].to_bytes(4,byteorder='little'))
    h.update(ovmf_hash)

    print('\nGetting Launch Measurement')
    meas = Qmp.command('query-sev-launch-measure')
    launch_measure = base64.b64decode(meas['data'])

    ##
    # returned data per Table 52. LAUNCH_MEASURE Measurement Buffer
    ##
    nonce = launch_measure[32:48]
    h.update(nonce)
    measure = launch_measure[0:32]

    print('Measure:   ', measure.hex())
    print('should be: ', h.digest().hex())
    print('')

    if (measure != h.digest()):
        sys.exit('Measurement doesn\'t match')

    print('Measurement matches, Injecting Secret')

    ##
    # construct the secret table: two guids + 4 byte lengths plus string
    # and zero terminator
    #
    # Secret layout is  guid, len (4 bytes), data
    # with len being the length from start of guid to end of data
    #
    # The table header covers the entire table then each entry covers
    # only its local data
    #
    # our current table has the header guid with total table length
    # followed by the secret guid with the zero terminated secret 
    ##
    
    # total length of table: header plus one entry with trailing \0
    l = 16 + 4 + 16 + 4 + len(disk_secret) + 1
    # SEV-ES requires rounding to 16
    l = (l + 15) & ~15
    secret = bytearray(l);
    secret[0:16] = UUID('{1e74f542-71dd-4d66-963e-ef4287ff173b}').bytes_le
    secret[16:20] = len(secret).to_bytes(4, byteorder='little')
    secret[20:36] = UUID('{736869e5-84f0-4973-92ec-06879ce3da0b}').bytes_le
    secret[36:40] = (16 + 4 + len(disk_secret) + 1).to_bytes(4, byteorder='little')
    secret[40:40+len(disk_secret)] = disk_secret.encode()
    
    ##
    # encrypt the secret table with the TEK in ctr mode using a random IV
    ##
    IV=os.urandom(16)
    # -EKNUCKLEHEADS in python crypto don't understand CTR mode
    e = AES.new(TEK, AES.MODE_CTR, counter=Counter.new(128,initial_value=int.from_bytes(IV, byteorder='big')));
    encrypted_secret = e.encrypt(bytes(secret))

    ##
    # ultimately needs to be an argument, but there's only
    # compressed and no real use case
    ##
    FLAGS = 0

    ##
    # Table 55. LAUNCH_SECRET Packet Header Buffer
    ##
    header=bytearray(52);
    header[0:4]=FLAGS.to_bytes(4,byteorder='little')
    header[4:20]=IV
    h = hmac.new(TIK, digestmod='sha256');
    h.update(bytes([0x01]))
    # FLAGS || IV
    h.update(header[0:20])
    h.update(l.to_bytes(4, byteorder='little'))
    h.update(l.to_bytes(4, byteorder='little'))
    h.update(encrypted_secret)
    h.update(measure)
    header[20:52]=h.digest()

    Qmp.command('sev-inject-launch-secret',
                **{'packet-header': base64.b64encode(header).decode(),
                   'secret': base64.b64encode(encrypted_secret).decode()
                })

    print('\nSecret Injection Successful, starting VM')

    Qmp.command('cont')




^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: Interactive launch over QMP socket?
  2021-02-10 18:14 ` James Bottomley
@ 2021-02-10 18:46   ` Connor Kuehl
  2021-02-10 19:06     ` James Bottomley
  0 siblings, 1 reply; 12+ messages in thread
From: Connor Kuehl @ 2021-02-10 18:46 UTC (permalink / raw)
  To: jejb, qemu-devel; +Cc: npmccallum, dgilbert

On 2/10/21 12:14 PM, James Bottomley wrote:
>> I would like to add a message type to QMP which allows guest owners
>> to supply this data over a socket and _not_ require these components
>> a priori via command line arguments. In doing so, this would allow
>> for a 100% remote attestation process over the socket. However, I'm
>> not sure how to express this interactive "waiting" for this data to
>> become available with internal APIs (assuming it's not supplied as a
>> command  line argument).
> 
> Well, I never understood why qemu can't deduce the value of cbitpos ...
> it even errors out if you get it wrong.  However, other things like the
> policy and the session file have to be present at start of day.
> They're not things that can be passed in after qemu starts building the
> machine image because they need to be present to begin building it.

Right, I didn't mean to include cbitpos in consideration for this. I'm 
only interested in supplying the session, policy, and certificate info 
over the socket.

Shouldn't the session, policy, and certificate information only be 
required in time for the KVM_SEV_LAUNCH_START ioctl call? This is the 
place I'm interested in waiting for the relevant data.

> The patch for remote attestation (which was only recently added to the
> PSP protocol) is here:
> 
> https://lore.kernel.org/kvm/20210105163943.30510-1-brijesh.singh@amd.com/

Thank you! I didn't see this, I'll read up on it.

Connor



^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: Interactive launch over QMP socket?
  2021-02-10 18:46   ` Connor Kuehl
@ 2021-02-10 19:06     ` James Bottomley
  2021-02-10 20:39       ` Connor Kuehl
  0 siblings, 1 reply; 12+ messages in thread
From: James Bottomley @ 2021-02-10 19:06 UTC (permalink / raw)
  To: Connor Kuehl, qemu-devel; +Cc: npmccallum, dgilbert

On Wed, 2021-02-10 at 12:46 -0600, Connor Kuehl wrote:
> On 2/10/21 12:14 PM, James Bottomley wrote:
> > > I would like to add a message type to QMP which allows guest
> > > owners to supply this data over a socket and _not_ require these
> > > components a priori via command line arguments. In doing so, this
> > > would allow for a 100% remote attestation process over the
> > > socket. However, I'm not sure how to express this interactive
> > > "waiting" for this data to become available with internal APIs
> > > (assuming it's not supplied as a command  line argument).
> > 
> > Well, I never understood why qemu can't deduce the value of cbitpos
> > ... it even errors out if you get it wrong.  However, other things
> > like the policy and the session file have to be present at start of
> > day. They're not things that can be passed in after qemu starts
> > building the machine image because they need to be present to begin
> > building it.
> 
> Right, I didn't mean to include cbitpos in consideration for this.
> I'm only interested in supplying the session, policy, and certificate
> info over the socket.
> 
> Shouldn't the session, policy, and certificate information only be 
> required in time for the KVM_SEV_LAUNCH_START ioctl call? This is
> the place I'm interested in waiting for the relevant data.

Well, it could, but I see the session information as being the same as
the image file, which is also a command line argument, so if you can do
the image file on the command line, why not the session info as well?

The other problem is the session info is exchanged for a launch handle
in kvm_init, which is machine_init in qemu terms.  That's called
phenomenally early, so there's not much of kvm to pause before you do
that.  So either qemu has to be rewritten to pause before processing
command line arguments, and then any argument can be added over QMP, or
the handle exchange has to occur later.

James




^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: Interactive launch over QMP socket?
  2021-02-10 19:06     ` James Bottomley
@ 2021-02-10 20:39       ` Connor Kuehl
  2021-02-11  9:11         ` Dr. David Alan Gilbert
  0 siblings, 1 reply; 12+ messages in thread
From: Connor Kuehl @ 2021-02-10 20:39 UTC (permalink / raw)
  To: jejb, qemu-devel; +Cc: npmccallum, dgilbert

On 2/10/21 1:06 PM, James Bottomley wrote:
> On Wed, 2021-02-10 at 12:46 -0600, Connor Kuehl wrote:
>> Right, I didn't mean to include cbitpos in consideration for this.
>> I'm only interested in supplying the session, policy, and certificate
>> info over the socket.
>>
>> Shouldn't the session, policy, and certificate information only be
>> required in time for the KVM_SEV_LAUNCH_START ioctl call? This is
>> the place I'm interested in waiting for the relevant data.
> 
> Well, it could, but I see the session information as being the same as
> the image file, which is also a command line argument, so if you can do
> the image file on the command line, why not the session info as well?

It would be interesting to allow remote delivery of the initial image as 
well because for purposes of attestation I would argue that the guest 
owner should have as much of the locus of control as possible. However, 
because the guest image is unlikely to change between launches/guests, 
it's probably more helpful to deliver it to the host, let it cache it, 
and supply that via a command line argument. I'm mainly interested in 
the session blob, policy, and certificate for now though.

I don't see a similar value in caching a session blob or policy because 
it is trivial to generate these and put them in a JSON object and send 
them on demand. I think that chopping up part of the attestation 
process, setting it aside, and having to figure out how to deliver it to 
the host where the QEMU process will launch creates an impedance 
mismatch. Usability impedance mismatches tend to motivate the creation 
of one or more automation/translation layers to automate that "glue" away.

Extending QMP to allow end-to-end attestation via QEMU removes the need 
for that glue and improves interoperability with other client 
implementations who care about attestation. Providers would just need to 
point out the QMP endpoint for guest owners. It lends itself to a more 
"atomic" transaction-like attestation experience overall.

> The other problem is the session info is exchanged for a launch handle
> in kvm_init, which is machine_init in qemu terms.  That's called
> phenomenally early, so there's not much of kvm to pause before you do
> that.  So either qemu has to be rewritten to pause before processing
> command line arguments, and then any argument can be added over QMP, or
> the handle exchange has to occur later.

Ah, I see, thank you.

Connor

> James
> 
> 



^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: Interactive launch over QMP socket?
  2021-02-10 20:39       ` Connor Kuehl
@ 2021-02-11  9:11         ` Dr. David Alan Gilbert
  0 siblings, 0 replies; 12+ messages in thread
From: Dr. David Alan Gilbert @ 2021-02-11  9:11 UTC (permalink / raw)
  To: Connor Kuehl; +Cc: jejb, npmccallum, qemu-devel

* Connor Kuehl (ckuehl@redhat.com) wrote:
> On 2/10/21 1:06 PM, James Bottomley wrote:
> > On Wed, 2021-02-10 at 12:46 -0600, Connor Kuehl wrote:
> > > Right, I didn't mean to include cbitpos in consideration for this.
> > > I'm only interested in supplying the session, policy, and certificate
> > > info over the socket.
> > > 
> > > Shouldn't the session, policy, and certificate information only be
> > > required in time for the KVM_SEV_LAUNCH_START ioctl call? This is
> > > the place I'm interested in waiting for the relevant data.
> > 
> > Well, it could, but I see the session information as being the same as
> > the image file, which is also a command line argument, so if you can do
> > the image file on the command line, why not the session info as well?
> 
> It would be interesting to allow remote delivery of the initial image as
> well because for purposes of attestation I would argue that the guest owner
> should have as much of the locus of control as possible. However, because
> the guest image is unlikely to change between launches/guests, it's probably
> more helpful to deliver it to the host, let it cache it, and supply that via
> a command line argument. I'm mainly interested in the session blob, policy,
> and certificate for now though.
> 
> I don't see a similar value in caching a session blob or policy because it
> is trivial to generate these and put them in a JSON object and send them on
> demand. I think that chopping up part of the attestation process, setting it
> aside, and having to figure out how to deliver it to the host where the QEMU
> process will launch creates an impedance mismatch. Usability impedance
> mismatches tend to motivate the creation of one or more
> automation/translation layers to automate that "glue" away.
> 
> Extending QMP to allow end-to-end attestation via QEMU removes the need for
> that glue and improves interoperability with other client implementations
> who care about attestation. Providers would just need to point out the QMP
> endpoint for guest owners. It lends itself to a more "atomic"
> transaction-like attestation experience overall.

Note that QMP is not 'safe' - anyone who has control of QMP can cause
the qemu to try and open arbitrary files on the host (by binding them as
disks for example) or allocate memory (by hot adding RAM); so raw QMP is
not something that you could give to a guest owner.

Dave

> > The other problem is the session info is exchanged for a launch handle
> > in kvm_init, which is machine_init in qemu terms.  That's called
> > phenomenally early, so there's not much of kvm to pause before you do
> > that.  So either qemu has to be rewritten to pause before processing
> > command line arguments, and then any argument can be added over QMP, or
> > the handle exchange has to occur later.
> 
> Ah, I see, thank you.
> 
> Connor
> 
> > James
> > 
> > 
> 
-- 
Dr. David Alan Gilbert / dgilbert@redhat.com / Manchester, UK



^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: Interactive launch over QMP socket?
  2021-02-10 18:01 Interactive launch over QMP socket? Connor Kuehl
  2021-02-10 18:14 ` James Bottomley
@ 2021-02-22 11:40 ` Kevin Wolf
  2021-02-22 15:39   ` Daniel P. Berrangé
  2021-02-22 12:18 ` Daniel P. Berrangé
  2 siblings, 1 reply; 12+ messages in thread
From: Kevin Wolf @ 2021-02-22 11:40 UTC (permalink / raw)
  To: Connor Kuehl; +Cc: jejb, npmccallum, qemu-devel, dgilbert

Am 10.02.2021 um 19:01 hat Connor Kuehl geschrieben:
> Hello,
> 
> Does QEMU have an internal API which would allow VM construction to wait at
> a *very specific point* until specific data/QMP message(s) are supplied via
> the QMP socket?
> 
> For some additional context: QEMU supports launching AMD SEV-protected
> guests; in short: encrypted virtual machines. Guest owners may participate
> in attestation to cryptographically verify their assumptions about the
> guest's initial state, the host's platform, and the host platform owner's
> identity. If the guest owner is satisfied with the attestation process, a
> secret can be safely injected into the guest's address space over a secure
> channel.
> 
> Attestation is an unavoidably interactive process.
> 
> It appears that QEMU already exposes most of the API required to perform
> this attestation remotely with a guest owner over QMP, with only one
> exception: starting the attestation session. It looks like the session
> components (policy, session-file, and dh-cert-file) are supplied via command
> line arguments to QEMU and don't have a message type in the QMP spec:
> 
> 	-object sev-guest,id=sev0,cbitpos=47,reduced-phys-bits=1,policy=0x1,session-file=blah.session,dh-cert-file=guest_owner.cert
> 
> I would like to add a message type to QMP which allows guest owners to
> supply this data over a socket and _not_ require these components a priori
> via command line arguments.

I don't think you need a new QMP command for this. If you would use
-object on the command line, you can use QMP object-add at runtime.

Kevin



^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: Interactive launch over QMP socket?
  2021-02-10 18:01 Interactive launch over QMP socket? Connor Kuehl
  2021-02-10 18:14 ` James Bottomley
  2021-02-22 11:40 ` Kevin Wolf
@ 2021-02-22 12:18 ` Daniel P. Berrangé
  2021-02-22 15:00   ` Connor Kuehl
  2 siblings, 1 reply; 12+ messages in thread
From: Daniel P. Berrangé @ 2021-02-22 12:18 UTC (permalink / raw)
  To: Connor Kuehl; +Cc: jejb, npmccallum, qemu-devel, dgilbert

On Wed, Feb 10, 2021 at 12:01:09PM -0600, Connor Kuehl wrote:
> Hello,
> 
> Does QEMU have an internal API which would allow VM construction to wait at
> a *very specific point* until specific data/QMP message(s) are supplied via
> the QMP socket?
> 
> For some additional context: QEMU supports launching AMD SEV-protected
> guests; in short: encrypted virtual machines. Guest owners may participate
> in attestation to cryptographically verify their assumptions about the
> guest's initial state, the host's platform, and the host platform owner's
> identity. If the guest owner is satisfied with the attestation process, a
> secret can be safely injected into the guest's address space over a secure
> channel.
> 
> Attestation is an unavoidably interactive process.
> 
> It appears that QEMU already exposes most of the API required to perform
> this attestation remotely with a guest owner over QMP, with only one
> exception: starting the attestation session. It looks like the session
> components (policy, session-file, and dh-cert-file) are supplied via command
> line arguments to QEMU and don't have a message type in the QMP spec:
> 
> 	-object sev-guest,id=sev0,cbitpos=47,reduced-phys-bits=1,policy=0x1,session-file=blah.session,dh-cert-file=guest_owner.cert
> 
> I would like to add a message type to QMP which allows guest owners to
> supply this data over a socket and _not_ require these components a priori
> via command line arguments. In doing so, this would allow for a 100% remote
> attestation process over the socket. However, I'm not sure how to express
> this interactive "waiting" for this data to become available with internal
> APIs (assuming it's not supplied as a command line argument).
> 
> For example, in order to accomplish a 100% remote attestation:
> 
> Somewhere in between sev_guest_init() and sev_launch_start(), the guest
> owner may send the following messages:
> 
> 1. "query-sev" to collect important information about the platform state
> 
> 2. "query-sev-capabilities" to independently verify the platform certificate
> chain and derive a shared secret for establishing a secure channel with the
> AMD SP.

AFAIK, these two commands are merely fetching info about the host, and the
info doesn't vary based on guest config. IOW, this can be done before the
real guest QEMU process is launched, using a throwaway QEMU instance....

> 3. "sev-launch-start" this is the only message that I think is missing from
> the QMP message types for remote attestation. This is how the guest owner
> would deliver the session components over the socket instead of as command
> line arguments.

... so this doesn't actually seem to need to be done in QMP on the fly.
It can be provided on the CLI, which seems to be possible wth the args
shown earlier.

> Then, sometime before the VM is launched and is running, the guest owner may
> send:
> 
> 4. "query-sev-launch-measure" to compare its measurement against the AMD
> SP's measurement
> 
> 5. "sev-inject-launch-secret" if happy with attestation, securely deliver
> secrets
> 
> 6. Guest owner could send a "cont" command and the VM can launch
> 
> Any advice on how to accomplish adding this degree of interaction to
> supplying inputs to specific parts of the launch process this is greatly
> appreciated.

It seems like this is all doable already unless I'm missing something.

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 :|



^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: Interactive launch over QMP socket?
  2021-02-22 12:18 ` Daniel P. Berrangé
@ 2021-02-22 15:00   ` Connor Kuehl
  2021-02-22 15:36     ` Daniel P. Berrangé
  0 siblings, 1 reply; 12+ messages in thread
From: Connor Kuehl @ 2021-02-22 15:00 UTC (permalink / raw)
  To: Daniel P. Berrangé; +Cc: jejb, npmccallum, qemu-devel, dgilbert

On 2/22/21 6:18 AM, Daniel P. Berrangé wrote:
> 
> ... so this doesn't actually seem to need to be done in QMP on the fly.
> It can be provided on the CLI, which seems to be possible wth the args
> shown earlier.
> 

> 
> It seems like this is all doable already unless I'm missing something.

That's correct; however, I would like to make it possible for the 
entirety of it to happen on the fly, ultimately rendering the CLI args 
optional.

Connor



^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: Interactive launch over QMP socket?
  2021-02-22 15:00   ` Connor Kuehl
@ 2021-02-22 15:36     ` Daniel P. Berrangé
  0 siblings, 0 replies; 12+ messages in thread
From: Daniel P. Berrangé @ 2021-02-22 15:36 UTC (permalink / raw)
  To: Connor Kuehl; +Cc: jejb, npmccallum, qemu-devel, dgilbert

On Mon, Feb 22, 2021 at 09:00:36AM -0600, Connor Kuehl wrote:
> On 2/22/21 6:18 AM, Daniel P. Berrangé wrote:
> > 
> > ... so this doesn't actually seem to need to be done in QMP on the fly.
> > It can be provided on the CLI, which seems to be possible wth the args
> > shown earlier.
> > 
> 
> > 
> > It seems like this is all doable already unless I'm missing something.
> 
> That's correct; however, I would like to make it possible for the entirety
> of it to happen on the fly, ultimately rendering the CLI args optional.

There is a long term goal to make entire of QEMU CLI optional, such that
it only contains the QMP config, and then do every thing related to VM
setup as QMP commands. So if current CLI is functionally sufficient,
then eventually, the same will be doable exclusively at runtime. We
don't have a firm ETA for this though.

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 :|



^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: Interactive launch over QMP socket?
  2021-02-22 11:40 ` Kevin Wolf
@ 2021-02-22 15:39   ` Daniel P. Berrangé
  2021-02-22 16:23     ` Kevin Wolf
  0 siblings, 1 reply; 12+ messages in thread
From: Daniel P. Berrangé @ 2021-02-22 15:39 UTC (permalink / raw)
  To: Kevin Wolf; +Cc: Connor Kuehl, jejb, npmccallum, qemu-devel, dgilbert

On Mon, Feb 22, 2021 at 12:40:07PM +0100, Kevin Wolf wrote:
> Am 10.02.2021 um 19:01 hat Connor Kuehl geschrieben:
> > Hello,
> > 
> > Does QEMU have an internal API which would allow VM construction to wait at
> > a *very specific point* until specific data/QMP message(s) are supplied via
> > the QMP socket?
> > 
> > For some additional context: QEMU supports launching AMD SEV-protected
> > guests; in short: encrypted virtual machines. Guest owners may participate
> > in attestation to cryptographically verify their assumptions about the
> > guest's initial state, the host's platform, and the host platform owner's
> > identity. If the guest owner is satisfied with the attestation process, a
> > secret can be safely injected into the guest's address space over a secure
> > channel.
> > 
> > Attestation is an unavoidably interactive process.
> > 
> > It appears that QEMU already exposes most of the API required to perform
> > this attestation remotely with a guest owner over QMP, with only one
> > exception: starting the attestation session. It looks like the session
> > components (policy, session-file, and dh-cert-file) are supplied via command
> > line arguments to QEMU and don't have a message type in the QMP spec:
> > 
> > 	-object sev-guest,id=sev0,cbitpos=47,reduced-phys-bits=1,policy=0x1,session-file=blah.session,dh-cert-file=guest_owner.cert
> > 
> > I would like to add a message type to QMP which allows guest owners to
> > supply this data over a socket and _not_ require these components a priori
> > via command line arguments.
> 
> I don't think you need a new QMP command for this. If you would use
> -object on the command line, you can use QMP object-add at runtime.

If the object were standalone that'd true, but 'sev-guest' object you
create needs to be given to the '-machine' arg's 'memory-encryption'
parameter. So there's a dependancy that means 'sev-guest' can only
be used with -object in reality and not QMP object-add.

This will eventually be solved when we make it possible to fully
configure QEMU exclusively via QMP.

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 :|



^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: Interactive launch over QMP socket?
  2021-02-22 15:39   ` Daniel P. Berrangé
@ 2021-02-22 16:23     ` Kevin Wolf
  0 siblings, 0 replies; 12+ messages in thread
From: Kevin Wolf @ 2021-02-22 16:23 UTC (permalink / raw)
  To: Daniel P. Berrangé
  Cc: Connor Kuehl, jejb, npmccallum, qemu-devel, dgilbert

Am 22.02.2021 um 16:39 hat Daniel P. Berrangé geschrieben:
> On Mon, Feb 22, 2021 at 12:40:07PM +0100, Kevin Wolf wrote:
> > Am 10.02.2021 um 19:01 hat Connor Kuehl geschrieben:
> > > Hello,
> > > 
> > > Does QEMU have an internal API which would allow VM construction to wait at
> > > a *very specific point* until specific data/QMP message(s) are supplied via
> > > the QMP socket?
> > > 
> > > For some additional context: QEMU supports launching AMD SEV-protected
> > > guests; in short: encrypted virtual machines. Guest owners may participate
> > > in attestation to cryptographically verify their assumptions about the
> > > guest's initial state, the host's platform, and the host platform owner's
> > > identity. If the guest owner is satisfied with the attestation process, a
> > > secret can be safely injected into the guest's address space over a secure
> > > channel.
> > > 
> > > Attestation is an unavoidably interactive process.
> > > 
> > > It appears that QEMU already exposes most of the API required to perform
> > > this attestation remotely with a guest owner over QMP, with only one
> > > exception: starting the attestation session. It looks like the session
> > > components (policy, session-file, and dh-cert-file) are supplied via command
> > > line arguments to QEMU and don't have a message type in the QMP spec:
> > > 
> > > 	-object sev-guest,id=sev0,cbitpos=47,reduced-phys-bits=1,policy=0x1,session-file=blah.session,dh-cert-file=guest_owner.cert
> > > 
> > > I would like to add a message type to QMP which allows guest owners to
> > > supply this data over a socket and _not_ require these components a priori
> > > via command line arguments.
> > 
> > I don't think you need a new QMP command for this. If you would use
> > -object on the command line, you can use QMP object-add at runtime.
> 
> If the object were standalone that'd true, but 'sev-guest' object you
> create needs to be given to the '-machine' arg's 'memory-encryption'
> parameter. So there's a dependancy that means 'sev-guest' can only
> be used with -object in reality and not QMP object-add.

I see. But an additional QMP command can't change much about this
either.

Maybe the most realistic option today would be making some properties
optional initally so the object can be created and referenced in
-machine, and then you would use qom-set to provide the information
before you actually start using the object.

> This will eventually be solved when we make it possible to fully
> configure QEMU exclusively via QMP.

Yes, once -machine can actually be done via QMP, that would be solved.

Kevin



^ permalink raw reply	[flat|nested] 12+ messages in thread

end of thread, other threads:[~2021-02-22 16:29 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-02-10 18:01 Interactive launch over QMP socket? Connor Kuehl
2021-02-10 18:14 ` James Bottomley
2021-02-10 18:46   ` Connor Kuehl
2021-02-10 19:06     ` James Bottomley
2021-02-10 20:39       ` Connor Kuehl
2021-02-11  9:11         ` Dr. David Alan Gilbert
2021-02-22 11:40 ` Kevin Wolf
2021-02-22 15:39   ` Daniel P. Berrangé
2021-02-22 16:23     ` Kevin Wolf
2021-02-22 12:18 ` Daniel P. Berrangé
2021-02-22 15:00   ` Connor Kuehl
2021-02-22 15:36     ` Daniel P. Berrangé

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.