latchset / clevis

Automated Encryption Framework
GNU General Public License v3.0
838 stars 99 forks source link

Support for TPM 1.x #84

Open petasis opened 5 years ago

petasis commented 5 years ago

Hi all,

Is there any change of adding support for TPM 1.x, for those stacked with an old mainboard/bios that does not support TPM 2.0?

martinezjavier commented 5 years ago

@petasis I don't know of anyone working on this in the short, but if someone is interested patches are welcomed!

The pin is called tpm2 and not tpm to make it clear that it only supports TPM 2.0. Since TPM 2.0 is not backward compatible with TPM 1.2 (both the programming model and software stack is different) a tpm1 pin has to be implemented for TPM 1.2 support.

Something that would make TPM 1.2 support more complicated is the fact that the TPM 1.2 software stack (trousers) requires a user-space daemon (tcsd) which would have to run in the initramfs.

That's not the case for TPM 2.0 since clevis is using the kernel-space resource manager (/dev/tpmrm?). But that's not available for TPM 1.2 chips.

gastamper commented 5 years ago

Not trying to plug my own work but @petasis, consider this project if it fits your needs. It's not clevis, but I did use clevis as the basis for the dracut hooks.

@martinezjavier It's semi-tangential but you don't actually have to have trousers/tcsd running in order to just read from TPM 1.2, which is all we generally care about at boot time. See this binary for an example, which is what I used in the above-linked project.

phoenix-frozen commented 3 years ago

Can confirm, I used some tooling during my PhD that just talked to /dev/tpm0 without needing any of the usual TPM 1.2 TSS. No idea what happened to that tooling now, but I don't think it ships in Debian anymore. I think the core library those tools were based on was called "libtpm", but I can't find it now.

oldium commented 5 months ago

I have a working Clevis support for TPM 1.2 (currently modified directly in file system), so I plan to create a Pull Request this week. I am using tpm_sealdata and tpm_unsealdata with “well-known SRK password” (-z parameter to tpm_sealdata and tpm_unsealdata) to prevent any further password prompt during boot. The encryption and decryption can use PCR registers (-p parameter to tpm_sealdata). Currently it works inside normal initramfs, not with Dracut.

oldium commented 5 months ago

You can follow (work in progress) my development branch https://github.com/oldium/clevis/commits/feature/tpm1/.

The script uses tpm_sealdata and tpm_unsealdata tools to encrypt and decrypt secrets. It also uses “well-known” SRK password to prevent further password prompt during login (initially tpm_takeownership -z has to be used when taking TPM ownership to make this work).

What works:

Status:

oldium commented 5 months ago

As this is work-in-progress, I plan to change the encryption algorithm tomorrow - currently the password is sealed directly with tpm_sealdata. I will do what TPM2 does (I understand more what it does and why now 😅) - it generates a cryptographically strong random encryption key (for encrypting the password) and encrypts the key with TPM afterwards. And during decrypting it decrypts the key first with TPM and afterwards decrypts the password with the decrypted key.

EDIT: it seems I do not get it fully yet, so investigating...

EDIT2: tpm2 really seals the encryption key (JWK) used to encrypt the password and unseals the JWK afterwards. This can be done with tpm_sealdata and tpm_unsealdata too.

oldium commented 5 months ago

Done. The code is now sealing JWK (which is used to encrypt the password) into TPM similar to what the tpm2 pin does.

oldium commented 5 months ago

TPM1 pin work is done, so now the Dracut and Systemd parts...

oldium commented 2 months ago

Updated systemd dependencies (so that tcsd is able to start before other services - same as clevis). I will play with Dracut now, I have a VM with sofware-emulated TPM 1.2, so it should be safe 😊

Cavaler commented 1 month ago

Is there any progress on this? Is there any way we could help?

oldium commented 1 month ago

I have basic setup of VM already (dracut with simulated TPM1.2) for testing, so I just need to find some time to finish this.

oldium commented 1 month ago

Just wanted to give a small heads-up. Dracut with SystemD is locally working for me. Work is not yet committed; I need to test Dracut without SystemD and retest initramfs-tools with the latest changes. I would like to finish it this week.

oldium commented 1 month ago

Most of the work is done.

I also plan to fix how the non-SystemD Dracut unlocker introduced in v20 works before finishing the pull request. The unlocker currently ignores rd.luks variables completely. It currently runs in the initqueue/settled and initqueue/online Dracut hooks and calls clevis luks unlock, I plan to inject it into the Dracut cryptroot-ask flow, so that the script prepares a pipe in /tmp/luks.keys and when the cryptroot-ask tries to read the key file (a prepared pipe in this case), it will retrieve the stored clevis password.

This is like in the initramfs-tools unlocking flow, which uses analogous approach - it supplies the password instead of trying to unlock the disk directly.

oldium commented 4 weeks ago

Unlocking via pipe works (code in wip branch here - the unlocking loop is almost copy-paste from initramfs-tools now, so it needs to share the code instead). I need to clean-up, split the patches, and retest all again.

oldium commented 3 weeks ago

Done. Enjoy 😁

oldium commented 3 weeks ago

Release package for the latest v20 version with TPM 1.2 updates compiled for Debian 12 (bookworm) on amd64 arch can be found here. I just took Trixie v20 sources, updated them and compiled on Debian 12.

Edit: rebuilt packages with +tpm1 suffix.