Commit Graph
3 Commits
Author SHA1 Message Date
liquidraver 799d694914 crypto: simplify entropy path after audit review
- Lift duplicated identity-gen block from main_companion.cpp +
  main_repeater.cpp into ZephyrRNG::generateFirstBootIdentity().
  Both mains shrink from ~40 lines to a 3-line helper call.
- Add LocalIdentity::fromSeed() so seed-derived keygen doesn't need
  a one-shot RNG wrapper; delete SeededRNG.
- Drop the per-byte ADC sampling loop: getBattMilliVolts() does an
  8-sample average + 10ms regulator settle internally, costing
  300-480ms of real wall-time and actively destroying the LSB jitter
  it was meant to harvest. Jitter mixer already dwarfs it.
- Centralize the printk + sys_reboot pattern as
  Utils::cryptoPanicReboot(); drop the 2000ms pre-reboot k_msleep
  (printk is synchronous, sleep just blocked the mesh thread on
  the ZephyrRNG::random() retry-failure path).
- Inline sample_cpu_jitter health check via online scalars instead
  of a 512-byte deltas[] array. Saves 1.5KB stack churn across boot
  and tracks every sample instead of only the first 128.
- extract_via_aes_ctr now uses Utils::sha256 instead of open-coding
  psa_hash_compute.
2026-05-29 07:58:54 +02:00
liquidraver b692ca72ed crypto: harden all crypto-sensitive memcmp + memset sites
Audit-driven sweep found additional compiler-optimization-sensitive
patterns beyond the login password compare just fixed:

P4.F3 (HIGH) — Utils::MACThenDecrypt verified packet MACs with
plain memcmp. Runs on EVERY encrypted-then-MAC'd packet in the
mesh; a timing oracle here lets attackers forge MACs byte-by-byte
across the whole mesh layer. Replaced with constantTimeEqual.

P4.F4 (MEDIUM) — Multiple memset(secret, 0, ...) calls on
stack-resident crypto buffers (Ed25519 seed, ADC noise pool, AES
key derived in extract_via_aes_ctr, HWINFO unique ID) were
subject to dead-store elimination under -Os. GCC/Clang routinely
elide these when the buffer is never read after; the wipe vanishes
and the secret persists on stack until next call overwrites.
Replaced with secureZeroize using volatile pointer writes.

P4.F5 (LOW) — Identity::validatePrivateKey boot self-test compared
shared secrets with plain memcmp. Boot-only, no attacker
observation channel, but hygiene matters and the fix is one line.
Also added secret-wipe for ss1/ss2 on all return paths.

Promoted the local ct_memeq() previously added to RepeaterMesh.cpp
into Utils::constantTimeEqual + Utils::secureZeroize (Utils.h/cpp)
so the login compare and MAC compare share the same audited helper.

Both helpers verified by Thumb-2 disassembly on rak3401_1watt:
- constantTimeEqual: loop branches on iterator, accumulator
  load-modify-stored to stack every iteration, final return uses
  CLZ+LSR (no conditional branch on result).
- secureZeroize: STRB.W to memory in a counted loop, not replaced
  with memset builtin and not eliminated.
2026-05-28 13:26:20 +02:00
liquidraver 8d1823d0b6 First iteration that seems to work 2026-02-20 12:43:13 +01:00