Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

macOS: works with Yubikey 4 but not Yubico Security Key (U2F-only) #166

Closed
candlerb opened this issue May 2, 2020 · 9 comments
Closed
Labels
bug report Something isn't working

Comments

@candlerb
Copy link

candlerb commented May 2, 2020

Background: I am testing out the U2F functionality of OpenSSH, and I have installed OpenSSH 8.2p1 from homebrew under macOS 10.14.6. This has brought in libfido2 1.4.0_1 as well.

When I use a Yubikey 4 it all works fine. I can generate an ecdsa-sk key and authenticate using it.

When I use an older Yubikey U2F-only key, it fails. This is the blue "security key", which identifies itself as:

Security key by Yubico
Product ID: 0x0120
Vendor ID: 0x1050
Version: 3.33
Speed: Up to 12Mb/sec

Mine is pretty old, although it's still made (possibly a newer revision):
https://www.yubico.com/product/security-key-by-yubico

The key I have works quite happily for U2F authentication on websites like Google, Github etc.

This is what I see when I try to generate a key with openssh:

$ ssh-keygen -vvvv -t ecdsa-sk -f ~/.ssh/id_ecdsa_sk2
Generating public/private ecdsa-sk key pair.
You may need to touch your authenticator to authorize key generation.
debug3: start_helper: started pid=54551
debug3: ssh_msg_send: type 5
debug3: ssh_msg_recv entering
debug1: start_helper: starting /usr/local/Cellar/openssh/8.2p1_1/libexec/ssh-sk-helper
debug1: sshsk_enroll: provider "internal", device "(null)", application "ssh:", userid "(null)", flags 0x01, challenge len 0
debug1: sshsk_enroll: using random challenge
debug1: ssh_sk_enroll: using device IOService:/AppleACPIPlatformExpert/PCI0@0/AppleACPIPCI/XHC1@14/XHC1@14000000/HS01@14100000/Security Key by Yubico@14100000/IOUSBHostInterface@0/IOUSBHostHIDDevice@14100000,0

<< pauses here waiting for touch >>

debug1: ssh_sk_enroll: fido_dev_make_cred: FIDO_ERR_RX
debug1: sshsk_enroll: provider "internal" returned failure -1
debug1: ssh-sk-helper: Enrollment failed: invalid format
debug1: ssh-sk-helper: reply len 8
debug3: ssh_msg_send: type 5
debug1: client_converse: helper returned error -4
debug3: reap_helper: pid=54551
Key enrollment failed: invalid format

It seems there is an error coming back from fido_dev_make_cred

Any suggestions what is going on? I wasn't sure whether to raise it here first, or with openssh.
However I believe that OpenSSH and libfido2 have been built correctly, given that it works with the new key. You can see the flags they were built with here:

And the call to fido_dev_make_cred is here.

P.S. Neither Yubikey supports ed25519-sk: the generation fails immediately, without a touch, saying "Key enrollment failed: invalid format". But that's to be expected I think.

@candlerb candlerb added the question Further information is requested label May 2, 2020
@candlerb
Copy link
Author

candlerb commented May 2, 2020

