On 01/10/2018 08:22 AM, Laszlo Ersek wrote:
Stefan,
On 01/09/18 20:02, Stefan Berger wrote:
Another twist is that Intel's EDK2 also implements this but the data
structure layout is different and they use SMM + SMIs etc.
https://github.com/tianocore/edk2/blob/master/SecurityPkg/Tcg/Tcg2Smm/Tpm.asl#L81
As I described in my investigation linked from
<https://bugzilla.tianocore.org/show_bug.cgi?id=594#c5>, we should not
include the Tcg2Smm driver in OVMF, for TPM enablement -- at least for
the short & mid terms.
What does the Tcg2Smm driver do? In section (2f), I described that the
driver installs two tables, "TPM2" and an "SSDT".
- The TPM2 table from this driver is unneeded, since QEMU generates its
own TPM2 table, which describes the TPM device's access method --
TIS+Cancel (method 6).
- The SSDT from the driver is again unneeded. It provides (via the _DSM
method) an ACPI-level API that the OS can use, for talking to the TPM
device. An implementation detail of this ACPI method is that it raises
an SMI, for entering the firmware at an elevated privilege level (= in
SMM). Then, the actual TPM hardware manipulation, or even the TPM
*software emulation*, is performed by the firmware, in SMM.
This approach is totally ill-suited for the QEMU virtualization stack.
For starters, none of the firmware code exist -- as open source anyway
-- that would actually handle such ACPI->SMM requests. Second, I'm sure
we don't want to debug TPM software emulation running in SMM guest
firmware, rather than an actual QEMU device model.
Once we have a real device model, accessed via IO ports and/or MMIO
locations, perhaps in combination with request/response buffers
allocated in guest RAM, the SMI/SMM implementation detail falls away
completely. Our TPM emulation would attain its "privileged / protected"
status simply by existing in the hypervisor (QEMU).
Regarding the SMI/SMM: I think it will be needed for the TPM Physical
Presence interface where ACPI gets a code from the user that it sends to
the firmware and the firmware acts upon next reboot. SMM stores this
code in a UEFI variable (EDK2) to protect it from modules executed by
UEFI. I was trying to use a memory area (PPI memory device) for storing
this code but it would not give the same protection for UEFI compared to
the variable. I suppose the reason is that UEFI can execute (untrusted)
code that could manipulate this memory area and cause unwanted changes
to the TPM upon reboot by for example writing a code for clearing the
TPM. How 'safe' would the BIOS be or any path from the BIOS until the OS
kernel takes over? Can untrusted code be executed by something like a
BIOS module (vgabios.bin and the like) and mess with that memory area? A
grub module?
One other complication is the memory area that EDK2 requires for
exchanging of data ('that code' for example) between ACPI and SMM. It's
hard coded to 0xFFFF 0000. However, with SeaBIOS I cannot use this
memory and there's this comment here: 'src/fw/shadow.c:// On the
emulators, the bios at 0xf0000 is also at 0xffff0000'.
So the point is SMM is needed for UEFI. QEMU would need to provide the
ACPI code for it, which is basically a translation of the ACPI from EDK2
so that this could work. To support SeaBIOS as well, we would have to be
able to distinguish a BIOS from the UEFI on the QEMU level so that we
could produce different ACPI (no SMI and different OperationRegion than
0xFFFF 0000 for SeaBIOS), *if* on a system with a BIOS the memory area
can be considered to be safe (like that EDK2 variable). Otherwise I am
afraid it's better to not support it in SeaBIOS and provide all
necessary early TPM 2 operations via user interaction with the menu only.
Comments ?
Stefan
_______________________________________________
SeaBIOS mailing list
SeaBIOS@seabios.org
https://mail.coreboot.org/mailman/listinfo/seabios