Search code examples
linuxpkcs#11yubicoyubikeyhardware-security-module

Yubikey API access via NFC


Device and Environment

Secure Element (currently) used: Yubikey 5 NFC

OS (currently) used: Linux (future targets will be Win and Android)

Readers used: ACS ACR122U, REINER SCT cyberJack RFID, SCM SCL011

Goals

Connect to Yubikey via NFC and implement/run the following methods:

  • Create Key Pair
  • Export Public Key
  • Sign
  • Encrypt
  • Decrypt

Current status

Based on Yubico's PKCS#11 wrapper library I implemented the 5 methods above. With the Yubikey connected via USB they work pretty fine.

Issues

1) Docs/Support

I couldn't found any related docs on Yubico's website regarding APIs via NFC. There seems to be no mailing list but a hint:

Ask Technical Questions: For technical questions, try Stack Exchange sites. Stack Exchange is a network of question and answer sites for developers to learn and share their knowledge, which includes Stack Overflow.

Here I am. ;-)

Update according to Alexander (thank you): Some sources are published by Yubico on github at github.com/Yubico

2) Errors on CLI tools

The Yubikey is shown by pcsc_scan on every reader mentioned above.

But using common tools like gp, opensc-tool, pkcs11-tool and pkcs15-tool mostly issue error 0x6A80 is shown when trying to use e.g. common APDU access. I'm not able to see any cardlet or even select one.

(Using other NFC devices I get 0x9000/success and data on some commands which cause 0x6A80 on the Yubikey.)

Example output of gp:

gp -lvdi
[DEBUG] TerminalManager - Selected the only reader with a card
SCardConnect("Yubico YubiKey OTP+FIDO+CCID 00 00", T=*) -> T=1, 3BFD1300008131FE158073C021C057597562694B657940
# GlobalPlatformPro 325fe84
# Running on Linux 5.18.5-100.fc35.x86_64 amd64, Java 11.0.14 by SAP SE
A>> T=1 (4+0000) 00A40400 00 
A<< (0000+2) (1ms) 6A80
Error: Could not SELECT default selected: 0x6A80 (Wrong data/incorrect values in data)
pro.javacard.gp.GPException: Could not SELECT default selected: 0x6A80 (Wrong data/incorrect values in data)
    at pro.javacard.gp.GPException.check(GPException.java:64)
    at pro.javacard.gp.GPSession.discover(GPSession.java:145)
    at pro.javacard.gp.GPTool.run(GPTool.java:208)
    at pro.javacard.gp.GPTool.main(GPTool.java:107)
SCardDisconnect("Yubico YubiKey OTP+FIDO+CCID 00 00", true) tx:5/rx:2

Questions

  1. Where can related docs be found?
  2. Which APIs are available to access the Yubikey via NFC to implement the 5 methods mentioned above?
  3. What needs to be done to use those APIs (e.g. installation of additional libs)?

Updates

2022-08-16

Got a hint: In yubico-piv-tool/blob/master/lib/ykpiv.h is a define of YKPIV_INS_SELECT_APPLICATION with value A4 which looks very common.

Success for select:

# opensc-tool -s 00:A4:04:00:05:A0:00:00:03:08:00 -v
Using reader with a card: ACS ACR122U 00 00
Connecting to card in reader ACS ACR122U 00 00...
Using card driver Personal Identity Verification Card.
Sending: 00 A4 04 00 05 A0 00 00 03 08 00 
Received (SW1=0x90, SW2=0x00):
61 11 4F 06 00 00 10 00 01 00 79 07 4F 05 A0 00 a.O.......y.O...
00 03 08                                        ...

Select file command

2022-08-31

yubico-piv-tool can be used for access via USB and NFC. The "reader" option -r is used for this. Default is Yubikey which can even be abbreviated with Y.

The same "light" matching of reader name happens for NFC readers: The name just need to match roughly. In my case it works with these strings for my three readers: ACR122U, cyberJack and (ancient) SCL011. By specifying the reader names I can easily get the status via NFC.

I asked Yubico support again for docs. But at least I see now a way to investigate by analyzing the yubico-piv-tool source code. Maybe it could be even possible to use PKCS#11 via NFC.

2022-09-25

Success!

tl;dr: Using latest yubico-piv-tool package in version 2.3.0 and re-compiling everything made our PKCS#11 software run via NFC with actually NO changes of our code.

Will do some more tests and will finally phrase a matching answer with all gotchas.

Will keep this updated here.

2022-10-04

With the former "success" message we had one issue that just one reader did work (which must not happen when using pcscd). This was caused by a small bug in slot handling in our PKCS#11 code (when using Yubikey via USB we always had just one slot with one token - with NFC we have three readers/slots).

Still testing. When everything is done then I will post an answer.


Solution

  • There were a couple of issues. Main issues were a bug in our source code on handling multiple readers/slots and an older version (2.2.1) of yubico-piv-tool/libykcs11.so. Current version 2.3.0 from 2022-03-01 works fine.

    As Yubico support said the access to Yubikey via PKCS#11 works transparently via USB and NFC with no changes.

    With pcsc_scan and all my NFC readers connected at the same time I could access "Yubikey 5 NFC" via:

    • USB
    • NFC via ACS ACR122U
    • NFC via REINER SCT cyberJack RFID
    • NFC via SCM SCL011

    Except fixing the bug for handling multiple slots there were no changes in our PKCS#11 source code required to access Yubikey via NFC.

    To finally answer my questions:

    1. "Where can related docs be found?" => On Yubico website and on Yubico Github projects.
    2. "Which APIs are available to access the Yubikey via NFC to implement the 5 methods mentioned above?" => Just use the PKCS#11 API and libykcs11.so from yubico-piv-tool >= 2.3.0.
    3. "What needs to be done to use those APIs (e.g. installation of additional libs)?" => No additional API is required. Just use PKCS#11.