Implement (modified) HMAC
This commit is contained in:
parent
08c8d33b20
commit
9a0b35609b
43
puer.c
43
puer.c
|
@ -205,3 +205,46 @@ void finalize_hash(struct hashstate *state, unsigned char hash[32]) {
|
||||||
// there
|
// there
|
||||||
explicit_bzero(state, sizeof(struct hashstate));
|
explicit_bzero(state, sizeof(struct hashstate));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void hmac(unsigned char output[32], unsigned char key[], size_t keylen, unsigned char message[], size_t messagelen) {
|
||||||
|
// The blocksize of the underlying has function is 128 bits (16B)
|
||||||
|
// but HMAC is specified assuming that the hash function output (in
|
||||||
|
// our case 256 bits or 32B) fits in one block. As far as I can
|
||||||
|
// tell extending the key to be two blocks long is not a problem.
|
||||||
|
|
||||||
|
unsigned char padded_key[32];
|
||||||
|
if (keylen > 16) {
|
||||||
|
// We hash it even if it is shorter than our extended key
|
||||||
|
// length to avoid giving attacker any funny surfaces to
|
||||||
|
// play with at the interface of two blocks
|
||||||
|
struct hashstate state;
|
||||||
|
initialize_hash(&state);
|
||||||
|
feed_hash(&state, key, keylen);
|
||||||
|
finalize_hash(&state, padded_key);
|
||||||
|
} else {
|
||||||
|
// Copy the key and zero-pad if necessary
|
||||||
|
memset(padded_key, 0, 32);
|
||||||
|
memcpy(padded_key, key, keylen);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Outer and inner key derivation
|
||||||
|
unsigned char outer_key[32], inner_key[32];
|
||||||
|
for (size_t i = 0; i < 32; i++) {
|
||||||
|
outer_key[i] = padded_key[i] ^ 0x5c;
|
||||||
|
inner_key[i] = padded_key[i] ^ 0x36;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Inner hash
|
||||||
|
unsigned char inner_hash[32];
|
||||||
|
struct hashstate state;
|
||||||
|
initialize_hash(&state);
|
||||||
|
feed_hash(&state, inner_key, 32);
|
||||||
|
feed_hash(&state, message, messagelen);
|
||||||
|
finalize_hash(&state, inner_hash);
|
||||||
|
|
||||||
|
// Outer hash
|
||||||
|
initialize_hash(&state);
|
||||||
|
feed_hash(&state, outer_key, 32);
|
||||||
|
feed_hash(&state, inner_hash, 32);
|
||||||
|
finalize_hash(&state, output);
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue