qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Qemu-devel] [PATCH v2 4/4] acpi: build TPM Physical Presence interf


From: Stefan Berger
Subject: Re: [Qemu-devel] [PATCH v2 4/4] acpi: build TPM Physical Presence interface
Date: Tue, 13 Feb 2018 16:32:32 -0500
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:45.0) Gecko/20100101 Thunderbird/45.4.0

On 02/13/2018 04:04 PM, Laszlo Ersek wrote:
On 02/13/18 21:29, Stefan Berger wrote:
On 02/13/2018 02:59 PM, Laszlo Ersek wrote:
On 02/13/18 20:37, Kevin O'Connor wrote:
On Tue, Feb 13, 2018 at 05:16:49PM +0100, Laszlo Ersek wrote:
On 02/12/18 21:49, Stefan Berger wrote:
On 02/12/2018 03:46 PM, Kevin O'Connor wrote:
I'm not sure I fully understand the goals of the PPI interface.
Here's what I understand so far:

The TPM specs define some actions that are considered privileged.  An
example of this would be disabling the TPM itself.  In order to
prevent an attacker from performing these actions without
authorization, the TPM specs define a mechanism to assert "physical
presence" before the privileged action can be done.  They do this by
having the firmware present a menu during early boot that permits
these privileged operations, and then the firmware locks the TPM chip
so the actions can no longer be done by any software that runs after
the firmware.  Thus "physical presence" is asserted by demonstrating
one has console access to the machine during early boot.

The PPI spec implements a work around for this - presumably some
found
the enforcement mechanism too onerous.  It allows the OS to provide a
request code to the firmware, and on the next boot the firmware will
take the requested action before it locks the chip.  Thus allowing
the
OS to indirectly perform the privileged action even after the chip
has
been locked.  Thus, the PPI system seems to be an "elaborate hack" to
allow users to circumvent the physical presence mechanism (if they
choose to).
Correct.
Here's what I understand the proposed implementation involves:

1 - in addition to emulating the TPM device itself, QEMU will also
       introduce a virtual memory device with 0x400 bytes.
Correct.
2 - on first boot the firmware (seabios and uefi) will populate the
       memory region created in step 1.  In particular it will fill an
       array with the list of request codes it supports.  (Each
request
       is an 8bit value, the array has 256 entries.)
Correct. Each firmware would fill out the 256 byte array depending on
what it supports. The 8 bit values are basically flags and so on.
3 - QEMU will produce AML code implementing the standard PPI ACPI
       interface.  This AML code will take the request, find the table
       produced in step 1, compare it to the list of accepted requests
       produced in step 2, and then place the 8bit request in another
       qemu virtual memory device (at 0xFFFF0000 or 0xFED45000).
Correct.

Now EDK2 wants to store the code in a UEFI variable in NVRAM. We
therefore would need to trigger an SMI. In SeaBIOS we wouldn't have to
do this.

4 - the OS will signal a reboot, qemu will do its normal reboot
logic,
       and the firmware will be run again.

5 - the firmware will extract the code written in stage 3, and if the
       tpm device has been configured to accept PPI codes from the
OS, it
       will invoke the requested action.
SeaBIOS would look into memory to find the code. EDK2 will read the
code
from a UEFI variable.

Did I understand the above correctly?
I think so. With the fine differences between SeaBIOS and EDK2
pointed out.
Here's what I suggest:

Please everyone continue working on this, according to Kevin's &
Stefan's description, but focus on QEMU and SeaBIOS *only*. Ignore edk2
for now.
If this were targetted at SeaBIOS, I'd look for a simpler
QEMU/firmware interface.  Something like:

A - QEMU produces AML code implementing the standard PPI ACPI
      interface that generates a request code and stores it in the
      device memory of an existing device (eg, writable fw_cfg or an
      extension field in the existing emulated TPM device).
ACPI code writing into fw_cfg sounds difficult.
I initially had PPI SeaBIOS code write into the TPM TIS device's memory
into some custom addresses. I'd consider this a hack. Now we have that
virtual memory device with those 0x400 bytes...

In these 0x400 bytes we have 256 bytes that are used for configuration
flags describing the supported opcode as you previously described. This
array allows us to decouple the firmware implementation from the ACPI
code and we need not hard code what is supported in the firmware inside
the ACPI code (which would be difficult to do anyway since in QEMU we
would not what firmware will be started and what PPI opcodes are
support) and the ppi sysfs entries in Linux for example show exactly
those PPI opcodes that are supported. The firmware needs to set those
flags and the firmware knows what it supports.

I hope we can settle that this device is the right path.

B - after a reboot the firmware extracts the PPI request code
      (produced in step A) and performs the requested action (if the TPM
      is configured to accept OS generated codes).

That is, skip steps 1 and 2 from the original proposal.
I think A/B can work fine, as long as
- the firmware can somehow dynamically recognize the device / "register
    block" that the request codes have to be pulled from, and
I experimented with what Igor had suggested with the fw_cfg file
callback and so on.

- QEMU is free to move the device or register block around, from release
    to release, without disturbing migration.
I think we should basically limit the firmware to writing two addresses
into this fw_cfg file:
- SeaBIOS: write back the same address that QEMU suggested in the file
(currently 0xfed4 5000)
- EDK2: write back 0xffff 0000
Given that I intend to rip the SecurityPkg ASL code out of OVMF's
solution for this, I don't think that the address 0xffff_0000 has any
relevance for OVMF. If the QEMU x86 MMIO space generally has a suitable
gap at 0xfed4_5000 (and I do think it has, even considering pflash &
LAPIC), then just put the register block there.

As long as Igor agrees. :)

Another question just occurred to me. If the guest OS queues some PPI
operations, and then the VM is powered down fully (instead of a reboot),
then we're at liberty to forget the queued PPI ops, right?

I would say that is implementation-dependent. UEFI wouldn't forget due to these UEFI Variables in NVRAM...

    Stefan


Thanks
Laszlo

No other address would be accepted by QEMU since presumably QEMU knows
where otherwise address collisions can occur.





reply via email to

[Prev in Thread] Current Thread [Next in Thread]