sha512_256_builtin.c (29860B)
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-2026 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_builtin.c 41 * @brief Calculation of SHA-512/256 digest, built-in implementation 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_builtin.h" 55 56 MHD_INTERNAL MHD_FN_PAR_NONNULL_ALL_ MHD_FN_PAR_OUT_ (1) void 57 mhd_SHA512_256_blti_init (struct mhd_Sha512_256CtxBlti *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_ MHD_FN_PAR_INOUT_ (1) 471 MHD_FN_PAR_IN_SIZE_ (3, 2) void 472 mhd_SHA512_256_blti_update (struct mhd_Sha512_256CtxBlti *restrict ctx, 473 size_t size, 474 const void *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 const uint8_t *unpr_d; 479 480 unpr_d = (const uint8_t *)data; 481 482 #ifndef MHD_UNIT_TESTING 483 /* The function works fine with empty data, but it is expected 484 that MHD calls it only with real data to process. */ 485 mhd_assert ((0 != size) 486 && "A safeguard against an accidental call with missing data"); 487 #endif 488 489 /* Note: (count & (mhd_SHA512_256_BLOCK_SIZE-1)) 490 equals (count % mhd_SHA512_256_BLOCK_SIZE) for this block size. */ 491 bytes_have = (unsigned int)(ctx->count & (mhd_SHA512_256_BLOCK_SIZE - 1)); 492 ctx->count += size; 493 #if SIZEOF_SIZE_T > 7 494 if (size > ctx->count) 495 ctx->count_bits_hi += 1U << 3; /* Value wrap */ 496 #endif /* SIZEOF_SIZE_T > 7 */ 497 count_hi = ctx->count >> 61; 498 if (0 != count_hi) 499 { 500 ctx->count_bits_hi += count_hi; 501 ctx->count &= UINT64_C (0x1FFFFFFFFFFFFFFF); 502 } 503 504 if (0 != bytes_have) 505 { 506 unsigned int bytes_left = mhd_SHA512_256_BLOCK_SIZE - bytes_have; 507 if (size >= bytes_left) 508 { /* Combine new data with data in the buffer and 509 process the full block. */ 510 memcpy (((uint8_t *)ctx->buffer) + bytes_have, 511 unpr_d, 512 bytes_left); 513 unpr_d += bytes_left; 514 size -= bytes_left; 515 sha512_256_transform (ctx->H, ctx->buffer); 516 bytes_have = 0; 517 } 518 } 519 520 while (mhd_SHA512_256_BLOCK_SIZE <= size) 521 { /* Process any full blocks of new data directly, 522 without copying to the buffer. */ 523 sha512_256_transform (ctx->H, unpr_d); 524 unpr_d += mhd_SHA512_256_BLOCK_SIZE; 525 size -= mhd_SHA512_256_BLOCK_SIZE; 526 } 527 528 if (0 != size) 529 { /* Copy incomplete block of new data (if any) 530 to the buffer. */ 531 memcpy (((uint8_t *)ctx->buffer) + bytes_have, unpr_d, size); 532 } 533 } 534 535 536 /** 537 * Size of "length" insertion in bits. 538 * See FIPS PUB 180-4 clause 5.1.2. 539 */ 540 #define SHA512_256_SIZE_OF_LEN_ADD_BITS 128 541 542 /** 543 * Size of "length" insertion in bytes. 544 */ 545 #define SHA512_256_SIZE_OF_LEN_ADD (SHA512_256_SIZE_OF_LEN_ADD_BITS / 8) 546 547 MHD_INTERNAL MHD_FN_PAR_NONNULL_ALL_ MHD_FN_PAR_INOUT_ (1) 548 MHD_FN_PAR_OUT_ (2) void 549 mhd_SHA512_256_blti_finish ( 550 struct mhd_Sha512_256CtxBlti *restrict ctx, 551 uint8_t digest[MHD_FN_PAR_FIX_ARR_SIZE_ (mhd_SHA512_256_DIGEST_SIZE)]) 552 { 553 uint64_t num_bits; /**< Number of processed bits */ 554 unsigned int bytes_have; /**< Number of bytes in the context buffer */ 555 556 /* Memorise the number of processed bits. 557 The padding and other data added here during the postprocessing must 558 not change the amount of hashed data. */ 559 num_bits = ctx->count << 3; 560 561 /* Note: (count & (mhd_SHA512_256_BLOCK_SIZE-1)) 562 equals (count % mhd_SHA512_256_BLOCK_SIZE) for this block size. */ 563 bytes_have = (unsigned int)(ctx->count & (mhd_SHA512_256_BLOCK_SIZE - 1)); 564 565 /* Input data must be padded with a single bit "1", then with zeros and 566 the finally the length of data in bits must be added as the final bytes 567 of the last block. 568 See FIPS PUB 180-4 clause 5.1.2. */ 569 570 /* Data is always processed in form of bytes (not by individual bits), 571 therefore position of the first padding bit in byte is always 572 predefined (0x80). */ 573 /* Buffer always have space for one byte at least (as full buffers are 574 processed immediately). */ 575 ((uint8_t *)ctx->buffer)[bytes_have++] = 0x80; 576 577 if (mhd_SHA512_256_BLOCK_SIZE - bytes_have < SHA512_256_SIZE_OF_LEN_ADD) 578 { /* No space in the current block to put the total length of message. 579 Pad the current block with zeros and process it. */ 580 if (bytes_have < mhd_SHA512_256_BLOCK_SIZE) 581 memset (((uint8_t *)ctx->buffer) + bytes_have, 0, 582 mhd_SHA512_256_BLOCK_SIZE - bytes_have); 583 /* Process the full block. */ 584 sha512_256_transform (ctx->H, ctx->buffer); 585 /* Start the new block. */ 586 bytes_have = 0; 587 } 588 589 /* Pad the rest of the buffer with zeros. */ 590 memset (((uint8_t *)ctx->buffer) + bytes_have, 0, 591 mhd_SHA512_256_BLOCK_SIZE - SHA512_256_SIZE_OF_LEN_ADD - bytes_have); 592 /* Put high part of number of bits in processed message and then lower 593 part of number of bits as big-endian values. 594 See FIPS PUB 180-4 clause 5.1.2. */ 595 /* Note: the target location is predefined and buffer is always aligned */ 596 mhd_PUT_64BIT_BE (ctx->buffer + mhd_SHA512_256_BLOCK_SIZE_WORDS - 2, 597 ctx->count_bits_hi); 598 mhd_PUT_64BIT_BE (ctx->buffer + mhd_SHA512_256_BLOCK_SIZE_WORDS - 1, 599 num_bits); 600 /* Process the full final block. */ 601 sha512_256_transform (ctx->H, ctx->buffer); 602 603 /* Put in BE mode the leftmost part of the hash as the final digest. 604 See FIPS PUB 180-4 clause 6.7. */ 605 if (1) 606 { 607 bool use_tmp_buf_to_align_result; 608 609 #if defined(mhd_PUT_64BIT_BE_UNALIGNED) 610 use_tmp_buf_to_align_result = false; 611 #elif defined(MHD_FAVOR_SMALL_CODE) 612 use_tmp_buf_to_align_result = true; /* smaller code: eliminated branch below */ 613 #else 614 use_tmp_buf_to_align_result = 615 (0 != ((uintptr_t)digest) % mhd_UINT64_ALIGN); 616 #endif 617 if (use_tmp_buf_to_align_result) 618 { 619 /* If storing of the final result requires aligned address and 620 the destination address is not aligned or compact code is used, 621 store the final digest in aligned temporary buffer first, then 622 copy it to the destination. */ 623 uint64_t alig_dgst[mhd_SHA512_256_DIGEST_SIZE_WORDS]; 624 mhd_PUT_64BIT_BE (alig_dgst + 0, ctx->H[0]); 625 mhd_PUT_64BIT_BE (alig_dgst + 1, ctx->H[1]); 626 mhd_PUT_64BIT_BE (alig_dgst + 2, ctx->H[2]); 627 mhd_PUT_64BIT_BE (alig_dgst + 3, ctx->H[3]); 628 /* Copy result to the unaligned destination address */ 629 memcpy (digest, alig_dgst, mhd_SHA512_256_DIGEST_SIZE); 630 } 631 else 632 { 633 /* Use cast to (void*) here to mute compiler alignment warnings. 634 * Compilers are not smart enough to see that alignment has been checked. */ 635 mhd_PUT_64BIT_BE ((void *)(digest + 0 * mhd_SHA512_256_BYTES_IN_WORD), \ 636 ctx->H[0]); 637 mhd_PUT_64BIT_BE ((void *)(digest + 1 * mhd_SHA512_256_BYTES_IN_WORD), \ 638 ctx->H[1]); 639 mhd_PUT_64BIT_BE ((void *)(digest + 2 * mhd_SHA512_256_BYTES_IN_WORD), \ 640 ctx->H[2]); 641 mhd_PUT_64BIT_BE ((void *)(digest + 3 * mhd_SHA512_256_BYTES_IN_WORD), \ 642 ctx->H[3]); 643 } 644 } 645 646 /* Erase potentially sensitive data. */ 647 memset (ctx, 0, sizeof(struct mhd_Sha512_256CtxBlti)); 648 } 649 650 651 mhd_DATA_TRUNCATION_RUNTIME_CHECK_RESTORE