1 /*
2 * Copyright (c) 2000, 2001 X-Way Rights BV
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 *
18 */
19
20 /*!\file sha256.c
21 * \brief SHA-256 hash function, as specified by NIST DFIPS 180-2.
22 * \author Bob Deblier <bob.deblier@telenet.be>
23 * \ingroup HASH_m HASH_sha256_m
24 */
25
26 #define BEECRYPT_DLL_EXPORT
27
28 #if HAVE_CONFIG_H
29 # include "config.h"
30 #endif
31
32 #include "beecrypt/sha256.h"
33 #include "beecrypt/sha2k32.h"
34 #include "beecrypt/endianness.h"
35
36 /*!\addtogroup HASH_sha256_m
37 * \{
38 */
39
40 static const uint32_t hinit[8] = {
41 0x6a09e667U, 0xbb67ae85U, 0x3c6ef372U, 0xa54ff53aU, 0x510e527fU, 0x9b05688cU, 0x1f83d9abU, 0x5be0cd19U
42 };
43
44 const hashFunction sha256 = {
45 .name = "SHA-256",
46 .paramsize = sizeof(sha256Param),
47 .blocksize = 64,
48 .digestsize = 32,
49 .reset = (hashFunctionReset) sha256Reset,
50 .update = (hashFunctionUpdate) sha256Update,
51 .digest = (hashFunctionDigest) sha256Digest
52 };
53
sha256Reset(register sha256Param * sp)54 int sha256Reset(register sha256Param* sp)
55 {
56 memcpy(sp->h, hinit, 8 * sizeof(uint32_t));
57 memset(sp->data, 0, 64 * sizeof(uint32_t));
58 #if (MP_WBITS == 64)
59 mpzero(1, sp->length);
60 #elif (MP_WBITS == 32)
61 mpzero(2, sp->length);
62 #else
63 # error
64 #endif
65 sp->offset = 0;
66 return 0;
67 }
68
69 #define R(x,s) ((x) >> (s))
70 #define S(x,s) ROTR32(x, s)
71
72 #define CH(x,y,z) ((x&(y^z))^z)
73 #define MAJ(x,y,z) (((x|y)&z)|(x&y))
74 #define SIG0(x) (S(x,2) ^ S(x,13) ^ S(x,22))
75 #define SIG1(x) (S(x,6) ^ S(x,11) ^ S(x,25))
76 #define sig0(x) (S(x,7) ^ S(x,18) ^ R(x,3))
77 #define sig1(x) (S(x,17) ^ S(x,19) ^ R(x,10))
78
79 #define ROUND(a,b,c,d,e,f,g,h,w,k) \
80 temp = h + SIG1(e) + CH(e,f,g) + k + w; \
81 h = temp + SIG0(a) + MAJ(a,b,c); \
82 d += temp
83
84 #ifndef ASM_SHA256PROCESS
sha256Process(register sha256Param * sp)85 void sha256Process(register sha256Param* sp)
86 {
87 register uint32_t a, b, c, d, e, f, g, h, temp;
88 register uint32_t *w;
89 register const uint32_t *k;
90 register byte t;
91
92 #if WORDS_BIGENDIAN
93 w = sp->data + 16;
94 #else
95 w = sp->data;
96 t = 16;
97 while (t--)
98 {
99 temp = swapu32(*w);
100 *(w++) = temp;
101 }
102 #endif
103
104 t = 48;
105 while (t--)
106 {
107 temp = sig1(w[-2]) + w[-7] + sig0(w[-15]) + w[-16];
108 *(w++) = temp;
109 }
110
111 w = sp->data;
112
113 a = sp->h[0]; b = sp->h[1]; c = sp->h[2]; d = sp->h[3];
114 e = sp->h[4]; f = sp->h[5]; g = sp->h[6]; h = sp->h[7];
115
116 k = SHA2_32BIT_K;
117
118 ROUND(a,b,c,d,e,f,g,h,w[ 0],k[ 0]);
119 ROUND(h,a,b,c,d,e,f,g,w[ 1],k[ 1]);
120 ROUND(g,h,a,b,c,d,e,f,w[ 2],k[ 2]);
121 ROUND(f,g,h,a,b,c,d,e,w[ 3],k[ 3]);
122 ROUND(e,f,g,h,a,b,c,d,w[ 4],k[ 4]);
123 ROUND(d,e,f,g,h,a,b,c,w[ 5],k[ 5]);
124 ROUND(c,d,e,f,g,h,a,b,w[ 6],k[ 6]);
125 ROUND(b,c,d,e,f,g,h,a,w[ 7],k[ 7]);
126 ROUND(a,b,c,d,e,f,g,h,w[ 8],k[ 8]);
127 ROUND(h,a,b,c,d,e,f,g,w[ 9],k[ 9]);
128 ROUND(g,h,a,b,c,d,e,f,w[10],k[10]);
129 ROUND(f,g,h,a,b,c,d,e,w[11],k[11]);
130 ROUND(e,f,g,h,a,b,c,d,w[12],k[12]);
131 ROUND(d,e,f,g,h,a,b,c,w[13],k[13]);
132 ROUND(c,d,e,f,g,h,a,b,w[14],k[14]);
133 ROUND(b,c,d,e,f,g,h,a,w[15],k[15]);
134 ROUND(a,b,c,d,e,f,g,h,w[16],k[16]);
135 ROUND(h,a,b,c,d,e,f,g,w[17],k[17]);
136 ROUND(g,h,a,b,c,d,e,f,w[18],k[18]);
137 ROUND(f,g,h,a,b,c,d,e,w[19],k[19]);
138 ROUND(e,f,g,h,a,b,c,d,w[20],k[20]);
139 ROUND(d,e,f,g,h,a,b,c,w[21],k[21]);
140 ROUND(c,d,e,f,g,h,a,b,w[22],k[22]);
141 ROUND(b,c,d,e,f,g,h,a,w[23],k[23]);
142 ROUND(a,b,c,d,e,f,g,h,w[24],k[24]);
143 ROUND(h,a,b,c,d,e,f,g,w[25],k[25]);
144 ROUND(g,h,a,b,c,d,e,f,w[26],k[26]);
145 ROUND(f,g,h,a,b,c,d,e,w[27],k[27]);
146 ROUND(e,f,g,h,a,b,c,d,w[28],k[28]);
147 ROUND(d,e,f,g,h,a,b,c,w[29],k[29]);
148 ROUND(c,d,e,f,g,h,a,b,w[30],k[30]);
149 ROUND(b,c,d,e,f,g,h,a,w[31],k[31]);
150 ROUND(a,b,c,d,e,f,g,h,w[32],k[32]);
151 ROUND(h,a,b,c,d,e,f,g,w[33],k[33]);
152 ROUND(g,h,a,b,c,d,e,f,w[34],k[34]);
153 ROUND(f,g,h,a,b,c,d,e,w[35],k[35]);
154 ROUND(e,f,g,h,a,b,c,d,w[36],k[36]);
155 ROUND(d,e,f,g,h,a,b,c,w[37],k[37]);
156 ROUND(c,d,e,f,g,h,a,b,w[38],k[38]);
157 ROUND(b,c,d,e,f,g,h,a,w[39],k[39]);
158 ROUND(a,b,c,d,e,f,g,h,w[40],k[40]);
159 ROUND(h,a,b,c,d,e,f,g,w[41],k[41]);
160 ROUND(g,h,a,b,c,d,e,f,w[42],k[42]);
161 ROUND(f,g,h,a,b,c,d,e,w[43],k[43]);
162 ROUND(e,f,g,h,a,b,c,d,w[44],k[44]);
163 ROUND(d,e,f,g,h,a,b,c,w[45],k[45]);
164 ROUND(c,d,e,f,g,h,a,b,w[46],k[46]);
165 ROUND(b,c,d,e,f,g,h,a,w[47],k[47]);
166 ROUND(a,b,c,d,e,f,g,h,w[48],k[48]);
167 ROUND(h,a,b,c,d,e,f,g,w[49],k[49]);
168 ROUND(g,h,a,b,c,d,e,f,w[50],k[50]);
169 ROUND(f,g,h,a,b,c,d,e,w[51],k[51]);
170 ROUND(e,f,g,h,a,b,c,d,w[52],k[52]);
171 ROUND(d,e,f,g,h,a,b,c,w[53],k[53]);
172 ROUND(c,d,e,f,g,h,a,b,w[54],k[54]);
173 ROUND(b,c,d,e,f,g,h,a,w[55],k[55]);
174 ROUND(a,b,c,d,e,f,g,h,w[56],k[56]);
175 ROUND(h,a,b,c,d,e,f,g,w[57],k[57]);
176 ROUND(g,h,a,b,c,d,e,f,w[58],k[58]);
177 ROUND(f,g,h,a,b,c,d,e,w[59],k[59]);
178 ROUND(e,f,g,h,a,b,c,d,w[60],k[60]);
179 ROUND(d,e,f,g,h,a,b,c,w[61],k[61]);
180 ROUND(c,d,e,f,g,h,a,b,w[62],k[62]);
181 ROUND(b,c,d,e,f,g,h,a,w[63],k[63]);
182
183 sp->h[0] += a;
184 sp->h[1] += b;
185 sp->h[2] += c;
186 sp->h[3] += d;
187 sp->h[4] += e;
188 sp->h[5] += f;
189 sp->h[6] += g;
190 sp->h[7] += h;
191 }
192 #endif
193
sha256Update(register sha256Param * sp,const byte * data,size_t size)194 int sha256Update(register sha256Param* sp, const byte* data, size_t size)
195 {
196 register uint32_t proclength;
197
198 #if (MP_WBITS == 64)
199 mpw add[1];
200 mpsetw(1, add, size);
201 mplshift(1, add, 3);
202 mpadd(1, sp->length, add);
203 #elif (MP_WBITS == 32)
204 mpw add[2];
205 mpsetw(2, add, size);
206 mplshift(2, add, 3);
207 mpadd(2, sp->length, add);
208 #else
209 # error
210 #endif
211
212 while (size > 0)
213 {
214 proclength = ((sp->offset + size) > 64U) ? (64U - sp->offset) : size;
215 memcpy(((byte *) sp->data) + sp->offset, data, proclength);
216 size -= proclength;
217 data += proclength;
218 sp->offset += proclength;
219
220 if (sp->offset == 64U)
221 {
222 sha256Process(sp);
223 sp->offset = 0;
224 }
225 }
226 return 0;
227 }
228
sha256Finish(register sha256Param * sp)229 static void sha256Finish(register sha256Param* sp)
230 {
231 register byte *ptr = ((byte *) sp->data) + sp->offset++;
232
233 *(ptr++) = 0x80;
234
235 if (sp->offset > 56)
236 {
237 while (sp->offset++ < 64)
238 *(ptr++) = 0;
239
240 sha256Process(sp);
241 sp->offset = 0;
242 }
243
244 ptr = ((byte *) sp->data) + sp->offset;
245 while (sp->offset++ < 56)
246 *(ptr++) = 0;
247
248 #if (MP_WBITS == 64)
249 ptr[0] = (byte)(sp->length[0] >> 56);
250 ptr[1] = (byte)(sp->length[0] >> 48);
251 ptr[2] = (byte)(sp->length[0] >> 40);
252 ptr[3] = (byte)(sp->length[0] >> 32);
253 ptr[4] = (byte)(sp->length[0] >> 24);
254 ptr[5] = (byte)(sp->length[0] >> 16);
255 ptr[6] = (byte)(sp->length[0] >> 8);
256 ptr[7] = (byte)(sp->length[0] );
257 #elif (MP_WBITS == 32)
258 ptr[0] = (byte)(sp->length[0] >> 24);
259 ptr[1] = (byte)(sp->length[0] >> 16);
260 ptr[2] = (byte)(sp->length[0] >> 8);
261 ptr[3] = (byte)(sp->length[0] );
262 ptr[4] = (byte)(sp->length[1] >> 24);
263 ptr[5] = (byte)(sp->length[1] >> 16);
264 ptr[6] = (byte)(sp->length[1] >> 8);
265 ptr[7] = (byte)(sp->length[1] );
266 #else
267 # error
268 #endif
269
270 sha256Process(sp);
271 sp->offset = 0;
272 }
273
sha256Digest(register sha256Param * sp,byte * data)274 int sha256Digest(register sha256Param* sp, byte* data)
275 {
276 sha256Finish(sp);
277
278 /* encode 8 integers big-endian style */
279 data[ 0] = (byte)(sp->h[0] >> 24);
280 data[ 1] = (byte)(sp->h[0] >> 16);
281 data[ 2] = (byte)(sp->h[0] >> 8);
282 data[ 3] = (byte)(sp->h[0] >> 0);
283 data[ 4] = (byte)(sp->h[1] >> 24);
284 data[ 5] = (byte)(sp->h[1] >> 16);
285 data[ 6] = (byte)(sp->h[1] >> 8);
286 data[ 7] = (byte)(sp->h[1] >> 0);
287 data[ 8] = (byte)(sp->h[2] >> 24);
288 data[ 9] = (byte)(sp->h[2] >> 16);
289 data[10] = (byte)(sp->h[2] >> 8);
290 data[11] = (byte)(sp->h[2] >> 0);
291 data[12] = (byte)(sp->h[3] >> 24);
292 data[13] = (byte)(sp->h[3] >> 16);
293 data[14] = (byte)(sp->h[3] >> 8);
294 data[15] = (byte)(sp->h[3] >> 0);
295 data[16] = (byte)(sp->h[4] >> 24);
296 data[17] = (byte)(sp->h[4] >> 16);
297 data[18] = (byte)(sp->h[4] >> 8);
298 data[19] = (byte)(sp->h[4] >> 0);
299 data[20] = (byte)(sp->h[5] >> 24);
300 data[21] = (byte)(sp->h[5] >> 16);
301 data[22] = (byte)(sp->h[5] >> 8);
302 data[23] = (byte)(sp->h[5] >> 0);
303 data[24] = (byte)(sp->h[6] >> 24);
304 data[25] = (byte)(sp->h[6] >> 16);
305 data[26] = (byte)(sp->h[6] >> 8);
306 data[27] = (byte)(sp->h[6] >> 0);
307 data[28] = (byte)(sp->h[7] >> 24);
308 data[29] = (byte)(sp->h[7] >> 16);
309 data[30] = (byte)(sp->h[7] >> 8);
310 data[31] = (byte)(sp->h[7] >> 0);
311
312 sha256Reset(sp);
313 return 0;
314 }
315
316 /*!\}
317 */
318