SecKeyGeneratePair on iOS 18 returning missing SecKeyRef

A call to the API SecKeyGeneratePair in SecureEnclave for iOS18 returns an OSStatus 0 but the SecKeyRef is not present.

Understand that this API is currently deprecated and there are plans to move to the new APIs, but I believe this API should still work in iOS18 as expected for now.

The API works as expected on iPadOS 18.

// Create SE key
let sacRef = SecAccessControlCreateWithFlags(kCFAllocatorDefault,
                                             kSecAttrAccessibleAfterFirstUnlock,
                                             .privateKeyUsage, nil)!
let privKeyAttr = [
    kSecAttrAccessControl: sacRef,
    kSecAttrIsPermanent: true,
] as NSDictionary
os_log("Priv key params: %{public}@", log: osLogger, privKeyAttr)

let keygenAttr = [
    kSecAttrApplicationLabel: attrApplicationLabelSeKey,
    kSecAttrTokenID: kSecAttrTokenIDSecureEnclave,
    kSecPrivateKeyAttrs: privKeyAttr,
    kSecAttrKeyType: kSecAttrKeyTypeEC,
    kSecAttrKeySizeInBits: 256
] as NSDictionary

var error: Unmanaged<CFError>?
os_log("keygen params: %{public}@", log: osLogger, keygenAttr)

var keyRef: SecKey?
let status = SecKeyGeneratePair(keygenAttr,
                              &keyRef,
                              nil)
os_log("SecKeyGeneratePair osStatus: %{public}d, keyRef: %{public}@", log: osLogger, status, keyRef == nil ? "null" : "ref present")

Did this code work as you expect on an earlier version of iOS? If so, please provide feedback (in Xcode, use the Help > Provide Feedback menu), and report the iOS version in which it worked, and the difference between the expected and actual behavior on the iOS 18 Beta release.

You're right to point out that the function is deprecated, consider using SecKeyCreateRandomKey instead, or the higher-level Apple CryptoKit framework. To store CryptoKit keys in the keychain, see this sample project.

SecKeyGeneratePair on iOS 18 returning missing SecKeyRef
 
 
Q