On Thu, Apr 25, 2013 at 7:51 PM, Niels Möller nisse@lysator.liu.se wrote:
Nikos Mavrogiannopoulos n.mavrogiannopoulos@gmail.com writes:
Moreover, I need two hmac contexts in order to implement reset().
Can you explain how this works and what is needed? I don't remember much of TLS, so I have no idea what "reset" means here.
The current HMAC API assumes that the hashing state is kept per call. That is if I have to hash a series of packets with contents X_0, X_1, ..., X_n I do: hmac_set_key(s); for (i=1;i<n;i++) { hmac_update(s, X_i) hmac_digest(s, output) }
In this approach the output of X_i contains the state which resulted from hashing X_(i-1). In TLS, however, hmac is used simply as: for (i=1;i<n;i++) { hmac_set_key(s); hmac_update(s, X_i) hmac_digest(s, output) }
that is the MAC of X_i is independent of X_(i-1), and no state is kept across records. The reset I am mentioning is a simplification of the above as: hmac_set_key(s); for (i=1;i<n;i++) { hmac_update(s, X_i) hmac_digest(s, output) hmac_reset(s) }
and effectively sets the state s, to the same values it was after hmac_set_key().
On plain HMAC the memory for the hashes was not that significant, but on umac that method is quite wasteful. I don't see a straightforward solution to that though, without a high level API.
Would it help to have a separate struct for the expanded key, and use that key with several per-message contexts? A bit like the split between struct gcm_key and struct gcm_ctx, in gcm.h? The same could be done also with hmac, if needed.
That looks like a nice and clean solution. Would it be something like: hmac_set_key(struct hmac_key*) hmac_init(struct hmac_ctx*, struct hmac_key*) hmac_update(struct hmac_ctx*) hmac_digest(struct hmac_ctx*, output) ?
It would be nice if umac could be used under such an abstraction (or if the umac_set_nonce would imply the reset).
regards, Nikos