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

2018-02-15 Thread Stefan Berger

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

2018-02-14 Thread Kevin O'Connor
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

2018-02-13 Thread Stefan Berger

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 / 

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

2018-02-13 Thread Laszlo Ersek
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 

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

2018-02-13 Thread Stefan Berger

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 

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

2018-02-13 Thread Laszlo Ersek
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

2018-02-13 Thread Kevin O'Connor
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

2018-02-13 Thread Laszlo Ersek
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

2018-02-13 Thread Laszlo Ersek
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 

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

2018-02-13 Thread Igor Mammedov
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

2018-02-13 Thread Igor Mammedov
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 

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

2018-02-13 Thread Laszlo Ersek
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) 

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

2018-02-13 Thread Laszlo Ersek
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 

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

2018-02-13 Thread Igor Mammedov
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

2018-02-13 Thread Laszlo Ersek
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

2018-02-13 Thread Igor Mammedov
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

2018-02-13 Thread Igor Mammedov
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 

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

2018-02-12 Thread Stefan Berger

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

2018-02-12 Thread Kevin O'Connor
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

2018-02-12 Thread Stefan Berger

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

2018-02-12 Thread Kevin O'Connor
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

2018-02-12 Thread Stefan Berger

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)
   ...
   

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

2018-02-12 Thread Igor Mammedov
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 

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

2018-02-12 Thread Stefan Berger

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 

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

2018-02-12 Thread Igor Mammedov
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", 

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

2018-02-09 Thread Stefan Berger

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),
+