]> git.saurik.com Git - apple/security.git/blame - OSX/sec/Security/SecPBKDF.c
Security-59754.80.3.tar.gz
[apple/security.git] / OSX / sec / Security / SecPBKDF.c
CommitLineData
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 */
18void 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
31void 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 46OSStatus 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 73OSStatus 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 99OSStatus 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 108OSStatus 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}