in src/hmac.c [113:170]
int HMAC_SHA256_oneshot(char* out, int outlen,
const char* key, int keylen,
const char* in, int inlen)
{
if (out == NULL || key == NULL || in == NULL)
return ERR_NULLPOINTER_HMAC;
if (keylen < SHA256_HASH_SIZE)
return ERR_KEYSIZE_HMAC;
if (outlen <= 0 || outlen > SHA256_HASH_SIZE || inlen < 0)
return ERR_BADARGLEN_HMAC;
int i;
hash256 sha256;
char ipad = 0x36;
char opad = 0x5c;
char k0[SHA256_BLOCK_SIZE];
char digest[SHA256_HASH_SIZE];
HASH256_init(&sha256);
// Fill k0 with 0s for future padding
for(i = 0; i < SHA256_BLOCK_SIZE; i++)
k0[i] = 0x00;
// If the key size is larger than the block size, then hash it
if (keylen > SHA256_BLOCK_SIZE) {
for(i = 0; i < keylen; i++)
HASH256_process(&sha256, key[i]);
HASH256_hash(&sha256, k0);
}
// Otherwise the key is simply padded with 0s into k0
else {
for(i = 0; i < keylen; i++)
k0[i] = key[i];
}
// Compute H((k0 ^ ipad) || in)
for(i = 0; i < SHA256_BLOCK_SIZE; i++)
HASH256_process(&sha256, k0[i] ^ ipad);
for(i = 0; i < inlen; i++)
HASH256_process(&sha256, in[i]);
HASH256_hash(&sha256, digest);
// Compute `H((k0 ^ opad ) || H((k0 ^ ipad) || in))`
for(i = 0; i < SHA256_BLOCK_SIZE; i++)
HASH256_process(&sha256, k0[i] ^ opad);
for(i = 0; i < SHA256_HASH_SIZE; i++)
HASH256_process(&sha256, digest[i]);
HASH256_hash(&sha256, digest);
// Erase the secret key as it is not needed anymore
for(i = 0; i < SHA256_BLOCK_SIZE; i++)
k0[i] = 0x00;
for(i = 0; i < outlen; i++)
out[i] = digest[i];
return SUCCESS;
}