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 }