]> git.ipfire.org Git - thirdparty/nettle.git/commitdiff
Extract some utility functions for hmac key setup.
authorNiels Möller <nisse@lysator.liu.se>
Mon, 21 Oct 2024 19:18:05 +0000 (21:18 +0200)
committerNiels Möller <nisse@lysator.liu.se>
Sun, 22 Jun 2025 19:11:04 +0000 (21:11 +0200)
Makefile.in
hmac-internal.c [new file with mode: 0644]
hmac-internal.h [new file with mode: 0644]
hmac-sha256.c
sha2-internal.h
sha256.c

index cf7af2ea37b6f748c6fcf1d62be9b2def747866f..1be97b0cc6487ad3ebb4512167c7e6b1245189c8 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 \
diff --git a/hmac-internal.c b/hmac-internal.c
new file mode 100644 (file)
index 0000000..c9f73b8
--- /dev/null
@@ -0,0 +1,71 @@
+/* hmac-internal.c
+
+   Copyright (C) 2024 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_outer_block (size_t block_size, uint8_t *block, size_t key_size, const uint8_t *key)
+{
+  assert (key_size <= block_size);
+  memset (block, OPAD, block_size);
+  memxor (block, key, key_size);
+}
+
+void
+_nettle_hmac_outer_block_digest (size_t block_size, uint8_t *block, size_t key_size)
+{
+  assert (key_size <= block_size);
+
+  memxor_byte (block, OPAD, key_size);
+  memset (block + key_size, OPAD, block_size - key_size);
+}
+
+void
+_nettle_hmac_inner_block (size_t block_size, uint8_t *block)
+{
+  memxor_byte (block, OPAD ^ IPAD, block_size);
+}
diff --git a/hmac-internal.h b/hmac-internal.h
new file mode 100644 (file)
index 0000000..d0552c0
--- /dev/null
@@ -0,0 +1,49 @@
+/* hmac-internal.h
+
+   Copyright (C) 2024 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 "nettle-types.h"
+
+#define IPAD 0x36
+#define OPAD 0x5c
+
+/* Initialize BLOCK from KEY, with KEY_SIZE <= BLOCK_SIZE. If KEY ==
+   NULL, key is already written at the start of the block. */
+void _nettle_hmac_outer_block (size_t block_size, uint8_t *block, size_t key_size, const uint8_t *key);
+
+void
+_nettle_hmac_outer_block_digest (size_t block_size, uint8_t *block, size_t key_size);
+
+void _nettle_hmac_inner_block (size_t block_size, uint8_t *block);
+
+#endif /* NETTLE_HMAC_INTERNAL_H_INCLUDED */
index 047dc8f574af3683fec7e81497b479a3d2cef670..c1cf0879c069b090ecf575c92118d711ac55e64e 100644 (file)
 #include <string.h>
 
 #include "hmac.h"
+#include "hmac-internal.h"
 #include "memxor.h"
+#include "sha2-internal.h"
 
-#define IPAD 0x36
-#define OPAD 0x5c
+/* Initialize for processing a new message.*/
+static void 
+hmac_sha256_init (struct hmac_sha256_ctx *ctx)
+{
+  memcpy (ctx->state.state, ctx->inner, sizeof (ctx->state.state));
+  ctx->state.count = 1;
+  /* index should already be zero, from previous call to sha256_init or sha256_digest. */
+}
 
 void
 hmac_sha256_set_key(struct hmac_sha256_ctx *ctx,
                    size_t key_length, const uint8_t *key)
 {
-  uint8_t digest[SHA256_DIGEST_SIZE];
-
   sha256_init (&ctx->state);
   if (key_length > SHA256_BLOCK_SIZE)
     {
       sha256_update (&ctx->state, key_length, key);
-      sha256_digest (&ctx->state, digest);
-      key = digest;
-      key_length = SHA256_DIGEST_SIZE;
+      sha256_digest (&ctx->state, ctx->state.block);
+      _nettle_hmac_outer_block_digest (SHA256_BLOCK_SIZE, ctx->state.block, SHA256_DIGEST_SIZE);
     }
+  else
+    _nettle_hmac_outer_block (SHA256_BLOCK_SIZE, ctx->state.block,
+                             key_length, key);
 
-  memset (ctx->state.block, OPAD, SHA256_BLOCK_SIZE);
-  memxor (ctx->state.block, key, key_length);
-  sha256_update (&ctx->state, SHA256_BLOCK_SIZE, ctx->state.block);
-  memcpy (ctx->outer, ctx->state.state, sizeof(ctx->outer));
+  memcpy (ctx->outer, _nettle_sha256_iv, sizeof(ctx->outer));
+  sha256_compress (ctx->outer, ctx->state.block);
 
-  sha256_init (&ctx->state);
-  memset (ctx->state.block, IPAD, SHA256_BLOCK_SIZE);
-  memxor (ctx->state.block, key, key_length);
-  sha256_update (&ctx->state, SHA256_BLOCK_SIZE, ctx->state.block);
-  memcpy (ctx->inner, ctx->state.state, sizeof(ctx->outer));
+  _nettle_hmac_inner_block (SHA256_BLOCK_SIZE, ctx->state.block);
+  memcpy (ctx->inner, _nettle_sha256_iv, sizeof(ctx->inner));
+  sha256_compress (ctx->inner, ctx->state.block);
+
+  hmac_sha256_init (ctx);
 }
 
 void
