Hello everyone,
I'm trying to understand the actual limitations of the Secure Enclave (SEP) regarding cryptographic key capabilities, and more specifically how to generate and store the following key types in the keychain:
- Sign only: The key can only be used for digital signatures.
- Key agreement only: The key can only be used for key agreement operations.
- All operations: The key can be used for both signing and key agreement.
I've noticed some apparent differences between Apple's Security framework and CryptoKit, and I'm trying to understand whether these differences reflect actual SEP limitations or simply framework-level restrictions.
I'm currently using SecKeyCreateRandomKey to generate Secure Enclave-backed keys.
Here is the relevant code:
NSDictionary *privateAttributes = @{
(__bridge id)kSecAttrIsPermanent : @YES,
(__bridge id)kSecAttrAccessControl : ...,
(__bridge id)kSecAttrApplicationTag : ...,
// key agreement only
(__bridge id)kSecAttrCanSign: @NO,
(__bridge id)kSecAttrCanDerive: @YES
};
NSMutableDictionary *attributes = [ @{
(__bridge id)kSecAttrKeyType : (__bridge id)kSecAttrKeyTypeECSECPrimeRandom,
(__bridge id)kSecAttrTokenID : (__bridge id)kSecAttrTokenIDSecureEnclave,
(__bridge id)kSecAttrKeySizeInBits : @256,
(__bridge id)kSecPrivateKeyAttrs : privateAttributes
} mutableCopy ];
CFErrorRef generationError = nullptr;
SecKeyRef privateKey = SecKeyCreateRandomKey(
(__bridge CFDictionaryRef)attributes,
&generationError
);
However, when experimenting with these attributes, I encountered the following error:
SecKeyCreateRandomKey failed: Error Domain=NSOSStatusErrorDomain Code=-50 "Failed to generate keypair"
Underlying error: Error Domain=CryptoTokenKit Code=-8 "sepkey: sign requires '1' value when present"
Using signing-only attributes results in the same kind of error.
This makes me wonder whether the Security framework actually allows generating (and adding entries in the keyChain) only keys with both capabilities enabled.
- It is possible to create siging only key or key agreement only key with Security framework?
On the other hand, CryptoKit seems to expose two distinct Secure Enclave key types:
P256.SecureEnclave.Signing.PrivateKey
P256.SecureEnclave.KeyAgreement.PrivateKey
From the API design, it appears that CryptoKit only allows creating keys dedicated to one operation or the other. For example, a Signing.PrivateKey cannot be used for key agreement, and a KeyAgreement.PrivateKey cannot be used for signing.
- Is it possible to create both capabilities keys with CryptoKit framework?
- What are the actual cryptographic capability limitations imposed by the SEP itself?
I'd particularly like to understand which restrictions originate from:
- The Secure Enclave hardware.
- Security and CryptoKit frameworks.
Is there a documented way to generate and store in the keychain:
- A signing-only Secure Enclave key?
- A key-agreement-only Secure Enclave key?
- A Secure Enclave key supporting both operations?
Thanks in advance,
Idopte