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

Almost works: YubiKey 5Ci (Lightning side) on USB-C devices via Apple’s USB-C to Lightning adapter #144

Open
keepassium opened this issue Jan 17, 2024 · 7 comments

Comments

@keepassium
Copy link

We have confirmed that YubiKey 5Ci — the Lightning side of it — works with Yubikit as an MFI accessory on USB-C devices like iPhone 15. And I mean works as an MFI accessory, including the challenge-response mode. All it takes is Apple USB-C to Lightning adapter introduced at the end of 2023.

The only problem is that YubiKitDeviceCapabilities.supportsMFIAccessoryKey self-censors USB-devices as incompatible with MFI accessories. Our app uses an older version of YubiKit which did not know anything about iPhone 15, so it left MFI accessory interface enabled. And it worked, via Apple's adapter.

Would it be possible to extend YubiKitDeviceCapabilities with something like supportsMFIAccessoryWithAdapter?

@namelessmasses
Copy link

I may be OT-ish here, and I'm still curious that maybe I'm missing something about your situation (highly likely I'm missing something)... If you have a 5Ci - which has both USB-C and Lightning connectors - why would need a USB-C/Lightning adapter? I also have a 5Ci and I use the Lightning MFi on an iPhone 12 and the USB-C on an iPad Air (5th Gen.) with full functions and no issues in either case.

@keepassium
Copy link
Author

@namelessmasses, it's a bit messy, so bear with me.

According to this doc, OpenPGP application "can be accessed over the Smart Card connection when using any transport." Smart Card connections are natively supported on iOS 16+ (if I remember correctly), so you are all set.

However, challenge-response belongs to the OTP application which "can be accessed over the OTP connection when using the USB transport, and over the Smart Card connection when using the NFC and Lightning transports." Where the OTP connection "is available over the USB transport by using the OTP USB interface. It allows communication with the YubiKey by sending and reading HID feature reports".

Basically, performing challenge-response via USB requires sending/receiving raw HID reports — which is a no-go on iOS. So the only option is to relay it via Lightning.

@namelessmasses
Copy link

@keepassium hey, I'm just grateful you took the time to write a meaningful reply.

I feel like I'm still missing something here.

  1. Is your reference to OpenPGP application orthogonal to challenge-response over USB?

As far as HID issues I was honestly in disbelief until I just fired up the Demo app on my iPad (USB-C) and it reports "This device or version of iOS does not support operations with MFi Yubikeys."

  1. Isn't the Yubikey OTP USB interface supposed to act as a USB keyboard?
    1. How is it that a USB keyboard works then if HID a no-go on iOS?

I feel like there's something really odd here.

@keepassium
Copy link
Author

Is your reference to OpenPGP application orthogonal to challenge-response over USB?

Yes. Not all applications on YubiKey are available via all connections. So I needed an example of something that works on all connections to contrast it with challenge-response which is more picky.

As far as HID issues I was honestly in disbelief until I just fired up the Demo app on my iPad (USB-C) and it reports "This device or version of iOS does not support operations with MFi Yubikeys."

Apparently, this is based on Yubico's assumption which they encoded in Yubikit. But the assumption is wrong.

My app still uses a slightly modified Yubikit 3.2.0 from 2020. (Not fixing what ain't broken.) Back in 2020, the library assumed all iOS devices are MFi-capable, so it just tries to perform MFi even on a USB-only device. Practice shows, this actually works (with Apple's adapter) in contrast to Yubico's assumptions.

Isn't the Yubikey OTP USB interface supposed to act as a USB keyboard?
How is it that a USB keyboard works then if HID a no-go on iOS?

Yes, the OTP function does emulate a keyboard and types out the code — one-way communication from YubiKey to iOS. The HID part is handled by the system, and apps just receive keyboard input.

However, the challenge-response function needs two-way communication at a lower level. One does not simply send a challenge to system keyboard :) Instead, the app itself (not the system) must form and send raw HID frames. And this is not possible within iOS SDK.

@namelessmasses
Copy link

@keepassium my disbelief and refusal to accept that there could be such injustice in the universe has had me digging through this today... really, it's my general frustration and confounded curiosity with people making horrible assumptions when writing software libraries 😖

  1. Found some interesting code in the yubikit
  2. Reached the logic of "how does one send a challenge to a USB keyboard?"

... at least as far as finding that internally yubikit just instantiates a SmartCardInterface over whatever connection its provided and sends the APDU to select the ChallengeResponse application... I was just digging through the yubikit implementation of sendChallenge, then I saw your last response.

@keepassium
Copy link
Author

@namelessmasses , thank you for the interesting link. I guess this is a rudiment in the library, in case a future YubiKey model would support OTP over CCID.

In the meanwhile, I found a better document on how different YubiKey applications are mapped to USB transports. Sadly, OTP — and therefore challenge-response — is an outlier, and this is set in stone silicon:

OTP was available over Smart Card in the YubiKey NEO. Most OTP operations are now blocked over smart card.

And here the yubikit engineer directly confirmed that pretty much everything would work via TKSmartCard — except challenge-response :)

@namelessmasses
Copy link

@keepassium wow, my curiosity has brought me to a place of dismay leading to even further curiosity.

I even ran a few APDUs through opensc-tool on a non-iOS host and got excited when SELECT for the OTP application returned 9000.

Sadly, under the 0x1 instruction, every permutation of P1/P2 values for Yubico OTP/HMAC-1 and Slot1/Slot2 fails with either SW1/SW2 6985 or 6D00.

I really wondering why support for it over SmartCard was dropped in firmware. Makes me wonder is there something less secure about SmartCard?

Just seems kind of "crappy" to drop support like that especially those links where their announcements make it sound "more supported".

Well, thanks for your patient responses with me. I'm actually "here" to implement a proper OpenPGP source level API instead of having to deal with writing all of the APDU code over and over. I split my work into "minimal" and "expanded" use-cases. With the minimal use-cases now well specified I want to look at the expanded cases and see if there's anything like this. The OpenPGP SmartCard spec does have an INTERNAL AUTHENTICATE instruction that can use a certificate outside of the OpenPGP environment. From the spec

If a process needs a certificate from the card that is not provided by OpenPGP (e. g. x.509), then it can be stored in the DO 'Cardholder certificate' (7F21 AUT) as 1st occurrence.

That might be something you could offer your customers instead of them having to buy yet another adapter.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

No branches or pull requests

2 participants