[PATCH 00/16] hw/uefi: add uefi variable service

Gerd Hoffmann posted 16 patches 1 year ago
Patches applied successfully (tree, apply log)
git fetch https://github.com/patchew-project/qemu tags/patchew/20231115151242.184645-1-kraxel@redhat.com
Maintainers: Paolo Bonzini <pbonzini@redhat.com>, Peter Maydell <peter.maydell@linaro.org>, "Marc-André Lureau" <marcandre.lureau@redhat.com>, "Daniel P. Berrangé" <berrange@redhat.com>, Thomas Huth <thuth@redhat.com>, "Philippe Mathieu-Daudé" <philmd@linaro.org>, Markus Armbruster <armbru@redhat.com>, Michael Roth <michael.roth@amd.com>, Eric Blake <eblake@redhat.com>
include/hw/arm/virt.h              |   2 +
include/hw/uefi/var-service-api.h  |  40 ++
include/hw/uefi/var-service-edk2.h | 184 +++++++++
include/hw/uefi/var-service.h      | 119 ++++++
hw/arm/virt.c                      |  41 ++
hw/uefi/var-service-auth.c         |  91 +++++
hw/uefi/var-service-core.c         | 350 +++++++++++++++++
hw/uefi/var-service-guid.c         |  61 +++
hw/uefi/var-service-isa.c          |  88 +++++
hw/uefi/var-service-json.c         | 194 ++++++++++
hw/uefi/var-service-policy.c       | 390 +++++++++++++++++++
hw/uefi/var-service-sysbus.c       |  87 +++++
hw/uefi/var-service-vars.c         | 602 +++++++++++++++++++++++++++++
docs/devel/index-internals.rst     |   1 +
docs/devel/uefi-vars.rst           |  66 ++++
hw/Kconfig                         |   1 +
hw/meson.build                     |   1 +
hw/uefi/Kconfig                    |   9 +
hw/uefi/TODO.md                    |  17 +
hw/uefi/meson.build                |  18 +
hw/uefi/trace-events               |  16 +
meson.build                        |   1 +
qapi/meson.build                   |   1 +
qapi/qapi-schema.json              |   1 +
qapi/uefi.json                     |  40 ++
25 files changed, 2421 insertions(+)
create mode 100644 include/hw/uefi/var-service-api.h
create mode 100644 include/hw/uefi/var-service-edk2.h
create mode 100644 include/hw/uefi/var-service.h
create mode 100644 hw/uefi/var-service-auth.c
create mode 100644 hw/uefi/var-service-core.c
create mode 100644 hw/uefi/var-service-guid.c
create mode 100644 hw/uefi/var-service-isa.c
create mode 100644 hw/uefi/var-service-json.c
create mode 100644 hw/uefi/var-service-policy.c
create mode 100644 hw/uefi/var-service-sysbus.c
create mode 100644 hw/uefi/var-service-vars.c
create mode 100644 docs/devel/uefi-vars.rst
create mode 100644 hw/uefi/Kconfig
create mode 100644 hw/uefi/TODO.md
create mode 100644 hw/uefi/meson.build
create mode 100644 hw/uefi/trace-events
create mode 100644 qapi/uefi.json
[PATCH 00/16] hw/uefi: add uefi variable service
Posted by Gerd Hoffmann 1 year ago
This patch adds a virtual device to qemu which the uefi firmware can use
to store variables.  This moves the UEFI variable management from
privileged guest code (managing vars in pflash) to the host.  Main
advantage is that the need to have privilege separation in the guest
goes away.

On x86 privileged guest code runs in SMM.  It's supported by kvm, but
not liked much by various stakeholders in cloud space due to the
complexity SMM emulation brings.

On arm privileged guest code runs in el3 (aka secure world).  This is
not supported by kvm, which is unlikely to change anytime soon given
that even el2 support (nested virt) is being worked on for years and is
not yet in mainline.

The design idea is to reuse the request serialization protocol edk2 uses
for communication between SMM and non-SMM code, so large chunks of the
edk2 variable driver stack can be used unmodified.  Only the driver
which traps into SMM mode must be replaced by a driver which talks to
qemu instead.

A edk2 test branch can be found here (build with "-D QEMU_VARS=TRUE").
https://github.com/kraxel/edk2/commits/devel/secure-boot-external-vars

