# Is this a proper PBKDF2 key derivation function algorithm?

I've started implementing PBKDF2 algorithm recently and since I'm new in crypto, I would like to ask if my implementation is good.
I looked up some documentations and I tried to follow many of them and now I am really confused.

Documentations I've followed:
https://en.wikipedia.org/wiki/PBKDF2
https://en.wikipedia.org/wiki/Hash-based_message_authentication_code
crackstation(.)net/hashing-security.htm#properhashing // (Sorry, I can't post more than 2 links.) And many more to which I no more have got links.

Here is my C/C++ code:

typedef unsigned long UL;
volatile class KDF2
{
#define hLenSz 32 // Block size of sha256 in bytes
public:
KDF2()
{
}

std::string PBKDF2(string Password, string Salt, int c, int dkLen)
{
//Restrict max 128 bytes of Derivated Key
if(dkLen > 128)
{
dkLen = 128;
}

const int BlockSize = hLenSz / sizeof(UL); // 8 bytes

UL T[32] = {}; // Holds DK in 4 byte chunks
UL L[BlockSize] = {};
UL H[BlockSize] = {};
string hash = "";
string innerSalt = Salt + (char)dkLen;

int l = ceil((float)dkLen / (float)hLenSz); // Compute the number of passes needed to get the desired DK length

for(int i = 0; i < l; i++)
{
memset(L, 0, sizeof(L));

//Iterate c times
for(int j = 0; j < c; j++)
{
innerSalt = hash;

HexToLong(hash, H, BlockSize);
//XOR function
for(int p = 0; p < BlockSize; p++)
{
L[p] = L[p] ^ H[p];
}
}

for(int x = 0; x < BlockSize; x++)
{
T[BlockSize * i + x] = L[x];
}
}

std::string output = "";
for(int i = 0; i < dkLen / sizeof(UL); i++) // dkLen / 4 - unsigned long has 4 bytes
{
// hexify takes sizeof(T) and converts it to hex bytes
output += hexify<UL>(T[i]);
}
return output;
}

private:
//Hash-based message authentication code
{
char c;
string s;
UL Key[16] = {0};
UL X[16] = {0};
UL Y[16] = {0};
UL ipad = 0x36363636; // 0x36 = 54 = '6'
UL opad = 0x5c5c5c5c; // 0x5c = 92 = '\'
int k;
s = "";

//Process string key into sub-key
//Hash key in case it is less than 64 bytes
{

HexToLong(tmp, Key, 5);
}
else
{
for(int i = 0; i < 16; i++)
{
for(int j = 0; j < 4; j++)
{
if(4 * i + j <= Password.length())
{
k = Password[4 * i + j];
}
else
{
k = 0;
}
if(k < 0)
{
k = k + 256;
}
Key[i] += +k*pow(256, (double)3 - j);
}
}
}

for(int i = 0; i < 16; i++)
{
}

//Turn X-Array into a String
for(int i = 0; i < 16; i++)
{
for(int j = 0; j < 4; j++)
{
c = ((X[i] >> 8 * (3 - j)) % 256);
s += c;
}
}

//Append text to string
s += Salt;

string tmp = sha256(s);
HexToLong(tmp, Key, 5);

s = "";

//Convert Y array to a string
for(int i = 0; i < 16; i++)
{
for(int j = 0; j < 4; j++)
{
c = ((Y[i] >> 8 * (3 - j)) % 256);
s += c;
}
}

for(int i = 0; i < 5; i++)
{
for(int j = 0; j < 4; j++)
{
c = ((Key[i] >> 8 * (3 - j)) % 256);
s += c;
}
}

//Hash final aggregated string
return sha256(s);
}

UL f(UL B, UL C, UL D, int t)
{
if(t < 20)
{
return ((B & C) ^ ((~B) & D));
}
if((t > 19) & (t < 40))
{
return (B ^ C ^ D);
}
if((t > 39) & (t < 60))
{
return ((B & C) ^ (B & D) ^ (C & D));
}
if(t > 59)
{
return (B ^ C ^ D);
}
}

template< typename T >
std::string hexify(T i)
{
std::stringbuf buf;
std::ostream os(&buf);

os << std::setfill('0') << std::setw(sizeof(T) * 2) << std::hex << i;

return buf.str().c_str();
}

void HexToLong(string input, unsigned long* output, int outSize)
{
char hx[8] = {};

for(int i = 0; i < outSize; i++)
{
for(int j = 0; j < 8; j++)
{
hx[j] = input[j + (8 * i)];
}
output[i] = strtoul(hx, nullptr, 16);
}
}
};


The class is volatile because sometimes I ran into a optimization problem. I haven't yet figured out where the problem might be.

So to make it clear, my final questions are:

• Is this a proper PBKDF2 algorithm?

• Should PBKDF2 contain HMAC function or just iterate some hash over and over again with given No. iterations?

• How can I enhance the system?

• Why don't you test your implementation Commented Sep 14, 2015 at 23:11
• This would be better placed at code review. It's not a question about crypto, except Q2, which I think we'll not answer. Commented Sep 14, 2015 at 23:15
• @MaartenBodewes As I'm looking at the implementation test, that's not going to wrork for me. I'm using SHA256 instead of SHA1 and I've implemented some other things, that will make the final output different. Commented Sep 14, 2015 at 23:24
• If you've read the specification then you should be able to answer it yourself, right? HMAC is based on a hash, which can be configured as part of the configuration parameters... Commented Sep 15, 2015 at 0:03
• There seems to be some confusion about the term PBKDF2. A PBKDF is a generic term, meaning password based key derivation function. PBKDF1 and 2 are PBKDFs and so are bcrypt and scrypt. PBKDF2 on the other hand is a specific algorithm which has a single specification which you cannot deviate from. Now do you want to create your own PBKDF or do you want to implement PBKDF2? Commented Sep 15, 2015 at 0:09