Memory map
The EEPROM is organized into a configuration zone (first ~220 bytes) and a credential zone (remainder):Credential slot structure
Each of the 61 credential slots occupies 4 consecutive 32-byte EEPROM pages (128 bytes total): Each 32-byte page contains:- 16 bytes of plaintext (padded with
0xFF) encrypted as two AES-128 CBC blocks - The encryption uses the device-wide IV plus the AES master key that lives inside ATECC slot 8 — the cipher rounds run on the chip, never on the MCU.
status byte or CRC per page. Empty slots are written as encrypted 0xFF blanks during silentEraseAll().
Page address calculation
FIRST_CREDENTIAL_PAGEis computed fromCONFIG_TOTP_META_ENDrounded up to the next 32-byte boundary.slotIndexranges from 0 to 61.pageIndexranges from 0 (site) to 3 (TOTP).
Write sequence
ThewriteEepromPage() function writes 32 bytes at a page-aligned address:
- Check EEPROM presence via
Wire.beginTransmission()+ ACK test. - Send 2-byte address (MSB first) followed by 32 data bytes.
- Wait 10 ms for the EEPROM internal write cycle.
- Return
trueifWire.endTransmission()reported no error.
eepromWriteRaw() in zerokey-security.cpp splits the data at 32-byte page boundaries to avoid the M24C64’s address wrap-around behavior.
Read sequence
readEepromPage() reads exactly 32 bytes:
- Send 2-byte address via I²C write.
- Issue
Wire.requestFrom(eepromAddress, 32). - Read all available bytes into the output buffer.
- Zero-fill any bytes not received (partial read = error).
TOTP metadata
Each credential slot has a 2-byte TOTP metadata entry in the config zone:
Metadata is read/written independently of credential pages to allow quick TOTP detection without decrypting the entire slot.
Wear characteristics
- The M24C64-WMN6TP supports >1 million write cycles per page (datasheet guarantee).
- Credential pages are only rewritten when the user edits a field or imports data.
- Config zone pages (IV, PIN hash, threshold) are written during provisioning and PIN changes — infrequent events.
- The TOTP epoch at
0x0040is updated each time the user syncs time or generates a code — this is the most-written location. - Because credentials are typically static, expected EEPROM lifespan exceeds decades of normal use.
Troubleshooting
No decrypted credential ever touches persistent memory without explicit user action. Plaintext exists only in SRAM during the active session.