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