Signed-off-by: Dmitry Eremin-Solenikov <dbarysh...@gmail.com>
---
 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
nettle-bugs@lists.lysator.liu.se
http://lists.lysator.liu.se/mailman/listinfo/nettle-bugs

Reply via email to