libmicrohttpd

HTTP/1.x server C library (MHD 1.x, stable)
Log | Files | Refs | Submodules | README | LICENSE

commit 8d1a7ede98a1bb22132c34e115e58fcb49e0e610
parent 2f1e0dcc08ef99e9ba542d52c4c5b5378f51dc5a
Author: Evgeny Grin (Karlson2k) <k2k@narod.ru>
Date:   Fri, 19 Apr 2019 09:49:51 +0300

SHA256: reimplemented from scratch,
some ideas are borrowed from LGPLv2.1-licensed Libgcrypt

Diffstat:
Msrc/microhttpd/sha256.c | 696++++++++++++++++++++++++++++++++++++-------------------------------------------
Msrc/microhttpd/sha256.h | 99+++++++++++++++++++++++++++++++++++++++++++------------------------------------
2 files changed, 375 insertions(+), 420 deletions(-)

diff --git a/src/microhttpd/sha256.c b/src/microhttpd/sha256.c @@ -1,407 +1,353 @@ -/* sha256.c - - The sha256 hash function. - See http://csrc.nist.gov/publications/fips/fips180-2/fips180-2.pdf - - Copyright (C) 2001 Niels Möller - Copyright (C) 2018 Christian Grothoff (extraction of minimal subset - from GNU Nettle to work with GNU libmicrohttpd) - - 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/. +/* + This file is part of libmicrohttpd + Copyright (C) 2019 Karlson2k (Evgeny Grin) + Some ideas are based on Libgcrypt implementation. + Copyright (C) 2003, 2006, 2008, 2009 Free Software Foundation, Inc. + + libmicrohttpd is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. + If not, see <http://www.gnu.org/licenses/>. */ -/* Modelled after the sha1.c code by Peter Gutmann. */ +/** + * @file microhttpd/sha256.c + * @brief Calculation of SHA-256 digest as defined in FIPS PUB 180-4 (2015) + * @author Karlson2k (Evgeny Grin) + */ -#include <assert.h> -#include <stdlib.h> -#include <string.h> -#include <stdint.h> +/* Some tricks are based on Libgcrypt implementation. */ #include "sha256.h" - -/* Generated by the shadata program. */ -static const uint32_t -K[64] = -{ - 0x428a2f98UL, 0x71374491UL, 0xb5c0fbcfUL, 0xe9b5dba5UL, - 0x3956c25bUL, 0x59f111f1UL, 0x923f82a4UL, 0xab1c5ed5UL, - 0xd807aa98UL, 0x12835b01UL, 0x243185beUL, 0x550c7dc3UL, - 0x72be5d74UL, 0x80deb1feUL, 0x9bdc06a7UL, 0xc19bf174UL, - 0xe49b69c1UL, 0xefbe4786UL, 0x0fc19dc6UL, 0x240ca1ccUL, - 0x2de92c6fUL, 0x4a7484aaUL, 0x5cb0a9dcUL, 0x76f988daUL, - 0x983e5152UL, 0xa831c66dUL, 0xb00327c8UL, 0xbf597fc7UL, - 0xc6e00bf3UL, 0xd5a79147UL, 0x06ca6351UL, 0x14292967UL, - 0x27b70a85UL, 0x2e1b2138UL, 0x4d2c6dfcUL, 0x53380d13UL, - 0x650a7354UL, 0x766a0abbUL, 0x81c2c92eUL, 0x92722c85UL, - 0xa2bfe8a1UL, 0xa81a664bUL, 0xc24b8b70UL, 0xc76c51a3UL, - 0xd192e819UL, 0xd6990624UL, 0xf40e3585UL, 0x106aa070UL, - 0x19a4c116UL, 0x1e376c08UL, 0x2748774cUL, 0x34b0bcb5UL, - 0x391c0cb3UL, 0x4ed8aa4aUL, 0x5b9cca4fUL, 0x682e6ff3UL, - 0x748f82eeUL, 0x78a5636fUL, 0x84c87814UL, 0x8cc70208UL, - 0x90befffaUL, 0xa4506cebUL, 0xbef9a3f7UL, 0xc67178f2UL, -}; - - -/* A block, treated as a sequence of 32-bit words. */ -#define SHA256_DATA_LENGTH 16 - -/* The SHA256 functions. The Choice function is the same as the SHA1 - function f1, and the majority function is the same as the SHA1 f3 - function. They can be optimized to save one boolean operation each - - thanks to Rich Schroeppel, rcs@cs.arizona.edu for discovering - this */ - -/* #define Choice(x,y,z) ( ( (x) & (y) ) | ( ~(x) & (z) ) ) */ -#define Choice(x,y,z) ( (z) ^ ( (x) & ( (y) ^ (z) ) ) ) -/* #define Majority(x,y,z) ( ((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z)) ) */ -#define Majority(x,y,z) ( ((x) & (y)) ^ ((z) & ((x) ^ (y))) ) - -#define S0(x) (ROTL32(30,(x)) ^ ROTL32(19,(x)) ^ ROTL32(10,(x))) -#define S1(x) (ROTL32(26,(x)) ^ ROTL32(21,(x)) ^ ROTL32(7,(x))) - -#define s0(x) (ROTL32(25,(x)) ^ ROTL32(14,(x)) ^ ((x) >> 3)) -#define s1(x) (ROTL32(15,(x)) ^ ROTL32(13,(x)) ^ ((x) >> 10)) - -/* The initial expanding function. The hash function is defined over an - 64-word expanded input array W, where the first 16 are copies of the input - data, and the remaining 64 are defined by - - W[ t ] = s1(W[t-2]) + W[t-7] + s0(W[i-15]) + W[i-16] - - This implementation generates these values on the fly in a circular - buffer - thanks to Colin Plumb, colin@nyx10.cs.du.edu for this - optimization. -*/ - -#define EXPAND(W,i) \ -( W[(i) & 15 ] += (s1(W[((i)-2) & 15]) + W[((i)-7) & 15] + s0(W[((i)-15) & 15])) ) - -/* The prototype SHA sub-round. The fundamental sub-round is: - - T1 = h + S1(e) + Choice(e,f,g) + K[t] + W[t] - T2 = S0(a) + Majority(a,b,c) - a' = T1+T2 - b' = a - c' = b - d' = c - e' = d + T1 - f' = e - g' = f - h' = g - - but this is implemented by unrolling the loop 8 times and renaming - the variables - ( h, a, b, c, d, e, f, g ) = ( a, b, c, d, e, f, g, h ) each - iteration. */ - -/* It's crucial that DATA is only used once, as that argument will - * have side effects. */ -#define ROUND(a,b,c,d,e,f,g,h,k,data) do { \ - h += S1(e) + Choice(e,f,g) + k + data; \ - d += h; \ - h += S0(a) + Majority(a,b,c); \ - } while (0) - - -/* Reads a 32-bit integer, in network, big-endian, byte order */ -#define READ_UINT32(p) \ -( (((uint32_t) (p)[0]) << 24) \ - | (((uint32_t) (p)[1]) << 16) \ - | (((uint32_t) (p)[2]) << 8) \ - | ((uint32_t) (p)[3])) - -#define WRITE_UINT32(p, i) \ -do { \ - (p)[0] = ((i) >> 24) & 0xff; \ - (p)[1] = ((i) >> 16) & 0xff; \ - (p)[2] = ((i) >> 8) & 0xff; \ - (p)[3] = (i) & 0xff; \ -} while(0) - -#define WRITE_UINT64(p, i) \ -do { \ - (p)[0] = ((i) >> 56) & 0xff; \ - (p)[1] = ((i) >> 48) & 0xff; \ - (p)[2] = ((i) >> 40) & 0xff; \ - (p)[3] = ((i) >> 32) & 0xff; \ - (p)[4] = ((i) >> 24) & 0xff; \ - (p)[5] = ((i) >> 16) & 0xff; \ - (p)[6] = ((i) >> 8) & 0xff; \ - (p)[7] = (i) & 0xff; \ -} while(0) - -/* The masking of the right shift is needed to allow n == 0 (using - just 32 - n and 64 - n results in undefined behaviour). Most uses - of these macros use a constant and non-zero rotation count. */ -#define ROTL32(n,x) (((x)<<(n)) | ((x)>>((-(n)&31)))) - -static void -_nettle_sha256_compress(uint32_t *state, const uint8_t *input, const uint32_t *k) -{ - uint32_t data[SHA256_DATA_LENGTH]; - uint32_t A, B, C, D, E, F, G, H; /* Local vars */ - unsigned i; - uint32_t *d; - - for (i = 0; i < SHA256_DATA_LENGTH; i++, input+= 4) - { - data[i] = READ_UINT32(input); - } - - /* Set up first buffer and local data buffer */ - A = state[0]; - B = state[1]; - C = state[2]; - D = state[3]; - E = state[4]; - F = state[5]; - G = state[6]; - H = state[7]; - - /* Heavy mangling */ - /* First 16 subrounds that act on the original data */ - - for (i = 0, d = data; i<16; i+=8, k += 8, d+= 8) - { - ROUND(A, B, C, D, E, F, G, H, k[0], d[0]); - ROUND(H, A, B, C, D, E, F, G, k[1], d[1]); - ROUND(G, H, A, B, C, D, E, F, k[2], d[2]); - ROUND(F, G, H, A, B, C, D, E, k[3], d[3]); - ROUND(E, F, G, H, A, B, C, D, k[4], d[4]); - ROUND(D, E, F, G, H, A, B, C, k[5], d[5]); - ROUND(C, D, E, F, G, H, A, B, k[6], d[6]); - ROUND(B, C, D, E, F, G, H, A, k[7], d[7]); - } - - for (; i<64; i += 16, k+= 16) - { - ROUND(A, B, C, D, E, F, G, H, k[ 0], EXPAND(data, 0)); - ROUND(H, A, B, C, D, E, F, G, k[ 1], EXPAND(data, 1)); - ROUND(G, H, A, B, C, D, E, F, k[ 2], EXPAND(data, 2)); - ROUND(F, G, H, A, B, C, D, E, k[ 3], EXPAND(data, 3)); - ROUND(E, F, G, H, A, B, C, D, k[ 4], EXPAND(data, 4)); - ROUND(D, E, F, G, H, A, B, C, k[ 5], EXPAND(data, 5)); - ROUND(C, D, E, F, G, H, A, B, k[ 6], EXPAND(data, 6)); - ROUND(B, C, D, E, F, G, H, A, k[ 7], EXPAND(data, 7)); - ROUND(A, B, C, D, E, F, G, H, k[ 8], EXPAND(data, 8)); - ROUND(H, A, B, C, D, E, F, G, k[ 9], EXPAND(data, 9)); - ROUND(G, H, A, B, C, D, E, F, k[10], EXPAND(data, 10)); - ROUND(F, G, H, A, B, C, D, E, k[11], EXPAND(data, 11)); - ROUND(E, F, G, H, A, B, C, D, k[12], EXPAND(data, 12)); - ROUND(D, E, F, G, H, A, B, C, k[13], EXPAND(data, 13)); - ROUND(C, D, E, F, G, H, A, B, k[14], EXPAND(data, 14)); - ROUND(B, C, D, E, F, G, H, A, k[15], EXPAND(data, 15)); - } - - /* Update state */ - state[0] += A; - state[1] += B; - state[2] += C; - state[3] += D; - state[4] += E; - state[5] += F; - state[6] += G; - state[7] += H; -} - - -#define COMPRESS(ctx, data) (_nettle_sha256_compress((ctx)->state, (data), K)) - -/* Initialize the SHA values */ - +#include <string.h> +#ifdef HAVE_MEMORY_H +#include <memory.h> +#endif /* HAVE_MEMORY_H */ +#include "mhd_bithelpers.h" +#include "mhd_assert.h" + +/** + * Initialise structure for SHA256 calculation. + * + * @param ctx_ must be a `struct sha256_ctx *` + */ void sha256_init (void *ctx_) { - /* Initial values, also generated by the shadata program. */ - static const uint32_t H0[_SHA256_DIGEST_LENGTH] = - { - 0x6a09e667UL, 0xbb67ae85UL, 0x3c6ef372UL, 0xa54ff53aUL, - 0x510e527fUL, 0x9b05688cUL, 0x1f83d9abUL, 0x5be0cd19UL, - }; - struct sha256_ctx *ctx = ctx_; - - memcpy(ctx->state, H0, sizeof(H0)); - - /* Initialize bit count */ + struct sha256_ctx *const ctx = ctx_; + /* Initial hash values, see FIPS PUB 180-4 paragraph 5.3.3 */ + /* First thirty-two bits of the fractional parts of the square + * roots of the first eight prime numbers: 2, 3, 5, 7, 11, 13, + * 17, 19." */ + ctx->H[0] = 0x6a09e667UL; + ctx->H[1] = 0xbb67ae85UL; + ctx->H[2] = 0x3c6ef372UL; + ctx->H[3] = 0xa54ff53aUL; + ctx->H[4] = 0x510e527fUL; + ctx->H[5] = 0x9b05688cUL; + ctx->H[6] = 0x1f83d9abUL; + ctx->H[7] = 0x5be0cd19UL; + + /* Initialise number of bytes. */ ctx->count = 0; - - /* Initialize buffer */ - ctx->index = 0; } +/** + * Number of bytes in single SHA-256 word + * used to process data + */ +#define SHA256_BYTES_IN_WORD 4 + +/** + * Length of data block in words + */ +#define SHA256_BLOCK_LENGTH (SHA256_BLOCK_SIZE / SHA256_BYTES_IN_WORD) + +/** + * Base of SHA-256 transformation. + * Gets full 64 bytes block of data and updates hash values; + * @param H hash values + * @param data data, must be exactly 64 bytes long + */ +static void +sha256_transform (uint32_t H[_SHA256_DIGEST_LENGTH], + const uint8_t data[SHA256_BLOCK_SIZE]) +{ + /* Working variables, + see FIPS PUB 180-4 paragraph 6.2. */ + uint32_t a = H[0]; + uint32_t b = H[1]; + uint32_t c = H[2]; + uint32_t d = H[3]; + uint32_t e = H[4]; + uint32_t f = H[5]; + uint32_t g = H[6]; + uint32_t h = H[7]; + + /* Data buffer, used as cyclic buffer. + See FIPS PUB 180-4 paragraphs 5.2.1, 6.2. */ + uint32_t W[16]; + + /* 'Ch' and 'Maj' macro functions are defined with + widely-used optimization. + See FIPS PUB 180-4 formulae 4.2, 4.3. */ +#define Ch(x,y,z) ( (z) ^ ((x) & ((y) ^ (z))) ) +#define Maj(x,y,z) ( ((x) & (y)) ^ ((z) & ((x) ^ (y))) ) + /* Unoptimized (original) versions: */ +/* #define Ch(x,y,z) ( ( (x) & (y) ) | ( ~(x) & (z) ) ) */ +/* #define Maj(x,y,z) ( ((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z)) ) */ + + /* Four 'Sigma' macro functions. + See FIPS PUB 180-4 formulae 4.4, 4.5, 4.6, 4.7. */ +#define SIG0(x) ( _MHD_ROTR32((x),2) ^ _MHD_ROTR32((x),13) ^ _MHD_ROTR32((x),22) ) +#define SIG1(x) ( _MHD_ROTR32((x),6) ^ _MHD_ROTR32((x),11) ^ _MHD_ROTR32((x),25) ) +#define sig0(x) ( _MHD_ROTR32((x),7) ^ _MHD_ROTR32((x),18) ^ ((x) >> 3) ) +#define sig1(x) ( _MHD_ROTR32((x),17) ^ _MHD_ROTR32((x),19) ^ ((x) >> 10) ) + + /* Single step of SHA-256 computation, + see FIPS PUB 180-4 paragraph 6.2.2 step 3. + * Note: instead of reassigning all working variables on each step, + variables are rotated for each step: + SHA2STEP32(a, b, c, d, e, f, g, h, K[0], data[0]); + SHA2STEP32(h, a, b, c, d, e, f, g, K[1], data[1]); + so current 'vD' will be used as 'vE' on next step, + current 'vH' will be used as 'vA' on next step. + * Note: first (vH += SIG1(vE) + Ch(vE,vF,vG) + kt + wt) equals T1 in FIPS PUB 180-4 paragraph 6.2.2 step 3. + second (vH += SIG0(vA) + Maj(vE,vF,vC) equals T1 + T2 in FIPS PUB 180-4 paragraph 6.2.2 step 3. + * Note: 'wt' must be used exactly one time in this macro as it change other data as well + every time when used. */ +#define SHA2STEP32(vA,vB,vC,vD,vE,vF,vG,vH,kt,wt) do { \ + (vD) += ((vH) += SIG1((vE)) + Ch((vE),(vF),(vG)) + (kt) + (wt)); \ + (vH) += SIG0((vA)) + Maj((vA),(vB),(vC)); } while (0) + + /* Get value of W(t) from input data buffer, + See FIPS PUB 180-4 paragraph 6.2. + Input data must be read in big-endian bytes order, + see FIPS PUB 180-4 paragraph 3.1.2. */ +#define GET_W_FROM_DATA(buf,t) \ + _MHD_GET_32BIT_BE(((uint8_t*)(buf)) + (t) * SHA256_BYTES_IN_WORD) + + /* During first 16 steps, before making any calculations on each step, + the W element is read from input data buffer as big-endian value and + stored in array of W elements. */ + /* 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, 0x428a2f98UL, W[0] = GET_W_FROM_DATA(data,0)); + SHA2STEP32(h, a, b, c, d, e, f, g, 0x71374491UL, W[1] = GET_W_FROM_DATA(data,1)); + SHA2STEP32(g, h, a, b, c, d, e, f, 0xb5c0fbcfUL, W[2] = GET_W_FROM_DATA(data,2)); + SHA2STEP32(f, g, h, a, b, c, d, e, 0xe9b5dba5UL, W[3] = GET_W_FROM_DATA(data,3)); + SHA2STEP32(e, f, g, h, a, b, c, d, 0x3956c25bUL, W[4] = GET_W_FROM_DATA(data,4)); + SHA2STEP32(d, e, f, g, h, a, b, c, 0x59f111f1UL, W[5] = GET_W_FROM_DATA(data,5)); + SHA2STEP32(c, d, e, f, g, h, a, b, 0x923f82a4UL, W[6] = GET_W_FROM_DATA(data,6)); + SHA2STEP32(b, c, d, e, f, g, h, a, 0xab1c5ed5UL, W[7] = GET_W_FROM_DATA(data,7)); + SHA2STEP32(a, b, c, d, e, f, g, h, 0xd807aa98UL, W[8] = GET_W_FROM_DATA(data,8)); + SHA2STEP32(h, a, b, c, d, e, f, g, 0x12835b01UL, W[9] = GET_W_FROM_DATA(data,9)); + SHA2STEP32(g, h, a, b, c, d, e, f, 0x243185beUL, W[10] = GET_W_FROM_DATA(data,10)); + SHA2STEP32(f, g, h, a, b, c, d, e, 0x550c7dc3UL, W[11] = GET_W_FROM_DATA(data,11)); + SHA2STEP32(e, f, g, h, a, b, c, d, 0x72be5d74UL, W[12] = GET_W_FROM_DATA(data,12)); + SHA2STEP32(d, e, f, g, h, a, b, c, 0x80deb1feUL, W[13] = GET_W_FROM_DATA(data,13)); + SHA2STEP32(c, d, e, f, g, h, a, b, 0x9bdc06a7UL, W[14] = GET_W_FROM_DATA(data,14)); + SHA2STEP32(b, c, d, e, f, g, h, a, 0xc19bf174UL, W[15] = GET_W_FROM_DATA(data,15)); + + /* 'W' generation and assignment for 16 <= t <= 63. + See FIPS PUB 180-4 paragraph 6.2.2. + As only last 16 'W' are used in calculations, it is possible to + use 16 elements array of W as cyclic buffer. + * Note: ((t-16)&0xf) have same value as (t&0xf) */ +#define Wgen(w,t) ( (w)[(t-16)&0xf] + sig1((w)[((t)-2)&0xf]) + \ + (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. */ + /* 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, 0xe49b69c1UL, W[16&0xf] = Wgen(W,16)); + SHA2STEP32(h, a, b, c, d, e, f, g, 0xefbe4786UL, W[17&0xf] = Wgen(W,17)); + SHA2STEP32(g, h, a, b, c, d, e, f, 0x0fc19dc6UL, W[18&0xf] = Wgen(W,18)); + SHA2STEP32(f, g, h, a, b, c, d, e, 0x240ca1ccUL, W[19&0xf] = Wgen(W,19)); + SHA2STEP32(e, f, g, h, a, b, c, d, 0x2de92c6fUL, W[20&0xf] = Wgen(W,20)); + SHA2STEP32(d, e, f, g, h, a, b, c, 0x4a7484aaUL, W[21&0xf] = Wgen(W,21)); + SHA2STEP32(c, d, e, f, g, h, a, b, 0x5cb0a9dcUL, W[22&0xf] = Wgen(W,22)); + SHA2STEP32(b, c, d, e, f, g, h, a, 0x76f988daUL, W[23&0xf] = Wgen(W,23)); + SHA2STEP32(a, b, c, d, e, f, g, h, 0x983e5152UL, W[24&0xf] = Wgen(W,24)); + SHA2STEP32(h, a, b, c, d, e, f, g, 0xa831c66dUL, W[25&0xf] = Wgen(W,25)); + SHA2STEP32(g, h, a, b, c, d, e, f, 0xb00327c8UL, W[26&0xf] = Wgen(W,26)); + SHA2STEP32(f, g, h, a, b, c, d, e, 0xbf597fc7UL, W[27&0xf] = Wgen(W,27)); + SHA2STEP32(e, f, g, h, a, b, c, d, 0xc6e00bf3UL, W[28&0xf] = Wgen(W,28)); + SHA2STEP32(d, e, f, g, h, a, b, c, 0xd5a79147UL, W[29&0xf] = Wgen(W,29)); + SHA2STEP32(c, d, e, f, g, h, a, b, 0x06ca6351UL, W[30&0xf] = Wgen(W,30)); + SHA2STEP32(b, c, d, e, f, g, h, a, 0x14292967UL, W[31&0xf] = Wgen(W,31)); + SHA2STEP32(a, b, c, d, e, f, g, h, 0x27b70a85UL, W[32&0xf] = Wgen(W,32)); + SHA2STEP32(h, a, b, c, d, e, f, g, 0x2e1b2138UL, W[33&0xf] = Wgen(W,33)); + SHA2STEP32(g, h, a, b, c, d, e, f, 0x4d2c6dfcUL, W[34&0xf] = Wgen(W,34)); + SHA2STEP32(f, g, h, a, b, c, d, e, 0x53380d13UL, W[35&0xf] = Wgen(W,35)); + SHA2STEP32(e, f, g, h, a, b, c, d, 0x650a7354UL, W[36&0xf] = Wgen(W,36)); + SHA2STEP32(d, e, f, g, h, a, b, c, 0x766a0abbUL, W[37&0xf] = Wgen(W,37)); + SHA2STEP32(c, d, e, f, g, h, a, b, 0x81c2c92eUL, W[38&0xf] = Wgen(W,38)); + SHA2STEP32(b, c, d, e, f, g, h, a, 0x92722c85UL, W[39&0xf] = Wgen(W,39)); + SHA2STEP32(a, b, c, d, e, f, g, h, 0xa2bfe8a1UL, W[40&0xf] = Wgen(W,40)); + SHA2STEP32(h, a, b, c, d, e, f, g, 0xa81a664bUL, W[41&0xf] = Wgen(W,41)); + SHA2STEP32(g, h, a, b, c, d, e, f, 0xc24b8b70UL, W[42&0xf] = Wgen(W,42)); + SHA2STEP32(f, g, h, a, b, c, d, e, 0xc76c51a3UL, W[43&0xf] = Wgen(W,43)); + SHA2STEP32(e, f, g, h, a, b, c, d, 0xd192e819UL, W[44&0xf] = Wgen(W,44)); + SHA2STEP32(d, e, f, g, h, a, b, c, 0xd6990624UL, W[45&0xf] = Wgen(W,45)); + SHA2STEP32(c, d, e, f, g, h, a, b, 0xf40e3585UL, W[46&0xf] = Wgen(W,46)); + SHA2STEP32(b, c, d, e, f, g, h, a, 0x106aa070UL, W[47&0xf] = Wgen(W,47)); + SHA2STEP32(a, b, c, d, e, f, g, h, 0x19a4c116UL, W[48&0xf] = Wgen(W,48)); + SHA2STEP32(h, a, b, c, d, e, f, g, 0x1e376c08UL, W[49&0xf] = Wgen(W,49)); + SHA2STEP32(g, h, a, b, c, d, e, f, 0x2748774cUL, W[50&0xf] = Wgen(W,50)); + SHA2STEP32(f, g, h, a, b, c, d, e, 0x34b0bcb5UL, W[51&0xf] = Wgen(W,51)); + SHA2STEP32(e, f, g, h, a, b, c, d, 0x391c0cb3UL, W[52&0xf] = Wgen(W,52)); + SHA2STEP32(d, e, f, g, h, a, b, c, 0x4ed8aa4aUL, W[53&0xf] = Wgen(W,53)); + SHA2STEP32(c, d, e, f, g, h, a, b, 0x5b9cca4fUL, W[54&0xf] = Wgen(W,54)); + SHA2STEP32(b, c, d, e, f, g, h, a, 0x682e6ff3UL, W[55&0xf] = Wgen(W,55)); + SHA2STEP32(a, b, c, d, e, f, g, h, 0x748f82eeUL, W[56&0xf] = Wgen(W,56)); + SHA2STEP32(h, a, b, c, d, e, f, g, 0x78a5636fUL, W[57&0xf] = Wgen(W,57)); + SHA2STEP32(g, h, a, b, c, d, e, f, 0x84c87814UL, W[58&0xf] = Wgen(W,58)); + SHA2STEP32(f, g, h, a, b, c, d, e, 0x8cc70208UL, W[59&0xf] = Wgen(W,59)); + SHA2STEP32(e, f, g, h, a, b, c, d, 0x90befffaUL, W[60&0xf] = Wgen(W,60)); + SHA2STEP32(d, e, f, g, h, a, b, c, 0xa4506cebUL, W[61&0xf] = Wgen(W,61)); + SHA2STEP32(c, d, e, f, g, h, a, b, 0xbef9a3f7UL, W[62&0xf] = Wgen(W,62)); + SHA2STEP32(b, c, d, e, f, g, h, a, 0xc67178f2UL, W[63&0xf] = Wgen(W,63)); + + /* Compute intermediate hash. + See FIPS PUB 180-4 paragraph 4.2.2 step 4. */ + H[0] += a; + H[1] += b; + H[2] += c; + H[3] += d; + H[4] += e; + H[5] += f; + H[6] += g; + H[7] += h; +} -/* Takes the compression function f as argument. NOTE: also clobbers - length and data. */ -#define MD_UPDATE(ctx, length, data, f, incr) \ - do { \ - if ((ctx)->index) \ - { \ - /* Try to fill partial block */ \ - unsigned __md_left = sizeof((ctx)->block) - (ctx)->index; \ - if ((length) < __md_left) \ - { \ - memcpy((ctx)->block + (ctx)->index, (data), (length)); \ - (ctx)->index += (length); \ - goto __md_done; /* Finished */ \ - } \ - else \ - { \ - memcpy((ctx)->block + (ctx)->index, (data), __md_left); \ - \ - f((ctx), (ctx)->block); \ - (incr); \ - \ - (data) += __md_left; \ - (length) -= __md_left; \ - } \ - } \ - while ((length) >= sizeof((ctx)->block)) \ - { \ - f((ctx), (data)); \ - (incr); \ - \ - (data) += sizeof((ctx)->block); \ - (length) -= sizeof((ctx)->block); \ - } \ - memcpy ((ctx)->block, (data), (length)); \ - (ctx)->index = (length); \ - __md_done: \ - ; \ - } while (0) - -/* Pads the block to a block boundary with the bit pattern 1 0*, - leaving size octets for the length field at the end. If needed, - compresses the block and starts a new one. */ -#define MD_PAD(ctx, size, f) \ - do { \ - unsigned __md_i; \ - __md_i = (ctx)->index; \ - \ - /* Set the first char of padding to 0x80. This is safe since there \ - is always at least one byte free */ \ - \ - assert(__md_i < sizeof((ctx)->block)); \ - (ctx)->block[__md_i++] = 0x80; \ - \ - if (__md_i > (sizeof((ctx)->block) - (size))) \ - { /* No room for length in this block. Process it and \ - pad with another one */ \ - memset((ctx)->block + __md_i, 0, sizeof((ctx)->block) - __md_i); \ - \ - f((ctx), (ctx)->block); \ - __md_i = 0; \ - } \ - memset((ctx)->block + __md_i, 0, \ - sizeof((ctx)->block) - (size) - __md_i); \ - \ - } while (0) - - +/** + * Process portion of bytes. + * + * @param ctx_ must be a `struct sha256_ctx *` + * @param data bytes to add to hash + * @param length number of bytes in @a data + */ void sha256_update (void *ctx_, const uint8_t *data, size_t length) { - struct sha256_ctx *ctx = ctx_; - MD_UPDATE (ctx, length, data, COMPRESS, ctx->count++); -} - - - -void -_nettle_write_be32(size_t length, uint8_t *dst, - const uint32_t *src) -{ - size_t i; - size_t words; - unsigned leftover; + struct sha256_ctx *const ctx = ctx_; + unsigned bytes_have; /**< Number of bytes in buffer */ - words = length / 4; - leftover = length % 4; + mhd_assert((data != NULL) || (length == 0)); - for (i = 0; i < words; i++, dst += 4) - WRITE_UINT32(dst, src[i]); + /* Note: (count & (SHA256_BLOCK_SIZE-1)) + equal (count % SHA256_BLOCK_SIZE) for this block size. */ + bytes_have = (unsigned)(ctx->count & (SHA256_BLOCK_SIZE-1)); + ctx->count += length; - if (leftover) + if (bytes_have) { - uint32_t word; - unsigned j = leftover; - - word = src[i]; - - switch (leftover) - { - default: - abort(); - case 3: - dst[--j] = (word >> 8) & 0xff; - /* Fall through */ - case 2: - dst[--j] = (word >> 16) & 0xff; - /* Fall through */ - case 1: - dst[--j] = (word >> 24) & 0xff; - } + unsigned bytes_left = SHA256_BLOCK_SIZE - bytes_have; + if (length >= bytes_left) + { /* Combine new data with data in buffer and + process full block. */ + memcpy (ctx->buffer + bytes_have, + data, + bytes_left); + data += bytes_left; + length -= bytes_left; + sha256_transform (ctx->H, ctx->buffer); + bytes_have = 0; + } } -} - -static void -sha256_write_digest (struct sha256_ctx *ctx, - size_t length, - uint8_t *digest) -{ - uint64_t bit_count; - - assert(length <= SHA256_DIGEST_SIZE); - - MD_PAD(ctx, 8, COMPRESS); + while (length >= SHA256_BLOCK_SIZE) + { /* Process any full blocks of new data directly, + without copying to buffer. */ + sha256_transform (ctx->H, data); + data += SHA256_BLOCK_SIZE; + length -= SHA256_BLOCK_SIZE; + } - /* There are 512 = 2^9 bits in one block */ - bit_count = (ctx->count << 9) | (ctx->index << 3); + if (length != 0) + { /* Copy incomplete block of new data (if any) + to buffer. */ + memcpy (ctx->buffer + bytes_have, data, length); + } +} - /* This is slightly inefficient, as the numbers are converted to - big-endian format, and will be converted back by the compression - function. It's probably not worth the effort to fix this. */ - WRITE_UINT64(ctx->block + (SHA256_BLOCK_SIZE - 8), bit_count); - COMPRESS(ctx, ctx->block); - _nettle_write_be32(length, digest, ctx->state); -} +/** + * Size of "length" padding addition in bytes. + * See FIPS PUB 180-4 paragraph 5.1.1. + */ +#define SHA256_SIZE_OF_LEN_ADD (64 / 8) +/** + * Finalise SHA256 calculation, return digest. + * + * @param ctx_ must be a `struct sha256_ctx *` + * @param digest[out] set to the hash, must be #SHA256_DIGEST_SIZE bytes + */ void -sha256_digest (void *ctx_, - uint8_t *digest) +sha256_finish (void *ctx_, + uint8_t digest[SHA256_DIGEST_SIZE]) { - struct sha256_ctx *ctx = ctx_; + struct sha256_ctx *const ctx = ctx_; + uint64_t num_bits; /**< Number of processed bits */ + unsigned bytes_have; /**< Number of bytes in buffer */ + + num_bits = ctx->count << 3; + /* Note: (count & (SHA256_BLOCK_SIZE-1)) + 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. + 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). */ + /* Buffer always have space at least for one byte (as full buffers are + processed immediately). */ + 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. */ + while (bytes_have < SHA256_BLOCK_SIZE) ctx->buffer[bytes_have++] = 0; + /* Process full block. */ + sha256_transform (ctx->H, ctx->buffer); + /* Start new block. */ + bytes_have = 0; + } - sha256_write_digest (ctx, - SHA256_DIGEST_SIZE, - digest); - sha256_init (ctx); + /* Pad the rest of the buffer with zeros. */ + memset(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(ctx->buffer + SHA256_BLOCK_SIZE - SHA256_SIZE_OF_LEN_ADD, num_bits); + /* Process full final block. */ + sha256_transform (ctx->H, ctx->buffer); + + /* Put final hash/digest in BE mode */ + _MHD_PUT_32BIT_BE(digest + 0 * SHA256_BYTES_IN_WORD, ctx->H[0]); + _MHD_PUT_32BIT_BE(digest + 1 * SHA256_BYTES_IN_WORD, ctx->H[1]); + _MHD_PUT_32BIT_BE(digest + 2 * SHA256_BYTES_IN_WORD, ctx->H[2]); + _MHD_PUT_32BIT_BE(digest + 3 * SHA256_BYTES_IN_WORD, ctx->H[3]); + _MHD_PUT_32BIT_BE(digest + 4 * SHA256_BYTES_IN_WORD, ctx->H[4]); + _MHD_PUT_32BIT_BE(digest + 5 * SHA256_BYTES_IN_WORD, ctx->H[5]); + _MHD_PUT_32BIT_BE(digest + 6 * SHA256_BYTES_IN_WORD, ctx->H[6]); + _MHD_PUT_32BIT_BE(digest + 7 * SHA256_BYTES_IN_WORD, ctx->H[7]); + + /* Erase potentially sensitive data. */ + memset(ctx, 0, sizeof(struct sha256_ctx)); } diff --git a/src/microhttpd/sha256.h b/src/microhttpd/sha256.h @@ -1,58 +1,64 @@ -/* sha256.h - - The sha256 hash function. - - Copyright (C) 2001, 2012 Niels Möller - Copyright (C) 2018 Christian Grothoff (extraction of minimal subset - from GNU Nettle to work with GNU libmicrohttpd) - - 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. +/* + This file is part of libmicrohttpd + Copyright (C) 2019 Karlson2k (Evgeny Grin) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. + If not, see <http://www.gnu.org/licenses/>. +*/ - or +/** + * @file microhttpd/sha256.h + * @brief Calculation of SHA-256 digest + * @author Karlson2k (Evgeny Grin) + */ - * 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. +#ifndef MHD_SHA256_H +#define MHD_SHA256_H 1 - or both in parallel, as here. +#include "mhd_options.h" +#include <stdint.h> - 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. +/** + * Digest is kept internally as 8 32-bit words. + */ +#define _SHA256_DIGEST_LENGTH 8 - 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/. -*/ +/** + * Size of SHA-256 digest in bytes + */ +#define SHA256_DIGEST_SIZE (_SHA256_DIGEST_LENGTH * 4) -#ifndef NETTLE_SHA2_H_INCLUDED -#define NETTLE_SHA2_H_INCLUDED +/** + * Size of SHA-256 digest string in chars + */ +#define SHA256_DIGEST_STRING_SIZE ((SHA256_DIGEST_SIZE) * 2 + 1) -#define SHA256_DIGEST_SIZE 32 +/** + * Size of single processing block in bytes + */ #define SHA256_BLOCK_SIZE 64 -/* Digest is kept internally as 8 32-bit words. */ -#define _SHA256_DIGEST_LENGTH 8 struct sha256_ctx { - uint32_t state[_SHA256_DIGEST_LENGTH]; /* State variables */ - uint64_t count; /* 64-bit block count */ - uint8_t block[SHA256_BLOCK_SIZE]; /* SHA256 data buffer */ - unsigned int index; /* index into buffer */ + uint32_t H[_SHA256_DIGEST_LENGTH]; /**< Intermediate hash value / digest at end of calculation */ + uint64_t count; /**< number of bytes, mod 2^64 */ + uint8_t buffer[SHA256_BLOCK_SIZE]; /**< SHA256 input data buffer */ }; - /** - * Start SHA256 calculation. + * Initialise structure for SHA256 calculation. * * @param ctx_ must be a `struct sha256_ctx *` */ @@ -61,25 +67,28 @@ sha256_init (void *ctx_); /** - * Update hash calculation. + * Process portion of bytes. * * @param ctx_ must be a `struct sha256_ctx *` - * @param length number of bytes in @a data * @param data bytes to add to hash + * @param length number of bytes in @a data */ void sha256_update (void *ctx_, const uint8_t *data, size_t length); + /** - * Complete SHA256 calculation. + * Finalise SHA256 calculation, return digest. * * @param ctx_ must be a `struct sha256_ctx *` * @param digest[out] set to the hash, must be #SHA256_DIGEST_SIZE bytes */ void -sha256_digest (void *ctx_, +sha256_finish (void *ctx_, uint8_t digest[SHA256_DIGEST_SIZE]); -#endif /* NETTLE_SHA2_H_INCLUDED */ +#define sha256_digest sha256_finish + +#endif /* MHD_SHA256_H */