I am try to use the kSecAttrTokenIDSecureEnclave for generating KeyPair using function . But when try to encrypt data using function
SecKeyEncrypt(publicKey,padding,(const uint8_t *)[symmetricKey bytes],keyBufferSize,cipherBuffer,&cipherBufferSize);
getting error code -50, which show a parameter error. Can anyone suggest me what I am missing ?
here is my functions that generate key pair and try to encrypt the data
- (void)generateKeyPair{
OSStatus sanityCheck = noErr;
NSData *privateTag = [[NSData alloc] initWithBytes:privateKeyIdentifier length:sizeof(privateKeyIdentifier)];
NSData *publicTag = [[NSData alloc] initWithBytes:publicKeyIdentifier length:sizeof(publicKeyIdentifier)];
// Container dictionaries.
NSMutableDictionary * privateKeyAttr = [[NSMutableDictionary alloc] init];
NSMutableDictionary * publicKeyAttr = [[NSMutableDictionary alloc] init];
NSMutableDictionary * keyPairAttr = [[NSMutableDictionary alloc] init];
CFErrorRef error = NULL;
// Should be the secret invalidated when passcode is removed? If not then use `kSecAttrAccessibleWhenUnlocked`.
SecAccessControlRef sacObject = SecAccessControlCreateWithFlags(
kCFAllocatorDefault,
kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly,
kSecAccessControlTouchIDAny | kSecAccessControlPrivateKeyUsage,
&error
);
if (error != errSecSuccess) {
NSLog(@"Generate key error: %@\n", error);
}
[privateKeyAttr setObject:(__bridge id)sacObject forKey:(id)kSecAttrAccessControl];
[keyPairAttr setObject:[NSNumber numberWithUnsignedInteger:256] forKey:(id)kSecAttrKeySizeInBits];
[keyPairAttr setObject:(id)kSecAttrTokenIDSecureEnclave forKey:(id)kSecAttrTokenID];
[keyPairAttr setObject:(id)kSecAttrKeyTypeECSECPrimeRandom forKey:(id)kSecAttrKeyType];
// Set the private key dictionary.
[privateKeyAttr setObject:[NSNumber numberWithBool:YES] forKey:(id)kSecAttrIsPermanent];
[privateKeyAttr setObject:privateTag forKey:(id)kSecAttrApplicationTag];
// See SecKey.h to set other flag values.
// Set the public key dictionary.
[publicKeyAttr setObject:[NSNumber numberWithBool:NO] forKey:(id)kSecAttrIsPermanent];
[publicKeyAttr setObject:publicTag forKey:(id)kSecAttrApplicationTag];
// See SecKey.h to set other flag values.
// Set attributes to top level dictionary.
[keyPairAttr setObject:privateKeyAttr forKey:(id)kSecPrivateKeyAttrs];
[keyPairAttr setObject:publicKeyAttr forKey:(id)kSecPublicKeyAttrs];
// SecKeyGeneratePair returns the SecKeyRefs just for educational purposes.
sanityCheck = SecKeyGeneratePair((CFDictionaryRef)keyPairAttr, &publicKeyRef, &privateKeyRef);
LOGGING_FACILITY( sanityCheck == noErr && publicKeyRef != NULL && privateKeyRef != NULL, @"Something really bad went wrong with generating the key pair." );
//Encypt
NSString *stringData = @"Hello Testing";
NSLog(@"encryptedData Data = %@",stringData);
NSData *encryptedData = [self wrapSymmetricKey:[stringData dataUsingEncoding:NSUTF8StringEncoding] keyRef:publicKeyRef];
}
- (NSData *)wrapSymmetricKey:(NSData *)symmetricKey keyRef:(SecKeyRef)publicKey {
OSStatus sanityCheck = noErr;
size_t cipherBufferSize = 0;
size_t keyBufferSize = 0;
LOGGING_FACILITY( symmetricKey != nil, @"Symmetric key parameter is nil." );
LOGGING_FACILITY( publicKey != nil, @"Key parameter is nil." );
NSData * cipher = nil;
uint8_t * cipherBuffer = NULL;
// Calculate the buffer sizes.
cipherBufferSize = SecKeyGetBlockSize(publicKey);
keyBufferSize = [symmetricKey length];
// Allocate some buffer space. I don't trust calloc.
cipherBuffer = malloc(cipherBufferSize * sizeof(uint8_t) );
memset((void *)cipherBuffer, 0x0, cipherBufferSize * sizeof(uint8_t));
SecPadding padding = kSecPaddingNone;
// Encrypt using the public key.
sanityCheck = SecKeyEncrypt( publicKey,
padding,
(const uint8_t *)[symmetricKey bytes],
keyBufferSize,
cipherBuffer,
&cipherBufferSize
);
LOGGING_FACILITY1( sanityCheck == noErr, @"Error encrypting, OSStatus == %d.", sanityCheck );
// Build up cipher text blob.
cipher = [NSData dataWithBytes:(const void *)cipherBuffer length:(NSUInteger)cipherBufferSize];
if (cipherBuffer) free(cipherBuffer);
return cipher;
}