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
474void SHA256_Clone(SHA256Context* dest, SHA256Context* src)
475{
476  memcpy(dest, src, sizeof *dest);
477}
478
479/* Comment out unused code, mostly the SHA384 and SHA512 implementations. */
480#if 0
481SECStatus
482SHA256_HashBuf(unsigned char *dest, const unsigned char *src,
483               unsigned int src_length)
484{
485    SHA256Context ctx;
486    unsigned int outLen;
487
488    SHA256_Begin(&ctx);
489    SHA256_Update(&ctx, src, src_length);
490    SHA256_End(&ctx, dest, &outLen, SHA256_LENGTH);
491
492    return SECSuccess;
493}
494
495
496SECStatus
497SHA256_Hash(unsigned char *dest, const char *src)
498{
499    return SHA256_HashBuf(dest, (const unsigned char *)src, PORT_Strlen(src));
500}
501
502
503void SHA256_TraceState(SHA256Context *ctx) { }
504
505unsigned int
506SHA256_FlattenSize(SHA256Context *ctx)
507{
508    return sizeof *ctx;
509}
510
511SECStatus
512SHA256_Flatten(SHA256Context *ctx,unsigned char *space)
513{
514    PORT_Memcpy(space, ctx, sizeof *ctx);
515    return SECSuccess;
516}
517
518SHA256Context *
519SHA256_Resurrect(unsigned char *space, void *arg)
520{
521    SHA256Context *ctx = SHA256_NewContext();
522    if (ctx)
523	PORT_Memcpy(ctx, space, sizeof *ctx);
524    return ctx;
525}
526
527/* ======= SHA512 and SHA384 common constants and defines ================= */
528
529/* common #defines for SHA512 and SHA384 */
530#if defined(HAVE_LONG_LONG)
531#define ROTR64(x,n) ((x >> n) | (x << (64 - n)))
532#define ROTL64(x,n) ((x << n) | (x >> (64 - n)))
533
534#define S0(x) (ROTR64(x,28) ^ ROTR64(x,34) ^ ROTR64(x,39))
535#define S1(x) (ROTR64(x,14) ^ ROTR64(x,18) ^ ROTR64(x,41))
536#define s0(x) (t1 = x, ROTR64(t1, 1) ^ ROTR64(t1, 8) ^ SHR(t1,7))
537#define s1(x) (t2 = x, ROTR64(t2,19) ^ ROTR64(t2,61) ^ SHR(t2,6))
538
539#if PR_BYTES_PER_LONG == 8
540#define ULLC(hi,lo) 0x ## hi ## lo ## UL
541#elif defined(_MSC_VER)
542#define ULLC(hi,lo) 0x ## hi ## lo ## ui64
543#else
544#define ULLC(hi,lo) 0x ## hi ## lo ## ULL
545#endif
546
547#define SHA_MASK16 ULLC(0000FFFF,0000FFFF)
548#define SHA_MASK8  ULLC(00FF00FF,00FF00FF)
549#define SHA_HTONLL(x) (t1 = x, \
550  t1 = ((t1 & SHA_MASK8 ) <<  8) | ((t1 >>  8) & SHA_MASK8 ), \
551  t1 = ((t1 & SHA_MASK16) << 16) | ((t1 >> 16) & SHA_MASK16), \
552  (t1 >> 32) | (t1 << 32))
553#define BYTESWAP8(x)  x = SHA_HTONLL(x)
554
555#else /* no long long */
556
557#if defined(IS_LITTLE_ENDIAN)
558#define ULLC(hi,lo) { 0x ## lo ## U, 0x ## hi ## U }
559#else
560#define ULLC(hi,lo) { 0x ## hi ## U, 0x ## lo ## U }
561#endif
562
563#define SHA_HTONLL(x) ( BYTESWAP4(x.lo), BYTESWAP4(x.hi), \
564   x.hi ^= x.lo ^= x.hi ^= x.lo, x)
565#define BYTESWAP8(x)  do { PRUint32 tmp; BYTESWAP4(x.lo); BYTESWAP4(x.hi); \
566   tmp = x.lo; x.lo = x.hi; x.hi = tmp; } while (0)
567#endif
568
569/* SHA-384 and SHA-512 constants, K512. */
570static const PRUint64 K512[80] = {
571#if PR_BYTES_PER_LONG == 8
572     0x428a2f98d728ae22UL ,  0x7137449123ef65cdUL ,
573     0xb5c0fbcfec4d3b2fUL ,  0xe9b5dba58189dbbcUL ,
574     0x3956c25bf348b538UL ,  0x59f111f1b605d019UL ,
575     0x923f82a4af194f9bUL ,  0xab1c5ed5da6d8118UL ,
576     0xd807aa98a3030242UL ,  0x12835b0145706fbeUL ,
577     0x243185be4ee4b28cUL ,  0x550c7dc3d5ffb4e2UL ,
578     0x72be5d74f27b896fUL ,  0x80deb1fe3b1696b1UL ,
579     0x9bdc06a725c71235UL ,  0xc19bf174cf692694UL ,
580     0xe49b69c19ef14ad2UL ,  0xefbe4786384f25e3UL ,
581     0x0fc19dc68b8cd5b5UL ,  0x240ca1cc77ac9c65UL ,
582     0x2de92c6f592b0275UL ,  0x4a7484aa6ea6e483UL ,
583     0x5cb0a9dcbd41fbd4UL ,  0x76f988da831153b5UL ,
584     0x983e5152ee66dfabUL ,  0xa831c66d2db43210UL ,
585     0xb00327c898fb213fUL ,  0xbf597fc7beef0ee4UL ,
586     0xc6e00bf33da88fc2UL ,  0xd5a79147930aa725UL ,
587     0x06ca6351e003826fUL ,  0x142929670a0e6e70UL ,
588     0x27b70a8546d22ffcUL ,  0x2e1b21385c26c926UL ,
589     0x4d2c6dfc5ac42aedUL ,  0x53380d139d95b3dfUL ,
590     0x650a73548baf63deUL ,  0x766a0abb3c77b2a8UL ,
591     0x81c2c92e47edaee6UL ,  0x92722c851482353bUL ,
592     0xa2bfe8a14cf10364UL ,  0xa81a664bbc423001UL ,
593     0xc24b8b70d0f89791UL ,  0xc76c51a30654be30UL ,
594     0xd192e819d6ef5218UL ,  0xd69906245565a910UL ,
595     0xf40e35855771202aUL ,  0x106aa07032bbd1b8UL ,
596     0x19a4c116b8d2d0c8UL ,  0x1e376c085141ab53UL ,
597     0x2748774cdf8eeb99UL ,  0x34b0bcb5e19b48a8UL ,
598     0x391c0cb3c5c95a63UL ,  0x4ed8aa4ae3418acbUL ,
599     0x5b9cca4f7763e373UL ,  0x682e6ff3d6b2b8a3UL ,
600     0x748f82ee5defb2fcUL ,  0x78a5636f43172f60UL ,
601     0x84c87814a1f0ab72UL ,  0x8cc702081a6439ecUL ,
602     0x90befffa23631e28UL ,  0xa4506cebde82bde9UL ,
603     0xbef9a3f7b2c67915UL ,  0xc67178f2e372532bUL ,
604     0xca273eceea26619cUL ,  0xd186b8c721c0c207UL ,
605     0xeada7dd6cde0eb1eUL ,  0xf57d4f7fee6ed178UL ,
606     0x06f067aa72176fbaUL ,  0x0a637dc5a2c898a6UL ,
607     0x113f9804bef90daeUL ,  0x1b710b35131c471bUL ,
608     0x28db77f523047d84UL ,  0x32caab7b40c72493UL ,
609     0x3c9ebe0a15c9bebcUL ,  0x431d67c49c100d4cUL ,
610     0x4cc5d4becb3e42b6UL ,  0x597f299cfc657e2aUL ,
611     0x5fcb6fab3ad6faecUL ,  0x6c44198c4a475817UL
612#else
613    ULLC(428a2f98,d728ae22), ULLC(71374491,23ef65cd),
614    ULLC(b5c0fbcf,ec4d3b2f), ULLC(e9b5dba5,8189dbbc),
615    ULLC(3956c25b,f348b538), ULLC(59f111f1,b605d019),
616    ULLC(923f82a4,af194f9b), ULLC(ab1c5ed5,da6d8118),
617    ULLC(d807aa98,a3030242), ULLC(12835b01,45706fbe),
618    ULLC(243185be,4ee4b28c), ULLC(550c7dc3,d5ffb4e2),
619    ULLC(72be5d74,f27b896f), ULLC(80deb1fe,3b1696b1),
620    ULLC(9bdc06a7,25c71235), ULLC(c19bf174,cf692694),
621    ULLC(e49b69c1,9ef14ad2), ULLC(efbe4786,384f25e3),
622    ULLC(0fc19dc6,8b8cd5b5), ULLC(240ca1cc,77ac9c65),
623    ULLC(2de92c6f,592b0275), ULLC(4a7484aa,6ea6e483),
624    ULLC(5cb0a9dc,bd41fbd4), ULLC(76f988da,831153b5),
625    ULLC(983e5152,ee66dfab), ULLC(a831c66d,2db43210),
626    ULLC(b00327c8,98fb213f), ULLC(bf597fc7,beef0ee4),
627    ULLC(c6e00bf3,3da88fc2), ULLC(d5a79147,930aa725),
628    ULLC(06ca6351,e003826f), ULLC(14292967,0a0e6e70),
629    ULLC(27b70a85,46d22ffc), ULLC(2e1b2138,5c26c926),
630    ULLC(4d2c6dfc,5ac42aed), ULLC(53380d13,9d95b3df),
631    ULLC(650a7354,8baf63de), ULLC(766a0abb,3c77b2a8),
632    ULLC(81c2c92e,47edaee6), ULLC(92722c85,1482353b),
633    ULLC(a2bfe8a1,4cf10364), ULLC(a81a664b,bc423001),
634    ULLC(c24b8b70,d0f89791), ULLC(c76c51a3,0654be30),
635    ULLC(d192e819,d6ef5218), ULLC(d6990624,5565a910),
636    ULLC(f40e3585,5771202a), ULLC(106aa070,32bbd1b8),
637    ULLC(19a4c116,b8d2d0c8), ULLC(1e376c08,5141ab53),
638    ULLC(2748774c,df8eeb99), ULLC(34b0bcb5,e19b48a8),
639    ULLC(391c0cb3,c5c95a63), ULLC(4ed8aa4a,e3418acb),
640    ULLC(5b9cca4f,7763e373), ULLC(682e6ff3,d6b2b8a3),
641    ULLC(748f82ee,5defb2fc), ULLC(78a5636f,43172f60),
642    ULLC(84c87814,a1f0ab72), ULLC(8cc70208,1a6439ec),
643    ULLC(90befffa,23631e28), ULLC(a4506ceb,de82bde9),
644    ULLC(bef9a3f7,b2c67915), ULLC(c67178f2,e372532b),
645    ULLC(ca273ece,ea26619c), ULLC(d186b8c7,21c0c207),
646    ULLC(eada7dd6,cde0eb1e), ULLC(f57d4f7f,ee6ed178),
647    ULLC(06f067aa,72176fba), ULLC(0a637dc5,a2c898a6),
648    ULLC(113f9804,bef90dae), ULLC(1b710b35,131c471b),
649    ULLC(28db77f5,23047d84), ULLC(32caab7b,40c72493),
650    ULLC(3c9ebe0a,15c9bebc), ULLC(431d67c4,9c100d4c),
651    ULLC(4cc5d4be,cb3e42b6), ULLC(597f299c,fc657e2a),
652    ULLC(5fcb6fab,3ad6faec), ULLC(6c44198c,4a475817)
653#endif
654};
655
656struct SHA512ContextStr {
657    union {
658	PRUint64 w[80];	    /* message schedule, input buffer, plus 64 words */
659	PRUint32 l[160];
660	PRUint8  b[640];
661    } u;
662    PRUint64 h[8];	    /* 8 state variables */
663    PRUint64 sizeLo;	    /* 64-bit count of hashed bytes. */
664};
665
666/* =========== SHA512 implementation ===================================== */
667
668/* SHA-512 initial hash values */
669static const PRUint64 H512[8] = {
670#if PR_BYTES_PER_LONG == 8
671     0x6a09e667f3bcc908UL ,  0xbb67ae8584caa73bUL ,
672     0x3c6ef372fe94f82bUL ,  0xa54ff53a5f1d36f1UL ,
673     0x510e527fade682d1UL ,  0x9b05688c2b3e6c1fUL ,
674     0x1f83d9abfb41bd6bUL ,  0x5be0cd19137e2179UL
675#else
676    ULLC(6a09e667,f3bcc908), ULLC(bb67ae85,84caa73b),
677    ULLC(3c6ef372,fe94f82b), ULLC(a54ff53a,5f1d36f1),
678    ULLC(510e527f,ade682d1), ULLC(9b05688c,2b3e6c1f),
679    ULLC(1f83d9ab,fb41bd6b), ULLC(5be0cd19,137e2179)
680#endif
681};
682
683
684SHA512Context *
685SHA512_NewContext(void)
686{
687    SHA512Context *ctx = PORT_New(SHA512Context);
688    return ctx;
689}
690
691void
692SHA512_DestroyContext(SHA512Context *ctx, PRBool freeit)
693{
694    if (freeit) {
695        PORT_ZFree(ctx, sizeof *ctx);
696    }
697}
698
699void
700SHA512_Begin(SHA512Context *ctx)
701{
702    memset(ctx, 0, sizeof *ctx);
703    memcpy(H, H512, sizeof H512);
704}
705
706#if defined(SHA512_TRACE)
707#if defined(HAVE_LONG_LONG)
708#define DUMP(n,a,d,e,h) printf(" t = %2d, %s = %016lx, %s = %016lx\n", \
709			       n, #e, d, #a, h);
710#else
711#define DUMP(n,a,d,e,h) printf(" t = %2d, %s = %08x%08x, %s = %08x%08x\n", \
712			       n, #e, d.hi, d.lo, #a, h.hi, h.lo);
713#endif
714#else
715#define DUMP(n,a,d,e,h)
716#endif
717
718#if defined(HAVE_LONG_LONG)
719
720#define ADDTO(x,y) y += x
721
722#define INITW(t) W[t] = (s1(W[t-2]) + W[t-7] + s0(W[t-15]) + W[t-16])
723
724#define ROUND(n,a,b,c,d,e,f,g,h) \
725    h += S1(e) + Ch(e,f,g) + K512[n] + W[n]; \
726    d += h; \
727    h += S0(a) + Maj(a,b,c); \
728    DUMP(n,a,d,e,h)
729
730#else /* use only 32-bit variables, and don't unroll loops */
731
732#undef  NOUNROLL512
733#define NOUNROLL512 1
734
735#define ADDTO(x,y) y.lo += x.lo; y.hi += x.hi + (x.lo > y.lo)
736
737#define ROTR64a(x,n,lo,hi) (x.lo >> n | x.hi << (32-n))
738#define ROTR64A(x,n,lo,hi) (x.lo << (64-n) | x.hi >> (n-32))
739#define  SHR64a(x,n,lo,hi) (x.lo >> n | x.hi << (32-n))
740
741/* Capitol Sigma and lower case sigma functions */
742#define s0lo(x) (ROTR64a(x,1,lo,hi) ^ ROTR64a(x,8,lo,hi) ^ SHR64a(x,7,lo,hi))
743#define s0hi(x) (ROTR64a(x,1,hi,lo) ^ ROTR64a(x,8,hi,lo) ^ (x.hi >> 7))
744
745#define s1lo(x) (ROTR64a(x,19,lo,hi) ^ ROTR64A(x,61,lo,hi) ^ SHR64a(x,6,lo,hi))
746#define s1hi(x) (ROTR64a(x,19,hi,lo) ^ ROTR64A(x,61,hi,lo) ^ (x.hi >> 6))
747
748#define S0lo(x)(ROTR64a(x,28,lo,hi) ^ ROTR64A(x,34,lo,hi) ^ ROTR64A(x,39,lo,hi))
749#define S0hi(x)(ROTR64a(x,28,hi,lo) ^ ROTR64A(x,34,hi,lo) ^ ROTR64A(x,39,hi,lo))
750
751#define S1lo(x)(ROTR64a(x,14,lo,hi) ^ ROTR64a(x,18,lo,hi) ^ ROTR64A(x,41,lo,hi))
752#define S1hi(x)(ROTR64a(x,14,hi,lo) ^ ROTR64a(x,18,hi,lo) ^ ROTR64A(x,41,hi,lo))
753
754/* 32-bit versions of Ch and Maj */
755#define Chxx(x,y,z,lo) ((x.lo & y.lo) ^ (~x.lo & z.lo))
756#define Majx(x,y,z,lo) ((x.lo & y.lo) ^ (x.lo & z.lo) ^ (y.lo & z.lo))
757
758#define INITW(t) \
759    do { \
760	PRUint32 lo, tm; \
761	PRUint32 cy = 0; \
762	lo = s1lo(W[t-2]); \
763	lo += (tm = W[t-7].lo);     if (lo < tm) cy++; \
764	lo += (tm = s0lo(W[t-15])); if (lo < tm) cy++; \
765	lo += (tm = W[t-16].lo);    if (lo < tm) cy++; \
766	W[t].lo = lo; \
767	W[t].hi = cy + s1hi(W[t-2]) + W[t-7].hi + s0hi(W[t-15]) + W[t-16].hi; \
768    } while (0)
769
770#define ROUND(n,a,b,c,d,e,f,g,h) \
771    { \
772	PRUint32 lo, tm, cy; \
773	lo  = S1lo(e); \
774	lo += (tm = Chxx(e,f,g,lo));    cy = (lo < tm); \
775	lo += (tm = K512[n].lo);	if (lo < tm) cy++; \
776	lo += (tm =    W[n].lo);	if (lo < tm) cy++; \
777	h.lo += lo;			if (h.lo < lo) cy++; \
778	h.hi += cy + S1hi(e) + Chxx(e,f,g,hi) + K512[n].hi + W[n].hi; \
779	d.lo += h.lo; \
780	d.hi += h.hi + (d.lo < h.lo); \
781	lo  = S0lo(a);  \
782	lo += (tm = Majx(a,b,c,lo));	cy = (lo < tm); \
783	h.lo += lo;			if (h.lo < lo) cy++; \
784	h.hi += cy + S0hi(a) + Majx(a,b,c,hi); \
785	DUMP(n,a,d,e,h) \
786    }
787#endif
788
789static void
790SHA512_Compress(SHA512Context *ctx)
791{
792#if defined(IS_LITTLE_ENDIAN)
793  {
794#if defined(HAVE_LONG_LONG)
795    PRUint64 t1;
796#else
797    PRUint32 t1;
798#endif
799    BYTESWAP8(W[0]);
800    BYTESWAP8(W[1]);
801    BYTESWAP8(W[2]);
802    BYTESWAP8(W[3]);
803    BYTESWAP8(W[4]);
804    BYTESWAP8(W[5]);
805    BYTESWAP8(W[6]);
806    BYTESWAP8(W[7]);
807    BYTESWAP8(W[8]);
808    BYTESWAP8(W[9]);
809    BYTESWAP8(W[10]);
810    BYTESWAP8(W[11]);
811    BYTESWAP8(W[12]);
812    BYTESWAP8(W[13]);
813    BYTESWAP8(W[14]);
814    BYTESWAP8(W[15]);
815  }
816#endif
817
818  {
819    PRUint64 t1, t2;
820#ifdef NOUNROLL512
821    {
822	/* prepare the "message schedule"   */
823	int t;
824	for (t = 16; t < 80; ++t) {
825	    INITW(t);
826	}
827    }
828#else
829    INITW(16);
830    INITW(17);
831    INITW(18);
832    INITW(19);
833
834    INITW(20);
835    INITW(21);
836    INITW(22);
837    INITW(23);
838    INITW(24);
839    INITW(25);
840    INITW(26);
841    INITW(27);
842    INITW(28);
843    INITW(29);
844
845    INITW(30);
846    INITW(31);
847    INITW(32);
848    INITW(33);
849    INITW(34);
850    INITW(35);
851    INITW(36);
852    INITW(37);
853    INITW(38);
854    INITW(39);
855
856    INITW(40);
857    INITW(41);
858    INITW(42);
859    INITW(43);
860    INITW(44);
861    INITW(45);
862    INITW(46);
863    INITW(47);
864    INITW(48);
865    INITW(49);
866
867    INITW(50);
868    INITW(51);
869    INITW(52);
870    INITW(53);
871    INITW(54);
872    INITW(55);
873    INITW(56);
874    INITW(57);
875    INITW(58);
876    INITW(59);
877
878    INITW(60);
879    INITW(61);
880    INITW(62);
881    INITW(63);
882    INITW(64);
883    INITW(65);
884    INITW(66);
885    INITW(67);
886    INITW(68);
887    INITW(69);
888
889    INITW(70);
890    INITW(71);
891    INITW(72);
892    INITW(73);
893    INITW(74);
894    INITW(75);
895    INITW(76);
896    INITW(77);
897    INITW(78);
898    INITW(79);
899#endif
900  }
901#ifdef SHA512_TRACE
902  {
903    int i;
904    for (i = 0; i < 80; ++i) {
905#ifdef HAVE_LONG_LONG
906	printf("W[%2d] = %016lx\n", i, W[i]);
907#else
908	printf("W[%2d] = %08x%08x\n", i, W[i].hi, W[i].lo);
909#endif
910    }
911  }
912#endif
913  {
914    PRUint64 a, b, c, d, e, f, g, h;
915
916    a = H[0];
917    b = H[1];
918    c = H[2];
919    d = H[3];
920    e = H[4];
921    f = H[5];
922    g = H[6];
923    h = H[7];
924
925#ifdef NOUNROLL512
926    {
927	int t;
928	for (t = 0; t < 80; t+= 8) {
929	    ROUND(t+0,a,b,c,d,e,f,g,h)
930	    ROUND(t+1,h,a,b,c,d,e,f,g)
931	    ROUND(t+2,g,h,a,b,c,d,e,f)
932	    ROUND(t+3,f,g,h,a,b,c,d,e)
933	    ROUND(t+4,e,f,g,h,a,b,c,d)
934	    ROUND(t+5,d,e,f,g,h,a,b,c)
935	    ROUND(t+6,c,d,e,f,g,h,a,b)
936	    ROUND(t+7,b,c,d,e,f,g,h,a)
937	}
938    }
939#else
940    ROUND( 0,a,b,c,d,e,f,g,h)
941    ROUND( 1,h,a,b,c,d,e,f,g)
942    ROUND( 2,g,h,a,b,c,d,e,f)
943    ROUND( 3,f,g,h,a,b,c,d,e)
944    ROUND( 4,e,f,g,h,a,b,c,d)
945    ROUND( 5,d,e,f,g,h,a,b,c)
946    ROUND( 6,c,d,e,f,g,h,a,b)
947    ROUND( 7,b,c,d,e,f,g,h,a)
948
949    ROUND( 8,a,b,c,d,e,f,g,h)
950    ROUND( 9,h,a,b,c,d,e,f,g)
951    ROUND(10,g,h,a,b,c,d,e,f)
952    ROUND(11,f,g,h,a,b,c,d,e)
953    ROUND(12,e,f,g,h,a,b,c,d)
954    ROUND(13,d,e,f,g,h,a,b,c)
955    ROUND(14,c,d,e,f,g,h,a,b)
956    ROUND(15,b,c,d,e,f,g,h,a)
957
958    ROUND(16,a,b,c,d,e,f,g,h)
959    ROUND(17,h,a,b,c,d,e,f,g)
960    ROUND(18,g,h,a,b,c,d,e,f)
961    ROUND(19,f,g,h,a,b,c,d,e)
962    ROUND(20,e,f,g,h,a,b,c,d)
963    ROUND(21,d,e,f,g,h,a,b,c)
964    ROUND(22,c,d,e,f,g,h,a,b)
965    ROUND(23,b,c,d,e,f,g,h,a)
966
967    ROUND(24,a,b,c,d,e,f,g,h)
968    ROUND(25,h,a,b,c,d,e,f,g)
969    ROUND(26,g,h,a,b,c,d,e,f)
970    ROUND(27,f,g,h,a,b,c,d,e)
971    ROUND(28,e,f,g,h,a,b,c,d)
972    ROUND(29,d,e,f,g,h,a,b,c)
973    ROUND(30,c,d,e,f,g,h,a,b)
974    ROUND(31,b,c,d,e,f,g,h,a)
975
976    ROUND(32,a,b,c,d,e,f,g,h)
977    ROUND(33,h,a,b,c,d,e,f,g)
978    ROUND(34,g,h,a,b,c,d,e,f)
979    ROUND(35,f,g,h,a,b,c,d,e)
980    ROUND(36,e,f,g,h,a,b,c,d)
981    ROUND(37,d,e,f,g,h,a,b,c)
982    ROUND(38,c,d,e,f,g,h,a,b)
983    ROUND(39,b,c,d,e,f,g,h,a)
984
985    ROUND(40,a,b,c,d,e,f,g,h)
986    ROUND(41,h,a,b,c,d,e,f,g)
987    ROUND(42,g,h,a,b,c,d,e,f)
988    ROUND(43,f,g,h,a,b,c,d,e)
989    ROUND(44,e,f,g,h,a,b,c,d)
990    ROUND(45,d,e,f,g,h,a,b,c)
991    ROUND(46,c,d,e,f,g,h,a,b)
992    ROUND(47,b,c,d,e,f,g,h,a)
993
994    ROUND(48,a,b,c,d,e,f,g,h)
995    ROUND(49,h,a,b,c,d,e,f,g)
996    ROUND(50,g,h,a,b,c,d,e,f)
997    ROUND(51,f,g,h,a,b,c,d,e)
998    ROUND(52,e,f,g,h,a,b,c,d)
999    ROUND(53,d,e,f,g,h,a,b,c)
1000    ROUND(54,c,d,e,f,g,h,a,b)
1001    ROUND(55,b,c,d,e,f,g,h,a)
1002
1003    ROUND(56,a,b,c,d,e,f,g,h)
1004    ROUND(57,h,a,b,c,d,e,f,g)
1005    ROUND(58,g,h,a,b,c,d,e,f)
1006    ROUND(59,f,g,h,a,b,c,d,e)
1007    ROUND(60,e,f,g,h,a,b,c,d)
1008    ROUND(61,d,e,f,g,h,a,b,c)
1009    ROUND(62,c,d,e,f,g,h,a,b)
1010    ROUND(63,b,c,d,e,f,g,h,a)
1011
1012    ROUND(64,a,b,c,d,e,f,g,h)
1013    ROUND(65,h,a,b,c,d,e,f,g)
1014    ROUND(66,g,h,a,b,c,d,e,f)
1015    ROUND(67,f,g,h,a,b,c,d,e)
1016    ROUND(68,e,f,g,h,a,b,c,d)
1017    ROUND(69,d,e,f,g,h,a,b,c)
1018    ROUND(70,c,d,e,f,g,h,a,b)
1019    ROUND(71,b,c,d,e,f,g,h,a)
1020
1021    ROUND(72,a,b,c,d,e,f,g,h)
1022    ROUND(73,h,a,b,c,d,e,f,g)
1023    ROUND(74,g,h,a,b,c,d,e,f)
1024    ROUND(75,f,g,h,a,b,c,d,e)
1025    ROUND(76,e,f,g,h,a,b,c,d)
1026    ROUND(77,d,e,f,g,h,a,b,c)
1027    ROUND(78,c,d,e,f,g,h,a,b)
1028    ROUND(79,b,c,d,e,f,g,h,a)
1029#endif
1030
1031    ADDTO(a,H[0]);
1032    ADDTO(b,H[1]);
1033    ADDTO(c,H[2]);
1034    ADDTO(d,H[3]);
1035    ADDTO(e,H[4]);
1036    ADDTO(f,H[5]);
1037    ADDTO(g,H[6]);
1038    ADDTO(h,H[7]);
1039  }
1040}
1041
1042void
1043SHA512_Update(SHA512Context *ctx, const unsigned char *input,
1044              unsigned int inputLen)
1045{
1046    unsigned int inBuf;
1047    if (!inputLen)
1048    	return;
1049
1050#if defined(HAVE_LONG_LONG)
1051    inBuf = (unsigned int)ctx->sizeLo & 0x7f;
1052    /* Add inputLen into the count of bytes processed, before processing */
1053    ctx->sizeLo += inputLen;
1054#else
1055    inBuf = (unsigned int)ctx->sizeLo.lo & 0x7f;
1056    ctx->sizeLo.lo += inputLen;
1057    if (ctx->sizeLo.lo < inputLen) ctx->sizeLo.hi++;
1058#endif
1059
1060    /* if data already in buffer, attemp to fill rest of buffer */
1061    if (inBuf) {
1062    	unsigned int todo = SHA512_BLOCK_LENGTH - inBuf;
1063	if (inputLen < todo)
1064	    todo = inputLen;
1065	memcpy(B + inBuf, input, todo);
1066	input    += todo;
1067	inputLen -= todo;
1068	if (inBuf + todo == SHA512_BLOCK_LENGTH)
1069	    SHA512_Compress(ctx);
1070    }
1071
1072    /* if enough data to fill one or more whole buffers, process them. */
1073    while (inputLen >= SHA512_BLOCK_LENGTH) {
1074    	memcpy(B, input, SHA512_BLOCK_LENGTH);
1075	input    += SHA512_BLOCK_LENGTH;
1076	inputLen -= SHA512_BLOCK_LENGTH;
1077	SHA512_Compress(ctx);
1078    }
1079    /* if data left over, fill it into buffer */
1080    if (inputLen)
1081    	memcpy(B, input, inputLen);
1082}
1083
1084void
1085SHA512_End(SHA512Context *ctx, unsigned char *digest,
1086           unsigned int *digestLen, unsigned int maxDigestLen)
1087{
1088#if defined(HAVE_LONG_LONG)
1089    unsigned int inBuf  = (unsigned int)ctx->sizeLo & 0x7f;
1090    unsigned int padLen = (inBuf < 112) ? (112 - inBuf) : (112 + 128 - inBuf);
1091    PRUint64 lo, t1;
1092    lo = (ctx->sizeLo << 3);
1093#else
1094    unsigned int inBuf  = (unsigned int)ctx->sizeLo.lo & 0x7f;
1095    unsigned int padLen = (inBuf < 112) ? (112 - inBuf) : (112 + 128 - inBuf);
1096    PRUint64 lo = ctx->sizeLo;
1097    PRUint32 t1;
1098    lo.lo <<= 3;
1099#endif
1100
1101    SHA512_Update(ctx, pad, padLen);
1102
1103#if defined(HAVE_LONG_LONG)
1104    W[14] = 0;
1105#else
1106    W[14].lo = 0;
1107    W[14].hi = 0;
1108#endif
1109
1110    W[15] = lo;
1111#if defined(IS_LITTLE_ENDIAN)
1112    BYTESWAP8(W[15]);
1113#endif
1114    SHA512_Compress(ctx);
1115
1116    /* now output the answer */
1117#if defined(IS_LITTLE_ENDIAN)
1118    BYTESWAP8(H[0]);
1119    BYTESWAP8(H[1]);
1120    BYTESWAP8(H[2]);
1121    BYTESWAP8(H[3]);
1122    BYTESWAP8(H[4]);
1123    BYTESWAP8(H[5]);
1124    BYTESWAP8(H[6]);
1125    BYTESWAP8(H[7]);
1126#endif
1127    padLen = PR_MIN(SHA512_LENGTH, maxDigestLen);
1128    memcpy(digest, H, padLen);
1129    if (digestLen)
1130	*digestLen = padLen;
1131}
1132
1133SECStatus
1134SHA512_HashBuf(unsigned char *dest, const unsigned char *src,
1135               unsigned int src_length)
1136{
1137    SHA512Context ctx;
1138    unsigned int outLen;
1139
1140    SHA512_Begin(&ctx);
1141    SHA512_Update(&ctx, src, src_length);
1142    SHA512_End(&ctx, dest, &outLen, SHA512_LENGTH);
1143
1144    return SECSuccess;
1145}
1146
1147
1148SECStatus
1149SHA512_Hash(unsigned char *dest, const char *src)
1150{
1151    return SHA512_HashBuf(dest, (const unsigned char *)src, PORT_Strlen(src));
1152}
1153
1154
1155void SHA512_TraceState(SHA512Context *ctx) { }
1156
1157unsigned int
1158SHA512_FlattenSize(SHA512Context *ctx)
1159{
1160    return sizeof *ctx;
1161}
1162
1163SECStatus
1164SHA512_Flatten(SHA512Context *ctx,unsigned char *space)
1165{
1166    PORT_Memcpy(space, ctx, sizeof *ctx);
1167    return SECSuccess;
1168}
1169
1170SHA512Context *
1171SHA512_Resurrect(unsigned char *space, void *arg)
1172{
1173    SHA512Context *ctx = SHA512_NewContext();
1174    if (ctx)
1175	PORT_Memcpy(ctx, space, sizeof *ctx);
1176    return ctx;
1177}
1178
1179void SHA512_Clone(SHA512Context *dest, SHA512Context *src)
1180{
1181    memcpy(dest, src, sizeof *dest);
1182}
1183
1184/* ======================================================================= */
1185/* SHA384 uses a SHA512Context as the real context.
1186** The only differences between SHA384 an SHA512 are:
1187** a) the intialization values for the context, and
1188** b) the number of bytes of data produced as output.
1189*/
1190
1191/* SHA-384 initial hash values */
1192static const PRUint64 H384[8] = {
1193#if PR_BYTES_PER_LONG == 8
1194     0xcbbb9d5dc1059ed8UL ,  0x629a292a367cd507UL ,
1195     0x9159015a3070dd17UL ,  0x152fecd8f70e5939UL ,
1196     0x67332667ffc00b31UL ,  0x8eb44a8768581511UL ,
1197     0xdb0c2e0d64f98fa7UL ,  0x47b5481dbefa4fa4UL
1198#else
1199    ULLC(cbbb9d5d,c1059ed8), ULLC(629a292a,367cd507),
1200    ULLC(9159015a,3070dd17), ULLC(152fecd8,f70e5939),
1201    ULLC(67332667,ffc00b31), ULLC(8eb44a87,68581511),
1202    ULLC(db0c2e0d,64f98fa7), ULLC(47b5481d,befa4fa4)
1203#endif
1204};
1205
1206SHA384Context *
1207SHA384_NewContext(void)
1208{
1209    return SHA512_NewContext();
1210}
1211
1212void
1213SHA384_DestroyContext(SHA384Context *ctx, PRBool freeit)
1214{
1215    SHA512_DestroyContext(ctx, freeit);
1216}
1217
1218void
1219SHA384_Begin(SHA384Context *ctx)
1220{
1221    memset(ctx, 0, sizeof *ctx);
1222    memcpy(H, H384, sizeof H384);
1223}
1224
1225void
1226SHA384_Update(SHA384Context *ctx, const unsigned char *input,
1227		    unsigned int inputLen)
1228{
1229    SHA512_Update(ctx, input, inputLen);
1230}
1231
1232void
1233SHA384_End(SHA384Context *ctx, unsigned char *digest,
1234		 unsigned int *digestLen, unsigned int maxDigestLen)
1235{
1236#define SHA_MIN(a,b) (a < b ? a : b)
1237    unsigned int maxLen = SHA_MIN(maxDigestLen, SHA384_LENGTH);
1238    SHA512_End(ctx, digest, digestLen, maxLen);
1239}
1240
1241SECStatus
1242SHA384_HashBuf(unsigned char *dest, const unsigned char *src,
1243			  unsigned int src_length)
1244{
1245    SHA512Context ctx;
1246    unsigned int outLen;
1247
1248    SHA384_Begin(&ctx);
1249    SHA512_Update(&ctx, src, src_length);
1250    SHA512_End(&ctx, dest, &outLen, SHA384_LENGTH);
1251
1252    return SECSuccess;
1253}
1254
1255SECStatus
1256SHA384_Hash(unsigned char *dest, const char *src)
1257{
1258    return SHA384_HashBuf(dest, (const unsigned char *)src, PORT_Strlen(src));
1259}
1260
1261void SHA384_TraceState(SHA384Context *ctx) { }
1262
1263unsigned int
1264SHA384_FlattenSize(SHA384Context *ctx)
1265{
1266    return sizeof(SHA384Context);
1267}
1268
1269SECStatus
1270SHA384_Flatten(SHA384Context *ctx,unsigned char *space)
1271{
1272    return SHA512_Flatten(ctx, space);
1273}
1274
1275SHA384Context *
1276SHA384_Resurrect(unsigned char *space, void *arg)
1277{
1278    return SHA512_Resurrect(space, arg);
1279}
1280
1281void SHA384_Clone(SHA384Context *dest, SHA384Context *src)
1282{
1283    memcpy(dest, src, sizeof *dest);
1284}
1285#endif  /* Comment out unused code. */
1286
1287/* ======================================================================= */
1288#ifdef SELFTEST
1289#include <stdio.h>
1290
1291static const char abc[] = { "abc" };
1292static const char abcdbc[] = {
1293    "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"
1294};
1295static const char abcdef[] = {
1296    "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmn"
1297    "hijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu"
1298};
1299
1300void
1301dumpHash32(const unsigned char *buf, unsigned int bufLen)
1302{
1303    unsigned int i;
1304    for (i = 0; i < bufLen; i += 4) {
1305	printf(" %02x%02x%02x%02x", buf[i], buf[i+1], buf[i+2], buf[i+3]);
1306    }
1307    printf("\n");
1308}
1309
1310void test256(void)
1311{
1312    unsigned char outBuf[SHA256_LENGTH];
1313
1314    printf("SHA256, input = %s\n", abc);
1315    SHA256_Hash(outBuf, abc);
1316    dumpHash32(outBuf, sizeof outBuf);
1317
1318    printf("SHA256, input = %s\n", abcdbc);
1319    SHA256_Hash(outBuf, abcdbc);
1320    dumpHash32(outBuf, sizeof outBuf);
1321}
1322
1323void
1324dumpHash64(const unsigned char *buf, unsigned int bufLen)
1325{
1326    unsigned int i;
1327    for (i = 0; i < bufLen; i += 8) {
1328    	if (i % 32 == 0)
1329	    printf("\n");
1330	printf(" %02x%02x%02x%02x%02x%02x%02x%02x",
1331	       buf[i  ], buf[i+1], buf[i+2], buf[i+3],
1332	       buf[i+4], buf[i+5], buf[i+6], buf[i+7]);
1333    }
1334    printf("\n");
1335}
1336
1337void test512(void)
1338{
1339    unsigned char outBuf[SHA512_LENGTH];
1340
1341    printf("SHA512, input = %s\n", abc);
1342    SHA512_Hash(outBuf, abc);
1343    dumpHash64(outBuf, sizeof outBuf);
1344
1345    printf("SHA512, input = %s\n", abcdef);
1346    SHA512_Hash(outBuf, abcdef);
1347    dumpHash64(outBuf, sizeof outBuf);
1348}
1349
1350void time512(void)
1351{
1352    unsigned char outBuf[SHA512_LENGTH];
1353
1354    SHA512_Hash(outBuf, abc);
1355    SHA512_Hash(outBuf, abcdef);
1356}
1357
1358void test384(void)
1359{
1360    unsigned char outBuf[SHA384_LENGTH];
1361
1362    printf("SHA384, input = %s\n", abc);
1363    SHA384_Hash(outBuf, abc);
1364    dumpHash64(outBuf, sizeof outBuf);
1365
1366    printf("SHA384, input = %s\n", abcdef);
1367    SHA384_Hash(outBuf, abcdef);
1368    dumpHash64(outBuf, sizeof outBuf);
1369}
1370
1371int main (int argc, char *argv[], char *envp[])
1372{
1373    int i = 1;
1374    if (argc > 1) {
1375    	i = atoi(argv[1]);
1376    }
1377    if (i < 2) {
1378	test256();
1379	test512();
1380	test384();
1381    } else {
1382    	while (i-- > 0) {
1383	    time512();
1384	}
1385	printf("done\n");
1386    }
1387    return 0;
1388}
1389
1390#endif
1391