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")
Answered by Documentation Engineer in 791021022

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.

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.

I bumped into this issue via another channel, so I thought I’d provide some additional info here:

  • Based on our current understanding of this issue, it seems to be a bug in iOS itself (FB13879236).

  • As per standard policy, I can’t comment on a timeline for a potential fix. All I can say right now is there there’s no fix in the current iOS 18 beta (18.0b2).

In terms of recommendations:

  • Please continue to re-test as new betas are seeded.

  • This API has been deprecated since the iOS 15 SDK (2021), and its replacement is available in iOS 10 (2016) and later. Regardless of how this pans out, you should block out some time to update your code.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

SecKeyGeneratePair on iOS 18 returning missing SecKeyRef
 
 
Q