5 // Created by Richard Murphy on 2/13/13.
10 #include <SecureObjectSync/SOSUserKey.h>
11 #include <corecrypto/ccrng.h>
12 #include <corecrypto/ccec.h>
13 #include <CommonCrypto/CommonRandomSPI.h>
14 #include <CoreFoundation/CFString.h>
17 #include <corecrypto/ccrng_pbkdf2_prng.h>
19 #define UK_CONST_DECL(k,v) CFTypeRef k = (CFTypeRef)(CFSTR(v));
21 UK_CONST_DECL (ukSalt
, "salt");
22 UK_CONST_DECL (ukIteration
, "iteration");
24 static const size_t saltlen
= 16;
25 static const unsigned long iterations
= 10240;
27 static dispatch_once_t keyParmStoreInit
;
28 static CFMutableDictionaryRef keyParmStorage
= NULL
;
29 static void SOSKeyParmStore(CFStringRef user_label
, CFDictionaryRef parmData
) {
30 dispatch_once(&keyParmStoreInit
, ^{
31 keyParmStorage
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 50, &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
);
33 CFDictionaryAddValue(keyParmStorage
, user_label
, parmData
);
36 static CFDictionaryRef
SOSKeyParmRetrieve(CFStringRef user_label
) {
37 if(keyParmStorage
&& CFDictionaryContainsKey(keyParmStorage
, user_label
)) {
38 CFDictionaryRef parmData
= CFDictionaryGetValue(keyParmStorage
, user_label
);
43 const void *keys[] = { ukSalt, ukIteration };
44 const void *values[] = { cfsalt, cfiteration };
45 CFDictionaryRef query = CFDictionaryCreate(kCFAllocatorDefault, keys, values, sizeof(keys)/sizeof(*keys), NULL, NULL);
46 CFDictionaryRef retval = CFDictionaryCreate(
53 SOSUserKeyGenParmPersist(CFStringRef user_label
)
58 SOSUserKeyGenParmRetrieve(CFStringRef user_label
)
64 SOSUserKeyGenerate(int keysize
, CFStringRef user_label
, CFDataRef user_password
, SecKeyRef
*user_pubkey
, SecKeyRef
*user_privkey
)
67 ccec_const_cp_t cp
= ccec_get_cp(keysize
);
68 ccec_full_ctx_decl_cp(cp
, full_key
);
69 struct ccrng_pbkdf2_prng_state pbkdf2_prng
;
70 uint8_t salt
[saltlen
];
71 if(CCRandomCopyBytes(kCCRandomDefault
, salt
, sizeof(salt
)) != kCCSuccess
) return false;
72 uint8_t password_bytes
= CFDataGetBytePtr(user_password
);
73 size_t password_length
= CFDataGetLength(user_password
);
74 ccrng_pbkdf2_prng_init(&pbkdf2_prng
, 72, password_length
, password_bytes
, sizeof(salt
), salt
, iterations
);
75 struct ccrng_state
*rng
= (struct ccrng_state
*)&pbkdf2_prng
;
76 ccec_generate_key(cp
, rng
, full_key
);