[SeaBIOS] Saving a few bytes across a reboot

Laszlo Ersek lersek at redhat.com
Wed Feb 7 16:50:49 CET 2018

On 02/07/18 15:57, Stefan Berger wrote:
> On 02/07/2018 09:18 AM, Laszlo Ersek wrote:
>> On 02/07/18 14:51, Stefan Berger wrote:

>>> To support SeaBIOS as well, we would have to be
>>> able to distinguish a BIOS from the UEFI on the QEMU level so that we
>>> could produce different ACPI
>> Yes and no,
>>> (no SMI and different OperationRegion than
>>> 0xFFFF 0000 for SeaBIOS),
>> "yes" with regard to the SMM difference, "no" with regard to the
>> operation region. We have an ACPI linker/loader command that makes the
>> firmware basically just allocate memory, and we have two other ACPI
>> linker/loader commands that (a) patch the allocation address into other
>> ACPI artifacts, (b) return the allocation address to QEMU (for device
>> emulation purposes), if necessary.
> I thought about allowing the firmware to configure the memory region to
> use for the PPI interface. UEFI would say 0xFFFF 0000, SeaBIOS would
> choose some other area (0xFEF4 5000). Does the ACPI patcher handle this
> case or does the address patching have to be set up while building the
> tables in QEMU? If latter, then we would have to know in QEMU whether
> it's going to be BIOS or UEFI as firmware. I have tried a lot of things
> in the recent past, but I forgot whether this type of patching is possible.

The ACPI linker/loader commands are typically added to the "linker
script" in the very functions that build the ACPI payload.

And, distinguishing the firmwares is not necessary just for this; the
point of the firmware-side allocation is that QEMU does not dictate the
address. Each firmware is expected to use its own memory allocation
service, which in turn will ensure that the runtime OS stays away from
the allocated area. So the allocation address is ultimately determined
by the firmware.

The other two commands make the firmware patch the actual allocation
address (whatever it may be) into other ACPI artifacts, and make the
firmware pass the allocation address (whatever it may be) back to QEMU.

>> My operating knowledge about the TPM had been that
>>    Components measure stuff into PCRs, and if any untrusted agent messes
>>    with those measurements, for example by directly writing to the PCRs,
>>    then the TPM will simply not unseal its secrets, hence such tampering
>>    is self-defeating for those agents.
>> While this might be correct (I hope it is correct!), the *PPI* part of
>> TPM appears entirely different. In fact I don't have the slightest idea
>> *why* PPI is lumped together with the TPM.
> The physical presence interface allows *automation of TPM operations and
> changing the TPM's state* (such as clearing all keys) that are typically
> only possible via interaction with the TPM menu in the firmware. Think
> of it as some TPM operations that can only run successfully while the
> system runs the firmware. Once the firmware has given control to the
> next stage (bootloader, kernel) these operations are not possible
> anymore since the firmware has execute some TPM commands that put the
> TPM into a state so it wouldn't allow those operations anymore.

OK, but if the OS is allowed to modify this set of "queued operations",
then what protection is expected of SMM? Whether you can modify the TPM
directly, or queue random commands for it at libery, what's the difference?

>> Can you explain in more detail what the PPI operations are, and why they
>> need protection, from what agents exactly? What is the purported
>> lifecycle of such PPI operations?
> With the clearing of the TPM one would loose all keys associated with
> the TPM. So you don't want some software module to be able to set such a
> 'code', reset the machine, and the user looses all keys on the way. The
> control has to be strongly with the admin.

Where is this barrier erected, between OS and firmware, or between
privileged and non-privileged OS user?

SMM is only relevant if the barrier is expected between OS and firmware;
i.e. you want to constrain the OS kernel to a subset of valid
operations. If the barrier is between privileged and non-privileged OS
user, then the implementation belongs in the OS kernel, since mere users
don't have direct hardware access anyway.

