1 /*
2  * Copyright (c) 2004 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 sha384.c
21  * \brief SHA-384 hash function, as specified by NIST FIPS 180-2.
22  * \author Bob Deblier <bob.deblier@telenet.be>
23  * \ingroup HASH_m HASH_sha384_m
24  */
25 
26 #define BEECRYPT_DLL_EXPORT
27 
28 #if HAVE_CONFIG_H
29 # include "config.h"
30 #endif
31 
32 #ifdef OPTIMIZE_SSE2
33 # include <emmintrin.h>
34 #endif
35 #if HAVE_ENDIAN_H && HAVE_ASM_BYTEORDER_H
36 # include <endian.h>
37 #endif
38 
39 #include "beecrypt/sha384.h"
40 #include "beecrypt/sha2k64.h"
41 #include "beecrypt/endianness.h"
42 
43 /*!\addtogroup HASH_sha384_m
44  * \{
45  */
46 
47 static const uint64_t hinit[8] = {
48 	#if (SIZEOF_UNSIGNED_LONG == 8) || !HAVE_UNSIGNED_LONG_LONG
49 	0xcbbb9d5dc1059ed8UL,
50 	0x629a292a367cd507UL,
51 	0x9159015a3070dd17UL,
52 	0x152fecd8f70e5939UL,
53 	0x67332667ffc00b31UL,
54 	0x8eb44a8768581511UL,
55 	0xdb0c2e0d64f98fa7UL,
56 	0x47b5481dbefa4fa4UL
57 	#else
58 	0xcbbb9d5dc1059ed8ULL,
59 	0x629a292a367cd507ULL,
60 	0x9159015a3070dd17ULL,
61 	0x152fecd8f70e5939ULL,
62 	0x67332667ffc00b31ULL,
63 	0x8eb44a8768581511ULL,
64 	0xdb0c2e0d64f98fa7ULL,
65 	0x47b5481dbefa4fa4ULL
66 	#endif
67 };
68 
69 const hashFunction sha384 = {
70 	.name = "SHA-384",
71 	.paramsize = sizeof(sha384Param),
72 	.blocksize = 128,
73 	.digestsize = 48,
74 	.reset = (hashFunctionReset) sha384Reset,
75 	.update = (hashFunctionUpdate) sha384Update,
76 	.digest = (hashFunctionDigest) sha384Digest
77 };
78 
sha384Reset(register sha384Param * sp)79 int sha384Reset(register sha384Param* sp)
80 {
81 	memcpy(sp->h, hinit, 8 * sizeof(uint64_t));
82 	memset(sp->data, 0, 80 * sizeof(uint64_t));
83 	#if (MP_WBITS == 64)
84 	mpzero(2, sp->length);
85 	#elif (MP_WBITS == 32)
86 	mpzero(4, sp->length);
87 	#else
88 	# error
89 	#endif
90 	sp->offset = 0;
91 	return 0;
92 }
93 
94 #ifdef OPTIMIZE_SSE2
95 
96 # define R(x,s) _mm_srli_si64(x,s)
97 # define S(x,s) _m_pxor(_mm_srli_si64(x,s),_mm_slli_si64(x,64-(s)))
98 # define CH(x,y,z) _m_pxor(_m_pand(x,_m_pxor(y,z)),z)
99 # define MAJ(x,y,z) _m_por(_m_pand(_m_por(x,y),z),_m_pand(x,y))
100 # define SIG0(x) _m_pxor(_m_pxor(S(x,28),S(x,34)),S(x,39))
101 # define SIG1(x) _m_pxor(_m_pxor(S(x,14),S(x,18)),S(x,41))
102 # define sig0(x) _m_pxor(_m_pxor(S(x,1),S(x,8)),R(x,7))
103 # define sig1(x) _m_pxor(_m_pxor(S(x,19),S(x,61)),R(x,6))
104 
105 # define ROUND(a,b,c,d,e,f,g,h,w,k) \
106 	temp = _mm_add_si64(h, _mm_add_si64(_mm_add_si64(SIG1(e), CH(e,f,g)), _mm_add_si64(k, w))); \
107 	h = _mm_add_si64(temp, _mm_add_si64(SIG0(a), MAJ(a,b,c))); \
108 	d = _mm_add_si64(d, temp)
109 
110 #else
111 
112 # define R(x,s) ((x) >> (s))
113 # define S(x,s) ROTR64(x, s)
114 # define CH(x,y,z) ((x&(y^z))^z)
115 # define MAJ(x,y,z) (((x|y)&z)|(x&y))
116 # define SIG0(x) (S(x,28) ^ S(x,34) ^ S(x,39))
117 # define SIG1(x) (S(x,14) ^ S(x,18) ^ S(x,41))
118 # define sig0(x) (S(x,1) ^ S(x,8) ^ R(x,7))
119 # define sig1(x) (S(x,19) ^ S(x,61) ^ R(x,6))
120 
121 # define ROUND(a,b,c,d,e,f,g,h,w,k)	\
122 	temp = h + SIG1(e) + CH(e,f,g) + k + w;	\
123 	h = temp + SIG0(a) + MAJ(a,b,c);	\
124 	d += temp
125 
126 #endif
127 
128 #ifndef ASM_SHA384PROCESS
sha384Process(register sha384Param * sp)129 void sha384Process(register sha384Param* sp)
130 {
131 	#ifdef OPTIMIZE_SSE2
132 
133 	# if defined(_MSC_VER) || defined (__INTEL_COMPILER) || defined(__clang__)
134 	static const __m64 MASK = { 0x00FF00FF00FF00FF };
135 	# elif defined(__GNUC__)
136 	static const __m64 MASK = { 0x00FF00FF, 0x00FF00FF };
137 	# else
138 	#  error
139 	# endif
140 
141 	__m64 a, b, c, d, e, f, g, h, temp;
142 	register       __m64 *w;
143 	register const __m64 *k;
144 	register byte t;
145 
146 	w = (__m64*) sp->data;
147 	t = 16;
148 	while (t--)
149 	{
150 		temp = *w;
151 		*(w++) = _m_pxor(
152 				_mm_slli_si64(_m_pshufw(_m_pand(temp, MASK), 27), 8),
153 				_m_pshufw(_m_pand(_mm_srli_si64(temp, 8), MASK), 27)
154 			);
155 	}
156 
157 	t = 64;
158 	while (t--)
159 	{
160 		temp = _mm_add_si64(_mm_add_si64(sig1(w[-2]), w[-7]), _mm_add_si64(sig0(w[-15]), w[-16]));
161 		*(w++) = temp;
162 	}
163 
164 	w = (__m64*) sp->h;
165 
166 	a = w[0]; b = w[1]; c = w[2]; d = w[3];
167 	e = w[4]; f = w[5]; g = w[6]; h = w[7];
168 
169 	w = (__m64*) sp->data;
170 	k = (__m64*) SHA2_64BIT_K;
171 
172 	#else
173 
174 	register uint64_t a, b, c, d, e, f, g, h, temp;
175 	register       uint64_t *w;
176 	register const uint64_t *k;
177 	register byte t;
178 
179 	# if WORDS_BIGENDIAN
180 	w = sp->data + 16;
181 	# else
182 	w = sp->data;
183 	t = 16;
184 	while (t--)
185 	{
186 		temp = swapu64(*w);
187 		*(w++) = temp;
188 	}
189 	# endif
190 
191 	t = 64;
192 	while (t--)
193 	{
194 		temp = sig1(w[-2]) + w[-7] + sig0(w[-15]) + w[-16];
195 		*(w++) = temp;
196 	}
197 
198 	w = sp->data;
199 
200 	a = sp->h[0]; b = sp->h[1]; c = sp->h[2]; d = sp->h[3];
201 	e = sp->h[4]; f = sp->h[5]; g = sp->h[6]; h = sp->h[7];
202 
203 	k = SHA2_64BIT_K;
204 	#endif
205 
206 	ROUND(a,b,c,d,e,f,g,h,w[ 0],k[ 0]);
207 	ROUND(h,a,b,c,d,e,f,g,w[ 1],k[ 1]);
208 	ROUND(g,h,a,b,c,d,e,f,w[ 2],k[ 2]);
209 	ROUND(f,g,h,a,b,c,d,e,w[ 3],k[ 3]);
210 	ROUND(e,f,g,h,a,b,c,d,w[ 4],k[ 4]);
211 	ROUND(d,e,f,g,h,a,b,c,w[ 5],k[ 5]);
212 	ROUND(c,d,e,f,g,h,a,b,w[ 6],k[ 6]);
213 	ROUND(b,c,d,e,f,g,h,a,w[ 7],k[ 7]);
214 	ROUND(a,b,c,d,e,f,g,h,w[ 8],k[ 8]);
215 	ROUND(h,a,b,c,d,e,f,g,w[ 9],k[ 9]);
216 	ROUND(g,h,a,b,c,d,e,f,w[10],k[10]);
217 	ROUND(f,g,h,a,b,c,d,e,w[11],k[11]);
218 	ROUND(e,f,g,h,a,b,c,d,w[12],k[12]);
219 	ROUND(d,e,f,g,h,a,b,c,w[13],k[13]);
220 	ROUND(c,d,e,f,g,h,a,b,w[14],k[14]);
221 	ROUND(b,c,d,e,f,g,h,a,w[15],k[15]);
222 	ROUND(a,b,c,d,e,f,g,h,w[16],k[16]);
223 	ROUND(h,a,b,c,d,e,f,g,w[17],k[17]);
224 	ROUND(g,h,a,b,c,d,e,f,w[18],k[18]);
225 	ROUND(f,g,h,a,b,c,d,e,w[19],k[19]);
226 	ROUND(e,f,g,h,a,b,c,d,w[20],k[20]);
227 	ROUND(d,e,f,g,h,a,b,c,w[21],k[21]);
228 	ROUND(c,d,e,f,g,h,a,b,w[22],k[22]);
229 	ROUND(b,c,d,e,f,g,h,a,w[23],k[23]);
230 	ROUND(a,b,c,d,e,f,g,h,w[24],k[24]);
231 	ROUND(h,a,b,c,d,e,f,g,w[25],k[25]);
232 	ROUND(g,h,a,b,c,d,e,f,w[26],k[26]);
233 	ROUND(f,g,h,a,b,c,d,e,w[27],k[27]);
234 	ROUND(e,f,g,h,a,b,c,d,w[28],k[28]);
235 	ROUND(d,e,f,g,h,a,b,c,w[29],k[29]);
236 	ROUND(c,d,e,f,g,h,a,b,w[30],k[30]);
237 	ROUND(b,c,d,e,f,g,h,a,w[31],k[31]);
238 	ROUND(a,b,c,d,e,f,g,h,w[32],k[32]);
239 	ROUND(h,a,b,c,d,e,f,g,w[33],k[33]);
240 	ROUND(g,h,a,b,c,d,e,f,w[34],k[34]);
241 	ROUND(f,g,h,a,b,c,d,e,w[35],k[35]);
242 	ROUND(e,f,g,h,a,b,c,d,w[36],k[36]);
243 	ROUND(d,e,f,g,h,a,b,c,w[37],k[37]);
244 	ROUND(c,d,e,f,g,h,a,b,w[38],k[38]);
245 	ROUND(b,c,d,e,f,g,h,a,w[39],k[39]);
246 	ROUND(a,b,c,d,e,f,g,h,w[40],k[40]);
247 	ROUND(h,a,b,c,d,e,f,g,w[41],k[41]);
248 	ROUND(g,h,a,b,c,d,e,f,w[42],k[42]);
249 	ROUND(f,g,h,a,b,c,d,e,w[43],k[43]);
250 	ROUND(e,f,g,h,a,b,c,d,w[44],k[44]);
251 	ROUND(d,e,f,g,h,a,b,c,w[45],k[45]);
252 	ROUND(c,d,e,f,g,h,a,b,w[46],k[46]);
253 	ROUND(b,c,d,e,f,g,h,a,w[47],k[47]);
254 	ROUND(a,b,c,d,e,f,g,h,w[48],k[48]);
255 	ROUND(h,a,b,c,d,e,f,g,w[49],k[49]);
256 	ROUND(g,h,a,b,c,d,e,f,w[50],k[50]);
257 	ROUND(f,g,h,a,b,c,d,e,w[51],k[51]);
258 	ROUND(e,f,g,h,a,b,c,d,w[52],k[52]);
259 	ROUND(d,e,f,g,h,a,b,c,w[53],k[53]);
260 	ROUND(c,d,e,f,g,h,a,b,w[54],k[54]);
261 	ROUND(b,c,d,e,f,g,h,a,w[55],k[55]);
262 	ROUND(a,b,c,d,e,f,g,h,w[56],k[56]);
263 	ROUND(h,a,b,c,d,e,f,g,w[57],k[57]);
264 	ROUND(g,h,a,b,c,d,e,f,w[58],k[58]);
265 	ROUND(f,g,h,a,b,c,d,e,w[59],k[59]);
266 	ROUND(e,f,g,h,a,b,c,d,w[60],k[60]);
267 	ROUND(d,e,f,g,h,a,b,c,w[61],k[61]);
268 	ROUND(c,d,e,f,g,h,a,b,w[62],k[62]);
269 	ROUND(b,c,d,e,f,g,h,a,w[63],k[63]);
270 	ROUND(a,b,c,d,e,f,g,h,w[64],k[64]);
271 	ROUND(h,a,b,c,d,e,f,g,w[65],k[65]);
272 	ROUND(g,h,a,b,c,d,e,f,w[66],k[66]);
273 	ROUND(f,g,h,a,b,c,d,e,w[67],k[67]);
274 	ROUND(e,f,g,h,a,b,c,d,w[68],k[68]);
275 	ROUND(d,e,f,g,h,a,b,c,w[69],k[69]);
276 	ROUND(c,d,e,f,g,h,a,b,w[70],k[70]);
277 	ROUND(b,c,d,e,f,g,h,a,w[71],k[71]);
278 	ROUND(a,b,c,d,e,f,g,h,w[72],k[72]);
279 	ROUND(h,a,b,c,d,e,f,g,w[73],k[73]);
280 	ROUND(g,h,a,b,c,d,e,f,w[74],k[74]);
281 	ROUND(f,g,h,a,b,c,d,e,w[75],k[75]);
282 	ROUND(e,f,g,h,a,b,c,d,w[76],k[76]);
283 	ROUND(d,e,f,g,h,a,b,c,w[77],k[77]);
284 	ROUND(c,d,e,f,g,h,a,b,w[78],k[78]);
285 	ROUND(b,c,d,e,f,g,h,a,w[79],k[79]);
286 
287 	#ifdef OPTIMIZE_SSE2
288 	w = (__m64*) sp->h;
289 	w[0] = _mm_add_si64(w[0], a);
290 	w[1] = _mm_add_si64(w[1], b);
291 	w[2] = _mm_add_si64(w[2], c);
292 	w[3] = _mm_add_si64(w[3], d);
293 	w[4] = _mm_add_si64(w[4], e);
294 	w[5] = _mm_add_si64(w[5], f);
295 	w[6] = _mm_add_si64(w[6], g);
296 	w[7] = _mm_add_si64(w[7], h);
297 	_mm_empty();
298 	#else
299 	sp->h[0] += a;
300 	sp->h[1] += b;
301 	sp->h[2] += c;
302 	sp->h[3] += d;
303 	sp->h[4] += e;
304 	sp->h[5] += f;
305 	sp->h[6] += g;
306 	sp->h[7] += h;
307 	#endif
308 }
309 #endif
310 
sha384Update(register sha384Param * sp,const byte * data,size_t size)311 int sha384Update(register sha384Param* sp, const byte* data, size_t size)
312 {
313 	register size_t proclength;
314 
315 	#if (MP_WBITS == 64)
316 	mpw add[2];
317 	mpsetw(2, add, size);
318 	mplshift(2, add, 3);
319 	mpadd(2, sp->length, add);
320 	#elif (MP_WBITS == 32)
321 	mpw add[4];
322 	mpsetws(4, add, size);
323 	mplshift(4, add, 3);
324 	mpadd(4, sp->length, add);
325 	#else
326 	# error
327 	#endif
328 
329 	while (size > 0)
330 	{
331 		proclength = ((sp->offset + size) > 128U) ? (128U - sp->offset) : size;
332 		memcpy(((byte *) sp->data) + sp->offset, data, proclength);
333 		size -= proclength;
334 		data += proclength;
335 		sp->offset += proclength;
336 
337 		if (sp->offset == 128U)
338 		{
339 			sha384Process(sp);
340 			sp->offset = 0;
341 		}
342 	}
343 	return 0;
344 }
345 
sha384Finish(register sha384Param * sp)346 static void sha384Finish(register sha384Param* sp)
347 {
348 	register byte *ptr = ((byte *) sp->data) + sp->offset++;
349 
350 	*(ptr++) = 0x80;
351 
352 	if (sp->offset > 112)
353 	{
354 		while (sp->offset++ < 128)
355 			*(ptr++) = 0;
356 
357 		sha384Process(sp);
358 		sp->offset = 0;
359 	}
360 
361 	ptr = ((byte *) sp->data) + sp->offset;
362 	while (sp->offset++ < 112)
363 		*(ptr++) = 0;
364 
365 	#if (MP_WBITS == 64)
366 	ptr[ 0] = (byte)(sp->length[0] >> 56);
367 	ptr[ 1] = (byte)(sp->length[0] >> 48);
368 	ptr[ 2] = (byte)(sp->length[0] >> 40);
369 	ptr[ 3] = (byte)(sp->length[0] >> 32);
370 	ptr[ 4] = (byte)(sp->length[0] >> 24);
371 	ptr[ 5] = (byte)(sp->length[0] >> 16);
372 	ptr[ 6] = (byte)(sp->length[0] >>  8);
373 	ptr[ 7] = (byte)(sp->length[0]      );
374 	ptr[ 8] = (byte)(sp->length[1] >> 56);
375 	ptr[ 9] = (byte)(sp->length[1] >> 48);
376 	ptr[10] = (byte)(sp->length[1] >> 40);
377 	ptr[11] = (byte)(sp->length[1] >> 32);
378 	ptr[12] = (byte)(sp->length[1] >> 24);
379 	ptr[13] = (byte)(sp->length[1] >> 16);
380 	ptr[14] = (byte)(sp->length[1] >>  8);
381 	ptr[15] = (byte)(sp->length[1]      );
382 	#elif (MP_WBITS == 32)
383 	ptr[ 0] = (byte)(sp->length[0] >> 24);
384 	ptr[ 1] = (byte)(sp->length[0] >> 16);
385 	ptr[ 2] = (byte)(sp->length[0] >>  8);
386 	ptr[ 3] = (byte)(sp->length[0]      );
387 	ptr[ 4] = (byte)(sp->length[1] >> 24);
388 	ptr[ 5] = (byte)(sp->length[1] >> 16);
389 	ptr[ 6] = (byte)(sp->length[1] >>  8);
390 	ptr[ 7] = (byte)(sp->length[1]      );
391 	ptr[ 8] = (byte)(sp->length[2] >> 24);
392 	ptr[ 9] = (byte)(sp->length[2] >> 16);
393 	ptr[10] = (byte)(sp->length[2] >>  8);
394 	ptr[11] = (byte)(sp->length[2]      );
395 	ptr[12] = (byte)(sp->length[3] >> 24);
396 	ptr[13] = (byte)(sp->length[3] >> 16);
397 	ptr[14] = (byte)(sp->length[3] >>  8);
398 	ptr[15] = (byte)(sp->length[3]      );
399 	#else
400 	# error
401 	#endif
402 
403 	sha384Process(sp);
404 	sp->offset = 0;
405 }
406 
sha384Digest(register sha384Param * sp,byte * data)407 int sha384Digest(register sha384Param* sp, byte* data)
408 {
409 	sha384Finish(sp);
410 
411 	/* encode 8 integers big-endian style */
412 	data[ 0] = (byte)(sp->h[0] >> 56);
413 	data[ 1] = (byte)(sp->h[0] >> 48);
414 	data[ 2] = (byte)(sp->h[0] >> 40);
415 	data[ 3] = (byte)(sp->h[0] >> 32);
416 	data[ 4] = (byte)(sp->h[0] >> 24);
417 	data[ 5] = (byte)(sp->h[0] >> 16);
418 	data[ 6] = (byte)(sp->h[0] >>  8);
419 	data[ 7] = (byte)(sp->h[0] >>  0);
420 
421 	data[ 8] = (byte)(sp->h[1] >> 56);
422 	data[ 9] = (byte)(sp->h[1] >> 48);
423 	data[10] = (byte)(sp->h[1] >> 40);
424 	data[11] = (byte)(sp->h[1] >> 32);
425 	data[12] = (byte)(sp->h[1] >> 24);
426 	data[13] = (byte)(sp->h[1] >> 16);
427 	data[14] = (byte)(sp->h[1] >>  8);
428 	data[15] = (byte)(sp->h[1] >>  0);
429 
430 	data[16] = (byte)(sp->h[2] >> 56);
431 	data[17] = (byte)(sp->h[2] >> 48);
432 	data[18] = (byte)(sp->h[2] >> 40);
433 	data[19] = (byte)(sp->h[2] >> 32);
434 	data[20] = (byte)(sp->h[2] >> 24);
435 	data[21] = (byte)(sp->h[2] >> 16);
436 	data[22] = (byte)(sp->h[2] >>  8);
437 	data[23] = (byte)(sp->h[2] >>  0);
438 
439 	data[24] = (byte)(sp->h[3] >> 56);
440 	data[25] = (byte)(sp->h[3] >> 48);
441 	data[26] = (byte)(sp->h[3] >> 40);
442 	data[27] = (byte)(sp->h[3] >> 32);
443 	data[28] = (byte)(sp->h[3] >> 24);
444 	data[29] = (byte)(sp->h[3] >> 16);
445 	data[30] = (byte)(sp->h[3] >>  8);
446 	data[31] = (byte)(sp->h[3] >>  0);
447 
448 	data[32] = (byte)(sp->h[4] >> 56);
449 	data[33] = (byte)(sp->h[4] >> 48);
450 	data[34] = (byte)(sp->h[4] >> 40);
451 	data[35] = (byte)(sp->h[4] >> 32);
452 	data[36] = (byte)(sp->h[4] >> 24);
453 	data[37] = (byte)(sp->h[4] >> 16);
454 	data[38] = (byte)(sp->h[4] >>  8);
455 	data[39] = (byte)(sp->h[4] >>  0);
456 
457 	data[40] = (byte)(sp->h[5] >> 56);
458 	data[41] = (byte)(sp->h[5] >> 48);
459 	data[42] = (byte)(sp->h[5] >> 40);
460 	data[43] = (byte)(sp->h[5] >> 32);
461 	data[44] = (byte)(sp->h[5] >> 24);
462 	data[45] = (byte)(sp->h[5] >> 16);
463 	data[46] = (byte)(sp->h[5] >>  8);
464 	data[47] = (byte)(sp->h[5] >>  0);
465 
466 	sha384Reset(sp);
467 	return 0;
468 }
469 
470 /*!\}
471  */
472