# Epsilon Tools ``` tools/ deploy.py Unified build, provision & flash pipeline deploy.example.json Batch config template C3PO/ C2 server (TCP + TUI + Web) nanoPB/ Protobuf definitions (c2.proto) ``` ## Prerequisites - Python 3.8+ - ESP-IDF v5.3.2 (`source ~/esp-idf/export.sh`) - esptool (`pip install esptool`) --- ## Deploy (`deploy.py`) Single pipeline: **build** firmware, **generate** crypto keys, **provision** factory NVS, **flash** all partitions, **register** keys in C2 keystore. ### Usage ```bash # Interactive wizard python deploy.py # Single device (WiFi + OTA) python deploy.py -p /dev/ttyUSB0 -d ce4f626b \ --wifi MySSID MyPass --srv 192.168.1.51 # Single device (WiFi, no OTA) python deploy.py -p /dev/ttyUSB0 -d a91dd021 --no-ota \ --wifi MySSID MyPass --srv 192.168.1.51 # Batch deploy python deploy.py --config deploy.example.json ``` ### Modes | Flag | Effect | |------|--------| | *(default)* | Full pipeline: build + provision + flash | | `--provision-only` | Generate key + flash factory NVS only | | `--flash-only` | Flash existing build (skip rebuild) | | `--build-only` | Build firmware only (no flash) | | `--erase` | Erase entire flash before writing | | `--monitor` | Open serial monitor after flash | ### OTA vs Non-OTA | | OTA | Non-OTA (`--no-ota`) | |---|---|---| | Partition table | `partitions.csv` | `partitions_noota.csv` | | App partitions | 2 x 1.875 MB (ota_0/ota_1) | 1 x 3.875 MB (factory) | | Firmware updates | HTTPS OTA | Manual reflash | | mbedTLS cert bundle | Yes | No | ### Flash Map ``` Offset OTA Non-OTA ------ --- ------- 0x1000 bootloader bootloader 0x8000 partition table partition table 0xD000 ota data -- 0x10000 factory NVS (key) factory NVS (key) 0x20000 app (ota_0) app (factory, 3.875 MB) ``` ### Batch Config `deploy.example.json`: ```json { "devices": [ { "device_id": "ce4f626b", "port": "/dev/ttyUSB0", "srv_ip": "192.168.1.51", "srv_port": 2626, "network_mode": "wifi", "wifi_ssid": "MyWiFi", "wifi_pass": "MyPassword", "module_network": true, "ota_enabled": true }, { "device_id": "a91dd021", "port": "/dev/ttyUSB1", "srv_ip": "192.168.1.51", "srv_port": 2626, "network_mode": "wifi", "wifi_ssid": "MyWiFi", "wifi_pass": "MyPassword", "module_network": true, "module_fakeap": true, "ota_enabled": false } ] } ``` ### Config Fields | Field | Default | Description | |-------|---------|-------------| | `device_id` | random | 8 hex chars unique ID | | `port` | -- | Serial port | | `srv_ip` | `192.168.1.100` | C2 server IP | | `srv_port` | `2626` | C2 server port | | `network_mode` | `wifi` | `wifi` or `gprs` | | `wifi_ssid` | -- | WiFi SSID | | `wifi_pass` | -- | WiFi password | | `gprs_apn` | `sl2sfr` | GPRS APN | | `hostname` | random | Device hostname on network | | `module_network` | `true` | ping, arp, proxy, dos | | `module_fakeap` | `false` | Fake AP, captive portal, sniffer | | `module_recon` | `false` | Reconnaissance | | `recon_camera` | `false` | ESP32-CAM | | `recon_ble_trilat` | `false` | BLE trilateration | | `ota_enabled` | `true` | OTA firmware updates | | `master_key` | random | 64 hex chars (override auto-gen) | ### Crypto Each deploy generates a **256-bit master key** per device: 1. Random 32-byte key generated (or provided via `--key`) 2. Written to factory NVS (`fctry` @ `0x10000`, namespace `crypto`, key `master_key`) 3. Registered in `C3PO/keys.json` 4. On boot, firmware derives encryption key via **HKDF-SHA256** (salt=device_id, info=`espilon-c2-v1`) 5. All C2 traffic encrypted with **ChaCha20-Poly1305 AEAD** (12-byte nonce + 16-byte tag) --- ## C2 Server (`C3PO/`) Command & Control server for deployed ESP32 agents. - Threaded TCP server with per-device encrypted communications - ChaCha20-Poly1305 AEAD + HKDF key derivation - Device registry + master key keystore (`keys.json`) - TUI (Textual) + Web dashboard - Camera UDP receiver + MLAT support - Command dispatch: single device, group, or broadcast ```bash cd C3PO && python3 c3po.py ``` See [C3PO/README.md](C3PO/README.md) for details. --- ## Proto Definitions (`nanoPB/`) nanoPB protobuf definitions for ESP32 <-> C2 wire protocol. - `c2.proto` -- `Command` and `AgentMessage` messages - `c2.options` -- nanoPB field size constraints --- **Authors:** @off-path, @eun0us