From zero to a working security key in about ten minutes.
This is experimental firmware with no security audit and no secure element. It's fine for trying things out and for credentials you can afford to lose; see the threat model before using it for anything real.
flowchart TD
a["nix develop · cargo build"] --> b["firmware.uf2"]
b --> c["hold BOOT, plug in"]
c --> d["flash: drag-and-drop or picotool load"]
d --> e["board reboots, enumerates over USB"]
e --> f["set PIN, enroll a passkey / ssh key"]
- An RP2350 board (tested: Waveshare RP2350-One; any RP2350 with USB works)
- A USB cable
- Nix with flakes enabled (everything —
toolchain,
picotool, host tools — comes from the dev shell). Without Nix: rustup +rustup target add thumbv8m.main-none-eabihf+ picotool ≥ 2.0, and the Python deps fromflake.nixfor the host tools.
nix develop # first run downloads the toolchain
cargo build --release -p firmware
picotool uf2 convert target/thumbv8m.main-none-eabihf/release/firmware -t elf firmware.uf2This is the touch build: FIDO operations (registering, logging in) require
a press of the presence button (BOOTSEL by default; set PRESENCE_PIN=<gpio> for
a dedicated GPIO button). For a no-touch build (needed by the automated test
suites, or if your board is hard to reach) add --features no-touch. All build knobs:
build.md.
-
Hold the BOOT button while plugging the board in (or hold BOOT, tap RESET). A mass-storage drive named
RP2350appears. -
Flash it, either way:
- Drag-and-drop:
cp firmware.uf2 /Volumes/RP2350/(macOS) or copy it to the mounted drive on Linux. - picotool (more robust — it verifies, and skips the mass-storage layer):
picotool load -v firmware.uf2 && picotool reboot.
The
RP2350drive is a fake FAT volume the bootrom emulates — it only understands the UF2 blocks written to it, not a real filesystem. On some machines the OS's mass-storage layer breaks that (macOS resource-fork sidecar files and Spotlight, buffered or reordered writes, the board rebooting the instant the last block lands), so the copy errors or silently does nothing.picotool loadspeaks the bootrom's PICOBOOT protocol directly, so reach for it whenever the drive never appears or the copy fails. - Drag-and-drop:
-
The board reboots itself and enumerates as
RS-Key Security Key. (The default build uses the project's own USB identity, VID:PID0x1209:0x0001from pid.codes; the PC/SC reader name contains "RS-Key". For a build that presents the YubiKey USB identity soykman/Yubico Authenticator auto-recognize it, build the opt-inVIDPID=Yubikey5flavor — see build.md.)
Check it:
rsk status # FIDO getInfo + secure-boot + backup state, over USB
ykman info # needs the opt-in VIDPID=Yubikey5 build: YubiKey 5A, firmware 5.7.4, 6 appsOn Linux, the CCID half (OpenPGP/PIV/OATH) needs pcscd + a polkit rule
first — see linux.md. FIDO works as soon as the udev rules are in
place.
rsk fido set-pinBrowsers and ssh-keygen will prompt for it when enrolling. 8 wrong attempts
lock the PIN until a reset — standard security-key behaviour.
A passkey — go to any WebAuthn site (or https://webauthn.io to try), register a security key, touch the button when the LED asks.
An SSH key:
ssh-keygen -t ed25519-sk -f ~/.ssh/id_ed25519_sk # touch twice, enter PIN
ssh-copy-id -i ~/.ssh/id_ed25519_sk you@server
ssh -i ~/.ssh/id_ed25519_sk you@server # one touch to log inThe id_ed25519_sk file is a handle, not a key — it is useless without the
board. Copy it to other machines you ssh from.
macOS note: Apple's
/usr/bin/sshhas no FIDO support. Use Homebrew OpenSSH (brew install openssh, then the absolute path/opt/homebrew/opt/openssh/bin/sshor put it first inPATH). Details: guides/ssh.md.
rsk backup export --scheme bip39 # 24 words, write them down
rsk backup finalize # seals the export windowThe words recover your deterministic FIDO identity (ssh-sk logins, 2FA
registrations) onto a fresh board with rsk backup restore. Anyone who has the
words can recreate that identity on their own board, so store them like cash.
They do not cover resident passkeys, OpenPGP or PIV keys — see
guides/seed-backup.md.
- Feature guides — OpenPGP with gpg, PIV, OATH codes, OTP slots, soft-lock, LED colors
- production.md — fuse the master key into OTP + enable secure boot (irreversible, read first)
- threat-model.md — what this device actually protects against