]> git.ipfire.org Git - thirdparty/nettle.git/commitdiff
Refactor HMAC, reducing context sizes.
authorNiels Möller <nisse@lysator.liu.se>
Sun, 22 Jun 2025 19:44:13 +0000 (21:44 +0200)
committerNiels Möller <nisse@lysator.liu.se>
Sun, 22 Jun 2025 20:08:15 +0000 (22:08 +0200)
15 files changed:
ChangeLog
Makefile.in
hmac-gosthash94.c
hmac-internal.c [new file with mode: 0644]
hmac-internal.h [new file with mode: 0644]
hmac-md5.c
hmac-ripemd160.c
hmac-sha1.c
hmac-sha224.c
hmac-sha256.c
hmac-sha384.c
hmac-sha512.c
hmac-sm3.c
hmac-streebog.c
hmac.h

index 331e1a3298a0ff6f4d39f28fd72e6040c8b93d3d..22a55040310b5e2fc8df552ae49d0d4813fe1227 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,20 @@
+2025-06-22  Niels Möller  <nisse@lysator.liu.se>
+
+       Refactor HMAC. Reduces the size of HMAC contexts, sha256 reduced
+       from 336 bytes to 192, sha512 from 648 to 376, and sha1 from 312
+       to 168.
+       * hmac.h (_NETTLE_HMAC_CTX): New macro. The outer and inner
+       members no longer include any block buffers. Change all the
+       hmac_*_ctx structs to use the new definition.
+       * hmac-internal.h (_NETTLE_HMAC_DIGEST, _NETTLE_HMAC_DIGEST_U):
+       New file, new macros. Update all hmac_*_digest functions to use
+       one of these macros.
+       * hmac-internal.c (_nettle_hmac_set_key): New file, new function,
+       using the new style of context struct. Update all hmac_*_set_key
+       functions.
+       * Makefile.in (nettle_SOURCES): Add hmac-internal.c.
+       (DISTFILES): Add hmac-internal.h.
+
 2025-06-22  Niels Möller  <nisse@lysator.liu.se>
 
        * testsuite/testutils.c (test_mac): Print name of mac algorithm on
index cf7af2ea37b6f748c6fcf1d62be9b2def747866f..7d89bff1023ef0bfaebaf84568fc8414f1c402fa 100644 (file)
@@ -130,7 +130,7 @@ nettle_SOURCES = aes-decrypt-internal.c aes-decrypt-table.c \
                 cmac.c cmac64.c cmac-aes128.c cmac-aes256.c cmac-des3.c \
                 cmac-aes128-meta.c cmac-aes256-meta.c cmac-des3-meta.c \
                 gost28147.c gosthash94.c gosthash94-meta.c \
-                hmac.c hmac-gosthash94.c hmac-md5.c hmac-ripemd160.c \
+                hmac.c hmac-internal.c hmac-gosthash94.c hmac-md5.c hmac-ripemd160.c \
                 hmac-sha1.c hmac-sha224.c hmac-sha256.c hmac-sha384.c \
                 hmac-sha512.c hmac-streebog.c hmac-sm3.c \
                 hmac-md5-meta.c hmac-ripemd160-meta.c hmac-sha1-meta.c \
@@ -281,7 +281,7 @@ DISTFILES = $(SOURCES) $(HEADERS) getopt.h getopt_int.h \
        serpent-internal.h cast128_sboxes.h desinfo.h desCode.h \
        ripemd160-internal.h md-internal.h sha2-internal.h \
        memxor-internal.h nettle-internal.h non-nettle.h nettle-write.h \
-       ctr-internal.h chacha-internal.h sha3-internal.h \
+       ctr-internal.h chacha-internal.h hmac-internal.h sha3-internal.h \
        salsa20-internal.h umac-internal.h hogweed-internal.h \
        rsa-internal.h pkcs1-internal.h dsa-internal.h eddsa-internal.h \
        gmp-glue.h ecc-internal.h fat-setup.h oaep.h \
index ea72470c278c751814dc2a7e8e8c9087d1841d1b..3d4c3dc9129b7554df1eed0fa2348d00530ccbd4 100644 (file)
@@ -3,6 +3,7 @@
    HMAC-GOSTHASH94 message authentication code.
 
    Copyright (C) 2016 Dmitry Eremin-Solenikov
