/nanos-app-yubico-otp

Yubico OTP implementation for the Ledger Nano S

Primary LanguageCApache License 2.0Apache-2.0

Yubico OTP implementation for the Ledger Nano S (nanos-app-yubico-otp)

This application can generate symmetric one time passwords compatible with those generated by Yubico's YubiKeys.

This application was developed independently of Ledger or Yubico, and is not endorsed by either. The keys generated with this application should only be used for testing or in in-house authentication systems when authorized by the system's administrators. Specifically, keys generated with this application should not be uploaded to YubiCloud.

Building and running

To build nanos-app-yubico-otp, follow Ledger's instructions to set up a Nano S development environment, then just run make.

To install, run make load. To uninstall, run make delete. To make installation and updating easier, as well as to avoid seeing the "non-genuine application" nag when running the app, follow Ledger's instructions to create a developer key, install it on your Nano S and sign your builds with it.

Key generation

When generating a new key, nanos-app-yubico-otp will generate a random 6-byte public ID. The private ID and AES key are then derived from the public ID as follows:

  1. compute H = SHA256(public ID)
  2. use BIP32 with the Ledger's master key to derive a key K and chain C along a path formed by 0x79756269 ('yubi' in hex) and H
  3. compute D = SHA256(K + C)
  4. seed an AES-256 CTR_DRBG with D
  5. compute AES key = first 16 bytes of output of the DRBG, then private ID = following 6 bytes of output

As this process is entirely deterministic, the same Ledger will always generate the same private ID & AES key when given the same public ID (provided that its master key doesn't change). Only the public ID is stored in the Ledger's persistent memory.

Note: at the moment, any application running on your Nano S can execute this process and derive your secret keys. Reportedly, Nano S firmware 1.4 is going to introduce the possibility of limiting apps to using a pre-determined set of BIP32 paths.

Note: reinstalling or updating nanos-app-yubico-otp will delete the public IDs stored in the Ledger's persistent memory. It is not currently possible to get them back in, which means you won't be able to continue using the same keys. This will be fixed in the version 0.2.0 of nanos-app-yubico-otp, when it will be possible to import a key by entering its public ID.

Note on OTP timestamps

Yubico OTPs include timestamps --- information about how much time had passed since the token was powered on when the token was generated. This information seems to have been intended to be used to aid in detecting phishing attacks (of the kind where a user's OTP is phished but not used immediately, and the user then immediately proceeds to enter another OTP into a legitimate login form).

However, seven years since the release of Yubico's official validator, the feature remains effectively unimplemented (see lines 431--472 of ykval-verify.php in version 2.39 of yubikey-val, especially the comment saying "should we nuke or enable?"). Likewise, none of the 3rd party validation libraries seem to be using the timestamp for anything.

Because the Nano S lacks an accurate RTC, and the timestamps aren't actually used for anything in the real world, nanos-app-yubico-otp does not include accurate timestamps in the generated OTPs. The token's use counter is duplicated instead, to ensure that at least the fake timestamps increase monotonically.

Note on serial numbers

Some services might ask you for your token's serial number when enrolling it. The token's serial number does not affect key or token generation in any way on real Yubikeys, so you should feel free to set it to any random string that the service will accept.

Licensing

nanos-app-yubico-otp is available under the Apache License 2.0, and includes the following 3rd party code: