Home IO Control
ESPHome add-on for IO-Homecontrol devices
Loading...
Searching...
No Matches
redaction.h
Go to the documentation of this file.
1#pragma once
2
3/// @file redaction.h
4/// @brief Key-material redaction helpers shared by every surface that can emit frame bytes
5/// or debug text (frame logging today; telemetry and diagnostic reports later).
6/// @ingroup hioc_protocol
7///
8/// The one deliberate, narrow exception to this file's masking is `IOHOME_UNSAFE_LOG_KEY_MATERIAL`
9/// (log_frame.h::render_frame_hex_redacted()) — a maintainer-only, opt-in-only build flag for
10/// capturing a genuine pairing exchange for `tests/corpus/`. See that function's doxygen for the
11/// full rules before ever defining it.
12
13#include "proto_constants.h"
14#include "proto_sizes.h"
15
16#include <cstddef>
17#include <cstdint>
18#include <cstring>
19
20namespace esphome {
21namespace home_io_control {
22
23/// @brief Whether a frame command's payload carries key material that must never be logged
24/// or reported verbatim.
25///
26/// CMD_KEY_TRANSFER (0x32) carries the system key encrypted with the pairing transfer key —
27/// still key material, so callers rendering frame bytes must mask this payload rather than
28/// print it.
29///
30/// CMD_CHALLENGE_REQ (0x3C) and CMD_CHALLENGE_RESP (0x3D) are masked for the same reason even
31/// though neither carries the key itself: create_hmac() builds the 0x3D payload by AES-128-ECB
32/// encrypting an IV built from the 0x3C challenge and the challenged frame's own (plaintext)
33/// transcript under the system key, then truncating to 6 bytes (proto_crypto.cpp). Logging both
34/// frames publishes a known-plaintext/known-ciphertext pair for that block cipher under the
35/// system key, so they get the same treatment as literal key material.
36///
37/// CMD_ONEWAY_ADD_CONTROLLER (0x30) is masked even though this codebase has no 1W key-adoption
38/// feature and never builds or parses this command itself: the radio receives every frame that
39/// matches the IO-Homecontrol sync word regardless of destination address (see
40/// log_component_capture()'s doc comment), so a neighboring installation's 1W device performing
41/// its key-copy gesture is overheard and logged like any other traffic. That broadcast hands its
42/// network's wrapped system key to whoever is listening, so the raw command byte alone is enough
43/// to know the payload must be masked even without decoding it.
44/// @param cmd Frame command byte.
45/// @return true if the payload of a frame with this command must be masked.
46inline bool command_carries_key_material(uint8_t cmd) {
47 return cmd == CMD_KEY_TRANSFER || cmd == CMD_CHALLENGE_REQ || cmd == CMD_CHALLENGE_RESP ||
49}
50
51/// @brief Whether a buffer contains the system key as a contiguous run of bytes.
52///
53/// A last-line-of-defense scan for accidental key leaks in ad hoc debug or report text,
54/// independent of which command produced the buffer.
55/// @param buf Buffer to scan.
56/// @param len Length of buf in bytes.
57/// @param system_key Pointer to the AES_KEY_SIZE-byte system key.
58/// @return true if system_key appears anywhere in buf.
59inline bool contains_key_material(const uint8_t *buf, size_t len, const uint8_t *system_key) {
60 if (buf == nullptr || system_key == nullptr || len < AES_KEY_SIZE)
61 return false;
62 for (size_t i = 0; i + AES_KEY_SIZE <= len; i++) {
63 if (memcmp(buf + i, system_key, AES_KEY_SIZE) == 0)
64 return true;
65 }
66 return false;
67}
68
69} // namespace home_io_control
70} // namespace esphome
static constexpr uint8_t CMD_KEY_TRANSFER
Send encrypted system key to device.
static constexpr uint8_t CMD_ONEWAY_ADD_CONTROLLER
1W "add controller": a 1W device broadcasts this while its key-copy gesture is active,...
bool contains_key_material(const uint8_t *buf, size_t len, const uint8_t *system_key)
Whether a buffer contains the system key as a contiguous run of bytes.
Definition redaction.h:59
static constexpr uint8_t CMD_CHALLENGE_REQ
6-byte random challenge.
static constexpr uint8_t AES_KEY_SIZE
AES-128 key size.
Definition proto_sizes.h:23
static constexpr uint8_t CMD_CHALLENGE_RESP
HMAC proof answering a 0x3C.
bool command_carries_key_material(uint8_t cmd)
Whether a frame command's payload carries key material that must never be logged or reported verbatim...
Definition redaction.h:46
IO-Homecontrol command IDs, result codes and protocol enumerations.
Fundamental IO-Homecontrol frame and crypto size constants.