+   Copyright (C) 2025 Niels Möller
 
    This file is part of GNU Nettle.
 
 #endif
 
 #include "hmac.h"
+#include "hmac-internal.h"
 
 void
 hmac_gosthash94_set_key(struct hmac_gosthash94_ctx *ctx,
-                   size_t key_length, const uint8_t *key)
+                       size_t key_length, const uint8_t *key)
 {
-  HMAC_SET_KEY(ctx, &nettle_gosthash94, key_length, key);
+  _nettle_hmac_set_key (sizeof(ctx->outer), ctx->outer, ctx->inner, &ctx->state,
+                       ctx->state.block, &nettle_gosthash94, key_length, key);
 }
 
 void
@@ -55,14 +58,18 @@ void
 hmac_gosthash94_digest(struct hmac_gosthash94_ctx *ctx,
                       uint8_t *digest)
 {
-  HMAC_DIGEST(ctx, &nettle_gosthash94, digest);
+  /* Needs a call to gosthash94_update, since
+     GOSTHASH94_DIGEST_SIZE == GOSTHASH94_BLOCK_SIZE. */
+  _NETTLE_HMAC_DIGEST_U (ctx->outer, ctx->inner, &ctx->state, gosthash94_digest,
+                        gosthash94_update, digest);
 }
 
 void
 hmac_gosthash94cp_set_key(struct hmac_gosthash94cp_ctx *ctx,
                    size_t key_length, const uint8_t *key)
 {
-  HMAC_SET_KEY(ctx, &nettle_gosthash94cp, key_length, key);
+  _nettle_hmac_set_key (sizeof(ctx->outer), ctx->outer, ctx->inner, &ctx->state,
+                       ctx->state.block, &nettle_gosthash94cp, key_length, key);
 }
 
 void
