Thoughts on Apple’s FIDO2 Support

Robert Quattlebaum
3 min readMar 25, 2020

--

Picture of two FIDO Authenticators; CC BY-SA 4.0

Safari on both iOS and macOS has supported FIDO2 authenticators for several months now. In some cases it works great, but in others not so much. I haven’t found any comprehensive analysis of the implementation and its quirks, so I figured I would go ahead and write up what I’ve learned.

Note that this post only applies to macOS 10.15.2 and iOS 13.4. Things could change in later versions.

What’s supported

  • USB-HID CTAP1 and CTAP2 authenticators are supported on both iOS and macOS, which includes all USB-based U2F and FIDO2 security keys
  • NFC Type-A CTAP2 authenticators can register and authenticate on iOS.
  • Both resident and non-resident keys are supported
  • U2F login flow (Username+password required) is supported
  • Single-factor login flow (no username, no password, no PIN) is supported
  • Direct Attestation is supported (but read caveats below)

What’s not (yet?) supported

  • PIN entry. If the authenticator indicates that it needs a PIN for an operation, Safari will not attempt to use the authenticator further.
  • Bluetooth Low Energy (BLE) authenticators are not supported.

What’s Broken

  • iOS: NFC CTAP1-only authenticators do not work on iOS unless they return a CTAP2 error for the CTAP2 info command. (FB7630100)
  • iOS and macOS: All CTAP1 (U2F) registration responses that have a 70-byte attestation signature will be rejected, which means that around 25% of all registration attempts using CTAP1-only (FIDO U2F) authenticators will fail. Users can just try again until it works, so not a huge setback overall. Authentications do not seem to be affected. (FB7639773) This is likely due to Apple directly using the ECDSA signature length values from the FIDO U2F Raw Message Formats specification, which incorrectly states that the signature length will be between 71 and 73 bytes instead of 70 and 72. Oops.

Caveats

  • iOS: A Yubico FIDO2 authenticator that has a PIN set can’t currently be registered with a new service over NFC. USB with the same authenticator works fine. This is due to the device’s insistence that ALL “makeCredential” requests received over NFC must require a PIN to be entered (if a PIN is set), even when the same operation using CTAP1 would not require a PIN. Android doesn’t have this problem because it will always use CTAP1 if there are no features requested that require CTAP2.
  • iOS and macOS: No indication is given to the user if the website/RP is requesting direct attestation, the platform simply hands over the attestation certificate without question. Contrast this with the superior behavior of Chome, which informs the user that they are sending over the attestation. This is important because attestation information can be used to correlate activity and potentially identify a user. (There is some discussion about if such disclosure is an actual Webauthn requirement. If it is a citable requirement then I’ll move this to the “What’s Broken” section above)
  • iOS: When using NFC authenticators on iOS, the platform sends extended APDUs to the authenticator (most Android devices send standard APDUs). This is entirely acceptable according to the FIDO2 standards. However, if the authenticator’s implementation of extended APDUs is broken, some or all FIDO2 actions may not work. This condition may be common on uncertified authenticators that haven’t been well tested. Certified FIDO2 authenticators, as well as models that have passed the certification tests but aren’t certified, should work fine. The fix for people owning such authenticators is to to replace them: Apple is doing everything right in this case.
  • iOS and macOS: No indication is given to the user if the website/RP is requesting a resident key. Many roaming authenticators have limited space available and limited ability to manage existing registrations. To be fair, Chrome doesn’t do this either.

--

--