Physical Presence-based Auth using Li-Fi
Overview
Li-Fi Auth implements a physical-presence-based authorization protocol using Li-Fi (light-fidelity) communication. Instead of one-time credential verification, authorization is continuously bound to the entity's maintained optical link with the authorizing device. Losing the light signal triggers immediate revocation.
Repository: iotauth/lifi-auth
Security model
Traditional authentication grants access at a single point in time. Li-Fi Auth ties authorization to continuous physical presence:
| Goal | Description |
|---|---|
| G1 — Freshness / expiration | Authorization is time-bounded and expires automatically. |
| G2 — Replay resistance | Observed presence material cannot be reused after expiration. |
| G3 — Relay-bounded authorization | Relay attacks degrade in effectiveness with signal propagation delay. |
| G4 — Revocation on interruption | Losing optical reception immediately triggers deauthorization. |
These properties make Li-Fi Auth suitable for scenarios where physical co-location must be enforced as a security invariant — for example, authorizing a device only while a technician is physically present in a room.
Hardware
Sender (Raspberry Pi Pico)
| Component | Purpose |
|---|---|
| Raspberry Pi Pico | Microcontroller running the sender firmware |
| Li-Fi LED transmitter | Modulates data onto a visible or infrared light beam |
| TC4420 LED driver | High-current LED drive for the transmitter |
Receiver (Raspberry Pi 4)
| Component | Purpose |
|---|---|
| Raspberry Pi 4 Model B | Host computer running the receiver application |
| OP350 photodiode | Detects the incoming light signal |
| TLV3501 comparator | Signal detection and conditioning circuitry |
Wiring (UART1 between Pico and Pi 4)
| Signal | Pico pin | Pi 4 GPIO |
|---|---|---|
| TX (Pico → Pi 4) | GPIO4 (Pin 6) | GPIO15 (RX) |
| RX (Pi 4 → Pico) | GPIO5 (Pin 7) | GPIO14 (TX) |
| Ground | GND | GND |
Software architecture
lifi-auth/
├── sender/src/ Raspberry Pi Pico firmware (AES-128-GCM, key slots, watchdog)
├── receiver/ Raspberry Pi 4 application (key provisioning, decryption)
├── src/ Core shared modules
├── include/ Public headers
├── lib/ Submodules: mbedtls, pico-sdk, picotool
├── deps/ Dependencies: iotauth, sst-c-api
├── config/ mbedTLS configuration
├── artifacts/ Build outputs with SHA256 checksums
└── run_build.sh Build orchestrator
Dependencies for the sender:
- Raspberry Pi Pico SDK
- mbedTLS v3.5.1 (AES-128-GCM, PRNG)
- picotool (firmware flashing)
Dependencies for the receiver:
- OpenSSL development libraries
- SST C API (
sst-c-api) for session key integration
Build
Clone with submodules:
git clone https://github.com/iotauth/lifi-auth.git
cd lifi-auth
git submodule update --init --recursive
Build the Pico sender firmware:
./run_build.sh pico
Build the Pi 4 receiver application:
./run_build.sh pi4
Build artifacts are stored in artifacts/ with SHA256 checksums. The script retains the last three builds by default.
Flash the Pico
On Linux (direct copy when the Pico is in BOOTSEL mode):
cp artifacts/lifi_sender.uf2 /media/$USER/RPI-RP2/
On Windows / WSL, use the picotool:
picotool load artifacts/lifi_sender.uf2 --force
Run the receiver
After wiring the hardware and flashing the Pico:
./receiver/lifi_receiver <config-file>
The receiver:
- Listens on UART1 for the preamble bytes
0xAB 0xCDfrom the Pico. - Provisions an AES-128-GCM session key to the Pico via the secure UART channel.
- Receives Li-Fi frames encrypted by the Pico.
- Decrypts and authenticates each frame.
- Revokes authorization if the optical signal is interrupted for more than the configured watchdog timeout.
Sender command interface
The Pico sender accepts commands prefixed with CMD: over its USB serial console:
| Command | Action |
|---|---|
CMD:help | Print available commands. |
CMD:print key | Print the current active key slot. |
CMD:slot status | Show the status of key slots A and B. |
CMD:use slot A / CMD:use slot B | Switch the active key slot. |
CMD:clear slot | Erase the current slot. |
CMD:new key | Request a new key provisioning from the receiver. |
CMD:entropy test | Run an entropy quality test on the PRNG. |
CMD:reboot | Reboot the Pico. |
Key storage
The Pico stores keys in redundant A/B flash slots. The slots survive power cycles; only CMD:clear slot or a new provisioning request erases them. The receiver uses SST Auth (via sst-c-api) to derive and manage the session keys, binding the Pico's authorization to an active SST session.
Transmission parameters
| Parameter | Value |
|---|---|
| Baud rate | 1 Mbps |
| Encryption | AES-128-GCM |
| PRNG | mbedTLS CTR_DRBG |
| Key slots | 2 (A / B, redundant) |
| Watchdog | Hardware watchdog for unresponsive sender detection |
Further reading
- Auth Guide — SST Auth concepts used for key provisioning
- C Guide — sst-c-api used in the receiver application
- iotauth/lifi-auth on GitHub