sha512_256.c (28863B)
1 /* 2 This file is part of GNU libmicrohttpd 3 Copyright (C) 2022-2023 Evgeny Grin (Karlson2k) 4 5 GNU libmicrohttpd is free software; you can redistribute it and/or 6 modify it under the terms of the GNU Lesser General Public 7 License as published by the Free Software Foundation; either 8 version 2.1 of the License, or (at your option) any later version. 9 10 This library is distributed in the hope that it will be useful, 11 but WITHOUT ANY WARRANTY; without even the implied warranty of 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 Lesser General Public License for more details. 14 15 You should have received a copy of the GNU Lesser General Public 16 License along with this library. 17 If not, see <http://www.gnu.org/licenses/>. 18 */ 19 20 /** 21 * @file microhttpd/sha512_256.c 22 * @brief Calculation of SHA-512/256 digest as defined in FIPS PUB 180-4 (2015) 23 * @author Karlson2k (Evgeny Grin) 24 */ 25 26 #include "sha512_256.h" 27 28 #include <string.h> 29 #ifdef HAVE_MEMORY_H 30 #include <memory.h> 31 #endif /* HAVE_MEMORY_H */ 32 #include "mhd_bithelpers.h" 33 #include "mhd_assert.h" 34 35 /** 36 * Initialise structure for SHA-512/256 calculation. 37 * 38 * @param ctx the calculation context 39 */ 40 void 41 MHD_SHA512_256_init (struct Sha512_256Ctx *ctx) 42 { 43 /* Initial hash values, see FIPS PUB 180-4 clause 5.3.6.2 */ 44 /* Values generated by "IV Generation Function" as described in 45 * clause 5.3.6 */ 46 ctx->H[0] = UINT64_C (0x22312194FC2BF72C); 47 ctx->H[1] = UINT64_C (0x9F555FA3C84C64C2); 48 ctx->H[2] = UINT64_C (0x2393B86B6F53B151); 49 ctx->H[3] = UINT64_C (0x963877195940EABD); 50 ctx->H[4] = UINT64_C (0x96283EE2A88EFFE3); 51 ctx->H[5] = UINT64_C (0xBE5E1E2553863992); 52 ctx->H[6] = UINT64_C (0x2B0199FC2C85B8AA); 53 ctx->H[7] = UINT64_C (0x0EB72DDC81C52CA2); 54 55 /* Initialise number of bytes and high part of number of bits. */ 56 ctx->count = 0; 57 ctx->count_bits_hi = 0; 58 } 59 60 61 MHD_DATA_TRUNCATION_RUNTIME_CHECK_DISABLE_ 62 63 /** 64 * Base of SHA-512/256 transformation. 65 * Gets full 128 bytes block of data and updates hash values; 66 * @param H hash values 67 * @param data the data buffer with #SHA512_256_BLOCK_SIZE bytes block 68 */ 69 static void 70 sha512_256_transform (uint64_t H[SHA512_256_HASH_SIZE_WORDS], 71 const void *data) 72 { 73 /* Working variables, 74 see FIPS PUB 180-4 clause 6.7, 6.4. */ 75 uint64_t a = H[0]; 76 uint64_t b = H[1]; 77 uint64_t c = H[2]; 78 uint64_t d = H[3]; 79 uint64_t e = H[4]; 80 uint64_t f = H[5]; 81 uint64_t g = H[6]; 82 uint64_t h = H[7]; 83 84 /* Data buffer, used as a cyclic buffer. 85 See FIPS PUB 180-4 clause 5.2.2, 6.7, 6.4. */ 86 uint64_t W[16]; 87 88 #ifndef _MHD_GET_64BIT_BE_ALLOW_UNALIGNED 89 if (0 != (((uintptr_t) data) % _MHD_UINT64_ALIGN)) 90 { /* The input data is unaligned */ 91 /* Copy the unaligned input data to the aligned buffer */ 92 memcpy (W, data, sizeof(W)); 93 /* The W[] buffer itself will be used as the source of the data, 94 * but the data will be reloaded in correct bytes order on 95 * the next steps */ 96 data = (const void *) W; 97 } 98 #endif /* _MHD_GET_64BIT_BE_ALLOW_UNALIGNED */ 99 100 /* 'Ch' and 'Maj' macro functions are defined with 101 widely-used optimisation. 102 See FIPS PUB 180-4 formulae 4.8, 4.9. */ 103 #define Ch(x,y,z) ( (z) ^ ((x) & ((y) ^ (z))) ) 104 #define Maj(x,y,z) ( ((x) & (y)) ^ ((z) & ((x) ^ (y))) ) 105 /* Unoptimized (original) versions: */ 106 /* #define Ch(x,y,z) ( ( (x) & (y) ) ^ ( ~(x) & (z) ) ) */ 107 /* #define Maj(x,y,z) ( ((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z)) ) */ 108 109 /* Four 'Sigma' macro functions. 110 See FIPS PUB 180-4 formulae 4.10, 4.11, 4.12, 4.13. */ 111 #define SIG0(x) \ 112 ( _MHD_ROTR64 ((x), 28) ^ _MHD_ROTR64 ((x), 34) ^ _MHD_ROTR64 ((x), 39) ) 113 #define SIG1(x) \ 114 ( _MHD_ROTR64 ((x), 14) ^ _MHD_ROTR64 ((x), 18) ^ _MHD_ROTR64 ((x), 41) ) 115 #define sig0(x) \ 116 ( _MHD_ROTR64 ((x), 1) ^ _MHD_ROTR64 ((x), 8) ^ ((x) >> 7) ) 117 #define sig1(x) \ 118 ( _MHD_ROTR64 ((x), 19) ^ _MHD_ROTR64 ((x), 61) ^ ((x) >> 6) ) 119 120 /* One step of SHA-512/256 computation, 121 see FIPS PUB 180-4 clause 6.4.2 step 3. 122 * Note: this macro updates working variables in-place, without rotation. 123 * Note: the first (vH += SIG1(vE) + Ch(vE,vF,vG) + kt + wt) equals T1 in 124 FIPS PUB 180-4 clause 6.4.2 step 3. 125 the second (vH += SIG0(vA) + Maj(vE,vF,vC) equals T1 + T2 in 126 FIPS PUB 180-4 clause 6.4.2 step 3. 127 * Note: 'wt' must be used exactly one time in this macro as it change other 128 data as well every time when used. */ 129 #define SHA2STEP64(vA,vB,vC,vD,vE,vF,vG,vH,kt,wt) do { \ 130 (vD) += ((vH) += SIG1 ((vE)) + Ch ((vE),(vF),(vG)) + (kt) + (wt)); \ 131 (vH) += SIG0 ((vA)) + Maj ((vA),(vB),(vC)); } while (0) 132 133 /* Get value of W(t) from input data buffer for 0 <= t <= 15, 134 See FIPS PUB 180-4 clause 6.2. 135 Input data must be read in big-endian bytes order, 136 see FIPS PUB 180-4 clause 3.1.2. */ 137 #define GET_W_FROM_DATA(buf,t) \ 138 _MHD_GET_64BIT_BE (((const uint64_t*) (buf)) + (t)) 139 140 /* 'W' generation and assignment for 16 <= t <= 79. 141 See FIPS PUB 180-4 clause 6.4.2. 142 As only last 16 'W' are used in calculations, it is possible to 143 use 16 elements array of W as a cyclic buffer. 144 * Note: ((t-16) & 15) have same value as (t & 15) */ 145 #define Wgen(w,t) ( (w)[(t - 16) & 15] + sig1 ((w)[((t) - 2) & 15]) \ 146 + (w)[((t) - 7) & 15] + sig0 ((w)[((t) - 15) & 15]) ) 147 148 #ifndef MHD_FAVOR_SMALL_CODE 149 150 /* Note: instead of using K constants as array, all K values are specified 151 individually for each step, see FIPS PUB 180-4 clause 4.2.3 for 152 K values. */ 153 /* Note: instead of reassigning all working variables on each step, 154 variables are rotated for each step: 155 SHA2STEP64(a, b, c, d, e, f, g, h, K[0], data[0]); 156 SHA2STEP64(h, a, b, c, d, e, f, g, K[1], data[1]); 157 so current 'vD' will be used as 'vE' on next step, 158 current 'vH' will be used as 'vA' on next step. */ 159 #if _MHD_BYTE_ORDER == _MHD_BIG_ENDIAN 160 if ((const void *) W == data) 161 { 162 /* The input data is already in the cyclic data buffer W[] in correct bytes 163 order. */ 164 SHA2STEP64 (a, b, c, d, e, f, g, h, UINT64_C (0x428a2f98d728ae22), W[0]); 165 SHA2STEP64 (h, a, b, c, d, e, f, g, UINT64_C (0x7137449123ef65cd), W[1]); 166 SHA2STEP64 (g, h, a, b, c, d, e, f, UINT64_C (0xb5c0fbcfec4d3b2f), W[2]); 167 SHA2STEP64 (f, g, h, a, b, c, d, e, UINT64_C (0xe9b5dba58189dbbc), W[3]); 168 SHA2STEP64 (e, f, g, h, a, b, c, d, UINT64_C (0x3956c25bf348b538), W[4]); 169 SHA2STEP64 (d, e, f, g, h, a, b, c, UINT64_C (0x59f111f1b605d019), W[5]); 170 SHA2STEP64 (c, d, e, f, g, h, a, b, UINT64_C (0x923f82a4af194f9b), W[6]); 171 SHA2STEP64 (b, c, d, e, f, g, h, a, UINT64_C (0xab1c5ed5da6d8118), W[7]); 172 SHA2STEP64 (a, b, c, d, e, f, g, h, UINT64_C (0xd807aa98a3030242), W[8]); 173 SHA2STEP64 (h, a, b, c, d, e, f, g, UINT64_C (0x12835b0145706fbe), W[9]); 174 SHA2STEP64 (g, h, a, b, c, d, e, f, UINT64_C (0x243185be4ee4b28c), W[10]); 175 SHA2STEP64 (f, g, h, a, b, c, d, e, UINT64_C (0x550c7dc3d5ffb4e2), W[11]); 176 SHA2STEP64 (e, f, g, h, a, b, c, d, UINT64_C (0x72be5d74f27b896f), W[12]); 177 SHA2STEP64 (d, e, f, g, h, a, b, c, UINT64_C (0x80deb1fe3b1696b1), W[13]); 178 SHA2STEP64 (c, d, e, f, g, h, a, b, UINT64_C (0x9bdc06a725c71235), W[14]); 179 SHA2STEP64 (b, c, d, e, f, g, h, a, UINT64_C (0xc19bf174cf692694), W[15]); 180 } 181 else /* Combined with the next 'if' */ 182 #endif /* _MHD_BYTE_ORDER == _MHD_BIG_ENDIAN */ 183 if (1) 184 { 185 /* During first 16 steps, before making any calculations on each step, 186 the W element is read from the input data buffer as big-endian value and 187 stored in the array of W elements. */ 188 SHA2STEP64 (a, b, c, d, e, f, g, h, UINT64_C (0x428a2f98d728ae22), \ 189 W[0] = GET_W_FROM_DATA (data, 0)); 190 SHA2STEP64 (h, a, b, c, d, e, f, g, UINT64_C (0x7137449123ef65cd), \ 191 W[1] = GET_W_FROM_DATA (data, 1)); 192 SHA2STEP64 (g, h, a, b, c, d, e, f, UINT64_C (0xb5c0fbcfec4d3b2f), \ 193 W[2] = GET_W_FROM_DATA (data, 2)); 194 SHA2STEP64 (f, g, h, a, b, c, d, e, UINT64_C (0xe9b5dba58189dbbc), \ 195 W[3] = GET_W_FROM_DATA (data, 3)); 196 SHA2STEP64 (e, f, g, h, a, b, c, d, UINT64_C (0x3956c25bf348b538), \ 197 W[4] = GET_W_FROM_DATA (data, 4)); 198 SHA2STEP64 (d, e, f, g, h, a, b, c, UINT64_C (0x59f111f1b605d019), \ 199 W[5] = GET_W_FROM_DATA (data, 5)); 200 SHA2STEP64 (c, d, e, f, g, h, a, b, UINT64_C (0x923f82a4af194f9b), \ 201 W[6] = GET_W_FROM_DATA (data, 6)); 202 SHA2STEP64 (b, c, d, e, f, g, h, a, UINT64_C (0xab1c5ed5da6d8118), \ 203 W[7] = GET_W_FROM_DATA (data, 7)); 204 SHA2STEP64 (a, b, c, d, e, f, g, h, UINT64_C (0xd807aa98a3030242), \ 205 W[8] = GET_W_FROM_DATA (data, 8)); 206 SHA2STEP64 (h, a, b, c, d, e, f, g, UINT64_C (0x12835b0145706fbe), \ 207 W[9] = GET_W_FROM_DATA (data, 9)); 208 SHA2STEP64 (g, h, a, b, c, d, e, f, UINT64_C (0x243185be4ee4b28c), \ 209 W[10] = GET_W_FROM_DATA (data, 10)); 210 SHA2STEP64 (f, g, h, a, b, c, d, e, UINT64_C (0x550c7dc3d5ffb4e2), \ 211 W[11] = GET_W_FROM_DATA (data, 11)); 212 SHA2STEP64 (e, f, g, h, a, b, c, d, UINT64_C (0x72be5d74f27b896f), \ 213 W[12] = GET_W_FROM_DATA (data, 12)); 214 SHA2STEP64 (d, e, f, g, h, a, b, c, UINT64_C (0x80deb1fe3b1696b1), \ 215 W[13] = GET_W_FROM_DATA (data, 13)); 216 SHA2STEP64 (c, d, e, f, g, h, a, b, UINT64_C (0x9bdc06a725c71235), \ 217 W[14] = GET_W_FROM_DATA (data, 14)); 218 SHA2STEP64 (b, c, d, e, f, g, h, a, UINT64_C (0xc19bf174cf692694), \ 219 W[15] = GET_W_FROM_DATA (data, 15)); 220 } 221 222 /* During last 64 steps, before making any calculations on each step, 223 current W element is generated from other W elements of the cyclic buffer 224 and the generated value is stored back in the cyclic buffer. */ 225 /* Note: instead of using K constants as array, all K values are specified 226 individually for each step, see FIPS PUB 180-4 clause 4.2.3 for 227 K values. */ 228 SHA2STEP64 (a, b, c, d, e, f, g, h, UINT64_C (0xe49b69c19ef14ad2), \ 229 W[16 & 15] = Wgen (W,16)); 230 SHA2STEP64 (h, a, b, c, d, e, f, g, UINT64_C (0xefbe4786384f25e3), \ 231 W[17 & 15] = Wgen (W,17)); 232 SHA2STEP64 (g, h, a, b, c, d, e, f, UINT64_C (0x0fc19dc68b8cd5b5), \ 233 W[18 & 15] = Wgen (W,18)); 234 SHA2STEP64 (f, g, h, a, b, c, d, e, UINT64_C (0x240ca1cc77ac9c65), \ 235 W[19 & 15] = Wgen (W,19)); 236 SHA2STEP64 (e, f, g, h, a, b, c, d, UINT64_C (0x2de92c6f592b0275), \ 237 W[20 & 15] = Wgen (W,20)); 238 SHA2STEP64 (d, e, f, g, h, a, b, c, UINT64_C (0x4a7484aa6ea6e483), \ 239 W[21 & 15] = Wgen (W,21)); 240 SHA2STEP64 (c, d, e, f, g, h, a, b, UINT64_C (0x5cb0a9dcbd41fbd4), \ 241 W[22 & 15] = Wgen (W,22)); 242 SHA2STEP64 (b, c, d, e, f, g, h, a, UINT64_C (0x76f988da831153b5), \ 243 W[23 & 15] = Wgen (W,23)); 244 SHA2STEP64 (a, b, c, d, e, f, g, h, UINT64_C (0x983e5152ee66dfab), \ 245 W[24 & 15] = Wgen (W,24)); 246 SHA2STEP64 (h, a, b, c, d, e, f, g, UINT64_C (0xa831c66d2db43210), \ 247 W[25 & 15] = Wgen (W,25)); 248 SHA2STEP64 (g, h, a, b, c, d, e, f, UINT64_C (0xb00327c898fb213f), \ 249 W[26 & 15] = Wgen (W,26)); 250 SHA2STEP64 (f, g, h, a, b, c, d, e, UINT64_C (0xbf597fc7beef0ee4), \ 251 W[27 & 15] = Wgen (W,27)); 252 SHA2STEP64 (e, f, g, h, a, b, c, d, UINT64_C (0xc6e00bf33da88fc2), \ 253 W[28 & 15] = Wgen (W,28)); 254 SHA2STEP64 (d, e, f, g, h, a, b, c, UINT64_C (0xd5a79147930aa725), \ 255 W[29 & 15] = Wgen (W,29)); 256 SHA2STEP64 (c, d, e, f, g, h, a, b, UINT64_C (0x06ca6351e003826f), \ 257 W[30 & 15] = Wgen (W,30)); 258 SHA2STEP64 (b, c, d, e, f, g, h, a, UINT64_C (0x142929670a0e6e70), \ 259 W[31 & 15] = Wgen (W,31)); 260 SHA2STEP64 (a, b, c, d, e, f, g, h, UINT64_C (0x27b70a8546d22ffc), \ 261 W[32 & 15] = Wgen (W,32)); 262 SHA2STEP64 (h, a, b, c, d, e, f, g, UINT64_C (0x2e1b21385c26c926), \ 263 W[33 & 15] = Wgen (W,33)); 264 SHA2STEP64 (g, h, a, b, c, d, e, f, UINT64_C (0x4d2c6dfc5ac42aed), \ 265 W[34 & 15] = Wgen (W,34)); 266 SHA2STEP64 (f, g, h, a, b, c, d, e, UINT64_C (0x53380d139d95b3df), \ 267 W[35 & 15] = Wgen (W,35)); 268 SHA2STEP64 (e, f, g, h, a, b, c, d, UINT64_C (0x650a73548baf63de), \ 269 W[36 & 15] = Wgen (W,36)); 270 SHA2STEP64 (d, e, f, g, h, a, b, c, UINT64_C (0x766a0abb3c77b2a8), \ 271 W[37 & 15] = Wgen (W,37)); 272 SHA2STEP64 (c, d, e, f, g, h, a, b, UINT64_C (0x81c2c92e47edaee6), \ 273 W[38 & 15] = Wgen (W,38)); 274 SHA2STEP64 (b, c, d, e, f, g, h, a, UINT64_C (0x92722c851482353b), \ 275 W[39 & 15] = Wgen (W,39)); 276 SHA2STEP64 (a, b, c, d, e, f, g, h, UINT64_C (0xa2bfe8a14cf10364), \ 277 W[40 & 15] = Wgen (W,40)); 278 SHA2STEP64 (h, a, b, c, d, e, f, g, UINT64_C (0xa81a664bbc423001), \ 279 W[41 & 15] = Wgen (W,41)); 280 SHA2STEP64 (g, h, a, b, c, d, e, f, UINT64_C (0xc24b8b70d0f89791), \ 281 W[42 & 15] = Wgen (W,42)); 282 SHA2STEP64 (f, g, h, a, b, c, d, e, UINT64_C (0xc76c51a30654be30), \ 283 W[43 & 15] = Wgen (W,43)); 284 SHA2STEP64 (e, f, g, h, a, b, c, d, UINT64_C (0xd192e819d6ef5218), \ 285 W[44 & 15] = Wgen (W,44)); 286 SHA2STEP64 (d, e, f, g, h, a, b, c, UINT64_C (0xd69906245565a910), \ 287 W[45 & 15] = Wgen (W,45)); 288 SHA2STEP64 (c, d, e, f, g, h, a, b, UINT64_C (0xf40e35855771202a), \ 289 W[46 & 15] = Wgen (W,46)); 290 SHA2STEP64 (b, c, d, e, f, g, h, a, UINT64_C (0x106aa07032bbd1b8), \ 291 W[47 & 15] = Wgen (W,47)); 292 SHA2STEP64 (a, b, c, d, e, f, g, h, UINT64_C (0x19a4c116b8d2d0c8), \ 293 W[48 & 15] = Wgen (W,48)); 294 SHA2STEP64 (h, a, b, c, d, e, f, g, UINT64_C (0x1e376c085141ab53), \ 295 W[49 & 15] = Wgen (W,49)); 296 SHA2STEP64 (g, h, a, b, c, d, e, f, UINT64_C (0x2748774cdf8eeb99), \ 297 W[50 & 15] = Wgen (W,50)); 298 SHA2STEP64 (f, g, h, a, b, c, d, e, UINT64_C (0x34b0bcb5e19b48a8), \ 299 W[51 & 15] = Wgen (W,51)); 300 SHA2STEP64 (e, f, g, h, a, b, c, d, UINT64_C (0x391c0cb3c5c95a63), \ 301 W[52 & 15] = Wgen (W,52)); 302 SHA2STEP64 (d, e, f, g, h, a, b, c, UINT64_C (0x4ed8aa4ae3418acb), \ 303 W[53 & 15] = Wgen (W,53)); 304 SHA2STEP64 (c, d, e, f, g, h, a, b, UINT64_C (0x5b9cca4f7763e373), \ 305 W[54 & 15] = Wgen (W,54)); 306 SHA2STEP64 (b, c, d, e, f, g, h, a, UINT64_C (0x682e6ff3d6b2b8a3), \ 307 W[55 & 15] = Wgen (W,55)); 308 SHA2STEP64 (a, b, c, d, e, f, g, h, UINT64_C (0x748f82ee5defb2fc), \ 309 W[56 & 15] = Wgen (W,56)); 310 SHA2STEP64 (h, a, b, c, d, e, f, g, UINT64_C (0x78a5636f43172f60), \ 311 W[57 & 15] = Wgen (W,57)); 312 SHA2STEP64 (g, h, a, b, c, d, e, f, UINT64_C (0x84c87814a1f0ab72), \ 313 W[58 & 15] = Wgen (W,58)); 314 SHA2STEP64 (f, g, h, a, b, c, d, e, UINT64_C (0x8cc702081a6439ec), \ 315 W[59 & 15] = Wgen (W,59)); 316 SHA2STEP64 (e, f, g, h, a, b, c, d, UINT64_C (0x90befffa23631e28), \ 317 W[60 & 15] = Wgen (W,60)); 318 SHA2STEP64 (d, e, f, g, h, a, b, c, UINT64_C (0xa4506cebde82bde9), \ 319 W[61 & 15] = Wgen (W,61)); 320 SHA2STEP64 (c, d, e, f, g, h, a, b, UINT64_C (0xbef9a3f7b2c67915), \ 321 W[62 & 15] = Wgen (W,62)); 322 SHA2STEP64 (b, c, d, e, f, g, h, a, UINT64_C (0xc67178f2e372532b), \ 323 W[63 & 15] = Wgen (W,63)); 324 SHA2STEP64 (a, b, c, d, e, f, g, h, UINT64_C (0xca273eceea26619c), \ 325 W[64 & 15] = Wgen (W,64)); 326 SHA2STEP64 (h, a, b, c, d, e, f, g, UINT64_C (0xd186b8c721c0c207), \ 327 W[65 & 15] = Wgen (W,65)); 328 SHA2STEP64 (g, h, a, b, c, d, e, f, UINT64_C (0xeada7dd6cde0eb1e), \ 329 W[66 & 15] = Wgen (W,66)); 330 SHA2STEP64 (f, g, h, a, b, c, d, e, UINT64_C (0xf57d4f7fee6ed178), \ 331 W[67 & 15] = Wgen (W,67)); 332 SHA2STEP64 (e, f, g, h, a, b, c, d, UINT64_C (0x06f067aa72176fba), \ 333 W[68 & 15] = Wgen (W,68)); 334 SHA2STEP64 (d, e, f, g, h, a, b, c, UINT64_C (0x0a637dc5a2c898a6), \ 335 W[69 & 15] = Wgen (W,69)); 336 SHA2STEP64 (c, d, e, f, g, h, a, b, UINT64_C (0x113f9804bef90dae), \ 337 W[70 & 15] = Wgen (W,70)); 338 SHA2STEP64 (b, c, d, e, f, g, h, a, UINT64_C (0x1b710b35131c471b), \ 339 W[71 & 15] = Wgen (W,71)); 340 SHA2STEP64 (a, b, c, d, e, f, g, h, UINT64_C (0x28db77f523047d84), \ 341 W[72 & 15] = Wgen (W,72)); 342 SHA2STEP64 (h, a, b, c, d, e, f, g, UINT64_C (0x32caab7b40c72493), \ 343 W[73 & 15] = Wgen (W,73)); 344 SHA2STEP64 (g, h, a, b, c, d, e, f, UINT64_C (0x3c9ebe0a15c9bebc), \ 345 W[74 & 15] = Wgen (W,74)); 346 SHA2STEP64 (f, g, h, a, b, c, d, e, UINT64_C (0x431d67c49c100d4c), \ 347 W[75 & 15] = Wgen (W,75)); 348 SHA2STEP64 (e, f, g, h, a, b, c, d, UINT64_C (0x4cc5d4becb3e42b6), \ 349 W[76 & 15] = Wgen (W,76)); 350 SHA2STEP64 (d, e, f, g, h, a, b, c, UINT64_C (0x597f299cfc657e2a), \ 351 W[77 & 15] = Wgen (W,77)); 352 SHA2STEP64 (c, d, e, f, g, h, a, b, UINT64_C (0x5fcb6fab3ad6faec), \ 353 W[78 & 15] = Wgen (W,78)); 354 SHA2STEP64 (b, c, d, e, f, g, h, a, UINT64_C (0x6c44198c4a475817), \ 355 W[79 & 15] = Wgen (W,79)); 356 #else /* MHD_FAVOR_SMALL_CODE */ 357 if (1) 358 { 359 unsigned int t; 360 /* K constants array. 361 See FIPS PUB 180-4 clause 4.2.3 for K values. */ 362 static const uint64_t K[80] = 363 { UINT64_C (0x428a2f98d728ae22), UINT64_C (0x7137449123ef65cd), 364 UINT64_C (0xb5c0fbcfec4d3b2f), UINT64_C (0xe9b5dba58189dbbc), 365 UINT64_C (0x3956c25bf348b538), UINT64_C (0x59f111f1b605d019), 366 UINT64_C (0x923f82a4af194f9b), UINT64_C (0xab1c5ed5da6d8118), 367 UINT64_C (0xd807aa98a3030242), UINT64_C (0x12835b0145706fbe), 368 UINT64_C (0x243185be4ee4b28c), UINT64_C (0x550c7dc3d5ffb4e2), 369 UINT64_C (0x72be5d74f27b896f), UINT64_C (0x80deb1fe3b1696b1), 370 UINT64_C (0x9bdc06a725c71235), UINT64_C (0xc19bf174cf692694), 371 UINT64_C (0xe49b69c19ef14ad2), UINT64_C (0xefbe4786384f25e3), 372 UINT64_C (0x0fc19dc68b8cd5b5), UINT64_C (0x240ca1cc77ac9c65), 373 UINT64_C (0x2de92c6f592b0275), UINT64_C (0x4a7484aa6ea6e483), 374 UINT64_C (0x5cb0a9dcbd41fbd4), UINT64_C (0x76f988da831153b5), 375 UINT64_C (0x983e5152ee66dfab), UINT64_C (0xa831c66d2db43210), 376 UINT64_C (0xb00327c898fb213f), UINT64_C (0xbf597fc7beef0ee4), 377 UINT64_C (0xc6e00bf33da88fc2), UINT64_C (0xd5a79147930aa725), 378 UINT64_C (0x06ca6351e003826f), UINT64_C (0x142929670a0e6e70), 379 UINT64_C (0x27b70a8546d22ffc), UINT64_C (0x2e1b21385c26c926), 380 UINT64_C (0x4d2c6dfc5ac42aed), UINT64_C (0x53380d139d95b3df), 381 UINT64_C (0x650a73548baf63de), UINT64_C (0x766a0abb3c77b2a8), 382 UINT64_C (0x81c2c92e47edaee6), UINT64_C (0x92722c851482353b), 383 UINT64_C (0xa2bfe8a14cf10364), UINT64_C (0xa81a664bbc423001), 384 UINT64_C (0xc24b8b70d0f89791), UINT64_C (0xc76c51a30654be30), 385 UINT64_C (0xd192e819d6ef5218), UINT64_C (0xd69906245565a910), 386 UINT64_C (0xf40e35855771202a), UINT64_C (0x106aa07032bbd1b8), 387 UINT64_C (0x19a4c116b8d2d0c8), UINT64_C (0x1e376c085141ab53), 388 UINT64_C (0x2748774cdf8eeb99), UINT64_C (0x34b0bcb5e19b48a8), 389 UINT64_C (0x391c0cb3c5c95a63), UINT64_C (0x4ed8aa4ae3418acb), 390 UINT64_C (0x5b9cca4f7763e373), UINT64_C (0x682e6ff3d6b2b8a3), 391 UINT64_C (0x748f82ee5defb2fc), UINT64_C (0x78a5636f43172f60), 392 UINT64_C (0x84c87814a1f0ab72), UINT64_C (0x8cc702081a6439ec), 393 UINT64_C (0x90befffa23631e28), UINT64_C (0xa4506cebde82bde9), 394 UINT64_C (0xbef9a3f7b2c67915), UINT64_C (0xc67178f2e372532b), 395 UINT64_C (0xca273eceea26619c), UINT64_C (0xd186b8c721c0c207), 396 UINT64_C (0xeada7dd6cde0eb1e), UINT64_C (0xf57d4f7fee6ed178), 397 UINT64_C (0x06f067aa72176fba), UINT64_C (0x0a637dc5a2c898a6), 398 UINT64_C (0x113f9804bef90dae), UINT64_C (0x1b710b35131c471b), 399 UINT64_C (0x28db77f523047d84), UINT64_C (0x32caab7b40c72493), 400 UINT64_C (0x3c9ebe0a15c9bebc), UINT64_C (0x431d67c49c100d4c), 401 UINT64_C (0x4cc5d4becb3e42b6), UINT64_C (0x597f299cfc657e2a), 402 UINT64_C (0x5fcb6fab3ad6faec), UINT64_C (0x6c44198c4a475817)}; 403 404 /* One step of SHA-512/256 computation with working variables rotation, 405 see FIPS PUB 180-4 clause 6.4.2 step 3. 406 * Note: this version of macro reassign all working variable on 407 each step. */ 408 #define SHA2STEP64RV(vA,vB,vC,vD,vE,vF,vG,vH,kt,wt) do { \ 409 uint64_t tmp_h_ = (vH); \ 410 SHA2STEP64((vA),(vB),(vC),(vD),(vE),(vF),(vG),tmp_h_,(kt),(wt)); \ 411 (vH) = (vG); \ 412 (vG) = (vF); \ 413 (vF) = (vE); \ 414 (vE) = (vD); \ 415 (vD) = (vC); \ 416 (vC) = (vB); \ 417 (vB) = (vA); \ 418 (vA) = tmp_h_; } while (0) 419 420 /* During first 16 steps, before making any calculations on each step, 421 the W element is read from the input data buffer as big-endian value and 422 stored in the array of W elements. */ 423 for (t = 0; t < 16; ++t) 424 { 425 SHA2STEP64RV (a, b, c, d, e, f, g, h, K[t], \ 426 W[t] = GET_W_FROM_DATA (data, t)); 427 } 428 /* During last 64 steps, before making any calculations on each step, 429 current W element is generated from other W elements of the cyclic buffer 430 and the generated value is stored back in the cyclic buffer. */ 431 for (t = 16; t < 80; ++t) 432 { 433 SHA2STEP64RV (a, b, c, d, e, f, g, h, K[t], \ 434 W[t & 15] = Wgen (W,t)); 435 } 436 } 437 #endif /* MHD_FAVOR_SMALL_CODE */ 438 439 /* Compute and store the intermediate hash. 440 See FIPS PUB 180-4 clause 6.4.2 step 4. */ 441 H[0] += a; 442 H[1] += b; 443 H[2] += c; 444 H[3] += d; 445 H[4] += e; 446 H[5] += f; 447 H[6] += g; 448 H[7] += h; 449 } 450 451 452 /** 453 * Process portion of bytes. 454 * 455 * @param ctx the calculation context 456 * @param data bytes to add to hash 457 * @param length number of bytes in @a data 458 */ 459 void 460 MHD_SHA512_256_update (struct Sha512_256Ctx *ctx, 461 const uint8_t *data, 462 size_t length) 463 { 464 unsigned int bytes_have; /**< Number of bytes in the context buffer */ 465 uint64_t count_hi; /**< The high part to be moved to another variable */ 466 467 mhd_assert ((data != NULL) || (length == 0)); 468 469 #ifndef MHD_FAVOR_SMALL_CODE 470 if (0 == length) 471 return; /* Shortcut, do nothing */ 472 #endif /* ! MHD_FAVOR_SMALL_CODE */ 473 474 /* Note: (count & (SHA512_256_BLOCK_SIZE-1)) 475 equals (count % SHA512_256_BLOCK_SIZE) for this block size. */ 476 bytes_have = (unsigned int) (ctx->count & (SHA512_256_BLOCK_SIZE - 1)); 477 ctx->count += length; 478 #if SIZEOF_SIZE_T > 7 479 if (length > ctx->count) 480 ctx->count_bits_hi += 1U << 3; /* Value wrap */ 481 #endif /* SIZEOF_SIZE_T > 7 */ 482 count_hi = ctx->count >> 61; 483 if (0 != count_hi) 484 { 485 ctx->count_bits_hi += count_hi; 486 ctx->count &= UINT64_C (0x1FFFFFFFFFFFFFFF); 487 } 488 489 if (0 != bytes_have) 490 { 491 unsigned int bytes_left = SHA512_256_BLOCK_SIZE - bytes_have; 492 if (length >= bytes_left) 493 { /* Combine new data with data in the buffer and 494 process the full block. */ 495 memcpy (((uint8_t *) ctx->buffer) + bytes_have, 496 data, 497 bytes_left); 498 data += bytes_left; 499 length -= bytes_left; 500 sha512_256_transform (ctx->H, ctx->buffer); 501 bytes_have = 0; 502 } 503 } 504 505 while (SHA512_256_BLOCK_SIZE <= length) 506 { /* Process any full blocks of new data directly, 507 without copying to the buffer. */ 508 sha512_256_transform (ctx->H, data); 509 data += SHA512_256_BLOCK_SIZE; 510 length -= SHA512_256_BLOCK_SIZE; 511 } 512 513 if (0 != length) 514 { /* Copy incomplete block of new data (if any) 515 to the buffer. */ 516 memcpy (((uint8_t *) ctx->buffer) + bytes_have, data, length); 517 } 518 } 519 520 521 /** 522 * Size of "length" insertion in bits. 523 * See FIPS PUB 180-4 clause 5.1.2. 524 */ 525 #define SHA512_256_SIZE_OF_LEN_ADD_BITS 128 526 527 /** 528 * Size of "length" insertion in bytes. 529 */ 530 #define SHA512_256_SIZE_OF_LEN_ADD (SHA512_256_SIZE_OF_LEN_ADD_BITS / 8) 531 532 /** 533 * Finalise SHA-512/256 calculation, return digest. 534 * 535 * @param ctx the calculation context 536 * @param[out] digest set to the hash, must be #SHA512_256_DIGEST_SIZE bytes 537 */ 538 void 539 MHD_SHA512_256_finish (struct Sha512_256Ctx *ctx, 540 uint8_t digest[SHA512_256_DIGEST_SIZE]) 541 { 542 uint64_t num_bits; /**< Number of processed bits */ 543 unsigned int bytes_have; /**< Number of bytes in the context buffer */ 544 545 /* Memorise the number of processed bits. 546 The padding and other data added here during the postprocessing must 547 not change the amount of hashed data. */ 548 num_bits = ctx->count << 3; 549 550 /* Note: (count & (SHA512_256_BLOCK_SIZE-1)) 551 equals (count % SHA512_256_BLOCK_SIZE) for this block size. */ 552 bytes_have = (unsigned int) (ctx->count & (SHA512_256_BLOCK_SIZE - 1)); 553 554 /* Input data must be padded with a single bit "1", then with zeros and 555 the finally the length of data in bits must be added as the final bytes 556 of the last block. 557 See FIPS PUB 180-4 clause 5.1.2. */ 558 559 /* Data is always processed in form of bytes (not by individual bits), 560 therefore position of the first padding bit in byte is always 561 predefined (0x80). */ 562 /* Buffer always have space for one byte at least (as full buffers are 563 processed immediately). */ 564 ((uint8_t *) ctx->buffer)[bytes_have++] = 0x80; 565 566 if (SHA512_256_BLOCK_SIZE - bytes_have < SHA512_256_SIZE_OF_LEN_ADD) 567 { /* No space in the current block to put the total length of message. 568 Pad the current block with zeros and process it. */ 569 if (bytes_have < SHA512_256_BLOCK_SIZE) 570 memset (((uint8_t *) ctx->buffer) + bytes_have, 0, 571 SHA512_256_BLOCK_SIZE - bytes_have); 572 /* Process the full block. */ 573 sha512_256_transform (ctx->H, ctx->buffer); 574 /* Start the new block. */ 575 bytes_have = 0; 576 } 577 578 /* Pad the rest of the buffer with zeros. */ 579 memset (((uint8_t *) ctx->buffer) + bytes_have, 0, 580 SHA512_256_BLOCK_SIZE - SHA512_256_SIZE_OF_LEN_ADD - bytes_have); 581 /* Put high part of number of bits in processed message and then lower 582 part of number of bits as big-endian values. 583 See FIPS PUB 180-4 clause 5.1.2. */ 584 /* Note: the target location is predefined and buffer is always aligned */ 585 _MHD_PUT_64BIT_BE (ctx->buffer + SHA512_256_BLOCK_SIZE_WORDS - 2, 586 ctx->count_bits_hi); 587 _MHD_PUT_64BIT_BE (ctx->buffer + SHA512_256_BLOCK_SIZE_WORDS - 1, 588 num_bits); 589 /* Process the full final block. */ 590 sha512_256_transform (ctx->H, ctx->buffer); 591 592 /* Put in BE mode the leftmost part of the hash as the final digest. 593 See FIPS PUB 180-4 clause 6.7. */ 594 #ifndef _MHD_PUT_64BIT_BE_UNALIGNED 595 if (1 596 #ifndef MHD_FAVOR_SMALL_CODE 597 && (0 != ((uintptr_t) digest) % _MHD_UINT64_ALIGN) 598 #endif /* MHD_FAVOR_SMALL_CODE */ 599 ) 600 { 601 /* If storing of the final result requires aligned address and 602 the destination address is not aligned or compact code is used, 603 store the final digest in aligned temporary buffer first, then 604 copy it to the destination. */ 605 uint64_t alig_dgst[SHA512_256_DIGEST_SIZE_WORDS]; 606 _MHD_PUT_64BIT_BE (alig_dgst + 0, ctx->H[0]); 607 _MHD_PUT_64BIT_BE (alig_dgst + 1, ctx->H[1]); 608 _MHD_PUT_64BIT_BE (alig_dgst + 2, ctx->H[2]); 609 _MHD_PUT_64BIT_BE (alig_dgst + 3, ctx->H[3]); 610 /* Copy result to the unaligned destination address */ 611 memcpy (digest, alig_dgst, SHA512_256_DIGEST_SIZE); 612 } 613 #ifndef MHD_FAVOR_SMALL_CODE 614 else /* Combined with the next 'if' */ 615 #endif /* MHD_FAVOR_SMALL_CODE */ 616 #endif /* ! _MHD_PUT_64BIT_BE_UNALIGNED */ 617 #if ! defined(MHD_FAVOR_SMALL_CODE) || defined(_MHD_PUT_64BIT_BE_UNALIGNED) 618 if (1) 619 { 620 /* Use cast to (void*) here to mute compiler alignment warnings. 621 * Compilers are not smart enough to see that alignment has been checked. */ 622 _MHD_PUT_64BIT_BE ((void *) (digest + 0 * SHA512_256_BYTES_IN_WORD), \ 623 ctx->H[0]); 624 _MHD_PUT_64BIT_BE ((void *) (digest + 1 * SHA512_256_BYTES_IN_WORD), \ 625 ctx->H[1]); 626 _MHD_PUT_64BIT_BE ((void *) (digest + 2 * SHA512_256_BYTES_IN_WORD), \ 627 ctx->H[2]); 628 _MHD_PUT_64BIT_BE ((void *) (digest + 3 * SHA512_256_BYTES_IN_WORD), \ 629 ctx->H[3]); 630 } 631 #endif /* ! MHD_FAVOR_SMALL_CODE || _MHD_PUT_64BIT_BE_UNALIGNED */ 632 633 /* Erase potentially sensitive data. */ 634 memset (ctx, 0, sizeof(struct Sha512_256Ctx)); 635 } 636 637 638 MHD_DATA_TRUNCATION_RUNTIME_CHECK_RESTORE_