Command path proven end to end on the bus (node F8 interior lights, on/off/on),
each answering a distinct fresh challenge; bare opcodes without the exchange are
ignored. ids_can_auth.h verified bit-exact against ids_can_auth.py and the
captured/live pairs.
- idscan_cmd.py: stdlib socketcan tool running the full page-42/43 exchange
- esphome/onecontrol-canbus.yaml: correct IDS-CAN read dispatch (was stale RV-C
DGN code) + command path wired to the auth header
- README/memory: document the read map + command authentication; rename
sniff/ -> captures/; neutral device-integration framing throughout
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The CAN write gate (page-42/43 challenge/response) is a 32-round TEA/XTEA-family
Feistel keyed by a per-session 32-bit key; REMOTE_CONTROL = 0xB16B00B5. Verified
51/51 against captured challenge/response pairs across nodes 2A/61/75/F8 (one
global key, not per-node), so the CAN path can now actuate, not just sense.
- ids_can_auth.py Python reference + self-test (51/51)
- esphome/ids_can_auth.h C++ port for the ESP32 node (host-tested 8/8)
- sniff/analyze_auth.py structural analysis (rules out affine; confirms keyed cipher)
- sniff/auth-pairs-multinode-2026-06-11.txt +9 pairs across 4 nodes
- README document the cipher, session keys, unlock sequence
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>