@@ -71,9 +78,13 @@ hmac_gosthash94cp_update(struct hmac_gosthash94cp_ctx *ctx,
 {
   gosthash94cp_update(&ctx->state, length, data);
 }
+
 void
 hmac_gosthash94cp_digest(struct hmac_gosthash94cp_ctx *ctx,
                         uint8_t *digest)
 {
-  HMAC_DIGEST(ctx, &nettle_gosthash94cp, digest);
+  /* Needs a call to gosthash94cp_update, since
+     GOSTHASH94CP_DIGEST_SIZE == GOSTHASH94CP_BLOCK_SIZE. */
+  _NETTLE_HMAC_DIGEST_U (ctx->outer, ctx->inner, &ctx->state, gosthash94cp_digest,
+                        gosthash94cp_update, digest);
 }
diff --git a/hmac-internal.c b/hmac-internal.c
new file mode 100644 (file)
index 0000000..1a8dea5
--- /dev/null
@@ -0,0 +1,80 @@
+/* hmac-internal.c
+
+   Copyright (C) 2025 Niels Möller
+
+   This file is part of GNU Nettle.
+
+   GNU Nettle is free software: you can redistribute it and/or
+   modify it under the terms of either:
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at your
+       option) any later version.
+
+   or
+
+     * the GNU General Public License as published by the Free
+       Software Foundation; either version 2 of the License, or (at your
+       option) any later version.
+
+   or both in parallel, as here.
+
+   GNU Nettle is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   General Public License for more details.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see http://www.gnu.org/licenses/.
+*/
+
+#if HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <assert.h>
+#include <string.h>
+
+#include "hmac-internal.h"
+#include "memxor.h"
+
+static void
+memxor_byte (uint8_t *p, uint8_t b, size_t n)
+{
+  size_t i;
+  for (i = 0; i < n; i++)
+    p[i] ^= b;
+}
+
+void
+_nettle_hmac_set_key (size_t state_size, void *outer, void *inner,
+                     void *ctx, uint8_t *block,
+                     const struct nettle_hash *hash,
+                     size_t key_size, const uint8_t *key)
+{
+  hash->init (ctx);
+
+  if (key_size > hash->block_size)
+    {
+      hash->update (ctx, key_size, key);
+      hash->digest (ctx, block);
+      key_size = hash->digest_size;
+      memxor_byte (block, OPAD, key_size);
+      memset (block + key_size, OPAD, hash->block_size - key_size);
+    }
+  else
+    {
+      memset (block, OPAD, hash->block_size);
+      memxor (block, key, key_size);
+    }
+
+  hash->update (ctx, hash->block_size, block);
+  memcpy (outer, ctx, state_size);
+
+  memxor_byte (block, OPAD ^ IPAD, hash->block_size);
+
+  hash->init (ctx);
+  hash->update (ctx, hash->block_size, block);
+  memcpy (inner, ctx, state_size);
+}
diff --git a/hmac-internal.h b/hmac-internal.h
new file mode 100644 (file)
index 0000000..31c5812
--- /dev/null
@@ -0,0 +1,68 @@
+/* hmac-internal.h
+
+   Copyright (C) 2025 Niels Möller
+
+   This file is part of GNU Nettle.
+
+   GNU Nettle is free software: you can redistribute it and/or
+   modify it under the terms of either:
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at your
+       option) any later version.
+
+   or
+
+     * the GNU General Public License as published by the Free
+       Software Foundation; either version 2 of the License, or (at your
+       option) any later version.
+
+   or both in parallel, as here.
+
+   GNU Nettle is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   General Public License for more details.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see http://www.gnu.org/licenses/.
+*/
+
+#ifndef NETTLE_HMAC_INTERNAL_H_INCLUDED
+#define NETTLE_HMAC_INTERNAL_H_INCLUDED
+
+#include <string.h>
+
+#include "nettle-types.h"
+#include "nettle-meta.h"
+
+#define IPAD 0x36
+#define OPAD 0x5c
+
+void
+_nettle_hmac_set_key (size_t state_size, void *outer, void *inner,
+                     void *ctx, uint8_t *block,
+                     const struct nettle_hash *hash,
+                     size_t key_size, const uint8_t *key);
+
+/* Digest operation for the common case that digest_size < block_size. */
+#define _NETTLE_HMAC_DIGEST(outer, inner, ctx, digest, digest_size, out) do { \
+    digest((ctx), (ctx)->block);                                       \
+    memcpy ((ctx), (outer), sizeof (outer));                           \
+    (ctx)->index = (digest_size);                                      \
+    digest ((ctx), (out));                                             \
+    memcpy ((ctx), (inner), sizeof (inner));                           \
+  } while (0)
+
+/* Digest operation for the corner case that digest_size == block_size (e.g,
+   ghosthash and streebog512). */
+#define _NETTLE_HMAC_DIGEST_U(outer, inner, ctx, digest, update, out) do { \
+    digest((ctx), (ctx)->block);                                       \
+    memcpy ((ctx), (outer), sizeof (outer));                           \
+    update ((ctx), sizeof( (ctx)->block), (ctx)->block);               \
+    digest ((ctx), (out));                                             \
+    memcpy ((ctx), (inner), sizeof (inner));                           \
+  } while (0)
+
+#endif /* NETTLE_HMAC_INTERNAL_H_INCLUDED */
index afbdc5214c1162eae0dff7529c0535ac4fae3a8e..4b969624bb60b9811ab8453f671cf33109e5d7e5 100644 (file)
@@ -2,7 +2,7 @@
 
    HMAC-MD5 message authentication code.
 
-   Copyright (C) 2002 Niels Möller
+   Copyright (C) 2002, 2025 Niels Möller
 
    This file is part of GNU Nettle.
 
 #endif
 
 #include "hmac.h"
+#include "hmac-internal.h"
 
 void
 hmac_md5_set_key(struct hmac_md5_ctx *ctx,
                 size_t key_length, const uint8_t *key)
 {
-  HMAC_SET_KEY(ctx, &nettle_md5, key_length, key);
+  _nettle_hmac_set_key (sizeof(ctx->outer), ctx->outer, ctx->inner, &ctx->state,
+                       ctx->state.block, &nettle_md5, key_length, key);
 }
 
 void
@@ -55,5 +57,6 @@ void
 hmac_md5_digest(struct hmac_md5_ctx *ctx,
                uint8_t *digest)
 {
-  HMAC_DIGEST(ctx, &nettle_md5, digest);
+  _NETTLE_HMAC_DIGEST (ctx->outer, ctx->inner, &ctx->state, md5_digest,
+                      MD5_DIGEST_SIZE, digest);
 }
index 4776ae86dc62bdf69cca6ee27d6ace5f27620b49..9b194e596f36072b6e136418a6cbd70b26ec800c 100644 (file)
@@ -2,7 +2,7 @@
 
    HMAC-RIPEMD160 message authentication code.
 
