For the past month, I've been prototyping my own hardware password manager using the Cardputer, a compact device that's surprisingly perfect for the task.
I learned about the Cardputer while searching for the ideal hardware to build a password manager. It's essentially a microcontroller (the ESP32-S3) packed with a screen and a keyboard. What really sold me on it were these features:
- Direct Interaction: I can interact directly with the device – typing my master password, searching for credentials, and confirming password entry, all on the Cardputer itself.
- USB Keyboard Emulation: The device can seamlessly emulate a USB keyboard, allowing for both manual and automatic password entry into other devices.
- Hardware-Accelerated Crypto: The ESP32-S3 boasts hardware acceleration for AES and SHA operations, crucial for secure password management.
- Secure Element Integration: The Cardputer supports an optional ATECC608B secure element (available as an official accessory), providing additional cryptographic capabilities, secure key storage, and true random number generation.
Taming the Cardputer
Securing the Secrets
The prototype is functional. While the source code isn't ready for release yet, I'd like to share some of the key design decisions.
For data serialization, I chose FlatBuffers. Its zero-copy nature is particularly well-suited to the no_alloc environment of this project, minimizing memory overhead. The main database structure is inspired by KeePass. Note that the database is read-only on the device; entries cannot be added, modified, or removed.
The database is encrypted using AES-GCM-SIV. The encryption key is derived via HKDF, with the input keying material (IKM) composed of three distinct components:
- User's Master Password: The output of PBKDF2 applied to the user's master password, using a randomly generated salt.
- eFuse Key in ESP32S3: The result of HKDF-Expand using a pre-defined message, keyed by random bytes securely burned into an ESP32-S3 eFuse. This ties the encryption to the specific hardware.
- ATECC608B Private Key: The output of HKDF using a pre-defined message, keyed by a shared secret. This secret is established through ECDH key exchange between the ECC key stored securely within the ATECC608B and an ephemeral key pair generated by the encryptor (e.g., a host computer or another device).
Okay, I might have gone a little overboard with the encryption. The eFuse and ATECC608B key derivation steps are probably not strictly necessary. But hey, it was fun to build! And even though secure elements aren't magic security shields (they do have known vulnerabilities), they make it way harder for someone to steal your passwords.
Final Thoughts
The Cardputer has proven to be a surprisingly capable platform for this secure password manager project, though not without its limitations.
What I liked:
- Affordability: The Cardputer's low cost is a major advantage, making this project accessible.
- Well-Suited Hardware: The hardware feature set is almost ideal – providing all the necessary functionality (display, keyboard, secure element, connectivity) without unnecessary extras.
- Small Attack Surface: The firmware footprint is relatively small (~300KB), minimizing the potential attack surface.
- Fast Boot Time: The device boots up quickly, making it convenient to use.
- Rust Ecosystem: The Rust ecosystem, with its package manager (cargo) and readily available crates, made development fast, easy, and enjoyable.
Areas for Improvement:
- Performance Limitations: The ESP32-S3's processing speed is a bottleneck, particularly for computationally intensive operations like PBKDF2-SHA512, which takes approximately 5 seconds for 65536 rounds. On the other hand, the performance is more than enough after the unlocking
- Documentation Gaps: The documentation for both the ESP32-S3 and ATECC608B could be improved. I encountered significant challenges setting up flash encryption, secure boot, and the undocumented KDF command in the ATECC608B.
- ATECC608B-TNGTLS Limitations: The Cardputer uses the ATECC608B-TNGTLS variant, which, unfortunately, does not enforce I/O encryption. This means communication between the ESP32-S3 and the secure element is not as secure as it could be.
- Known Vulnerabilities: Both the ESP32-S3 and ATECC608B have known vulnerabilities. While these don't necessarily render the device insecure, they highlight the importance of a strong master password as the primary defense.
- Missing RTIC Support: The lack of RTIC support on the ESP32-S3 is a missed opportunity for learning and exploration.
- RustCrypto Hardware Acceleration Limitations: RustCrypto's AES implementation can effectively leverage hardware acceleration when available, but that does not seems true for the HMAC, HKDF, and PBKDF2 implementations. I believe it's related to the dependency on the Clone trait.
- ECC Algorithm Support: The ATECC608B focuses on ECDSA curves and algorithms. Support for Ed25519 would be nice.
Comments