2 * Copyright (c) 2007-2009,2013-2014 Apple Inc. All Rights Reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
21 * @APPLE_LICENSE_HEADER_END@
25 #include <TargetConditionals.h>
26 #include <CoreFoundation/CoreFoundation.h>
27 #include <Security/Security.h>
28 #include <Security/SecRandom.h>
29 #include <CommonCrypto/CommonDigest.h>
30 #include <Security/SecKeyPriv.h>
31 #include <Security/SecItem.h>
34 #include <Security/SecCertificate.h>
35 #include <Security/SecCertificateInternal.h>
36 #include <Security/SecKey.h>
37 #include <Security/SecItem.h>
38 #include <Security/SecAsn1Types.h>
39 #include <Security/oidsalg.h>
40 #include <libDER/libDER.h>
45 #include "keychain_regressions.h"
46 #include "utilities/SecCFRelease.h"
49 static void testdigestandsignalg(SecKeyRef privKey
, SecKeyRef pubKey
, const SecAsn1AlgId
*algId
) {
50 uint8_t dataToDigest
[256];
51 size_t dataToDigestLen
= sizeof(dataToDigest
);
52 size_t sigLen
= SecKeyGetSize(privKey
, kSecKeySignatureSize
);
56 oid
.length
= algId
->algorithm
.Length
;
57 oid
.data
= algId
->algorithm
.Data
;
59 /* Get the oid in decimal for display purposes. */
60 CFStringRef oidStr
= SecDERItemCopyOIDDecimalRepresentation(kCFAllocatorDefault
, &oid
);
62 CFStringGetCString(oidStr
, oidBuf
, sizeof(oidBuf
), kCFStringEncodingUTF8
);
69 ok_status(status
= SecKeyDigestAndSign(privKey
, algId
, dataToDigest
, dataToDigestLen
,
70 sig
, &sigLen
), "digest and sign %s with %ld bit RSA key", oidBuf
, sigLen
* 8);
72 skip("SecKeyDigestAndSign failed", 3, status
== errSecSuccess
);
74 /* Verify the signature we just made. */
75 ok_status(SecKeyDigestAndVerify(pubKey
, algId
, dataToDigest
, dataToDigestLen
,
76 sig
, sigLen
), "digest and verify");
77 /* Invalidate the signature. */
79 is_status(SecKeyDigestAndVerify(pubKey
, algId
, dataToDigest
, dataToDigestLen
,
80 sig
, sigLen
), errSSLCrypto
, "digest and verify bad sig");
82 dataToDigest
[0] ^= 0xff;
83 is_status(SecKeyDigestAndVerify(pubKey
, algId
, dataToDigest
, dataToDigestLen
,
84 sig
, sigLen
), errSSLCrypto
, "digest and verify bad digest");
88 static void testdigestandsign(SecKeyRef privKey
, SecKeyRef pubKey
) {
89 static const SecAsn1Oid
*oids
[] = {
91 &CSSMOID_SHA224WithRSA
,
92 &CSSMOID_SHA256WithRSA
,
93 &CSSMOID_SHA384WithRSA
,
94 &CSSMOID_SHA512WithRSA
,
96 &CSSMOID_SHA1WithRSA_OIW
,
97 &CSSMOID_SHA1WithDSA
, // BSAFE
98 &CSSMOID_SHA1WithDSA_CMS
, // X509/CMS
99 &CSSMOID_SHA1WithDSA_JDK
, // JDK 1.1
105 SecAsn1AlgId algId
= {};
106 for (ix
= 0; ix
< sizeof(oids
) / sizeof(*oids
); ++ix
) {
108 algId
.algorithm
= *oids
[ix
];
110 algId
.algorithm
.Length
= 0;
111 algId
.algorithm
.Data
= NULL
;
114 testdigestandsignalg(privKey
, pubKey
, &algId
);
120 static void dump_bytes(uint8_t* bytes
, size_t amount
)
123 printf("0x%02x ", *bytes
);
131 #if !TARGET_OS_IPHONE
132 #define kEncryptDecryptTestCount 0
134 #define kEncryptDecryptTestCount 5
135 static void test_encrypt_decrypt(SecKeyRef pubKey
, SecKeyRef privKey
, uint32_t padding
, size_t keySizeInBytes
)
138 size_t max_len
= keySizeInBytes
;
140 case kSecPaddingNone
: max_len
= keySizeInBytes
; break;
141 case kSecPaddingOAEP
: max_len
= keySizeInBytes
- 2 - 2 * CC_SHA1_DIGEST_LENGTH
; break;
142 case kSecPaddingPKCS1
: max_len
= keySizeInBytes
- 11; break;
143 default: skip("what is the max_len for this padding?", 5, false);
146 uint8_t secret
[max_len
+ 1], encrypted_secret
[keySizeInBytes
], decrypted_secret
[keySizeInBytes
];
147 uint8_t *secret_ptr
= secret
;
148 size_t secret_len
= max_len
;
149 size_t encrypted_secret_len
= sizeof(encrypted_secret
);
150 size_t decrypted_secret_len
= sizeof(decrypted_secret
);
151 memset(decrypted_secret
, 0xff, decrypted_secret_len
);
152 SecRandomCopyBytes(kSecRandomDefault
, sizeof(secret
), secret
);
154 // zero pad, no accidental second zero byte
155 if (padding
== kSecPaddingNone
) {
160 is_status(SecKeyEncrypt(pubKey
, padding
,
161 secret
, sizeof(secret
),
162 encrypted_secret
, &encrypted_secret_len
), errSecParam
, "encrypt secret (overflow)");
163 ok_status(SecKeyEncrypt(pubKey
, padding
,
165 encrypted_secret
, &encrypted_secret_len
), "encrypt secret");
167 ok_status(SecKeyDecrypt(privKey
, padding
,
168 encrypted_secret
, encrypted_secret_len
,
169 decrypted_secret
, &decrypted_secret_len
), "decrypt secret");
171 // zero padding is removed on decode
172 if (padding
== kSecPaddingNone
) {
177 ok(decrypted_secret_len
== secret_len
, "correct length");
178 ok_status(memcmp(secret_ptr
, decrypted_secret
, secret_len
), "verify secret");
185 #if !TARGET_OS_IPHONE
186 /* This is part of Security.framework on iOS */
189 // kSecKeyKeySizeInBits = 0, // already exists on osx
190 kSecKeySignatureSize
= 101,
191 kSecKeyEncryptedDataSize
= 102,
192 // More might belong here, but we aren't settled on how
193 // to take into account padding and/or digest types.
197 size_t SecKeyGetSize(SecKeyRef key
, int whichSize
)
199 size_t result
= SecKeyGetBlockSize(key
);
201 /* This is only RSA */
202 if (whichSize
== kSecKeyKeySizeInBits
)
209 #define kKeyGenTestCount (11 + (3*kEncryptDecryptTestCount))
210 static void testkeygen(size_t keySizeInBits
) {
211 SecKeyRef pubKey
= NULL
, privKey
= NULL
;
212 size_t keySizeInBytes
= (keySizeInBits
+ 7) / 8;
215 kzib
= CFNumberCreate(NULL
, kCFNumberSInt32Type
, &keySizeInBits
);
216 CFMutableDictionaryRef kgp
= CFDictionaryCreateMutable(NULL
, 0, NULL
, NULL
);
217 CFDictionaryAddValue(kgp
, kSecAttrKeyType
, kSecAttrKeyTypeRSA
);
218 CFDictionaryAddValue(kgp
, kSecAttrKeySizeInBits
, kzib
);
221 ok_status(status
= SecKeyGeneratePair(kgp
, &pubKey
, &privKey
),
222 "Generate %ld bit (%ld byte) RSA keypair", keySizeInBits
,
228 skip("keygen failed", 8, status
== errSecSuccess
);
229 ok(pubKey
, "pubkey returned");
230 ok(privKey
, "privKey returned");
231 is(SecKeyGetSize(pubKey
, kSecKeyKeySizeInBits
), (size_t) keySizeInBits
, "public key size is ok");
232 is(SecKeyGetSize(privKey
, kSecKeyKeySizeInBits
), (size_t) keySizeInBits
, "private key size is ok");
234 /* Sign something. */
235 uint8_t something
[keySizeInBytes
];
236 size_t something_len
= keySizeInBytes
- 11;
237 SecRandomCopyBytes(kSecRandomDefault
, sizeof(something
), something
);
238 uint8_t sig
[keySizeInBytes
];
239 size_t sigLen
= sizeof(sig
);
241 /* TODO: This is returning another error on OS X */
242 is_status(SecKeyRawSign(privKey
, kSecPaddingPKCS1
,
243 something
, something_len
+ 1, sig
, &sigLen
),
244 errSecParam
, "sign overflow");
246 ok_status(SecKeyRawSign(privKey
, kSecPaddingPKCS1
,
247 something
, something_len
, sig
, &sigLen
), "sign something");
248 ok_status(SecKeyRawVerify(pubKey
, kSecPaddingPKCS1
,
249 something
, something_len
, sig
, sigLen
), "verify sig on something");
251 // Torture test ASN.1 encoder by setting high bit to 1.
252 uint8_t digest
[CC_SHA512_DIGEST_LENGTH
] = {
253 0x80, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
254 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
255 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
256 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
257 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
258 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
259 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
260 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
263 /* Thoses tests are making sure that MD2 and MD5 are NOT supported,
264 but they still are on OS X */
266 //CC_MD2(something, sizeof(something), digest);
267 ok_status(!SecKeyRawSign(privKey
, kSecPaddingPKCS1MD2
,
268 digest
, CC_MD2_DIGEST_LENGTH
, sig
, &sigLen
),
269 "don't sign md2 digest"); //FAIL
270 ok_status(!SecKeyRawVerify(pubKey
, kSecPaddingPKCS1MD2
,
271 digest
, CC_MD2_DIGEST_LENGTH
, sig
, sigLen
),
272 "verify sig on md2 digest fails"); //FAIL
274 //CC_MD5(something, sizeof(something), digest);
275 sigLen
= sizeof(sig
);
276 ok_status(!SecKeyRawSign(privKey
, kSecPaddingPKCS1MD5
,
277 digest
, CC_MD5_DIGEST_LENGTH
, sig
, &sigLen
),
278 "don't sign md5 digest"); //FAIL
279 ok_status(!SecKeyRawVerify(pubKey
, kSecPaddingPKCS1MD5
,
280 digest
, CC_MD5_DIGEST_LENGTH
, sig
, sigLen
),
281 "verify sig on md5 digest fails"); //FAIL
284 //CCDigest(kCCDigestSHA1, something, sizeof(something), digest);
285 sigLen
= sizeof(sig
);
286 ok_status(SecKeyRawSign(privKey
, kSecPaddingPKCS1SHA1
,
287 digest
, CC_SHA1_DIGEST_LENGTH
, sig
, &sigLen
),
289 ok_status(SecKeyRawVerify(pubKey
, kSecPaddingPKCS1SHA1
,
290 digest
, CC_SHA1_DIGEST_LENGTH
, sig
, sigLen
),
291 "verify sig on sha1 digest");
294 /* The assumptions in these tests are just wrong on OS X */
295 uint8_t signature
[keySizeInBytes
], *ptr
= signature
;
296 size_t signature_len
= sizeof(signature
);
297 ok_status(SecKeyEncrypt(pubKey
, kSecPaddingNone
, sig
, sigLen
, signature
, &signature_len
), "inspect signature");
298 is(signature_len
, keySizeInBytes
- 1, "got signature"); // FAIL for 2056
299 while(*ptr
&& ((size_t)(ptr
- signature
) < signature_len
)) ptr
++;
300 is(signature
+ signature_len
- ptr
, 16 /* length(\0 || OID_SHA1) */ + CC_SHA1_DIGEST_LENGTH
, "successful decode");
304 /* Those are not supported on OS X */
305 /* PKCS1 padding is 00 01 PAD * 8 or more 00 data.
306 data is SEQ { SEQ { OID NULL } BIT STRING 00 DIGEST }
307 So min data + pad overhead is 11 + 9 + oidlen
308 oidlen = 11 for the sha2 family of oids, so we have 29 bytes; or
309 232 bits of minimum overhead. */
310 const size_t pkcs1Overhead
= 232;
311 if (keySizeInBits
> 224 + pkcs1Overhead
) {
312 //CC_SHA224(something, sizeof(something), digest);
313 sigLen
= sizeof(sig
);
314 ok_status(SecKeyRawSign(privKey
, kSecPaddingPKCS1SHA224
,
315 digest
, CC_SHA224_DIGEST_LENGTH
, sig
, &sigLen
),
316 "sign sha224 digest");
317 ok_status(SecKeyRawVerify(pubKey
, kSecPaddingPKCS1SHA224
,
318 digest
, CC_SHA224_DIGEST_LENGTH
, sig
, sigLen
),
319 "verify sig on sha224 digest");
322 if (keySizeInBits
> 256 + pkcs1Overhead
) {
323 //CC_SHA256(something, sizeof(something), digest);
324 sigLen
= sizeof(sig
);
325 ok_status(SecKeyRawSign(privKey
, kSecPaddingPKCS1SHA256
,
326 digest
, CC_SHA256_DIGEST_LENGTH
, sig
, &sigLen
),
327 "sign sha256 digest");
328 ok_status(SecKeyRawVerify(pubKey
, kSecPaddingPKCS1SHA256
,
329 digest
, CC_SHA256_DIGEST_LENGTH
, sig
, sigLen
),
330 "verify sig on sha256 digest");
333 if (keySizeInBits
> 384 + pkcs1Overhead
) {
334 //CC_SHA384(something, sizeof(something), digest);
335 sigLen
= sizeof(sig
);
336 ok_status(SecKeyRawSign(privKey
, kSecPaddingPKCS1SHA384
,
337 digest
, CC_SHA384_DIGEST_LENGTH
, sig
, &sigLen
),
338 "sign sha384 digest");
339 ok_status(SecKeyRawVerify(pubKey
, kSecPaddingPKCS1SHA384
,
340 digest
, CC_SHA384_DIGEST_LENGTH
, sig
, sigLen
),
341 "verify sig on sha384 digest");
344 if (keySizeInBits
> 512 + pkcs1Overhead
) {
345 //CC_SHA512(something, sizeof(something), digest);
346 sigLen
= sizeof(sig
);
347 ok_status(SecKeyRawSign(privKey
, kSecPaddingPKCS1SHA512
,
348 digest
, CC_SHA512_DIGEST_LENGTH
, sig
, &sigLen
),
349 "sign sha512 digest");
350 ok_status(SecKeyRawVerify(pubKey
, kSecPaddingPKCS1SHA512
,
351 digest
, CC_SHA512_DIGEST_LENGTH
, sig
, sigLen
),
352 "verify sig on sha512 digest");
355 test_encrypt_decrypt(pubKey
, privKey
, kSecPaddingNone
, keySizeInBytes
);
356 test_encrypt_decrypt(pubKey
, privKey
, kSecPaddingPKCS1
, keySizeInBytes
);
357 test_encrypt_decrypt(pubKey
, privKey
, kSecPaddingOAEP
, keySizeInBytes
);
359 testdigestandsign(privKey
, pubKey
);
362 const void *privkeys
[] = {
365 const void *privvalues
[] = {
368 CFDictionaryRef privitem
= CFDictionaryCreate(NULL
, privkeys
, privvalues
,
369 sizeof(privkeys
) / sizeof(*privkeys
), NULL
, NULL
);
371 /* OS X: keys are always added to the keychain when generated */
372 ok_status(SecItemAdd(privitem
, NULL
), "add private key"); //FAIL
374 ok_status(SecItemDelete(privitem
), "delete private key");
375 CFReleaseNull(privitem
);
377 const void *pubkeys
[] = {
380 const void *pubvalues
[] = {
383 CFDictionaryRef pubitem
= CFDictionaryCreate(NULL
, pubkeys
, pubvalues
,
384 sizeof(pubkeys
) / sizeof(*pubkeys
), NULL
, NULL
);
386 /* OS X: keys are always added to the keychain when generated */
387 ok_status(SecItemAdd(pubitem
, NULL
), "add public key"); //FAIL
389 ok_status(SecItemDelete(pubitem
), "delete public key");
390 CFReleaseNull(pubitem
);
393 CFReleaseNull(pubKey
);
394 CFReleaseNull(privKey
);
398 #define kKeyGen2TestCount 11
399 static void testkeygen2(size_t keySizeInBits
) {
400 SecKeyRef pubKey
= NULL
, privKey
= NULL
;
401 size_t keySizeInBytes
= (keySizeInBits
+ 7) / 8;
404 CFUUIDRef ourUUID
= CFUUIDCreate(kCFAllocatorDefault
);
405 CFStringRef uuidString
= CFUUIDCreateString(kCFAllocatorDefault
, ourUUID
);
406 CFMutableStringRef publicName
= CFStringCreateMutableCopy(kCFAllocatorDefault
, 0, uuidString
);
407 CFMutableStringRef privateName
= CFStringCreateMutableCopy(kCFAllocatorDefault
, 0, uuidString
);
409 CFReleaseNull(ourUUID
);
410 CFReleaseNull(uuidString
);
412 CFStringAppend(publicName
, CFSTR("-Public-40"));
413 CFStringAppend(privateName
, CFSTR("-Private-40"));
414 CFMutableDictionaryRef pubd
= CFDictionaryCreateMutable(NULL
, 0, NULL
, NULL
);
415 CFMutableDictionaryRef privd
= CFDictionaryCreateMutable(NULL
, 0, NULL
, NULL
);
417 CFDictionaryAddValue(pubd
, kSecAttrLabel
, publicName
);
418 CFDictionaryAddValue(privd
, kSecAttrLabel
, privateName
);
420 kzib
= CFNumberCreate(NULL
, kCFNumberSInt32Type
, &keySizeInBits
);
421 CFMutableDictionaryRef kgp
= CFDictionaryCreateMutable(NULL
, 0, NULL
, NULL
);
422 CFDictionaryAddValue(kgp
, kSecAttrKeyType
, kSecAttrKeyTypeRSA
);
423 CFDictionaryAddValue(kgp
, kSecAttrKeySizeInBits
, kzib
);
424 CFDictionaryAddValue(kgp
, kSecAttrIsPermanent
, kCFBooleanTrue
);
425 CFDictionaryAddValue(kgp
, kSecPublicKeyAttrs
, pubd
);
426 CFDictionaryAddValue(kgp
, kSecPrivateKeyAttrs
, privd
);
429 ok_status(status
= SecKeyGeneratePair(kgp
, &pubKey
, &privKey
),
430 "Generate %ld bit (%ld byte) persistent RSA keypair",
431 keySizeInBits
, keySizeInBytes
);
436 skip("keygen failed", 8, status
== errSecSuccess
);
437 ok(pubKey
, "pubkey returned");
438 ok(privKey
, "privKey returned");
439 is(SecKeyGetSize(pubKey
, kSecKeyKeySizeInBits
), (size_t) keySizeInBits
, "public key size is ok");
440 is(SecKeyGetSize(privKey
, kSecKeyKeySizeInBits
), (size_t) keySizeInBits
, "private key size is ok");
442 SecKeyRef pubKey2
, privKey2
;
443 CFDictionaryAddValue(pubd
, kSecClass
, kSecClassKey
);
444 CFDictionaryAddValue(pubd
, kSecReturnRef
, kCFBooleanTrue
);
445 CFDictionaryAddValue(privd
, kSecClass
, kSecClassKey
);
446 CFDictionaryAddValue(privd
, kSecReturnRef
, kCFBooleanTrue
);
447 CFDictionaryAddValue(privd
, kSecAttrCanSign
, kCFBooleanTrue
);
448 ok_status(SecItemCopyMatching(pubd
, (CFTypeRef
*)&pubKey2
),
449 "retrieve pub key by label");
450 ok_status(SecItemCopyMatching(privd
, (CFTypeRef
*)&privKey2
),
451 "retrieve priv key by label and kSecAttrCanSign");
453 /* Sign something. */
454 uint8_t something
[50] = {0x80, 0xbe, 0xef, 0xba, 0xd0, };
455 uint8_t sig
[keySizeInBytes
];
456 size_t sigLen
= keySizeInBytes
;
457 ok_status(SecKeyRawSign(privKey2
, kSecPaddingPKCS1
,
458 something
, sizeof(something
), sig
, &sigLen
), "sign something");
459 ok_status(SecKeyRawVerify(pubKey2
, kSecPaddingPKCS1
,
460 something
, sizeof(something
), sig
, sigLen
), "verify sig on something");
463 /* SecKeyEncrypt does not return errSecParam on OS X in that case */
464 sigLen
= keySizeInBytes
;
465 is_status(SecKeyEncrypt(pubKey2
, kSecPaddingPKCS1SHA1
,
466 something
, sizeof(something
), sig
, &sigLen
), errSecParam
,
467 "encrypt something with invalid padding");
471 CFReleaseNull(pubKey2
);
472 CFReleaseNull(privKey2
);
474 /* delete from keychain - note: do it before releasing publicName and privateName
475 because pubd and privd have no retain/release callbacks */
476 ok_status(SecItemDelete(pubd
), "delete generated pub key");
477 ok_status(SecItemDelete(privd
), "delete generated priv key");
481 CFReleaseNull(pubKey
);
482 CFReleaseNull(privKey
);
484 CFReleaseNull(publicName
);
485 CFReleaseNull(privateName
);
492 #if !TARGET_OS_IPHONE
493 // Only exists currently in MacOSX
494 typedef struct KDFVector_t
{
501 int expected_failure
;
504 static KDFVector kdfv
[] = {
505 // Test Case PBKDF2 - HMACSHA1 http://tools.ietf.org/html/draft-josefsson-pbkdf2-test-vectors-00
506 { "password", "salt", 1, 1, 160, "0c60c80f961f0e71f3a9b524af6012062fe037a6", 0 },
507 { "password", "salt", 2, 1, 160, "ea6c014dc72d6f8ccd1ed92ace1d41f0d8de8957", 0 },
508 { "password", "salt", 4096, 1, 160, "4b007901b765489abead49d926f721d065a429c1", 0 },
509 { "password", "salt", 1, 0, 160, NULL
, -1} // This crashed
512 static size_t kdfvLen
= sizeof(kdfv
) / sizeof(KDFVector
);
514 static int testSecKDF(CFStringRef password
, CFDataRef salt
, CFNumberRef rounds
, CFStringRef alg
, CFNumberRef dklen
, CFDataRef expected
, int expected_failure
) {
515 CFMutableDictionaryRef parameters
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 4, &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
);
518 CFDictionaryAddValue(parameters
, kSecAttrSalt
, salt
);
519 CFDictionaryAddValue(parameters
, kSecAttrKeySizeInBits
, dklen
);
520 CFDictionaryAddValue(parameters
, kSecAttrPRF
, alg
);
521 CFDictionaryAddValue(parameters
, kSecAttrRounds
, rounds
);
523 SecKeyRef derivedKey
= SecKeyDeriveFromPassword(password
, parameters
, NULL
);
524 if(derivedKey
== NULL
&& expected_failure
) {
525 ok(1, "Correctly failed to produce a key");
527 } else if(derivedKey
== NULL
) {
528 ok(0, "Could not generate a key when we should have");
531 ok(1, "Made a new key");
533 // NEEDS Fix -- ok(status = expectedEqualsComputed(expected, derivedKey), "Derived key is as expected");
535 if(parameters
) CFRelease(parameters
);
536 if(derivedKey
) CFRelease(derivedKey
);
540 static CFDataRef
CFDataCreateFromHexBytes(char *s
) {
542 size_t len
= strlen(s
);
543 if(len%2
) return NULL
;
546 for(size_t i
=0; i
<len
; i
++) {
547 buf
[i
] = s
[i
*2] * 16 + s
[i
*2+1];
549 CFDataRef retval
= CFDataCreate(NULL
, buf
, len
);
555 PBKDF2Test(KDFVector
*kdfvec
)
557 CFDataRef expectedBytes
= CFDataCreateFromHexBytes(kdfvec
->expectedstr
);
558 CFStringRef password
= CFStringCreateWithCString(NULL
, kdfvec
->password
, kCFStringEncodingUTF8
);
559 CFDataRef salt
= CFDataCreate(NULL
, (const UInt8
*)kdfvec
->salt
, strlen(kdfvec
->salt
));
560 CFNumberRef rounds
= CFNumberCreate(NULL
, kCFNumberIntType
, &kdfvec
->rounds
);
561 CFNumberRef dklen
= CFNumberCreate(NULL
, kCFNumberIntType
, &kdfvec
->dklen
);
564 ok(testSecKDF(password
, salt
, rounds
, kSecAttrPRFHmacAlgSHA1
, dklen
, expectedBytes
, kdfvec
->expected_failure
), "Test SecKeyDeriveFromPassword PBKDF2");
566 if(expectedBytes
) CFRelease(expectedBytes
);
571 static void testkeyderivation() {
572 for(size_t testcase
= 0; testcase
< kdfvLen
; testcase
++) {
573 // diag("Test %lu\n", testcase + 1);
574 ok(PBKDF2Test(&kdfv
[testcase
]), "Successful full test of KDF Vector");
579 static size_t kdfvLen
= 0; // no kdf functions in Sec for iphone
580 #endif /* !TARGET_OS_IPHONE */
583 /* Test basic add delete update copy matching stuff. */
584 #define kTestCount ((2 * kKeyGenTestCount) + kKeyGen2TestCount + (int) (kdfvLen*3))
585 static void tests(void)
587 /* Comment out lines below for testing generating all common key sizes,
588 disabled now for speed reasons. */
592 testkeygen(2056); // Stranged sized for edge cases in padding.
596 testkeygen2(1024); // lots of FAIL!
597 #if !TARGET_OS_IPHONE
602 int kc_40_seckey(int argc
, char *const *argv
)
604 plan_tests(kTestCount
);