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