GNU libmicrohttpd 1.0.1
Loading...
Searching...
No Matches
sha512_256.c
Go to the documentation of this file.
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
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
40void
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
62
69static void
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
459void
461 const uint8_t *data,
462 size_t length)
463{
464 unsigned int bytes_have;
465 uint64_t count_hi;
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. */
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
525#define SHA512_256_SIZE_OF_LEN_ADD_BITS 128
526
530#define SHA512_256_SIZE_OF_LEN_ADD (SHA512_256_SIZE_OF_LEN_ADD_BITS / 8)
531
538void
540 uint8_t digest[SHA512_256_DIGEST_SIZE])
541{
542 uint64_t num_bits;
543 unsigned int bytes_have;
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
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,
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 */
586 ctx->count_bits_hi);
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
#define mhd_assert(CHK)
Definition mhd_assert.h:39
#define NULL
#define _MHD_UINT64_ALIGN
Definition mhd_align.h:93
macros for bits manipulations
#define _MHD_PUT_64BIT_BE(addr, value64)
#define MHD_DATA_TRUNCATION_RUNTIME_CHECK_DISABLE_
#define MHD_DATA_TRUNCATION_RUNTIME_CHECK_RESTORE_
macros for mhd_assert()
#define Wgen(w, t)
#define GET_W_FROM_DATA(buf, t)
void * data
#define SHA2STEP64(vA, vB, vC, vD, vE, vF, vG, vH, kt, wt)
void MHD_SHA512_256_finish(struct Sha512_256Ctx *ctx, uint8_t digest[SHA512_256_DIGEST_SIZE])
Definition sha512_256.c:539
void MHD_SHA512_256_init(struct Sha512_256Ctx *ctx)
Definition sha512_256.c:41
void MHD_SHA512_256_update(struct Sha512_256Ctx *ctx, const uint8_t *data, size_t length)
Definition sha512_256.c:460
static MHD_DATA_TRUNCATION_RUNTIME_CHECK_DISABLE_ void sha512_256_transform(uint64_t H[SHA512_256_HASH_SIZE_WORDS], const void *data)
Definition sha512_256.c:70
#define SHA512_256_SIZE_OF_LEN_ADD
Definition sha512_256.c:530
Calculation of SHA-512/256 digest.
#define SHA512_256_BLOCK_SIZE
Definition sha512_256.h:78
#define SHA512_256_BLOCK_SIZE_WORDS
Definition sha512_256.h:83
#define SHA512_256_HASH_SIZE_WORDS
Definition sha512_256.h:50
#define SHA512_256_DIGEST_SIZE_WORDS
Definition sha512_256.h:56
#define SHA512_256_DIGEST_SIZE
Definition sha512_256.h:62
#define SHA512_256_BYTES_IN_WORD
Definition sha512_256.h:44
uint64_t count_bits_hi
Definition sha512_256.h:102
uint64_t count
Definition sha512_256.h:97
uint64_t H[SHA512_256_HASH_SIZE_WORDS]
Definition sha512_256.h:92
uint64_t buffer[SHA512_256_BLOCK_SIZE_WORDS]
Definition sha512_256.h:93