-   Copyright (C) 2011 Niels Möller
+   Copyright (C) 2011, 2025 Niels Möller
 
    This file is part of GNU Nettle.
 
 #endif
 
 #include "hmac.h"
+#include "hmac-internal.h"
 
 void
 hmac_ripemd160_set_key(struct hmac_ripemd160_ctx *ctx,
                       size_t key_length, const uint8_t *key)
 {
-  HMAC_SET_KEY(ctx, &nettle_ripemd160, key_length, key);
+  _nettle_hmac_set_key (sizeof(ctx->outer), ctx->outer, ctx->inner, &ctx->state,
+                       ctx->state.block, &nettle_ripemd160, key_length, key);
 }
 
 void
@@ -55,5 +57,6 @@ void
 hmac_ripemd160_digest(struct hmac_ripemd160_ctx *ctx,
                      uint8_t *digest)
 {
-  HMAC_DIGEST(ctx, &nettle_ripemd160, digest);
+  _NETTLE_HMAC_DIGEST (ctx->outer, ctx->inner, &ctx->state, ripemd160_digest,
+                      RIPEMD160_DIGEST_SIZE, digest);
 }
index 108f9216ec618a943adcc1fcb148911f5db7f028..007251b5d4174229fec4e4eacf7d27218ecdcd51 100644 (file)
@@ -2,7 +2,7 @@
 
    HMAC-SHA1 message authentication code.
 
-   Copyright (C) 2002 Niels Möller
+   Copyright (C) 2002, 2025 Niels Möller
 
    This file is part of GNU Nettle.
 
 #endif
 
 #include "hmac.h"
+#include "hmac-internal.h"
 
 void
 hmac_sha1_set_key(struct hmac_sha1_ctx *ctx,
                  size_t key_length, const uint8_t *key)
 {
-  HMAC_SET_KEY(ctx, &nettle_sha1, key_length, key);
+  _nettle_hmac_set_key (sizeof(ctx->outer), ctx->outer, ctx->inner, &ctx->state,
+                       ctx->state.block, &nettle_sha1, key_length, key);
 }
 
 void
@@ -55,5 +57,6 @@ void
 hmac_sha1_digest(struct hmac_sha1_ctx *ctx,
                 uint8_t *digest)
 {
-  HMAC_DIGEST(ctx, &nettle_sha1, digest);
+  _NETTLE_HMAC_DIGEST (ctx->outer, ctx->inner, &ctx->state, sha1_digest,
+                      SHA1_DIGEST_SIZE, digest);
 }
index b1d6e594fbf6527382b3d80cf235315477251003..a2404b956d9d6f39d1b9742e7f4992a9cac9f465 100644 (file)
@@ -2,7 +2,7 @@
 
    HMAC-SHA224 message authentication code.
 
-   Copyright (C) 2003, 2010 Niels Möller
+   Copyright (C) 2003, 2010, 2025 Niels Möller
 
    This file is part of GNU Nettle.
 
 #endif
 
 #include "hmac.h"
+#include "hmac-internal.h"
 
 void
 hmac_sha224_set_key(struct hmac_sha224_ctx *ctx,
                    size_t key_length, const uint8_t *key)
 {
-  HMAC_SET_KEY(ctx, &nettle_sha224, key_length, key);
+  _nettle_hmac_set_key (sizeof(ctx->outer), ctx->outer, ctx->inner, &ctx->state,
+                       ctx->state.block, &nettle_sha224, key_length, key);
 }
 
 void
 hmac_sha224_digest(struct hmac_sha224_ctx *ctx,
                   uint8_t *digest)
 {
-  HMAC_DIGEST(ctx, &nettle_sha224, digest);
+  _NETTLE_HMAC_DIGEST (ctx->outer, ctx->inner, &ctx->state, sha224_digest,
+                      SHA224_DIGEST_SIZE, digest);
 }
index caa55f4d80bff09b2c796f80624310a354148326..f83a2669147dba1205014615ae5b7f832a3d6892 100644 (file)
@@ -2,7 +2,7 @@
 
    HMAC-SHA256 message authentication code.
 
-   Copyright (C) 2003 Niels Möller
+   Copyright (C) 2003, 2025 Niels Möller
 
    This file is part of GNU Nettle.
 
 #endif
 
 #include "hmac.h"
