Signed-off-by: Dmitry Eremin-Solenikov <[email protected]>
---
hmac.c | 62 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
hmac.h | 27 +++++++++++++++++++++++++
2 files changed, 89 insertions(+)
diff --git a/hmac.c b/hmac.c
index 6ac5e11a0686..6b925ce6e147 100644
--- a/hmac.c
+++ b/hmac.c
@@ -115,3 +115,65 @@ hmac_digest(const void *outer, const void *inner, void
*state,
memcpy(state, inner, hash->context_size);
}
+
+void
+hmac_block_set_key(void *outer, void *inner, void *state,
+ struct block_ctx *bctx,
+ const struct nettle_bctx_hash *hash,
+ size_t key_length, const uint8_t *key)
+{
+ TMP_DECL(pad, uint8_t, NETTLE_MAX_HASH_BLOCK_SIZE);
+ TMP_ALLOC(pad, hash->block_size);
+
+ hash->block_init(outer, bctx);
+ hash->block_init(inner, bctx);
+
+ if (key_length > hash->block_size)
+ {
+ /* Reduce key to the algorithm's hash size. Use the area pointed
+ * to by state for the temporary state. */
+
+ TMP_DECL(digest, uint8_t, NETTLE_MAX_HASH_DIGEST_SIZE);
+ TMP_ALLOC(digest, hash->digest_size);
+
+ hash->block_init(state, bctx);
+ hash->block_update(state, bctx, key_length, key);
+ hash->block_digest(state, bctx, hash->digest_size, digest);
+
+ key = digest;
+ key_length = hash->digest_size;
+ }
+
+ assert(key_length <= hash->block_size);
+
+ memset(pad, OPAD, hash->block_size);
+ memxor(pad, key, key_length);
+
+ hash->block_update(outer, bctx, hash->block_size, pad);
+
+ memset(pad, IPAD, hash->block_size);
+ memxor(pad, key, key_length);
+
+ hash->block_update(inner, bctx, hash->block_size, pad);
+
+ memcpy(state, inner, hash->state_size);
+}
+
+void
+hmac_block_digest(const void *outer, const void *inner, void *state,
+ struct block_ctx *bctx,
+ const struct nettle_bctx_hash *hash,
+ size_t length, uint8_t *dst)
+{
+ TMP_DECL(digest, uint8_t, NETTLE_MAX_HASH_DIGEST_SIZE);
+ TMP_ALLOC(digest, hash->digest_size);
+
+ hash->block_digest(state, bctx, hash->digest_size, digest);
+
+ memcpy(state, outer, hash->state_size);
+
+ hash->block_update(state, bctx, hash->digest_size, digest);
+ hash->block_digest(state, bctx, length, dst);
+
+ memcpy(state, inner, hash->state_size);
+}
diff --git a/hmac.h b/hmac.h
index 40a8e77aab6d..84ff4a56d93b 100644
--- a/hmac.h
+++ b/hmac.h
@@ -49,6 +49,8 @@ extern "C" {
#define hmac_set_key nettle_hmac_set_key
#define hmac_update nettle_hmac_update
#define hmac_digest nettle_hmac_digest
+#define hmac_block_set_key nettle_hmac_block_set_key
+#define hmac_block_digest nettle_hmac_block_digest
#define hmac_md5_set_key nettle_hmac_md5_set_key
#define hmac_md5_update nettle_hmac_md5_update
#define hmac_md5_digest nettle_hmac_md5_digest
@@ -86,6 +88,18 @@ hmac_digest(const void *outer, const void *inner, void
*state,
const struct nettle_hash *hash,
size_t length, uint8_t *digest);
+void
+hmac_block_set_key(void *outer, void *inner, void *state,
+ struct block_ctx *bctx,
+ const struct nettle_bctx_hash *hash,
+ size_t key_length, const uint8_t *key);
+
+void
+hmac_block_digest(const void *outer, const void *inner, void *state,
+ struct block_ctx *bctx,
+ const struct nettle_bctx_hash *hash,
+ size_t length, uint8_t *digest);
+
#define HMAC_CTX(type) \
{ type outer; type inner; type state; }
@@ -98,6 +112,19 @@ hmac_digest(const void *outer, const void *inner, void
*state,
hmac_digest( &(ctx)->outer, &(ctx)->inner, &(ctx)->state, \
(hash), (length), (digest) )
+#define HMAC_BLOCK_CTX(type, block_size) \
+{ type outer; type inner; type state; BLOCK_CTX(block_size); }
+
+#define HMAC_BLOCK_SET_KEY(ctx, hash, length, key) \
+ hmac_block_set_key( &(ctx)->outer, &(ctx)->inner, &(ctx)->state, \
+ (struct block_ctx *)&(ctx)->block, \
+ (hash), (length), (key) )
+
+#define HMAC_BLOCK_DIGEST(ctx, hash, length, digest) \
+ hmac_block_digest( &(ctx)->outer, &(ctx)->inner, &(ctx)->state, \
+ (struct block_ctx *)&(ctx)->block, \
+ (hash), (length), (digest) )
+
/* HMAC using specific hash functions */
/* hmac-md5 */
--
2.20.1
_______________________________________________
nettle-bugs mailing list
[email protected]
http://lists.lysator.liu.se/mailman/listinfo/nettle-bugs