electrickite / luks-tpm2

Utility to manage LUKS keys sealed by a TPM 2.0
GNU General Public License v3.0
50 stars 9 forks source link

Automatic resealing after update #8

Closed grawity closed 4 years ago

grawity commented 4 years ago

I just discovered this project, but I have been using your mkinitcpio-tpm2-encrypt with a few custom shellscripts and hooks to automate the key resealing.

To solve the problem of PCRs changing after a kernel upgrade, I ended up writing a tool that analyzes the TPM event log and "replays" it to calculate the new PCR: https://github.com/grawity/tpm_futurepcr

There are some hacks involved in the process (the recovery passphrase ought to be mandatory), and currently it only handles kernels started by systemd-boot, but so far it has been successfully handling both kernel and sd-boot upgrades, so it might be a viable alternative to luks-tpm2 temp.

electrickite commented 4 years ago

Sounds interesting. I would want anything added to luks-tpm2 to support general use cases and not rely on specific environments as much as possible (systemd-boot). Could your approach be made generic?

As a side note, I have not been using the temp/reset flow in luks-tpms2 in my own kernel update cycle for some time. Now, I simply do not use the kernel PCR to seal the LUKS key: I only use PCRs 0, 2, and 7. This ensures that my secure boot UEFI settings have not changed, and since I sign my kernels for secure boot, I can be reasonably sure that any kernel that can boot the system should be able to unseal the key.

grawity commented 4 years ago

Sounds interesting. I would want anything added to luks-tpm2 to support general use cases and not rely on specific environments as much as possible (systemd-boot). Could your approach be made generic?

The main feature is already fully generic, as it just recalculates hashes for every *.efi binary that was launched (standard EV_EFI_BOOT_SERVICES_APPLICATION events) – so it should work the same with any boot manager that starts vmlinuz via "EFI stub" and not via the older Linux-specific protocol. (I have not tested this with GRUB on UEFI, so I don't know what events if any are logged when GRUB starts the kernel.)

The only systemd-specific parts in the current code are for recalculating hashes for the kernel command line (which systemd-boot measures into PCR[8] as EV_IPL). The location where the "correct" command line is stored is obviously bootloader-specific... since I use aur/mksignkernels for Secure Boot, I decided to extract it out of the signed .efi blob, but that could easily be replaced or even removed entirely – it is completely independent from the main .efi re-hashing described above.

Now, I simply do not use the kernel PCR to seal the LUKS key: I only use PCRs 0, 2, and 7. This ensures that my secure boot UEFI settings have not changed, and since I sign my kernels for secure boot, I can be reasonably sure that any kernel that can boot the system should be able to unseal the key.

My concern with this method would be that if you use a separate boot manager (like grub or systemd-boot), then it doesn't protect you from someone booting the system with init=/bin/bash and bypassing system login while still having the rootfs unlocked.

(Edit: I just noticed that the systemd-provided EFI stub used by mksignkernels is supposed to force using the embedded command line when in Secure Boot mode, but for some reason I keep remembering that I was able to change it from within systemd-boot anyway.)

Though I think I'll be forced to use the built-in UEFI boot manager myself anyway (as inconvenient as it is on HP, it's the only way to make Windows use PCR0/2/7 for BitLocker) and leave systemd-boot for emergencies only...

wiktor-k commented 4 years ago

@electrickite Isn't PCR 1 secure boot settings? (it's called BIOS configuration on this page).

(I like your minimal threat model PCRs, I'm using PCRs 0-7 and it's a chore to re-reset the key every kernel upgrade and it doesn't add anything to security)

electrickite commented 4 years ago

@wiktor-k The PCRs used by different systems seem to be somewhat inconsistent and do not always conform to the spec. On my machine, changing the secure boot settings causes the value in PCR7 to change.

electrickite commented 4 years ago

@grawity I see you've been making some progress on tpm_futurepcr. Do you think it's work exploring integrating with this project?

grawity commented 4 years ago

@wiktor-k That page is misleading -- there are two different specs for BIOS and UEFI systems, and they have somewhat different PCR assignments. UEFI includes a whole list of new event types as well. (I don't remember if the BIOS spec is different for TPM 1.x vs 2.x, though.)

For example, in UEFI usage, PCR 7 is specifically just the Secure Boot-related variables (db, KEK, etc) and nothing else, whereas PCR 1 is general boot-related variables like BootCurrent and Boot000x.

(Side note: since tpm_futurepcr works by parsing and replaying the TPM "event log", you can run it with --verbose to generally see what was logged into each PCR.)

electrickite commented 4 years ago

@grawity Version 2.1.0 adds support for computing PCR values with an external command. tpm_futurepcr is used as an example :smile: