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 \
--- /dev/null
+/* 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);
+}
--- /dev/null
+/* 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 */
#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
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);
}
#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. */
#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;
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;