iOS 13, CryptoKit, Secure Enclave - Enforce biometric authentication ahead of private key usage

Goal: I would like to create a private key in the secure enclave via the cryptokit, store the key's reference in the iOS device's key chain and ensure that the key can only be reinitialized in the secure enclave after the user has authenticated himself via some biometric authentication method.


Current state: So far, I am able to initialize a private key in the secure enclave via the following code:


var privateKeyReference = try CryptoKit.SecureEnclave.P256.KeyAgreement.PrivateKey.init();


Furthermore, I can store and retrieve the corresponding private key's reference from the key chain. After retrieving the reference, I can reinitialize the private key in the secure enclave with the following code:


var privateKeyReference = getPrivateKeyReferenceFromKeyChain();
var privateKey = try CryptoKit.SecureEnclave.P256.KeyAgreement.PrivateKey.init(
  dataRepresentation: privateKeyReference
);


So far everything works as expected and all cryptographic operations with the private key succeed. Now, as far as I understand the spare documentation by Apple, I should be able to modify the first initialization of the private key to something as follows.


let authContext = LAContext();
let accessCtrl = SecAccessControlCreateWithFlags(
  kCFAllocatorDefault,
  kSecAttrAccesibleWhenUnlockedThisDeviceOnly,
  [.privateKeyUsage, .userPresence, .biometryCurrentSet],
  nil
);
var privateKeyReference = try CryptoKit.SecureEnclave.P256.KeyAgreement.PrivateKey.init(
  accessControl: accessCtrl!,
  authenticationContext: authContext
);


Thereby, ensuring that the private key can only be reinitialized, when the user authenticates himself via some biometric authentication method. The initial initialization stil works without any errors.


Problem: However, adding the previous code, I do not get any biometric authentication prompt and can not use the private key at all after reinitialization. The following error is logged whenever I try to execute some cryptographic operation with the reinitialized key, here for example some signing:

Error Domain=CryptoTokenKit Code=-9 "setoken: unable to sign digest" UserInfo={NSLocalizedDescription=setoken: unable to sign digest})


As far as I could guess from here, I think that

Code=-9
refers to the "authenticationNeeded" error.


Question: Can someone point me to some documentation or tutorial how to achieve what I am looking for or explain to me what I am missing?

Thanks!


Cross-Post: https://stackoverflow.com/questions/58102399/apple-ios-13-cryptokit-secure-enclave-enforce-biometric-authentication-ahea

Replies

closes the lock screen password and reopens ,SecKeyCreateSignature error report unable to sign digest


NSData *signature = CFBridgingRelease(SecKeyCreateSignature(privateKey, kSecKeyAlgorithmECDSASignatureMessageX962SHA256, (CFDataRef)data, (void *)&signatureError));



Printing description of signatureError:

Error Domain=CryptoTokenKit Code=-3 "setoken: unable to sign digest" UserInfo={NSLocalizedDescription=setoken: unable to sign digest, AKSError=-536363001}

Post not yet marked as solved Up vote reply of GXLR Down vote reply of GXLR
Any luck with this?