Using the Secure Enclave on Mac Book

I'm trying to write a proof-of-concept for using a key generated in the secure enclave, following the instructions from here: https://developer.apple.com/documentation/security/certificate_key_and_trust_services/keys/storing_keys_in_the_secure_enclave


Using that, I have the following code:

import Foundation
import Security
let access =
    SecAccessControlCreateWithFlags(kCFAllocatorDefault,
                                    kSecAttrAccessibleAlways,
                                    .privateKeyUsage,
                                    nil)!
let attributes: [String: Any] = [
    kSecAttrKeyType as String:            kSecAttrKeyTypeEC,
    kSecAttrKeySizeInBits as String:      256,
    kSecAttrTokenID as String:            kSecAttrTokenIDSecureEnclave,
    kSecPrivateKeyAttrs as String: [
        kSecAttrIsPermanent as String:      true,
        kSecAttrApplicationTag as String:   "com.example.keys.mykey".data(using: .utf8)!,
        kSecAttrAccessControl as String:    access
    ]
]
var error: Unmanaged<CFError>?
guard let privateKey = SecKeyCreateRandomKey(attributes as CFDictionary, &error) else {
    throw error!.takeRetainedValue() as Error
}
print("Successfully generated private key!")


However, when running this I get the following error:


Fatal error: Error raised at top level: Error Domain=NSOSStatusErrorDomain Code=-50 "failed to generate asymmetric keypair" (paramErr: error in user parameter list) UserInfo={NSDescription=failed to generate asymmetric keypair}: file /BuildRoot/Library/Caches/com.apple.xbs/Sources/swiftlang/swiftlang-900.0.74.1/src/swift/stdlib/public/core/ErrorType.swift, line 187
2018-02-06 00:33:00.299731-0800 signit[16668:214771] Fatal error: Error raised at top level: Error Domain=NSOSStatusErrorDomain Code=-50 "failed to generate asymmetric keypair" (paramErr: error in user parameter list) UserInfo={NSDescription=failed to generate asymmetric keypair}: file /BuildRoot/Library/Caches/com.apple.xbs/Sources/swiftlang/swiftlang-900.0.74.1/src/swift/stdlib/public/core/ErrorType.swift, line 187
(lldb)


I checked out the system logs and see this line:

default 00:25:52.787319 -0800 secd signit[16635]/1#-1 LF=0 add Error Domain=NSOSStatusErrorDomain Code=-50 "storing items into kSecAttrAccessGroupToken is not allowed" (paramErr: error in user parameter list) UserInfo={NSDescription=storing items into kSecAttrAccessGroupToken is not allowed}


Is there something I'm missing to be able to generate persistant secure enclave keys?

Accepted Reply

The code I have for this is very similar, the only difference being that I put the tag on both keys rather than just the private key.

paramsDict = [
    kSecAttrKeyType as String:           kSecAttrKeyTypeEC, 
    kSecAttrKeySizeInBits as String:     256, 
    kSecAttrTokenID as String:           kSecAttrTokenIDSecureEnclave, 
    kSecAttrApplicationTag as String:    appTag, 
    kSecPrivateKeyAttrs as String: [
        kSecAttrIsPermanent as String:   true, 
        kSecAttrAccessControl as String: access,
    ],
]

How are you signing your app? To get started you should sign your app as a Mac App Store development build. That’ll ensure you have direct access to the iOS-style keychain, which is required for the Secure Enclave.

Note I believe that you can use the Secure Enclave from a Developer ID app, it’s just a bit more complex to set up. Thus, if your final goal is Developer ID then I recommend that you start with a Mac App store development build and then, once you have that working, deal with the Developer ID side of things.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

Replies

The code I have for this is very similar, the only difference being that I put the tag on both keys rather than just the private key.

paramsDict = [
    kSecAttrKeyType as String:           kSecAttrKeyTypeEC, 
    kSecAttrKeySizeInBits as String:     256, 
    kSecAttrTokenID as String:           kSecAttrTokenIDSecureEnclave, 
    kSecAttrApplicationTag as String:    appTag, 
    kSecPrivateKeyAttrs as String: [
        kSecAttrIsPermanent as String:   true, 
        kSecAttrAccessControl as String: access,
    ],
]

How are you signing your app? To get started you should sign your app as a Mac App Store development build. That’ll ensure you have direct access to the iOS-style keychain, which is required for the Secure Enclave.

Note I believe that you can use the Secure Enclave from a Developer ID app, it’s just a bit more complex to set up. Thus, if your final goal is Developer ID then I recommend that you start with a Mac App store development build and then, once you have that working, deal with the Developer ID side of things.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"