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​