1
$\begingroup$

I am searching test vectors of the HMAC-SHA256 primitive to verify the correctness of an implementation.

Without hesitation I go on the NIST website to see what they offer.

While reading the corresponding file (HMAC.rsp from hmactestvectors.zip) I can see that the given test vectors associated to the SHA256 hash function are computed with different key sizes: $40$, $45$, $64$ and $70$ (in bytes).

I was a little surprised about this because according to the RFC 4868, the key used should be composed of $32$ bytes:

While no fixed key length is specified in [HMAC], this specification requires that when used as an integrity/authentication algorithm, a fixed key length equal to the output length of the hash functions MUST be supported, and key lengths other than the output length of the associated hash function MUST NOT be supported.

On the other hand, I read:

However cryptographic keys (for symmetric algorithms like HMAC) longer than 128 bits don't really add security, so there is no actual need to go to a full block-length key

(see What are requirements for HMAC secret key?)

That's why these test vectors are getting me confused:

  1. According to the RFC mentioned above, the key used should be a $256$-bit key.
  2. It seems that most of the time, HMAC is computed with a $128$-bit key.

But NIST test vectors are using longer keys than the output length (ie $256$ bits because SHA256 is used). Still according to RFC 4868:

key lengths less than the output length decrease security strength, and keys longer than the output length do not significantly increase security strength

So why did the NIST use these key sizes to compute their test vectors? Is it because HMAC algorithm is mainly based on a hash function and it's this feature that requires special assessment? There is also this document which specifies the procedures involved in validating implementations of HMAC but I don't see anything that justify the choice of the key sizes.

To verify the implementation in question is it possible to find other test vectors? Can I consider that if the ones given in RFC 4868 are verified then it's well implemented?

$\endgroup$
3
$\begingroup$

RFC4868 is not the HMAC RFC, which is actually RFC 2104. 4868 refers to the use of HMAC within IPSEC, which is why there is a key length restriction.

The maximum length key that can be used internally with HMAC-SHA256 is equal to the block size, 64 bytes or 512 bits. This can be useful in cases where the key is not full entropy such as the shared secret generated by a Diffie-Hellman key exchange; an ECDH secret of 512 bits has around 256-bits of security.

If the key length exceeds the block length, it must be first hashed to get it to fit within the block, this is the reason for the 70 byte test value, to make sure that implementations can properly handle it. The other lengths in the NIST vectors are one equal to the block length, and 2 arbitrarily shorter lengths. If an implementation can handle all 4 test values, it is generally safe to assume it can handle a 32-byte key as well.

$\endgroup$
  • $\begingroup$ Good answer. The NIST CAVP test vectors are based on values they have chosen to be generated. These four values chosen are example. It is not feasible to have all the possible values in the test vectors so they need to pick some. However, when a cryptographic product is validated (in Cryptographic Algorithm Validation Program, such as for FIPS 140-2), it is possible to select specific key sizes, which will be tested. $\endgroup$ – user4982 Feb 5 '16 at 19:45
2
$\begingroup$

The question why these things are chosen is not really answerable, except by the persons involved at NIST. I don't think there is too much to test though; after you test a few vectors you're testing the hash function rather than the HMAC.

A quick test shows the test vector in RFC 4868 2.7.2.1. SHA256 Authentication Test Vectors to be correct, in case you really need a test with a 32 byte key. I'd assume these are correct though. If you get the same value in your implementation then there should be something very wrong if they're off somehow.


If you want to really test your implementation, try and identify all the corner cases in your implementation. Then generate the input/output values with another well tested implementation and compare.

E.g. if you have an update function, make sure you don't have any instances where a byte is read out of bounds. Test the same vector using 1, 2 and 3 times update, i.e. try with different chunk sizes.

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.