Where is kSecAttrTokenIDSecureEnclave documented?
Asked Answered
S

1

9

I'm banging my head trying to generate a private-public key pair with kSecAttrTokenIDSecureEnclave so that the private key is generated in the secure enclave.

Where is kSecAttrTokenIDSecureEnclave documented? Below is my code, which fails with status code -50.

- (void)generateKeyPair {
    const UInt8 publicTagString[] = "public";
    const UInt8 privateTagString[] = "private";

    publicTag = CFDataCreate(0, publicTagString, sizeof(publicTagString));
    privateTag = CFDataCreate(0, privateTagString, sizeof(privateTagString));

    CFMutableDictionaryRef publicAttr = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, NULL, NULL);
    CFDictionaryAddValue(publicAttr, kSecAttrApplicationTag, publicTag);
    // CFDictionaryAddValue(publicAttr, kSecAttrIsPermanent, kCFBooleanTrue);
    CFDictionaryAddValue(publicAttr, kSecAttrCanEncrypt, kCFBooleanFalse);
    CFDictionaryAddValue(publicAttr, kSecAttrCanDecrypt, kCFBooleanFalse);
    CFDictionaryAddValue(publicAttr, kSecAttrCanDerive, kCFBooleanFalse);
    CFDictionaryAddValue(publicAttr, kSecAttrCanSign, kCFBooleanFalse);
    CFDictionaryAddValue(publicAttr, kSecAttrCanVerify, kCFBooleanTrue);
    CFDictionaryAddValue(publicAttr, kSecAttrCanUnwrap, kCFBooleanFalse);

    CFMutableDictionaryRef privateAttr = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, NULL, NULL);
    CFDictionaryAddValue(privateAttr, kSecAttrApplicationTag, privateTag);
    // CFDictionaryAddValue(privateAttr, kSecAttrIsPermanent, kCFBooleanTrue);
    CFDictionaryAddValue(privateAttr, kSecAttrCanEncrypt, kCFBooleanFalse);
    CFDictionaryAddValue(privateAttr, kSecAttrCanDecrypt, kCFBooleanFalse);
    CFDictionaryAddValue(privateAttr, kSecAttrCanDerive, kCFBooleanFalse);
    CFDictionaryAddValue(privateAttr, kSecAttrCanSign, kCFBooleanTrue);
    CFDictionaryAddValue(privateAttr, kSecAttrCanVerify, kCFBooleanFalse);
    CFDictionaryAddValue(privateAttr, kSecAttrCanUnwrap, kCFBooleanFalse);

    const void* parameterKeys[] = {
        kSecAttrKeyType,
        kSecAttrKeySizeInBits,
        kSecAttrTokenID,
        kSecPublicKeyAttrs,
        kSecPrivateKeyAttrs
    };

    int intKeySize = 512;
    CFNumberRef keySize = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &intKeySize);

    const void* parameterValues[] = {
        kSecAttrKeyTypeRSA,
        keySize,
        kSecAttrTokenIDSecureEnclave,
        publicAttr,
        privateAttr
    };

    CFDictionaryRef parameters = CFDictionaryCreate(
        kCFAllocatorDefault,
        parameterKeys,
        parameterValues,
        5, // ??? Make this programmatic
        NULL,
        NULL
    );

    OSStatus status = SecKeyGeneratePair(parameters, &publicKey, &privateKey);

    if(status != errSecSuccess) {
        [self logError:[NSString stringWithFormat:@"SecKeyGeneratePair status %d", (int)status] :nil];
        return;
    }
}
Selfrising answered 11/11, 2015 at 12:20 Comment(1)
"Things work properly with RSA, but then kSecAttrTokenIDSecureEnclave and kSecAccessControlPrivateKeyUsage can't be specified." Taken from here. Can't we have RSA pairs with kSecAttrTokenIDSecureEnclave then? Where is that documented?Selfrising
S
7

The error you are getting, -50, indicates a parameter error. A parameter you are passing to the function is incorrect or inappropriate for the operation. If you look at the SecItem header or the you will see:

kSecAttrTokenIDSecureEnclave Specifies well-known identifier of the token implemented using device's Secure Enclave. The only keychain items supported by the Secure Enclave token are 256-bit elliptic curve keys (kSecAttrKeyTypeEC). Keys must be generated on the secure enclave using SecKeyGenerateKeyPair call with kSecAttrTokenID set to kSecAttrTokenIDSecureEnclave in the parameters dictionary, it is not possible to import pregenerated keys to kSecAttrTokenIDSecureEnclave token.

RSA is not currently a supported cipher when generating a private key in the secure enclave. Switch to a 256 bit EC key.

This was covered in the WWDC 2015 session 706 Security And Your Apps. The Apple sample project "KeychainTouchID" shows the correct parameters for generating and using a key using the secure enclave.

Scottyscotus answered 1/12, 2015 at 21:26 Comment(1)
Update: as of iOS 10+ kSecAttrKeyTypeEC is deprecated in favor of kSecAttrKeyTypeECSECPrimeRandom.Apical

© 2022 - 2024 — McMap. All rights reserved.