#include "pbkdf2.h"
#include <CoreServices/../Frameworks/CarbonCore.framework/Headers/ConditionalMacros.h>
#include <string.h>
static void
F (PRF prf, UInt32 hLen,
const void *passwordPtr, UInt32 passwordLen,
const void *saltPtr, UInt32 saltLen,
UInt32 iterationCount,
UInt32 blockNumber,
void *dataPtr,
void *tempBuffer)
{
UInt8 *inBlock, *outBlock, *resultBlockPtr;
UInt32 iteration;
outBlock = (UInt8*)tempBuffer;
inBlock = outBlock + hLen;
memcpy (inBlock, saltPtr, saltLen);
#if TARGET_RT_LITTLE_ENDIAN
inBlock[saltLen + 0] = (UInt8)(blockNumber);
inBlock[saltLen + 1] = (UInt8)(blockNumber >> 8);
inBlock[saltLen + 2] = (UInt8)(blockNumber >> 16);
inBlock[saltLen + 3] = (UInt8)(blockNumber >> 24);
#else
inBlock[saltLen + 0] = (UInt8)(blockNumber >> 24);
inBlock[saltLen + 1] = (UInt8)(blockNumber >> 16);
inBlock[saltLen + 2] = (UInt8)(blockNumber >> 8);
inBlock[saltLen + 3] = (UInt8)(blockNumber);
#endif
resultBlockPtr = (UInt8*)dataPtr;
prf (passwordPtr, passwordLen, inBlock, saltLen + 4, outBlock);
memcpy (resultBlockPtr, outBlock, hLen);
for (iteration = 2; iteration <= iterationCount; iteration++)
{
UInt8 *tempBlock;
UInt32 byte;
tempBlock = inBlock;
inBlock = outBlock;
outBlock = tempBlock;
prf (passwordPtr, passwordLen, inBlock, hLen, outBlock);
for (byte = 0; byte < hLen; byte++)
resultBlockPtr[byte] ^= outBlock[byte];
}
}
void pbkdf2 (PRF prf, UInt32 hLen,
const void *passwordPtr, UInt32 passwordLen,
const void *saltPtr, UInt32 saltLen,
UInt32 iterationCount,
void *dkPtr, UInt32 dkLen,
void *tempBuffer)
{
UInt32 completeBlocks = dkLen / hLen;
UInt32 partialBlockSize = dkLen % hLen;
UInt32 blockNumber;
UInt8 *dataPtr = (UInt8*)dkPtr;
UInt8 *blkBuffer = (UInt8*)tempBuffer;
for (blockNumber = 1; blockNumber <= completeBlocks; blockNumber++)
{
F (prf, hLen, passwordPtr, passwordLen, saltPtr, saltLen,
iterationCount, blockNumber, dataPtr, blkBuffer + hLen);
dataPtr += hLen;
}
if (partialBlockSize > 0)
{
F (prf, hLen, passwordPtr, passwordLen, saltPtr, saltLen,
iterationCount, blockNumber, blkBuffer, blkBuffer + hLen);
memcpy (dataPtr, blkBuffer, partialBlockSize);
}
}