4 * Copyright (c) 2010,2012 Apple Inc. All Rights Reserved.
8 #include "Security/SecPBKDF.h"
9 #include "Security/pbkdf2.h"
11 #include <CommonCrypto/CommonHMAC.h>
12 #include "Security/SecBase.h"
17 /* CC Based HMAC PRF functions */
18 void hmac_sha1_PRF(const uint8_t *key
,
22 uint8_t digest
[CC_SHA1_DIGEST_LENGTH
])
24 CCHmacContext hmac_sha1_context
;
26 CCHmacInit(&hmac_sha1_context
, kCCHmacAlgSHA1
, key
, key_len
);
27 CCHmacUpdate(&hmac_sha1_context
, text
, text_len
);
28 CCHmacFinal(&hmac_sha1_context
, digest
);
31 void hmac_sha256_PRF(const uint8_t *key
,
35 uint8_t digest
[CC_SHA256_DIGEST_LENGTH
])
37 CCHmacContext hmac_sha256_context
;
39 CCHmacInit(&hmac_sha256_context
, kCCHmacAlgSHA256
, key
, key_len
);
40 CCHmacUpdate(&hmac_sha256_context
, text
, text_len
);
41 CCHmacFinal(&hmac_sha256_context
, digest
);
45 /* This implements the HMAC SHA-1 version of pbkdf2 and allocates a local buffer for the HMAC */
46 OSStatus
pbkdf2_hmac_sha1(const uint8_t *passwordPtr
, size_t passwordLen
,
47 const uint8_t *saltPtr
, size_t saltLen
,
48 uint32_t iterationCount
,
49 void *dkPtr
, size_t dkLen
)
51 // MAX(salt_length + 4, 20 /* SHA1 Digest size */) + 2 * 20;
52 // salt_length + HASH_SIZE is bigger than either salt + 4 and digestSize.
53 size_t kBigEnoughSize
= (saltLen
+ CC_SHA1_DIGEST_LENGTH
) + 2 * CC_SHA1_DIGEST_LENGTH
;
54 uint8_t *temp_data
= malloc(kBigEnoughSize
);
56 if (temp_data
== NULL
) {
57 return errSecMemoryError
;
60 pbkdf2(hmac_sha1_PRF
, CC_SHA1_DIGEST_LENGTH
,
61 passwordPtr
, passwordLen
,
67 bzero(temp_data
, kBigEnoughSize
);
72 /* This implements the HMAC SHA-256 version of pbkdf2 and allocates a local buffer for the HMAC */
73 OSStatus
pbkdf2_hmac_sha256(const uint8_t *passwordPtr
, size_t passwordLen
,
74 const uint8_t *saltPtr
, size_t saltLen
,
75 uint32_t iterationCount
,
76 void *dkPtr
, size_t dkLen
)
78 // MAX(salt_length + 4, 32 /* SHA1 Digest size */) + 2 * 32;
79 // salt_length + HASH_SIZE is bigger than either salt + 4 and digestSize.
80 size_t kBigEnoughSize
= (saltLen
+ CC_SHA256_DIGEST_LENGTH
) + 2 * CC_SHA256_DIGEST_LENGTH
;
81 uint8_t *temp_data
= malloc(kBigEnoughSize
);
83 if (temp_data
== NULL
) {
84 return errSecMemoryError
;
87 pbkdf2(hmac_sha256_PRF
, CC_SHA256_DIGEST_LENGTH
,
88 passwordPtr
, passwordLen
,
94 bzero(temp_data
, kBigEnoughSize
);
99 OSStatus
SecKeyFromPassphraseDataHMACSHA1(CFDataRef password
, CFDataRef salt
, uint32_t interationCount
, CFMutableDataRef derivedKey
)
101 return pbkdf2_hmac_sha1(CFDataGetBytePtr(password
), CFDataGetLength(password
),
102 CFDataGetBytePtr(salt
), CFDataGetLength(salt
),
104 CFDataGetMutableBytePtr(derivedKey
), CFDataGetLength(derivedKey
));
108 OSStatus
SecKeyFromPassphraseDataHMACSHA256(CFDataRef password
, CFDataRef salt
, uint32_t interationCount
, CFMutableDataRef derivedKey
)
110 return pbkdf2_hmac_sha256(CFDataGetBytePtr(password
), CFDataGetLength(password
),
111 CFDataGetBytePtr(salt
), CFDataGetLength(salt
),
113 CFDataGetMutableBytePtr(derivedKey
), CFDataGetLength(derivedKey
));