Skip to content

FIDO2: creation of resident credential fails after "Allow Host Access?" #107

Description

@juliadin

Before filing

  • I searched the existing issues and this is not a duplicate.
  • This is not an exploitable security bug (those go to a private advisory, not here).
  • I can still reproduce it on current main.

Area

FIDO2 / U2F / passkeys / ssh-sk

Firmware build

d9361ea build with display,strict-config 16M

Board

Waveshare RP2350-Touch-LCD-2.8

Host environment

nixos 26.11 unstable, Debian 12 as well

What happened

When I try to establish a resident credential (or discoverable? how dies FIDO call them?) the key hangs on the "Approved" screen with the green check.

Steps to reproduce

  1. ssh-keygen -t ed25519-sk -O resident
  • or ssh-keygen -t ecdsa-sk -O resident
  • or use the browser on a website that creates a discoverable credential (skips the two 'use this key' prompts)
  1. on the device: "Use this key?" -> hold to approve
  2. on the device: "Use this key?" -> hold to approve (again)
  3. on the device" "Allow host access?" -> hold to approve

The device is now stuck on the green check mark. I waited for 10 Minutes, the device does not recover.

Output / logs

Anything else

No response

Activity

  1. juliadin commented on Sep 4, 2026

    @juliadin
    ContributorAuthor

    I have to amend this. I realized that I had a problem flashing the current main. When I managed I wasn't able to get my board or a fresh one from the shelf to a responsive state so... I actually can not reproduce the error on current main and the hash I had on the device, able to reproduce was in fact 327fd28

  2. TheMaxMur commented on Sep 8, 2026

    @TheMaxMur
    Owner

    Hey, can you build firmware from develop branch and test?

  3. juliadin commented on Sep 11, 2026

    @juliadin
    ContributorAuthor

    I am sorry to say that 95afb25 still seems to have the problem for me.

  4. TheMaxMur commented on Sep 15, 2026

    @TheMaxMur
    Owner

    Hey, can you build firmware from develop branch and test?

  5. juliadin commented on Sep 15, 2026

    @juliadin
    ContributorAuthor

    On it

  6. juliadin commented on Sep 15, 2026

    @juliadin
    ContributorAuthor

    Sad to say, it doesn't work, but it now behaves differently:

    RS-Key on  HEAD (5f36634) [!] via 🦀 v1.96.0 via ❄  impure (nix-shell-env) took 18s
    ❯ ssh-keygen -t ed25519-sk -O resident
    Generating public/private ed25519-sk key pair.
    You may need to touch your authenticator to authorize key generation.
       -- Device asks for 'Hold to approve once (`use this key?`), then returns to home screen
    Enter PIN for authenticator: 
    You may need to touch your authenticator again to authorize key generation.
    Key enrollment failed: invalid format
    
    RS-Key on  HEAD (5f36634) [!] via 🦀 v1.96.0 via ❄  impure (nix-shell-env) took 21s
    ❯ ssh-keygen -t ecdsa-sk -O resident
    Generating public/private ecdsa-sk key pair.
    You may need to touch your authenticator to authorize key generation.
       -- Device asks for 'Hold to approve once (`use this key?`), then returns to home screen
    Enter PIN for authenticator:
    You may need to touch your authenticator again to authorize key generation.
    Key enrollment failed: invalid format
    

    non-resident key generation will ask "use this key?" twice, then after acceptance ask if I want to "Save new passkey for this account?" (the account mentioned is ssh: - which seems more like the flow for a resident key.

    I built and flashed 5f36634 with VIDPID=Yubikey5 LED_KIND=none FLASH_SIZE=16M BOARD=waveshare-touch-lcd cargo build --release -p firmware --features strong-pin,display

  7. TheMaxMur commented on Sep 17, 2026

    @TheMaxMur
    Owner

    Thanks for testing! The new output tells me a lot: this key has no FIDO PIN set, and that is where "invalid format" comes from.

    Why "invalid format"

    On a display build, getInfo always includes the uv option, and it turns true only once a FIDO PIN is set. OpenSSH checks that uv is present, not that it is true, so it asks for on-device verification anyway. libfido2 sees uv: false and refuses on the host side, and ssh-keygen falls back to asking for a PIN. That PIN goes to the key, the key answers PIN_NOT_SET, and OpenSSH has no message for that error, so it prints "invalid format".

    Your log fits: the PIN prompt came from the terminal, and the panel never showed "Allow host access?". That screen only appears when a FIDO PIN is set. You did get it in your first report, so the board had a FIDO PIN back then.

    Easy to miss: a display build has two separate PINs. The "Set a PIN?" screen on first boot sets the device PIN, which locks the on-device menus. ssh-keygen needs the FIDO PIN, which is set separately. I'll make that clearer in the docs.

    This also means your run never reached the part that froze before. The freeze was in the on-panel PIN pad, and that pad only opens when a FIDO PIN is set. So I still need a retest for the original bug.

    Could you try this?

    1. On the panel, open Settings → Security. Does the second row say "Set FIDO PIN" or "Change FIDO PIN"? (From the host, fido2-token -I /dev/hidrawN shows noclientPin when there is none.)

    2. Set a FIDO PIN there. Your build has strong-pin, so it needs at least 6 digits, and the pad refuses easy patterns like 123456, 121212 or 112233 with "Too easy to guess".

    3. If you had "Scramble PIN pad" on before, turn it on again. The freeze needed it.

    4. Run ssh-keygen -t ed25519-sk -O resident again. On the emulator, with a FIDO PIN set, the prompts were:

      • panel: "Allow host access?" (hold), then the FIDO PIN on the panel pad;
      • terminal: "Enter PIN for authenticator" (the same FIDO PIN);
      • panel: "Allow host access?" twice, then "Save".

      Add the "Use this key?" touches from the next section if you don't pass -O device=.

    5. Since 95afb25, did you reset the key, erase the flash, or switch boards? If the FIDO PIN disappeared only because you reflashed, that's a separate bug and I want to know.

    The double "Use this key?"

    libfido2 in nixpkgs is built with PC/SC support. With pcscd running, it finds the board twice: once over HID and once over CCID (fido2-token -L should list both). When OpenSSH finds more than one device, it sends a touch request to each and waits for one. Both are the same board, so the board asks once per request. Point ssh-keygen at the HID device to skip this:

    ssh-keygen -t ed25519-sk -O resident -O device=/dev/hidrawN
    

    "Save new passkey" on a non-resident key

    Fair point. The card is the same for every registration, even when nothing is stored on the key. I'll word it differently for non-resident keys.

    About the build

    A plain cargo build doesn't embed the partition table that fences the key's storage off from the bootloader. Run the ELF through scripts/pt.sh before flashing:

    scripts/pt.sh target/thumbv8m.main-none-eabihf/release/firmware firmware-pt.elf
    picotool load firmware-pt.elf -t elf
    

    Details: docs/build.md → The partition table

  8. juliadin commented on Sep 17, 2026

    @juliadin
    ContributorAuthor

    oh dear ... yeah ... my bad. I factory resetted a second key for this, set a device pin but not a fido pin... let me check again. Sorry to waste your time.

  9. TheMaxMur commented on Sep 17, 2026

    @TheMaxMur
    Owner

    That's fine; it'll be useful for others too, if anyone else runs into this problem, they can simply read this issue.

  10. juliadin commented on Sep 17, 2026

    @juliadin
    ContributorAuthor

    Scrambled keypad on, pin set, now works exactly as you described... I can also import the key back with 'ssh-add -K'

    though fido-token -L only listed the device once just now... I am neither here or there with the PC/SC daemon right now though because I am testing a lot of stuff.

    I didn't mention the part table fencing step but did it - just wanted to post the build config here so you knew which settings I was working with. Thanks for pointing this out though wherever possible. It's an essential part of the security design as I understand it and the writeup of your threat model and all the thought that went into the design are delightful to read and very very thorough. Thanks for that <3.

    Is it a design limitation with SSH or fido2 in general that the PIN is requested on the terminal as well? It would be neat if users had the benefit of the trusted display there as well ... but I guess that's within the firmware's domain of influence?

    P.S.: tested with authentik and enforcing discoverable credentials as well. that works now, too and it froze before... not very surprising to be honest but I wanted to drop that here, too :).

  11. TheMaxMur commented on Sep 17, 2026

    @TheMaxMur
    Owner

    The issue with entering the FIDO PIN in the terminal lies with OpenSSH. I’ve considered submitting a patch, but I’m not sure what their current stance on LLM-generated code is; I might look into it myself later, but right now I simply don’t have the time or energy.

  12. juliadin commented on Sep 17, 2026

    @juliadin
    ContributorAuthor

    yeah I suspected as much. Thanks for your time :)

  13. thinkingofmaud commented on Sep 19, 2026

    @thinkingofmaud

    same with 37d241d on windows OpenSSH_10.3p1.

  14. thinkingofmaud commented on Sep 19, 2026

    @thinkingofmaud

    The issue with entering the FIDO PIN in the terminal lies with OpenSSH.

    Maybe rsk can be used to enroll the handle after creation.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions