aboutsummaryrefslogtreecommitdiff
path: root/src/microhttpd/sha512_256.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/microhttpd/sha512_256.c')
-rw-r--r--src/microhttpd/sha512_256.c40
1 files changed, 25 insertions, 15 deletions
diff --git a/src/microhttpd/sha512_256.c b/src/microhttpd/sha512_256.c
index 54389c6b..a42a9b8e 100644
--- a/src/microhttpd/sha512_256.c
+++ b/src/microhttpd/sha512_256.c
@@ -1,6 +1,6 @@
1/* 1/*
2 This file is part of GNU libmicrohttpd 2 This file is part of GNU libmicrohttpd
3 Copyright (C) 2022 Karlson2k (Evgeny Grin) 3 Copyright (C) 2022 Evgeny Grin (Karlson2k)
4 4
5 GNU libmicrohttpd is free software; you can redistribute it and/or 5 GNU 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
@@ -60,9 +60,9 @@ MHD_SHA512_256_init (struct Sha512_256Ctx *ctx)
60 60
61/** 61/**
62 * Base of SHA-512/256 transformation. 62 * Base of SHA-512/256 transformation.
63 * Gets full 64 bytes block of data and updates hash values; 63 * Gets full 128 bytes block of data and updates hash values;
64 * @param H hash values 64 * @param H hash values
65 * @param data the data buffer with SHA512_256_BLOCK_SIZE bytes block 65 * @param data the data buffer with #SHA512_256_BLOCK_SIZE bytes block
66 */ 66 */
67static void 67static void
68sha512_256_transform (uint64_t H[SHA512_256_HASH_SIZE_WORDS], 68sha512_256_transform (uint64_t H[SHA512_256_HASH_SIZE_WORDS],
@@ -91,7 +91,7 @@ sha512_256_transform (uint64_t H[SHA512_256_HASH_SIZE_WORDS],
91 /* The W[] buffer itself will be used as the source of the data, 91 /* The W[] buffer itself will be used as the source of the data,
92 * but the data will be reloaded in correct bytes order on 92 * but the data will be reloaded in correct bytes order on
93 * the next steps */ 93 * the next steps */
94 data = (uint8_t *) W; 94 data = (const void *) W;
95 } 95 }
96#endif /* _MHD_GET_64BIT_BE_ALLOW_UNALIGNED */ 96#endif /* _MHD_GET_64BIT_BE_ALLOW_UNALIGNED */
97 97
@@ -118,12 +118,6 @@ sha512_256_transform (uint64_t H[SHA512_256_HASH_SIZE_WORDS],
118 /* One step of SHA-512/256 computation, 118 /* One step of SHA-512/256 computation,
119 see FIPS PUB 180-4 clause 6.4.2 step 3. 119 see FIPS PUB 180-4 clause 6.4.2 step 3.
120 * Note: this macro updates working variables in-place, without rotation. 120 * Note: this macro updates working variables in-place, without rotation.
121 * Note: instead of reassigning all working variables on each step,
122 variables are rotated for each step:
123 SHA2STEP64(a, b, c, d, e, f, g, h, K[0], data[0]);
124 SHA2STEP64(h, a, b, c, d, e, f, g, K[1], data[1]);
125 so current 'vD' will be used as 'vE' on next step,
126 current 'vH' will be used as 'vA' on next step.
127 * Note: the first (vH += SIG1(vE) + Ch(vE,vF,vG) + kt + wt) equals T1 in 121 * Note: the first (vH += SIG1(vE) + Ch(vE,vF,vG) + kt + wt) equals T1 in
128 FIPS PUB 180-4 clause 6.4.2 step 3. 122 FIPS PUB 180-4 clause 6.4.2 step 3.
129 the second (vH += SIG0(vA) + Maj(vE,vF,vC) equals T1 + T2 in 123 the second (vH += SIG0(vA) + Maj(vE,vF,vC) equals T1 + T2 in
@@ -442,8 +436,10 @@ MHD_SHA512_256_update (struct Sha512_256Ctx *ctx,
442 436
443 mhd_assert ((data != NULL) || (length == 0)); 437 mhd_assert ((data != NULL) || (length == 0));
444 438
439#ifndef MHD_FAVOR_SMALL_CODE
445 if (0 == length) 440 if (0 == length)
446 return; /* Do nothing */ 441 return; /* Shortcut, do nothing */
442#endif /* ! MHD_FAVOR_SMALL_CODE */
447 443
448 /* Note: (count & (SHA512_256_BLOCK_SIZE-1)) 444 /* Note: (count & (SHA512_256_BLOCK_SIZE-1))
449 equals (count % SHA512_256_BLOCK_SIZE) for this block size. */ 445 equals (count % SHA512_256_BLOCK_SIZE) for this block size. */
@@ -521,9 +517,11 @@ MHD_SHA512_256_finish (struct Sha512_256Ctx *ctx,
521 equals (count % SHA512_256_BLOCK_SIZE) for this block size. */ 517 equals (count % SHA512_256_BLOCK_SIZE) for this block size. */
522 bytes_have = (unsigned int) (ctx->count & (SHA512_256_BLOCK_SIZE - 1)); 518 bytes_have = (unsigned int) (ctx->count & (SHA512_256_BLOCK_SIZE - 1));
523 519
524 /* Input data must be padded with bit "1" and then the length of data in bits 520 /* Input data must be padded with a single bit "1", then with zeros and
525 must be added as the final bytes of the last block. 521 the finally the length of data in bits must be added as the final bytes
522 of the last block.
526 See FIPS PUB 180-4 clause 5.1.2. */ 523 See FIPS PUB 180-4 clause 5.1.2. */
524
527 /* Data is always processed in form of bytes (not by individual bits), 525 /* Data is always processed in form of bytes (not by individual bits),
528 therefore position of the first padding bit in byte is always 526 therefore position of the first padding bit in byte is always
529 predefined (0x80). */ 527 predefined (0x80). */
@@ -560,8 +558,16 @@ MHD_SHA512_256_finish (struct Sha512_256Ctx *ctx,
560 /* Put in BE mode the leftmost part of the hash as the final digest. 558 /* Put in BE mode the leftmost part of the hash as the final digest.
561 See FIPS PUB 180-4 clause 6.7. */ 559 See FIPS PUB 180-4 clause 6.7. */
562#ifndef _MHD_PUT_64BIT_BE_UNALIGNED 560#ifndef _MHD_PUT_64BIT_BE_UNALIGNED
563 if (0 != ((uintptr_t) digest) % _MHD_UINT64_ALIGN) 561 if (1
564 { /* The destination is unaligned */ 562#ifndef MHD_FAVOR_SMALL_CODE
563 && (0 != ((uintptr_t) digest) % _MHD_UINT64_ALIGN)
564#endif /* MHD_FAVOR_SMALL_CODE */
565 )
566 {
567 /* If storing of the final result requires aligned address and
568 the destination address is not aligned or compact code is used,
569 store the final digest in aligned temporary buffer first, then
570 copy it to the destination. */
565 uint64_t alig_dgst[SHA512_256_DIGEST_SIZE_WORDS]; 571 uint64_t alig_dgst[SHA512_256_DIGEST_SIZE_WORDS];
566 _MHD_PUT_64BIT_BE (alig_dgst + 0, ctx->H[0]); 572 _MHD_PUT_64BIT_BE (alig_dgst + 0, ctx->H[0]);
567 _MHD_PUT_64BIT_BE (alig_dgst + 1, ctx->H[1]); 573 _MHD_PUT_64BIT_BE (alig_dgst + 1, ctx->H[1]);
@@ -570,8 +576,11 @@ MHD_SHA512_256_finish (struct Sha512_256Ctx *ctx,
570 /* Copy result to the unaligned destination address */ 576 /* Copy result to the unaligned destination address */
571 memcpy (digest, alig_dgst, SHA512_256_DIGEST_SIZE); 577 memcpy (digest, alig_dgst, SHA512_256_DIGEST_SIZE);
572 } 578 }
579#ifndef MHD_FAVOR_SMALL_CODE
573 else /* Combined with the next 'if' */ 580 else /* Combined with the next 'if' */
581#endif /* MHD_FAVOR_SMALL_CODE */
574#endif /* ! _MHD_PUT_64BIT_BE_UNALIGNED */ 582#endif /* ! _MHD_PUT_64BIT_BE_UNALIGNED */
583#if ! defined(MHD_FAVOR_SMALL_CODE) || defined(_MHD_PUT_64BIT_BE_UNALIGNED)
575 if (1) 584 if (1)
576 { 585 {
577 /* Use cast to (void*) here to mute compiler alignment warnings. 586 /* Use cast to (void*) here to mute compiler alignment warnings.
@@ -585,6 +594,7 @@ MHD_SHA512_256_finish (struct Sha512_256Ctx *ctx,
585 _MHD_PUT_64BIT_BE ((void *) (digest + 3 * SHA512_256_BYTES_IN_WORD), \ 594 _MHD_PUT_64BIT_BE ((void *) (digest + 3 * SHA512_256_BYTES_IN_WORD), \
586 ctx->H[3]); 595 ctx->H[3]);
587 } 596 }
597#endif /* ! MHD_FAVOR_SMALL_CODE || _MHD_PUT_64BIT_BE_UNALIGNED */
588 598
589 /* Erase potentially sensitive data. */ 599 /* Erase potentially sensitive data. */
590 memset (ctx, 0, sizeof(struct Sha512_256Ctx)); 600 memset (ctx, 0, sizeof(struct Sha512_256Ctx));