GNU libmicrohttpd  1.0.1
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 
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 
40 void
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 
69 static 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 
459 void
461  const uint8_t *data,
462  size_t length)
463 {
464  unsigned int bytes_have;
465  uint64_t count_hi;
467  mhd_assert ((data != NULL) || (length == 0));
468 
469 #ifndef MHD_FAVOR_SMALL_CODE
470  if (0 == length)
471  return; /* Shortcut, do nothing */
472 #endif /* ! MHD_FAVOR_SMALL_CODE */
473 
474  /* Note: (count & (SHA512_256_BLOCK_SIZE-1))
475  equals (count % SHA512_256_BLOCK_SIZE) for this block size. */
476  bytes_have = (unsigned int) (ctx->count & (SHA512_256_BLOCK_SIZE - 1));
477  ctx->count += length;
478 #if SIZEOF_SIZE_T > 7
479  if (length > ctx->count)
480  ctx->count_bits_hi += 1U << 3; /* Value wrap */
481 #endif /* SIZEOF_SIZE_T > 7 */
482  count_hi = ctx->count >> 61;
483  if (0 != count_hi)
484  {
485  ctx->count_bits_hi += count_hi;
486  ctx->count &= UINT64_C (0x1FFFFFFFFFFFFFFF);
487  }
488 
489  if (0 != bytes_have)
490  {
491  unsigned int bytes_left = SHA512_256_BLOCK_SIZE - bytes_have;
492  if (length >= bytes_left)
493  { /* Combine new data with data in the buffer and
494  process the full block. */
495  memcpy (((uint8_t *) ctx->buffer) + bytes_have,
496  data,
497  bytes_left);
498  data += bytes_left;
499  length -= bytes_left;
500  sha512_256_transform (ctx->H, ctx->buffer);
501  bytes_have = 0;
502  }
503  }
504 
505  while (SHA512_256_BLOCK_SIZE <= length)
506  { /* Process any full blocks of new data directly,
507  without copying to the buffer. */
508  sha512_256_transform (ctx->H, data);
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 
538 void
540  uint8_t digest[SHA512_256_DIGEST_SIZE])
541 {
542  uint64_t num_bits;
543  unsigned int bytes_have;
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
Definition: reason_phrase.c:30
#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_
Definition: mhd_options.h:176
#define MHD_DATA_TRUNCATION_RUNTIME_CHECK_RESTORE_
Definition: mhd_options.h:177
macros for mhd_assert()
void * data
Definition: microhttpd.h:3968
#define Wgen(w, t)
#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
#define GET_W_FROM_DATA(buf, t)
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