+#include "hmac-internal.h"
 
 void
 hmac_sha256_set_key(struct hmac_sha256_ctx *ctx,
                    size_t key_length, const uint8_t *key)
 {
-  HMAC_SET_KEY(ctx, &nettle_sha256, key_length, key);
+  _nettle_hmac_set_key (sizeof(ctx->outer), ctx->outer, ctx->inner, &ctx->state,
+                       ctx->state.block, &nettle_sha256, key_length, key);
 }
 
 void
@@ -55,5 +57,6 @@ void
 hmac_sha256_digest(struct hmac_sha256_ctx *ctx,
                   uint8_t *digest)
 {
-  HMAC_DIGEST(ctx, &nettle_sha256, digest);
+  _NETTLE_HMAC_DIGEST (ctx->outer, ctx->inner, &ctx->state, sha256_digest,
+                      SHA256_DIGEST_SIZE, digest);
 }
index 9fbfb19f2b605b3816a681e8aeeb4bac7556f6a7..7f0562f988e3387ffb794cb503ee0376dbbfa001 100644 (file)
@@ -2,7 +2,7 @@
 
    HMAC-SHA384 message authentication code.
 
-   Copyright (C) 2003, 2010 Niels Möller
+   Copyright (C) 2003, 2010, 2025 Niels Möller
 
    This file is part of GNU Nettle.
 
 #endif
 
 #include "hmac.h"
+#include "hmac-internal.h"
 
 void
 hmac_sha384_set_key(struct hmac_sha512_ctx *ctx,
                    size_t key_length, const uint8_t *key)
 {
-  HMAC_SET_KEY(ctx, &nettle_sha384, key_length, key);
+  _nettle_hmac_set_key (sizeof(ctx->outer), ctx->outer, ctx->inner, &ctx->state,
+                       ctx->state.block, &nettle_sha384, key_length, key);
 }
 
 void
 hmac_sha384_digest(struct hmac_sha512_ctx *ctx,
                   uint8_t *digest)
 {
-  HMAC_DIGEST(ctx, &nettle_sha384, digest);
+  _NETTLE_HMAC_DIGEST (ctx->outer, ctx->inner, &ctx->state, sha384_digest,
+                      SHA384_DIGEST_SIZE, digest);
 }
index e7a43e7d9ec1424068440366564d7335c8108614..039c8d0ec1a15df4833d10e93faa02e67eaf14a5 100644 (file)
@@ -2,7 +2,7 @@
 
    HMAC-SHA512 message authentication code.
 
-   Copyright (C) 2003, 2010 Niels Möller
+   Copyright (C) 2003, 2010, 2025 Niels Möller
 
    This file is part of GNU Nettle.
 
 #endif
 
 #include "hmac.h"
+#include "hmac-internal.h"
 
 void
 hmac_sha512_set_key(struct hmac_sha512_ctx *ctx,
                    size_t key_length, const uint8_t *key)
 {
-  HMAC_SET_KEY(ctx, &nettle_sha512, key_length, key);
+  _nettle_hmac_set_key (sizeof(ctx->outer), ctx->outer, ctx->inner, &ctx->state,
+                       ctx->state.block, &nettle_sha512, key_length, key);
 }
 
 void
@@ -55,5 +57,6 @@ void
 hmac_sha512_digest(struct hmac_sha512_ctx *ctx,
                   uint8_t *digest)
 {
-  HMAC_DIGEST(ctx, &nettle_sha512, digest);
+  _NETTLE_HMAC_DIGEST (ctx->outer, ctx->inner, &ctx->state, sha512_digest,
+                      SHA512_DIGEST_SIZE, digest);
 }
index 67a21dde1b3df34258e88b6318fda514dcf30368..72e7428446e58435f80198104b130d6783e459df 100644 (file)
@@ -3,6 +3,7 @@
    HMAC-SM3 message authentication code.
 
    Copyright (C) 2021 Tianjia Zhang <tianjia.zhang@linux.alibaba.com>
+   Copyright (C) 2025 Niels Möller
 
    This file is part of GNU Nettle.
 
 #endif
 
 #include "hmac.h"
+#include "hmac-internal.h"
 
 void
 hmac_sm3_set_key(struct hmac_sm3_ctx *ctx,
                 size_t key_length, const uint8_t *key)
 {
-  HMAC_SET_KEY(ctx, &nettle_sm3, key_length, key);
+  _nettle_hmac_set_key (sizeof(ctx->outer), ctx->outer, ctx->inner, &ctx->state,
+                       ctx->state.block, &nettle_sm3, key_length, key);
 }
 
 void
