[SeaBIOS] Saving a few bytes across a reboot
stefanb at linux.vnet.ibm.com
Wed Feb 7 17:44:35 CET 2018
On 02/07/2018 10:50 AM, Laszlo Ersek wrote:
> 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?
On the OS level it is presumably an operation that is reserved to the
admin to queue the operation.
I am not that familiar with UEFI and who is allowed to run code there
and what code it can execute. But UEFI seems to lock the variable that
holds that PPI code that tells it what to do after next reboot. So
presumably a UEFI module cannot modify that variable but can only read
it (and hopefully not manipulate NVRAM directly). If PPI was implemented
through a memory location where the code gets written to it could do
that likely easily (unless memory protections are setup by UEFI, which I
don't know), cause a reset and have UEFI execute on that code.
>>> 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?
Between OS and firmware.
> 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?'
The standard implies that ACPI is used for passing the parameters from
OS to the firmware:
> 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,
So SMM can verify whether the parameters it gets are valid. Whether now
the user wanted to set operation 0 but the ACPI code submitted 5 (Clear
TPM), would be a matter of verifying the ACPI code that's in-between. Is
an attack via ACPI manipulation through some UEFI module possible?
> - 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".
There are operations in the PPI that set and clear flags that either
enable prompting or disable prompting for the execution of a certain TPM
operation by the firmware. For full automation and eliminating user
interaction entirely one would issue the code(s) to disable the prompts
(that's what PHYSICAL_PRESENCE_FLAGS_VARIABLE in EDK2 is for), zap the
TPM, then possibly re-enable the prompts. A couple of reboots are necessary.
FYI: The 'physical presence' meant that a user had to be present at the
physical keyboard when at a certain stage after machine start and then,
when entering the firmware, could run certain TPM operations that are
then enabled but also only possibly when in the firmware. When doing
this via a remote screen, the firmware may not support running these
commands since the physical keyboard or some other button wasn't
touched. Now with the PPI automation holding a key or button may not be
> 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?
On the OS level it must remain a privileged operation of an admin to
issue these PPI codes. That it is a privileged operation is implemented
by the OS and I don't think we need to do anything. What we would want
to prevent is abuse by a module that the firmware executes for example.
I think this is the driving force for a UEFI variable and the fact that
it's being locked (and later on unlocked so SMM mode can write to it ?)
As for the use case, I would say it's automation on the OS level. From
that perspective it's support could probably be deferred, which may
eliminate at least the SMM part. However, UEFI uses the PPI mechanisms
itself to issue certain commands when interacting with its menu. I am
not sure whether SMM code is involved here... but for being able to use
UEFI and TPM 2 at least for the UEFI support the PPI part needs to be
there, otherwise the menu items one gets won't do anything. [The
question is does UEFI execute ACPI or write directly in the UEFI
varaible? My guess is the latter.]
> (Sorry if this email is too long and confusing! I'm confused.)
Me too. I am not clear on specifics in UEFI, such as memory protections
setup while a module is running in UEFI. Is NVRAM protected from
overwrite? Who can run a module in UEFI? Does it need to be signed ?
More information about the SeaBIOS