- add sources.
[platform/framework/web/crosswalk.git] / src / crypto / third_party / nss / sha512.cc
1 /*
2  * sha512.c - implementation of SHA256, SHA384 and SHA512
3  *
4  * ***** BEGIN LICENSE BLOCK *****
5  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
6  *
7  * The contents of this file are subject to the Mozilla Public License Version
8  * 1.1 (the "License"); you may not use this file except in compliance with
9  * the License. You may obtain a copy of the License at
10  * http://www.mozilla.org/MPL/
11  *
12  * Software distributed under the License is distributed on an "AS IS" basis,
13  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
14  * for the specific language governing rights and limitations under the
15  * License.
16  *
17  * The Original Code is the Netscape security libraries.
18  *
19  * The Initial Developer of the Original Code is
20  * Netscape Communications Corporation.
21  * Portions created by the Initial Developer are Copyright (C) 2002
22  * the Initial Developer. All Rights Reserved.
23  *
24  * Contributor(s):
25  *
26  * Alternatively, the contents of this file may be used under the terms of
27  * either the GNU General Public License Version 2 or later (the "GPL"), or
28  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
29  * in which case the provisions of the GPL or the LGPL are applicable instead
30  * of those above. If you wish to allow use of your version of this file only
31  * under the terms of either the GPL or the LGPL, and not to allow others to
32  * use your version of this file under the terms of the MPL, indicate your
33  * decision by deleting the provisions above and replace them with the notice
34  * and other provisions required by the GPL or the LGPL. If you do not delete
35  * the provisions above, a recipient may use your version of this file under
36  * the terms of any one of the MPL, the GPL or the LGPL.
37  *
38  * ***** END LICENSE BLOCK ***** */
39 /* $Id: sha512.c,v 1.9 2006/10/13 16:54:04 wtchang%redhat.com Exp $ */
40
41 // Prevent manual unrolling in the sha256 code, which reduces the binary code
42 // size from ~10k to ~1k.  The performance should be reasonable for our use.
43 #define NOUNROLL256 1
44
45 #include "base/third_party/nspr/prtypes.h"  /* for PRUintXX */
46 #if defined(_X86_) || defined(SHA_NO_LONG_LONG)
47 #define NOUNROLL512 1
48 #undef HAVE_LONG_LONG
49 #endif
50 #include "crypto/third_party/nss/chromium-blapi.h"
51 #include "crypto/third_party/nss/chromium-sha256.h"    /* for struct SHA256ContextStr */
52
53 #include <stdlib.h>
54 #include <string.h>
55 #define PORT_New(type) static_cast<type*>(malloc(sizeof(type)))
56 #define PORT_ZFree(ptr, len) do { memset(ptr, 0, len); free(ptr); } while (0)
57 #define PORT_Strlen(s) static_cast<unsigned int>(strlen(s))
58 #define PORT_Memcpy memcpy
59
60 /* ============= Common constants and defines ======================= */
61
62 #define W ctx->u.w
63 #define B ctx->u.b
64 #define H ctx->h
65
66 #define SHR(x,n) (x >> n)
67 #define SHL(x,n) (x << n)
68 #define Ch(x,y,z)  ((x & y) ^ (~x & z))
69 #define Maj(x,y,z) ((x & y) ^ (x & z) ^ (y & z))
70
71 /* Padding used with all flavors of SHA */
72 static const PRUint8 pad[240] = {
73 0x80,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
74    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
75    /* compiler will fill the rest in with zeros */
76 };
77
78 /* ============= SHA256 implemenmtation ================================== */
79
80 /* SHA-256 constants, K256. */
81 static const PRUint32 K256[64] = {
82     0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5,
83     0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
84     0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
85     0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
86     0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc,
87     0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
88     0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7,
89     0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
90     0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
91     0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
92     0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3,
93     0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
94     0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5,
95     0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
96     0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
97     0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
98 };
99
100 /* SHA-256 initial hash values */
101 static const PRUint32 H256[8] = {
102     0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a,
103     0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19
104 };
105
106 #if defined(_MSC_VER) && defined(_X86_)
107 #ifndef FORCEINLINE
108 #if (_MSC_VER >= 1200)
109 #define FORCEINLINE __forceinline
110 #else
111 #define FORCEINLINE __inline
112 #endif
113 #endif
114 #define FASTCALL __fastcall
115
116 static FORCEINLINE PRUint32 FASTCALL
117 swap4b(PRUint32 dwd)
118 {
119     __asm {
120         mov   eax,dwd
121         bswap eax
122     }
123 }
124
125 #define SHA_HTONL(x) swap4b(x)
126 #define BYTESWAP4(x)  x = SHA_HTONL(x)
127
128 #elif defined(LINUX) && defined(_X86_)
129 #undef  __OPTIMIZE__
130 #define __OPTIMIZE__ 1
131 #undef  __pentium__
132 #define __pentium__ 1
133 #include <byteswap.h>
134 #define SHA_HTONL(x) bswap_32(x)
135 #define BYTESWAP4(x)  x = SHA_HTONL(x)
136
137 #else /* neither windows nor Linux PC */
138 #define SWAP4MASK  0x00FF00FF
139 #define SHA_HTONL(x) (t1 = (x), t1 = (t1 << 16) | (t1 >> 16), \
140                       ((t1 & SWAP4MASK) << 8) | ((t1 >> 8) & SWAP4MASK))
141 #define BYTESWAP4(x)  x = SHA_HTONL(x)
142 #endif
143
144 #if defined(_MSC_VER) && defined(_X86_)
145 #pragma intrinsic (_lrotr, _lrotl)
146 #define ROTR32(x,n) _lrotr(x,n)
147 #define ROTL32(x,n) _lrotl(x,n)
148 #else
149 #define ROTR32(x,n) ((x >> n) | (x << ((8 * sizeof x) - n)))
150 #define ROTL32(x,n) ((x << n) | (x >> ((8 * sizeof x) - n)))
151 #endif
152
153 /* Capitol Sigma and lower case sigma functions */
154 #define S0(x) (ROTR32(x, 2) ^ ROTR32(x,13) ^ ROTR32(x,22))
155 #define S1(x) (ROTR32(x, 6) ^ ROTR32(x,11) ^ ROTR32(x,25))
156 #define s0(x) (t1 = x, ROTR32(t1, 7) ^ ROTR32(t1,18) ^ SHR(t1, 3))
157 #define s1(x) (t2 = x, ROTR32(t2,17) ^ ROTR32(t2,19) ^ SHR(t2,10))
158
159 SHA256Context *
160 SHA256_NewContext(void)
161 {
162     SHA256Context *ctx = PORT_New(SHA256Context);
163     return ctx;
164 }
165
166 void
167 SHA256_DestroyContext(SHA256Context *ctx, PRBool freeit)
168 {
169     if (freeit) {
170         PORT_ZFree(ctx, sizeof *ctx);
171     }
172 }
173
174 void
175 SHA256_Begin(SHA256Context *ctx)
176 {
177     memset(ctx, 0, sizeof *ctx);
178     memcpy(H, H256, sizeof H256);
179 }
180
181 static void
182 SHA256_Compress(SHA256Context *ctx)
183 {
184   {
185     register PRUint32 t1, t2;
186
187 #if defined(IS_LITTLE_ENDIAN)
188     BYTESWAP4(W[0]);
189     BYTESWAP4(W[1]);
190     BYTESWAP4(W[2]);
191     BYTESWAP4(W[3]);
192     BYTESWAP4(W[4]);
193     BYTESWAP4(W[5]);
194     BYTESWAP4(W[6]);
195     BYTESWAP4(W[7]);
196     BYTESWAP4(W[8]);
197     BYTESWAP4(W[9]);
198     BYTESWAP4(W[10]);
199     BYTESWAP4(W[11]);
200     BYTESWAP4(W[12]);
201     BYTESWAP4(W[13]);
202     BYTESWAP4(W[14]);
203     BYTESWAP4(W[15]);
204 #endif
205
206 #define INITW(t) W[t] = (s1(W[t-2]) + W[t-7] + s0(W[t-15]) + W[t-16])
207
208     /* prepare the "message schedule"   */
209 #ifdef NOUNROLL256
210     {
211         int t;
212         for (t = 16; t < 64; ++t) {
213             INITW(t);
214         }
215     }
216 #else
217     INITW(16);
218     INITW(17);
219     INITW(18);
220     INITW(19);
221
222     INITW(20);
223     INITW(21);
224     INITW(22);
225     INITW(23);
226     INITW(24);
227     INITW(25);
228     INITW(26);
229     INITW(27);
230     INITW(28);
231     INITW(29);
232
233     INITW(30);
234     INITW(31);
235     INITW(32);
236     INITW(33);
237     INITW(34);
238     INITW(35);
239     INITW(36);
240     INITW(37);
241     INITW(38);
242     INITW(39);
243
244     INITW(40);
245     INITW(41);
246     INITW(42);
247     INITW(43);
248     INITW(44);
249     INITW(45);
250     INITW(46);
251     INITW(47);
252     INITW(48);
253     INITW(49);
254
255     INITW(50);
256     INITW(51);
257     INITW(52);
258     INITW(53);
259     INITW(54);
260     INITW(55);
261     INITW(56);
262     INITW(57);
263     INITW(58);
264     INITW(59);
265
266     INITW(60);
267     INITW(61);
268     INITW(62);
269     INITW(63);
270
271 #endif
272 #undef INITW
273   }
274   {
275     PRUint32 a, b, c, d, e, f, g, h;
276
277     a = H[0];
278     b = H[1];
279     c = H[2];
280     d = H[3];
281     e = H[4];
282     f = H[5];
283     g = H[6];
284     h = H[7];
285
286 #define ROUND(n,a,b,c,d,e,f,g,h) \
287     h += S1(e) + Ch(e,f,g) + K256[n] + W[n]; \
288     d += h; \
289     h += S0(a) + Maj(a,b,c);
290
291 #ifdef NOUNROLL256
292     {
293         int t;
294         for (t = 0; t < 64; t+= 8) {
295             ROUND(t+0,a,b,c,d,e,f,g,h)
296             ROUND(t+1,h,a,b,c,d,e,f,g)
297             ROUND(t+2,g,h,a,b,c,d,e,f)
298             ROUND(t+3,f,g,h,a,b,c,d,e)
299             ROUND(t+4,e,f,g,h,a,b,c,d)
300             ROUND(t+5,d,e,f,g,h,a,b,c)
301             ROUND(t+6,c,d,e,f,g,h,a,b)
302             ROUND(t+7,b,c,d,e,f,g,h,a)
303         }
304     }
305 #else
306     ROUND( 0,a,b,c,d,e,f,g,h)
307     ROUND( 1,h,a,b,c,d,e,f,g)
308     ROUND( 2,g,h,a,b,c,d,e,f)
309     ROUND( 3,f,g,h,a,b,c,d,e)
310     ROUND( 4,e,f,g,h,a,b,c,d)
311     ROUND( 5,d,e,f,g,h,a,b,c)
312     ROUND( 6,c,d,e,f,g,h,a,b)
313     ROUND( 7,b,c,d,e,f,g,h,a)
314
315     ROUND( 8,a,b,c,d,e,f,g,h)
316     ROUND( 9,h,a,b,c,d,e,f,g)
317     ROUND(10,g,h,a,b,c,d,e,f)
318     ROUND(11,f,g,h,a,b,c,d,e)
319     ROUND(12,e,f,g,h,a,b,c,d)
320     ROUND(13,d,e,f,g,h,a,b,c)
321     ROUND(14,c,d,e,f,g,h,a,b)
322     ROUND(15,b,c,d,e,f,g,h,a)
323
324     ROUND(16,a,b,c,d,e,f,g,h)
325     ROUND(17,h,a,b,c,d,e,f,g)
326     ROUND(18,g,h,a,b,c,d,e,f)
327     ROUND(19,f,g,h,a,b,c,d,e)
328     ROUND(20,e,f,g,h,a,b,c,d)
329     ROUND(21,d,e,f,g,h,a,b,c)
330     ROUND(22,c,d,e,f,g,h,a,b)
331     ROUND(23,b,c,d,e,f,g,h,a)
332
333     ROUND(24,a,b,c,d,e,f,g,h)
334     ROUND(25,h,a,b,c,d,e,f,g)
335     ROUND(26,g,h,a,b,c,d,e,f)
336     ROUND(27,f,g,h,a,b,c,d,e)
337     ROUND(28,e,f,g,h,a,b,c,d)
338     ROUND(29,d,e,f,g,h,a,b,c)
339     ROUND(30,c,d,e,f,g,h,a,b)
340     ROUND(31,b,c,d,e,f,g,h,a)
341
342     ROUND(32,a,b,c,d,e,f,g,h)
343     ROUND(33,h,a,b,c,d,e,f,g)
344     ROUND(34,g,h,a,b,c,d,e,f)
345     ROUND(35,f,g,h,a,b,c,d,e)
346     ROUND(36,e,f,g,h,a,b,c,d)
347     ROUND(37,d,e,f,g,h,a,b,c)
348     ROUND(38,c,d,e,f,g,h,a,b)
349     ROUND(39,b,c,d,e,f,g,h,a)
350
351     ROUND(40,a,b,c,d,e,f,g,h)
352     ROUND(41,h,a,b,c,d,e,f,g)
353     ROUND(42,g,h,a,b,c,d,e,f)
354     ROUND(43,f,g,h,a,b,c,d,e)
355     ROUND(44,e,f,g,h,a,b,c,d)
356     ROUND(45,d,e,f,g,h,a,b,c)
357     ROUND(46,c,d,e,f,g,h,a,b)
358     ROUND(47,b,c,d,e,f,g,h,a)
359
360     ROUND(48,a,b,c,d,e,f,g,h)
361     ROUND(49,h,a,b,c,d,e,f,g)
362     ROUND(50,g,h,a,b,c,d,e,f)
363     ROUND(51,f,g,h,a,b,c,d,e)
364     ROUND(52,e,f,g,h,a,b,c,d)
365     ROUND(53,d,e,f,g,h,a,b,c)
366     ROUND(54,c,d,e,f,g,h,a,b)
367     ROUND(55,b,c,d,e,f,g,h,a)
368
369     ROUND(56,a,b,c,d,e,f,g,h)
370     ROUND(57,h,a,b,c,d,e,f,g)
371     ROUND(58,g,h,a,b,c,d,e,f)
372     ROUND(59,f,g,h,a,b,c,d,e)
373     ROUND(60,e,f,g,h,a,b,c,d)
374     ROUND(61,d,e,f,g,h,a,b,c)
375     ROUND(62,c,d,e,f,g,h,a,b)
376     ROUND(63,b,c,d,e,f,g,h,a)
377 #endif
378
379     H[0] += a;
380     H[1] += b;
381     H[2] += c;
382     H[3] += d;
383     H[4] += e;
384     H[5] += f;
385     H[6] += g;
386     H[7] += h;
387   }
388 #undef ROUND
389 }
390
391 #undef s0
392 #undef s1
393 #undef S0
394 #undef S1
395
396 void
397 SHA256_Update(SHA256Context *ctx, const unsigned char *input,
398                     unsigned int inputLen)
399 {
400     unsigned int inBuf = ctx->sizeLo & 0x3f;
401     if (!inputLen)
402         return;
403
404     /* Add inputLen into the count of bytes processed, before processing */
405     if ((ctx->sizeLo += inputLen) < inputLen)
406         ctx->sizeHi++;
407
408     /* if data already in buffer, attemp to fill rest of buffer */
409     if (inBuf) {
410         unsigned int todo = SHA256_BLOCK_LENGTH - inBuf;
411         if (inputLen < todo)
412             todo = inputLen;
413         memcpy(B + inBuf, input, todo);
414         input    += todo;
415         inputLen -= todo;
416         if (inBuf + todo == SHA256_BLOCK_LENGTH)
417             SHA256_Compress(ctx);
418     }
419
420     /* if enough data to fill one or more whole buffers, process them. */
421     while (inputLen >= SHA256_BLOCK_LENGTH) {
422         memcpy(B, input, SHA256_BLOCK_LENGTH);
423         input    += SHA256_BLOCK_LENGTH;
424         inputLen -= SHA256_BLOCK_LENGTH;
425         SHA256_Compress(ctx);
426     }
427     /* if data left over, fill it into buffer */
428     if (inputLen)
429         memcpy(B, input, inputLen);
430 }
431
432 void
433 SHA256_End(SHA256Context *ctx, unsigned char *digest,
434            unsigned int *digestLen, unsigned int maxDigestLen)
435 {
436     unsigned int inBuf = ctx->sizeLo & 0x3f;
437     unsigned int padLen = (inBuf < 56) ? (56 - inBuf) : (56 + 64 - inBuf);
438     PRUint32 hi, lo;
439 #ifdef SWAP4MASK
440     PRUint32 t1;
441 #endif
442
443     hi = (ctx->sizeHi << 3) | (ctx->sizeLo >> 29);
444     lo = (ctx->sizeLo << 3);
445
446     SHA256_Update(ctx, pad, padLen);
447
448 #if defined(IS_LITTLE_ENDIAN)
449     W[14] = SHA_HTONL(hi);
450     W[15] = SHA_HTONL(lo);
451 #else
452     W[14] = hi;
453     W[15] = lo;
454 #endif
455     SHA256_Compress(ctx);
456
457     /* now output the answer */
458 #if defined(IS_LITTLE_ENDIAN)
459     BYTESWAP4(H[0]);
460     BYTESWAP4(H[1]);
461     BYTESWAP4(H[2]);
462     BYTESWAP4(H[3]);
463     BYTESWAP4(H[4]);
464     BYTESWAP4(H[5]);
465     BYTESWAP4(H[6]);
466     BYTESWAP4(H[7]);
467 #endif
468     padLen = PR_MIN(SHA256_LENGTH, maxDigestLen);
469     memcpy(digest, H, padLen);
470     if (digestLen)
471         *digestLen = padLen;
472 }
473
474 /* Comment out unused code, mostly the SHA384 and SHA512 implementations. */
475 #if 0
476 SECStatus
477 SHA256_HashBuf(unsigned char *dest, const unsigned char *src,
478                unsigned int src_length)
479 {
480     SHA256Context ctx;
481     unsigned int outLen;
482
483     SHA256_Begin(&ctx);
484     SHA256_Update(&ctx, src, src_length);
485     SHA256_End(&ctx, dest, &outLen, SHA256_LENGTH);
486
487     return SECSuccess;
488 }
489
490
491 SECStatus
492 SHA256_Hash(unsigned char *dest, const char *src)
493 {
494     return SHA256_HashBuf(dest, (const unsigned char *)src, PORT_Strlen(src));
495 }
496
497
498 void SHA256_TraceState(SHA256Context *ctx) { }
499
500 unsigned int
501 SHA256_FlattenSize(SHA256Context *ctx)
502 {
503     return sizeof *ctx;
504 }
505
506 SECStatus
507 SHA256_Flatten(SHA256Context *ctx,unsigned char *space)
508 {
509     PORT_Memcpy(space, ctx, sizeof *ctx);
510     return SECSuccess;
511 }
512
513 SHA256Context *
514 SHA256_Resurrect(unsigned char *space, void *arg)
515 {
516     SHA256Context *ctx = SHA256_NewContext();
517     if (ctx)
518         PORT_Memcpy(ctx, space, sizeof *ctx);
519     return ctx;
520 }
521
522 void SHA256_Clone(SHA256Context *dest, SHA256Context *src)
523 {
524     memcpy(dest, src, sizeof *dest);
525 }
526
527
528 /* ======= SHA512 and SHA384 common constants and defines ================= */
529
530 /* common #defines for SHA512 and SHA384 */
531 #if defined(HAVE_LONG_LONG)
532 #define ROTR64(x,n) ((x >> n) | (x << (64 - n)))
533 #define ROTL64(x,n) ((x << n) | (x >> (64 - n)))
534
535 #define S0(x) (ROTR64(x,28) ^ ROTR64(x,34) ^ ROTR64(x,39))
536 #define S1(x) (ROTR64(x,14) ^ ROTR64(x,18) ^ ROTR64(x,41))
537 #define s0(x) (t1 = x, ROTR64(t1, 1) ^ ROTR64(t1, 8) ^ SHR(t1,7))
538 #define s1(x) (t2 = x, ROTR64(t2,19) ^ ROTR64(t2,61) ^ SHR(t2,6))
539
540 #if PR_BYTES_PER_LONG == 8
541 #define ULLC(hi,lo) 0x ## hi ## lo ## UL
542 #elif defined(_MSC_VER)
543 #define ULLC(hi,lo) 0x ## hi ## lo ## ui64
544 #else
545 #define ULLC(hi,lo) 0x ## hi ## lo ## ULL
546 #endif
547
548 #define SHA_MASK16 ULLC(0000FFFF,0000FFFF)
549 #define SHA_MASK8  ULLC(00FF00FF,00FF00FF)
550 #define SHA_HTONLL(x) (t1 = x, \
551   t1 = ((t1 & SHA_MASK8 ) <<  8) | ((t1 >>  8) & SHA_MASK8 ), \
552   t1 = ((t1 & SHA_MASK16) << 16) | ((t1 >> 16) & SHA_MASK16), \
553   (t1 >> 32) | (t1 << 32))
554 #define BYTESWAP8(x)  x = SHA_HTONLL(x)
555
556 #else /* no long long */
557
558 #if defined(IS_LITTLE_ENDIAN)
559 #define ULLC(hi,lo) { 0x ## lo ## U, 0x ## hi ## U }
560 #else
561 #define ULLC(hi,lo) { 0x ## hi ## U, 0x ## lo ## U }
562 #endif
563
564 #define SHA_HTONLL(x) ( BYTESWAP4(x.lo), BYTESWAP4(x.hi), \
565    x.hi ^= x.lo ^= x.hi ^= x.lo, x)
566 #define BYTESWAP8(x)  do { PRUint32 tmp; BYTESWAP4(x.lo); BYTESWAP4(x.hi); \
567    tmp = x.lo; x.lo = x.hi; x.hi = tmp; } while (0)
568 #endif
569
570 /* SHA-384 and SHA-512 constants, K512. */
571 static const PRUint64 K512[80] = {
572 #if PR_BYTES_PER_LONG == 8
573      0x428a2f98d728ae22UL ,  0x7137449123ef65cdUL ,
574      0xb5c0fbcfec4d3b2fUL ,  0xe9b5dba58189dbbcUL ,
575      0x3956c25bf348b538UL ,  0x59f111f1b605d019UL ,
576      0x923f82a4af194f9bUL ,  0xab1c5ed5da6d8118UL ,
577      0xd807aa98a3030242UL ,  0x12835b0145706fbeUL ,
578      0x243185be4ee4b28cUL ,  0x550c7dc3d5ffb4e2UL ,
579      0x72be5d74f27b896fUL ,  0x80deb1fe3b1696b1UL ,
580      0x9bdc06a725c71235UL ,  0xc19bf174cf692694UL ,
581      0xe49b69c19ef14ad2UL ,  0xefbe4786384f25e3UL ,
582      0x0fc19dc68b8cd5b5UL ,  0x240ca1cc77ac9c65UL ,
583      0x2de92c6f592b0275UL ,  0x4a7484aa6ea6e483UL ,
584      0x5cb0a9dcbd41fbd4UL ,  0x76f988da831153b5UL ,
585      0x983e5152ee66dfabUL ,  0xa831c66d2db43210UL ,
586      0xb00327c898fb213fUL ,  0xbf597fc7beef0ee4UL ,
587      0xc6e00bf33da88fc2UL ,  0xd5a79147930aa725UL ,
588      0x06ca6351e003826fUL ,  0x142929670a0e6e70UL ,
589      0x27b70a8546d22ffcUL ,  0x2e1b21385c26c926UL ,
590      0x4d2c6dfc5ac42aedUL ,  0x53380d139d95b3dfUL ,
591      0x650a73548baf63deUL ,  0x766a0abb3c77b2a8UL ,
592      0x81c2c92e47edaee6UL ,  0x92722c851482353bUL ,
593      0xa2bfe8a14cf10364UL ,  0xa81a664bbc423001UL ,
594      0xc24b8b70d0f89791UL ,  0xc76c51a30654be30UL ,
595      0xd192e819d6ef5218UL ,  0xd69906245565a910UL ,
596      0xf40e35855771202aUL ,  0x106aa07032bbd1b8UL ,
597      0x19a4c116b8d2d0c8UL ,  0x1e376c085141ab53UL ,
598      0x2748774cdf8eeb99UL ,  0x34b0bcb5e19b48a8UL ,
599      0x391c0cb3c5c95a63UL ,  0x4ed8aa4ae3418acbUL ,
600      0x5b9cca4f7763e373UL ,  0x682e6ff3d6b2b8a3UL ,
601      0x748f82ee5defb2fcUL ,  0x78a5636f43172f60UL ,
602      0x84c87814a1f0ab72UL ,  0x8cc702081a6439ecUL ,
603      0x90befffa23631e28UL ,  0xa4506cebde82bde9UL ,
604      0xbef9a3f7b2c67915UL ,  0xc67178f2e372532bUL ,
605      0xca273eceea26619cUL ,  0xd186b8c721c0c207UL ,
606      0xeada7dd6cde0eb1eUL ,  0xf57d4f7fee6ed178UL ,
607      0x06f067aa72176fbaUL ,  0x0a637dc5a2c898a6UL ,
608      0x113f9804bef90daeUL ,  0x1b710b35131c471bUL ,
609      0x28db77f523047d84UL ,  0x32caab7b40c72493UL ,
610      0x3c9ebe0a15c9bebcUL ,  0x431d67c49c100d4cUL ,
611      0x4cc5d4becb3e42b6UL ,  0x597f299cfc657e2aUL ,
612      0x5fcb6fab3ad6faecUL ,  0x6c44198c4a475817UL
613 #else
614     ULLC(428a2f98,d728ae22), ULLC(71374491,23ef65cd),
615     ULLC(b5c0fbcf,ec4d3b2f), ULLC(e9b5dba5,8189dbbc),
616     ULLC(3956c25b,f348b538), ULLC(59f111f1,b605d019),
617     ULLC(923f82a4,af194f9b), ULLC(ab1c5ed5,da6d8118),
618     ULLC(d807aa98,a3030242), ULLC(12835b01,45706fbe),
619     ULLC(243185be,4ee4b28c), ULLC(550c7dc3,d5ffb4e2),
620     ULLC(72be5d74,f27b896f), ULLC(80deb1fe,3b1696b1),
621     ULLC(9bdc06a7,25c71235), ULLC(c19bf174,cf692694),
622     ULLC(e49b69c1,9ef14ad2), ULLC(efbe4786,384f25e3),
623     ULLC(0fc19dc6,8b8cd5b5), ULLC(240ca1cc,77ac9c65),
624     ULLC(2de92c6f,592b0275), ULLC(4a7484aa,6ea6e483),
625     ULLC(5cb0a9dc,bd41fbd4), ULLC(76f988da,831153b5),
626     ULLC(983e5152,ee66dfab), ULLC(a831c66d,2db43210),
627     ULLC(b00327c8,98fb213f), ULLC(bf597fc7,beef0ee4),
628     ULLC(c6e00bf3,3da88fc2), ULLC(d5a79147,930aa725),
629     ULLC(06ca6351,e003826f), ULLC(14292967,0a0e6e70),
630     ULLC(27b70a85,46d22ffc), ULLC(2e1b2138,5c26c926),
631     ULLC(4d2c6dfc,5ac42aed), ULLC(53380d13,9d95b3df),
632     ULLC(650a7354,8baf63de), ULLC(766a0abb,3c77b2a8),
633     ULLC(81c2c92e,47edaee6), ULLC(92722c85,1482353b),
634     ULLC(a2bfe8a1,4cf10364), ULLC(a81a664b,bc423001),
635     ULLC(c24b8b70,d0f89791), ULLC(c76c51a3,0654be30),
636     ULLC(d192e819,d6ef5218), ULLC(d6990624,5565a910),
637     ULLC(f40e3585,5771202a), ULLC(106aa070,32bbd1b8),
638     ULLC(19a4c116,b8d2d0c8), ULLC(1e376c08,5141ab53),
639     ULLC(2748774c,df8eeb99), ULLC(34b0bcb5,e19b48a8),
640     ULLC(391c0cb3,c5c95a63), ULLC(4ed8aa4a,e3418acb),
641     ULLC(5b9cca4f,7763e373), ULLC(682e6ff3,d6b2b8a3),
642     ULLC(748f82ee,5defb2fc), ULLC(78a5636f,43172f60),
643     ULLC(84c87814,a1f0ab72), ULLC(8cc70208,1a6439ec),
644     ULLC(90befffa,23631e28), ULLC(a4506ceb,de82bde9),
645     ULLC(bef9a3f7,b2c67915), ULLC(c67178f2,e372532b),
646     ULLC(ca273ece,ea26619c), ULLC(d186b8c7,21c0c207),
647     ULLC(eada7dd6,cde0eb1e), ULLC(f57d4f7f,ee6ed178),
648     ULLC(06f067aa,72176fba), ULLC(0a637dc5,a2c898a6),
649     ULLC(113f9804,bef90dae), ULLC(1b710b35,131c471b),
650     ULLC(28db77f5,23047d84), ULLC(32caab7b,40c72493),
651     ULLC(3c9ebe0a,15c9bebc), ULLC(431d67c4,9c100d4c),
652     ULLC(4cc5d4be,cb3e42b6), ULLC(597f299c,fc657e2a),
653     ULLC(5fcb6fab,3ad6faec), ULLC(6c44198c,4a475817)
654 #endif
655 };
656
657 struct SHA512ContextStr {
658     union {
659         PRUint64 w[80];     /* message schedule, input buffer, plus 64 words */
660         PRUint32 l[160];
661         PRUint8  b[640];
662     } u;
663     PRUint64 h[8];          /* 8 state variables */
664     PRUint64 sizeLo;        /* 64-bit count of hashed bytes. */
665 };
666
667 /* =========== SHA512 implementation ===================================== */
668
669 /* SHA-512 initial hash values */
670 static const PRUint64 H512[8] = {
671 #if PR_BYTES_PER_LONG == 8
672      0x6a09e667f3bcc908UL ,  0xbb67ae8584caa73bUL ,
673      0x3c6ef372fe94f82bUL ,  0xa54ff53a5f1d36f1UL ,
674      0x510e527fade682d1UL ,  0x9b05688c2b3e6c1fUL ,
675      0x1f83d9abfb41bd6bUL ,  0x5be0cd19137e2179UL
676 #else
677     ULLC(6a09e667,f3bcc908), ULLC(bb67ae85,84caa73b),
678     ULLC(3c6ef372,fe94f82b), ULLC(a54ff53a,5f1d36f1),
679     ULLC(510e527f,ade682d1), ULLC(9b05688c,2b3e6c1f),
680     ULLC(1f83d9ab,fb41bd6b), ULLC(5be0cd19,137e2179)
681 #endif
682 };
683
684
685 SHA512Context *
686 SHA512_NewContext(void)
687 {
688     SHA512Context *ctx = PORT_New(SHA512Context);
689     return ctx;
690 }
691
692 void
693 SHA512_DestroyContext(SHA512Context *ctx, PRBool freeit)
694 {
695     if (freeit) {
696         PORT_ZFree(ctx, sizeof *ctx);
697     }
698 }
699
700 void
701 SHA512_Begin(SHA512Context *ctx)
702 {
703     memset(ctx, 0, sizeof *ctx);
704     memcpy(H, H512, sizeof H512);
705 }
706
707 #if defined(SHA512_TRACE)
708 #if defined(HAVE_LONG_LONG)
709 #define DUMP(n,a,d,e,h) printf(" t = %2d, %s = %016lx, %s = %016lx\n", \
710                                n, #e, d, #a, h);
711 #else
712 #define DUMP(n,a,d,e,h) printf(" t = %2d, %s = %08x%08x, %s = %08x%08x\n", \
713                                n, #e, d.hi, d.lo, #a, h.hi, h.lo);
714 #endif
715 #else
716 #define DUMP(n,a,d,e,h)
717 #endif
718
719 #if defined(HAVE_LONG_LONG)
720
721 #define ADDTO(x,y) y += x
722
723 #define INITW(t) W[t] = (s1(W[t-2]) + W[t-7] + s0(W[t-15]) + W[t-16])
724
725 #define ROUND(n,a,b,c,d,e,f,g,h) \
726     h += S1(e) + Ch(e,f,g) + K512[n] + W[n]; \
727     d += h; \
728     h += S0(a) + Maj(a,b,c); \
729     DUMP(n,a,d,e,h)
730
731 #else /* use only 32-bit variables, and don't unroll loops */
732
733 #undef  NOUNROLL512
734 #define NOUNROLL512 1
735
736 #define ADDTO(x,y) y.lo += x.lo; y.hi += x.hi + (x.lo > y.lo)
737
738 #define ROTR64a(x,n,lo,hi) (x.lo >> n | x.hi << (32-n))
739 #define ROTR64A(x,n,lo,hi) (x.lo << (64-n) | x.hi >> (n-32))
740 #define  SHR64a(x,n,lo,hi) (x.lo >> n | x.hi << (32-n))
741
742 /* Capitol Sigma and lower case sigma functions */
743 #define s0lo(x) (ROTR64a(x,1,lo,hi) ^ ROTR64a(x,8,lo,hi) ^ SHR64a(x,7,lo,hi))
744 #define s0hi(x) (ROTR64a(x,1,hi,lo) ^ ROTR64a(x,8,hi,lo) ^ (x.hi >> 7))
745
746 #define s1lo(x) (ROTR64a(x,19,lo,hi) ^ ROTR64A(x,61,lo,hi) ^ SHR64a(x,6,lo,hi))
747 #define s1hi(x) (ROTR64a(x,19,hi,lo) ^ ROTR64A(x,61,hi,lo) ^ (x.hi >> 6))
748
749 #define S0lo(x)(ROTR64a(x,28,lo,hi) ^ ROTR64A(x,34,lo,hi) ^ ROTR64A(x,39,lo,hi))
750 #define S0hi(x)(ROTR64a(x,28,hi,lo) ^ ROTR64A(x,34,hi,lo) ^ ROTR64A(x,39,hi,lo))
751
752 #define S1lo(x)(ROTR64a(x,14,lo,hi) ^ ROTR64a(x,18,lo,hi) ^ ROTR64A(x,41,lo,hi))
753 #define S1hi(x)(ROTR64a(x,14,hi,lo) ^ ROTR64a(x,18,hi,lo) ^ ROTR64A(x,41,hi,lo))
754
755 /* 32-bit versions of Ch and Maj */
756 #define Chxx(x,y,z,lo) ((x.lo & y.lo) ^ (~x.lo & z.lo))
757 #define Majx(x,y,z,lo) ((x.lo & y.lo) ^ (x.lo & z.lo) ^ (y.lo & z.lo))
758
759 #define INITW(t) \
760     do { \
761         PRUint32 lo, tm; \
762         PRUint32 cy = 0; \
763         lo = s1lo(W[t-2]); \
764         lo += (tm = W[t-7].lo);     if (lo < tm) cy++; \
765         lo += (tm = s0lo(W[t-15])); if (lo < tm) cy++; \
766         lo += (tm = W[t-16].lo);    if (lo < tm) cy++; \
767         W[t].lo = lo; \
768         W[t].hi = cy + s1hi(W[t-2]) + W[t-7].hi + s0hi(W[t-15]) + W[t-16].hi; \
769     } while (0)
770
771 #define ROUND(n,a,b,c,d,e,f,g,h) \
772     { \
773         PRUint32 lo, tm, cy; \
774         lo  = S1lo(e); \
775         lo += (tm = Chxx(e,f,g,lo));    cy = (lo < tm); \
776         lo += (tm = K512[n].lo);        if (lo < tm) cy++; \
777         lo += (tm =    W[n].lo);        if (lo < tm) cy++; \
778         h.lo += lo;                     if (h.lo < lo) cy++; \
779         h.hi += cy + S1hi(e) + Chxx(e,f,g,hi) + K512[n].hi + W[n].hi; \
780         d.lo += h.lo; \
781         d.hi += h.hi + (d.lo < h.lo); \
782         lo  = S0lo(a);  \
783         lo += (tm = Majx(a,b,c,lo));    cy = (lo < tm); \
784         h.lo += lo;                     if (h.lo < lo) cy++; \
785         h.hi += cy + S0hi(a) + Majx(a,b,c,hi); \
786         DUMP(n,a,d,e,h) \
787     }
788 #endif
789
790 static void
791 SHA512_Compress(SHA512Context *ctx)
792 {
793 #if defined(IS_LITTLE_ENDIAN)
794   {
795 #if defined(HAVE_LONG_LONG)
796     PRUint64 t1;
797 #else
798     PRUint32 t1;
799 #endif
800     BYTESWAP8(W[0]);
801     BYTESWAP8(W[1]);
802     BYTESWAP8(W[2]);
803     BYTESWAP8(W[3]);
804     BYTESWAP8(W[4]);
805     BYTESWAP8(W[5]);
806     BYTESWAP8(W[6]);
807     BYTESWAP8(W[7]);
808     BYTESWAP8(W[8]);
809     BYTESWAP8(W[9]);
810     BYTESWAP8(W[10]);
811     BYTESWAP8(W[11]);
812     BYTESWAP8(W[12]);
813     BYTESWAP8(W[13]);
814     BYTESWAP8(W[14]);
815     BYTESWAP8(W[15]);
816   }
817 #endif
818
819   {
820     PRUint64 t1, t2;
821 #ifdef NOUNROLL512
822     {
823         /* prepare the "message schedule"   */
824         int t;
825         for (t = 16; t < 80; ++t) {
826             INITW(t);
827         }
828     }
829 #else
830     INITW(16);
831     INITW(17);
832     INITW(18);
833     INITW(19);
834
835     INITW(20);
836     INITW(21);
837     INITW(22);
838     INITW(23);
839     INITW(24);
840     INITW(25);
841     INITW(26);
842     INITW(27);
843     INITW(28);
844     INITW(29);
845
846     INITW(30);
847     INITW(31);
848     INITW(32);
849     INITW(33);
850     INITW(34);
851     INITW(35);
852     INITW(36);
853     INITW(37);
854     INITW(38);
855     INITW(39);
856
857     INITW(40);
858     INITW(41);
859     INITW(42);
860     INITW(43);
861     INITW(44);
862     INITW(45);
863     INITW(46);
864     INITW(47);
865     INITW(48);
866     INITW(49);
867
868     INITW(50);
869     INITW(51);
870     INITW(52);
871     INITW(53);
872     INITW(54);
873     INITW(55);
874     INITW(56);
875     INITW(57);
876     INITW(58);
877     INITW(59);
878
879     INITW(60);
880     INITW(61);
881     INITW(62);
882     INITW(63);
883     INITW(64);
884     INITW(65);
885     INITW(66);
886     INITW(67);
887     INITW(68);
888     INITW(69);
889
890     INITW(70);
891     INITW(71);
892     INITW(72);
893     INITW(73);
894     INITW(74);
895     INITW(75);
896     INITW(76);
897     INITW(77);
898     INITW(78);
899     INITW(79);
900 #endif
901   }
902 #ifdef SHA512_TRACE
903   {
904     int i;
905     for (i = 0; i < 80; ++i) {
906 #ifdef HAVE_LONG_LONG
907         printf("W[%2d] = %016lx\n", i, W[i]);
908 #else
909         printf("W[%2d] = %08x%08x\n", i, W[i].hi, W[i].lo);
910 #endif
911     }
912   }
913 #endif
914   {
915     PRUint64 a, b, c, d, e, f, g, h;
916
917     a = H[0];
918     b = H[1];
919     c = H[2];
920     d = H[3];
921     e = H[4];
922     f = H[5];
923     g = H[6];
924     h = H[7];
925
926 #ifdef NOUNROLL512
927     {
928         int t;
929         for (t = 0; t < 80; t+= 8) {
930             ROUND(t+0,a,b,c,d,e,f,g,h)
931             ROUND(t+1,h,a,b,c,d,e,f,g)
932             ROUND(t+2,g,h,a,b,c,d,e,f)
933             ROUND(t+3,f,g,h,a,b,c,d,e)
934             ROUND(t+4,e,f,g,h,a,b,c,d)
935             ROUND(t+5,d,e,f,g,h,a,b,c)
936             ROUND(t+6,c,d,e,f,g,h,a,b)
937             ROUND(t+7,b,c,d,e,f,g,h,a)
938         }
939     }
940 #else
941     ROUND( 0,a,b,c,d,e,f,g,h)
942     ROUND( 1,h,a,b,c,d,e,f,g)
943     ROUND( 2,g,h,a,b,c,d,e,f)
944     ROUND( 3,f,g,h,a,b,c,d,e)
945     ROUND( 4,e,f,g,h,a,b,c,d)
946     ROUND( 5,d,e,f,g,h,a,b,c)
947     ROUND( 6,c,d,e,f,g,h,a,b)
948     ROUND( 7,b,c,d,e,f,g,h,a)
949
950     ROUND( 8,a,b,c,d,e,f,g,h)
951     ROUND( 9,h,a,b,c,d,e,f,g)
952     ROUND(10,g,h,a,b,c,d,e,f)
953     ROUND(11,f,g,h,a,b,c,d,e)
954     ROUND(12,e,f,g,h,a,b,c,d)
955     ROUND(13,d,e,f,g,h,a,b,c)
956     ROUND(14,c,d,e,f,g,h,a,b)
957     ROUND(15,b,c,d,e,f,g,h,a)
958
959     ROUND(16,a,b,c,d,e,f,g,h)
960     ROUND(17,h,a,b,c,d,e,f,g)
961     ROUND(18,g,h,a,b,c,d,e,f)
962     ROUND(19,f,g,h,a,b,c,d,e)
963     ROUND(20,e,f,g,h,a,b,c,d)
964     ROUND(21,d,e,f,g,h,a,b,c)
965     ROUND(22,c,d,e,f,g,h,a,b)
966     ROUND(23,b,c,d,e,f,g,h,a)
967
968     ROUND(24,a,b,c,d,e,f,g,h)
969     ROUND(25,h,a,b,c,d,e,f,g)
970     ROUND(26,g,h,a,b,c,d,e,f)
971     ROUND(27,f,g,h,a,b,c,d,e)
972     ROUND(28,e,f,g,h,a,b,c,d)
973     ROUND(29,d,e,f,g,h,a,b,c)
974     ROUND(30,c,d,e,f,g,h,a,b)
975     ROUND(31,b,c,d,e,f,g,h,a)
976
977     ROUND(32,a,b,c,d,e,f,g,h)
978     ROUND(33,h,a,b,c,d,e,f,g)
979     ROUND(34,g,h,a,b,c,d,e,f)
980     ROUND(35,f,g,h,a,b,c,d,e)
981     ROUND(36,e,f,g,h,a,b,c,d)
982     ROUND(37,d,e,f,g,h,a,b,c)
983     ROUND(38,c,d,e,f,g,h,a,b)
984     ROUND(39,b,c,d,e,f,g,h,a)
985
986     ROUND(40,a,b,c,d,e,f,g,h)
987     ROUND(41,h,a,b,c,d,e,f,g)
988     ROUND(42,g,h,a,b,c,d,e,f)
989     ROUND(43,f,g,h,a,b,c,d,e)
990     ROUND(44,e,f,g,h,a,b,c,d)
991     ROUND(45,d,e,f,g,h,a,b,c)
992     ROUND(46,c,d,e,f,g,h,a,b)
993     ROUND(47,b,c,d,e,f,g,h,a)
994
995     ROUND(48,a,b,c,d,e,f,g,h)
996     ROUND(49,h,a,b,c,d,e,f,g)
997     ROUND(50,g,h,a,b,c,d,e,f)
998     ROUND(51,f,g,h,a,b,c,d,e)
999     ROUND(52,e,f,g,h,a,b,c,d)
1000     ROUND(53,d,e,f,g,h,a,b,c)
1001     ROUND(54,c,d,e,f,g,h,a,b)
1002     ROUND(55,b,c,d,e,f,g,h,a)
1003
1004     ROUND(56,a,b,c,d,e,f,g,h)
1005     ROUND(57,h,a,b,c,d,e,f,g)
1006     ROUND(58,g,h,a,b,c,d,e,f)
1007     ROUND(59,f,g,h,a,b,c,d,e)
1008     ROUND(60,e,f,g,h,a,b,c,d)
1009     ROUND(61,d,e,f,g,h,a,b,c)
1010     ROUND(62,c,d,e,f,g,h,a,b)
1011     ROUND(63,b,c,d,e,f,g,h,a)
1012
1013     ROUND(64,a,b,c,d,e,f,g,h)
1014     ROUND(65,h,a,b,c,d,e,f,g)
1015     ROUND(66,g,h,a,b,c,d,e,f)
1016     ROUND(67,f,g,h,a,b,c,d,e)
1017     ROUND(68,e,f,g,h,a,b,c,d)
1018     ROUND(69,d,e,f,g,h,a,b,c)
1019     ROUND(70,c,d,e,f,g,h,a,b)
1020     ROUND(71,b,c,d,e,f,g,h,a)
1021
1022     ROUND(72,a,b,c,d,e,f,g,h)
1023     ROUND(73,h,a,b,c,d,e,f,g)
1024     ROUND(74,g,h,a,b,c,d,e,f)
1025     ROUND(75,f,g,h,a,b,c,d,e)
1026     ROUND(76,e,f,g,h,a,b,c,d)
1027     ROUND(77,d,e,f,g,h,a,b,c)
1028     ROUND(78,c,d,e,f,g,h,a,b)
1029     ROUND(79,b,c,d,e,f,g,h,a)
1030 #endif
1031
1032     ADDTO(a,H[0]);
1033     ADDTO(b,H[1]);
1034     ADDTO(c,H[2]);
1035     ADDTO(d,H[3]);
1036     ADDTO(e,H[4]);
1037     ADDTO(f,H[5]);
1038     ADDTO(g,H[6]);
1039     ADDTO(h,H[7]);
1040   }
1041 }
1042
1043 void
1044 SHA512_Update(SHA512Context *ctx, const unsigned char *input,
1045               unsigned int inputLen)
1046 {
1047     unsigned int inBuf;
1048     if (!inputLen)
1049         return;
1050
1051 #if defined(HAVE_LONG_LONG)
1052     inBuf = (unsigned int)ctx->sizeLo & 0x7f;
1053     /* Add inputLen into the count of bytes processed, before processing */
1054     ctx->sizeLo += inputLen;
1055 #else
1056     inBuf = (unsigned int)ctx->sizeLo.lo & 0x7f;
1057     ctx->sizeLo.lo += inputLen;
1058     if (ctx->sizeLo.lo < inputLen) ctx->sizeLo.hi++;
1059 #endif
1060
1061     /* if data already in buffer, attemp to fill rest of buffer */
1062     if (inBuf) {
1063         unsigned int todo = SHA512_BLOCK_LENGTH - inBuf;
1064         if (inputLen < todo)
1065             todo = inputLen;
1066         memcpy(B + inBuf, input, todo);
1067         input    += todo;
1068         inputLen -= todo;
1069         if (inBuf + todo == SHA512_BLOCK_LENGTH)
1070             SHA512_Compress(ctx);
1071     }
1072
1073     /* if enough data to fill one or more whole buffers, process them. */
1074     while (inputLen >= SHA512_BLOCK_LENGTH) {
1075         memcpy(B, input, SHA512_BLOCK_LENGTH);
1076         input    += SHA512_BLOCK_LENGTH;
1077         inputLen -= SHA512_BLOCK_LENGTH;
1078         SHA512_Compress(ctx);
1079     }
1080     /* if data left over, fill it into buffer */
1081     if (inputLen)
1082         memcpy(B, input, inputLen);
1083 }
1084
1085 void
1086 SHA512_End(SHA512Context *ctx, unsigned char *digest,
1087            unsigned int *digestLen, unsigned int maxDigestLen)
1088 {
1089 #if defined(HAVE_LONG_LONG)
1090     unsigned int inBuf  = (unsigned int)ctx->sizeLo & 0x7f;
1091     unsigned int padLen = (inBuf < 112) ? (112 - inBuf) : (112 + 128 - inBuf);
1092     PRUint64 lo, t1;
1093     lo = (ctx->sizeLo << 3);
1094 #else
1095     unsigned int inBuf  = (unsigned int)ctx->sizeLo.lo & 0x7f;
1096     unsigned int padLen = (inBuf < 112) ? (112 - inBuf) : (112 + 128 - inBuf);
1097     PRUint64 lo = ctx->sizeLo;
1098     PRUint32 t1;
1099     lo.lo <<= 3;
1100 #endif
1101
1102     SHA512_Update(ctx, pad, padLen);
1103
1104 #if defined(HAVE_LONG_LONG)
1105     W[14] = 0;
1106 #else
1107     W[14].lo = 0;
1108     W[14].hi = 0;
1109 #endif
1110
1111     W[15] = lo;
1112 #if defined(IS_LITTLE_ENDIAN)
1113     BYTESWAP8(W[15]);
1114 #endif
1115     SHA512_Compress(ctx);
1116
1117     /* now output the answer */
1118 #if defined(IS_LITTLE_ENDIAN)
1119     BYTESWAP8(H[0]);
1120     BYTESWAP8(H[1]);
1121     BYTESWAP8(H[2]);
1122     BYTESWAP8(H[3]);
1123     BYTESWAP8(H[4]);
1124     BYTESWAP8(H[5]);
1125     BYTESWAP8(H[6]);
1126     BYTESWAP8(H[7]);
1127 #endif
1128     padLen = PR_MIN(SHA512_LENGTH, maxDigestLen);
1129     memcpy(digest, H, padLen);
1130     if (digestLen)
1131         *digestLen = padLen;
1132 }
1133
1134 SECStatus
1135 SHA512_HashBuf(unsigned char *dest, const unsigned char *src,
1136                unsigned int src_length)
1137 {
1138     SHA512Context ctx;
1139     unsigned int outLen;
1140
1141     SHA512_Begin(&ctx);
1142     SHA512_Update(&ctx, src, src_length);
1143     SHA512_End(&ctx, dest, &outLen, SHA512_LENGTH);
1144
1145     return SECSuccess;
1146 }
1147
1148
1149 SECStatus
1150 SHA512_Hash(unsigned char *dest, const char *src)
1151 {
1152     return SHA512_HashBuf(dest, (const unsigned char *)src, PORT_Strlen(src));
1153 }
1154
1155
1156 void SHA512_TraceState(SHA512Context *ctx) { }
1157
1158 unsigned int
1159 SHA512_FlattenSize(SHA512Context *ctx)
1160 {
1161     return sizeof *ctx;
1162 }
1163
1164 SECStatus
1165 SHA512_Flatten(SHA512Context *ctx,unsigned char *space)
1166 {
1167     PORT_Memcpy(space, ctx, sizeof *ctx);
1168     return SECSuccess;
1169 }
1170
1171 SHA512Context *
1172 SHA512_Resurrect(unsigned char *space, void *arg)
1173 {
1174     SHA512Context *ctx = SHA512_NewContext();
1175     if (ctx)
1176         PORT_Memcpy(ctx, space, sizeof *ctx);
1177     return ctx;
1178 }
1179
1180 void SHA512_Clone(SHA512Context *dest, SHA512Context *src)
1181 {
1182     memcpy(dest, src, sizeof *dest);
1183 }
1184
1185 /* ======================================================================= */
1186 /* SHA384 uses a SHA512Context as the real context.
1187 ** The only differences between SHA384 an SHA512 are:
1188 ** a) the intialization values for the context, and
1189 ** b) the number of bytes of data produced as output.
1190 */
1191
1192 /* SHA-384 initial hash values */
1193 static const PRUint64 H384[8] = {
1194 #if PR_BYTES_PER_LONG == 8
1195      0xcbbb9d5dc1059ed8UL ,  0x629a292a367cd507UL ,
1196      0x9159015a3070dd17UL ,  0x152fecd8f70e5939UL ,
1197      0x67332667ffc00b31UL ,  0x8eb44a8768581511UL ,
1198      0xdb0c2e0d64f98fa7UL ,  0x47b5481dbefa4fa4UL
1199 #else
1200     ULLC(cbbb9d5d,c1059ed8), ULLC(629a292a,367cd507),
1201     ULLC(9159015a,3070dd17), ULLC(152fecd8,f70e5939),
1202     ULLC(67332667,ffc00b31), ULLC(8eb44a87,68581511),
1203     ULLC(db0c2e0d,64f98fa7), ULLC(47b5481d,befa4fa4)
1204 #endif
1205 };
1206
1207 SHA384Context *
1208 SHA384_NewContext(void)
1209 {
1210     return SHA512_NewContext();
1211 }
1212
1213 void
1214 SHA384_DestroyContext(SHA384Context *ctx, PRBool freeit)
1215 {
1216     SHA512_DestroyContext(ctx, freeit);
1217 }
1218
1219 void
1220 SHA384_Begin(SHA384Context *ctx)
1221 {
1222     memset(ctx, 0, sizeof *ctx);
1223     memcpy(H, H384, sizeof H384);
1224 }
1225
1226 void
1227 SHA384_Update(SHA384Context *ctx, const unsigned char *input,
1228                     unsigned int inputLen)
1229 {
1230     SHA512_Update(ctx, input, inputLen);
1231 }
1232
1233 void
1234 SHA384_End(SHA384Context *ctx, unsigned char *digest,
1235                  unsigned int *digestLen, unsigned int maxDigestLen)
1236 {
1237 #define SHA_MIN(a,b) (a < b ? a : b)
1238     unsigned int maxLen = SHA_MIN(maxDigestLen, SHA384_LENGTH);
1239     SHA512_End(ctx, digest, digestLen, maxLen);
1240 }
1241
1242 SECStatus
1243 SHA384_HashBuf(unsigned char *dest, const unsigned char *src,
1244                           unsigned int src_length)
1245 {
1246     SHA512Context ctx;
1247     unsigned int outLen;
1248
1249     SHA384_Begin(&ctx);
1250     SHA512_Update(&ctx, src, src_length);
1251     SHA512_End(&ctx, dest, &outLen, SHA384_LENGTH);
1252
1253     return SECSuccess;
1254 }
1255
1256 SECStatus
1257 SHA384_Hash(unsigned char *dest, const char *src)
1258 {
1259     return SHA384_HashBuf(dest, (const unsigned char *)src, PORT_Strlen(src));
1260 }
1261
1262 void SHA384_TraceState(SHA384Context *ctx) { }
1263
1264 unsigned int
1265 SHA384_FlattenSize(SHA384Context *ctx)
1266 {
1267     return sizeof(SHA384Context);
1268 }
1269
1270 SECStatus
1271 SHA384_Flatten(SHA384Context *ctx,unsigned char *space)
1272 {
1273     return SHA512_Flatten(ctx, space);
1274 }
1275
1276 SHA384Context *
1277 SHA384_Resurrect(unsigned char *space, void *arg)
1278 {
1279     return SHA512_Resurrect(space, arg);
1280 }
1281
1282 void SHA384_Clone(SHA384Context *dest, SHA384Context *src)
1283 {
1284     memcpy(dest, src, sizeof *dest);
1285 }
1286 #endif  /* Comment out unused code. */
1287
1288 /* ======================================================================= */
1289 #ifdef SELFTEST
1290 #include <stdio.h>
1291
1292 static const char abc[] = { "abc" };
1293 static const char abcdbc[] = {
1294     "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"
1295 };
1296 static const char abcdef[] = {
1297     "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmn"
1298     "hijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu"
1299 };
1300
1301 void
1302 dumpHash32(const unsigned char *buf, unsigned int bufLen)
1303 {
1304     unsigned int i;
1305     for (i = 0; i < bufLen; i += 4) {
1306         printf(" %02x%02x%02x%02x", buf[i], buf[i+1], buf[i+2], buf[i+3]);
1307     }
1308     printf("\n");
1309 }
1310
1311 void test256(void)
1312 {
1313     unsigned char outBuf[SHA256_LENGTH];
1314
1315     printf("SHA256, input = %s\n", abc);
1316     SHA256_Hash(outBuf, abc);
1317     dumpHash32(outBuf, sizeof outBuf);
1318
1319     printf("SHA256, input = %s\n", abcdbc);
1320     SHA256_Hash(outBuf, abcdbc);
1321     dumpHash32(outBuf, sizeof outBuf);
1322 }
1323
1324 void
1325 dumpHash64(const unsigned char *buf, unsigned int bufLen)
1326 {
1327     unsigned int i;
1328     for (i = 0; i < bufLen; i += 8) {
1329         if (i % 32 == 0)
1330             printf("\n");
1331         printf(" %02x%02x%02x%02x%02x%02x%02x%02x",
1332                buf[i  ], buf[i+1], buf[i+2], buf[i+3],
1333                buf[i+4], buf[i+5], buf[i+6], buf[i+7]);
1334     }
1335     printf("\n");
1336 }
1337
1338 void test512(void)
1339 {
1340     unsigned char outBuf[SHA512_LENGTH];
1341
1342     printf("SHA512, input = %s\n", abc);
1343     SHA512_Hash(outBuf, abc);
1344     dumpHash64(outBuf, sizeof outBuf);
1345
1346     printf("SHA512, input = %s\n", abcdef);
1347     SHA512_Hash(outBuf, abcdef);
1348     dumpHash64(outBuf, sizeof outBuf);
1349 }
1350
1351 void time512(void)
1352 {
1353     unsigned char outBuf[SHA512_LENGTH];
1354
1355     SHA512_Hash(outBuf, abc);
1356     SHA512_Hash(outBuf, abcdef);
1357 }
1358
1359 void test384(void)
1360 {
1361     unsigned char outBuf[SHA384_LENGTH];
1362
1363     printf("SHA384, input = %s\n", abc);
1364     SHA384_Hash(outBuf, abc);
1365     dumpHash64(outBuf, sizeof outBuf);
1366
1367     printf("SHA384, input = %s\n", abcdef);
1368     SHA384_Hash(outBuf, abcdef);
1369     dumpHash64(outBuf, sizeof outBuf);
1370 }
1371
1372 int main (int argc, char *argv[], char *envp[])
1373 {
1374     int i = 1;
1375     if (argc > 1) {
1376         i = atoi(argv[1]);
1377     }
1378     if (i < 2) {
1379         test256();
1380         test512();
1381         test384();
1382     } else {
1383         while (i-- > 0) {
1384             time512();
1385         }
1386         printf("done\n");
1387     }
1388     return 0;
1389 }
1390
1391 #endif