101 lines
3.1 KiB
Markdown
101 lines
3.1 KiB
Markdown
# KB2040 Hidden Signer (HID + WebUSB)
|
|
|
|
This directory contains an Arduino firmware scaffold that implements the `kb2040_hidden_signer` plan on top of a TinyUSB composite device.
|
|
|
|
- Firmware: [`kb2040_hidden_signer.ino`](./kb2040_hidden_signer.ino)
|
|
- Host client: [`examples/kb2040_hidden_signer_client.py`](../../examples/kb2040_hidden_signer_client.py)
|
|
|
|
## What is implemented
|
|
|
|
1. Composite USB device with two active interfaces:
|
|
- HID Consumer Control (media keys)
|
|
- Vendor/WebUSB transport (framed JSON)
|
|
2. Default media mode:
|
|
- Play/Pause, Next, Previous buttons emit HID consumer usages
|
|
- Rotary encoder emits volume up/down
|
|
3. Hidden mode toggle:
|
|
- Hold PLAY + NEXT for 3 seconds to toggle media/signer mode
|
|
4. WebUSB framed transport:
|
|
- 4-byte big-endian length + JSON payload
|
|
5. Signer RPC scaffold methods:
|
|
- `ping`
|
|
- `get_status`
|
|
- `set_mnemonic`
|
|
- `set_auto_approve`
|
|
- `get_public_key` (deterministic placeholder pubkey)
|
|
- `sign_event` (approval gate + placeholder signature)
|
|
|
|
## What remains to reach production n_signer parity
|
|
|
|
1. Replace placeholder crypto with real `n_signer` core integration:
|
|
- mnemonic -> seed -> key derivation
|
|
- secp256k1 schnorr signing
|
|
- full auth envelope verification
|
|
2. Replace naive JSON parsing with robust parsing (e.g. `ArduinoJson` or cJSON port).
|
|
3. Wire exact `keyboard_modules` pin mapping and display abstraction.
|
|
4. Add secure memory wiping and persistent policy storage if required.
|
|
|
|
## Arduino setup (IDE)
|
|
|
|
1. Install Adafruit board index in Arduino IDE.
|
|
2. Install **Adafruit RP2040** boards package.
|
|
3. Select board **Adafruit KB2040**.
|
|
4. Set **Tools -> USB Stack -> Adafruit TinyUSB**.
|
|
5. Install library **Adafruit TinyUSB Library**.
|
|
6. Open and flash [`kb2040_hidden_signer.ino`](./kb2040_hidden_signer.ino).
|
|
|
|
## Arduino CLI flashing (recommended repeatable command)
|
|
|
|
Use this exact command when flashing from CLI:
|
|
|
|
```bash
|
|
arduino-cli compile --upload -p /dev/ttyACM0 \
|
|
--fqbn rp2040:rp2040:adafruit_kb2040:usbstack=tinyusb \
|
|
firmware/kb2040_hidden_signer
|
|
```
|
|
|
|
Notes:
|
|
- `usbstack=tinyusb` is **required** for this firmware (TinyUSB composite device).
|
|
- If you omit that option, build fails with `TinyUSB is not selected`.
|
|
- If `/dev/ttyACM0` changes, find the current port with:
|
|
|
|
```bash
|
|
arduino-cli board list
|
|
```
|
|
|
|
## Host validation
|
|
|
|
Install dependency:
|
|
|
|
```bash
|
|
pip install pyusb
|
|
```
|
|
|
|
Basic dual-interface verification:
|
|
|
|
```bash
|
|
python3 tests/test_kb2040_dual.py
|
|
```
|
|
|
|
Signer RPC flow (WebUSB/vendor interface):
|
|
|
|
```bash
|
|
python3 examples/kb2040_hidden_signer_client.py status
|
|
python3 examples/kb2040_hidden_signer_client.py set-mnemonic --mnemonic "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about"
|
|
python3 examples/kb2040_hidden_signer_client.py get-public-key
|
|
python3 examples/kb2040_hidden_signer_client.py sign-event --event '{"kind":1,"content":"hello"}'
|
|
```
|
|
|
|
## Pin mapping
|
|
|
|
Current defaults in [`kb2040_hidden_signer.ino`](./kb2040_hidden_signer.ino):
|
|
|
|
- `PIN_BTN_PLAY = 2`
|
|
- `PIN_BTN_NEXT = 3`
|
|
- `PIN_BTN_PREV = 4`
|
|
- `PIN_ENC_A = 5`
|
|
- `PIN_ENC_B = 6`
|
|
- `PIN_ENC_SW = 7`
|
|
|
|
Update these constants to match your physical `keyboard_modules` build.
|