Modular by design
ZeroKeyUSB firmware is written in C++ for the Microchip SAMD21 microcontroller.It follows a layered architecture that keeps hardware drivers, security primitives, and the user interface cleanly separated.
Layer | Responsibilities |
---|---|
Application logic | Credential manager, menu flow, host commands. |
Services & security | Encryption routines, TOTP engine, Master PIN gatekeeper. |
Drivers & helpers | OLED display, touch controller, I²C EEPROM, USB HID interface. |
SAMD21 HAL / CMSIS | Vendor hardware layer that exposes the MCU peripherals. |
Boot sequence
- Power-on self-test – validates clock configuration, memory integrity, and ensures the EEPROM responds on the I²C bus.
- Entropy gathering – if the initialization vector (IV) is missing, a new one is generated using analog noise from a floating pin.
- PIN gatekeeper – the device remains locked until the user enters the correct Master PIN. Only then are encrypted blocks decrypted in RAM.
- Runtime services – the menu system, USB HID keyboard, and TOTP engine are initialized.
EEPROM ERROR
) and halts execution to avoid exposing partial data.
Core services
🔐 Credential vault
- Stores up to 64 credentials, each split into encrypted blocks (site, username, password, optional TOTP secret).
- Confirms EEPROM writes through I²C acknowledgment to ensure successful completion.
- Keeps decrypted data in RAM only as long as necessary to type it via USB HID output.
🛡️ PIN gatekeeper
- Uses the Master PIN directly as the AES-128 key (future versions may add a salted KDF).
- Validates the PIN by decrypting and comparing the stored signature block.
- Applies exponential lockout delays after failed attempts, with counters stored in EEPROM for persistence.
⏱️ Scheduler
- Coordinates display refresh, touch polling, and USB reports on a cooperative timing loop (~1 ms granularity).
- Recalculates TOTP codes every 30 seconds without blocking the UI.
- No interrupts or preemptive scheduling — timing is deterministic and fully controlled in firmware.
🔄 Host command handler
- Operates through the CDC endpoint of the composite USB interface (HID + Serial).
- Handles local commands for backup, restore, time synchronization, and factory reset.
- Transfers occur in plaintext and are meant strictly for offline use via the local web manager or terminal.
Hardware abstraction layer
Driver | Responsibilities | Interfaces |
---|---|---|
Display | Initializes the 128×32 OLED, renders glyphs, progress bars, and smooth scrolling | I²C (400 kHz) |
Touch sensor | Calibrates TS06 thresholds, debounces taps, detects long presses | I²C |
EEPROM | Provides transactional reads/writes with I²C acknowledgment checks | I²C |
USB HID | Emulates a keyboard using a US-QWERTY layout and exposes a CDC serial endpoint | USB FS |
display.render()
, touch.poll()
, eeprom.write_block()
) that keep the upper layers small and auditable.
State machines everywhere
Every interactive screen — lock screen, credential list, editor, TOTP viewer, and danger zone — is implemented as a finite state machine (FSM).This deterministic design simplifies debugging and formal security review:
- Each state defines explicit transitions triggered by touch events.
- Sensitive states (e.g., Backup, Factory Reset) require long-press confirmation within the same FSM.
- Inactivity timeouts automatically return to the lock screen, ensuring decrypted data is never left visible.
Memory footprint
Region | Size | Description |
---|---|---|
Flash | ~64 KB | Firmware code, fonts, icons, static strings. |
SRAM | ~16 KB | UI buffers, decrypted credential cache, TOTP workspace. |
EEPROM | 8 KB | Encrypted user data, IV, PIN signature, metadata, counters. |
Build & verification
- Compiled with ARM GCC under reproducible build flags for deterministic binaries.
- Builds are manually tested and verified on hardware before release.
- Firmware integrity is verified at the factory before flashing — there is no remote update or binary signing mechanism at runtime.
ZeroKeyUSB runs on a minimal firmware stack: no RTOS, no dynamic memory allocation, and no hidden debug backdoors.
All tasks are cooperative and time-deterministic — simplicity is treated as a security feature.
All tasks are cooperative and time-deterministic — simplicity is treated as a security feature.