The Initialization Vector (IV) ensures that identical plaintext blocks produce different ciphertext under AES-128 CBC. ZeroKeyUSB generates the IV once at provisioning using the ATECC608A hardware TRNG, stores it in EEPROM, and validates it on every unlock.Documentation Index
Fetch the complete documentation index at: https://docs.zerokeyusb.com/llms.txt
Use this file to discover all available pages before exploring further.
Generation procedure
Called as part ofstoreSignature() (the PIN setup routine):
generateAndStoreIV()callsfillIVFromAtecc(iv).fillIVFromAtecc()callszerokeyAtecc.random(buf)— the ATECC608ARANDOMcommand with mode0x00(updates the internal DRBG seed before generating).- The first 16 bytes of the 32-byte TRNG output are copied into
iv[16]. ivIsValid()checks the result: rejects all-0x00or all-0xFF(statistically impossible with a working TRNG, but guards against chip faults).- The IV is written to EEPROM at
0x0010–0x001FviaeepromWriteRaw(). - After IV storage,
eraseAll()is called to reset all credential pages to encrypted blanks under the new IV.
EEPROM layout
| Address | Content |
|---|---|
0x0010 | IV byte 0 |
0x0011 | IV byte 1 |
| … | … |
0x001F | IV byte 15 |
Validation on unlock
loadIVfromEEPROM() is called before every encrypt or decrypt operation:
- Reads 16 bytes from
0x0010. - If the I²C read fails → attempts TRNG regeneration and EEPROM re-write.
- If
ivIsValid()returns false (all-zero or all-FF) → regenerates from ATECC TRNG and stores. - If regeneration also fails → returns
false; caller shows an error screen.
Regeneration triggers
The IV is regenerated automatically when:- The EEPROM read fails (I²C error).
- The stored value is all-
0x00or all-0xFF(blank/corrupt EEPROM). - The user generates a new PIN (the full
storeSignature()flow re-generates the IV).
generateAndStoreIV() function therefore calls eraseAll() immediately after storing the new IV to bring the EEPROM to a consistent (encrypted-blank) state.
Why a single device-wide IV?
- Keeps the layout simple, deterministic, and fully auditable.
- CBC mode with a fixed IV across all slots does not weaken confidentiality as long as the AES key is secret and the IV itself was generated randomly — the key varies per device.
- Per-record IVs would require 16 additional bytes per credential slot and complicate the EEPROM layout significantly.
- The primary confidentiality guarantee comes from the 128-bit randomly generated AES master key, not from IV uniqueness across records.
The IV never leaves the device. Ciphertext extracted from one ZeroKeyUSB cannot be decrypted with another unit even if the PIN and device serial are known, because the AES master key is device-unique.
Tamper detection
ivIsValid()rejects obviously corrupt values (all-zero, all-FF).- If the IV is flipped bit-by-bit in EEPROM, the next AES-CBC decryption will produce garbage for the first block of every slot (IV affects only the XOR input for block 0; subsequent blocks are self-synchronising in CBC decryption).
- There is no CRC or MAC stored alongside the IV in the current implementation. An attacker who can write arbitrary bytes to EEPROM address
0x0010can force IV regeneration (and thus data loss) by corrupting those bytes.
ATECC608A TRNG properties
- The
RANDOMcommand with mode0x00updates the chip’s internal DRBG seed from hardware entropy before returning 32 random bytes. - The DRBG is designed to FIPS 140-2 requirements with a maximum seed life before forced re-seeding.
- Output is validated locally (
ivIsValid) to catch pathological failures.