]> git.saurik.com Git - apple/security.git/blob - OSX/sec/Security/SecPBKDF.c
Security-58286.200.222.tar.gz
[apple/security.git] / OSX / sec / Security / SecPBKDF.c
1 /*
2 * SecPBKDF.c
3 *
4 * Copyright (c) 2010,2012 Apple Inc. All Rights Reserved.
5 *
6 */
7
8 #include "Security/SecPBKDF.h"
9 #include "Security/pbkdf2.h"
10
11 #include <CommonCrypto/CommonHMAC.h>
12 #include "Security/SecBase.h"
13
14 #include <stdlib.h>
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
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
44
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)
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.
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 }
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
67 bzero(temp_data, kBigEnoughSize);
68
69 return errSecSuccess;
70 }
71
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)
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.
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 }
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);
95
96 return errSecSuccess;
97 }
98
99 OSStatus SecKeyFromPassphraseDataHMACSHA1(CFDataRef password, CFDataRef salt, uint32_t interationCount, CFMutableDataRef derivedKey)
100 {
101 return pbkdf2_hmac_sha1(CFDataGetBytePtr(password), CFDataGetLength(password),
102 CFDataGetBytePtr(salt), CFDataGetLength(salt),
103 interationCount,
104 CFDataGetMutableBytePtr(derivedKey), CFDataGetLength(derivedKey));
105
106 }
107
108 OSStatus SecKeyFromPassphraseDataHMACSHA256(CFDataRef password, CFDataRef salt, uint32_t interationCount, CFMutableDataRef derivedKey)
109 {
110 return pbkdf2_hmac_sha256(CFDataGetBytePtr(password), CFDataGetLength(password),
111 CFDataGetBytePtr(salt), CFDataGetLength(salt),
112 interationCount,
113 CFDataGetMutableBytePtr(derivedKey), CFDataGetLength(derivedKey));
114
115 }