On my system, I used `tpm2-measure-pcr=yes` in `/etc/crypttab.initramfs`, then used `--tpm2-pcrs=0+2+7+15:sha256=0000000000000000000000000000000000000000000000000000000000000000` with `systemd-cryptenroll`.
As soon as a volume is decrypted, initrd will write `volume-key` to PCR 15, so any further executables can no longer access the data stored in the TPM.
When I first read about TPM-based FDE on Linux[0], I was excited that the systemd guys were finally taking a step in the right direction - BitLocker/FileVault were standard on Windows/macOS for a long time by that point. FDE should be secure by default, dead-simple to set up (e.g. a checkbox in the installer that defaults to "enabled"), and painless for everyday use.
Then I read about the implementation details[0], and it's a complex bloody mess with an unending chain of brittle steps and edge cases, that are begging for a mistake and get exploited. So here we are.
I'm convinced that "measure the kernel" into "measure the initrd" into "show login screen" is all it should take.
I don't understand why anyone would use passwordless disk encryption. It just seems inherently vulnerable, especially with the threat model of physical compromise.
Entering a password on boot isn't even that much work
Seems like this could be easily mitigated with a read only root filesystem using dm verity
Store the root hash of the dm verity formatted rootfs in the PCR. If a malicious partition is presented to initrd, its root hash will not match the trusted one stored in the TPM.
Or if you need a writeable rootfs, use fs verity and store the signature of init into the PCR. The trusted init signature won’t match signature of malicious init.
LUKS for encryption and verity for integrity/verification.
You can mitigate this by including PCRs that sign the kernel and initrd, however it means whenever you update you need to unlock manually. On Redhat-based distros this can be done with PCRs 8 and 9, though IIRC this may change on other distros.
Also AFAIK there is no standard way to guess the new PCRs on reboot so you can't pre-update them before rebooting. So you either need to unlock manually or use a network decryption like dracut-sshd.
I was wondering about the solution you propose which seems a bit complicated to me. Here's my idea, please tell me if I'm completely wrong here.
What if I put a file on the root filesystem with some random content (say 32 bytes), let's name it /prehash. I hash this file (sha256, blake2, whatever). Then, in the signed initrd, just after mounting the filesystem, I assert that hash(/prehash) == expected_hash or crash the system otherwise. Do you think it would be enough to fix the issue?
The "mitigation" itself is still not very safe if you're paranoid about governments or very motivated organisations. The extra step of checking PCR12 is performed by the initrd that you trust because it's signed by a private key that has probably leaked to every serious hacking corp / government. They can just boot their own signed initrd and kindly ask the TPM that will oblige.
I personally replace the firmware certificates (PK, KEK, db, dbx, …) with my own and sign every kernel/initrd update, I also unlock my disks with a passphrase anyways, but I'm on the fence WRT if it's more secure than TPM.
Yes in theory TPM key extraction is feasible (and even easy if it's performed by a chip other than your CPU https://pulsesecurity.co.nz/articles/TPM-sniffing ) but it is harder than filming/watching you type the passphrase or installing a discrete key-logger ?
> You are safe if you additionally use a pin to unlock your TPM
Does the default configuration not somehow tangle a user-entered password to authentication against the TPM?
That's still not perfect (i.e. how do you make PIN/password entry non-keyloggable), but anything else, in particular extending the trusted computing base to the entire kernel and the hardware it runs on and hoping that they will both be bug-free and impossible to impersonate, seems like a bad idea.
The TPM is also in a much better position to properly velocity check PIN/password entries than the OS.
So if you use this PCR state machine, the problem is that the step before initrd doesn't require the correct password to move the PCR forward? It accepts any password that decrypts the next stage, which didn't have its integrity verified here.
Seems there are multiple ways of solving this, and adding integrity checks is only one. It could also let the TPM verify the disk decryption password (when it's needed.)
The other option is to have an intrusion prevention switch or two in the case so the TPM locks itself in some way and the machine refuses to boot at all without some PKI attestation.
Personally i would like a way to use TMP2 (with PIN) + password. (i.e. mode where PIN is derived from the password, but is also used to encrypt), so that i do not have to trust the TPM manufacturer.
Hah, my gist from 2022 is on this post as a "broken guide". I'd disagree in saying it is broken. It works just fine and I flat out say at the top to not use it if you are worried about a cold boot attack on your hardware.
Bypassing disk encryption on systems with automatic TPM2 unlock
(oddlama.org)189 points by arjvik 17 January 2025 | 107 comments
Comments
As soon as a volume is decrypted, initrd will write `volume-key` to PCR 15, so any further executables can no longer access the data stored in the TPM.
[0]: https://0pointer.de/blog/brave-new-trusted-boot-world.html
Then I read about the implementation details[0], and it's a complex bloody mess with an unending chain of brittle steps and edge cases, that are begging for a mistake and get exploited. So here we are.
I'm convinced that "measure the kernel" into "measure the initrd" into "show login screen" is all it should take.
Entering a password on boot isn't even that much work
Store the root hash of the dm verity formatted rootfs in the PCR. If a malicious partition is presented to initrd, its root hash will not match the trusted one stored in the TPM.
Or if you need a writeable rootfs, use fs verity and store the signature of init into the PCR. The trusted init signature won’t match signature of malicious init.
LUKS for encryption and verity for integrity/verification.
Also AFAIK there is no standard way to guess the new PCRs on reboot so you can't pre-update them before rebooting. So you either need to unlock manually or use a network decryption like dracut-sshd.
I am the author of one of the older guides https://blastrock.github.io/fde-tpm-sb.html .
I was wondering about the solution you propose which seems a bit complicated to me. Here's my idea, please tell me if I'm completely wrong here.
What if I put a file on the root filesystem with some random content (say 32 bytes), let's name it /prehash. I hash this file (sha256, blake2, whatever). Then, in the signed initrd, just after mounting the filesystem, I assert that hash(/prehash) == expected_hash or crash the system otherwise. Do you think it would be enough to fix the issue?
I personally replace the firmware certificates (PK, KEK, db, dbx, …) with my own and sign every kernel/initrd update, I also unlock my disks with a passphrase anyways, but I'm on the fence WRT if it's more secure than TPM.
Yes in theory TPM key extraction is feasible (and even easy if it's performed by a chip other than your CPU https://pulsesecurity.co.nz/articles/TPM-sniffing ) but it is harder than filming/watching you type the passphrase or installing a discrete key-logger ?
Does the default configuration not somehow tangle a user-entered password to authentication against the TPM?
That's still not perfect (i.e. how do you make PIN/password entry non-keyloggable), but anything else, in particular extending the trusted computing base to the entire kernel and the hardware it runs on and hoping that they will both be bug-free and impossible to impersonate, seems like a bad idea.
The TPM is also in a much better position to properly velocity check PIN/password entries than the OS.
So if you use this PCR state machine, the problem is that the step before initrd doesn't require the correct password to move the PCR forward? It accepts any password that decrypts the next stage, which didn't have its integrity verified here.
Seems there are multiple ways of solving this, and adding integrity checks is only one. It could also let the TPM verify the disk decryption password (when it's needed.)
Edit: never mind, I think it's still vulnerable.
I recently changed motherboard on my laptop, had the bitlocker key if not I was told I'll have to reinstall Windows all over again.
Even with the key, one must decrypt and re-encrypt.
If someone steals the NAS how easily can they get to the data? Assuming volumes are encrypted, but the are automatically mounted on boot?
How to ensure the data is safe in case of theft.