> Also, to prevent fumbling with the variables, UEFI seems to make the variable read-only.

That seems to imply the barrier is between OS kernel and firmware.

> I am wondering whether a malicious UEFI module could be written that
> patches the ACPI tables and does what it wants when it comes to these
> early TPM operations, rather than what the admin wants.

This is a good point, and it applies to more than just ACPI. The answer
is that it doesn't matter what *any* OS level code does -- as long as
the barrier is expected between OS and firmware --, because the SMM code
in the firmware must perform *complete* validation / verification of the

Another example is the UEFI runtime variable services. In the
SMM_REQUIRE build of OVMF, those services are split to two privilege
levels, "runtime DXE driver" and "SMM driver". The runtime DXE driver
layer provides the OS with the UEFI interface, but internally it only
formats a request buffer (serializes the variable operation), and raises
an SMI. Once in SMM, the "SMM driver" layer de-serializes and verifies
the request, and performs it if it's valid. If the OS messes with the
"runtime DXE driver" half of the service (because it can -- that layer
lives in simple system memory), the worst the OS can do is submit a
crafted request buffer to the SMM half. The SMM half in turn *always*
has to evaluate the request buffer as if it came from a malicious agent
(an attacker). In other words, the "runtime DXE driver" half is just a
convenience for the OS, for preparing a well-formed request buffer.
(Which can still be rejected, of course, if the request doesn't pass
higher-level authentication and such).

The same applies to your example. The queued PPI operations must be
entirely validated in SMM; the ACPI code for formatting / submitting
them is just a convenience. If the trust is based in the ACPI code, then
the security model is busted. This is why I ask above, 'if the OS is
allowed to modify this set of "queued operations", then what protection
is expected of SMM?'

Again, we have to see where the barrier is, between OS and firmware, or
between OS-level users:

- In both cases, 3rd party UEFI apps / driver are considered equally
  privileged to the OS kernel;

- in the OS<->firmware barrier case, SMM is required, and UEFI apps and
  the OS kernel are similarly restricted to submitting requests to SMM,
  and all the business verification belongs in SMM,

- in the "barrier between OS-level users" case, SMM is not needed; UEFI
  apps and the OS kernel are equally allowed to access hardware
  directly, and non-privileged users are restricted by the OS kernel

> Its ACPI code would just enter SMM and instruct to clear the TPM upon
> reboot whenever invoked. If that's possible then we may have 'only'
> moved the problem from the secured UEFI variable to patching ACPI
> code, which is more work of course. (We need signed ACPI tables...)

Right; if you want to prevent UEFI apps (equivalently, the OS kernel)
from queueing such a "zap TPM" operation, then SMM is required, *and*
the code running in SMM needs *some* mechanism to authenticate the
request (beyond checking for well-formedness).

For example, regarding UEFI variables that are related to Secure Boot,
variable update requests (from the OS or 3rd party UEFI apps/drivers)
are verified (in SMM) by checking digital signatures on those requests.

... Judged purely from the *name* of the feature, "Physical Presence
Interface", I think the idea is that a physically present user is
allowed to issue / queue a "zap TPM" request. The question then becomes
how you define "physically present".

OVMF currently equates all UEFI-level code with a user being physically
present; see the UserPhysicalPresent() implementation in
"OvmfPkg/Library/PlatformSecureLib/PlatformSecureLib.c". (The
PlatformSecureLib class "Provides a platform-specific method to enable
Secure Boot Custom Mode setup", which is not precisely your use case,
but similarly privileged.) I wouldn't know how to define physical
presence otherwise, in virtual firmware. If you can figure out a way to
deduce physical presence in the guest *OS*, then we can say the barrier
is between OS-level users, not between OS and firmware, and then SMM is
not needed.

What do we want to *use* PPI for? What agents should *not* be allowed to
queue a "zap TPM" operation?

(Sorry if this email is too long and confusing! I'm confused.)


More information about the SeaBIOS mailing list