# Why there isn't a consistent key transform function of HMAC?

I am currently learning, the internal working of HMAC. There exists a key transformation process in the beginning, which works as follows:-

Make the length of $$K$$ (Key) equal to $$B$$ (number of bits in each block):-

1) If Length of $$K$$ < $$B$$:- Pad 0 bits to the beginning of the message, to the point the the above condition is satisfied.

2) If Length of $$K$$ = $$B$$:- Do nothing (or proceed to the further step)

3) If Length of $$K$$ > $$B$$:- Pass $$K$$ with a Message Digest algorithm, which will return a key trimmed down i.e. it satisfy the condition len($$K$$) = len($$B$$)

QUESTIONS:-

1. Why can't we simply pass the $$K$$ via a Message Digest Algorithm, whether the key size is less or more? Because the output will be of the same size (the size that we expect), then why bother doing padding in one process and passing via a Message Digest Algorithm in other?
2. Or why not choose a consistent trimming/padding scheme instead of using a Message Digest Algorithm. By that I mean, if the $$K$$ > $$B$$, then do trimming of bits to a particular size which is predefined (not the best option, but seems like a way to achieve the result too).

## Why does HMAC do that?

The process of expanding or compressing the key material to exactly one block length this way shouldn't be necessary from a security perspective. The reason for this transformation is to enable an optimization when the same key will be used to process multiple messages. (See RFC 2104)

If this optimization is used, it means that you can eliminate the need to process the inner key more than once. This part of the specification allows an implemenation take a snapshot of the hash function state after processing a whole block. If anything less than one block were used, then this wouldn't help. A hash function cannot process part of a message until after it knows the full block.

Because the first block never contains message bits, it is possible to pre-compute this hash function state as soon as you know the key. Had the first block been allowed to contain message bits, there wouldn't be much work HMAC's underlying hash function could do until it knew those message bits.

Consistently padding keys to a multiple of the block size would also allow pre-computation. But I'm guessing that method was ruled out to save a few bytes RAM/ROM and keep things related to this optimization simple.

The one security downside to the actual HMAC specification is that it is trivial to generate distinct but equivalent keys.

(That's only an issue if the source that provides the key is untrusted, key sizes are variable, and there is something application-specific that requires it be impossible to find equivalent keys. For basic message authentication a trusted source or fixed length key is enough to avoid that potential issue.)

## Why is it inconsistent?

I don't know, but it was published in 1996. There are a bunch of examples of 90's cryptography that seem strange in hindsight.

HMAC could have been designed in some other way that enables similar optimizations. Something as simple as prepending the key length to the inner key then padding the new string with zeros to a multiple of one block size, for example.

In practice there isn't much need to implement case 3. Most modern hash algorithms (and even insecure algorithms from the same era as HMAC, like MD5, SHA-1, and RIPEMD) have block sizes much bigger than the length needed for symmetric keys.

(However, key exchange algorithms may generate larger shared secrets, but then you probably have access to something like HKDF. (You shouldn't use the same key for encryption and authentication, after all.))

It wouldn't be unreasonable to write an implementation that only supports case 1 and 2. (The decision should be documented and trying to use HMAC with overly long keys should be treated as an error.) In my opinion it's probably a good idea to force programmers to explicitly pre-hash long keys if they need full compatibility with HMAC.