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 13#include <string.h> 14 15/* CC Based HMAC PRF functions */ 16void hmac_sha1_PRF(const uint8_t *key, 17 size_t key_len, 18 const uint8_t *text, 19 size_t text_len, 20 uint8_t digest[CC_SHA1_DIGEST_LENGTH]) 21{ 22 CCHmacContext hmac_sha1_context; 23 24 CCHmacInit(&hmac_sha1_context, kCCHmacAlgSHA1, key, key_len); 25 CCHmacUpdate(&hmac_sha1_context, text, text_len); 26 CCHmacFinal(&hmac_sha1_context, digest); 27} 28 29 30/* This implements the HMAC SHA-1 version of pbkdf2 and allocates a local buffer for the HMAC */ 31void pbkdf2_hmac_sha1(const uint8_t *passwordPtr, size_t passwordLen, 32 const uint8_t *saltPtr, size_t saltLen, 33 uint32_t iterationCount, 34 void *dkPtr, size_t dkLen) 35{ 36 // MAX(salt_length + 4, 20 /* SHA1 Digest size */) + 2 * 20; 37 // salt_length + HASH_SIZE is bigger than either salt + 4 and digestSize. 38 const size_t kBigEnoughSize = (saltLen + CC_SHA1_DIGEST_LENGTH) + 2 * CC_SHA1_DIGEST_LENGTH; 39 uint8_t temp_data[kBigEnoughSize]; 40 41 pbkdf2(hmac_sha1_PRF, CC_SHA1_DIGEST_LENGTH, 42 passwordPtr, passwordLen, 43 saltPtr, saltLen, 44 iterationCount, 45 dkPtr, dkLen, 46 temp_data); 47 48 bzero(temp_data, kBigEnoughSize); 49} 50 51 52void SecKeyFromPassphraseDataHMACSHA1(CFDataRef password, CFDataRef salt, uint32_t interationCount, CFMutableDataRef derivedKey) 53{ 54 pbkdf2_hmac_sha1(CFDataGetBytePtr(password), CFDataGetLength(password), 55 CFDataGetBytePtr(salt), CFDataGetLength(salt), 56 interationCount, 57 CFDataGetMutableBytePtr(derivedKey), CFDataGetLength(derivedKey)); 58 59} 60