Posts

Post marked as solved
15 Replies
3.4k Views
Hello. We have encountered a failure that we haven't seen before regarding use of Secure Enclave private keys and creating cryptographic signatures. We've used this code on thousands of iOS devices (from iOS 11.2 to iOS 14.6) without issue, and recently saw an error that we were not able to find documentation for. We are hoping to find out more details about the failure so that we can avoid it in the future. Steps to Reproduce On an iPhone 11 Pro running iOS 14.4.2, generate a private key in the Secure Enclave via SecKeyCreateRandomKey() with the following parameters. [ kSecAttrTokenID: kSecAttrTokenIDSecureEnclave, kSecAttrKeyType: kSecAttrKeyTypeECSECPrimeRandom, kSecAttrKeySizeInBits: 256, kSecPrivateKeyAttrs: [ kSecAttrAccessControl: SecAccessControlCreateWithFlags( kCFAllocatorDefault, kSecAttrAccessibleWhenUnlockedThisDeviceOnly, [.touchIDAny, .privateKeyUsage], nil )!, kSecAttrIsPermanent: true ], kSecAttrApplicationLabel: "unique label" // a customer identifier ] (Note that app is using deployment target of iOS 11.2, thus the use of .touchIDAny). Fetch the aformentioned key with SecItemCopyMatching(…) with the following parameters: [ kSecClass: kSecClassKey, kSecAttrKeyType: kSecAttrKeyTypeECSECPrimeRandom, kSecAttrKeySizeInBits: 256, kSecReturnRef: true, kSecUseOperationPrompt: "Verify your identity", kSecAttrApplicationLabel: "unique label" // a customer identifier ] Create a signature of a CFData by with the key from step #2: var error: Unmanaged<CFError>? let signature = SecKeyCreateSignature(key, .ecdsaSignatureMessageX962SHA256, data, &error) Expected Result The customer is prompted for Face ID, passes, and SecKeyCreateSignature(…) successfully returns a signature. Note that this method successfully works for us on thousands of devices, from iOS 11.2 to iOS 14.6. Actual Result In a rare isolated case, we are seeing the SecItemCopyMatching(…) succeed and then the SecKeyCreateSignature(…) call fails to display the Face ID prompt. Instead, SecKeyCreateSignature(…) immediately fails and populates an error with the following information: domain: CryptoTokenKit code: -3 localizedDescription: The operation couldn’t be completed. (CryptoTokenKit error -3.) description: "<sepk:p256 kid=1214c04d05261ee3>: unable to sign digest" UserInfo={NSDebugDescription=<sepk:p256 kid=1214c04d05261ee3>: unable to sign digest, AKSError=-536362999} On this particular iPhone 11 Pro device, the customer did not have any issues with this code around 6 months prior to the failure. The customer has more recently encountered the failure, and we have confirmed the device fail to create signatures 100% of the time with the above error. We have asked the customer to reboot the device to no avail, and we have confirmed that Face ID does indeed successfully work on the device's lock screen. The failure still continues. Additional Notes We are not able to find any information about this specific failure from the documentation or additional research on the web. We were able to deduce that that CryptoTokenKit error -3 maps to TKErrorCodeCorruptedData. In the documentation of TKErrorCodeCorruptedData, it is unclear if the corruption is referring to the private key or or to the dataToSign parameter of SecKeyCreateSignature(). Do you have any insight into why/when this error is returned, and how might we avoid it in the future? Thank you.
Posted
by spindel.
Last updated
.