@@ -81,14 +87,12 @@ void
 hmac_sha256_digest(struct hmac_sha256_ctx *ctx,
                   uint8_t *digest)
 {
-  uint8_t inner_digest[SHA256_DIGEST_SIZE];
-  sha256_digest (&ctx->state, inner_digest);
+  sha256_digest (&ctx->state, ctx->state.block);
 
   memcpy (ctx->state.state, ctx->outer, sizeof (ctx->state.state));
   ctx->state.count = 1;
-  sha256_update (&ctx->state, SHA256_DIGEST_SIZE, inner_digest);
+  ctx->state.index = SHA256_DIGEST_SIZE;
   sha256_digest (&ctx->state, digest);
 
-  memcpy (ctx->state.state, ctx->inner, sizeof (ctx->state.state));
-  ctx->state.count = 1;
+  hmac_sha256_init (ctx);
 }
index 93080bee67a633a3ae7edae02b001421173a34c5..58e99b227b26e6a30367f1f360bae35e24441f58 100644 (file)
@@ -36,6 +36,9 @@
 
 #include "nettle-types.h"
 
+extern const uint32_t _nettle_sha224_iv[_SHA256_DIGEST_LENGTH];
+extern const uint32_t _nettle_sha256_iv[_SHA256_DIGEST_LENGTH];
+
 /* Internal compression function. STATE points to 8 uint32_t words,
    DATA points to 64 bytes of input data, possibly unaligned, and K
    points to the table of constants. */
index a2a5d4236cbd1ba2cbe193fe72f3b90a0b833b36..d25729477688718cc4ff099693824c871aa98da3 100644 (file)
--- a/sha256.c
+++ b/sha256.c
@@ -79,19 +79,17 @@ sha256_compress(uint32_t *state, const uint8_t *input)
 
 #define COMPRESS(ctx, data) (sha256_compress((ctx)->state, (data)))
 
-/* Initialize the SHA values */
-
-void
-sha256_init(struct sha256_ctx *ctx)
-{
-  /* Initial values, also generated by the shadata program. */
-  static const uint32_t H0[_SHA256_DIGEST_LENGTH] =
+/* Initial values, also generated by the shadata program. */
+const uint32_t _nettle_sha256_iv[_SHA256_DIGEST_LENGTH] =
   {
     0x6a09e667UL, 0xbb67ae85UL, 0x3c6ef372UL, 0xa54ff53aUL, 
     0x510e527fUL, 0x9b05688cUL, 0x1f83d9abUL, 0x5be0cd19UL, 
   };
 
-  memcpy(ctx->state, H0, sizeof(H0));
+void
+sha256_init(struct sha256_ctx *ctx)
+{
+  memcpy(ctx->state, _nettle_sha256_iv, sizeof(ctx->state));
 
   /* Initialize bit count */
   ctx->count = 0;
@@ -156,19 +154,19 @@ sha256_digest(struct sha256_ctx *ctx,
   sha256_init(ctx);
 }
 
-/* sha224 variant. */
+/* SHA224 variant. */
 
-void
-sha224_init(struct sha256_ctx *ctx)
-{
-  /* Initial values. Low 32 bits of the initial values for sha384. */
-  static const uint32_t H0[_SHA256_DIGEST_LENGTH] =
+/* Initial values. Low 32 bits of the initial values for sha384. */
+const uint32_t _nettle_sha224_iv[_SHA256_DIGEST_LENGTH] =
   {
     0xc1059ed8, 0x367cd507, 0x3070dd17, 0xf70e5939,
     0xffc00b31, 0x68581511, 0x64f98fa7, 0xbefa4fa4,
   };
 
-  memcpy(ctx->state, H0, sizeof(H0));
+void
+sha224_init(struct sha256_ctx *ctx)
+{
+  memcpy(ctx->state, _nettle_sha224_iv, sizeof(ctx->state));
 
   /* Initialize bit count */
   ctx->count = 0;