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.as...
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).
So here's what should be done:
- QEMU should implement the TPM device model, using TIS+Cancel (method 6) or CRB (method 7). These are collectively called "dTPM".
- QEMU should continue generating a TPM2 ACPI table, for describing one of the above access methods to the OS, as appropriate for the actual device model.
- OVMF should include the following drivers from edk2, without changes: - Tcg2Pei/Tcg2Pei.inf - Tcg2Dxe/Tcg2Dxe.inf
- OVMF should include the following drivers from edk2, - either verbatim (if they work out like that), - or with small customizations (if the drivers themselves offer sufficiently flexible knobs), - or else as modules duplicated / rewritten under OvmfPkg, - or they might even turn out unnecessary:
- Tcg2Config/Tcg2ConfigPei.inf - Tcg2Config/Tcg2ConfigDxe.inf
QEMU would also be generating the ACPI for this UEFI I suppose. So now who needs to adapt to whom? And can EDK2 be adapted to do something different or should it remain as-is and SeaBIOS would have to work similarly as EDK2 does? I don't know much about SMM / SMIs and how it work unfortunately and whether it can work from the OS when ACPI raises an SMI. Any opinions ?
To be honest, I don't understand SeaBIOS's role here (beyond executing the linker/loader script from QEMU). To my knowledge, SeaBIOS does not intend to be a TPM client. As far as I understand, only - UEFI applications, - and then the OS (UEFI-based, or traditional BIOS-based) are expected to function as TPM clients.
Under the approach described near the top,
- UEFI clients (such as UEFI boot loaders) are satisfied by the inclusion of the "Tcg2Dxe/Tcg2Dxe.inf" driver in OVMF -- because said driver produces the EFI_TCG2_PROTOCOL;
- and the OS (regardless of UEFI or traditional BIOS) is satisfied by finding the TPM hardware description in the TPM2 table of QEMU, and then by talking to the TPM device model (implemented in QEMU) with its own native driver.
So... I'm missing the point of the thread starter message -- "Saving a few bytes across a reboot". Save them for what purpose?
BTW, from the "TCG PC Client Platform TPM Profile (PTP) Specification", it seems like the FIFO (TIS) interface is hard-coded *in the spec* at FED4_0000h – FED4_4FFFh. So we don't even have to make that dynamic.
Regarding CRB (as an alternative to TIS+Cancel), I'm trying to wrap my brain around the exact resources that the CRB interface requries. Marc-André, can you summarize those?
Thanks, Laszlo