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