onlyn00bs-badge

OnlyN00bs: a DEF CON 34 friend-finder badge. ESP32 firmware, Web Bluetooth setup app, printable case
git clone https://git.virtualshack.io/onlyn00bs-badge.git
Log | Files | Refs | README | LICENSE

README.md (5705B)


      1 # ๐Ÿ“Ÿ OnlyN00bs โ€” a DEF CON 34 friend-finder badge
      2 
      3 A badge for a friend group: each badge broadcasts your handle and shows the handles of
      4 other crew badges in range โ€” sorted by signal strength, so the closest friends float to
      5 the top. Built to be **spoof-proof in the worst RF environment on earth**: beacons are
      6 HMAC-signed with a shared group key, so randos and impersonators never make it onto your
      7 screen.
      8 
      9 ```
     10    you: crash_override โ”€โ”€ 4 nearby โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
     11      โ–โ–‚โ–ƒโ–„โ–…  acid_burn            -52 dBm
     12      โ–โ–‚โ–ƒโ–„   cereal_killer        -61 dBm
     13      โ–โ–‚โ–ƒ    lord_nikon           -73 dBm
     14      โ–โ–‚     phantom_phreak       -88 dBm
     15 ```
     16 
     17 User guide (setup, screens, button, battery, troubleshooting):
     18 [badge.virtualshack.io](https://badge.virtualshack.io).
     19 
     20 ## Hardware
     21 
     22 An off-the-shelf **FireBeetle 2 ESP32-E** (onboard LiPo charger + JST-PH) driving a
     23 **2.42" SSD1309 mono OLED** off a **2000 mAh LiPo**, one push button, in a 3D-printed case.
     24 Parts: [`hardware/BOM.md`](hardware/BOM.md). Case files: [`hardware/cad/`](hardware/cad/).
     25 
     26 ## Layout
     27 
     28 ```
     29 firmware/            PlatformIO project (Arduino-ESP32 core 3.x)
     30   platformio.ini       build envs (below)
     31   src/
     32     config.h             channel, intervals, BLE UUIDs, pins
     33     secrets.h.example    template for your crew's group key (copy to secrets.h)
     34     beacon.h             signed wire format + HMAC sign/verify
     35     peers.h              bounded, flood-resistant peer table
     36     encounters.h         LittleFS encounter log + report aggregation
     37     clock.h              soft real-time clock (BLE-seeded, NVS-checkpointed)
     38     points.h ยท points_history.h ยท pet.h ยท battery.*
     39     display_oled.cpp     the badge display (U8g2)
     40     main.cpp             mode state machine (provisioning / discovery / views)
     41 provisioning/
     42   index.html           Web Bluetooth setup app โ€” handle, avatar, clock, metrics export
     43 web/src/              the site at badge.virtualshack.io โ€” static, no build step; the
     44                        service worker makes it (and the setup app) work offline
     45 hardware/
     46   BOM.md               parts for one badge
     47   cad/                 case generators (pure Python โ†’ STL) + the production STLs
     48 docs/
     49   hmac-beacon-auth.md  the beacon signing scheme and its limits
     50   provisioning.md      the BLE setup protocol
     51   docker.md            reproducible build container
     52 drivers/               USB-serial driver note for flashing from macOS
     53 ```
     54 
     55 ## How it works
     56 
     57 **Setup (BLE).** In setup mode the badge advertises a BLE GATT service and shows a fresh
     58 3-character pairing code. Open `provisioning/index.html` in Chrome or Edge (Web Bluetooth
     59 โ€” not available on iOS), connect, enter the code, then set a handle, avatar and clock. The
     60 handle is sanitized (printable ASCII, โ‰ค 24 bytes) on both sides and stored in NVS. Setup
     61 only listens while the badge is in setup mode. Details: [`docs/provisioning.md`](docs/provisioning.md).
     62 
     63 **Discovery (ESP-NOW).** The badge broadcasts a signed beacon about once a second on a
     64 fixed channel. Incoming beacons are HMAC-verified against the group key *before* anything
     65 touches the peer table; the table is bounded and ages entries out, so a flood of garbage
     66 can't exhaust memory or fill the screen.
     67 
     68 **Encounters, points, avatar.** Each continuous stretch near a friend is logged to
     69 LittleFS. The badge ranks friends by time together, awards points for time spent near crew,
     70 graphs them over the con, and runs an ASCII avatar that reacts to events. The setup app
     71 exports the logs and points over BLE to charts, PDF and JSON โ€” nothing leaves your browser.
     72 
     73 ## Security model
     74 
     75 Full mechanism and limits: [`docs/hmac-beacon-auth.md`](docs/hmac-beacon-auth.md).
     76 
     77 - **Shared group key.** Beacon = `{magic, version, counter, handle, HMAC-SHA256(key, โ€ฆ)}`.
     78   Verification failure โ†’ silent drop. That filters outsiders and spoofers.
     79 - **It signs, it does not encrypt.** Anyone listening on 2.4 GHz can read handles and
     80   follow a badge. Pick a handle you're happy to have in the air.
     81 - **`counter`** jumps forward each boot, so captured beacons can't be replayed as fresher.
     82 - **Handles are untrusted input.** A handle set over BLE is clamped to printable ASCII
     83   (โ‰ค 24 bytes) before it's stored; a received handle must carry a valid signature and pass
     84   a 1โ€“24 byte length check, but its bytes aren't filtered โ€” a key holder can send any
     85   byte values.
     86 
     87 ## Build and flash
     88 
     89 ```sh
     90 cp firmware/src/secrets.h.example firmware/src/secrets.h
     91 #   put your crew's key in it:  openssl rand -hex 32
     92 cd firmware
     93 pio run -e oled_v3_prod -t upload     # refuses to build without a real key
     94 pio device monitor
     95 ```
     96 
     97 Every badge in a crew needs the **same** key; badges with different keys can't see each
     98 other. `oled_v3` is the same firmware without the key check, for development. Prefer no
     99 host toolchain: [`docs/docker.md`](docs/docker.md). Then open `provisioning/index.html`
    100 from `localhost` (a secure context, so Web Bluetooth works) to set the badge up.
    101 
    102 ## License
    103 
    104 | what | paths | license |
    105 |---|---|---|
    106 | Code | `firmware/`, `provisioning/`, `web/src/` (HTML, CSS, JS), `hardware/cad/*.py`, `Dockerfile` | [MIT](LICENSE) |
    107 | Case models, docs, photos | `hardware/cad/stl/`, `docs/`, `*.md`, `web/src/assets/img/` | [CC BY-SA 4.0](LICENSE-CC-BY-SA-4.0.txt) |
    108 
    109 Libraries are fetched at build time and keep their own licenses (arduino-esp32 LGPL-2.1,
    110 ESP-IDF Apache-2.0, NimBLE-Arduino Apache-2.0, U8g2 BSD-2-Clause) โ€” relevant if you
    111 redistribute a compiled firmware image.
    112 
    113 Attribution: **virtualtack** โ€” [badge.virtualshack.io](https://badge.virtualshack.io).
    114 See [`SNAPSHOT.md`](SNAPSHOT.md) for what this repository deliberately leaves out.