https://mjg59.dreamwidth.org/58077.html
Account name: [ ] Password [ ] [Log in]
(OpenID?) (Forgot it?) [ ] Remember Me
You're viewing [personal profile] mjg59's journal
Create a Dreamwidth Account Learn More
[ ] [Interest ] [Go]
Reload page in style: site light
Matthew Garrett
Update on Linux hibernation support when lockdown is enabled
Update on Linux hibernation support when lockdown is enabled
Dec. 30th, 2021 07:00 pm
[personal profile] mjg59
Some time back I wrote up a description of my proposed (and
implemented) solution for making hibernation work under Linux even
within the bounds of the integrity model. It's been a while, so
here's an update.
The first is that localities just aren't an option. It turns out that
they're optional in the spec, and TPMs are entirely permitted to say
they don't support them. The only time they're likely to work is on
platforms that support DRTM implementations like TXT. Most consumer
hardware doesn't fall into that category, so we don't get to use that
solution. Unfortunate, but, well.
The second is that I'd ignored an attack vector. If the kernel is
configured to restrict access to PCR 23, then yes, an attacker is
never able to modify PCR 23 to be in the same state it would be if
hibernation were occurring and the key certification data will fail
to validate. Unfortunately, an attacker could simply boot into an
older kernel that didn't implement the PCR 23 restriction, and could
fake things up there (yes, this is getting a bit convoluted, but the
entire point here is to make this impossible rather than just
awkward). Once PCR 23 was in the correct state, they would then be
able to write out a new swap image, boot into a new kernel that
supported the secure hibernation solution, and have that resume
successfully in the (incorrect) belief that the image was written out
in a secure environment.
This felt like an awkward problem to fix. We need to be able to
distinguish between the kernel having modified the PCRs and userland
having modified the PCRs, and we need to be able to do this without
modifying any kernels that have already been released[1]. The normal
approach to determining whether an event occurred in a specific phase
of the boot process is to "cap" the PCR - extend it with a known
value that indicates a transition between stages of the boot process.
Any events that occur before the cap event must have occurred in the
previous stage of boot, and since the final PCR value depends on the
order of measurements and not just the contents of those
measurements, if a PCR is capped before userland runs, userland can't
fake the same PCR value afterwards. If Linux capped a PCR before
userland started running, we'd be able to place a measurement there
before the cap occurred and then prove that that extension occurred
before userland had the opportunity to interfere. We could simply
place a statement that the kernel supported the PCR 23 restrictions
there, and we'd be fine.
Unfortunately Linux doesn't currently do this, and adding support for
doing so doesn't fix the problem - if an attacker boots a kernel that
doesn't cap a PCR, they can just cap it themselves from userland. So,
we're faced with the same problem: booting an older kernel allows the
system to be placed in an identical state to the current kernel, and
a fake hibernation image can be written out. Solving this required a
PCR that was being modified after kernel code was running, but before
userland was started, even with existing kernels.
Thankfully, there is one! PCR 5 is defined as containing measurements
related to boot management configuration and data. One of the
measurements it contains is the result of the UEFI ExitBootServices()
call. ExitBootServices() is called at the transition from the UEFI
boot environment to the running OS, and the kernel contains code that
executes before it. So, if we measure an assertion regarding whether
or not we support restricted access to PCR 23 into PCR 5 before we
call ExitBootServices(), this will prevent userspace from spoofing us
(because userspace will only be able to extend PCR 5 after the
firmware extended PCR 5 in response to ExitBootServices() being
called). Obviously this depends on the firmware actually performing
the PCR 5 extension when ExitBootServices() is called, but if
firmware's out of spec then I don't think there's any real
expectation of it being secure enough for any of this to buy you
anything anyway.
My current tree is here, but there's a couple of things I want to do
before submitting it, including ensuring that the key material is
wiped from RAM after use (otherwise it could potentially be scraped
out and used to generate another image afterwards) and, uh, actually
making sure this works (I no longer have the machine I was previously
using for testing, and switching my other dev machine over to TPM 2
firmware is proving troublesome, so I need to pull another machine
out of the stack and reimage it).
[1] The linear nature of time makes feature development much more
frustrating
* Previous Entry
* Add Memory
* Share This Entry
* Next Entry
---------------------------------------------------------------------
* 5 comments
* Reply
---------------------------------------------------------------------
Flat | Top-Level Comments Only
no subject
Date: 2021-12-31 12:06 pm (UTC)
bens_dad: (Default)
From: [personal profile] bens_dad
`[1] The linear nature of time makes feature development much more
frustrating'
I don't envy you if you are trying to protect against time-machines.
([personal profile] fanf did think about protection against attacks
by ntp time-servers, but that should be easier.)
* Link
* Reply
encrypted and authenticated
Date: 2022-01-01 01:06 am (UTC)
From: (Anonymous)
Does the use of TPM to seal a key adequately address the authenticity
of the hibernation image? I'm aware of prior effort https://lkml.org/
lkml/2019/7/10/601 in which it was going to be authenticated by HMAC.
It was suggested elsewhere https://lkml.org/lkml/2019/1/8/1280 to use
AES-GCM. -cmurf
* Link
* Reply
* Thread
* Hide 1 comment
* Show 1 comment
Re: encrypted and authenticated
Date: 2022-01-01 01:20 am (UTC)
From: [personal profile] mjg59
I've just updated (without any testing) the patchset to use hmac with
a TPM-sealed key. Given the use case the guarantees should be pretty
similar regardless, but hmac is easier to reason about.
* Link
* Reply
* Thread from start
* Parent
no subject
Date: 2022-01-01 02:44 am (UTC)
From: (Anonymous)
What stops an attacker from simply booting a modified kernel that
does what old and new kernels don't (and then kexec-ing the new
kernel they're trying to fool)?
* Link
* Reply
* Thread
* Hide 1 comment
* Show 1 comment
no subject
Date: 2022-01-01 04:11 am (UTC)
From: [personal profile] mjg59
Lockdown is predicated on the idea that you have some mechanism to
ensure that only trustworthy kernels are booted in the first place,
so to do that you'd have to disable secure boot (and in that case,
you could just boot whatever you wanted in the first place, no need
to subvert hibernation in the process)
* Link
* Reply
* Thread from start
* Parent
* Previous Entry
* Add Memory
* Share This Entry
* Next Entry
* 5 comments
* Reply
Flat | Top-Level Comments Only
Profile
Matthew Garrett
About Matthew
Power management, mobile and firmware developer on Linux. Security
developer at Aurora. Ex-biologist. [personal profile] mjg59 on
Twitter. Content here should not be interpreted as the opinion of my
employer.
Page Summary
* [personal profile] bens_dad - (no subject)
* (Anonymous) - encrypted and authenticated
* (Anonymous) - (no subject)
Active Entries
* 1: Update on Linux hibernation support when lockdown is enabled
* 2: Letting Birds scooters fly free
* 3: Does free software benefit from ML models being derived works
of training data?
* 4: Samsung laptop bug is not Linux specific
* 5: Mike Lindell's Cyber "Evidence"
* 6: Linux kernel lockdown, integrity, and confidentiality
* 7: Making hibernation work under Linux Lockdown
* 8: Producing a trustworthy x86-based Linux appliance
* 9: Feeding the trolls
* 10: Working with the kernel keyring
Expand Cut Tags
No cut tags
Top of page