Re: [Qemu-devel] [PATCH v2 4/4] acpi: build TPM Physical Presence interface
On 02/14/2018 01:39 PM, Kevin O'Connor wrote: On Tue, Feb 13, 2018 at 03:29:20PM -0500, Stefan Berger wrote: [...] 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. It seems that the primary purpose of the 0x400 virtual device is to pass information from firmware to QEMU (specifically to pass the list of supported PPI opcodes to the QEMU generated AML code). Passing information between firmware and QEMU is not new territory, and fw_cfg was specifically built to do this. I'd prefer to use fw_cfg if we need to pass information between firmware and QEMU. That said, I don't see why this list is needed - why not just implement the same opcodes in both UEFI and SeaBIOS and be done with it? The spec defines 22 actions, and most of these are permutations of 4 basic features (Enable, Activate, Clear, SetOwnerInstall). ... which may be a substantial amount of work to implement. There are another 23 or so defined for TPM 2, some of which are optional. [...] I initially had PPI SeaBIOS code write into the TPM TIS device's memory into some custom addresses. I'd consider this a hack. Well, sure, it could be considered a hack. But, it seems to me the whole PPI spec is a bit of a hack. If elegance isn't an option, settle for simplicity? -Kevin
Re: [Qemu-devel] [PATCH v2 4/4] acpi: build TPM Physical Presence interface
On Tue, Feb 13, 2018 at 03:29:20PM -0500, Stefan Berger wrote: [...] > 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. It seems that the primary purpose of the 0x400 virtual device is to pass information from firmware to QEMU (specifically to pass the list of supported PPI opcodes to the QEMU generated AML code). Passing information between firmware and QEMU is not new territory, and fw_cfg was specifically built to do this. I'd prefer to use fw_cfg if we need to pass information between firmware and QEMU. That said, I don't see why this list is needed - why not just implement the same opcodes in both UEFI and SeaBIOS and be done with it? The spec defines 22 actions, and most of these are permutations of 4 basic features (Enable, Activate, Clear, SetOwnerInstall). [...] > I initially had PPI SeaBIOS code write into the TPM TIS device's memory into > some custom addresses. I'd consider this a hack. Well, sure, it could be considered a hack. But, it seems to me the whole PPI spec is a bit of a hack. If elegance isn't an option, settle for simplicity? -Kevin
Re: [Qemu-devel] [PATCH v2 4/4] acpi: build TPM Physical Presence interface
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 0x 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 / "reg
Re: [Qemu-devel] [PATCH v2 4/4] acpi: build TPM Physical Presence interface
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 0x 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 an
Re: [Qemu-devel] [PATCH v2 4/4] acpi: build TPM Physical Presence interface
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 0x 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
Re: [Qemu-devel] [PATCH v2 4/4] acpi: build TPM Physical Presence interface
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 0x 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
Re: [Qemu-devel] [PATCH v2 4/4] acpi: build TPM Physical Presence interface
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 0x 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. -Kevin
Re: [Qemu-devel] [PATCH v2 4/4] acpi: build TPM Physical Presence interface
On 02/13/18 17:34, Igor Mammedov wrote: > On Tue, 13 Feb 2018 17:16:49 +0100 > Laszlo Ersek wrote: > > [...] >> >> It's possible that I'll scream for additional hw enlightement under OVMF >> later; so I suggest designing in some kind of feature negotiation up-front. > We can add an extra fwcfg file for that later, when/if it's actually needed. Works for me. Thanks Laszlo
Re: [Qemu-devel] [PATCH v2 4/4] acpi: build TPM Physical Presence interface
On 02/13/18 17:19, Igor Mammedov wrote: > On Tue, 13 Feb 2018 16:39:01 +0100 > Laszlo Ersek wrote: > >> On 02/13/18 15:17, Igor Mammedov wrote: >>> On Tue, 13 Feb 2018 14:31:41 +0100 >>> Laszlo Ersek wrote: >>> On 02/13/18 13:57, Igor Mammedov wrote: > On Mon, 12 Feb 2018 15:17:21 -0500 > Stefan Berger wrote: > >> On 02/12/2018 02:45 PM, Kevin O'Connor wrote: >>> On Fri, Feb 09, 2018 at 03:19:31PM -0500, Stefan Berger wrote: I have played around with this patch and some modifications to EDK2. Though for EDK2 the question is whether to try to circumvent their current implementation that uses SMM or use SMM. With this patch so far I circumvent it, which is maybe not a good idea. The facts for EDK2's PPI: - from within the OS a PPI code is submitted to ACPI and ACPI enters SMM via an SMI and the PPI code is written into a UEFI variable. For this ACPI uses the memory are at 0x to pass parameters from the OS (via ACPI) to SMM. This is declared in ACPI with an OperationRegion() at that address. Once the machine is rebooted, UEFI reads the variable and finds the PPI code and reacts to it. >>> I'm a bit confused by this. The top 1M of the first 4G of ram is >>> generally mapped to the flash device on real machines. Indeed, this >>> is part of the mechanism used to boot an X86 machine - it starts >>> execution from flash at 0xfff0. This is true even on modern >>> machines. >>> >>> So, it seems strange that UEFI is pushing a code through a memory >>> device at 0x. I can't see how that would be portable. Are >>> you sure the memory write to 0x is not just a trigger to >>> invoke the SMI? >> >> I base this on the code here: >> >> https://github.com/tianocore/edk2/blob/master/SecurityPkg/Tcg/Tcg2Smm/Tpm.asl#L81 >> >> OperationRegion (TNVS, SystemMemory, 0x, 0xF0) > Is the goal to reuse EDK PPI impl. including ASL? Right, that is one important question. Some code in edk2 is meant only as example code (so actual firmware platforms are encouraged to copy & customize the code, or use similar or dissimilar alternatives). Some modules are meant for inclusion "as-is" in the platform description files (~ makefiles). There are so many edk2 modules related to TPM (several versions of the specs even) that it's hard to say what is meant for what usage type. (By my earlier count, there are 19 modules.) > If it's so, then perhaps we only need to write address into QEMU > and let OVMF to discard PPI SSDT from QEMU. That's something I would not like. When running on QEMU, it's OK for some edk2 modules to install their own ACPI tables, but only if they are "software" tables, such as the IBFT for iSCSI booting, BGRT (boot graphics table) for the boot logo / splash screen, etc. For ACPI tables that describe hardware (data tables) or carry out actions related to hardware (DefinitionBlocks / AML), I much prefer QEMU to generate all the stuff. If there is a conflict between hardware-related tables that QEMU generates and similar tables that pre-exist in edk2, I prefer working with the edk2 maintainers to customize their subsystems, so that a concrete firmware platform, such as OvmfPkg and ArmVirtPkg, can conditionalize / exclude those preexistent ACPI tables, while benefiting from the rest of the code. Then the ACPI linker/loader client used in both OvmfPkg and ArmVirtPkg can remain dumb and process & expose whatever tables QEMU generates. We could control the AML payload for TPM and/or TPM PPI -- e.g. whether it should raise an SMI -- via "-device tpm2,smi=on", for example. (Just making up the syntax, but you know what I mean.) We could go one step further, "-device tpm2,acpi=[on|off]". acpi=on would make QEMU generate the TPM related tables (perhaps targeting only SeaBIOS, if that makes sense), acpi=off would leave the related tables to the firmware. This is just speculation on my part; the point is I'd like to avoid any more "intelligent filtering" regarding ACPI tables in OVMF. What we have there is terrible enough already. >>> If we could discard EDK's generated tables, it's fine as well, >>> but we would need to model TPM device model to match EDK's one >>> (risk here is that implementation goes of sync, if it's not spec >>> dictated). Then SeaBIOS side could 're-implement' it using >>> the same set of tables from QEMU. >>> >>> I wonder if we could somehow detect firmware flavor we are >>> running on from ASL /wrt [no]using SMI/? >>> * I don't really like idea but we
Re: [Qemu-devel] [PATCH v2 4/4] acpi: build TPM Physical Presence interface
On Tue, 13 Feb 2018 17:16:49 +0100 Laszlo Ersek wrote: [...] > > It's possible that I'll scream for additional hw enlightement under OVMF > later; so I suggest designing in some kind of feature negotiation up-front. We can add an extra fwcfg file for that later, when/if it's actually needed. [...]
Re: [Qemu-devel] [PATCH v2 4/4] acpi: build TPM Physical Presence interface
On Tue, 13 Feb 2018 16:39:01 +0100 Laszlo Ersek wrote: > On 02/13/18 15:17, Igor Mammedov wrote: > > On Tue, 13 Feb 2018 14:31:41 +0100 > > Laszlo Ersek wrote: > > > >> On 02/13/18 13:57, Igor Mammedov wrote: > >>> On Mon, 12 Feb 2018 15:17:21 -0500 > >>> Stefan Berger wrote: > >>> > On 02/12/2018 02:45 PM, Kevin O'Connor wrote: > > On Fri, Feb 09, 2018 at 03:19:31PM -0500, Stefan Berger wrote: > >> I have played around with this patch and some modifications to EDK2. > >> Though > >> for EDK2 the question is whether to try to circumvent their current > >> implementation that uses SMM or use SMM. With this patch so far I > >> circumvent > >> it, which is maybe not a good idea. > >> > >> The facts for EDK2's PPI: > >> > >> - from within the OS a PPI code is submitted to ACPI and ACPI enters > >> SMM via > >> an SMI and the PPI code is written into a UEFI variable. For this ACPI > >> uses > >> the memory are at 0x to pass parameters from the OS (via > >> ACPI) to > >> SMM. This is declared in ACPI with an OperationRegion() at that > >> address. > >> Once the machine is rebooted, UEFI reads the variable and finds the > >> PPI code > >> and reacts to it. > > I'm a bit confused by this. The top 1M of the first 4G of ram is > > generally mapped to the flash device on real machines. Indeed, this > > is part of the mechanism used to boot an X86 machine - it starts > > execution from flash at 0xfff0. This is true even on modern > > machines. > > > > So, it seems strange that UEFI is pushing a code through a memory > > device at 0x. I can't see how that would be portable. Are > > you sure the memory write to 0x is not just a trigger to > > invoke the SMI? > > I base this on the code here: > > https://github.com/tianocore/edk2/blob/master/SecurityPkg/Tcg/Tcg2Smm/Tpm.asl#L81 > > OperationRegion (TNVS, SystemMemory, 0x, 0xF0) > >>> Is the goal to reuse EDK PPI impl. including ASL? > >> > >> Right, that is one important question. Some code in edk2 is meant only > >> as example code (so actual firmware platforms are encouraged to copy & > >> customize the code, or use similar or dissimilar alternatives). Some > >> modules are meant for inclusion "as-is" in the platform description > >> files (~ makefiles). There are so many edk2 modules related to TPM > >> (several versions of the specs even) that it's hard to say what is meant > >> for what usage type. (By my earlier count, there are 19 modules.) > >> > >>> If it's so, then perhaps we only need to write address into QEMU > >>> and let OVMF to discard PPI SSDT from QEMU. > >> > >> That's something I would not like. When running on QEMU, it's OK for > >> some edk2 modules to install their own ACPI tables, but only if they are > >> "software" tables, such as the IBFT for iSCSI booting, BGRT (boot > >> graphics table) for the boot logo / splash screen, etc. For ACPI tables > >> that describe hardware (data tables) or carry out actions related to > >> hardware (DefinitionBlocks / AML), I much prefer QEMU to generate all > >> the stuff. > >> > >> If there is a conflict between hardware-related tables that QEMU > >> generates and similar tables that pre-exist in edk2, I prefer working > >> with the edk2 maintainers to customize their subsystems, so that a > >> concrete firmware platform, such as OvmfPkg and ArmVirtPkg, can > >> conditionalize / exclude those preexistent ACPI tables, while benefiting > >> from the rest of the code. Then the ACPI linker/loader client used in > >> both OvmfPkg and ArmVirtPkg can remain dumb and process & expose > >> whatever tables QEMU generates. > >> > >> We could control the AML payload for TPM and/or TPM PPI -- e.g. whether > >> it should raise an SMI -- via "-device tpm2,smi=on", for example. (Just > >> making up the syntax, but you know what I mean.) > >> > >> We could go one step further, "-device tpm2,acpi=[on|off]". acpi=on > >> would make QEMU generate the TPM related tables (perhaps targeting only > >> SeaBIOS, if that makes sense), acpi=off would leave the related tables > >> to the firmware. > >> > >> This is just speculation on my part; the point is I'd like to avoid any > >> more "intelligent filtering" regarding ACPI tables in OVMF. What we have > >> there is terrible enough already. > > If we could discard EDK's generated tables, it's fine as well, > > but we would need to model TPM device model to match EDK's one > > (risk here is that implementation goes of sync, if it's not spec > > dictated). Then SeaBIOS side could 're-implement' it using > > the same set of tables from QEMU. > > > > I wonder if we could somehow detect firmware flavor we are > > running on from ASL /wrt [no]using SMI/? > > * I don't really like idea but we can probably detect > >in QEMU if firmware
Re: [Qemu-devel] [PATCH v2 4/4] acpi: build TPM Physical Presence interface
On 02/12/18 21:49, Stefan Berger wrote: > On 02/12/2018 03:46 PM, Kevin O'Connor wrote: >> On Fri, Feb 09, 2018 at 03:19:31PM -0500, Stefan Berger wrote: >>> The PPI device in this patch series allocates 0x400 bytes. 0x200 >>> bytes are >>> used by the OperationRegion() in this patch series. The rest was >>> thought of >>> for future extensions. >>> >>> To allow both firmwares to use PPI, we would need to be able to have the >>> OperationRegion() be flexible and located at 0x for EDK2 and >>> 0xFED4 >>> 5000 for SeaBIOS, per choice of the firmware. One way to achieve this >>> would >>> be to have the firmwares choose their operation region base address by >>> writing into the PPI memory device at offset 0x200 (for example). A '1' >>> there would mean that we want the OperationRegion() at 0x , >>> and a >>> '2' would mean at the base address of the PPI device (0xFED4 5000). This >>> could be achieved by declaring a 2nd OperationRegion() in the ACPI >>> code that >>> is located at 0xFED4 5200 and we declare that 1st OperationRegion()'s >>> address based on findings from there. Further, a flags variable at >>> offset >>> 0x201 could indicate whether an SMI is needed to enter SMM or not. >>> Obviously, the ACPI code would become more complex to be able to support >>> both firmwares at the same time. >>> >>> This is a lot of details but I rather post this description before >>> posting >>> more patches. To make these changes and get it to work with at least >>> SeaBIOS >>> is probably fairly easy. But is this acceptable? >> 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 0x 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. Generate as much as possible AML in QEMU, using the linker/loader. If you generate data tables, please don't forget about the "OVMF SDT header probe suppressor" padding (see vmgenid for example). Focus on basic TPM enablement (measurements, PCRs) an
Re: [Qemu-devel] [PATCH v2 4/4] acpi: build TPM Physical Presence interface
On 02/13/18 15:17, Igor Mammedov wrote: > On Tue, 13 Feb 2018 14:31:41 +0100 > Laszlo Ersek wrote: > >> On 02/13/18 13:57, Igor Mammedov wrote: >>> On Mon, 12 Feb 2018 15:17:21 -0500 >>> Stefan Berger wrote: >>> On 02/12/2018 02:45 PM, Kevin O'Connor wrote: > On Fri, Feb 09, 2018 at 03:19:31PM -0500, Stefan Berger wrote: >> I have played around with this patch and some modifications to EDK2. >> Though >> for EDK2 the question is whether to try to circumvent their current >> implementation that uses SMM or use SMM. With this patch so far I >> circumvent >> it, which is maybe not a good idea. >> >> The facts for EDK2's PPI: >> >> - from within the OS a PPI code is submitted to ACPI and ACPI enters SMM >> via >> an SMI and the PPI code is written into a UEFI variable. For this ACPI >> uses >> the memory are at 0x to pass parameters from the OS (via ACPI) >> to >> SMM. This is declared in ACPI with an OperationRegion() at that address. >> Once the machine is rebooted, UEFI reads the variable and finds the PPI >> code >> and reacts to it. > I'm a bit confused by this. The top 1M of the first 4G of ram is > generally mapped to the flash device on real machines. Indeed, this > is part of the mechanism used to boot an X86 machine - it starts > execution from flash at 0xfff0. This is true even on modern > machines. > > So, it seems strange that UEFI is pushing a code through a memory > device at 0x. I can't see how that would be portable. Are > you sure the memory write to 0x is not just a trigger to > invoke the SMI? I base this on the code here: https://github.com/tianocore/edk2/blob/master/SecurityPkg/Tcg/Tcg2Smm/Tpm.asl#L81 OperationRegion (TNVS, SystemMemory, 0x, 0xF0) >>> Is the goal to reuse EDK PPI impl. including ASL? >> >> Right, that is one important question. Some code in edk2 is meant only >> as example code (so actual firmware platforms are encouraged to copy & >> customize the code, or use similar or dissimilar alternatives). Some >> modules are meant for inclusion "as-is" in the platform description >> files (~ makefiles). There are so many edk2 modules related to TPM >> (several versions of the specs even) that it's hard to say what is meant >> for what usage type. (By my earlier count, there are 19 modules.) >> >>> If it's so, then perhaps we only need to write address into QEMU >>> and let OVMF to discard PPI SSDT from QEMU. >> >> That's something I would not like. When running on QEMU, it's OK for >> some edk2 modules to install their own ACPI tables, but only if they are >> "software" tables, such as the IBFT for iSCSI booting, BGRT (boot >> graphics table) for the boot logo / splash screen, etc. For ACPI tables >> that describe hardware (data tables) or carry out actions related to >> hardware (DefinitionBlocks / AML), I much prefer QEMU to generate all >> the stuff. >> >> If there is a conflict between hardware-related tables that QEMU >> generates and similar tables that pre-exist in edk2, I prefer working >> with the edk2 maintainers to customize their subsystems, so that a >> concrete firmware platform, such as OvmfPkg and ArmVirtPkg, can >> conditionalize / exclude those preexistent ACPI tables, while benefiting >> from the rest of the code. Then the ACPI linker/loader client used in >> both OvmfPkg and ArmVirtPkg can remain dumb and process & expose >> whatever tables QEMU generates. >> >> We could control the AML payload for TPM and/or TPM PPI -- e.g. whether >> it should raise an SMI -- via "-device tpm2,smi=on", for example. (Just >> making up the syntax, but you know what I mean.) >> >> We could go one step further, "-device tpm2,acpi=[on|off]". acpi=on >> would make QEMU generate the TPM related tables (perhaps targeting only >> SeaBIOS, if that makes sense), acpi=off would leave the related tables >> to the firmware. >> >> This is just speculation on my part; the point is I'd like to avoid any >> more "intelligent filtering" regarding ACPI tables in OVMF. What we have >> there is terrible enough already. > If we could discard EDK's generated tables, it's fine as well, > but we would need to model TPM device model to match EDK's one > (risk here is that implementation goes of sync, if it's not spec > dictated). Then SeaBIOS side could 're-implement' it using > the same set of tables from QEMU. > > I wonder if we could somehow detect firmware flavor we are > running on from ASL /wrt [no]using SMI/? > * I don't really like idea but we can probably detect >in QEMU if firmware is OVMF or not and generate extra SMI hunk >based on that. > * or we could always generate SMI code and probe for some >EDK specific SSDT code to see in AML to enable it. >Maybe OVMF could inject such table. There are already several QEMU artifacts that are specific to
Re: [Qemu-devel] [PATCH v2 4/4] acpi: build TPM Physical Presence interface
On Tue, 13 Feb 2018 14:31:41 +0100 Laszlo Ersek wrote: > On 02/13/18 13:57, Igor Mammedov wrote: > > On Mon, 12 Feb 2018 15:17:21 -0500 > > Stefan Berger wrote: > > > >> On 02/12/2018 02:45 PM, Kevin O'Connor wrote: > >>> On Fri, Feb 09, 2018 at 03:19:31PM -0500, Stefan Berger wrote: > I have played around with this patch and some modifications to EDK2. > Though > for EDK2 the question is whether to try to circumvent their current > implementation that uses SMM or use SMM. With this patch so far I > circumvent > it, which is maybe not a good idea. > > The facts for EDK2's PPI: > > - from within the OS a PPI code is submitted to ACPI and ACPI enters SMM > via > an SMI and the PPI code is written into a UEFI variable. For this ACPI > uses > the memory are at 0x to pass parameters from the OS (via ACPI) > to > SMM. This is declared in ACPI with an OperationRegion() at that address. > Once the machine is rebooted, UEFI reads the variable and finds the PPI > code > and reacts to it. > >>> I'm a bit confused by this. The top 1M of the first 4G of ram is > >>> generally mapped to the flash device on real machines. Indeed, this > >>> is part of the mechanism used to boot an X86 machine - it starts > >>> execution from flash at 0xfff0. This is true even on modern > >>> machines. > >>> > >>> So, it seems strange that UEFI is pushing a code through a memory > >>> device at 0x. I can't see how that would be portable. Are > >>> you sure the memory write to 0x is not just a trigger to > >>> invoke the SMI? > >> > >> I base this on the code here: > >> > >> https://github.com/tianocore/edk2/blob/master/SecurityPkg/Tcg/Tcg2Smm/Tpm.asl#L81 > >> > >> OperationRegion (TNVS, SystemMemory, 0x, 0xF0) > > Is the goal to reuse EDK PPI impl. including ASL? > > Right, that is one important question. Some code in edk2 is meant only > as example code (so actual firmware platforms are encouraged to copy & > customize the code, or use similar or dissimilar alternatives). Some > modules are meant for inclusion "as-is" in the platform description > files (~ makefiles). There are so many edk2 modules related to TPM > (several versions of the specs even) that it's hard to say what is meant > for what usage type. (By my earlier count, there are 19 modules.) > > > If it's so, then perhaps we only need to write address into QEMU > > and let OVMF to discard PPI SSDT from QEMU. > > That's something I would not like. When running on QEMU, it's OK for > some edk2 modules to install their own ACPI tables, but only if they are > "software" tables, such as the IBFT for iSCSI booting, BGRT (boot > graphics table) for the boot logo / splash screen, etc. For ACPI tables > that describe hardware (data tables) or carry out actions related to > hardware (DefinitionBlocks / AML), I much prefer QEMU to generate all > the stuff. > > If there is a conflict between hardware-related tables that QEMU > generates and similar tables that pre-exist in edk2, I prefer working > with the edk2 maintainers to customize their subsystems, so that a > concrete firmware platform, such as OvmfPkg and ArmVirtPkg, can > conditionalize / exclude those preexistent ACPI tables, while benefiting > from the rest of the code. Then the ACPI linker/loader client used in > both OvmfPkg and ArmVirtPkg can remain dumb and process & expose > whatever tables QEMU generates. > > We could control the AML payload for TPM and/or TPM PPI -- e.g. whether > it should raise an SMI -- via "-device tpm2,smi=on", for example. (Just > making up the syntax, but you know what I mean.) > > We could go one step further, "-device tpm2,acpi=[on|off]". acpi=on > would make QEMU generate the TPM related tables (perhaps targeting only > SeaBIOS, if that makes sense), acpi=off would leave the related tables > to the firmware. > > This is just speculation on my part; the point is I'd like to avoid any > more "intelligent filtering" regarding ACPI tables in OVMF. What we have > there is terrible enough already. If we could discard EDK's generated tables, it's fine as well, but we would need to model TPM device model to match EDK's one (risk here is that implementation goes of sync, if it's not spec dictated). Then SeaBIOS side could 're-implement' it using the same set of tables from QEMU. I wonder if we could somehow detect firmware flavor we are running on from ASL /wrt [no]using SMI/? * I don't really like idea but we can probably detect in QEMU if firmware is OVMF or not and generate extra SMI hunk based on that. * or we could always generate SMI code and probe for some EDK specific SSDT code to see in AML to enable it. Maybe OVMF could inject such table. > > Thanks > Laszlo
Re: [Qemu-devel] [PATCH v2 4/4] acpi: build TPM Physical Presence interface
On 02/13/18 13:57, Igor Mammedov wrote: > On Mon, 12 Feb 2018 15:17:21 -0500 > Stefan Berger wrote: > >> On 02/12/2018 02:45 PM, Kevin O'Connor wrote: >>> On Fri, Feb 09, 2018 at 03:19:31PM -0500, Stefan Berger wrote: I have played around with this patch and some modifications to EDK2. Though for EDK2 the question is whether to try to circumvent their current implementation that uses SMM or use SMM. With this patch so far I circumvent it, which is maybe not a good idea. The facts for EDK2's PPI: - from within the OS a PPI code is submitted to ACPI and ACPI enters SMM via an SMI and the PPI code is written into a UEFI variable. For this ACPI uses the memory are at 0x to pass parameters from the OS (via ACPI) to SMM. This is declared in ACPI with an OperationRegion() at that address. Once the machine is rebooted, UEFI reads the variable and finds the PPI code and reacts to it. >>> I'm a bit confused by this. The top 1M of the first 4G of ram is >>> generally mapped to the flash device on real machines. Indeed, this >>> is part of the mechanism used to boot an X86 machine - it starts >>> execution from flash at 0xfff0. This is true even on modern >>> machines. >>> >>> So, it seems strange that UEFI is pushing a code through a memory >>> device at 0x. I can't see how that would be portable. Are >>> you sure the memory write to 0x is not just a trigger to >>> invoke the SMI? >> >> I base this on the code here: >> >> https://github.com/tianocore/edk2/blob/master/SecurityPkg/Tcg/Tcg2Smm/Tpm.asl#L81 >> >> OperationRegion (TNVS, SystemMemory, 0x, 0xF0) > Is the goal to reuse EDK PPI impl. including ASL? Right, that is one important question. Some code in edk2 is meant only as example code (so actual firmware platforms are encouraged to copy & customize the code, or use similar or dissimilar alternatives). Some modules are meant for inclusion "as-is" in the platform description files (~ makefiles). There are so many edk2 modules related to TPM (several versions of the specs even) that it's hard to say what is meant for what usage type. (By my earlier count, there are 19 modules.) > If it's so, then perhaps we only need to write address into QEMU > and let OVMF to discard PPI SSDT from QEMU. That's something I would not like. When running on QEMU, it's OK for some edk2 modules to install their own ACPI tables, but only if they are "software" tables, such as the IBFT for iSCSI booting, BGRT (boot graphics table) for the boot logo / splash screen, etc. For ACPI tables that describe hardware (data tables) or carry out actions related to hardware (DefinitionBlocks / AML), I much prefer QEMU to generate all the stuff. If there is a conflict between hardware-related tables that QEMU generates and similar tables that pre-exist in edk2, I prefer working with the edk2 maintainers to customize their subsystems, so that a concrete firmware platform, such as OvmfPkg and ArmVirtPkg, can conditionalize / exclude those preexistent ACPI tables, while benefiting from the rest of the code. Then the ACPI linker/loader client used in both OvmfPkg and ArmVirtPkg can remain dumb and process & expose whatever tables QEMU generates. We could control the AML payload for TPM and/or TPM PPI -- e.g. whether it should raise an SMI -- via "-device tpm2,smi=on", for example. (Just making up the syntax, but you know what I mean.) We could go one step further, "-device tpm2,acpi=[on|off]". acpi=on would make QEMU generate the TPM related tables (perhaps targeting only SeaBIOS, if that makes sense), acpi=off would leave the related tables to the firmware. This is just speculation on my part; the point is I'd like to avoid any more "intelligent filtering" regarding ACPI tables in OVMF. What we have there is terrible enough already. Thanks Laszlo
Re: [Qemu-devel] [PATCH v2 4/4] acpi: build TPM Physical Presence interface
On Mon, 12 Feb 2018 15:17:21 -0500 Stefan Berger wrote: > On 02/12/2018 02:45 PM, Kevin O'Connor wrote: > > On Fri, Feb 09, 2018 at 03:19:31PM -0500, Stefan Berger wrote: > >> I have played around with this patch and some modifications to EDK2. Though > >> for EDK2 the question is whether to try to circumvent their current > >> implementation that uses SMM or use SMM. With this patch so far I > >> circumvent > >> it, which is maybe not a good idea. > >> > >> The facts for EDK2's PPI: > >> > >> - from within the OS a PPI code is submitted to ACPI and ACPI enters SMM > >> via > >> an SMI and the PPI code is written into a UEFI variable. For this ACPI uses > >> the memory are at 0x to pass parameters from the OS (via ACPI) to > >> SMM. This is declared in ACPI with an OperationRegion() at that address. > >> Once the machine is rebooted, UEFI reads the variable and finds the PPI > >> code > >> and reacts to it. > > I'm a bit confused by this. The top 1M of the first 4G of ram is > > generally mapped to the flash device on real machines. Indeed, this > > is part of the mechanism used to boot an X86 machine - it starts > > execution from flash at 0xfff0. This is true even on modern > > machines. > > > > So, it seems strange that UEFI is pushing a code through a memory > > device at 0x. I can't see how that would be portable. Are > > you sure the memory write to 0x is not just a trigger to > > invoke the SMI? > > I base this on the code here: > > https://github.com/tianocore/edk2/blob/master/SecurityPkg/Tcg/Tcg2Smm/Tpm.asl#L81 > > OperationRegion (TNVS, SystemMemory, 0x, 0xF0) Is the goal to reuse EDK PPI impl. including ASL? If it's so, then perhaps we only need to write address into QEMU and let OVMF to discard PPI SSDT from QEMU. > Stefan > > > > > -Kevin > > > >
Re: [Qemu-devel] [PATCH v2 4/4] acpi: build TPM Physical Presence interface
On Mon, 12 Feb 2018 13:45:17 -0500 Stefan Berger wrote: > On 02/12/2018 12:52 PM, Igor Mammedov wrote: > > On Mon, 12 Feb 2018 11:44:16 -0500 > > Stefan Berger wrote: > > > >> On 02/12/2018 09:27 AM, Igor Mammedov wrote: > >>> On Fri, 9 Feb 2018 15:19:31 -0500 > >>> Stefan Berger wrote: > >>> > On 01/16/2018 10:51 AM, Stefan Berger wrote: > > The TPM Physical Presence interface consists of an ACPI part, a shared > > memory part, and code in the firmware. Users can send messages to the > > firmware by writing a code into the shared memory through invoking the > > ACPI code. When a reboot happens, the firmware looks for the code and > > acts on it by sending sequences of commands to the TPM. > > > > This patch adds the ACPI code. It is similar to the one in EDK2 but > > doesn't > > assume that SMIs are necessary to use. It uses a similar datastructure > > for > > the shared memory as EDK2 does so that EDK2 and SeaBIOS could both make > > use > > of it. I extended the shared memory data structure with an array of 256 > > bytes, one for each code that could be implemented. The array contains > > flags describing the individual codes. This decouples the ACPI > > implementation > > from the firmware implementation. > > > > The underlying TCG specification is accessible from the following page. > > > > https://trustedcomputinggroup.org/tcg-physical-presence-interface-specification/ > > > > This patch implements version 1.30. > I have played around with this patch and some modifications to EDK2. > Though for EDK2 the question is whether to try to circumvent their > current implementation that uses SMM or use SMM. With this patch so far > I circumvent it, which is maybe not a good idea. > > The facts for EDK2's PPI: > > - from within the OS a PPI code is submitted to ACPI and ACPI enters SMM > via an SMI and the PPI code is written into a UEFI variable. For this > ACPI uses the memory are at 0x to pass parameters from the OS > (via ACPI) to SMM. This is declared in ACPI with an OperationRegion() at > that address. Once the machine is rebooted, UEFI reads the variable and > finds the PPI code and reacts to it. > > > The facts for SeaBIOS: > - we cannot use the area at 0x since SeaBIOS is also mapped to > this address. So we would have to use the PPI memory device's memory > region, which is currently at 0xFED4 5000. SeaBIOS doesn't have > persistent memory like NVRAM where it stores varaibles. So to pass the > PPI code here the OS would invoke ACPI, which in turn would write the > PPI code into the PPI memory directly. Upon reboot SeaBIOS would find > the PPI code in the PPI memory device and react to it. > > The PPI device in this patch series allocates 0x400 bytes. 0x200 bytes > are used by the OperationRegion() in this patch series. The rest was > thought of for future extensions. > > To allow both firmwares to use PPI, we would need to be able to have the > OperationRegion() be flexible and located at 0x for EDK2 and > 0xFED4 5000 for SeaBIOS, per choice of the firmware. One way to achieve > this would be to have the firmwares choose their operation region base > address by writing into the PPI memory device at offset 0x200 (for > example). A '1' there would mean that we want the OperationRegion() at > 0x , and a '2' would mean at the base address of the PPI device > (0xFED4 5000). This could be achieved by declaring a 2nd > OperationRegion() in the ACPI code that is located at 0xFED4 5200 and we > declare that 1st OperationRegion()'s address based on findings from > there. Further, a flags variable at offset 0x201 could indicate whether > an SMI is needed to enter SMM or not. Obviously, the ACPI code would > become more complex to be able to support both firmwares at the same > time. > This is a lot of details but I rather post this description before > posting more patches. To make these changes and get it to work with at > least SeaBIOS is probably fairly easy. But is this acceptable? > >>> You could use hw/acpi/vmgenid.c as example, > >>> > >>> use following command to instruct firmware to write address back to QEMU: > >>> > >>> bios_linker_loader_write_pointer(linker, > >>> TMP_PPI_ADDR_FW_CFG_FILE, 0, sizeof(uint64_t), > >>> TPM_PPI_MEM_FW_CFG_FILE, TPM_PPI_MEM_OFFSET); > >>> > >>> then when address is written into fwcfg, a callback in QEMU would be > >>> called due to > >>> > >>> /* Create a read-write fw_cfg file for Address */ > >>> fw_cfg_add_file_callback(s, TPM_PPI_ADDR_FW_CFG_FILE, ...); > >>> > >>> when CB is called you could map persistent overlay memory region > >>> (PPI memory device
Re: [Qemu-devel] [PATCH v2 4/4] acpi: build TPM Physical Presence interface
On 02/12/2018 03:46 PM, Kevin O'Connor wrote: On Fri, Feb 09, 2018 at 03:19:31PM -0500, Stefan Berger wrote: The PPI device in this patch series allocates 0x400 bytes. 0x200 bytes are used by the OperationRegion() in this patch series. The rest was thought of for future extensions. To allow both firmwares to use PPI, we would need to be able to have the OperationRegion() be flexible and located at 0x for EDK2 and 0xFED4 5000 for SeaBIOS, per choice of the firmware. One way to achieve this would be to have the firmwares choose their operation region base address by writing into the PPI memory device at offset 0x200 (for example). A '1' there would mean that we want the OperationRegion() at 0x , and a '2' would mean at the base address of the PPI device (0xFED4 5000). This could be achieved by declaring a 2nd OperationRegion() in the ACPI code that is located at 0xFED4 5200 and we declare that 1st OperationRegion()'s address based on findings from there. Further, a flags variable at offset 0x201 could indicate whether an SMI is needed to enter SMM or not. Obviously, the ACPI code would become more complex to be able to support both firmwares at the same time. This is a lot of details but I rather post this description before posting more patches. To make these changes and get it to work with at least SeaBIOS is probably fairly easy. But is this acceptable? 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 0x 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. Separately, is there someone clamoring for PPI support today? That is, is the goal to implement PPI to make QEMU more spec compliant, or is there someone struggling to perform a particular task today that this support would improve? We could defer the implementation of this. My main goal was to to support TPM migration in QEMU and the PPI device also needs to be migrated as part of TPM migration. So that's why I am looking at PPI now. Stefan Thanks, -Kevin
Re: [Qemu-devel] [PATCH v2 4/4] acpi: build TPM Physical Presence interface
On Fri, Feb 09, 2018 at 03:19:31PM -0500, Stefan Berger wrote: > The PPI device in this patch series allocates 0x400 bytes. 0x200 bytes are > used by the OperationRegion() in this patch series. The rest was thought of > for future extensions. > > To allow both firmwares to use PPI, we would need to be able to have the > OperationRegion() be flexible and located at 0x for EDK2 and 0xFED4 > 5000 for SeaBIOS, per choice of the firmware. One way to achieve this would > be to have the firmwares choose their operation region base address by > writing into the PPI memory device at offset 0x200 (for example). A '1' > there would mean that we want the OperationRegion() at 0x , and a > '2' would mean at the base address of the PPI device (0xFED4 5000). This > could be achieved by declaring a 2nd OperationRegion() in the ACPI code that > is located at 0xFED4 5200 and we declare that 1st OperationRegion()'s > address based on findings from there. Further, a flags variable at offset > 0x201 could indicate whether an SMI is needed to enter SMM or not. > Obviously, the ACPI code would become more complex to be able to support > both firmwares at the same time. > > This is a lot of details but I rather post this description before posting > more patches. To make these changes and get it to work with at least SeaBIOS > is probably fairly easy. But is this acceptable? 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). 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. 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.) 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 0x or 0xFED45000). 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. Did I understand the above correctly? Separately, is there someone clamoring for PPI support today? That is, is the goal to implement PPI to make QEMU more spec compliant, or is there someone struggling to perform a particular task today that this support would improve? Thanks, -Kevin
Re: [Qemu-devel] [PATCH v2 4/4] acpi: build TPM Physical Presence interface
On 02/12/2018 02:45 PM, Kevin O'Connor wrote: On Fri, Feb 09, 2018 at 03:19:31PM -0500, Stefan Berger wrote: I have played around with this patch and some modifications to EDK2. Though for EDK2 the question is whether to try to circumvent their current implementation that uses SMM or use SMM. With this patch so far I circumvent it, which is maybe not a good idea. The facts for EDK2's PPI: - from within the OS a PPI code is submitted to ACPI and ACPI enters SMM via an SMI and the PPI code is written into a UEFI variable. For this ACPI uses the memory are at 0x to pass parameters from the OS (via ACPI) to SMM. This is declared in ACPI with an OperationRegion() at that address. Once the machine is rebooted, UEFI reads the variable and finds the PPI code and reacts to it. I'm a bit confused by this. The top 1M of the first 4G of ram is generally mapped to the flash device on real machines. Indeed, this is part of the mechanism used to boot an X86 machine - it starts execution from flash at 0xfff0. This is true even on modern machines. So, it seems strange that UEFI is pushing a code through a memory device at 0x. I can't see how that would be portable. Are you sure the memory write to 0x is not just a trigger to invoke the SMI? I base this on the code here: https://github.com/tianocore/edk2/blob/master/SecurityPkg/Tcg/Tcg2Smm/Tpm.asl#L81 OperationRegion (TNVS, SystemMemory, 0x, 0xF0) It sounds as if the ultimate TPM interface that must be supported is the ACPI DSDT methods. Since you're crafting the DSDT table yourself, why does there need to be two different backends - why can't the same mechanism be used for both SeaBIOS and UEFI? Is this because you are looking to reuse TPM code already in UEFI that requires a specific interface? UEFI uses SMM to write the PPI code into a UEFI variable that it then presumably stores back to NVRAM. With SeaBIOS I would go the path of having the ACPI code write the code in the OperationRegion() and leave it at that, so not invoke SMM. EDK2 also reads the result of the operation from a register that SMM uses to pass a return value through. We wouldn't need that for SeaBIOS. Stefan -Kevin
Re: [Qemu-devel] [PATCH v2 4/4] acpi: build TPM Physical Presence interface
On Fri, Feb 09, 2018 at 03:19:31PM -0500, Stefan Berger wrote: > I have played around with this patch and some modifications to EDK2. Though > for EDK2 the question is whether to try to circumvent their current > implementation that uses SMM or use SMM. With this patch so far I circumvent > it, which is maybe not a good idea. > > The facts for EDK2's PPI: > > - from within the OS a PPI code is submitted to ACPI and ACPI enters SMM via > an SMI and the PPI code is written into a UEFI variable. For this ACPI uses > the memory are at 0x to pass parameters from the OS (via ACPI) to > SMM. This is declared in ACPI with an OperationRegion() at that address. > Once the machine is rebooted, UEFI reads the variable and finds the PPI code > and reacts to it. I'm a bit confused by this. The top 1M of the first 4G of ram is generally mapped to the flash device on real machines. Indeed, this is part of the mechanism used to boot an X86 machine - it starts execution from flash at 0xfff0. This is true even on modern machines. So, it seems strange that UEFI is pushing a code through a memory device at 0x. I can't see how that would be portable. Are you sure the memory write to 0x is not just a trigger to invoke the SMI? It sounds as if the ultimate TPM interface that must be supported is the ACPI DSDT methods. Since you're crafting the DSDT table yourself, why does there need to be two different backends - why can't the same mechanism be used for both SeaBIOS and UEFI? Is this because you are looking to reuse TPM code already in UEFI that requires a specific interface? -Kevin
Re: [Qemu-devel] [PATCH v2 4/4] acpi: build TPM Physical Presence interface
On 02/12/2018 12:52 PM, Igor Mammedov wrote: On Mon, 12 Feb 2018 11:44:16 -0500 Stefan Berger wrote: On 02/12/2018 09:27 AM, Igor Mammedov wrote: On Fri, 9 Feb 2018 15:19:31 -0500 Stefan Berger wrote: On 01/16/2018 10:51 AM, Stefan Berger wrote: The TPM Physical Presence interface consists of an ACPI part, a shared memory part, and code in the firmware. Users can send messages to the firmware by writing a code into the shared memory through invoking the ACPI code. When a reboot happens, the firmware looks for the code and acts on it by sending sequences of commands to the TPM. This patch adds the ACPI code. It is similar to the one in EDK2 but doesn't assume that SMIs are necessary to use. It uses a similar datastructure for the shared memory as EDK2 does so that EDK2 and SeaBIOS could both make use of it. I extended the shared memory data structure with an array of 256 bytes, one for each code that could be implemented. The array contains flags describing the individual codes. This decouples the ACPI implementation from the firmware implementation. The underlying TCG specification is accessible from the following page. https://trustedcomputinggroup.org/tcg-physical-presence-interface-specification/ This patch implements version 1.30. I have played around with this patch and some modifications to EDK2. Though for EDK2 the question is whether to try to circumvent their current implementation that uses SMM or use SMM. With this patch so far I circumvent it, which is maybe not a good idea. The facts for EDK2's PPI: - from within the OS a PPI code is submitted to ACPI and ACPI enters SMM via an SMI and the PPI code is written into a UEFI variable. For this ACPI uses the memory are at 0x to pass parameters from the OS (via ACPI) to SMM. This is declared in ACPI with an OperationRegion() at that address. Once the machine is rebooted, UEFI reads the variable and finds the PPI code and reacts to it. The facts for SeaBIOS: - we cannot use the area at 0x since SeaBIOS is also mapped to this address. So we would have to use the PPI memory device's memory region, which is currently at 0xFED4 5000. SeaBIOS doesn't have persistent memory like NVRAM where it stores varaibles. So to pass the PPI code here the OS would invoke ACPI, which in turn would write the PPI code into the PPI memory directly. Upon reboot SeaBIOS would find the PPI code in the PPI memory device and react to it. The PPI device in this patch series allocates 0x400 bytes. 0x200 bytes are used by the OperationRegion() in this patch series. The rest was thought of for future extensions. To allow both firmwares to use PPI, we would need to be able to have the OperationRegion() be flexible and located at 0x for EDK2 and 0xFED4 5000 for SeaBIOS, per choice of the firmware. One way to achieve this would be to have the firmwares choose their operation region base address by writing into the PPI memory device at offset 0x200 (for example). A '1' there would mean that we want the OperationRegion() at 0x , and a '2' would mean at the base address of the PPI device (0xFED4 5000). This could be achieved by declaring a 2nd OperationRegion() in the ACPI code that is located at 0xFED4 5200 and we declare that 1st OperationRegion()'s address based on findings from there. Further, a flags variable at offset 0x201 could indicate whether an SMI is needed to enter SMM or not. Obviously, the ACPI code would become more complex to be able to support both firmwares at the same time. This is a lot of details but I rather post this description before posting more patches. To make these changes and get it to work with at least SeaBIOS is probably fairly easy. But is this acceptable? You could use hw/acpi/vmgenid.c as example, use following command to instruct firmware to write address back to QEMU: bios_linker_loader_write_pointer(linker, TMP_PPI_ADDR_FW_CFG_FILE, 0, sizeof(uint64_t), TPM_PPI_MEM_FW_CFG_FILE, TPM_PPI_MEM_OFFSET); then when address is written into fwcfg, a callback in QEMU would be called due to /* Create a read-write fw_cfg file for Address */ fw_cfg_add_file_callback(s, TPM_PPI_ADDR_FW_CFG_FILE, ...); when CB is called you could map persistent overlay memory region (PPI memory device) at address written by firmware. As for OperationRegion, you can instruct firmware to patch address in AML as well, using bios_linker_loader_add_pointer() linker command. what I'd suggest is to use dedicated TPM SSDT table and at its start put a DWORD/QWORD variable where address would be patched in and then use that variable as argument to OperationRegion ssdt = init_aml_allocator(); ... addr_offset = table_data->len + build_append_named_dword(ssdt->buf, "PPIA"); ... ... aml_operation_region("TPPI", AML_SYSTEM_MEMORY, aml_name("PPIA"), TPM_PPI_STRUCT_SIZE) ... bios_linker_loader_add_pointer(linker, ACPI_BUILD_TABLE_FILE, a
Re: [Qemu-devel] [PATCH v2 4/4] acpi: build TPM Physical Presence interface
On Mon, 12 Feb 2018 11:44:16 -0500 Stefan Berger wrote: > On 02/12/2018 09:27 AM, Igor Mammedov wrote: > > On Fri, 9 Feb 2018 15:19:31 -0500 > > Stefan Berger wrote: > > > >> On 01/16/2018 10:51 AM, Stefan Berger wrote: > >>> The TPM Physical Presence interface consists of an ACPI part, a shared > >>> memory part, and code in the firmware. Users can send messages to the > >>> firmware by writing a code into the shared memory through invoking the > >>> ACPI code. When a reboot happens, the firmware looks for the code and > >>> acts on it by sending sequences of commands to the TPM. > >>> > >>> This patch adds the ACPI code. It is similar to the one in EDK2 but > >>> doesn't > >>> assume that SMIs are necessary to use. It uses a similar datastructure for > >>> the shared memory as EDK2 does so that EDK2 and SeaBIOS could both make > >>> use > >>> of it. I extended the shared memory data structure with an array of 256 > >>> bytes, one for each code that could be implemented. The array contains > >>> flags describing the individual codes. This decouples the ACPI > >>> implementation > >>> from the firmware implementation. > >>> > >>> The underlying TCG specification is accessible from the following page. > >>> > >>> https://trustedcomputinggroup.org/tcg-physical-presence-interface-specification/ > >>> > >>> This patch implements version 1.30. > >> I have played around with this patch and some modifications to EDK2. > >> Though for EDK2 the question is whether to try to circumvent their > >> current implementation that uses SMM or use SMM. With this patch so far > >> I circumvent it, which is maybe not a good idea. > >> > >> The facts for EDK2's PPI: > >> > >> - from within the OS a PPI code is submitted to ACPI and ACPI enters SMM > >> via an SMI and the PPI code is written into a UEFI variable. For this > >> ACPI uses the memory are at 0x to pass parameters from the OS > >> (via ACPI) to SMM. This is declared in ACPI with an OperationRegion() at > >> that address. Once the machine is rebooted, UEFI reads the variable and > >> finds the PPI code and reacts to it. > >> > >> > >> The facts for SeaBIOS: > >> - we cannot use the area at 0x since SeaBIOS is also mapped to > >> this address. So we would have to use the PPI memory device's memory > >> region, which is currently at 0xFED4 5000. SeaBIOS doesn't have > >> persistent memory like NVRAM where it stores varaibles. So to pass the > >> PPI code here the OS would invoke ACPI, which in turn would write the > >> PPI code into the PPI memory directly. Upon reboot SeaBIOS would find > >> the PPI code in the PPI memory device and react to it. > >> > >> The PPI device in this patch series allocates 0x400 bytes. 0x200 bytes > >> are used by the OperationRegion() in this patch series. The rest was > >> thought of for future extensions. > >> > >> To allow both firmwares to use PPI, we would need to be able to have the > >> OperationRegion() be flexible and located at 0x for EDK2 and > >> 0xFED4 5000 for SeaBIOS, per choice of the firmware. One way to achieve > >> this would be to have the firmwares choose their operation region base > >> address by writing into the PPI memory device at offset 0x200 (for > >> example). A '1' there would mean that we want the OperationRegion() at > >> 0x , and a '2' would mean at the base address of the PPI device > >> (0xFED4 5000). This could be achieved by declaring a 2nd > >> OperationRegion() in the ACPI code that is located at 0xFED4 5200 and we > >> declare that 1st OperationRegion()'s address based on findings from > >> there. Further, a flags variable at offset 0x201 could indicate whether > >> an SMI is needed to enter SMM or not. Obviously, the ACPI code would > >> become more complex to be able to support both firmwares at the same time. > >> This is a lot of details but I rather post this description before > >> posting more patches. To make these changes and get it to work with at > >> least SeaBIOS is probably fairly easy. But is this acceptable? > > You could use hw/acpi/vmgenid.c as example, > > > > use following command to instruct firmware to write address back to QEMU: > > > > bios_linker_loader_write_pointer(linker, > > TMP_PPI_ADDR_FW_CFG_FILE, 0, sizeof(uint64_t), > > TPM_PPI_MEM_FW_CFG_FILE, TPM_PPI_MEM_OFFSET); > > > > then when address is written into fwcfg, a callback in QEMU would be called > > due to > > > > /* Create a read-write fw_cfg file for Address */ > > fw_cfg_add_file_callback(s, TPM_PPI_ADDR_FW_CFG_FILE, ...); > > > > when CB is called you could map persistent overlay memory region > > (PPI memory device) at address written by firmware. > > > > As for OperationRegion, you can instruct firmware to patch address > > in AML as well, using bios_linker_loader_add_pointer() linker command. > > what I'd suggest is to use dedicated TPM SSDT table and > > at its start put a DWORD/QWORD variable where address would be patch
Re: [Qemu-devel] [PATCH v2 4/4] acpi: build TPM Physical Presence interface
On 02/12/2018 09:27 AM, Igor Mammedov wrote: On Fri, 9 Feb 2018 15:19:31 -0500 Stefan Berger wrote: On 01/16/2018 10:51 AM, Stefan Berger wrote: The TPM Physical Presence interface consists of an ACPI part, a shared memory part, and code in the firmware. Users can send messages to the firmware by writing a code into the shared memory through invoking the ACPI code. When a reboot happens, the firmware looks for the code and acts on it by sending sequences of commands to the TPM. This patch adds the ACPI code. It is similar to the one in EDK2 but doesn't assume that SMIs are necessary to use. It uses a similar datastructure for the shared memory as EDK2 does so that EDK2 and SeaBIOS could both make use of it. I extended the shared memory data structure with an array of 256 bytes, one for each code that could be implemented. The array contains flags describing the individual codes. This decouples the ACPI implementation from the firmware implementation. The underlying TCG specification is accessible from the following page. https://trustedcomputinggroup.org/tcg-physical-presence-interface-specification/ This patch implements version 1.30. I have played around with this patch and some modifications to EDK2. Though for EDK2 the question is whether to try to circumvent their current implementation that uses SMM or use SMM. With this patch so far I circumvent it, which is maybe not a good idea. The facts for EDK2's PPI: - from within the OS a PPI code is submitted to ACPI and ACPI enters SMM via an SMI and the PPI code is written into a UEFI variable. For this ACPI uses the memory are at 0x to pass parameters from the OS (via ACPI) to SMM. This is declared in ACPI with an OperationRegion() at that address. Once the machine is rebooted, UEFI reads the variable and finds the PPI code and reacts to it. The facts for SeaBIOS: - we cannot use the area at 0x since SeaBIOS is also mapped to this address. So we would have to use the PPI memory device's memory region, which is currently at 0xFED4 5000. SeaBIOS doesn't have persistent memory like NVRAM where it stores varaibles. So to pass the PPI code here the OS would invoke ACPI, which in turn would write the PPI code into the PPI memory directly. Upon reboot SeaBIOS would find the PPI code in the PPI memory device and react to it. The PPI device in this patch series allocates 0x400 bytes. 0x200 bytes are used by the OperationRegion() in this patch series. The rest was thought of for future extensions. To allow both firmwares to use PPI, we would need to be able to have the OperationRegion() be flexible and located at 0x for EDK2 and 0xFED4 5000 for SeaBIOS, per choice of the firmware. One way to achieve this would be to have the firmwares choose their operation region base address by writing into the PPI memory device at offset 0x200 (for example). A '1' there would mean that we want the OperationRegion() at 0x , and a '2' would mean at the base address of the PPI device (0xFED4 5000). This could be achieved by declaring a 2nd OperationRegion() in the ACPI code that is located at 0xFED4 5200 and we declare that 1st OperationRegion()'s address based on findings from there. Further, a flags variable at offset 0x201 could indicate whether an SMI is needed to enter SMM or not. Obviously, the ACPI code would become more complex to be able to support both firmwares at the same time. This is a lot of details but I rather post this description before posting more patches. To make these changes and get it to work with at least SeaBIOS is probably fairly easy. But is this acceptable? You could use hw/acpi/vmgenid.c as example, use following command to instruct firmware to write address back to QEMU: bios_linker_loader_write_pointer(linker, TMP_PPI_ADDR_FW_CFG_FILE, 0, sizeof(uint64_t), TPM_PPI_MEM_FW_CFG_FILE, TPM_PPI_MEM_OFFSET); then when address is written into fwcfg, a callback in QEMU would be called due to /* Create a read-write fw_cfg file for Address */ fw_cfg_add_file_callback(s, TPM_PPI_ADDR_FW_CFG_FILE, ...); when CB is called you could map persistent overlay memory region (PPI memory device) at address written by firmware. As for OperationRegion, you can instruct firmware to patch address in AML as well, using bios_linker_loader_add_pointer() linker command. what I'd suggest is to use dedicated TPM SSDT table and at its start put a DWORD/QWORD variable where address would be patched in and then use that variable as argument to OperationRegion ssdt = init_aml_allocator(); ... addr_offset = table_data->len + build_append_named_dword(ssdt->buf, "PPIA"); ... ... aml_operation_region("TPPI", AML_SYSTEM_MEMORY, aml_name("PPIA"), TPM_PPI_STRUCT_SIZE) ... bios_linker_loader_add_pointer(linker, ACPI_BUILD_TABLE_FILE, addr_offset, sizeof(uint32_t), TPM_PPI_MEM_FW_CFG_FILE, 0); This way both UEFI and Seabios would use the same im
Re: [Qemu-devel] [PATCH v2 4/4] acpi: build TPM Physical Presence interface
On Fri, 9 Feb 2018 15:19:31 -0500 Stefan Berger wrote: > On 01/16/2018 10:51 AM, Stefan Berger wrote: > > The TPM Physical Presence interface consists of an ACPI part, a shared > > memory part, and code in the firmware. Users can send messages to the > > firmware by writing a code into the shared memory through invoking the > > ACPI code. When a reboot happens, the firmware looks for the code and > > acts on it by sending sequences of commands to the TPM. > > > > This patch adds the ACPI code. It is similar to the one in EDK2 but doesn't > > assume that SMIs are necessary to use. It uses a similar datastructure for > > the shared memory as EDK2 does so that EDK2 and SeaBIOS could both make use > > of it. I extended the shared memory data structure with an array of 256 > > bytes, one for each code that could be implemented. The array contains > > flags describing the individual codes. This decouples the ACPI > > implementation > > from the firmware implementation. > > > > The underlying TCG specification is accessible from the following page. > > > > https://trustedcomputinggroup.org/tcg-physical-presence-interface-specification/ > > > > This patch implements version 1.30. > > I have played around with this patch and some modifications to EDK2. > Though for EDK2 the question is whether to try to circumvent their > current implementation that uses SMM or use SMM. With this patch so far > I circumvent it, which is maybe not a good idea. > > The facts for EDK2's PPI: > > - from within the OS a PPI code is submitted to ACPI and ACPI enters SMM > via an SMI and the PPI code is written into a UEFI variable. For this > ACPI uses the memory are at 0x to pass parameters from the OS > (via ACPI) to SMM. This is declared in ACPI with an OperationRegion() at > that address. Once the machine is rebooted, UEFI reads the variable and > finds the PPI code and reacts to it. > > > The facts for SeaBIOS: > - we cannot use the area at 0x since SeaBIOS is also mapped to > this address. So we would have to use the PPI memory device's memory > region, which is currently at 0xFED4 5000. SeaBIOS doesn't have > persistent memory like NVRAM where it stores varaibles. So to pass the > PPI code here the OS would invoke ACPI, which in turn would write the > PPI code into the PPI memory directly. Upon reboot SeaBIOS would find > the PPI code in the PPI memory device and react to it. > > The PPI device in this patch series allocates 0x400 bytes. 0x200 bytes > are used by the OperationRegion() in this patch series. The rest was > thought of for future extensions. > > To allow both firmwares to use PPI, we would need to be able to have the > OperationRegion() be flexible and located at 0x for EDK2 and > 0xFED4 5000 for SeaBIOS, per choice of the firmware. One way to achieve > this would be to have the firmwares choose their operation region base > address by writing into the PPI memory device at offset 0x200 (for > example). A '1' there would mean that we want the OperationRegion() at > 0x , and a '2' would mean at the base address of the PPI device > (0xFED4 5000). This could be achieved by declaring a 2nd > OperationRegion() in the ACPI code that is located at 0xFED4 5200 and we > declare that 1st OperationRegion()'s address based on findings from > there. Further, a flags variable at offset 0x201 could indicate whether > an SMI is needed to enter SMM or not. Obviously, the ACPI code would > become more complex to be able to support both firmwares at the same time. > This is a lot of details but I rather post this description before > posting more patches. To make these changes and get it to work with at > least SeaBIOS is probably fairly easy. But is this acceptable? You could use hw/acpi/vmgenid.c as example, use following command to instruct firmware to write address back to QEMU: bios_linker_loader_write_pointer(linker, TMP_PPI_ADDR_FW_CFG_FILE, 0, sizeof(uint64_t), TPM_PPI_MEM_FW_CFG_FILE, TPM_PPI_MEM_OFFSET); then when address is written into fwcfg, a callback in QEMU would be called due to /* Create a read-write fw_cfg file for Address */ fw_cfg_add_file_callback(s, TPM_PPI_ADDR_FW_CFG_FILE, ...); when CB is called you could map persistent overlay memory region (PPI memory device) at address written by firmware. As for OperationRegion, you can instruct firmware to patch address in AML as well, using bios_linker_loader_add_pointer() linker command. what I'd suggest is to use dedicated TPM SSDT table and at its start put a DWORD/QWORD variable where address would be patched in and then use that variable as argument to OperationRegion ssdt = init_aml_allocator(); ... addr_offset = table_data->len + build_append_named_dword(ssdt->buf, "PPIA"); ... ... aml_operation_region("TPPI", AML_SYSTEM_MEMORY, am
Re: [Qemu-devel] [PATCH v2 4/4] acpi: build TPM Physical Presence interface
On 01/16/2018 10:51 AM, Stefan Berger wrote: The TPM Physical Presence interface consists of an ACPI part, a shared memory part, and code in the firmware. Users can send messages to the firmware by writing a code into the shared memory through invoking the ACPI code. When a reboot happens, the firmware looks for the code and acts on it by sending sequences of commands to the TPM. This patch adds the ACPI code. It is similar to the one in EDK2 but doesn't assume that SMIs are necessary to use. It uses a similar datastructure for the shared memory as EDK2 does so that EDK2 and SeaBIOS could both make use of it. I extended the shared memory data structure with an array of 256 bytes, one for each code that could be implemented. The array contains flags describing the individual codes. This decouples the ACPI implementation from the firmware implementation. The underlying TCG specification is accessible from the following page. https://trustedcomputinggroup.org/tcg-physical-presence-interface-specification/ This patch implements version 1.30. I have played around with this patch and some modifications to EDK2. Though for EDK2 the question is whether to try to circumvent their current implementation that uses SMM or use SMM. With this patch so far I circumvent it, which is maybe not a good idea. The facts for EDK2's PPI: - from within the OS a PPI code is submitted to ACPI and ACPI enters SMM via an SMI and the PPI code is written into a UEFI variable. For this ACPI uses the memory are at 0x to pass parameters from the OS (via ACPI) to SMM. This is declared in ACPI with an OperationRegion() at that address. Once the machine is rebooted, UEFI reads the variable and finds the PPI code and reacts to it. The facts for SeaBIOS: - we cannot use the area at 0x since SeaBIOS is also mapped to this address. So we would have to use the PPI memory device's memory region, which is currently at 0xFED4 5000. SeaBIOS doesn't have persistent memory like NVRAM where it stores varaibles. So to pass the PPI code here the OS would invoke ACPI, which in turn would write the PPI code into the PPI memory directly. Upon reboot SeaBIOS would find the PPI code in the PPI memory device and react to it. The PPI device in this patch series allocates 0x400 bytes. 0x200 bytes are used by the OperationRegion() in this patch series. The rest was thought of for future extensions. To allow both firmwares to use PPI, we would need to be able to have the OperationRegion() be flexible and located at 0x for EDK2 and 0xFED4 5000 for SeaBIOS, per choice of the firmware. One way to achieve this would be to have the firmwares choose their operation region base address by writing into the PPI memory device at offset 0x200 (for example). A '1' there would mean that we want the OperationRegion() at 0x , and a '2' would mean at the base address of the PPI device (0xFED4 5000). This could be achieved by declaring a 2nd OperationRegion() in the ACPI code that is located at 0xFED4 5200 and we declare that 1st OperationRegion()'s address based on findings from there. Further, a flags variable at offset 0x201 could indicate whether an SMI is needed to enter SMM or not. Obviously, the ACPI code would become more complex to be able to support both firmwares at the same time. This is a lot of details but I rather post this description before posting more patches. To make these changes and get it to work with at least SeaBIOS is probably fairly easy. But is this acceptable? Stefan Signed-off-by: Stefan Berger --- v1->v2: - get rid of FAIL variable; function 5 was using it and always returns 0; the value is related to the ACPI function call not a possible failure of the TPM function call. - extend shared memory data structure with per-opcode entries holding flags and use those flags to determine what to return to caller - implement interface version 1.3 --- hw/i386/acpi-build.c| 273 include/hw/acpi/acpi-defs.h | 2 + include/hw/acpi/tpm.h | 31 + 3 files changed, 306 insertions(+) diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c index 522d6d2..f8c2d01 100644 --- a/hw/i386/acpi-build.c +++ b/hw/i386/acpi-build.c @@ -42,6 +42,7 @@ #include "hw/acpi/memory_hotplug.h" #include "sysemu/tpm.h" #include "hw/acpi/tpm.h" +#include "hw/tpm/tpm_ppi.h" #include "hw/acpi/vmgenid.h" #include "sysemu/tpm_backend.h" #include "hw/timer/mc146818rtc_regs.h" @@ -1860,6 +1861,276 @@ static Aml *build_q35_osc_method(void) } static void +build_tpm_ppi(Aml *dev, TPMVersion tpm_version) +{ +Aml *method, *field, *ifctx, *ifctx2, *ifctx3, *pak; + +aml_append(dev, + aml_operation_region("TPPI", AML_SYSTEM_MEMORY, +aml_int(TPM_PPI_ADDR_BASE), +TPM_PPI_STRUCT_SIZE)); + +fiel