Home IO Control
ESPHome add-on for IO-Homecontrol devices
Loading...
Searching...
No Matches
hub_key_extraction.cpp File Reference

"Accept Foreign Pairing (Key Extraction)" — device-role responder hub wiring. More...

#include "hub_internal.h"
#include "pairing_responder.h"
#include "proto_commands.h"
#include "proto_crypto.h"
#include <esp_random.h>
#include <cstdio>
#include <cstring>
Include dependency graph for hub_key_extraction.cpp:

Go to the source code of this file.

Namespaces

namespace  esphome
namespace  esphome::home_io_control

Detailed Description

"Accept Foreign Pairing (Key Extraction)" — device-role responder hub wiring.

Owns the impure side of the key-extraction feature: arming/disarming, throwaway node-ID generation, the 10-minute auto-off timer, transmitting device-role replies, and the security-sensitive result log block. The pure state-transition decisions live in pairing_responder.h/.cpp; the four RX branches that call into this file are in process_received_packet_() (hub_status.cpp).

Note
Hardware-confirmed 2026-08-02: a full extraction (0x28 through 0x33) between two real boards — SX1276 running this responder, SX1262 running this project's own PairingEngine as the "hub" — recovered the hub's node_id/system_key byte-for-byte. That validates the crypto, the state machine, and the radio wiring end-to-end on real RF hardware.
Warning
What that test does NOT validate: compatibility with a genuine third-party hub (Somfy TaHoma/Smoove, Velux KLF200, etc.). The device-role frames built here (create_discover_resp(), create_challenge_req(), create_key_confirm()) were reverse-engineered from this project's own encoder and a small number of captures. The self-test above necessarily agrees with those conventions (it's the same codebase on both ends); a real hub's exact requirements (discovery-response field completeness, retry cadence) may still differ. recover_system_key_from_transfer()'s IV-derivation formula itself is now pinned against two (Somfy TaHoma/Smoove, Velux KLF200, etc.). That self-test necessarily agrees with this codebase's own conventions — it is the same encoder on both ends — so it is blind to two things: a device-role frame that is self-consistent but wrong on air, and a protocol step a real hub requires that this project's own controller role never sends. Both are real failure modes against real hubs; see tests/corpus/captures/issues/issue_45_*_key_extraction_stall.yaml. The device-role builders (create_discover_resp(), create_challenge_req_device_role(), create_key_confirm(), create_discover_confirm_ack()) are each pinned against a real device's captured framing by tests/corpus_device_role_builder_test.cpp — except create_discover_resp()'s flags/timestamp bytes, which remain placeholders. recover_system_key_from_transfer()'s IV-derivation formula is independently pinned against two externally-captured known-answer key transfers (ProtoCrypto.CryptKeyMatchesDocumented*Capture in proto_crypto_test.cpp), so that formula does not rest on this codebase's own conventions — though both captures are short requests and don't exercise construct_iv()'s 8-byte truncation window, so a real hub sending a longer request is an open question. Treat a recovered key as unconfirmed until it has been verified against a real hub, or by successfully controlling a device with it.

Definition in file hub_key_extraction.cpp.