Passwords have always been a weak point in security. They can be guessed, stolen, or phished. Even a strong password can be compromised in a data breach if the server’s storage is flawed, for example, using weak encryption or storing passwords in plain text. Credentials sent over insecure channels are vulnerable to interception, and any user can fall victim to social engineering attacks in a weak moment.
Using unique, strong passwords for every site is essential, which makes a password manager a necessity. However, even with a password manager, you must remain vigilant. You can still be phished, or an infostealer could compromise your device and access all your passwords. While two-factor authentication (2FA) adds an extra layer of security, even it is not immune to phishing.
Fortunately, a solution to most of these issues already exists: WebAuthn. WebAuthn is a web standard that enables strong, passwordless authentication using public-key cryptography. It allows users to authenticate with a hardware security key, biometric data, or other secure methods. With WebAuthn, the user’s private key is stored securely on their device, and only the public key is shared with the server. This means that even if the server is compromised, the user’s credentials remain safe. WebAuthn is supported by all major browsers and platforms, making it a viable solution for modern web applications. Initially designed for multi-factor authentication (MFA), it has since evolved to support passwordless authentication. Sadly, despite being available for years, WebAuthn has not yet seen widespread adoption.
A significant hurdle is the user experience. For many, WebAuthn is more complex and less familiar than traditional password-based authentication. The introduction of Passkeys is set to improve this significantly. Passkeys remove the dependency on dedicated hardware security keys, allowing users to authenticate using their device’s built-in biometric sensors or other secure methods. This makes the process more seamless and accessible for everyday users and even allows sharing passkeys across devices within the same Apple, Google, or Microsoft ecosystem.
Introducing TuSK
However, I’m not a fan of having Apple, Google, or Microsoft control my authentication credentials, and they don’t support Linux. I own two FIDO2 security keys, but managing them can be a hassle or perhaps I’m just too lazy to find my keys when I need them. Instead, I want my laptop to act as a security key without compromising too much on security. I’m wary of password managers that store 2FA codes alongside passwords or Passkey implementations that don’t use a hardware-backed secure element, such as the software-based PassKeeZ.
Using the TPM for WebAuthn isn’t a new idea. It was already discussed by James Bottomley back in 2019. An existing implementation is tpm-fido. While it demonstrates the potential of using a Trusted Platform Module (TPM) for secure key storage, it’s several years old and lacks support for modern WebAuthn features like resident keys, which are the basis for Passkeys and passwordless authentication.
For these reasons, I built TuSK (TPM Security Key), a virtual FIDO2 security key written in Rust and backed by the TPM.
I used the OpenSK project as a foundation. OpenSK is an open-source FIDO2 security key implementation written in Rust for embedded devices. While its API is tailored for low-level hardware, it provides a solid base that only required adding some TPM integration code. Thanks to this foundation, TuSK already supports many modern features. However, some elements, like PIN authentication and counters, are not yet backed by the TPM.
One of the main limitations is the lack of secure user verification. To prevent malware from abusing a security key by endlessly attempting to authenticate, a secure user verification method is essential. For this reason, most security keys require user presence verification, such as a button press or biometric scan. Apple, Google, and Microsoft use similar methods, often with additional protections like secure enclaves or trusted execution environments.
WARNING: TuSK is a work in progress and is not yet suitable for production use. Always have alternative authentication methods available, such as a physical security key.
Future
There is still much work to be done to improve TuSK’s security and functionality. The PIN authentication needs to be backed by the TPM for enhanced security. Furthermore, there’s a security concern with non-resident keys: any user on the system with access to the TPM can use it to sign authentication requests. For non-resident keys, the TPM creates a unique key pair that is encrypted and stored within the credential ID sent to the relying party.
Resident keys offer slightly better protection. With resident keys, the TPM-wrapped private key is stored on disk, and only an identifier is sent to the relying party. This means an attacker needs access to both the TPM and the filesystem where the key is stored.
Currently user verification is faked by always returning a successful verification result. At least a popup could be shown to the user to indicate that authentication is taking place.
It would be great to have Passkeys that can be shared between devices, but this would have significant security implications, as it implies the ability to copy private keys. Apple, Google, and Microsoft mitigate this by only allowing Passkeys to be shared with other trusted devices that contain a secure enclave. Replicating these security measures on an open platform like Linux is a considerable challenge.
Please feel free to try out TuSK and provide feedback or suggestions for improvements. All documentation and source code are available on GitHub and is licensed under the GPLv3 or later.