From 319c05af5c92820c1da3c143f2ee200d3ac4bbbb Mon Sep 17 00:00:00 2001 From: Florian Date: Sat, 16 May 2026 10:26:49 -0500 Subject: [PATCH] [BT] Default BLE AES key empty, skip decryption without a key (#2310) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * [BT] Default BLE AES key empty, skip decryption without a key Shipping a non-empty default key caused fresh installs to attempt decryption of every encrypted PVVX/BTHome v2/Victron advertisement with the placeholder string from User_config.h. Frames that didn't happen to share that key were silently dropped at the CCM auth step, masking otherwise-decodable devices (notably Victron MPPT) until users found and entered a per-MAC key. Initialise ble_aes[] to "" and treat an empty default as "no default configured" in the decryption path - mirroring Theengs Gateway, which has no default and skips frames whose MAC has no bindkey. Per-MAC keys in ble_aes_keys still take precedence; the BLE_AES macro remains as the WebUI placeholder hint. Co-Authored-By: Claude Opus 4.7 (1M context) * [BT] clang-format: move BLE_AES default comment above #define clang-format-9 rejected the trailing-comment continuation on the empty BLE_AES default line. Move the explanation to a leading // block above the #ifndef so the directive line is comment-free. Co-Authored-By: Claude Opus 4.7 (1M context) * [BT] Use THEENGS_LOG_TRACE for missing-AES-key skip log Previous commit referenced THEENGS_LOG_DEBUG, which OMG does not define (only VERBOSE/TRACE/NOTICE/WARNING/ERROR exist), breaking every BLE firmware build. Switch to THEENGS_LOG_TRACE — same level as the adjacent "Custom AES key" / "Default AES key" trace lines. Co-Authored-By: Claude Opus 4.7 (1M context) --------- Co-authored-by: Claude Opus 4.7 (1M context) --- main/User_config.h | 4 +++- main/config_WebContent.h | 3 +-- main/gatewayBT.cpp | 7 ++++++- main/main.cpp | 4 ++++ 4 files changed, 14 insertions(+), 4 deletions(-) diff --git a/main/User_config.h b/main/User_config.h index df73eb8..3ac82d2 100644 --- a/main/User_config.h +++ b/main/User_config.h @@ -694,8 +694,10 @@ void storeSignalValue(uint64_t); # ifndef JSON_BLE_AES_CUSTOM_KEYS # define JSON_BLE_AES_CUSTOM_KEYS 256 // 42 byte BLE Custom Key * 6 rounded up to 256. # endif +// Runtime default for ble_aes[]. Empty = no default; override at build time +// with -DBLE_AES='"<32-hex-key>"' to ship a stock key. # ifndef BLE_AES -# define BLE_AES "00112233445566778899001122334455" +# define BLE_AES "" # endif # endif #endif diff --git a/main/config_WebContent.h b/main/config_WebContent.h index a535c2d..11d0369 100644 --- a/main/config_WebContent.h +++ b/main/config_WebContent.h @@ -294,8 +294,7 @@ const char config_ble_body_decoder[] = const char config_ble_body_encrypt[] = "

Encryption

" "

BLE AES Default Key (32 char hex)

" - "" + "" "

BLE Key Pairs

" "

MacAddress:AESKey with space separator

" "

"; diff --git a/main/gatewayBT.cpp b/main/gatewayBT.cpp index 02def11..1f4bf0c 100644 --- a/main/gatewayBT.cpp +++ b/main/gatewayBT.cpp @@ -1275,9 +1275,14 @@ void process_bledata(JsonObject& BLEdata) { if (ble_aes_keys.containsKey(macWOdots)) { THEENGS_LOG_TRACE(F("[BLEDecryptor] Custom AES key %s" CR), ble_aes_keys[macWOdots].as()); bleaeskeylength = hexToBytes(ble_aes_keys[macWOdots], bleaeskey, 16); - } else { + } else if (strlen(ble_aes) >= 32) { THEENGS_LOG_TRACE(F("[BLEDecryptor] Default AES key" CR)); bleaeskeylength = hexToBytes(ble_aes, bleaeskey, 16); + } else { + // No per-MAC key configured and no default set: skip silently rather + // than attempting decryption with a placeholder key. + THEENGS_LOG_TRACE(F("[BLEDecryptor] No AES key configured for %s, skipping" CR), macWOdots.c_str()); + return; } // Check AES Key if (bleaeskeylength != 16) { diff --git a/main/main.cpp b/main/main.cpp index bf37052..ace2afd 100644 --- a/main/main.cpp +++ b/main/main.cpp @@ -96,6 +96,10 @@ char gateway_name[parameters_size + 1] = Gateway_Name; unsigned long lastDiscovery = 0; #if BLEDecryptor +// BLE_AES defaults to "" (see User_config.h) so encrypted PVVX/BTHome/Victron +// frames are only decrypted when a per-MAC key is configured (ble_aes_keys) or +// the user enters a default. Sites shipping a stock default key can still set +// it at build time via -DBLE_AES='"<32-hex-key>"'. char ble_aes[parameters_size] = BLE_AES; StaticJsonDocument ble_aes_keys; #endif