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