iOS 15 with FaceID authentication error when resetting FaceID

We use biometricID (faceID/touchID) authentication to access to a secret stored in keychain.

We create the access control object with the biometryCurrentSet option as shown to make sure if FaceID / TouchID changes the entry should be invalidated.

let secAccessControlObj = SecAccessControlCreateWithFlags(nil, kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly, .biometryCurrentSet, accessControlError)

Below is the set and get query, Set Query:

[String(kSecClass): kSecClassGenericPassword,
        String(kSecAttrAccount): group as AnyObject,
        String(kSecAttrService): service as AnyObject,
        String(kSecUseAuthenticationUI) : kSecUseAuthenticationUIAllow as AnyObject,
        String(kSecAttrAccessControl) : secAccessControlObj,
        String(kSecValueData) : value as AnyObject,
        String(kSecAttrCreationDate) : Date() as AnyObject]

Get Query:

[String(kSecClass): kSecClassGenericPassword,
        String(kSecAttrAccount): group as AnyObject,
        String(kSecAttrService): service as AnyObject,
        String(kSecUseAuthenticationUI) : kSecUseAuthenticationUIAllow as AnyObject,
        String(kSecAttrAccessControl) : secAccessControlObj,
        String(kSecValueData) : value as AnyObject,
        String(kSecAttrCreationDate) : Date() as AnyObject]

Steps:

  1. Set the value in keychain using the set query above
  2. Reset the faceID
  3. Use the get query to get the value from keychain by authenticating against TouchID/ FaceID.

Result: When we try to get the value from keychain using SecItemCopyMatching(query as CFDictionary, result) we get the error code errSecAuthFailed (-25293) on iOS 15.

Analysis: Prior to this (iOS 14 and below) the error code would be errSecItemNotFound which makes more sense. This is an issue for iOS 15 only as we also get errSecAuthFailed when user backgrounds the app while authenticating with FaceID/TouchID. This creates a ambiguity for us. In our testing when we backgrounded the app while authentication is in progress, we found the actual call to SecItemCopyMatching(::) was made when app's state was actually active but when the call returned the state had become background and the error code was again errSecAuthFailed

This seems to be a bug with iOS 15 as it creates a ambiguity for the caller. I think the error code returned after resetting faceID should still be errSecItemNotFound in which case we can know the secret is actually lost since FaceID is reset and can treat errSecAuthFailed as error where the secret is actually not lost but just that failed temporarily.

Please let us know if we need to file a bug

  • Just meet the same issue, errSecAuthFailed makes no sense in this scenario... especially when you use Keychain ACL to do login check for security reason...

    I think this is a bug.

Add a Comment

Replies

Just meet the same issue, errSecAuthFailed makes no sense in this scenario... especially when you use Keychain ACL to do login check for security reason...