So over the past day, I was working on adding HMAC and PBKDF2 to hashlib, yet my PBKDF code is not returning a hash that matches any of the known hashes a generator or php's builtin one returns. After so many attempts to fix, from rewriting the HMAC code, to checking endianness, nothing is working, so I'll post here and see if anyone can spot what's wrong.
Code: https://github.com/acagliano/hashlib/blob/dev/src/main.c#L1727
From what I understand, SHA256 HMAC is more or less SHA-256, with some modifications to the Init and Final functions. In Init, it xors the key with the ipad, and updates the initial state with the ipad. In Final, it hashes the ipad with the message to return a digest, then hashes the opad and that digest to return the HMAC. I implemented that code in lines 1727-1771.
https://en.wikipedia.org/wiki/HMAC
As for PBKDF2, it seems like it works this way:
Code:
https://en.wikipedia.org/wiki/PBKDF2
Yet my code refuses to produce the correct output.
Edit: After some testing, I have realized that my HMAC code isn't working. Now I did notice one error in it, which I corrected, and pushed, but the output still doesn't match what it should be.
I've consulted the wiki on HMAC, as well as the RFC documentation on PKCS#5 (https://datatracker.ietf.org/doc/rfc8018/) (didn't find HMAC listed). Also consulted 2 other implementations:
https://github.com/aperezdc/hmac-sha256/blob/master/hmac-sha256.c
https://github.com/h5p9sl/hmac_sha256/blob/master/hmac_sha256.c
Despite mine being schismed into update/init/final, the algorithm looks more or less the same. Therefore I am at a complete loss and am posting this here hoping other people can take a look and see they notice anything I'm not seeing.
Code: https://github.com/acagliano/hashlib/blob/dev/src/main.c#L1727
From what I understand, SHA256 HMAC is more or less SHA-256, with some modifications to the Init and Final functions. In Init, it xors the key with the ipad, and updates the initial state with the ipad. In Final, it hashes the ipad with the message to return a digest, then hashes the opad and that digest to return the HMAC. I implemented that code in lines 1727-1771.
https://en.wikipedia.org/wiki/HMAC
As for PBKDF2, it seems like it works this way:
Code:
Given:
passwd = password of length plen,
salt = random string of len slen
rounds = number of iterations
keylen = number of bytes to output
key = output PBKDF2 key
key = PBKDF2(passwd, salt, rounds, keylen):
block = 1
for pos from 0 => keylen by 32:
sha256_hmac_setup_key(password)
sha256_hmac_update(salt)
sha256_hmac_update(BIG_ENDIAN(block++))
sha_composite = sha256_hmac_final()
for count from 1 to rounds:
sha256_hmac_reset() \ sets back to state after setup key
sha256_hmac_update(sha_composite)
sha_buffer = sha256_hmac_final()
sha_composite ^= sha_buffer
memcpy(&key[pos], sha_composite, MIN(32, keylen-blocks))
https://en.wikipedia.org/wiki/PBKDF2
Yet my code refuses to produce the correct output.
Edit: After some testing, I have realized that my HMAC code isn't working. Now I did notice one error in it, which I corrected, and pushed, but the output still doesn't match what it should be.
I've consulted the wiki on HMAC, as well as the RFC documentation on PKCS#5 (https://datatracker.ietf.org/doc/rfc8018/) (didn't find HMAC listed). Also consulted 2 other implementations:
https://github.com/aperezdc/hmac-sha256/blob/master/hmac-sha256.c
https://github.com/h5p9sl/hmac_sha256/blob/master/hmac_sha256.c
Despite mine being schismed into update/init/final, the algorithm looks more or less the same. Therefore I am at a complete loss and am posting this here hoping other people can take a look and see they notice anything I'm not seeing.