@@ -55,5 +58,6 @@ void
 hmac_sm3_digest(struct hmac_sm3_ctx *ctx,
                uint8_t *digest)
 {
-  HMAC_DIGEST(ctx, &nettle_sm3, digest);
+  _NETTLE_HMAC_DIGEST (ctx->outer, ctx->inner, &ctx->state, sm3_digest,
+                      SM3_DIGEST_SIZE, digest);
 }
index ab5da30890a65b78943a201d07cc7744497233ab..b0b788f352a0e4f7487eacb19ad967d73ec558a4 100644 (file)
@@ -3,6 +3,7 @@
    HMAC-Streebog message authentication code.
 
    Copyright (C) 2016 Dmitry Eremin-Solenikov
+   Copyright (C) 2025 Niels Möller
 
    This file is part of GNU Nettle.
 
 #endif
 
 #include "hmac.h"
+#include "hmac-internal.h"
 
 void
 hmac_streebog512_set_key(struct hmac_streebog512_ctx *ctx,
                         size_t key_length, const uint8_t *key)
 {
-  HMAC_SET_KEY(ctx, &nettle_streebog512, key_length, key);
+  _nettle_hmac_set_key (sizeof(ctx->outer), ctx->outer, ctx->inner, &ctx->state,
+                       ctx->state.block, &nettle_streebog512, key_length, key);
 }
 
 void
@@ -55,19 +58,24 @@ void
 hmac_streebog512_digest(struct hmac_streebog512_ctx *ctx,
                        uint8_t *digest)
 {
-  HMAC_DIGEST(ctx, &nettle_streebog512, digest);
+  /* Needs a call to streebog512_update, since STREEBOG512_DIGEST_SIZE
+     == STREEBOG512_BLOCK_SIZE. */
+  _NETTLE_HMAC_DIGEST_U (ctx->outer, ctx->inner, &ctx->state, streebog512_digest,
+                        streebog512_update, digest);
 }
 
 void
 hmac_streebog256_set_key(struct hmac_streebog256_ctx *ctx,
                         size_t key_length, const uint8_t *key)
 {
-  HMAC_SET_KEY(ctx, &nettle_streebog256, key_length, key);
+  _nettle_hmac_set_key (sizeof(ctx->outer), ctx->outer, ctx->inner, &ctx->state,
+                       ctx->state.block, &nettle_streebog256, key_length, key);
 }
 
 void
 hmac_streebog256_digest(struct hmac_streebog256_ctx *ctx,
                        uint8_t *digest)
 {
-  HMAC_DIGEST(ctx, &nettle_streebog256, digest);
+  _NETTLE_HMAC_DIGEST (ctx->outer, ctx->inner, &ctx->state, streebog256_digest,
+                      STREEBOG256_DIGEST_SIZE, digest);
 }
diff --git a/hmac.h b/hmac.h
index 7e41b5b4f54fe593d32cb6ac1d605471cdc80120..08c02468021b5ede828efb82baaf5866e7037a73 100644 (file)
--- a/hmac.h
+++ b/hmac.h
@@ -2,7 +2,7 @@
 
    HMAC message authentication code (RFC-2104).
 
-   Copyright (C) 2001, 2002 Niels Möller
+   Copyright (C) 2001, 2002, 2025 Niels Möller
 
    This file is part of GNU Nettle.
 
@@ -34,6 +34,8 @@
 #ifndef NETTLE_HMAC_H_INCLUDED
 #define NETTLE_HMAC_H_INCLUDED
 
+#include <stdalign.h>
+
 #include "nettle-meta.h"
 
 #include "gosthash94.h"
