rlm@1: // Pbkdf2HmacSha1.cpp rlm@1: rlm@1: #include "StdAfx.h" rlm@1: rlm@1: #include "HmacSha1.h" rlm@1: rlm@1: namespace NCrypto { rlm@1: namespace NSha1 { rlm@1: rlm@1: void Pbkdf2Hmac(const Byte *pwd, size_t pwdSize, const Byte *salt, size_t saltSize, rlm@1: UInt32 numIterations, Byte *key, size_t keySize) rlm@1: { rlm@1: CHmac baseCtx; rlm@1: baseCtx.SetKey(pwd, pwdSize); rlm@1: for (UInt32 i = 1; keySize > 0; i++) rlm@1: { rlm@1: CHmac ctx = baseCtx; rlm@1: ctx.Update(salt, saltSize); rlm@1: Byte u[kDigestSize] = { (Byte)(i >> 24), (Byte)(i >> 16), (Byte)(i >> 8), (Byte)(i) }; rlm@1: const unsigned int curSize = (keySize < kDigestSize) ? (unsigned int)keySize : kDigestSize; rlm@1: ctx.Update(u, 4); rlm@1: ctx.Final(u, kDigestSize); rlm@1: rlm@1: unsigned int s; rlm@1: for (s = 0; s < curSize; s++) rlm@1: key[s] = u[s]; rlm@1: rlm@1: for (UInt32 j = numIterations; j > 1; j--) rlm@1: { rlm@1: ctx = baseCtx; rlm@1: ctx.Update(u, kDigestSize); rlm@1: ctx.Final(u, kDigestSize); rlm@1: for (s = 0; s < curSize; s++) rlm@1: key[s] ^= u[s]; rlm@1: } rlm@1: rlm@1: key += curSize; rlm@1: keySize -= curSize; rlm@1: } rlm@1: } rlm@1: rlm@1: void Pbkdf2Hmac32(const Byte *pwd, size_t pwdSize, const UInt32 *salt, size_t saltSize, rlm@1: UInt32 numIterations, UInt32 *key, size_t keySize) rlm@1: { rlm@1: CHmac32 baseCtx; rlm@1: baseCtx.SetKey(pwd, pwdSize); rlm@1: for (UInt32 i = 1; keySize > 0; i++) rlm@1: { rlm@1: CHmac32 ctx = baseCtx; rlm@1: ctx.Update(salt, saltSize); rlm@1: UInt32 u[kDigestSizeInWords] = { i }; rlm@1: const unsigned int curSize = (keySize < kDigestSizeInWords) ? (unsigned int)keySize : kDigestSizeInWords; rlm@1: ctx.Update(u, 1); rlm@1: ctx.Final(u, kDigestSizeInWords); rlm@1: rlm@1: // Speed-optimized code start rlm@1: ctx = baseCtx; rlm@1: ctx.GetLoopXorDigest(u, numIterations - 1); rlm@1: // Speed-optimized code end rlm@1: rlm@1: unsigned int s; rlm@1: for (s = 0; s < curSize; s++) rlm@1: key[s] = u[s]; rlm@1: rlm@1: /* rlm@1: // Default code start rlm@1: for (UInt32 j = numIterations; j > 1; j--) rlm@1: { rlm@1: ctx = baseCtx; rlm@1: ctx.Update(u, kDigestSizeInWords); rlm@1: ctx.Final(u, kDigestSizeInWords); rlm@1: for (s = 0; s < curSize; s++) rlm@1: key[s] ^= u[s]; rlm@1: } rlm@1: // Default code end rlm@1: */ rlm@1: rlm@1: key += curSize; rlm@1: keySize -= curSize; rlm@1: } rlm@1: } rlm@1: rlm@1: }}