sha512_256_int.c (29401B)
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 } while (0) 437 438 /* During first 16 steps, before making any calculations on each step, 439 the W element is read from the input data buffer as big-endian value and 440 stored in the array of W elements. */ 441 for (t = 0; t < 16; ++t) 442 { 443 SHA2STEP64RV (a, b, c, d, e, f, g, h, K[t], \ 444 W[t] = GET_W_FROM_DATA (data, t)); 445 } 446 /* During last 64 steps, before making any calculations on each step, 447 current W element is generated from other W elements of the cyclic buffer 448 and the generated value is stored back in the cyclic buffer. */ 449 for (t = 16; t < 80; ++t) 450 { 451 SHA2STEP64RV (a, b, c, d, e, f, g, h, K[t], \ 452 W[t & 15] = Wgen (W, t)); 453 } 454 } 455 #endif /* MHD_FAVOR_SMALL_CODE */ 456 457 /* Compute and store the intermediate hash. 458 See FIPS PUB 180-4 clause 6.4.2 step 4. */ 459 H[0] += a; 460 H[1] += b; 461 H[2] += c; 462 H[3] += d; 463 H[4] += e; 464 H[5] += f; 465 H[6] += g; 466 H[7] += h; 467 } 468 469 470 MHD_INTERNAL MHD_FN_PAR_NONNULL_ALL_ 471 MHD_FN_PAR_IN_SIZE_ (3, 2) void 472 mhd_SHA512_256_update (struct mhd_Sha512_256CtxInt *restrict ctx, 473 size_t size, 474 const uint8_t *restrict data) 475 { 476 unsigned int bytes_have; /**< Number of bytes in the context buffer */ 477 uint64_t count_hi; /**< The high part to be moved to another variable */ 478 479 mhd_assert (0 != size); 480 481 /* Note: (count & (mhd_SHA512_256_BLOCK_SIZE-1)) 482 equals (count % mhd_SHA512_256_BLOCK_SIZE) for this block size. */ 483 bytes_have = (unsigned int)(ctx->count & (mhd_SHA512_256_BLOCK_SIZE - 1)); 484 ctx->count += size; 485 #if SIZEOF_SIZE_T > 7 486 if (size > ctx->count) 487 ctx->count_bits_hi += 1U << 3; /* Value wrap */ 488 #endif /* SIZEOF_SIZE_T > 7 */ 489 count_hi = ctx->count >> 61; 490 if (0 != count_hi) 491 { 492 ctx->count_bits_hi += count_hi; 493 ctx->count &= UINT64_C (0x1FFFFFFFFFFFFFFF); 494 } 495 496 if (0 != bytes_have) 497 { 498 unsigned int bytes_left = mhd_SHA512_256_BLOCK_SIZE - bytes_have; 499 if (size >= bytes_left) 500 { /* Combine new data with data in the buffer and 501 process the full block. */ 502 memcpy (((uint8_t *)ctx->buffer) + bytes_have, 503 data, 504 bytes_left); 505 data += bytes_left; 506 size -= bytes_left; 507 sha512_256_transform (ctx->H, ctx->buffer); 508 bytes_have = 0; 509 } 510 } 511 512 while (mhd_SHA512_256_BLOCK_SIZE <= size) 513 { /* Process any full blocks of new data directly, 514 without copying to the buffer. */ 515 sha512_256_transform (ctx->H, data); 516 data += mhd_SHA512_256_BLOCK_SIZE; 517 size -= mhd_SHA512_256_BLOCK_SIZE; 518 } 519 520 if (0 != size) 521 { /* Copy incomplete block of new data (if any) 522 to the buffer. */ 523 memcpy (((uint8_t *)ctx->buffer) + bytes_have, data, size); 524 } 525 } 526 527 528 /** 529 * Size of "length" insertion in bits. 530 * See FIPS PUB 180-4 clause 5.1.2. 531 */ 532 #define SHA512_256_SIZE_OF_LEN_ADD_BITS 128 533 534 /** 535 * Size of "length" insertion in bytes. 536 */ 537 #define SHA512_256_SIZE_OF_LEN_ADD (SHA512_256_SIZE_OF_LEN_ADD_BITS / 8) 538 539 MHD_INTERNAL MHD_FN_PAR_NONNULL_ALL_ void 540 mhd_SHA512_256_finish (struct mhd_Sha512_256CtxInt *restrict ctx, 541 uint8_t digest[mhd_SHA512_256_DIGEST_SIZE]) 542 { 543 uint64_t num_bits; /**< Number of processed bits */ 544 unsigned int bytes_have; /**< Number of bytes in the context buffer */ 545 546 /* Memorise the number of processed bits. 547 The padding and other data added here during the postprocessing must 548 not change the amount of hashed data. */ 549 num_bits = ctx->count << 3; 550 551 /* Note: (count & (mhd_SHA512_256_BLOCK_SIZE-1)) 552 equals (count % mhd_SHA512_256_BLOCK_SIZE) for this block size. */ 553 bytes_have = (unsigned int)(ctx->count & (mhd_SHA512_256_BLOCK_SIZE - 1)); 554 555 /* Input data must be padded with a single bit "1", then with zeros and 556 the finally the length of data in bits must be added as the final bytes 557 of the last block. 558 See FIPS PUB 180-4 clause 5.1.2. */ 559 560 /* Data is always processed in form of bytes (not by individual bits), 561 therefore position of the first padding bit in byte is always 562 predefined (0x80). */ 563 /* Buffer always have space for one byte at least (as full buffers are 564 processed immediately). */ 565 ((uint8_t *)ctx->buffer)[bytes_have++] = 0x80; 566 567 if (mhd_SHA512_256_BLOCK_SIZE - bytes_have < SHA512_256_SIZE_OF_LEN_ADD) 568 { /* No space in the current block to put the total length of message. 569 Pad the current block with zeros and process it. */ 570 if (bytes_have < mhd_SHA512_256_BLOCK_SIZE) 571 memset (((uint8_t *)ctx->buffer) + bytes_have, 0, 572 mhd_SHA512_256_BLOCK_SIZE - bytes_have); 573 /* Process the full block. */ 574 sha512_256_transform (ctx->H, ctx->buffer); 575 /* Start the new block. */ 576 bytes_have = 0; 577 } 578 579 /* Pad the rest of the buffer with zeros. */ 580 memset (((uint8_t *)ctx->buffer) + bytes_have, 0, 581 mhd_SHA512_256_BLOCK_SIZE - SHA512_256_SIZE_OF_LEN_ADD - bytes_have); 582 /* Put high part of number of bits in processed message and then lower 583 part of number of bits as big-endian values. 584 See FIPS PUB 180-4 clause 5.1.2. */ 585 /* Note: the target location is predefined and buffer is always aligned */ 586 mhd_PUT_64BIT_BE (ctx->buffer + mhd_SHA512_256_BLOCK_SIZE_WORDS - 2, 587 ctx->count_bits_hi); 588 mhd_PUT_64BIT_BE (ctx->buffer + mhd_SHA512_256_BLOCK_SIZE_WORDS - 1, 589 num_bits); 590 /* Process the full final block. */ 591 sha512_256_transform (ctx->H, ctx->buffer); 592 593 /* Put in BE mode the leftmost part of the hash as the final digest. 594 See FIPS PUB 180-4 clause 6.7. */ 595 if (1) 596 { 597 bool use_tmp_buf_to_align_result; 598 599 #if defined(mhd_PUT_64BIT_BE_UNALIGNED) 600 use_tmp_buf_to_align_result = false; 601 #elif defined(MHD_FAVOR_SMALL_CODE) 602 use_tmp_buf_to_align_result = true; /* smaller code: eliminated branch below */ 603 #else 604 use_tmp_buf_to_align_result = 605 (0 != ((uintptr_t)digest) % mhd_UINT64_ALIGN); 606 #endif 607 if (use_tmp_buf_to_align_result) 608 { 609 /* If storing of the final result requires aligned address and 610 the destination address is not aligned or compact code is used, 611 store the final digest in aligned temporary buffer first, then 612 copy it to the destination. */ 613 uint64_t alig_dgst[mhd_SHA512_256_DIGEST_SIZE_WORDS]; 614 mhd_PUT_64BIT_BE (alig_dgst + 0, ctx->H[0]); 615 mhd_PUT_64BIT_BE (alig_dgst + 1, ctx->H[1]); 616 mhd_PUT_64BIT_BE (alig_dgst + 2, ctx->H[2]); 617 mhd_PUT_64BIT_BE (alig_dgst + 3, ctx->H[3]); 618 /* Copy result to the unaligned destination address */ 619 memcpy (digest, alig_dgst, mhd_SHA512_256_DIGEST_SIZE); 620 } 621 else 622 { 623 /* Use cast to (void*) here to mute compiler alignment warnings. 624 * Compilers are not smart enough to see that alignment has been checked. */ 625 mhd_PUT_64BIT_BE ((void *)(digest + 0 * mhd_SHA512_256_BYTES_IN_WORD), \ 626 ctx->H[0]); 627 mhd_PUT_64BIT_BE ((void *)(digest + 1 * mhd_SHA512_256_BYTES_IN_WORD), \ 628 ctx->H[1]); 629 mhd_PUT_64BIT_BE ((void *)(digest + 2 * mhd_SHA512_256_BYTES_IN_WORD), \ 630 ctx->H[2]); 631 mhd_PUT_64BIT_BE ((void *)(digest + 3 * mhd_SHA512_256_BYTES_IN_WORD), \ 632 ctx->H[3]); 633 } 634 } 635 636 /* Erase potentially sensitive data. */ 637 memset (ctx, 0, sizeof(struct mhd_Sha512_256CtxInt)); 638 } 639 640 641 mhd_DATA_TRUNCATION_RUNTIME_CHECK_RESTORE