@@ -86,6 +88,7 @@ extern "C" {
 #define hmac_sm3_update nettle_hmac_sm3_update
 #define hmac_sm3_digest nettle_hmac_sm3_digest
 
+/* Old "generic" hmac support. */
 void
 hmac_set_key(void *outer, void *inner, void *state,
             const struct nettle_hash *hash,
@@ -115,10 +118,14 @@ hmac_digest(const void *outer, const void *inner, void *state,
   hmac_digest( &(ctx)->outer, &(ctx)->inner, &(ctx)->state,    \
                (hash), (digest) )
 
-/* HMAC using specific hash functions */
+#define _NETTLE_HMAC_CTX(type) {                       \
+    alignas(type) char outer[offsetof (type, index)];  \
+    alignas(type) char inner[offsetof (type, index)];  \
+    type state;                                                \
+  }
 
 /* hmac-md5 */
-struct hmac_md5_ctx HMAC_CTX(struct md5_ctx);
+struct hmac_md5_ctx _NETTLE_HMAC_CTX (struct md5_ctx);
 
 void
 hmac_md5_set_key(struct hmac_md5_ctx *ctx,
@@ -134,7 +141,7 @@ hmac_md5_digest(struct hmac_md5_ctx *ctx,
 
 
 /* hmac-ripemd160 */
-struct hmac_ripemd160_ctx HMAC_CTX(struct ripemd160_ctx);
+struct hmac_ripemd160_ctx _NETTLE_HMAC_CTX (struct ripemd160_ctx);
 
 void
 hmac_ripemd160_set_key(struct hmac_ripemd160_ctx *ctx,
@@ -150,7 +157,7 @@ hmac_ripemd160_digest(struct hmac_ripemd160_ctx *ctx,
 
 
 /* hmac-sha1 */
-struct hmac_sha1_ctx HMAC_CTX(struct sha1_ctx);
+struct hmac_sha1_ctx _NETTLE_HMAC_CTX (struct sha1_ctx);
 
 void
 hmac_sha1_set_key(struct hmac_sha1_ctx *ctx,
@@ -165,7 +172,7 @@ hmac_sha1_digest(struct hmac_sha1_ctx *ctx,
                 uint8_t *digest);
 
 /* hmac-sha256 */
-struct hmac_sha256_ctx HMAC_CTX(struct sha256_ctx);
+struct hmac_sha256_ctx _NETTLE_HMAC_CTX (struct sha256_ctx);
 
 void
 hmac_sha256_set_key(struct hmac_sha256_ctx *ctx,
@@ -193,7 +200,7 @@ hmac_sha224_digest(struct hmac_sha224_ctx *ctx,
                   uint8_t *digest);
 
 /* hmac-sha512 */
-struct hmac_sha512_ctx HMAC_CTX(struct sha512_ctx);
+struct hmac_sha512_ctx _NETTLE_HMAC_CTX (struct sha512_ctx);
 
 void
 hmac_sha512_set_key(struct hmac_sha512_ctx *ctx,
@@ -221,7 +228,7 @@ hmac_sha384_digest(struct hmac_sha512_ctx *ctx,
                   uint8_t *digest);
 
 /* hmac-gosthash94 */
-struct hmac_gosthash94_ctx HMAC_CTX(struct gosthash94_ctx);
+struct hmac_gosthash94_ctx _NETTLE_HMAC_CTX (struct gosthash94_ctx);
 
 void
 hmac_gosthash94_set_key(struct hmac_gosthash94_ctx *ctx,
@@ -235,7 +242,7 @@ hmac_gosthash94_update(struct hmac_gosthash94_ctx *ctx,
 hmac_gosthash94_digest(struct hmac_gosthash94_ctx *ctx,
                       uint8_t *digest);
 
-struct hmac_gosthash94cp_ctx HMAC_CTX(struct gosthash94cp_ctx);
+#define hmac_gosthash94cp_ctx hmac_gosthash94_ctx
 
 void
 hmac_gosthash94cp_set_key(struct hmac_gosthash94cp_ctx *ctx,
@@ -251,7 +258,7 @@ hmac_gosthash94cp_digest(struct hmac_gosthash94cp_ctx *ctx,
 
 
 /* hmac-streebog */
-struct hmac_streebog512_ctx HMAC_CTX(struct streebog512_ctx);
+struct hmac_streebog512_ctx _NETTLE_HMAC_CTX (struct streebog512_ctx);
 
 void
 hmac_streebog512_set_key(struct hmac_streebog512_ctx *ctx,
@@ -278,7 +285,7 @@ hmac_streebog256_digest(struct hmac_streebog256_ctx *ctx,
                        uint8_t *digest);
 
 /* hmac-sm3 */
-struct hmac_sm3_ctx HMAC_CTX(struct sm3_ctx);
+struct hmac_sm3_ctx _NETTLE_HMAC_CTX (struct sm3_ctx);
 
 void
 hmac_sm3_set_key(struct hmac_sm3_ctx *ctx,