I am having to implement my own HMAC-SHA256 for use in an embedded project. I am having trouble getting it to work. I cant even get the pseudo code, hand-calculated to work, so I know I am doing something wrong!
My pseduoCode calcuations. Following the diagram in wikipedia
1 function hmac (key, message)
2 if (length(key) > blocksize) then
3 // keys longer than blocksize are shortened
4 key = hash(key)
5 end if
6 if (length(key) < blocksize) then
7 // keys shorter than blocksize are zero-padded
8 key = key ∥ zeroes(blocksize - length(key))
9 end if
10
11 // Where blocksize is that of the underlying hash function
12 o_key_pad = [0x5c * blocksize] ⊕ key
13 i_key_pad = [0x36 * blocksize] ⊕ key // Where ⊕ is exclusive or (XOR)
14 // Where ∥ is concatenation
15 return hash(o_key_pad ∥ hash(i_key_pad ∥ message))
16 end function
When I do by-hand calculations for key="mykey" and message="helloworld" I get the following:
key = 0x6d796b6579000000000000000000000000000000000000000000000000000000
o_key_pad = 0x31253739255c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c5c
i_key_pad = 0x5b4f5d534f363636363636363636363636363636363636363636363636363636
hash(i_key_pad ∥ message) = 6fb2e91de7b8b5ec6283846ff7245cd6eb4a4fd26056b529bd42d99fcf3314d2
and the overall hmac of 0d76a16089f85cd2169bb64b6f2c818e6a404a218896483fcd97fee5cce185ae
When fixing the key length and calulating the inner and outer padding, you need to use the blocksize of the underlying hash function, which is not the same as its output size. This is the size of the input blocks that the function operates on. In the case of SHA256, the blocksize is 512 bits (64 bytes) and the output size is 256 bits (32 bytes).
Your results are what you get if you use 32 as the blocksize.
Using the correct length blocksize the
key
,o_key_pad
andi_key_pad
are basically the same, only twice as long with trailing00
,5c
or36
bytes respectively.The result of the inner hash (i.e.
hash(i_key_pad ∥ message)
is:and the final value (
hash(o_key_pad ∥ hash(i_key_pad ∥ message))
) is:which matches the result I get from OpenSSL’s HMAC implementation.