aboutsummaryrefslogtreecommitdiff
path: root/hash.c
diff options
context:
space:
mode:
authorRob Austein <sra@hactrn.net>2015-06-04 16:00:43 -0400
committerRob Austein <sra@hactrn.net>2015-06-04 16:00:43 -0400
commit9176df4906ae90df7b0b1e16485571fd3d3132d8 (patch)
tree4a7f972ed39676dff012c2a8e7714e2b32d6a314 /hash.c
parent456de6962b4f96f7775e5ad56e057ea112d77bce (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.
Diffstat (limited to 'hash.c')
-rw-r--r--hash.c41
1 files changed, 20 insertions, 21 deletions
diff --git a/hash.c b/hash.c
index 2a05150..224aac4 100644
--- a/hash.c
+++ b/hash.c
@@ -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;