Aside: I note that openssh only calls fido_init when debugging is enabled (which it normally isn't), here and here:

#ifdef SK_DEBUG
        fido_init(FIDO_DEBUG);
#endif

I don't know if skipping this initialization is permitted.

@candlerb
Copy link
Author

candlerb commented May 2, 2020

I was able to capture debug, by rebuilding with SK_DEBUG defined:

--- a/Formula/openssh.rb
+++ b/Formula/openssh.rb
@@ -38,7 +38,7 @@ class Openssh < Formula
   end

   def install
-    ENV.append "CPPFLAGS", "-D__APPLE_SANDBOX_NAMED_EXTERNAL__"
+    ENV.append "CPPFLAGS", "-D__APPLE_SANDBOX_NAMED_EXTERNAL__ -DSK_DEBUG"

     # Ensure sandbox profile prefix is correct.
     # We introduce this issue with patching, it's not an upstream bug.

While waiting for the touch, it chats away like this:

debug1: ssh_sk_enroll: using device IOService:/AppleACPIPlatformExpert/PCI0@0/AppleACPIPCI/XHC1@14/XHC1@14000000/HS01@14100000/Security Key by Yubico@14100000/IOUSBHostInterface@0/IOUSBHostHIDDevice@14100000,0
fido_tx: d=0x7f8ff7600090, cmd=0x06, buf=0x7f8ff7600090, count=8
0000: 28 01 68 31 00 d4 0a c8
fido_rx: d=0x7f8ff7600090, cmd=0x06, buf=0x7f8ff7600098, count=17, ms=-1
rx_preamble: initiation frame at 0x7ffee7d95600
0000: ff ff ff ff 86 00 11 28 01 68 31 00 d4 0a c8 03
0016: 00 86 76 02 01 00 00 01 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=17
fido_rx: buf=0x7f8ff7600098, len=17
0000: 28 01 68 31 00 d4 0a c8 03 00 86 76 02 01 00 00
0016: 01
fido_tx: d=0x7f8ff7600090, cmd=0x03, buf=0x7f8ff7700682, count=73
0000: 00 01 00 00 00 00 40 6e a4 dd 34 0d d2 92 c3 53
0016: 29 ba 51 f8 29 ff 41 c1 7e e1 dd 68 d3 96 43 54
0032: cf d5 b8 f0 0a 04 71 e3 06 10 e8 a1 62 11 59 60
0048: fe 1e c2 23 e6 52 9c 9f 4b 6e 80 20 0d cb 5e 5c
0064: 32 1c 8a f1 e2 b1 bf 00 00
fido_rx: d=0x7f8ff7600090, cmd=0x03, buf=0x7ffee7d95130, count=1200, ms=-1
rx_preamble: initiation frame at 0x7ffee7d94ff0
0000: 03 00 86 76 83 00 02 69 85 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=0x7ffee7d95130, len=2
0000: 69 85
...

After touch:

fido_tx: d=0x7f8ff7600090, cmd=0x03, buf=0x7f8ff7700682, count=73
0000: 00 01 00 00 00 00 40 6e a4 dd 34 0d d2 92 c3 53
0016: 29 ba 51 f8 29 ff 41 c1 7e e1 dd 68 d3 96 43 54
0032: cf d5 b8 f0 0a 04 71 e3 06 10 e8 a1 62 11 59 60
0048: fe 1e c2 23 e6 52 9c 9f 4b 6e 80 20 0d cb 5e 5c
0064: 32 1c 8a f1 e2 b1 bf 00 00
fido_rx: d=0x7f8ff7600090, cmd=0x03, buf=0x7ffee7d95130, count=1200, ms=-1
fido_hid_read: CFRunLoopRunInMode=3
rx: rx_preamble
u2f_register: fido_rx
debug1: ssh_sk_enroll: fido_dev_make_cred: FIDO_ERR_RX
debug1: sshsk_enroll: provider "internal" returned failure -1
debug1: ssh-sk-helper: Enrollment failed: invalid format
debug1: ssh-sk-helper: reply len 8
debug3: ssh_msg_send: type 5
debug1: client_converse: helper returned error -4
debug3: reap_helper: pid=67656
Key enrollment failed: invalid format

I don't know if that helps at all. I can't tell yet if this is a Mac-specific problem, and I guess I'd need to set up a Linux machine with OpenSSH 8.2 to be sure.

I see libfido2 comes with some CLI tools:

$ fido2-token -L
IOService:/AppleACPIPlatformExpert/PCI0@0/AppleACPIPCI/XHC1@14/XHC1@14000000/HS01@14100000/Security Key by Yubico@14100000/IOUSBHostInterface@0/IOUSBHostHIDDevice@14100000,0: vendor=0x1050, product=0x0120 (Yubico Security Key by Yubico)

Let me know if there's anything useful I can try with these.

@candlerb
Copy link
Author

candlerb commented May 2, 2020

This key works under Linux:

root@focal:~# ssh-keygen -vvvv -t ecdsa-sk -f ~/.ssh/id_ecdsa_sk2
Generating public/private ecdsa-sk key pair.
You may need to touch your authenticator to authorize key generation.
debug3: start_helper: started pid=364
debug3: ssh_msg_send: type 5
debug3: ssh_msg_recv entering
debug1: start_helper: starting /usr/lib/openssh/ssh-sk-helper
debug1: sshsk_enroll: provider "internal", device "(null)", application "ssh:", userid "(null)", flags 0x01, challenge len 0
debug1: sshsk_enroll: using random challenge
debug1: ssh_sk_enroll: using device /dev/hidraw0
debug3: ssh_sk_enroll: attestation cert len=544
debug1: ssh-sk-helper: reply len 864
debug3: ssh_msg_send: type 5
debug3: reap_helper: pid=364
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /root/.ssh/id_ecdsa_sk2
Your public key has been saved in /root/.ssh/id_ecdsa_sk2.pub

Setup:

  • base system Ubuntu 18.04

  • lxd container with Ubuntu 20.04

  • passing through the Yubikey:

    lxc config device add focal hidraw0 unix-char path=/dev/hidraw0
    

However, Ubuntu 20.04 uses libfido2 1.3.1, so I can't be sure whether it's a Mac USB issue, or a difference with libfido2 1.4.0.

root@focal:~# dpkg-query -l | grep libfido
ii  libfido2-1:amd64               1.3.1-1ubuntu2                    amd64        library for generating and verifying FIDO 2.0 objects

@martelletto
Copy link
Contributor

Hi,

This looks like a regression with U2F-only devices on macOS introduced by 8f8a99d. The FIDO2 spec gives the impression (to me, at least) that CTAPHID_KEEPALIVE exists in CTAP1 (U2F), when it is actually a CTAP2 extension. If it is not too much hassle, can you try to revert 8f8a99d?

Regarding OpenSSH and fido_init(), OpenSSH should be calling fido_init(). There are currently no ill effects from not calling it, but that might change in the future.

Thanks for the comprehensive report!

-p.

@candlerb
Copy link
Author

candlerb commented May 2, 2020

Yes, that fixes the problem, thank you!


Workaround for homebrew:

--- a/Formula/libfido2.rb
+++ b/Formula/libfido2.rb
@@ -4,6 +4,7 @@ class Libfido2 < Formula
   url "https://github.com/Yubico/libfido2/archive/1.4.0.tar.gz"
   sha256 "ad921fbe7d4bb70e4a971e564cd01f341daf9b5ed5d69b3cbab94a8a811d2a6c"
   revision 1
+  patch :DATA

   bottle do
     cellar :any
@@ -52,3 +53,40 @@ class Libfido2 < Formula
     system "./test"
   end
 end
+__END__

followed by the output of git show 8f8a99d1a -R

@martelletto martelletto added bug report Something isn't working and removed question Further information is requested labels May 2, 2020
@martelletto
Copy link
Contributor

Thanks! I will see what I can do about this bug. It's a bit late here, so hopefully tomorrow.

-p.

@candlerb candlerb changed the title OpenSSH/libfido2 works with Yubikey 4 but not Yubico Security Key macOS: works with Yubikey 4 but not Yubico Security Key (U2F-only) May 2, 2020
@martelletto
Copy link
Contributor

Fixed in 39544a2. Thanks for the detailed report and testing.

@candlerb
Copy link
Author

candlerb commented May 4, 2020

All working fine with that tiny patch.

The odd thing is: according to this matrix, Yubikey 4 is not FIDO2. Perhaps I was just lucky, and being a newer device it was able to complete the crypto operation in less than 300ms?

@martelletto
Copy link
Contributor

I was only able to reproduce the problem with an older Yubikey NEO, so I suppose your theory makes sense: the difference in behaviour is not due to FIDO2-capable devices sending CTAPHID_KEEPALIVE when in U2F-only mode (which would be nonsensical, since CTAPHID_KEEPALIVE is unspecified in U2F), but likely due to different (faster) hardware.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug report Something isn't working
Development

Successfully merging a pull request may close this issue.

2 participants