# Plan: Issue #2 — AES-256-GCM + ECDH + PSK voor BLE relay commands ## Beveiligingsmodel ### Provisioning (eenmalig, USB CDC) Android genereert 32B PSK (pre-shared key) en provisioned beide ESP's: - `SET_KEY` → Server ESP (NVS `syl/psk`) - `SET_KEY` → Client ESP (NVS `syl/psk`) ### BLE ECDH handshake (elke sessie) ``` Client Server |── pubkey(65B) || HMAC(PSK,pubkey)(32B) ─────>| verify HMAC met PSK | | genereer eigen keypair |<─ pubkey(65B) || HMAC(PSK,pubkey)(32B) ──────| verify HMAC met PSK | | AES_KEY = SHA-256(ECDH_shared_secret) AES_KEY = SHA-256(ECDH_shared_secret) ``` - PSK verlaat nooit het apparaat over BLE — alleen HMAC ervan - Zonder PSK kan MITM geen geldige HMAC voor fake pubkey produceren - Per-sessie AES keys → perfect forward secrecy - PSK gelekt? → her-provisionen via USB CDC ## Packet structuren ### ECDH handshake packet (97 bytes) ``` pubkey[65] || HMAC-SHA256(PSK, pubkey)[32] ``` BLE characteristic: `beb5483e-...-f26dc`, properties `WRITE_NR | NOTIFY` ### Relay command (29 bytes, AES-256-GCM) ``` seq(4) || nonce(8) || ciphertext_cmd(1) || tag(16) ``` Nonce voor GCM = `seq(4) || random(8)` = 12 bytes. Sequence > lastSeq voor replay protection per sessie. ## NVS / SharedPreferences | Opslag | Sleutel | Waarde | |---|---|---| | ESP NVS `syl` | `psk` | 32B PSK | | ESP NVS `syl` | `uuid` | 16B device UUID | | Android Prefs | `psk` | 64-char hex PSK | | Android Prefs | `device_uuid` | 32-char hex UUID | ## Bestandswijzigingen ### Nieuw - `src/ecdh_helper.h` — ECDH keypair generatie + shared secret (mbedtls/ecdh.h) ### Gewijzigd - `src/main.cpp` — HMAC → ECDH handshake + AES-GCM decrypt; PSK uit NVS - `src/client.cpp` — HMAC → ECDH handshake + AES-GCM encrypt; PSK uit NVS - `android/.../BleRelayManager.kt` — HMAC → ECDH (KeyAgreement) + AES-GCM (Cipher) - `android/.../SettingsActivity.kt` — SET_KEY schrijft voortaan PSK - `android/.../PrefsHelper.kt` — `hmac_key` → `psk` - `version.txt` — bump server + client versies ## Werkt NIET met oude firmware/app Geen backward compatibility: schone break. HMAC packets worden niet meer geaccepteerd.