]>
Commit | Line | Data |
---|---|---|
b1ab9ed8 A |
1 | /* |
2 | * SecPBKDF.c | |
3 | * | |
d8f41ccd | 4 | * Copyright (c) 2010,2012 Apple Inc. All Rights Reserved. |
b1ab9ed8 A |
5 | * |
6 | */ | |
7 | ||
8 | #include "Security/SecPBKDF.h" | |
9 | #include "Security/pbkdf2.h" | |
10 | ||
11 | #include <CommonCrypto/CommonHMAC.h> | |
79b9da22 | 12 | #include "Security/SecBase.h" |
b1ab9ed8 | 13 | |
79b9da22 | 14 | #include <stdlib.h> |
b1ab9ed8 A |
15 | #include <string.h> |
16 | ||
17 | /* CC Based HMAC PRF functions */ | |
18 | void hmac_sha1_PRF(const uint8_t *key, | |
19 | size_t key_len, | |
20 | const uint8_t *text, | |
21 | size_t text_len, | |
22 | uint8_t digest[CC_SHA1_DIGEST_LENGTH]) | |
23 | { | |
24 | CCHmacContext hmac_sha1_context; | |
25 | ||
26 | CCHmacInit(&hmac_sha1_context, kCCHmacAlgSHA1, key, key_len); | |
27 | CCHmacUpdate(&hmac_sha1_context, text, text_len); | |
28 | CCHmacFinal(&hmac_sha1_context, digest); | |
29 | } | |
30 | ||
6b200bc3 A |
31 | void hmac_sha256_PRF(const uint8_t *key, |
32 | size_t key_len, | |
33 | const uint8_t *text, | |
34 | size_t text_len, | |
35 | uint8_t digest[CC_SHA256_DIGEST_LENGTH]) | |
36 | { | |
37 | CCHmacContext hmac_sha256_context; | |
38 | ||
39 | CCHmacInit(&hmac_sha256_context, kCCHmacAlgSHA256, key, key_len); | |
40 | CCHmacUpdate(&hmac_sha256_context, text, text_len); | |
41 | CCHmacFinal(&hmac_sha256_context, digest); | |
42 | } | |
43 | ||
b1ab9ed8 A |
44 | |
45 | /* This implements the HMAC SHA-1 version of pbkdf2 and allocates a local buffer for the HMAC */ | |
79b9da22 | 46 | OSStatus pbkdf2_hmac_sha1(const uint8_t *passwordPtr, size_t passwordLen, |
b1ab9ed8 A |
47 | const uint8_t *saltPtr, size_t saltLen, |
48 | uint32_t iterationCount, | |
49 | void *dkPtr, size_t dkLen) | |
50 | { | |
51 | // MAX(salt_length + 4, 20 /* SHA1 Digest size */) + 2 * 20; | |
52 | // salt_length + HASH_SIZE is bigger than either salt + 4 and digestSize. | |
79b9da22 A |
53 | size_t kBigEnoughSize = (saltLen + CC_SHA1_DIGEST_LENGTH) + 2 * CC_SHA1_DIGEST_LENGTH; |
54 | uint8_t *temp_data = malloc(kBigEnoughSize); | |
55 | ||
56 | if (temp_data == NULL) { | |
57 | return errSecMemoryError; | |
58 | } | |
b1ab9ed8 A |
59 | |
60 | pbkdf2(hmac_sha1_PRF, CC_SHA1_DIGEST_LENGTH, | |
61 | passwordPtr, passwordLen, | |
62 | saltPtr, saltLen, | |
63 | iterationCount, | |
64 | dkPtr, dkLen, | |
65 | temp_data); | |
66 | ||
79b9da22 A |
67 | bzero(temp_data, kBigEnoughSize); |
68 | ||
69 | return errSecSuccess; | |
b1ab9ed8 A |
70 | } |
71 | ||
6b200bc3 | 72 | /* This implements the HMAC SHA-256 version of pbkdf2 and allocates a local buffer for the HMAC */ |
79b9da22 | 73 | OSStatus pbkdf2_hmac_sha256(const uint8_t *passwordPtr, size_t passwordLen, |
6b200bc3 A |
74 | const uint8_t *saltPtr, size_t saltLen, |
75 | uint32_t iterationCount, | |
76 | void *dkPtr, size_t dkLen) | |
77 | { | |
78 | // MAX(salt_length + 4, 32 /* SHA1 Digest size */) + 2 * 32; | |
79 | // salt_length + HASH_SIZE is bigger than either salt + 4 and digestSize. | |
79b9da22 A |
80 | size_t kBigEnoughSize = (saltLen + CC_SHA256_DIGEST_LENGTH) + 2 * CC_SHA256_DIGEST_LENGTH; |
81 | uint8_t *temp_data = malloc(kBigEnoughSize); | |
82 | ||
83 | if (temp_data == NULL) { | |
84 | return errSecMemoryError; | |
85 | } | |
6b200bc3 A |
86 | |
87 | pbkdf2(hmac_sha256_PRF, CC_SHA256_DIGEST_LENGTH, | |
88 | passwordPtr, passwordLen, | |
89 | saltPtr, saltLen, | |
90 | iterationCount, | |
91 | dkPtr, dkLen, | |
92 | temp_data); | |
93 | ||
94 | bzero(temp_data, kBigEnoughSize); | |
79b9da22 A |
95 | |
96 | return errSecSuccess; | |
6b200bc3 | 97 | } |
b1ab9ed8 | 98 | |
79b9da22 | 99 | OSStatus SecKeyFromPassphraseDataHMACSHA1(CFDataRef password, CFDataRef salt, uint32_t interationCount, CFMutableDataRef derivedKey) |
b1ab9ed8 | 100 | { |
79b9da22 | 101 | return pbkdf2_hmac_sha1(CFDataGetBytePtr(password), CFDataGetLength(password), |
b1ab9ed8 A |
102 | CFDataGetBytePtr(salt), CFDataGetLength(salt), |
103 | interationCount, | |
104 | CFDataGetMutableBytePtr(derivedKey), CFDataGetLength(derivedKey)); | |
105 | ||
106 | } | |
6b200bc3 | 107 | |
79b9da22 | 108 | OSStatus SecKeyFromPassphraseDataHMACSHA256(CFDataRef password, CFDataRef salt, uint32_t interationCount, CFMutableDataRef derivedKey) |
6b200bc3 | 109 | { |
79b9da22 | 110 | return pbkdf2_hmac_sha256(CFDataGetBytePtr(password), CFDataGetLength(password), |
6b200bc3 A |
111 | CFDataGetBytePtr(salt), CFDataGetLength(salt), |
112 | interationCount, | |
113 | CFDataGetMutableBytePtr(derivedKey), CFDataGetLength(derivedKey)); | |
114 | ||
115 | } |