rust-u2f icon indicating copy to clipboard operation
rust-u2f copied to clipboard

TPM2 Support

Open danstiner opened this issue 2 years ago • 2 comments

Currently we store keys in the user's keychain, or if that's not available just in a file in their home directory. This is sufficient for many use cases, such as providing a 2nd factor that is phishing resistant. Passwordless login as allowed in the newer FIDO2 specification is different however, it acts as two factors simultaneously, being both something you have (the device storing secret keys) and then either one thing you know (pin based unlock) or one thing you are (biometric unlock).

Security concerns

For passwordless login, some sites may require that secrets cannot be copied to another device in order to have a strong guarantee you are using the exact same device to login that you originally used to register for the site. The only way to reliably accomplish this is to make the secrets not accessible to any software on the computer, and the only way to do that I am aware of is doing the encryption and signing entirely in hardware. This is possible with the newer TPM2 standard and with ARM's secure enclave approach.

The threat model is other software on the computer with access to the user's session stealing private keys. Storing key in a TPM prevents copying them, but such an attacker would likely be able to access the TPM also and ask it to use the secrets to sign whatever it wants. This effectively lets the attacker authenticate as the user whenever they want, as long as access to the user's session is maintained.

To have equivalent security to a real hardware authenticator, we basically would need the same architecture. Namely a TPM or secure enclave that requires a manual unlock for each signing via a special button or biometric scan. As far as I know only Apple's laptops with Touch ID / Face ID have this level of integration. Modern smartphones also have this capability. (Note this changes with FIDO2 which supports PINs)

So to implement this more research would be needed on how to provide meaningful security. Potentially the answer is to wait for new hardware to hit the market with better security hardware. Or to store keys on a smartphone's secure enclave and relay all authentication requests to the phone.

Complexity concerns

A big downside is this adds a lot of complexity to the project. Both inherit complexity of managing keys in a hardware device, and incidental complexity that comes with the complex TPM APIs, needing the TPM to be initialized correctly, and potentially sharing the TPM with other software on the computer.

The most interesting effort to support TPM2 on Linux seems to be https://tpm2-software.github.io/. In theory support is as simple as making sure systemd-abrmd is installed and talk to the tpm device through that using the https://crates.io/crates/tss-esapi library.

Open questions

  • [ ] Do TPM2 devices directly support the required signing algorithms? That's really the only way to never have keys leave the tpm hardware. Otherwise will we have to keep the secrets stored somewhere and just temporarily decrypt them in order to use them to sign an authorization request and then zero out the key.
  • [ ] Does the TPM2 device need to be initialized? How do we get that to happen? Is there now a setup process required?
  • [ ] Should we only support TPM keys unless the user explicitly says non-TPM is okay? If so how do we prevent a malicious application from forcing us back to less-secure key storage mechanisms.
  • [ ] Should we be using a PKCS#11 interface to allow multiple different devices to be supported? Or just target TPM2 as that is becoming pretty ubiquitous due to Windows 11 requiring TPM2 support.

danstiner avatar May 09 '22 23:05 danstiner

incidental complexity that comes with the complex TPM APIs, needing the TPM to be initialized correctly, and potentially sharing the TPM with other software on the computer.

Given that having this would be beneficial to other users of the secret service, maybe it'd be worth bringing the issue to their attention, or to the attention of one of the implementations that might do pioneer work. If gnome keyring were to gain the capacity to store SSH keys in a TPM, rust-u2f could use that infrastructure for sharing the TPM.

(I might have a use case in a completely different area, which doesn't have the workforce behind it to drive it either, but I'm slowly starting to gather momentum).

chrysn avatar Jul 16 '22 17:07 chrysn

There is already a Go-based implementation: psanford/tpm-fido

I'm not sure if this is exactly what you want. But it shows a way to communicate with a TPM device.

NWater23 avatar Mar 09 '24 02:03 NWater23