← Home Few Bits
Cover image for SeedSetup — Offline, Deterministic Provisioning for Headless Devices

SeedSetup — Offline, Deterministic Provisioning for Headless Devices

Alex Solis Alex Solis ·

Why offline provisioning?

Many tiny devices ship without displays, keyboards, or the luxury of a smartphone app. In field deployments and privacy‑sensitive projects you might not want to depend on a cloud service, or a phone scanning a QR code, or a device cycling through Bluetooth pairing modes. SeedSetup is a small, pragmatic pattern: derive everything a headless device needs from a short human‑readable mnemonic. No connectivity required during provisioning; the same mnemonic deterministically recreates device identity, keys, and credentials.

What it gives you

  • Consistent device ID and secret keys from a 12–24 word mnemonic.
  • Deterministic Wi‑Fi SSID/password generation for offline setup.
  • Single small library footprint: PBKDF2/HKDF + a mnemonic wordlist + minimal crypto.
  • Easy manual provisioning: read words off a sticker or keycard, type them into a serial console.

How it works, simply

SeedSetup combines three minimal building blocks:

  1. A BIP‑39 style mnemonic (English or local wordlist) that people can write or say.
  2. A password‑based key derivation (PBKDF2) to turn the mnemonic into a seed.
  3. An HKDF tree to split the seed into roles: device ID, signing key, Wi‑Fi credentials, configuration token.

The device stores only a small checksum of the mnemonic (to detect typos) and the derived keys it needs. If you ever need to reprovision, you retype the same mnemonic into the device's serial console and it regenerates the same keys and credentials.

Why deterministic is handy

Deterministic provisioning makes backups trivial and avoids per‑device secrets written by hand. You can generate a single mnemonic per batch, or give each unit a unique mnemonic printed on a sticker. If a unit is physically recovered in the field, you can restore its identity from the printed mnemonic. If a mnemonic is compromised, rotate by issuing a new one and reprovision devices.

Hardware and software footprint

SeedSetup targets tiny MCUs. You only need:

  • A microcontroller with ~32–64KB flash for code and wordlist bits (wordlists can be compacted).
  • Acceleration for SHA‑256 is optional — software SHA is fine.
  • Serial/USB CDC or UART for entering the mnemonic and reviewing status.

On the software side the core functions are small: a mnemonic encoder/decoder, PBKDF2‑HMAC‑SHA256 (one call), and a tiny HKDF extractor. A careful C implementation with lookup tables fits comfortably into small builds. For prototyping an interpreted runtime (MicroPython) with a compact SHA library also works.

Step‑by‑step: minimal implementation

  1. Pick a wordlist and mnemonic length. Twelve words give ~128 bits of entropy — a practical sweet spot.
  2. On a host, generate mnemonics and optionally print them on stickers or cards. Keep a CSV mapping if you want batch names.
  3. On device boot, present a serial prompt: enter mnemonic:. Read typed words and normalize spacing/case.
  4. Compute seed = PBKDF2_HMAC_SHA256(mnemonic, "seed", iterations=2048). Store only derived keys, not the mnemonic.
  5. Use HKDF to produce specific outputs: HKDF(seed, "device-id") → 8 bytes for a hex ID; HKDF(seed, "signing") → 32‑byte signing key; HKDF(seed, "wifi") → 128 bits split into SSID/password generation.
  6. Save small verification: a 4‑byte checksum of the mnemonic's seed. On subsequent provisioning attempts verify the checksum before overwriting.

Example snippet (pseudocode)

seed = PBKDF2(mnemonic, salt="seed", iters=2048) device_id = HKDF(seed, info="device-id", L=8) sign_key = HKDF(seed, info="signing", L=32) wifi_blob = HKDF(seed, info="wifi", L=16) ssid = "dev-" + hex(device_id) password = base32(wifi_blob)[:12]

Practical tips and gotchas

Keep iterations low enough to run on the MCU but high enough to slow brute force. For 32‑bit micros, 2048–4096 PBKDF2 iterations are usually usable; test on your target. If CPU is too slow, do the heavy derivation on an initial provisioning host and write the derived keys to the device once.

Mnemonic entry is the human bottleneck. Allow fuzzy matching: common typos, extra spaces, and case differences should be ignored. Offer a short checksum displayed after entry so you can confirm before committing.

Avoid storing raw mnemonics. If an attacker can read your device flash, you want the mnemonic gone and only derived secrets present. Consider erasing any temporary buffers after derivation.

Security notes

SeedSetup is not a silver bullet. The security model assumes the mnemonic is treated like a password. If you print mnemonics on a sticker attached to a device, the sticker is the secret. For stronger security, combine the mnemonic with a device‑unique hardware secret (like a fused eFUSE bit) during HKDF.

If you need device attestation to cloud services, use the derived signing key with a standard protocol (COSE/CBOR signing, JWT, etc.). The deterministic key means you can reissue certificates if needed without a CA contacting each device.

Troubleshooting checklist

  • Device hangs during PBKDF2: lower iterations or offload to host for initial write.
  • Mnemonic fails checksum: allow user to retype and show computed checksum before writing.
  • Wi‑Fi credentials not accepted: verify endianness and encoding when converting HKDF bytes to human fields.

Final thoughts

SeedSetup trades a tiny bit of human entry effort for a lot of convenience: reproducible identities, offline provisioning, and a small software footprint. For field sensors, privacy‑focused gadgets, or small batches without a cloud backend, it’s a practical pattern: simple to implement, easy to audit, and forgiving when you need to restore a device with nothing but a few words on paper.