The uefi-vars device must re-implement the privileged edk2 protocols
(i.e. the code running in SMM mode).  The implementation is not complete
yet, specifically updating authenticated variables is not implemented.
These variables are simply read-only for now.

But there is enough functionality working that it is possible to run
guests, including guests in secure boot mode, so I'm sending this out
for feedback (before tackling the remaining 20% which evidently will
need 80% of the time ;)

Because the guest can not write to authenticated variables (yet) it can
not enroll secure boot keys itself, this must be done on the host.  The
virt-firmware tools (https://gitlab.com/kraxel/virt-firmware) can be
used for that:

virt-fw-vars --enroll-redhat --secure-boot --output-json uefivars.json

enjoy & take care,
  Gerd

Gerd Hoffmann (16):
  hw/uefi: add include/hw/uefi/var-service-api.h
  hw/uefi: add include/hw/uefi/var-service-edk2.h
  hw/uefi: add include/hw/uefi/var-service.h
  hw/uefi: add var-service-guid.c
  hw/uefi: add var-service-core.c
  hw/uefi: add var-service-vars.c
  hw/uefi: add var-service-auth.c
  hw/uefi: add var-service-policy.c
  hw/uefi: add support for storing persistent variables on disk
  hw/uefi: add trace-events
  hw/uefi: add to Kconfig
  hw/uefi: add to meson
  hw/uefi: add uefi-vars-sysbus device
  hw/uefi: add uefi-vars-isa device
  hw/arm: add uefi variable support to virt machine type
  docs: add uefi variable service documentation and TODO list.

 include/hw/arm/virt.h              |   2 +
 include/hw/uefi/var-service-api.h  |  40 ++
 include/hw/uefi/var-service-edk2.h | 184 +++++++++
 include/hw/uefi/var-service.h      | 119 ++++++
 hw/arm/virt.c                      |  41 ++
 hw/uefi/var-service-auth.c         |  91 +++++
 hw/uefi/var-service-core.c         | 350 +++++++++++++++++
 hw/uefi/var-service-guid.c         |  61 +++
 hw/uefi/var-service-isa.c          |  88 +++++
 hw/uefi/var-service-json.c         | 194 ++++++++++
 hw/uefi/var-service-policy.c       | 390 +++++++++++++++++++
 hw/uefi/var-service-sysbus.c       |  87 +++++
 hw/uefi/var-service-vars.c         | 602 +++++++++++++++++++++++++++++
 docs/devel/index-internals.rst     |   1 +
 docs/devel/uefi-vars.rst           |  66 ++++
 hw/Kconfig                         |   1 +
 hw/meson.build                     |   1 +
 hw/uefi/Kconfig                    |   9 +
 hw/uefi/TODO.md                    |  17 +
 hw/uefi/meson.build                |  18 +
 hw/uefi/trace-events               |  16 +
 meson.build                        |   1 +
 qapi/meson.build                   |   1 +
 qapi/qapi-schema.json              |   1 +
 qapi/uefi.json                     |  40 ++
 25 files changed, 2421 insertions(+)
 create mode 100644 include/hw/uefi/var-service-api.h
 create mode 100644 include/hw/uefi/var-service-edk2.h
 create mode 100644 include/hw/uefi/var-service.h
 create mode 100644 hw/uefi/var-service-auth.c
 create mode 100644 hw/uefi/var-service-core.c
 create mode 100644 hw/uefi/var-service-guid.c
 create mode 100644 hw/uefi/var-service-isa.c
 create mode 100644 hw/uefi/var-service-json.c
 create mode 100644 hw/uefi/var-service-policy.c
 create mode 100644 hw/uefi/var-service-sysbus.c
 create mode 100644 hw/uefi/var-service-vars.c
 create mode 100644 docs/devel/uefi-vars.rst
 create mode 100644 hw/uefi/Kconfig
 create mode 100644 hw/uefi/TODO.md
 create mode 100644 hw/uefi/meson.build
 create mode 100644 hw/uefi/trace-events
 create mode 100644 qapi/uefi.json

-- 
2.41.0
Re: [PATCH 00/16] hw/uefi: add uefi variable service
Posted by Alexander Graf 1 year ago
Hey Gerd!

On 15.11.23 16:12, Gerd Hoffmann wrote:
> This patch adds a virtual device to qemu which the uefi firmware can use
> to store variables.  This moves the UEFI variable management from
> privileged guest code (managing vars in pflash) to the host.  Main
> advantage is that the need to have privilege separation in the guest
> goes away.
>
> On x86 privileged guest code runs in SMM.  It's supported by kvm, but
> not liked much by various stakeholders in cloud space due to the
> complexity SMM emulation brings.
>
> On arm privileged guest code runs in el3 (aka secure world).  This is
> not supported by kvm, which is unlikely to change anytime soon given
> that even el2 support (nested virt) is being worked on for years and is
> not yet in mainline.
>
> The design idea is to reuse the request serialization protocol edk2 uses
> for communication between SMM and non-SMM code, so large chunks of the
> edk2 variable driver stack can be used unmodified.  Only the driver
> which traps into SMM mode must be replaced by a driver which talks to
> qemu instead.


I'm not sure I like the split :). If we cut things off at the SMM 
communication layer, we still have a lot of code inside the Runtime 
Services (RTS) code that is edk2 specific which means we're tying 
ourselves tightly to the edk2 data format. It also means we can not 
easily expose UEFI variables that QEMU owns, which can come in very 
handy when implementing MOR - another feature that depends on SMM today.

In EC2, we are simply serializing all variable RTS calls to the 
hypervisor, similar to the Xen implementation 
(https://www.youtube.com/watch?v=jiR8khaECEk).

The edk2 side code we have built is here: 
https://github.com/aws/uefi/tree/main/edk2-stable202211 (see anything 
with VarStore in the name).

For the vmm side, we currently have an AWS-internal C++ implementation 
that I can convert into QEMU code and send as patch if there is real 
interest. Given that we deal with untrusted input, I would strongly 
prefer if we could move it to a Rust implementation instead though. We 
started a Rust reimplementation of it that interface that can build as a 
library with C bindings which QEMU could then link against:

   https://github.com/Mimoja/rs-uefi-varstore/tree/for_main

The code never went beyond the initial stages, but if we're pulling the 
variable store to QEMU, this would be the best path forward IMHO.


If instead, we just want something we can quickly integrate while eating 
up the additional security risk, I think we should just reuse the Xen 
implementation.


Alex





Amazon Development Center Germany GmbH
Krausenstr. 38
10117 Berlin
Geschaeftsfuehrung: Christian Schlaeger, Jonathan Weiss
Eingetragen am Amtsgericht Charlottenburg unter HRB 149173 B
Sitz: Berlin
Ust-ID: DE 289 237 879


Re: [PATCH 00/16] hw/uefi: add uefi variable service
Posted by Gerd Hoffmann 1 year ago
On Mon, Nov 20, 2023 at 12:53:45PM +0100, Alexander Graf wrote:
> Hey Gerd!
> 
> On 15.11.23 16:12, Gerd Hoffmann wrote:
> > This patch adds a virtual device to qemu which the uefi firmware can use
> > to store variables.  This moves the UEFI variable management from
> > privileged guest code (managing vars in pflash) to the host.  Main
> > advantage is that the need to have privilege separation in the guest
> > goes away.
> > 
> > On x86 privileged guest code runs in SMM.  It's supported by kvm, but
> > not liked much by various stakeholders in cloud space due to the
> > complexity SMM emulation brings.
> > 
> > On arm privileged guest code runs in el3 (aka secure world).  This is
> > not supported by kvm, which is unlikely to change anytime soon given
> > that even el2 support (nested virt) is being worked on for years and is
> > not yet in mainline.
> > 
> > The design idea is to reuse the request serialization protocol edk2 uses
> > for communication between SMM and non-SMM code, so large chunks of the
> > edk2 variable driver stack can be used unmodified.  Only the driver
> > which traps into SMM mode must be replaced by a driver which talks to
> > qemu instead.
> 
> 
> I'm not sure I like the split :). If we cut things off at the SMM
> communication layer, we still have a lot of code inside the Runtime Services
> (RTS) code that is edk2 specific which means we're tying ourselves tightly
> to the edk2 data format.

Which data format?

Request serialization format?  Yes.  I can't see what is wrong with
that.  We need one anyway, and I don't see why inventing a new one is
any better than the one we already have in edk2.

Variable storage format?  Nope, that is not the case.  The variable
driver supports a cache, which I think is a read-only mapping of the
variable store, so using that might imply we have to use edk2 storage
format.  Didn't check in detail through.  The cache is optional, can be
disabled at compile time using PcdEnableVariableRuntimeCache=FALSE, and
I intentionally do not use the cache feature, exactly to avoid unwanted
constrains to the host side implementation.

> It also means we can not easily expose UEFI
> variables that QEMU owns,

Qemu owning variables should be no problem.  Adding monitor commands to
read/write UEFI variables should be possible too.

> which can come in very handy when implementing MOR
> - another feature that depends on SMM today.

Have a pointer for me?  Google finds me
https://learn.microsoft.com/en-us/windows-hardware/drivers/bringup/device-guard-requirements,
which describes the variable behavior (which I think should be no
problem to implement), but doesn't say a word about what exactly gets
locked when enabled ...

> In EC2, we are simply serializing all variable RTS calls to the hypervisor,

The edk2 code effectively does the same (with PcdEnableVariableRuntimeCache=FALSE).

> similar to the Xen implementation
> (https://www.youtube.com/watch?v=jiR8khaECEk).

Is the Xen implementation upstream?  Can't see a xen variable driver in
OvmfPkg.  The video is from 2019.  What is the state of this?

> The edk2 side code we have built is here:
> https://github.com/aws/uefi/tree/main/edk2-stable202211 (see anything with
> VarStore in the name).

Ok, so it's just the variables.  The edk2 variant also sends variable
policy requests (see Edk2VariablePolicyProtocol,
https://github.com/tianocore/edk2/blob/master/MdeModulePkg/Library/VariablePolicyLib/ReadMe.md).
And it can easily be extended should the need arise in the future (all
requests are tagged with a protocol/event guid).

> Given that we deal with untrusted input, I would strongly prefer if we could
> move it to a Rust implementation instead though.

Valid point.

I've started in C because I have next no to experience with rust (yet),
so getting a test-able / demo-able implementation done was much easier
for me.  Also I think we don't have any rust infrastructure in qemu
(yet?).  Being able to use the qapi / qobject support to read/write the
variable store in json format is nice too.

But I'm open to discuss other options.

> We started a Rust
> reimplementation of it that interface that can build as a library with C
> bindings which QEMU could then link against:
> 
>   https://github.com/Mimoja/rs-uefi-varstore/tree/for_main
> 
> The code never went beyond the initial stages,

Hmm.  Why not?

> but if we're pulling the variable store to QEMU, this would be the
> best path forward IMHO.

Ok, so you are trying to sell me a prototype as solution?
/me looks a bit skeptical ...

take care,
  Gerd
Re: [PATCH 00/16] hw/uefi: add uefi variable service
Posted by Laszlo Ersek 1 year ago
On 11/20/23 17:50, Gerd Hoffmann wrote:
> On Mon, Nov 20, 2023 at 12:53:45PM +0100, Alexander Graf wrote:
>> Hey Gerd!
>>
>> On 15.11.23 16:12, Gerd Hoffmann wrote:
>>> This patch adds a virtual device to qemu which the uefi firmware can use
>>> to store variables.  This moves the UEFI variable management from
>>> privileged guest code (managing vars in pflash) to the host.  Main
>>> advantage is that the need to have privilege separation in the guest
>>> goes away.
>>>
>>> On x86 privileged guest code runs in SMM.  It's supported by kvm, but
>>> not liked much by various stakeholders in cloud space due to the
>>> complexity SMM emulation brings.
>>>
>>> On arm privileged guest code runs in el3 (aka secure world).  This is
>>> not supported by kvm, which is unlikely to change anytime soon given
>>> that even el2 support (nested virt) is being worked on for years and is
>>> not yet in mainline.
>>>
>>> The design idea is to reuse the request serialization protocol edk2 uses
>>> for communication between SMM and non-SMM code, so large chunks of the
>>> edk2 variable driver stack can be used unmodified.  Only the driver
>>> which traps into SMM mode must be replaced by a driver which talks to
>>> qemu instead.
>>
>>
>> I'm not sure I like the split :). If we cut things off at the SMM
>> communication layer, we still have a lot of code inside the Runtime Services
>> (RTS) code that is edk2 specific which means we're tying ourselves tightly
>> to the edk2 data format.
> 
> Which data format?
> 
> Request serialization format?  Yes.  I can't see what is wrong with
> that.

... I can't even see what's wrong with *that*. Realistically /
practically, I think only edk2 has been considered as guest UEFI
firmware for QEMU/KVM virtual machines, as far as upstream projects go.
It's certainly edk2 that's bundled with QEMU.

My understanding is that firmware is just considered a part of the
virtualization platform, so teaching edk2 specifics to QEMU doesn't seem
wrong. (As long as we have the personpower to maintain interoperability.)

> We need one anyway, and I don't see why inventing a new one is
> any better than the one we already have in edk2.
> 
> Variable storage format?  Nope, that is not the case.  The variable
> driver supports a cache, which I think is a read-only mapping of the
> variable store, so using that might imply we have to use edk2 storage
> format.  Didn't check in detail through.  The cache is optional, can be
> disabled at compile time using PcdEnableVariableRuntimeCache=FALSE, and
> I intentionally do not use the cache feature, exactly to avoid unwanted
> constrains to the host side implementation.
> 
>> It also means we can not easily expose UEFI
>> variables that QEMU owns,
> 
> Qemu owning variables should be no problem.  Adding monitor commands to
> read/write UEFI variables should be possible too.

This patch set is actually an improvement towards QEMU-owned variables.
Right now, all variables are internal to the guest; QEMU only has a
pflash-level view.

> 
>> which can come in very handy when implementing MOR
>> - another feature that depends on SMM today.
> 
> Have a pointer for me?  Google finds me
> https://learn.microsoft.com/en-us/windows-hardware/drivers/bringup/device-guard-requirements,
> which describes the variable behavior (which I think should be no
> problem to implement), but doesn't say a word about what exactly gets
> locked when enabled ...

See:

  TCG PC Client Platform
  Reset Attack Mitigation Specification

My copy is

  Family “2.0”
  Version 1.10 Revision 17
  January 21, 2019
  Published

You should find it somewhere in the download area of
<https://trustedcomputinggroup.org>.

E.g....
<https://www.trustedcomputinggroup.org/wp-content/uploads/Platform-Reset-Attack-Mitigation-Specification.pdf>


In the past we've had a bunch of discussions / patches around this. Some
examples:

- [edk2] multiple levels of support for MOR / MORLock

http://mid.mail-archive.com/039cf353-80fb-9f20-6ad2-f52517ab4de7@redhat.com

- https://bugzilla.tianocore.org/show_bug.cgi?id=727

(see edk2 commit range listed there, too)

- commit 704b71d7e11f115a3b5b03471d6420a7a70f1585

- commit d20ae95a13e851d56c6618108b18c93526505ca2

- https://bugzilla.redhat.com/show_bug.cgi?id=1854212

- https://bugzilla.redhat.com/show_bug.cgi?id=1498159


> 
>> In EC2, we are simply serializing all variable RTS calls to the hypervisor,
> 
> The edk2 code effectively does the same (with PcdEnableVariableRuntimeCache=FALSE).
> 
>> similar to the Xen implementation
>> (https://www.youtube.com/watch?v=jiR8khaECEk).
> 
> Is the Xen implementation upstream?  Can't see a xen variable driver in
> OvmfPkg.  The video is from 2019.  What is the state of this?

Not sure about the current state, but when that presentation came out,
we discussed it briefly internally. I don't have time to review that old
discussion now for the sake of potentially publishing it inside this
discussion, but for interested Red Hatters, I can provide a pointer:

  [virt-devel] Securing Secure Boot on Xen | FOSDEM'19
  Date: Fri, 8 Feb 2019 20:46:46 +0100
  msgid: <37382312-986c-4ce4-1ba3-942697738d65@redhat.com>

> 
>> The edk2 side code we have built is here:
>> https://github.com/aws/uefi/tree/main/edk2-stable202211 (see anything with
>> VarStore in the name).

Well... why was this never upstreamed to edk2? (Side question, of course.)

> 
> Ok, so it's just the variables.  The edk2 variant also sends variable
> policy requests (see Edk2VariablePolicyProtocol,
> https://github.com/tianocore/edk2/blob/master/MdeModulePkg/Library/VariablePolicyLib/ReadMe.md).
> And it can easily be extended should the need arise in the future (all
> requests are tagged with a protocol/event guid).
> 
>> Given that we deal with untrusted input, I would strongly prefer if we could
>> move it to a Rust implementation instead though.
> 
> Valid point.

Agree that the point is valid.

(And this was one of my concerns, if not my main concern, in the above
internal discussion, about Xen varstored.)

Especially due to the heavy crypto that the final version is supposed to
have.

Even during the present patch review, while going through only the
headers thus far, I've already said at least twice that we're going to
have to be super careful about integer overflows and buffer overflows.
Any such problem is no longer a guest<->guest privilege boundary breach
but a guest<->host one.

Not sure if the suggested remedy ("write it in Rust") is practical.

> 
> I've started in C because I have next no to experience with rust (yet),
> so getting a test-able / demo-able implementation done was much easier
> for me.  Also I think we don't have any rust infrastructure in qemu
> (yet?).  Being able to use the qapi / qobject support to read/write the
> variable store in json format is nice too.
> 
> But I'm open to discuss other options.

A selfish aspect: given that I've been reviewing this set, should I
consider it a proof of concept / prototype, or something we might want
to build upon, i.e., should I assume we'd put these foundations into
production at some point? I've been reviewing the series with the latter
in mind, but if that's not correct, I should probably adjust my pedantry
knob.

> 
>> We started a Rust
>> reimplementation of it that interface that can build as a library with C
>> bindings which QEMU could then link against:
>>
>>   https://github.com/Mimoja/rs-uefi-varstore/tree/for_main
>>
>> The code never went beyond the initial stages,
> 
> Hmm.  Why not?

And I'm a bit annoyed that you had to write ~2500 lines of QEMU code
(not counting edk2) for qemu-devel to learn about these initiatives. :/

> 
>> but if we're pulling the variable store to QEMU, this would be the
>> best path forward IMHO.
> 
> Ok, so you are trying to sell me a prototype as solution?
> /me looks a bit skeptical ...

at least with virtiofsd, we had gone with a C impl first, and only then
with a Rust impl...

Laszlo


Re: [PATCH 00/16] hw/uefi: add uefi variable service
Posted by Gerd Hoffmann 1 year ago
  Hi,

> Even during the present patch review, while going through only the
> headers thus far, I've already said at least twice that we're going to
> have to be super careful about integer overflows and buffer overflows.
> Any such problem is no longer a guest<->guest privilege boundary breach
> but a guest<->host one.
> 
> Not sure if the suggested remedy ("write it in Rust") is practical.

It should prevent certain classes of bugs such as buffer overflows.  Not
sure how much compromises you have to make (i.e. 'unsafe' code sections)
for a C library interface, so you can link the lib into qemu.  And of
course it wouldn't automatically stop logic errors.

> > But I'm open to discuss other options.
> 
> A selfish aspect: given that I've been reviewing this set, should I
> consider it a proof of concept / prototype, or something we might want
> to build upon, i.e., should I assume we'd put these foundations into
> production at some point? I've been reviewing the series with the latter
> in mind, but if that's not correct, I should probably adjust my pedantry
> knob.

In case we continue the C route I certainly expect that this patch set
will turn into something production-ready, and I've tried to code things
up accordingly.  Copy buffers so the guest can't modify them while qemu
processes them, carefully check length fields, ...

> at least with virtiofsd, we had gone with a C impl first, and only then
> with a Rust impl...

And virtiofsd was easier because it is a completely separate process,
not something you want link into qemu ...

take care,
  Gerd
Re: [PATCH 00/16] hw/uefi: add uefi variable service
Posted by Daniel P. Berrangé 1 year ago
On Tue, Nov 21, 2023 at 04:58:44PM +0100, Laszlo Ersek wrote:
> On 11/20/23 17:50, Gerd Hoffmann wrote:
> > On Mon, Nov 20, 2023 at 12:53:45PM +0100, Alexander Graf wrote:
> >> Hey Gerd!
> >>
> >> On 15.11.23 16:12, Gerd Hoffmann wrote:
> >>> This patch adds a virtual device to qemu which the uefi firmware can use
> >>> to store variables.  This moves the UEFI variable management from
> >>> privileged guest code (managing vars in pflash) to the host.  Main
> >>> advantage is that the need to have privilege separation in the guest
> >>> goes away.
> >>>
> >>> On x86 privileged guest code runs in SMM.  It's supported by kvm, but
> >>> not liked much by various stakeholders in cloud space due to the
> >>> complexity SMM emulation brings.
> >>>
> >>> On arm privileged guest code runs in el3 (aka secure world).  This is
> >>> not supported by kvm, which is unlikely to change anytime soon given
> >>> that even el2 support (nested virt) is being worked on for years and is
> >>> not yet in mainline.
> >>>
> >>> The design idea is to reuse the request serialization protocol edk2 uses
> >>> for communication between SMM and non-SMM code, so large chunks of the
> >>> edk2 variable driver stack can be used unmodified.  Only the driver
> >>> which traps into SMM mode must be replaced by a driver which talks to
> >>> qemu instead.
> >>
> >>
> >> I'm not sure I like the split :). If we cut things off at the SMM
> >> communication layer, we still have a lot of code inside the Runtime Services
> >> (RTS) code that is edk2 specific which means we're tying ourselves tightly
> >> to the edk2 data format.
> > 
> > Which data format?
> > 
> > Request serialization format?  Yes.  I can't see what is wrong with
> > that.
> 
> ... I can't even see what's wrong with *that*. Realistically /
> practically, I think only edk2 has been considered as guest UEFI
> firmware for QEMU/KVM virtual machines, as far as upstream projects go.
> It's certainly edk2 that's bundled with QEMU.
> 
> My understanding is that firmware is just considered a part of the
> virtualization platform, so teaching edk2 specifics to QEMU doesn't seem
> wrong. (As long as we have the personpower to maintain interoperability.)
> 
> > We need one anyway, and I don't see why inventing a new one is
> > any better than the one we already have in edk2.
> > 
> > Variable storage format?  Nope, that is not the case.  The variable
> > driver supports a cache, which I think is a read-only mapping of the
> > variable store, so using that might imply we have to use edk2 storage
> > format.  Didn't check in detail through.  The cache is optional, can be
> > disabled at compile time using PcdEnableVariableRuntimeCache=FALSE, and
> > I intentionally do not use the cache feature, exactly to avoid unwanted
> > constrains to the host side implementation.
> > 
> >> It also means we can not easily expose UEFI
> >> variables that QEMU owns,
> > 
> > Qemu owning variables should be no problem.  Adding monitor commands to
> > read/write UEFI variables should be possible too.
> 
> This patch set is actually an improvement towards QEMU-owned variables.
> Right now, all variables are internal to the guest; QEMU only has a
> pflash-level view.

To throw confidental computing into the mix....

Right now for SEV-SNP/TDX, the EDK2 builds are stateless so that
variables are thrown away at poweroff.

Long term though there's interest in having the ability to (optionally)
offer persistence of variables to confidential computing too.

The key issue is that the host QEMU is not trusted so it would not be
viable to let QEMU receive the variables in plain text.

One option I've illustrated before is that have SVSM (or equiv)
expose an encrypted storage service to EDK2. Given the proposed EDK2
side protocol/modifications for variable storage, I wonder if it is
viable for SVSM (or equiv) to replace QEMU in providing the backend
storage impl ?  IOW, host QEMU would expose a pflash to the guest,
to which SVSM would apply full disk encryption, and then store the
EFI variables in it

With 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 :|
Re: [PATCH 00/16] hw/uefi: add uefi variable service
Posted by Gerd Hoffmann 1 year ago
  Hi,

> One option I've illustrated before is that have SVSM (or equiv)
> expose an encrypted storage service to EDK2. Given the proposed EDK2
> side protocol/modifications for variable storage, I wonder if it is
> viable for SVSM (or equiv) to replace QEMU in providing the backend
> storage impl ?  IOW, host QEMU would expose a pflash to the guest,
> to which SVSM would apply full disk encryption, and then store the
> EFI variables in it

Yes.  IIRC (it's been a while I've looked at the spec) the SVSM can
request that access to specific pages trap, so it could use that to 
emulate the mmio/sysbus variant of the device.  Not sure if that could
work for io/isa too.  Another option would be to add a third interface
variant which uses SVSM service calls.

And one advantage of a rust implementation would be that integrating
with coconut-svsm (which is written in rust too) might be easier.  On
the other hand the SVSM is a very different environment, the rust stdlib
is not available for example, and the way persistence is implemented
will probably look very different too.  Another difference is crypto
support, qemu uses nettle / gnutls whereas svsm will probably use
openssl.  So not sure how big the opportunity to share the code between
qemu and svsm on the backend side actually is.

take care,
  Gerd