aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEvgeny Grin (Karlson2k) <k2k@narod.ru>2022-09-12 13:26:45 +0300
committerEvgeny Grin (Karlson2k) <k2k@narod.ru>2022-09-25 18:39:41 +0300
commit85a90925974b0c69e0ef77b555bcc6a8f051dc65 (patch)
tree16b56a6c94d4c60043d61b716bbd7bb7dbc832cc
parent403f3b8e6ad06ff556029e23d8c4c7d519e8c29c (diff)
downloadlibmicrohttpd-85a90925974b0c69e0ef77b555bcc6a8f051dc65.tar.gz
libmicrohttpd-85a90925974b0c69e0ef77b555bcc6a8f051dc65.zip
sha256: backported minor optimisations from SHA-512/256
-rw-r--r--src/microhttpd/sha256.c38
-rw-r--r--src/microhttpd/sha256.h13
2 files changed, 29 insertions, 22 deletions
diff --git a/src/microhttpd/sha256.c b/src/microhttpd/sha256.c
index f62b4ba1..2203441e 100644
--- a/src/microhttpd/sha256.c
+++ b/src/microhttpd/sha256.c
@@ -1,6 +1,6 @@
1/* 1/*
2 This file is part of libmicrohttpd 2 This file is part of libmicrohttpd
3 Copyright (C) 2019-2021 Karlson2k (Evgeny Grin) 3 Copyright (C) 2019-2022 Evgeny Grin (Karlson2k)
4 4
5 libmicrohttpd is free software; you can redistribute it and/or 5 libmicrohttpd is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public 6 modify it under the terms of the GNU Lesser General Public
@@ -66,7 +66,7 @@ MHD_SHA256_init (struct Sha256Ctx *ctx)
66 */ 66 */
67static void 67static void
68sha256_transform (uint32_t H[_SHA256_DIGEST_LENGTH], 68sha256_transform (uint32_t H[_SHA256_DIGEST_LENGTH],
69 const uint8_t data[SHA256_BLOCK_SIZE]) 69 const void *data)
70{ 70{
71 /* Working variables, 71 /* Working variables,
72 see FIPS PUB 180-4 paragraph 6.2. */ 72 see FIPS PUB 180-4 paragraph 6.2. */
@@ -127,7 +127,7 @@ sha256_transform (uint32_t H[_SHA256_DIGEST_LENGTH],
127 /* The W[] buffer itself will be used as the source of the data, 127 /* The W[] buffer itself will be used as the source of the data,
128 * but data will be reloaded in correct bytes order during 128 * but data will be reloaded in correct bytes order during
129 * the next steps */ 129 * the next steps */
130 data = (uint8_t *) W; 130 data = (const void *) W;
131 } 131 }
132#endif /* _MHD_GET_32BIT_BE_UNALIGNED */ 132#endif /* _MHD_GET_32BIT_BE_UNALIGNED */
133 133
@@ -188,8 +188,8 @@ sha256_transform (uint32_t H[_SHA256_DIGEST_LENGTH],
188 + (w)[((t) - 7) & 0xf] + sig0 ((w)[((t) - 15) & 0xf]) ) 188 + (w)[((t) - 7) & 0xf] + sig0 ((w)[((t) - 15) & 0xf]) )
189 189
190 /* During last 48 steps, before making any calculations on each step, 190 /* During last 48 steps, before making any calculations on each step,
191 W element is generated from W elements of cyclic buffer and generated value 191 current W element is generated from other W elements of the cyclic buffer
192 stored back in cyclic buffer. */ 192 and the generated value is stored back in the cyclic buffer. */
193 /* Note: instead of using K constants as array, all K values are specified 193 /* Note: instead of using K constants as array, all K values are specified
194 individually for each step, see FIPS PUB 180-4 paragraph 4.2.2 for K values. */ 194 individually for each step, see FIPS PUB 180-4 paragraph 4.2.2 for K values. */
195 SHA2STEP32 (a, b, c, d, e, f, g, h, UINT32_C (0xe49b69c1), W[16 & 0xf] = \ 195 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,
332 if (length >= bytes_left) 332 if (length >= bytes_left)
333 { /* Combine new data with data in the buffer and 333 { /* Combine new data with data in the buffer and
334 process full block. */ 334 process full block. */
335 memcpy (ctx->buffer + bytes_have, 335 memcpy (((uint8_t *) ctx->buffer) + bytes_have,
336 data, 336 data,
337 bytes_left); 337 bytes_left);
338 data += bytes_left; 338 data += bytes_left;
@@ -353,7 +353,7 @@ MHD_SHA256_update (struct Sha256Ctx *ctx,
353 if (0 != length) 353 if (0 != length)
354 { /* Copy incomplete block of new data (if any) 354 { /* Copy incomplete block of new data (if any)
355 to the buffer. */ 355 to the buffer. */
356 memcpy (ctx->buffer + bytes_have, data, length); 356 memcpy (((uint8_t *) ctx->buffer) + bytes_have, data, length);
357 } 357 }
358} 358}
359 359
@@ -382,19 +382,24 @@ MHD_SHA256_finish (struct Sha256Ctx *ctx,
382 equal (count % SHA256_BLOCK_SIZE) for this block size. */ 382 equal (count % SHA256_BLOCK_SIZE) for this block size. */
383 bytes_have = (unsigned) (ctx->count & (SHA256_BLOCK_SIZE - 1)); 383 bytes_have = (unsigned) (ctx->count & (SHA256_BLOCK_SIZE - 1));
384 384
385 /* Input data must be padded with bit "1" and with length of data in bits. 385 /* Input data must be padded with a single bit "1", then with zeros and
386 the finally the length of data in bits must be added as the final bytes
387 of the last block.
386 See FIPS PUB 180-4 paragraph 5.1.1. */ 388 See FIPS PUB 180-4 paragraph 5.1.1. */
389
387 /* Data is always processed in form of bytes (not by individual bits), 390 /* Data is always processed in form of bytes (not by individual bits),
388 therefore position of first padding bit in byte is always predefined (0x80). */ 391 therefore position of first padding bit in byte is always
392 predefined (0x80). */
389 /* Buffer always have space at least for one byte (as full buffers are 393 /* Buffer always have space at least for one byte (as full buffers are
390 processed immediately). */ 394 processed immediately). */
391 ctx->buffer[bytes_have++] = 0x80; 395 ((uint8_t *) ctx->buffer)[bytes_have++] = 0x80;
392 396
393 if (SHA256_BLOCK_SIZE - bytes_have < SHA256_SIZE_OF_LEN_ADD) 397 if (SHA256_BLOCK_SIZE - bytes_have < SHA256_SIZE_OF_LEN_ADD)
394 { /* No space in current block to put total length of message. 398 { /* No space in current block to put total length of message.
395 Pad current block with zeros and process it. */ 399 Pad current block with zeros and process it. */
396 if (bytes_have < SHA256_BLOCK_SIZE) 400 if (bytes_have < SHA256_BLOCK_SIZE)
397 memset (ctx->buffer + bytes_have, 0, SHA256_BLOCK_SIZE - bytes_have); 401 memset (((uint8_t *) ctx->buffer) + bytes_have, 0,
402 SHA256_BLOCK_SIZE - bytes_have);
398 /* Process full block. */ 403 /* Process full block. */
399 sha256_transform (ctx->H, ctx->buffer); 404 sha256_transform (ctx->H, ctx->buffer);
400 /* Start new block. */ 405 /* Start new block. */
@@ -402,12 +407,10 @@ MHD_SHA256_finish (struct Sha256Ctx *ctx,
402 } 407 }
403 408
404 /* Pad the rest of the buffer with zeros. */ 409 /* Pad the rest of the buffer with zeros. */
405 memset (ctx->buffer + bytes_have, 0, 410 memset (((uint8_t *) ctx->buffer) + bytes_have, 0,
406 SHA256_BLOCK_SIZE - SHA256_SIZE_OF_LEN_ADD - bytes_have); 411 SHA256_BLOCK_SIZE - SHA256_SIZE_OF_LEN_ADD - bytes_have);
407 /* Put number of bits in processed message as big-endian value. */ 412 /* Put the number of bits in processed message as big-endian value. */
408 _MHD_PUT_64BIT_BE_SAFE (ctx->buffer + SHA256_BLOCK_SIZE 413 _MHD_PUT_64BIT_BE_SAFE (ctx->buffer + SHA256_BLOCK_SIZE_WORDS - 2, num_bits);
409 - SHA256_SIZE_OF_LEN_ADD,
410 num_bits);
411 /* Process full final block. */ 414 /* Process full final block. */
412 sha256_transform (ctx->H, ctx->buffer); 415 sha256_transform (ctx->H, ctx->buffer);
413 416
@@ -428,9 +431,8 @@ MHD_SHA256_finish (struct Sha256Ctx *ctx,
428 memcpy (digest, alig_dgst, SHA256_DIGEST_SIZE); 431 memcpy (digest, alig_dgst, SHA256_DIGEST_SIZE);
429 } 432 }
430 else 433 else
431#else /* _MHD_PUT_32BIT_BE_UNALIGNED */ 434#endif /* ! _MHD_PUT_32BIT_BE_UNALIGNED */
432 if (1) 435 if (1)
433#endif /* _MHD_PUT_32BIT_BE_UNALIGNED */
434 { 436 {
435 /* Use cast to (void*) here to mute compiler alignment warnings. 437 /* Use cast to (void*) here to mute compiler alignment warnings.
436 * Compilers are not smart enough to see that alignment has been checked. */ 438 * Compilers are not smart enough to see that alignment has been checked. */
diff --git a/src/microhttpd/sha256.h b/src/microhttpd/sha256.h
index 8feb52fe..192f906a 100644
--- a/src/microhttpd/sha256.h
+++ b/src/microhttpd/sha256.h
@@ -1,6 +1,6 @@
1/* 1/*
2 This file is part of libmicrohttpd 2 This file is part of libmicrohttpd
3 Copyright (C) 2019-2021 Karlson2k (Evgeny Grin) 3 Copyright (C) 2019-2022 Evgeny Grin (Karlson2k)
4 4
5 This library is free software; you can redistribute it and/or 5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public 6 modify it under the terms of the GNU Lesser General Public
@@ -69,12 +69,17 @@
69 */ 69 */
70#define SHA256_BLOCK_SIZE (SHA256_BLOCK_SIZE_BITS / 8) 70#define SHA256_BLOCK_SIZE (SHA256_BLOCK_SIZE_BITS / 8)
71 71
72/**
73 * Size of single processing block in bytes
74 */
75#define SHA256_BLOCK_SIZE_WORDS (SHA256_BLOCK_SIZE_BITS / SHA256_WORD_SIZE_BITS)
76
72 77
73struct Sha256Ctx 78struct Sha256Ctx
74{ 79{
75 uint32_t H[_SHA256_DIGEST_LENGTH]; /**< Intermediate hash value / digest at end of calculation */ 80 uint32_t H[_SHA256_DIGEST_LENGTH]; /**< Intermediate hash value / digest at end of calculation */
76 uint8_t buffer[SHA256_BLOCK_SIZE]; /**< SHA256 input data buffer */ 81 uint32_t buffer[SHA256_BLOCK_SIZE_WORDS]; /**< SHA256 input data buffer */
77 uint64_t count; /**< number of bytes, mod 2^64 */ 82 uint64_t count; /**< number of bytes, mod 2^64 */
78}; 83};
79 84
80/** 85/**