
Linux Desktop Fingerabdruck Anmeldung mit einem Grow R503 Sensor + Arduino + einem Rust fprintd-Ersatz Daemon
Ein aus Einzelteilen zusammengebauter USB-Fingerabdruckleser für Linux-Desktops. Gesamtkosten der Teile unter 15 $. Direkter Ersatz für das ursprüngliche fprintd — PAM, KDE-Einstellungen, GNOME-Einstellungen, fprintd-verify, sudo mit Fingerabdruck, Bildschirmentsperrung mit Fingerabdruck – alles funktioniert.
Ab fw=1.0 / r503d 1.0.0 ist die Arduino↔Host-Verbindung authentifiziert: jeder Befehl und jede Antwort trägt einen SipHash-2-4-MAC, der mit einem über TOFU (Trust on First Use) festgelegten Geheimnis im EEPROM signiert ist. Replay- und Hot-Swap-Angriffe auf die USB-Seriellverbindung werden blockiert. Siehe SPEC.md §13 für das vollständige Design, einschließlich dessen, was das Bedrohungsmodell nicht abdeckt.

wünschte, ich hätte einen 3D-Drucker…``` ┌──────────┐ UART ┌─────────────┐ USB-CDC ┌──────────────────┐ │ Grow │ 57600 8N1│ Arduino │ /dev/r503 │ r503d daemon │ │ R503 │◀─────────▶│ (firmware) │◀──────────▶│ net.reactivated │ │ sensor │ 3.3V TTL │ │ framed, │ .Fprint on D-Bus│ └──────────┘ └─────────────┘ MAC'd └──────────────────┘ │ ▼ PAM, KDE, GNOME, fprintd-verify, …
## Warum
Hardware-USB-Fingerabdruckleser für Linux sind rar, teuer und die
vorhandenen (Validity, Synaptics, etc.) werden durch instabile
libfprint-Treiber reverse-engineered, die bei Hersteller-Firmware-Updates
brechen. Das Protokoll des Grow R503 ist **öffentlich**, die Arduino-Seite
ist eigener Code und die libfprint-Kompatibilitätsschicht ist nur D-Bus.
Sie erhalten außerdem einen Fingerabdruckleser, dessen Quelle Sie
vollständig einsehen können.
## Stückliste
| Bauteil | Hinweise | Ungefähre Kosten |
|------|-------|------|
| Grow R503 kapazitiver Fingerabdrucksensor | Der runde mit dem RGB-Ring | ~$10 |
| Arduino Uno R3 / Nano / Mega / beliebiges ATmega328-Board | Alles, was SoftwareSerial ausführt | $5–$25 |
| 4–6 Jumper-Kabel | Dupont / Steckbrett | trivial |
Das war's. **Kein Pegelwandler, kein Spannungsteiler** — siehe
[`SPEC.md` §3.1](https://github.com/matpb/linux-fingerprint-r503/blob/main/SPEC.md) für den Grund (die RX-Leitung des R503 ist in
der Praxis 5V-tolerant; das Datenblatt lügt).
## Verkabelung```
R503 Arduino (Uno R3 / Nano / etc.)
---- ------------------------------
Red (VCC) 3V3
White (3.3VT) 3V3 (touch-IC supply; shares rail with red)
Black (GND) GND
Yellow (TXD) D2 ── SoftwareSerial RX
Brown (RXD) D3 ── SoftwareSerial TX (direct — no divider!)
Blue (WAKEUP) D4 (optional; not used by firmware yet)
Falls Ihr R503 mit dem JST-SH-Stecker geliefert wird, schneiden Sie ein 6-poliges JST-SH-auf-Dupont-Kabel ab, um die Drähte freizulegen. Braun ist manchmal grün, je nach Verkäufer – prüfen Sie gegen den Draht, der in den RXD-Pin des JST-Steckers geht, nicht die Farbe.
Getestet auf Fedora 44 KDE; sollte auf jeder systemd-basierten Distribution mit fprintd, pam_fprintd und einer aktuellen Rust-Toolchain funktionieren.
Systempakete:
| Distribution | Build | Laufzeit |
|---|---|---|
| Fedora / RHEL | rust cargo arduino-cli tpm2-tss-devel | fprintd pam fprintd-pam tpm2-tss |
| Debian / Ubuntu | rustc cargo arduino-cli libtss2-dev | fprintd libpam-fprintd libtss2-esys-3.0.2-0 |
Die tss-esapi Pakete werden nur benötigt, wenn Sie --pair --seal-tpm (SPEC §13.12) verwenden möchten. Der Daemon baut und läuft ansonsten ohne TPM – tss-esapi ist eine harte Build-Abhängigkeit, aber eine weiche Laufzeitabhängigkeit (der Codepfad wird nur betreten, wenn /var/lib/r503d/key.tpm existiert).
Rust 1.95+, arduino-cli in Ihrem $PATH.
Haben Sie ein TPM2?```bash ls /dev/tpmrm0 && tpm2_pcrread sha256:7 | head -3
Wenn beide erfolgreich sind, kann Ihr Host den versiegelten Schlüsselpfad verwenden. Falls `/dev/tpmrm0` fehlt (ältere Hardware, TPM im BIOS deaktiviert oder eine VM ohne virtuelles TPM), bleiben Sie beim standardmäßigen Klartext-Schlüsselablauf.
## Erstellen & installieren
### 1. Firmware flashen
Öffnen Sie `firmware/r503fp/r503fp.ino` in der Arduino IDE und laden Sie es hoch. Oder mit
`arduino-cli`:```bash
# Uno R3:
arduino-cli compile --fqbn arduino:avr:uno firmware/r503fp/
arduino-cli upload --fqbn arduino:avr:uno --port /dev/ttyACM0 firmware/r503fp/
# Nano (modern Optiboot, including most Elegoo / WAVGAT clones):
arduino-cli compile --fqbn arduino:avr:nano:cpu=atmega328 firmware/r503fp/
arduino-cli upload --fqbn arduino:avr:nano:cpu=atmega328 --port /dev/ttyUSB0 firmware/r503fp/
# Nano with legacy 57600-baud bootloader (older clones):
# replace `cpu=atmega328` with `cpu=atmega328old`
Die Firmware verwendet Adafruit_Fingerprint. Die IDE bietet an, es beim ersten Kompilieren zu installieren.
Wenn arduino-cli upload mit not in sync: resp=0x7e fehlschlägt, ist Ihr Bootloader die andere Variante — tauschen Sie atmega328 ↔ atmega328old und versuchen Sie es erneut. Beide funktionieren; der Unterschied ist nur die Bootloader-Baudrate.
Erfordert Rust 1.95+.```bash cd pcside/daemon cargo build --release
### 3. Installation```bash
sudo bash pcside/daemon/dist/install.sh
Dieses Skript:
target/release/r503d nach /usr/local/bin/r503d/var/lib/r503d/ (Modus 0700 root:root) für den Schlüssel, den Zustand und die Benutzer-Slot-Registrierung/dev/r503 bereitstellt und den Geräteknoten auf root:root 0600 sperrt (nur der Daemon, der als root läuft, benötigt ihn; dies schließt den Standardpfad 0660 root:dialout, sodass kein anderer lokaler Benutzer den Port öffnen kann — Sicherheitsaudit 2026-05-28 / H1). Konsequenz: Nach der Installation benötigt jeder manuelle arduino-cli/serial-monitor-Befehl gegen /dev/r503 sudo./etc/systemd/system/r503d.service)net.reactivated.Fprint/usr/share/polkit-1/actions/net.reactivated.fprint.device.r503d.policy), die vom Aufruferidentitäts-Gate verwendet wird/etc/dbus-1/system.d/net.reactivated.Fprint.conf) — nur Mitglieder von root und wheel können mit dem Daemon sprechen; alle anderen erhalten AccessDenied am Broker, bevor der Daemon den Aufruf siehtfprintd.servicer503d.serviceEs ist idempotent — führen Sie es nach jedem cargo build --release erneut aus, um die neue Binärdatei bereitzustellen.