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). > > 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 - QEMU is free to move the device or register block around, from release to release, without disturbing migration. Thanks! Laszlo