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 "crypto/third_party/nss/chromium-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
swap4b(PRUint32 dwd)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 *
SHA256_NewContext(void)160 SHA256_NewContext(void)
161 {
162     SHA256Context *ctx = PORT_New(SHA256Context);
163     return ctx;
164 }
165 
166 void
SHA256_DestroyContext(SHA256Context * ctx,PRBool freeit)167 SHA256_DestroyContext(SHA256Context *ctx, PRBool freeit)
168 {
169     if (freeit) {
170         PORT_ZFree(ctx, sizeof *ctx);
171     }
172 }
173 
174 void
SHA256_Begin(SHA256Context * ctx)175 SHA256_Begin(SHA256Context *ctx)
176 {
177     memset(ctx, 0, sizeof *ctx);
178     memcpy(H, H256, sizeof H256);
179 }
180 
181 static void
SHA256_Compress(SHA256Context * ctx)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
SHA256_Update(SHA256Context * ctx,const unsigned char * input,unsigned int inputLen)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
SHA256_End(SHA256Context * ctx,unsigned char * digest,unsigned int * digestLen,unsigned int maxDigestLen)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
dumpHash32(const unsigned char * buf,unsigned int bufLen)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 
test256(void)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
dumpHash64(const unsigned char * buf,unsigned int bufLen)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 
test512(void)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 
time512(void)1351 void time512(void)
1352 {
1353     unsigned char outBuf[SHA512_LENGTH];
1354 
1355     SHA512_Hash(outBuf, abc);
1356     SHA512_Hash(outBuf, abcdef);
1357 }
1358 
test384(void)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 
main(int argc,char * argv[],char * envp[])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
1392