commit 85a90925974b0c69e0ef77b555bcc6a8f051dc65
parent 403f3b8e6ad06ff556029e23d8c4c7d519e8c29c
Author: Evgeny Grin (Karlson2k) <k2k@narod.ru>
Date: Mon, 12 Sep 2022 13:26:45 +0300
sha256: backported minor optimisations from SHA-512/256
Diffstat:
2 files changed, 29 insertions(+), 22 deletions(-)
diff --git a/src/microhttpd/sha256.c b/src/microhttpd/sha256.c
@@ -1,6 +1,6 @@
/*
This file is part of libmicrohttpd
- Copyright (C) 2019-2021 Karlson2k (Evgeny Grin)
+ Copyright (C) 2019-2022 Evgeny Grin (Karlson2k)
libmicrohttpd is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
@@ -66,7 +66,7 @@ MHD_SHA256_init (struct Sha256Ctx *ctx)
*/
static void
sha256_transform (uint32_t H[_SHA256_DIGEST_LENGTH],
- const uint8_t data[SHA256_BLOCK_SIZE])
+ const void *data)
{
/* Working variables,
see FIPS PUB 180-4 paragraph 6.2. */
@@ -127,7 +127,7 @@ sha256_transform (uint32_t H[_SHA256_DIGEST_LENGTH],
/* The W[] buffer itself will be used as the source of the data,
* but data will be reloaded in correct bytes order during
* the next steps */
- data = (uint8_t *) W;
+ data = (const void *) W;
}
#endif /* _MHD_GET_32BIT_BE_UNALIGNED */
@@ -188,8 +188,8 @@ sha256_transform (uint32_t H[_SHA256_DIGEST_LENGTH],
+ (w)[((t) - 7) & 0xf] + sig0 ((w)[((t) - 15) & 0xf]) )
/* During last 48 steps, before making any calculations on each step,
- W element is generated from W elements of cyclic buffer and generated value
- stored back in cyclic buffer. */
+ current W element is generated from other W elements of the cyclic buffer
+ and the generated value is stored back in the cyclic buffer. */
/* Note: instead of using K constants as array, all K values are specified
individually for each step, see FIPS PUB 180-4 paragraph 4.2.2 for K values. */
SHA2STEP32 (a, b, c, d, e, f, g, h, UINT32_C (0xe49b69c1), W[16 & 0xf] = \
@@ -332,7 +332,7 @@ MHD_SHA256_update (struct Sha256Ctx *ctx,
if (length >= bytes_left)
{ /* Combine new data with data in the buffer and
process full block. */
- memcpy (ctx->buffer + bytes_have,
+ memcpy (((uint8_t *) ctx->buffer) + bytes_have,
data,
bytes_left);
data += bytes_left;
@@ -353,7 +353,7 @@ MHD_SHA256_update (struct Sha256Ctx *ctx,
if (0 != length)
{ /* Copy incomplete block of new data (if any)
to the buffer. */
- memcpy (ctx->buffer + bytes_have, data, length);
+ memcpy (((uint8_t *) ctx->buffer) + bytes_have, data, length);
}
}
@@ -382,19 +382,24 @@ MHD_SHA256_finish (struct Sha256Ctx *ctx,
equal (count % SHA256_BLOCK_SIZE) for this block size. */
bytes_have = (unsigned) (ctx->count & (SHA256_BLOCK_SIZE - 1));
- /* Input data must be padded with bit "1" and with length of data in bits.
+ /* Input data must be padded with a single bit "1", then with zeros and
+ the finally the length of data in bits must be added as the final bytes
+ of the last block.
See FIPS PUB 180-4 paragraph 5.1.1. */
+
/* Data is always processed in form of bytes (not by individual bits),
- therefore position of first padding bit in byte is always predefined (0x80). */
+ therefore position of first padding bit in byte is always
+ predefined (0x80). */
/* Buffer always have space at least for one byte (as full buffers are
processed immediately). */
- ctx->buffer[bytes_have++] = 0x80;
+ ((uint8_t *) ctx->buffer)[bytes_have++] = 0x80;
if (SHA256_BLOCK_SIZE - bytes_have < SHA256_SIZE_OF_LEN_ADD)
{ /* No space in current block to put total length of message.
Pad current block with zeros and process it. */
if (bytes_have < SHA256_BLOCK_SIZE)
- memset (ctx->buffer + bytes_have, 0, SHA256_BLOCK_SIZE - bytes_have);
+ memset (((uint8_t *) ctx->buffer) + bytes_have, 0,
+ SHA256_BLOCK_SIZE - bytes_have);
/* Process full block. */
sha256_transform (ctx->H, ctx->buffer);
/* Start new block. */
@@ -402,12 +407,10 @@ MHD_SHA256_finish (struct Sha256Ctx *ctx,
}
/* Pad the rest of the buffer with zeros. */
- memset (ctx->buffer + bytes_have, 0,
+ memset (((uint8_t *) ctx->buffer) + bytes_have, 0,
SHA256_BLOCK_SIZE - SHA256_SIZE_OF_LEN_ADD - bytes_have);
- /* Put number of bits in processed message as big-endian value. */
- _MHD_PUT_64BIT_BE_SAFE (ctx->buffer + SHA256_BLOCK_SIZE
- - SHA256_SIZE_OF_LEN_ADD,
- num_bits);
+ /* Put the number of bits in processed message as big-endian value. */
+ _MHD_PUT_64BIT_BE_SAFE (ctx->buffer + SHA256_BLOCK_SIZE_WORDS - 2, num_bits);
/* Process full final block. */
sha256_transform (ctx->H, ctx->buffer);
@@ -428,9 +431,8 @@ MHD_SHA256_finish (struct Sha256Ctx *ctx,
memcpy (digest, alig_dgst, SHA256_DIGEST_SIZE);
}
else
-#else /* _MHD_PUT_32BIT_BE_UNALIGNED */
+#endif /* ! _MHD_PUT_32BIT_BE_UNALIGNED */
if (1)
-#endif /* _MHD_PUT_32BIT_BE_UNALIGNED */
{
/* Use cast to (void*) here to mute compiler alignment warnings.
* Compilers are not smart enough to see that alignment has been checked. */
diff --git a/src/microhttpd/sha256.h b/src/microhttpd/sha256.h
@@ -1,6 +1,6 @@
/*
This file is part of libmicrohttpd
- Copyright (C) 2019-2021 Karlson2k (Evgeny Grin)
+ Copyright (C) 2019-2022 Evgeny Grin (Karlson2k)
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
@@ -69,12 +69,17 @@
*/
#define SHA256_BLOCK_SIZE (SHA256_BLOCK_SIZE_BITS / 8)
+/**
+ * Size of single processing block in bytes
+ */
+#define SHA256_BLOCK_SIZE_WORDS (SHA256_BLOCK_SIZE_BITS / SHA256_WORD_SIZE_BITS)
+
struct Sha256Ctx
{
- uint32_t H[_SHA256_DIGEST_LENGTH]; /**< Intermediate hash value / digest at end of calculation */
- uint8_t buffer[SHA256_BLOCK_SIZE]; /**< SHA256 input data buffer */
- uint64_t count; /**< number of bytes, mod 2^64 */
+ uint32_t H[_SHA256_DIGEST_LENGTH]; /**< Intermediate hash value / digest at end of calculation */
+ uint32_t buffer[SHA256_BLOCK_SIZE_WORDS]; /**< SHA256 input data buffer */
+ uint64_t count; /**< number of bytes, mod 2^64 */
};
/**