Skip to content

danielinux/fidelio

Repository files navigation

Fidelio

Turn a rp2040 into a personal authentication key

Universal FIDO2/U2F key using Raspberry Pi Pico (rp2040) and wolfCrypt. Works with any raspberry-pi pico device with only one component added (pushbutton on GPIO15).

Goals and security model

Fidelio implements a FIDO2 authenticator (CTAP2/WebAuthn) with CTAP1/U2F compatibility, generally used as second factor in 2FA services, or in some specific cases for password-less authentication.

Associating a 2FA authentication service to a hardware key as second factor will require the user to provide the key to prove that they are still in possess of the hardware key that was initially registered.

The holder of the key can only prove the physical presence of the key during an authentication procedure. This is done by connecting it via USB and pushing a button.

Through this mechanism, the authenticator is given a proof that the request has been processed (signed) by the same key initially registered, so the user can be trusted as the authenticator assumes that the user is still holding the key.

Two-factor authentication based on FIDO mechanisms is generally considered more secure than time-based OTP services, like mobile apps or other devices that require clock synchronization with the authenticating party.

The device creates a unique private key, which is then used to derive the keys for the authenticating services requesting a FIDO authentication. This means that Fidelio does not pose any storage limitation on the number of authentication services that can be registered, as the same key is derived again whenever needed and it's never stored on the device. CTAP1/U2F remains supported for legacy services; CTAP2/WebAuthn is the primary protocol.

The codebase is simple and rather small, allowing for an easy full audit of the security model and the related implementations.

Security considerations

The security of Fidelio depends entirely on the physical presence of the hardware. If Fidelio is lost or stolen, the second factor of all the registered services must be considered compromised, and the keys associated to the device should be revoked from all the associated services. This usually does not represent an important security risk in itself, as long as a first factor is in use (commonly, password authentication).

A rp2040 board running Fidelio will not store any credentials or traces that can be associated with any running server. The only two pieces of information stored in the target's FLASH memory are the device's master key, generated on first use, and counters keeping track of crypto operations, as mandated by the FIDO protocols.

Hardware requirements

FIDO/U2F mandates the use of a single button to indicate that the user is actually present when the key is used. Without this button the authenticator will never assert user presence.

For this purpose, Fidelio requires a normally-open push-button between GPIO15 and GND.

On the Raspberry-pi pico board, this button can normally be soldered in place:

Raspberry Pico soldering

If you are using a different model and/or you want to change the pin for the presence button and LED, just edit pins.h and change the pin number defined by the macro PRESENCE_BUTTON and U2F_LED, respectively.

Build and flash:

  1. Clone this repository, create and populate build directory
git clone https://github.com/danielinux/fidelio.git
cd fidelio
git submodule update --init --single-branch pico-sdk lib/wolfssl
cd pico-sdk
git submodule update --init --single-branch lib/tinyusb
cd ..

  1. Create your own attestation certificate. This is required only once. The certificate generate will univocally identify your device.

You may change/customize the details in the certificate by editing the mkcert.sh script.

./mkcert.sh
  1. Configure CMake (pass the full absolute path to pico-sdk):
cmake -B build -DPICO_COPY_TO_RAM=1 -DFAMILY=rp2040 -DPICO_SDK_PATH=/path/to/fidelio/pico-sdk
  1. Compile:
cmake --build build
  1. Flash to the Pico (hold BOOTSEL when plugging in, then copy):
cp build/fidelio.uf2 /path/to/RPI-RP2

First run: generating the master key

The first time the device is plugged in into the computer, it will randomly generate its master key. The master key will be then used, for the entire lifetime of the device, to generate keys for single FIDO services.

Updating the Fidelio firmware to a newer version will not overwrite the master key, so the key will keep working with services that had been registered with the old firmware as well.

On first boot the LED will stay on while the master key is generated; press the presence button once to acknowledge, then the device will reboot automatically.

Set the FIDO2 PIN

After flashing, set the authenticator PIN:

fido2-token -S /dev/hidrawX    # enter your chosen PIN when prompted

Replace /dev/hidrawX with the device path listed by fido2-token -L. Press the presence button when prompted during this flow.

Testing

Online services

To ensure that your device is correctly working, connect Fidelio to your PC and visit the WebAuthn.io demo: https://webauthn.io/

Use “Register” to create a credential (press the presence button when asked, and enter the PIN you set above), then “Login” to exercise getAssertion.

Usage

Service example: github second factor

Go to your profile settings. Select "Password and authentication" from the Access menu.

Find the "Two factor authentication" configuration at the bottom of the page. Check the "Security Keys" option:

github.com 2FA config

The button "Register new security key" will associate the device running fidelio as a second factor to access your github account. Give it a unique name of your choice.

github.com 2FA security key configured

It is a good idea to configure more than one 2FA mechanism to your account to avoid the risk of being locked out of your account. This of course includes the possibility to use more than one fidelio hardware keys, stored in different places.

Local PAM services

To test on a linux machine install libpam-u2f and pamu2fcfg. Run pamu2fcfg -u $USER > ~/.config/Yubico/u2f_keys (create the directory if needed) and press the presence button when prompted. Add a line such as auth sufficient pam_u2f.so authfile=/home/%u/.config/Yubico/u2f_keys cue to the relevant file in /etc/pam.d (e.g. sudo, login) to allow U2F assertions as password-less auth or as a second factor; see man pamu2fcfg and man pam_u2f for options and multiple-key setups.

For CTAP2/FIDO2 flows install fido2-tools and libpam-fido2. Confirm detection with fido2-token -L, then create a resident PAM credential with fido2-cred -M -h pam://$(hostname) -i $USER > ~/.fido2-cred. Add auth sufficient pam_fido2.so authfile=/home/%u/.fido2-cred rp_id=$(hostname) to the same /etc/pam.d service to use the key for FIDO2 password-less login; see man pam_fido2 for tuning user verification, PIN prompts, and per-service rp_id values (e.g. matching SSH TrustedUserCAKeys hostnames).

Ensure you always keep a root console open when changing pam.d configuration, and test your changes properly after each change to avoid locking yourself out of your machine

About

Fido2+U2F token for 2FA with Raspberry Pi Pico

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Contributors 2

  •  
  •