Skip to main content

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:

GoalDescription
G1 — Freshness / expirationAuthorization is time-bounded and expires automatically.
G2 — Replay resistanceObserved presence material cannot be reused after expiration.
G3 — Relay-bounded authorizationRelay attacks degrade in effectiveness with signal propagation delay.
G4 — Revocation on interruptionLosing 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)

ComponentPurpose
Raspberry Pi PicoMicrocontroller running the sender firmware
Li-Fi LED transmitterModulates data onto a visible or infrared light beam
TC4420 LED driverHigh-current LED drive for the transmitter

Receiver (Raspberry Pi 4)

ComponentPurpose
Raspberry Pi 4 Model BHost computer running the receiver application
OP350 photodiodeDetects the incoming light signal
TLV3501 comparatorSignal detection and conditioning circuitry

Wiring (UART1 between Pico and Pi 4)

SignalPico pinPi 4 GPIO
TX (Pico → Pi 4)GPIO4 (Pin 6)GPIO15 (RX)
RX (Pi 4 → Pico)GPIO5 (Pin 7)GPIO14 (TX)
GroundGNDGND

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:

  1. Listens on UART1 for the preamble bytes 0xAB 0xCD from the Pico.
  2. Provisions an AES-128-GCM session key to the Pico via the secure UART channel.
  3. Receives Li-Fi frames encrypted by the Pico.
  4. Decrypts and authenticates each frame.
  5. 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:

CommandAction
CMD:helpPrint available commands.
CMD:print keyPrint the current active key slot.
CMD:slot statusShow the status of key slots A and B.
CMD:use slot A / CMD:use slot BSwitch the active key slot.
CMD:clear slotErase the current slot.
CMD:new keyRequest a new key provisioning from the receiver.
CMD:entropy testRun an entropy quality test on the PRNG.
CMD:rebootReboot 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

ParameterValue
Baud rate1 Mbps
EncryptionAES-128-GCM
PRNGmbedTLS CTR_DRBG
Key slots2 (A / B, redundant)
WatchdogHardware watchdog for unresponsive sender detection

Further reading