Yubico / libfido2

Provides library functionality for FIDO2, including communication with a device over USB or NFC.
Other
581 stars 153 forks source link

Unable to use FIPS key with libfido2 #783

Closed VedaviBalaji closed 5 months ago

VedaviBalaji commented 7 months ago

What version of libfido2 are you using? 1.14.0

What operating system are you running? macOS

What application are you using in conjunction with libfido2? Rust

How does the problem manifest itself? Always

Does the problem happen with different authenticators? Only on FIPS

Device type: YubiKey FIPS
Firmware version: 4.4.5
Enabled USB interfaces: OTP, FIDO

Applications
OTP             Enabled
FIDO U2F        Enabled
FIDO2           Not available
OATH            Disabled
PIV             Disabled
OpenPGP         Disabled
YubiHSM Auth    Not available

I have couple of things happening. Sometimes, the device does not open. (\ are custom application logs)

run_manifest: found 2 hid devices
\\ FIDO new device detected: device: 0, Path: ioreg://4295006647, name: Yubikey 4 OTP+U2F, manufacturer: Yubico 
fido_hid_open: IOHIDDeviceOpen
fido_dev_open_tx: dev->io.open
\\ Unable to open device. **

\\ FIDO new device detected: device: 1, Path: ioreg://4295035120, name: YubiKey OTP+FIDO+CCID, manufacturer: Yubico 
 fido_tx: dev=0x60000112a910, cmd=0x06
fido_tx: buf=0x60000112a910, len=8
0000: ec 5b 7b 17 c3 c1 5b fd
fido_rx: dev=0x60000112a910, cmd=0x06, ms=-1
rx_preamble: buf=0x7000062bcd80, len=64
...

Sometimes it opens but unable to get touch status Fails with 0x63c0

run_manifest: found 2 hid devices
 fido_rx: dev=0x6000036bfa80, cmd=0x03, ms=50
 rx_preamble: buf=0x70000b94ed80, len=64
0000: 00 7c 00 03 83 00 02 63 c0 00 00 00 00 00 00 00
 0016: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0032: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
 0048: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
rx: payload_len=2
 fido_rx: buf=0x7fc4b6864600, len=2
 0000: 63 c0
u2f_get_touch_status: unexpected sw
\\ Unable to get touch status

fido_rx: dev=0x6000036ebb10, cmd=0x10, ms=50
...

 fido_rx: dev=0x6000036bfa80, cmd=0x03, ms=50
 fido_hid_read: read: Resource temporarily unavailable
 rx: rx_preamble
u2f_get_touch_status: fido_rx
fido_rx: dev=0x6000036ebb10, cmd=0x10, ms=50

Does libfido2 work with FIPS key for macOS? I have 2 devices connected, one is FIPS (that doesn't work) and the other is FIDO2 device (works as expected).

LDVG commented 7 months ago

Hi,

Please see the YubiKey FIPS 4-series technical manual, section 2.5 U2F. The device must have a PIN set, through a proprietary instruction, and then unlocked by the user (once per power-up). That functionality is available in ykman. After unlocking, you should be able to communicate with the device without problem using libfido2.

VedaviBalaji commented 7 months ago

From what I read, looks like we need to unlock the device only for registration. We can still use authentication in "locked" state (which is what I mostly need). But when there are multiple keys, we need to perform begin_touch which internally seems to perform a dummy registration, which is not accepted by FIPS without unlocking, so my device selection does not work. This means to authenticate I can have only one FIPS device connected to the system. Let me know if this is right.

Also, if sometimes, I am unable to open the device, when only FIPS key is connected to the machine. Fails with

fido_hid_open: IOHIDDeviceOpen
fido_dev_open_tx: dev->io.open

But, if multiple keys are present, it opens fine, but touch fails due to dummy registration. Can we replace registration with auth cmd? I can try it out locally, but what are your thoughts?

LDVG commented 7 months ago

From what I read, looks like we need to unlock the device only for registration

Yes, that is correct.

But when there are multiple keys, we need to perform begin_touch which internally seems to perform a dummy registration, which is not accepted by FIPS without unlocking, so my device selection does not work.

Unfortunately, yes, fido_dev_get_touch_begin() will not work if the FIPS device is not unlocked.

This means to authenticate I can have only one FIPS device connected to the system.

Since the device speaks U2F, you could also silently probe the device(s) using a "pre-flight" assertion to determine if it holds the credential you're trying to authenticate with.

Also, if sometimes, I am unable to open the device, when only FIPS key is connected to the machine.

I have not seen this before and we'd probably need more information to debug it. Does it happen under any particular circumstance? It would be nice to see what IOHIDDeviceOpen returns when it fails. The patch below should log the result if you're interested in helping out:

diff --git a/src/hid_osx.c b/src/hid_osx.c
index 41e9d171..60064951 100644
--- a/src/hid_osx.c
+++ b/src/hid_osx.c
@@ -395,6 +395,7 @@ get_ioreg_entry(const char *path)
 void *
 fido_hid_open(const char *path)
 {
+   IOReturn         ostatus;
    struct hid_osx      *ctx;
    io_registry_entry_t  entry = MACH_PORT_NULL;
    char             loop_id[32];
@@ -448,9 +449,9 @@ fido_hid_open(const char *path)
        goto fail;
    }

-   if (IOHIDDeviceOpen(ctx->ref,
-       kIOHIDOptionsTypeSeizeDevice) != kIOReturnSuccess) {
-       fido_log_debug("%s: IOHIDDeviceOpen", __func__);
+   if ((ostatus = IOHIDDeviceOpen(ctx->ref,
+       kIOHIDOptionsTypeSeizeDevice)) != kIOReturnSuccess) {
+       fido_log_debug("%s: IOHIDDeviceOpen: %d", __func__, ostatus);
        goto fail;
    }

Can we replace registration with auth cmd? I can try it out locally, but what are your thoughts?

Are you referring to replacing the mechanism for how fido_dev_get_touch_*() work? No, if you were to send an authenticate command instead, the device would return an error immediately instead of waiting for touch.

LDVG commented 5 months ago

Closing this for now. Feel free to re-open if this is still an issue.