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 */
72static const PRUint8 pad[240] = {
730x80,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. */
81static 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 */
101static 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
116static FORCEINLINE PRUint32 FASTCALL
117swap4b(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
159SHA256Context *
160SHA256_NewContext(void)
161{
162    SHA256Context *ctx = PORT_New(SHA256Context);
163    return ctx;
164}
165
166void
167SHA256_DestroyContext(SHA256Context *ctx, PRBool freeit)
168{
169    if (freeit) {
170        PORT_ZFree(ctx, sizeof *ctx);
171    }
172}
173
174void
175SHA256_Begin(SHA256Context *ctx)
176{
177    memset(ctx, 0, sizeof *ctx);
178    memcpy(H, H256, sizeof H256);
179}
180
181static void
182SHA256_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
396void
397SHA256_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
432void
433SHA256_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
476SECStatus
477SHA256_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
491SECStatus
492SHA256_Hash(unsigned char *dest, const char *src)
493{
494    return SHA256_HashBuf(dest, (const unsigned char *)src, PORT_Strlen(src));
495}
496
497
498void SHA256_TraceState(SHA256Context *ctx) { }
499
500unsigned int
501SHA256_FlattenSize(SHA256Context *ctx)
502{
503    return sizeof *ctx;
504}
505
506SECStatus
507SHA256_Flatten(SHA256Context *ctx,unsigned char *space)
508{
509    PORT_Memcpy(space, ctx, sizeof *ctx);
510    return SECSuccess;
511}
512
513SHA256Context *
514SHA256_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
522void 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. */
571static 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
657struct 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 */
670static 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
685SHA512Context *
686SHA512_NewContext(void)
687{
688    SHA512Context *ctx = PORT_New(SHA512Context);
689    return ctx;
690}
691
692void
693SHA512_DestroyContext(SHA512Context *ctx, PRBool freeit)
694{
695    if (freeit) {
696        PORT_ZFree(ctx, sizeof *ctx);
697    }
698}
699
700void
701SHA512_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
790static void
791SHA512_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
1043void
1044SHA512_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
1085void
1086SHA512_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
1134SECStatus
1135SHA512_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
1149SECStatus
1150SHA512_Hash(unsigned char *dest, const char *src)
1151{
1152    return SHA512_HashBuf(dest, (const unsigned char *)src, PORT_Strlen(src));
1153}
1154
1155
1156void SHA512_TraceState(SHA512Context *ctx) { }
1157
1158unsigned int
1159SHA512_FlattenSize(SHA512Context *ctx)
1160{
1161    return sizeof *ctx;
1162}
1163
1164SECStatus
1165SHA512_Flatten(SHA512Context *ctx,unsigned char *space)
1166{
1167    PORT_Memcpy(space, ctx, sizeof *ctx);
1168    return SECSuccess;
1169}
1170
1171SHA512Context *
1172SHA512_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
1180void 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 */
1193static 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
1207SHA384Context *
1208SHA384_NewContext(void)
1209{
1210    return SHA512_NewContext();
1211}
1212
1213void
1214SHA384_DestroyContext(SHA384Context *ctx, PRBool freeit)
1215{
1216    SHA512_DestroyContext(ctx, freeit);
1217}
1218
1219void
1220SHA384_Begin(SHA384Context *ctx)
1221{
1222    memset(ctx, 0, sizeof *ctx);
1223    memcpy(H, H384, sizeof H384);
1224}
1225
1226void
1227SHA384_Update(SHA384Context *ctx, const unsigned char *input,
1228		    unsigned int inputLen)
1229{
1230    SHA512_Update(ctx, input, inputLen);
1231}
1232
1233void
1234SHA384_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
1242SECStatus
1243SHA384_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
1256SECStatus
1257SHA384_Hash(unsigned char *dest, const char *src)
1258{
1259    return SHA384_HashBuf(dest, (const unsigned char *)src, PORT_Strlen(src));
1260}
1261
1262void SHA384_TraceState(SHA384Context *ctx) { }
1263
1264unsigned int
1265SHA384_FlattenSize(SHA384Context *ctx)
1266{
1267    return sizeof(SHA384Context);
1268}
1269
1270SECStatus
1271SHA384_Flatten(SHA384Context *ctx,unsigned char *space)
1272{
1273    return SHA512_Flatten(ctx, space);
1274}
1275
1276SHA384Context *
1277SHA384_Resurrect(unsigned char *space, void *arg)
1278{
1279    return SHA512_Resurrect(space, arg);
1280}
1281
1282void 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
1292static const char abc[] = { "abc" };
1293static const char abcdbc[] = {
1294    "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"
1295};
1296static const char abcdef[] = {
1297    "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmn"
1298    "hijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu"
1299};
1300
1301void
1302dumpHash32(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
1311void 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
1324void
1325dumpHash64(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
1338void 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
1351void time512(void)
1352{
1353    unsigned char outBuf[SHA512_LENGTH];
1354
1355    SHA512_Hash(outBuf, abc);
1356    SHA512_Hash(outBuf, abcdef);
1357}
1358
1359void 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
1372int 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