"Fossies" - the Fresh Open Source Software Archive 
Member "duff-0.5.2/src/sha384.c" (10 Apr 2011, 13033 Bytes) of package /linux/privat/old/duff-0.5.2.tar.gz:
As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style:
standard) with prefixed line numbers and
code folding option.
Alternatively you can here
view or
download the uninterpreted source code file.
1 /*-
2 * Copyright (c) 2001-2003 Allan Saddi <allan@saddi.com>
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY ALLAN SADDI AND HIS CONTRIBUTORS ``AS IS''
15 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED. IN NO EVENT SHALL ALLAN SADDI OR HIS CONTRIBUTORS BE
18 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
19 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
20 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
21 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
22 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
23 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
24 * POSSIBILITY OF SUCH DAMAGE.
25 *
26 * $Id: sha384.c,v 1.1 2009/01/03 00:01:04 elmindreda Exp $
27 */
28
29 /*
30 * Define WORDS_BIGENDIAN if compiling on a big-endian architecture.
31 *
32 * Define SHA384_TEST to test the implementation using the NIST's
33 * sample messages. The output should be:
34 *
35 * cb00753f45a35e8b b5a03d699ac65007 272c32ab0eded163 1a8b605a43ff5bed
36 * 8086072ba1e7cc23 58baeca134c825a7
37 * 09330c33f71147e8 3d192fc782cd1b47 53111b173b3b05d2 2fa08086e3b0f712
38 * fcc7c71a557e2db9 66c3e9fa91746039
39 * 9d0e1809716474cb 086e834e310a4a1c ed149e9c00f24852 7972cec5704c2a5b
40 * 07b8b3dc38ecc4eb ae97ddd87f3d8985
41 */
42
43 #ifdef HAVE_CONFIG_H
44 #include <config.h>
45 #endif /* HAVE_CONFIG_H */
46
47 #if HAVE_INTTYPES_H
48 # include <inttypes.h>
49 #else
50 # if HAVE_STDINT_H
51 # include <stdint.h>
52 # endif
53 #endif
54
55 #include <string.h>
56
57 #include "sha384.h"
58
59 #ifndef lint
60 static const char rcsid[] =
61 "$Id: sha384.c,v 1.1 2009/01/03 00:01:04 elmindreda Exp $";
62 #endif /* !lint */
63
64 #define ROTL(x, n) (((x) << (n)) | ((x) >> (32 - (n))))
65 #define ROTR(x, n) (((x) >> (n)) | ((x) << (32 - (n))))
66 #define ROTL64(x, n) (((x) << (n)) | ((x) >> (64 - (n))))
67 #define ROTR64(x, n) (((x) >> (n)) | ((x) << (64 - (n))))
68
69 #define Ch(x, y, z) ((z) ^ ((x) & ((y) ^ (z))))
70 #define Maj(x, y, z) (((x) & ((y) | (z))) | ((y) & (z)))
71 #define SIGMA0(x) (ROTR64((x), 28) ^ ROTR64((x), 34) ^ ROTR64((x), 39))
72 #define SIGMA1(x) (ROTR64((x), 14) ^ ROTR64((x), 18) ^ ROTR64((x), 41))
73 #define sigma0(x) (ROTR64((x), 1) ^ ROTR64((x), 8) ^ ((x) >> 7))
74 #define sigma1(x) (ROTR64((x), 19) ^ ROTR64((x), 61) ^ ((x) >> 6))
75
76 #define DO_ROUND() { \
77 t1 = h + SIGMA1(e) + Ch(e, f, g) + *(Kp++) + *(W++); \
78 t2 = SIGMA0(a) + Maj(a, b, c); \
79 h = g; \
80 g = f; \
81 f = e; \
82 e = d + t1; \
83 d = c; \
84 c = b; \
85 b = a; \
86 a = t1 + t2; \
87 }
88
89 static const uint64_t K[80] = {
90 0x428a2f98d728ae22LL, 0x7137449123ef65cdLL,
91 0xb5c0fbcfec4d3b2fLL, 0xe9b5dba58189dbbcLL,
92 0x3956c25bf348b538LL, 0x59f111f1b605d019LL,
93 0x923f82a4af194f9bLL, 0xab1c5ed5da6d8118LL,
94 0xd807aa98a3030242LL, 0x12835b0145706fbeLL,
95 0x243185be4ee4b28cLL, 0x550c7dc3d5ffb4e2LL,
96 0x72be5d74f27b896fLL, 0x80deb1fe3b1696b1LL,
97 0x9bdc06a725c71235LL, 0xc19bf174cf692694LL,
98 0xe49b69c19ef14ad2LL, 0xefbe4786384f25e3LL,
99 0x0fc19dc68b8cd5b5LL, 0x240ca1cc77ac9c65LL,
100 0x2de92c6f592b0275LL, 0x4a7484aa6ea6e483LL,
101 0x5cb0a9dcbd41fbd4LL, 0x76f988da831153b5LL,
102 0x983e5152ee66dfabLL, 0xa831c66d2db43210LL,
103 0xb00327c898fb213fLL, 0xbf597fc7beef0ee4LL,
104 0xc6e00bf33da88fc2LL, 0xd5a79147930aa725LL,
105 0x06ca6351e003826fLL, 0x142929670a0e6e70LL,
106 0x27b70a8546d22ffcLL, 0x2e1b21385c26c926LL,
107 0x4d2c6dfc5ac42aedLL, 0x53380d139d95b3dfLL,
108 0x650a73548baf63deLL, 0x766a0abb3c77b2a8LL,
109 0x81c2c92e47edaee6LL, 0x92722c851482353bLL,
110 0xa2bfe8a14cf10364LL, 0xa81a664bbc423001LL,
111 0xc24b8b70d0f89791LL, 0xc76c51a30654be30LL,
112 0xd192e819d6ef5218LL, 0xd69906245565a910LL,
113 0xf40e35855771202aLL, 0x106aa07032bbd1b8LL,
114 0x19a4c116b8d2d0c8LL, 0x1e376c085141ab53LL,
115 0x2748774cdf8eeb99LL, 0x34b0bcb5e19b48a8LL,
116 0x391c0cb3c5c95a63LL, 0x4ed8aa4ae3418acbLL,
117 0x5b9cca4f7763e373LL, 0x682e6ff3d6b2b8a3LL,
118 0x748f82ee5defb2fcLL, 0x78a5636f43172f60LL,
119 0x84c87814a1f0ab72LL, 0x8cc702081a6439ecLL,
120 0x90befffa23631e28LL, 0xa4506cebde82bde9LL,
121 0xbef9a3f7b2c67915LL, 0xc67178f2e372532bLL,
122 0xca273eceea26619cLL, 0xd186b8c721c0c207LL,
123 0xeada7dd6cde0eb1eLL, 0xf57d4f7fee6ed178LL,
124 0x06f067aa72176fbaLL, 0x0a637dc5a2c898a6LL,
125 0x113f9804bef90daeLL, 0x1b710b35131c471bLL,
126 0x28db77f523047d84LL, 0x32caab7b40c72493LL,
127 0x3c9ebe0a15c9bebcLL, 0x431d67c49c100d4cLL,
128 0x4cc5d4becb3e42b6LL, 0x597f299cfc657e2aLL,
129 0x5fcb6fab3ad6faecLL, 0x6c44198c4a475817LL
130 };
131
132 #ifndef RUNTIME_ENDIAN
133
134 #ifdef WORDS_BIGENDIAN
135
136 #define BYTESWAP(x) (x)
137 #define BYTESWAP64(x) (x)
138
139 #else /* WORDS_BIGENDIAN */
140
141 #define BYTESWAP(x) ((ROTR((x), 8) & 0xff00ff00L) | \
142 (ROTL((x), 8) & 0x00ff00ffL))
143 #define BYTESWAP64(x) _byteswap64(x)
144
145 static inline uint64_t _byteswap64(uint64_t x)
146 {
147 uint32_t a = x >> 32;
148 uint32_t b = (uint32_t) x;
149 return ((uint64_t) BYTESWAP(b) << 32) | (uint64_t) BYTESWAP(a);
150 }
151
152 #endif /* WORDS_BIGENDIAN */
153
154 #else /* !RUNTIME_ENDIAN */
155
156 #define BYTESWAP(x) _byteswap(sc->littleEndian, x)
157 #define BYTESWAP64(x) _byteswap64(sc->littleEndian, x)
158
159 #define _BYTESWAP(x) ((ROTR((x), 8) & 0xff00ff00L) | \
160 (ROTL((x), 8) & 0x00ff00ffL))
161 #define _BYTESWAP64(x) __byteswap64(x)
162
163 static inline uint64_t __byteswap64(uint64_t x)
164 {
165 uint32_t a = x >> 32;
166 uint32_t b = (uint32_t) x;
167 return ((uint64_t) _BYTESWAP(b) << 32) | (uint64_t) _BYTESWAP(a);
168 }
169
170 static inline uint32_t _byteswap(int littleEndian, uint32_t x)
171 {
172 if (!littleEndian)
173 return x;
174 else
175 return _BYTESWAP(x);
176 }
177
178 static inline uint64_t _byteswap64(int littleEndian, uint64_t x)
179 {
180 if (!littleEndian)
181 return x;
182 else
183 return _BYTESWAP64(x);
184 }
185
186 static inline void setEndian(int *littleEndianp)
187 {
188 union {
189 uint32_t w;
190 uint8_t b[4];
191 } endian;
192
193 endian.w = 1L;
194 *littleEndianp = endian.b[0] != 0;
195 }
196
197 #endif /* !RUNTIME_ENDIAN */
198
199 static const uint8_t padding[128] = {
200 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
201 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
202 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
203 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
204 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
205 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
206 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
207 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
208 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
209 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
210 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
211 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
212 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
213 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
214 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
215 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
216 };
217
218 void
219 SHA384Init (SHA384Context *sc)
220 {
221 #ifdef RUNTIME_ENDIAN
222 setEndian (&sc->littleEndian);
223 #endif /* RUNTIME_ENDIAN */
224
225 sc->totalLength[0] = 0LL;
226 sc->totalLength[1] = 0LL;
227 sc->hash[0] = 0xcbbb9d5dc1059ed8LL;
228 sc->hash[1] = 0x629a292a367cd507LL;
229 sc->hash[2] = 0x9159015a3070dd17LL;
230 sc->hash[3] = 0x152fecd8f70e5939LL;
231 sc->hash[4] = 0x67332667ffc00b31LL;
232 sc->hash[5] = 0x8eb44a8768581511LL;
233 sc->hash[6] = 0xdb0c2e0d64f98fa7LL;
234 sc->hash[7] = 0x47b5481dbefa4fa4LL;
235 sc->bufferLength = 0L;
236 }
237
238 static void
239 burnStack (int size)
240 {
241 char buf[128];
242
243 memset (buf, 0, sizeof (buf));
244 size -= sizeof (buf);
245 if (size > 0)
246 burnStack (size);
247 }
248
249 static void
250 SHA384Guts (SHA384Context *sc, const uint64_t *cbuf)
251 {
252 uint64_t buf[80];
253 uint64_t *W, *W2, *W7, *W15, *W16;
254 uint64_t a, b, c, d, e, f, g, h;
255 uint64_t t1, t2;
256 const uint64_t *Kp;
257 int i;
258
259 W = buf;
260
261 for (i = 15; i >= 0; i--) {
262 *(W++) = BYTESWAP64(*cbuf);
263 cbuf++;
264 }
265
266 W16 = &buf[0];
267 W15 = &buf[1];
268 W7 = &buf[9];
269 W2 = &buf[14];
270
271 for (i = 63; i >= 0; i--) {
272 *(W++) = sigma1(*W2) + *(W7++) + sigma0(*W15) + *(W16++);
273 W2++;
274 W15++;
275 }
276
277 a = sc->hash[0];
278 b = sc->hash[1];
279 c = sc->hash[2];
280 d = sc->hash[3];
281 e = sc->hash[4];
282 f = sc->hash[5];
283 g = sc->hash[6];
284 h = sc->hash[7];
285
286 Kp = K;
287 W = buf;
288
289 for (i = 79; i >= 0; i--)
290 DO_ROUND();
291
292 sc->hash[0] += a;
293 sc->hash[1] += b;
294 sc->hash[2] += c;
295 sc->hash[3] += d;
296 sc->hash[4] += e;
297 sc->hash[5] += f;
298 sc->hash[6] += g;
299 sc->hash[7] += h;
300 }
301
302 void
303 SHA384Update (SHA384Context *sc, const void *vdata, uint32_t len)
304 {
305 const uint8_t *data = vdata;
306 uint32_t bufferBytesLeft;
307 uint32_t bytesToCopy;
308 uint64_t carryCheck;
309 int needBurn = 0;
310
311 #ifdef SHA384_FAST_COPY
312 if (sc->bufferLength) {
313 bufferBytesLeft = 128L - sc->bufferLength;
314
315 bytesToCopy = bufferBytesLeft;
316 if (bytesToCopy > len)
317 bytesToCopy = len;
318
319 memcpy (&sc->buffer.bytes[sc->bufferLength], data, bytesToCopy);
320
321 carryCheck = sc->totalLength[1];
322 sc->totalLength[1] += bytesToCopy * 8L;
323 if (sc->totalLength[1] < carryCheck)
324 sc->totalLength[0]++;
325
326 sc->bufferLength += bytesToCopy;
327 data += bytesToCopy;
328 len -= bytesToCopy;
329
330 if (sc->bufferLength == 128L) {
331 SHA384Guts (sc, sc->buffer.words);
332 needBurn = 1;
333 sc->bufferLength = 0L;
334 }
335 }
336
337 while (len > 127) {
338 carryCheck = sc->totalLength[1];
339 sc->totalLength[1] += 1024L;
340 if (sc->totalLength[1] < carryCheck)
341 sc->totalLength[0]++;
342
343 SHA384Guts (sc, data);
344 needBurn = 1;
345
346 data += 128L;
347 len -= 128L;
348 }
349
350 if (len) {
351 memcpy (&sc->buffer.bytes[sc->bufferLength], data, len);
352
353 carryCheck = sc->totalLength[1];
354 sc->totalLength[1] += len * 8L;
355 if (sc->totalLength[1] < carryCheck)
356 sc->totalLength[0]++;
357
358 sc->bufferLength += len;
359 }
360 #else /* SHA384_FAST_COPY */
361 while (len) {
362 bufferBytesLeft = 128L - sc->bufferLength;
363
364 bytesToCopy = bufferBytesLeft;
365 if (bytesToCopy > len)
366 bytesToCopy = len;
367
368 memcpy (&sc->buffer.bytes[sc->bufferLength], data, bytesToCopy);
369
370 carryCheck = sc->totalLength[1];
371 sc->totalLength[1] += bytesToCopy * 8L;
372 if (sc->totalLength[1] < carryCheck)
373 sc->totalLength[0]++;
374
375 sc->bufferLength += bytesToCopy;
376 data += bytesToCopy;
377 len -= bytesToCopy;
378
379 if (sc->bufferLength == 128L) {
380 SHA384Guts (sc, sc->buffer.words);
381 needBurn = 1;
382 sc->bufferLength = 0L;
383 }
384 }
385 #endif /* SHA384_FAST_COPY */
386
387 if (needBurn)
388 burnStack (sizeof (uint64_t[90]) + sizeof (uint64_t *[6]) + sizeof (int));
389 }
390
391 void
392 SHA384Final (SHA384Context *sc, uint8_t hash[SHA384_HASH_SIZE])
393 {
394 uint32_t bytesToPad;
395 uint64_t lengthPad[2];
396 int i;
397
398 bytesToPad = 240L - sc->bufferLength;
399 if (bytesToPad > 128L)
400 bytesToPad -= 128L;
401
402 lengthPad[0] = BYTESWAP64(sc->totalLength[0]);
403 lengthPad[1] = BYTESWAP64(sc->totalLength[1]);
404
405 SHA384Update (sc, padding, bytesToPad);
406 SHA384Update (sc, lengthPad, 16L);
407
408 if (hash) {
409 for (i = 0; i < SHA384_HASH_WORDS; i++) {
410 #ifdef SHA384_FAST_COPY
411 *((uint64_t *) hash) = BYTESWAP64(sc->hash[i]);
412 #else /* SHA384_FAST_COPY */
413 hash[0] = (uint8_t) (sc->hash[i] >> 56);
414 hash[1] = (uint8_t) (sc->hash[i] >> 48);
415 hash[2] = (uint8_t) (sc->hash[i] >> 40);
416 hash[3] = (uint8_t) (sc->hash[i] >> 32);
417 hash[4] = (uint8_t) (sc->hash[i] >> 24);
418 hash[5] = (uint8_t) (sc->hash[i] >> 16);
419 hash[6] = (uint8_t) (sc->hash[i] >> 8);
420 hash[7] = (uint8_t) sc->hash[i];
421 #endif /* SHA384_FAST_COPY */
422 hash += 8;
423 }
424 }
425 }
426
427 #ifdef SHA384_TEST
428
429 #include <stdio.h>
430 #include <stdlib.h>
431 #include <string.h>
432
433 int
434 main (int argc, char *argv[])
435 {
436 SHA384Context foo;
437 uint8_t hash[SHA384_HASH_SIZE];
438 char buf[1000];
439 int i;
440
441 SHA384Init (&foo);
442 SHA384Update (&foo, "abc", 3);
443 SHA384Final (&foo, hash);
444
445 for (i = 0; i < SHA384_HASH_SIZE;) {
446 printf ("%02x", hash[i++]);
447 if (!(i % 8))
448 printf (" ");
449 if (!(i % 32))
450 printf ("\n");
451 }
452 printf ("\n");
453
454 SHA384Init (&foo);
455 SHA384Update (&foo,
456 "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmn"
457 "hijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu",
458 112);
459 SHA384Final (&foo, hash);
460
461 for (i = 0; i < SHA384_HASH_SIZE;) {
462 printf ("%02x", hash[i++]);
463 if (!(i % 8))
464 printf (" ");
465 if (!(i % 32))
466 printf ("\n");
467 }
468 printf ("\n");
469
470 SHA384Init (&foo);
471 memset (buf, 'a', sizeof (buf));
472 for (i = 0; i < 1000; i++)
473 SHA384Update (&foo, buf, sizeof (buf));
474 SHA384Final (&foo, hash);
475
476 for (i = 0; i < SHA384_HASH_SIZE;) {
477 printf ("%02x", hash[i++]);
478 if (!(i % 8))
479 printf (" ");
480 if (!(i % 32))
481 printf ("\n");
482 }
483 printf ("\n");
484
485 exit (0);
486 }
487
488 #endif /* SHA384_TEST */