diff options
author | Rob Austein <sra@hactrn.net> | 2015-06-04 16:00:43 -0400 |
---|---|---|
committer | Rob Austein <sra@hactrn.net> | 2015-06-04 16:00:43 -0400 |
commit | 9176df4906ae90df7b0b1e16485571fd3d3132d8 (patch) | |
tree | 4a7f972ed39676dff012c2a8e7714e2b32d6a314 | |
parent | 456de6962b4f96f7775e5ad56e057ea112d77bce (diff) |
Whoops, we're supposed to hash an entire block for the key regardless
of how long the key is. With this fix, HMAC passes tests on Novena.
-rw-r--r-- | hash.c | 41 |
1 files changed, 20 insertions, 21 deletions
@@ -104,7 +104,6 @@ typedef struct { typedef struct { internal_hash_state_t hash_state; /* Hash state */ uint8_t keybuf[MAX_BLOCK_LEN]; /* HMAC key */ - size_t keylen; /* Length of HMAC key */ } internal_hmac_state_t; /* @@ -471,45 +470,45 @@ hal_error_t hal_hmac_initialize(const hal_hash_descriptor_t * const descriptor, state_length < descriptor->hmac_state_length) return HAL_ERROR_BAD_ARGUMENTS; + assert(descriptor->block_length <= sizeof(state->keybuf)); + +#if 0 /* * RFC 2104 frowns upon keys shorter than the digest length. + * ... but most of the test vectors fail this test! */ if (key_length < descriptor->digest_length) return HAL_ERROR_UNSUPPORTED_KEY; +#endif if ((err = hal_hash_initialize(descriptor, &oh, h, sizeof(*h))) != HAL_OK) return err; - memset(state->keybuf, 0, sizeof(state->keybuf)); - /* * If the supplied HMAC key is longer than the hash block length, we * need to hash the supplied HMAC key to get the real HMAC key. * Otherwise, we just use the supplied HMAC key directly. */ - if (key_length > descriptor->block_length) { - if ((err = hal_hash_update(oh, key, key_length)) != HAL_OK || - (err = hal_hash_finalize(oh, state->keybuf, sizeof(state->keybuf))) != HAL_OK || - (err = hal_hash_initialize(descriptor, &oh, h, sizeof(*h))) != HAL_OK) - return err; - state->keylen = descriptor->digest_length; - } + memset(state->keybuf, 0, sizeof(state->keybuf)); - else { + if (key_length <= descriptor->block_length) memcpy(state->keybuf, key, key_length); - state->keylen = key_length; - } + + else if ((err = hal_hash_update(oh, key, key_length)) != HAL_OK || + (err = hal_hash_finalize(oh, state->keybuf, sizeof(state->keybuf))) != HAL_OK || + (err = hal_hash_initialize(descriptor, &oh, h, sizeof(*h))) != HAL_OK) + return err; /* * XOR the key with the IPAD value, then start the inner hash. */ - for (i = 0; i < state->keylen; i++) + for (i = 0; i < descriptor->block_length; i++) state->keybuf[i] ^= HMAC_IPAD; - if ((err = hal_hash_update(oh, state->keybuf, state->keylen)) != HAL_OK) + if ((err = hal_hash_update(oh, state->keybuf, descriptor->block_length)) != HAL_OK) return err; /* @@ -517,7 +516,7 @@ hal_error_t hal_hmac_initialize(const hal_hash_descriptor_t * const descriptor, * IPAD, we need to XOR with both IPAD and OPAD to get key XOR OPAD. */ - for (i = 0; i < state->keylen; i++) + for (i = 0; i < descriptor->block_length; i++) state->keybuf[i] ^= HMAC_IPAD ^ HMAC_OPAD; /* @@ -575,11 +574,11 @@ hal_error_t hal_hmac_finalize(const hal_hmac_state_t opaque_state, * to get HMAC. Key was prepared for this in hal_hmac_initialize(). */ - if ((err = hal_hash_finalize(oh, d, sizeof(d))) != HAL_OK || - (err = hal_hash_initialize(descriptor, &oh, h, sizeof(*h))) != HAL_OK || - (err = hal_hash_update(oh, state->keybuf, state->keylen)) != HAL_OK || - (err = hal_hash_update(oh, d, descriptor->digest_length)) != HAL_OK || - (err = hal_hash_finalize(oh, hmac, length)) != HAL_OK) + if ((err = hal_hash_finalize(oh, d, sizeof(d))) != HAL_OK || + (err = hal_hash_initialize(descriptor, &oh, h, sizeof(*h))) != HAL_OK || + (err = hal_hash_update(oh, state->keybuf, descriptor->block_length)) != HAL_OK || + (err = hal_hash_update(oh, d, descriptor->digest_length)) != HAL_OK || + (err = hal_hash_finalize(oh, hmac, length)) != HAL_OK) return err; return HAL_OK; |