mirror of
https://github.com/liquidraver/ZephCore.git
synced 2026-09-01 22:08:19 +00:00
Adds a layered entropy mixer for first-boot identity Ed25519 keygen, primarily to address ESP32 where the hardware TRNG (WDEV_RND_REG) is only fed real entropy once the internal WiFi/BT radio is enabled — but identity gen runs before that on companion and indefinitely before that on a bare repeater. ESP-IDF's bootloader_random_enable() is not compiled by Zephyr-Espressif HAL, ruling out that workaround. Design reviewed with nextgens (author of upstream meshcore-dev/ MeshCore#2280 which fixes the same issue via BT/WiFi init/pull/deinit). ZephyrRNG::random — retry sys_csrand_get up to 4x with k_msleep backoff; cold-reboot on persistent failure. Previously fell back silently to sys_rand_get (xoshiro PRNG), which would have produced a weak Ed25519 seed on CSPRNG error. BUILD_ASSERT enforces CONFIG_CSPRNG_ENABLED. ZephyrRNG::mixIdentitySeed — layered entropy mixer for one-shot identity keygen. Combines sys_csrand_get (early + late), HWINFO unique device ID, caller-supplied ADC LSB noise, 200ms of CPU cycle-counter jitter (NIST SP 800-90B class source), and 50ms more jitter in an independent timing window. Conditioned via AES-256-CTR (NIST SP 800-108 KDF-in-Counter-Mode): SHA-256 of the pool extracts a 32-byte AES key; AES-256-ECB on an incrementing 128-bit counter expands to the requested output length. Uses PSA crypto already enabled in zephcore_common.conf. NIST-style repetition-count + variance health check on jitter samples; reboot on degenerate output. ~280ms one-time cost at first boot. LoRa radio TRNG was considered as an additional source but rejected on expert advice — radio sources are attacker-influenceable (jamming/spoofing). ui-joystick BLE passkey — switch from sys_rand32_get (non-crypto xoshiro) to sys_csrand_get. The 6-digit passkey is the MITM protection the rest of the BLE config enforces; predictable PINs weaken it. Identity reserved-prefix loop — replace the silent 10-attempt cap (which committed whatever it had on fall-through) with a bounded-retry-then-reboot pattern. Also: fix a pre-existing scope bug at main_companion.cpp:357 in the MESH_EVENT_PREFS_DIRTY handler — data_store was referenced inside mesh_event_loop() but declared 50+ lines later. Moved the call into a forward-declared helper defined after the statics. Unrelated to crypto work but uncovered during build verification; every companion build was broken.