From: Niels Möller Date: Mon, 21 Oct 2024 19:18:05 +0000 (+0200) Subject: Extract some utility functions for hmac key setup. X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=c94ed799d18fcc2274f9957b64201f5181e3ea53;p=thirdparty%2Fnettle.git Extract some utility functions for hmac key setup. --- diff --git a/Makefile.in b/Makefile.in index cf7af2ea..1be97b0c 100644 --- a/Makefile.in +++ b/Makefile.in @@ -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 index 00000000..c9f73b8a --- /dev/null +++ b/hmac-internal.c @@ -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 +#include + +#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 index 00000000..d0552c03 --- /dev/null +++ b/hmac-internal.h @@ -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 */ diff --git a/hmac-sha256.c b/hmac-sha256.c index 047dc8f5..c1cf0879 100644 --- a/hmac-sha256.c +++ b/hmac-sha256.c @@ -38,36 +38,42 @@ #include #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); } diff --git a/sha2-internal.h b/sha2-internal.h index 93080bee..58e99b22 100644 --- a/sha2-internal.h +++ b/sha2-internal.h @@ -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. */ diff --git a/sha256.c b/sha256.c index a2a5d423..d2572947 100644 --- 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;