Back to index

lightning-sunbird  0.9+nobinonly
sha512.c
Go to the documentation of this file.
00001 /*
00002  * sha512.c - implementation of SHA256, SHA384 and SHA512
00003  *
00004  * ***** BEGIN LICENSE BLOCK *****
00005  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00006  *
00007  * The contents of this file are subject to the Mozilla Public License Version
00008  * 1.1 (the "License"); you may not use this file except in compliance with
00009  * the License. You may obtain a copy of the License at
00010  * http://www.mozilla.org/MPL/
00011  *
00012  * Software distributed under the License is distributed on an "AS IS" basis,
00013  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00014  * for the specific language governing rights and limitations under the
00015  * License.
00016  *
00017  * The Original Code is the Netscape security libraries.
00018  *
00019  * The Initial Developer of the Original Code is
00020  * Netscape Communications Corporation.
00021  * Portions created by the Initial Developer are Copyright (C) 2002
00022  * the Initial Developer. All Rights Reserved.
00023  *
00024  * Contributor(s):
00025  *
00026  * Alternatively, the contents of this file may be used under the terms of
00027  * either the GNU General Public License Version 2 or later (the "GPL"), or
00028  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00029  * in which case the provisions of the GPL or the LGPL are applicable instead
00030  * of those above. If you wish to allow use of your version of this file only
00031  * under the terms of either the GPL or the LGPL, and not to allow others to
00032  * use your version of this file under the terms of the MPL, indicate your
00033  * decision by deleting the provisions above and replace them with the notice
00034  * and other provisions required by the GPL or the LGPL. If you do not delete
00035  * the provisions above, a recipient may use your version of this file under
00036  * the terms of any one of the MPL, the GPL or the LGPL.
00037  *
00038  * ***** END LICENSE BLOCK ***** */
00039 /* $Id: sha512.c,v 1.8.2.1 2006/10/13 17:02:58 wtchang%redhat.com Exp $ */
00040 #include "prcpucfg.h"
00041 #if defined(_X86_) || defined(SHA_NO_LONG_LONG)
00042 #define NOUNROLL512 1
00043 #undef HAVE_LONG_LONG
00044 #endif
00045 #include "prtypes.h" /* for PRUintXX */
00046 #include "secport.h" /* for PORT_XXX */
00047 #include "blapi.h"
00048 #include "sha256.h"  /* for struct SHA256ContextStr */
00049 
00050 /* ============= Common constants and defines ======================= */
00051 
00052 #define W ctx->u.w
00053 #define B ctx->u.b
00054 #define H ctx->h
00055 
00056 #define SHR(x,n) (x >> n)
00057 #define SHL(x,n) (x << n)
00058 #define Ch(x,y,z)  ((x & y) ^ (~x & z))
00059 #define Maj(x,y,z) ((x & y) ^ (x & z) ^ (y & z))
00060 
00061 /* Padding used with all flavors of SHA */
00062 static const PRUint8 pad[240] = { 
00063 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,
00064    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
00065    /* compiler will fill the rest in with zeros */
00066 };
00067 
00068 /* ============= SHA256 implemenmtation ================================== */
00069 
00070 /* SHA-256 constants, K256. */
00071 static const PRUint32 K256[64] = {
00072     0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 
00073     0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
00074     0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 
00075     0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
00076     0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 
00077     0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
00078     0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 
00079     0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
00080     0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 
00081     0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
00082     0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 
00083     0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
00084     0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 
00085     0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
00086     0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 
00087     0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
00088 };
00089 
00090 /* SHA-256 initial hash values */
00091 static const PRUint32 H256[8] = {
00092     0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 
00093     0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19
00094 };
00095 
00096 #if defined(_MSC_VER) && defined(_X86_)
00097 #ifndef FORCEINLINE
00098 #if (MSC_VER >= 1200)
00099 #define FORCEINLINE __forceinline
00100 #else
00101 #define FORCEINLINE __inline
00102 #endif
00103 #endif
00104 #define FASTCALL __fastcall
00105 
00106 static FORCEINLINE PRUint32 FASTCALL 
00107 swap4b(PRUint32 dwd) 
00108 {
00109     __asm {
00110        mov   eax,dwd
00111        bswap eax
00112     }
00113 }
00114 
00115 #define SHA_HTONL(x) swap4b(x)
00116 #define BYTESWAP4(x)  x = SHA_HTONL(x)
00117 
00118 #elif defined(LINUX) && defined(_X86_)
00119 #undef  __OPTIMIZE__
00120 #define __OPTIMIZE__ 1
00121 #undef  __pentium__
00122 #define __pentium__ 1
00123 #include <byteswap.h>
00124 #define SHA_HTONL(x) bswap_32(x)
00125 #define BYTESWAP4(x)  x = SHA_HTONL(x)
00126 
00127 #else /* neither windows nor Linux PC */
00128 #define SWAP4MASK  0x00FF00FF
00129 #define SHA_HTONL(x) (t1 = (x), t1 = (t1 << 16) | (t1 >> 16), \
00130                       ((t1 & SWAP4MASK) << 8) | ((t1 >> 8) & SWAP4MASK))
00131 #define BYTESWAP4(x)  x = SHA_HTONL(x)
00132 #endif
00133 
00134 #if defined(_MSC_VER) && defined(_X86_)
00135 #pragma intrinsic (_lrotr, _lrotl) 
00136 #define ROTR32(x,n) _lrotr(x,n)
00137 #define ROTL32(x,n) _lrotl(x,n)
00138 #else
00139 #define ROTR32(x,n) ((x >> n) | (x << ((8 * sizeof x) - n)))
00140 #define ROTL32(x,n) ((x << n) | (x >> ((8 * sizeof x) - n)))
00141 #endif
00142 
00143 /* Capitol Sigma and lower case sigma functions */
00144 #define S0(x) (ROTR32(x, 2) ^ ROTR32(x,13) ^ ROTR32(x,22))
00145 #define S1(x) (ROTR32(x, 6) ^ ROTR32(x,11) ^ ROTR32(x,25))
00146 #define s0(x) (t1 = x, ROTR32(t1, 7) ^ ROTR32(t1,18) ^ SHR(t1, 3))
00147 #define s1(x) (t2 = x, ROTR32(t2,17) ^ ROTR32(t2,19) ^ SHR(t2,10))
00148 
00149 SHA256Context *
00150 SHA256_NewContext(void)
00151 {
00152     SHA256Context *ctx = PORT_New(SHA256Context);
00153     return ctx;
00154 }
00155 
00156 void 
00157 SHA256_DestroyContext(SHA256Context *ctx, PRBool freeit)
00158 {
00159     if (freeit) {
00160         PORT_ZFree(ctx, sizeof *ctx);
00161     }
00162 }
00163 
00164 void 
00165 SHA256_Begin(SHA256Context *ctx)
00166 {
00167     memset(ctx, 0, sizeof *ctx);
00168     memcpy(H, H256, sizeof H256);
00169 }
00170 
00171 static void
00172 SHA256_Compress(SHA256Context *ctx)
00173 {
00174   {
00175     register PRUint32 t1, t2;
00176 
00177 #if defined(IS_LITTLE_ENDIAN)
00178     BYTESWAP4(W[0]);
00179     BYTESWAP4(W[1]);
00180     BYTESWAP4(W[2]);
00181     BYTESWAP4(W[3]);
00182     BYTESWAP4(W[4]);
00183     BYTESWAP4(W[5]);
00184     BYTESWAP4(W[6]);
00185     BYTESWAP4(W[7]);
00186     BYTESWAP4(W[8]);
00187     BYTESWAP4(W[9]);
00188     BYTESWAP4(W[10]);
00189     BYTESWAP4(W[11]);
00190     BYTESWAP4(W[12]);
00191     BYTESWAP4(W[13]);
00192     BYTESWAP4(W[14]);
00193     BYTESWAP4(W[15]);
00194 #endif
00195 
00196 #define INITW(t) W[t] = (s1(W[t-2]) + W[t-7] + s0(W[t-15]) + W[t-16])
00197 
00198     /* prepare the "message schedule"   */
00199 #ifdef NOUNROLL256
00200     {
00201        int t;
00202        for (t = 16; t < 64; ++t) {
00203            INITW(t);
00204        }
00205     }
00206 #else
00207     INITW(16);
00208     INITW(17);
00209     INITW(18);
00210     INITW(19);
00211 
00212     INITW(20);
00213     INITW(21);
00214     INITW(22);
00215     INITW(23);
00216     INITW(24);
00217     INITW(25);
00218     INITW(26);
00219     INITW(27);
00220     INITW(28);
00221     INITW(29);
00222 
00223     INITW(30);
00224     INITW(31);
00225     INITW(32);
00226     INITW(33);
00227     INITW(34);
00228     INITW(35);
00229     INITW(36);
00230     INITW(37);
00231     INITW(38);
00232     INITW(39);
00233 
00234     INITW(40);
00235     INITW(41);
00236     INITW(42);
00237     INITW(43);
00238     INITW(44);
00239     INITW(45);
00240     INITW(46);
00241     INITW(47);
00242     INITW(48);
00243     INITW(49);
00244 
00245     INITW(50);
00246     INITW(51);
00247     INITW(52);
00248     INITW(53);
00249     INITW(54);
00250     INITW(55);
00251     INITW(56);
00252     INITW(57);
00253     INITW(58);
00254     INITW(59);
00255 
00256     INITW(60);
00257     INITW(61);
00258     INITW(62);
00259     INITW(63);
00260 
00261 #endif
00262 #undef INITW
00263   }
00264   {
00265     PRUint32 a, b, c, d, e, f, g, h;
00266 
00267     a = H[0];
00268     b = H[1];
00269     c = H[2];
00270     d = H[3];
00271     e = H[4];
00272     f = H[5];
00273     g = H[6];
00274     h = H[7];
00275 
00276 #define ROUND(n,a,b,c,d,e,f,g,h) \
00277     h += S1(e) + Ch(e,f,g) + K256[n] + W[n]; \
00278     d += h; \
00279     h += S0(a) + Maj(a,b,c); 
00280 
00281 #ifdef NOUNROLL256
00282     {
00283        int t;
00284        for (t = 0; t < 64; t+= 8) {
00285            ROUND(t+0,a,b,c,d,e,f,g,h)
00286            ROUND(t+1,h,a,b,c,d,e,f,g)
00287            ROUND(t+2,g,h,a,b,c,d,e,f)
00288            ROUND(t+3,f,g,h,a,b,c,d,e)
00289            ROUND(t+4,e,f,g,h,a,b,c,d)
00290            ROUND(t+5,d,e,f,g,h,a,b,c)
00291            ROUND(t+6,c,d,e,f,g,h,a,b)
00292            ROUND(t+7,b,c,d,e,f,g,h,a)
00293        }
00294     }
00295 #else
00296     ROUND( 0,a,b,c,d,e,f,g,h)
00297     ROUND( 1,h,a,b,c,d,e,f,g)
00298     ROUND( 2,g,h,a,b,c,d,e,f)
00299     ROUND( 3,f,g,h,a,b,c,d,e)
00300     ROUND( 4,e,f,g,h,a,b,c,d)
00301     ROUND( 5,d,e,f,g,h,a,b,c)
00302     ROUND( 6,c,d,e,f,g,h,a,b)
00303     ROUND( 7,b,c,d,e,f,g,h,a)
00304 
00305     ROUND( 8,a,b,c,d,e,f,g,h)
00306     ROUND( 9,h,a,b,c,d,e,f,g)
00307     ROUND(10,g,h,a,b,c,d,e,f)
00308     ROUND(11,f,g,h,a,b,c,d,e)
00309     ROUND(12,e,f,g,h,a,b,c,d)
00310     ROUND(13,d,e,f,g,h,a,b,c)
00311     ROUND(14,c,d,e,f,g,h,a,b)
00312     ROUND(15,b,c,d,e,f,g,h,a)
00313 
00314     ROUND(16,a,b,c,d,e,f,g,h)
00315     ROUND(17,h,a,b,c,d,e,f,g)
00316     ROUND(18,g,h,a,b,c,d,e,f)
00317     ROUND(19,f,g,h,a,b,c,d,e)
00318     ROUND(20,e,f,g,h,a,b,c,d)
00319     ROUND(21,d,e,f,g,h,a,b,c)
00320     ROUND(22,c,d,e,f,g,h,a,b)
00321     ROUND(23,b,c,d,e,f,g,h,a)
00322 
00323     ROUND(24,a,b,c,d,e,f,g,h)
00324     ROUND(25,h,a,b,c,d,e,f,g)
00325     ROUND(26,g,h,a,b,c,d,e,f)
00326     ROUND(27,f,g,h,a,b,c,d,e)
00327     ROUND(28,e,f,g,h,a,b,c,d)
00328     ROUND(29,d,e,f,g,h,a,b,c)
00329     ROUND(30,c,d,e,f,g,h,a,b)
00330     ROUND(31,b,c,d,e,f,g,h,a)
00331 
00332     ROUND(32,a,b,c,d,e,f,g,h)
00333     ROUND(33,h,a,b,c,d,e,f,g)
00334     ROUND(34,g,h,a,b,c,d,e,f)
00335     ROUND(35,f,g,h,a,b,c,d,e)
00336     ROUND(36,e,f,g,h,a,b,c,d)
00337     ROUND(37,d,e,f,g,h,a,b,c)
00338     ROUND(38,c,d,e,f,g,h,a,b)
00339     ROUND(39,b,c,d,e,f,g,h,a)
00340 
00341     ROUND(40,a,b,c,d,e,f,g,h)
00342     ROUND(41,h,a,b,c,d,e,f,g)
00343     ROUND(42,g,h,a,b,c,d,e,f)
00344     ROUND(43,f,g,h,a,b,c,d,e)
00345     ROUND(44,e,f,g,h,a,b,c,d)
00346     ROUND(45,d,e,f,g,h,a,b,c)
00347     ROUND(46,c,d,e,f,g,h,a,b)
00348     ROUND(47,b,c,d,e,f,g,h,a)
00349 
00350     ROUND(48,a,b,c,d,e,f,g,h)
00351     ROUND(49,h,a,b,c,d,e,f,g)
00352     ROUND(50,g,h,a,b,c,d,e,f)
00353     ROUND(51,f,g,h,a,b,c,d,e)
00354     ROUND(52,e,f,g,h,a,b,c,d)
00355     ROUND(53,d,e,f,g,h,a,b,c)
00356     ROUND(54,c,d,e,f,g,h,a,b)
00357     ROUND(55,b,c,d,e,f,g,h,a)
00358 
00359     ROUND(56,a,b,c,d,e,f,g,h)
00360     ROUND(57,h,a,b,c,d,e,f,g)
00361     ROUND(58,g,h,a,b,c,d,e,f)
00362     ROUND(59,f,g,h,a,b,c,d,e)
00363     ROUND(60,e,f,g,h,a,b,c,d)
00364     ROUND(61,d,e,f,g,h,a,b,c)
00365     ROUND(62,c,d,e,f,g,h,a,b)
00366     ROUND(63,b,c,d,e,f,g,h,a)
00367 #endif
00368 
00369     H[0] += a;
00370     H[1] += b;
00371     H[2] += c;
00372     H[3] += d;
00373     H[4] += e;
00374     H[5] += f;
00375     H[6] += g;
00376     H[7] += h;
00377   }
00378 #undef ROUND
00379 }
00380 
00381 #undef s0
00382 #undef s1
00383 #undef S0
00384 #undef S1
00385 
00386 void 
00387 SHA256_Update(SHA256Context *ctx, const unsigned char *input,
00388                   unsigned int inputLen)
00389 {
00390     unsigned int inBuf = ctx->sizeLo & 0x3f;
00391     if (!inputLen)
00392        return;
00393 
00394     /* Add inputLen into the count of bytes processed, before processing */
00395     if ((ctx->sizeLo += inputLen) < inputLen)
00396        ctx->sizeHi++;
00397 
00398     /* if data already in buffer, attemp to fill rest of buffer */
00399     if (inBuf) {
00400        unsigned int todo = SHA256_BLOCK_LENGTH - inBuf;
00401        if (inputLen < todo)
00402            todo = inputLen;
00403        memcpy(B + inBuf, input, todo);
00404        input    += todo;
00405        inputLen -= todo;
00406        if (inBuf + todo == SHA256_BLOCK_LENGTH)
00407            SHA256_Compress(ctx);
00408     }
00409 
00410     /* if enough data to fill one or more whole buffers, process them. */
00411     while (inputLen >= SHA256_BLOCK_LENGTH) {
00412        memcpy(B, input, SHA256_BLOCK_LENGTH);
00413        input    += SHA256_BLOCK_LENGTH;
00414        inputLen -= SHA256_BLOCK_LENGTH;
00415        SHA256_Compress(ctx);
00416     }
00417     /* if data left over, fill it into buffer */
00418     if (inputLen) 
00419        memcpy(B, input, inputLen);
00420 }
00421 
00422 void 
00423 SHA256_End(SHA256Context *ctx, unsigned char *digest,
00424            unsigned int *digestLen, unsigned int maxDigestLen)
00425 {
00426     unsigned int inBuf = ctx->sizeLo & 0x3f;
00427     unsigned int padLen = (inBuf < 56) ? (56 - inBuf) : (56 + 64 - inBuf);
00428     PRUint32 hi, lo;
00429 #ifdef SWAP4MASK
00430     PRUint32 t1;
00431 #endif
00432 
00433     hi = (ctx->sizeHi << 3) | (ctx->sizeLo >> 29);
00434     lo = (ctx->sizeLo << 3);
00435 
00436     SHA256_Update(ctx, pad, padLen);
00437 
00438 #if defined(IS_LITTLE_ENDIAN)
00439     W[14] = SHA_HTONL(hi);
00440     W[15] = SHA_HTONL(lo);
00441 #else
00442     W[14] = hi;
00443     W[15] = lo;
00444 #endif
00445     SHA256_Compress(ctx);
00446 
00447     /* now output the answer */
00448 #if defined(IS_LITTLE_ENDIAN)
00449     BYTESWAP4(H[0]);
00450     BYTESWAP4(H[1]);
00451     BYTESWAP4(H[2]);
00452     BYTESWAP4(H[3]);
00453     BYTESWAP4(H[4]);
00454     BYTESWAP4(H[5]);
00455     BYTESWAP4(H[6]);
00456     BYTESWAP4(H[7]);
00457 #endif
00458     padLen = PR_MIN(SHA256_LENGTH, maxDigestLen);
00459     memcpy(digest, H, padLen);
00460     if (digestLen)
00461        *digestLen = padLen;
00462 }
00463 
00464 SECStatus 
00465 SHA256_HashBuf(unsigned char *dest, const unsigned char *src, 
00466                uint32 src_length)
00467 {
00468     SHA256Context ctx;
00469     unsigned int outLen;
00470 
00471     SHA256_Begin(&ctx);
00472     SHA256_Update(&ctx, src, src_length);
00473     SHA256_End(&ctx, dest, &outLen, SHA256_LENGTH);
00474 
00475     return SECSuccess;
00476 }
00477 
00478 
00479 SECStatus 
00480 SHA256_Hash(unsigned char *dest, const char *src)
00481 {
00482     return SHA256_HashBuf(dest, (const unsigned char *)src, PORT_Strlen(src));
00483 }
00484 
00485 
00486 void SHA256_TraceState(SHA256Context *ctx) { }
00487 
00488 unsigned int 
00489 SHA256_FlattenSize(SHA256Context *ctx)
00490 {
00491     return sizeof *ctx;
00492 }
00493 
00494 SECStatus 
00495 SHA256_Flatten(SHA256Context *ctx,unsigned char *space)
00496 {
00497     PORT_Memcpy(space, ctx, sizeof *ctx);
00498     return SECSuccess;
00499 }
00500 
00501 SHA256Context * 
00502 SHA256_Resurrect(unsigned char *space, void *arg)
00503 {
00504     SHA256Context *ctx = SHA256_NewContext();
00505     if (ctx) 
00506        PORT_Memcpy(ctx, space, sizeof *ctx);
00507     return ctx;
00508 }
00509 
00510 void SHA256_Clone(SHA256Context *dest, SHA256Context *src) 
00511 {
00512     memcpy(dest, src, sizeof *dest);
00513 }
00514 
00515 
00516 /* ======= SHA512 and SHA384 common constants and defines ================= */
00517 
00518 /* common #defines for SHA512 and SHA384 */
00519 #if defined(HAVE_LONG_LONG)
00520 #define ROTR64(x,n) ((x >> n) | (x << (64 - n)))
00521 #define ROTL64(x,n) ((x << n) | (x >> (64 - n)))
00522 
00523 #define S0(x) (ROTR64(x,28) ^ ROTR64(x,34) ^ ROTR64(x,39))
00524 #define S1(x) (ROTR64(x,14) ^ ROTR64(x,18) ^ ROTR64(x,41))
00525 #define s0(x) (t1 = x, ROTR64(t1, 1) ^ ROTR64(t1, 8) ^ SHR(t1,7))
00526 #define s1(x) (t2 = x, ROTR64(t2,19) ^ ROTR64(t2,61) ^ SHR(t2,6))
00527 
00528 #if PR_BYTES_PER_LONG == 8
00529 #define ULLC(hi,lo) 0x ## hi ## lo ## UL
00530 #elif defined(_MSC_VER)
00531 #define ULLC(hi,lo) 0x ## hi ## lo ## ui64
00532 #else
00533 #define ULLC(hi,lo) 0x ## hi ## lo ## ULL
00534 #endif
00535 
00536 #define SHA_MASK16 ULLC(0000FFFF,0000FFFF)
00537 #define SHA_MASK8  ULLC(00FF00FF,00FF00FF)
00538 #define SHA_HTONLL(x) (t1 = x, \
00539   t1 = ((t1 & SHA_MASK8 ) <<  8) | ((t1 >>  8) & SHA_MASK8 ), \
00540   t1 = ((t1 & SHA_MASK16) << 16) | ((t1 >> 16) & SHA_MASK16), \
00541   (t1 >> 32) | (t1 << 32))
00542 #define BYTESWAP8(x)  x = SHA_HTONLL(x)
00543 
00544 #else /* no long long */
00545 
00546 #if defined(IS_LITTLE_ENDIAN)
00547 #define ULLC(hi,lo) { 0x ## lo ## U, 0x ## hi ## U }
00548 #else
00549 #define ULLC(hi,lo) { 0x ## hi ## U, 0x ## lo ## U }
00550 #endif
00551 
00552 #define SHA_HTONLL(x) ( BYTESWAP4(x.lo), BYTESWAP4(x.hi), \
00553    x.hi ^= x.lo ^= x.hi ^= x.lo, x)
00554 #define BYTESWAP8(x)  do { PRUint32 tmp; BYTESWAP4(x.lo); BYTESWAP4(x.hi); \
00555    tmp = x.lo; x.lo = x.hi; x.hi = tmp; } while (0)
00556 #endif
00557 
00558 /* SHA-384 and SHA-512 constants, K512. */
00559 static const PRUint64 K512[80] = {
00560 #if PR_BYTES_PER_LONG == 8
00561      0x428a2f98d728ae22UL ,  0x7137449123ef65cdUL , 
00562      0xb5c0fbcfec4d3b2fUL ,  0xe9b5dba58189dbbcUL ,
00563      0x3956c25bf348b538UL ,  0x59f111f1b605d019UL , 
00564      0x923f82a4af194f9bUL ,  0xab1c5ed5da6d8118UL ,
00565      0xd807aa98a3030242UL ,  0x12835b0145706fbeUL , 
00566      0x243185be4ee4b28cUL ,  0x550c7dc3d5ffb4e2UL ,
00567      0x72be5d74f27b896fUL ,  0x80deb1fe3b1696b1UL , 
00568      0x9bdc06a725c71235UL ,  0xc19bf174cf692694UL ,
00569      0xe49b69c19ef14ad2UL ,  0xefbe4786384f25e3UL , 
00570      0x0fc19dc68b8cd5b5UL ,  0x240ca1cc77ac9c65UL ,
00571      0x2de92c6f592b0275UL ,  0x4a7484aa6ea6e483UL , 
00572      0x5cb0a9dcbd41fbd4UL ,  0x76f988da831153b5UL ,
00573      0x983e5152ee66dfabUL ,  0xa831c66d2db43210UL , 
00574      0xb00327c898fb213fUL ,  0xbf597fc7beef0ee4UL ,
00575      0xc6e00bf33da88fc2UL ,  0xd5a79147930aa725UL , 
00576      0x06ca6351e003826fUL ,  0x142929670a0e6e70UL ,
00577      0x27b70a8546d22ffcUL ,  0x2e1b21385c26c926UL , 
00578      0x4d2c6dfc5ac42aedUL ,  0x53380d139d95b3dfUL ,
00579      0x650a73548baf63deUL ,  0x766a0abb3c77b2a8UL , 
00580      0x81c2c92e47edaee6UL ,  0x92722c851482353bUL ,
00581      0xa2bfe8a14cf10364UL ,  0xa81a664bbc423001UL , 
00582      0xc24b8b70d0f89791UL ,  0xc76c51a30654be30UL ,
00583      0xd192e819d6ef5218UL ,  0xd69906245565a910UL , 
00584      0xf40e35855771202aUL ,  0x106aa07032bbd1b8UL ,
00585      0x19a4c116b8d2d0c8UL ,  0x1e376c085141ab53UL , 
00586      0x2748774cdf8eeb99UL ,  0x34b0bcb5e19b48a8UL ,
00587      0x391c0cb3c5c95a63UL ,  0x4ed8aa4ae3418acbUL , 
00588      0x5b9cca4f7763e373UL ,  0x682e6ff3d6b2b8a3UL ,
00589      0x748f82ee5defb2fcUL ,  0x78a5636f43172f60UL , 
00590      0x84c87814a1f0ab72UL ,  0x8cc702081a6439ecUL ,
00591      0x90befffa23631e28UL ,  0xa4506cebde82bde9UL , 
00592      0xbef9a3f7b2c67915UL ,  0xc67178f2e372532bUL ,
00593      0xca273eceea26619cUL ,  0xd186b8c721c0c207UL , 
00594      0xeada7dd6cde0eb1eUL ,  0xf57d4f7fee6ed178UL ,
00595      0x06f067aa72176fbaUL ,  0x0a637dc5a2c898a6UL , 
00596      0x113f9804bef90daeUL ,  0x1b710b35131c471bUL ,
00597      0x28db77f523047d84UL ,  0x32caab7b40c72493UL , 
00598      0x3c9ebe0a15c9bebcUL ,  0x431d67c49c100d4cUL ,
00599      0x4cc5d4becb3e42b6UL ,  0x597f299cfc657e2aUL , 
00600      0x5fcb6fab3ad6faecUL ,  0x6c44198c4a475817UL 
00601 #else
00602     ULLC(428a2f98,d728ae22), ULLC(71374491,23ef65cd), 
00603     ULLC(b5c0fbcf,ec4d3b2f), ULLC(e9b5dba5,8189dbbc),
00604     ULLC(3956c25b,f348b538), ULLC(59f111f1,b605d019), 
00605     ULLC(923f82a4,af194f9b), ULLC(ab1c5ed5,da6d8118),
00606     ULLC(d807aa98,a3030242), ULLC(12835b01,45706fbe), 
00607     ULLC(243185be,4ee4b28c), ULLC(550c7dc3,d5ffb4e2),
00608     ULLC(72be5d74,f27b896f), ULLC(80deb1fe,3b1696b1), 
00609     ULLC(9bdc06a7,25c71235), ULLC(c19bf174,cf692694),
00610     ULLC(e49b69c1,9ef14ad2), ULLC(efbe4786,384f25e3), 
00611     ULLC(0fc19dc6,8b8cd5b5), ULLC(240ca1cc,77ac9c65),
00612     ULLC(2de92c6f,592b0275), ULLC(4a7484aa,6ea6e483), 
00613     ULLC(5cb0a9dc,bd41fbd4), ULLC(76f988da,831153b5),
00614     ULLC(983e5152,ee66dfab), ULLC(a831c66d,2db43210), 
00615     ULLC(b00327c8,98fb213f), ULLC(bf597fc7,beef0ee4),
00616     ULLC(c6e00bf3,3da88fc2), ULLC(d5a79147,930aa725), 
00617     ULLC(06ca6351,e003826f), ULLC(14292967,0a0e6e70),
00618     ULLC(27b70a85,46d22ffc), ULLC(2e1b2138,5c26c926), 
00619     ULLC(4d2c6dfc,5ac42aed), ULLC(53380d13,9d95b3df),
00620     ULLC(650a7354,8baf63de), ULLC(766a0abb,3c77b2a8), 
00621     ULLC(81c2c92e,47edaee6), ULLC(92722c85,1482353b),
00622     ULLC(a2bfe8a1,4cf10364), ULLC(a81a664b,bc423001), 
00623     ULLC(c24b8b70,d0f89791), ULLC(c76c51a3,0654be30),
00624     ULLC(d192e819,d6ef5218), ULLC(d6990624,5565a910), 
00625     ULLC(f40e3585,5771202a), ULLC(106aa070,32bbd1b8),
00626     ULLC(19a4c116,b8d2d0c8), ULLC(1e376c08,5141ab53), 
00627     ULLC(2748774c,df8eeb99), ULLC(34b0bcb5,e19b48a8),
00628     ULLC(391c0cb3,c5c95a63), ULLC(4ed8aa4a,e3418acb), 
00629     ULLC(5b9cca4f,7763e373), ULLC(682e6ff3,d6b2b8a3),
00630     ULLC(748f82ee,5defb2fc), ULLC(78a5636f,43172f60), 
00631     ULLC(84c87814,a1f0ab72), ULLC(8cc70208,1a6439ec),
00632     ULLC(90befffa,23631e28), ULLC(a4506ceb,de82bde9), 
00633     ULLC(bef9a3f7,b2c67915), ULLC(c67178f2,e372532b),
00634     ULLC(ca273ece,ea26619c), ULLC(d186b8c7,21c0c207), 
00635     ULLC(eada7dd6,cde0eb1e), ULLC(f57d4f7f,ee6ed178),
00636     ULLC(06f067aa,72176fba), ULLC(0a637dc5,a2c898a6), 
00637     ULLC(113f9804,bef90dae), ULLC(1b710b35,131c471b),
00638     ULLC(28db77f5,23047d84), ULLC(32caab7b,40c72493), 
00639     ULLC(3c9ebe0a,15c9bebc), ULLC(431d67c4,9c100d4c),
00640     ULLC(4cc5d4be,cb3e42b6), ULLC(597f299c,fc657e2a), 
00641     ULLC(5fcb6fab,3ad6faec), ULLC(6c44198c,4a475817)
00642 #endif
00643 };
00644 
00645 struct SHA512ContextStr {
00646     union {
00647        PRUint64 w[80];          /* message schedule, input buffer, plus 64 words */
00648        PRUint32 l[160];
00649        PRUint8  b[640];
00650     } u;
00651     PRUint64 h[8];       /* 8 state variables */
00652     PRUint64 sizeLo;     /* 64-bit count of hashed bytes. */
00653 };
00654 
00655 /* =========== SHA512 implementation ===================================== */
00656 
00657 /* SHA-512 initial hash values */
00658 static const PRUint64 H512[8] = {
00659 #if PR_BYTES_PER_LONG == 8
00660      0x6a09e667f3bcc908UL ,  0xbb67ae8584caa73bUL , 
00661      0x3c6ef372fe94f82bUL ,  0xa54ff53a5f1d36f1UL , 
00662      0x510e527fade682d1UL ,  0x9b05688c2b3e6c1fUL , 
00663      0x1f83d9abfb41bd6bUL ,  0x5be0cd19137e2179UL 
00664 #else
00665     ULLC(6a09e667,f3bcc908), ULLC(bb67ae85,84caa73b), 
00666     ULLC(3c6ef372,fe94f82b), ULLC(a54ff53a,5f1d36f1), 
00667     ULLC(510e527f,ade682d1), ULLC(9b05688c,2b3e6c1f), 
00668     ULLC(1f83d9ab,fb41bd6b), ULLC(5be0cd19,137e2179)
00669 #endif
00670 };
00671 
00672 
00673 SHA512Context *
00674 SHA512_NewContext(void)
00675 {
00676     SHA512Context *ctx = PORT_New(SHA512Context);
00677     return ctx;
00678 }
00679 
00680 void 
00681 SHA512_DestroyContext(SHA512Context *ctx, PRBool freeit)
00682 {
00683     if (freeit) {
00684         PORT_ZFree(ctx, sizeof *ctx);
00685     }
00686 }
00687 
00688 void 
00689 SHA512_Begin(SHA512Context *ctx)
00690 {
00691     memset(ctx, 0, sizeof *ctx);
00692     memcpy(H, H512, sizeof H512);
00693 }
00694 
00695 #if defined(SHA512_TRACE)
00696 #if defined(HAVE_LONG_LONG)
00697 #define DUMP(n,a,d,e,h) printf(" t = %2d, %s = %016lx, %s = %016lx\n", \
00698                             n, #e, d, #a, h);
00699 #else
00700 #define DUMP(n,a,d,e,h) printf(" t = %2d, %s = %08x%08x, %s = %08x%08x\n", \
00701                             n, #e, d.hi, d.lo, #a, h.hi, h.lo);
00702 #endif
00703 #else
00704 #define DUMP(n,a,d,e,h)
00705 #endif
00706 
00707 #if defined(HAVE_LONG_LONG)
00708 
00709 #define ADDTO(x,y) y += x
00710 
00711 #define INITW(t) W[t] = (s1(W[t-2]) + W[t-7] + s0(W[t-15]) + W[t-16])
00712 
00713 #define ROUND(n,a,b,c,d,e,f,g,h) \
00714     h += S1(e) + Ch(e,f,g) + K512[n] + W[n]; \
00715     d += h; \
00716     h += S0(a) + Maj(a,b,c); \
00717     DUMP(n,a,d,e,h)
00718 
00719 #else /* use only 32-bit variables, and don't unroll loops */
00720 
00721 #undef  NOUNROLL512
00722 #define NOUNROLL512 1
00723 
00724 #define ADDTO(x,y) y.lo += x.lo; y.hi += x.hi + (x.lo > y.lo)
00725 
00726 #define ROTR64a(x,n,lo,hi) (x.lo >> n | x.hi << (32-n))
00727 #define ROTR64A(x,n,lo,hi) (x.lo << (64-n) | x.hi >> (n-32))
00728 #define  SHR64a(x,n,lo,hi) (x.lo >> n | x.hi << (32-n))
00729 
00730 /* Capitol Sigma and lower case sigma functions */
00731 #define s0lo(x) (ROTR64a(x,1,lo,hi) ^ ROTR64a(x,8,lo,hi) ^ SHR64a(x,7,lo,hi))
00732 #define s0hi(x) (ROTR64a(x,1,hi,lo) ^ ROTR64a(x,8,hi,lo) ^ (x.hi >> 7))
00733 
00734 #define s1lo(x) (ROTR64a(x,19,lo,hi) ^ ROTR64A(x,61,lo,hi) ^ SHR64a(x,6,lo,hi))
00735 #define s1hi(x) (ROTR64a(x,19,hi,lo) ^ ROTR64A(x,61,hi,lo) ^ (x.hi >> 6))
00736 
00737 #define S0lo(x)(ROTR64a(x,28,lo,hi) ^ ROTR64A(x,34,lo,hi) ^ ROTR64A(x,39,lo,hi))
00738 #define S0hi(x)(ROTR64a(x,28,hi,lo) ^ ROTR64A(x,34,hi,lo) ^ ROTR64A(x,39,hi,lo))
00739 
00740 #define S1lo(x)(ROTR64a(x,14,lo,hi) ^ ROTR64a(x,18,lo,hi) ^ ROTR64A(x,41,lo,hi))
00741 #define S1hi(x)(ROTR64a(x,14,hi,lo) ^ ROTR64a(x,18,hi,lo) ^ ROTR64A(x,41,hi,lo))
00742 
00743 /* 32-bit versions of Ch and Maj */
00744 #define Chxx(x,y,z,lo) ((x.lo & y.lo) ^ (~x.lo & z.lo))
00745 #define Majx(x,y,z,lo) ((x.lo & y.lo) ^ (x.lo & z.lo) ^ (y.lo & z.lo))
00746 
00747 #define INITW(t) \
00748     do { \
00749        PRUint32 lo, tm; \
00750        PRUint32 cy = 0; \
00751        lo = s1lo(W[t-2]); \
00752        lo += (tm = W[t-7].lo);     if (lo < tm) cy++; \
00753        lo += (tm = s0lo(W[t-15])); if (lo < tm) cy++; \
00754        lo += (tm = W[t-16].lo);    if (lo < tm) cy++; \
00755        W[t].lo = lo; \
00756        W[t].hi = cy + s1hi(W[t-2]) + W[t-7].hi + s0hi(W[t-15]) + W[t-16].hi; \
00757     } while (0)
00758 
00759 #define ROUND(n,a,b,c,d,e,f,g,h) \
00760     { \
00761        PRUint32 lo, tm, cy; \
00762        lo  = S1lo(e); \
00763        lo += (tm = Chxx(e,f,g,lo));    cy = (lo < tm); \
00764        lo += (tm = K512[n].lo);    if (lo < tm) cy++; \
00765        lo += (tm =    W[n].lo);    if (lo < tm) cy++; \
00766        h.lo += lo;                 if (h.lo < lo) cy++; \
00767        h.hi += cy + S1hi(e) + Chxx(e,f,g,hi) + K512[n].hi + W[n].hi; \
00768        d.lo += h.lo; \
00769        d.hi += h.hi + (d.lo < h.lo); \
00770        lo  = S0lo(a);  \
00771        lo += (tm = Majx(a,b,c,lo));       cy = (lo < tm); \
00772        h.lo += lo;                 if (h.lo < lo) cy++; \
00773        h.hi += cy + S0hi(a) + Majx(a,b,c,hi); \
00774        DUMP(n,a,d,e,h) \
00775     }
00776 #endif
00777 
00778 static void
00779 SHA512_Compress(SHA512Context *ctx)
00780 {
00781 #if defined(IS_LITTLE_ENDIAN)
00782   {
00783 #if defined(HAVE_LONG_LONG)
00784     PRUint64 t1;
00785 #else
00786     PRUint32 t1;
00787 #endif
00788     BYTESWAP8(W[0]);
00789     BYTESWAP8(W[1]);
00790     BYTESWAP8(W[2]);
00791     BYTESWAP8(W[3]);
00792     BYTESWAP8(W[4]);
00793     BYTESWAP8(W[5]);
00794     BYTESWAP8(W[6]);
00795     BYTESWAP8(W[7]);
00796     BYTESWAP8(W[8]);
00797     BYTESWAP8(W[9]);
00798     BYTESWAP8(W[10]);
00799     BYTESWAP8(W[11]);
00800     BYTESWAP8(W[12]);
00801     BYTESWAP8(W[13]);
00802     BYTESWAP8(W[14]);
00803     BYTESWAP8(W[15]);
00804   }
00805 #endif
00806 
00807   {
00808     PRUint64 t1, t2;
00809 #ifdef NOUNROLL512
00810     {
00811        /* prepare the "message schedule"   */
00812        int t;
00813        for (t = 16; t < 80; ++t) {
00814            INITW(t);
00815        }
00816     }
00817 #else
00818     INITW(16);
00819     INITW(17);
00820     INITW(18);
00821     INITW(19);
00822 
00823     INITW(20);
00824     INITW(21);
00825     INITW(22);
00826     INITW(23);
00827     INITW(24);
00828     INITW(25);
00829     INITW(26);
00830     INITW(27);
00831     INITW(28);
00832     INITW(29);
00833 
00834     INITW(30);
00835     INITW(31);
00836     INITW(32);
00837     INITW(33);
00838     INITW(34);
00839     INITW(35);
00840     INITW(36);
00841     INITW(37);
00842     INITW(38);
00843     INITW(39);
00844 
00845     INITW(40);
00846     INITW(41);
00847     INITW(42);
00848     INITW(43);
00849     INITW(44);
00850     INITW(45);
00851     INITW(46);
00852     INITW(47);
00853     INITW(48);
00854     INITW(49);
00855 
00856     INITW(50);
00857     INITW(51);
00858     INITW(52);
00859     INITW(53);
00860     INITW(54);
00861     INITW(55);
00862     INITW(56);
00863     INITW(57);
00864     INITW(58);
00865     INITW(59);
00866 
00867     INITW(60);
00868     INITW(61);
00869     INITW(62);
00870     INITW(63);
00871     INITW(64);
00872     INITW(65);
00873     INITW(66);
00874     INITW(67);
00875     INITW(68);
00876     INITW(69);
00877 
00878     INITW(70);
00879     INITW(71);
00880     INITW(72);
00881     INITW(73);
00882     INITW(74);
00883     INITW(75);
00884     INITW(76);
00885     INITW(77);
00886     INITW(78);
00887     INITW(79);
00888 #endif
00889   }
00890 #ifdef SHA512_TRACE
00891   {
00892     int i;
00893     for (i = 0; i < 80; ++i) {
00894 #ifdef HAVE_LONG_LONG
00895        printf("W[%2d] = %016lx\n", i, W[i]);
00896 #else
00897        printf("W[%2d] = %08x%08x\n", i, W[i].hi, W[i].lo);
00898 #endif
00899     }
00900   }
00901 #endif
00902   {
00903     PRUint64 a, b, c, d, e, f, g, h;
00904 
00905     a = H[0];
00906     b = H[1];
00907     c = H[2];
00908     d = H[3];
00909     e = H[4];
00910     f = H[5];
00911     g = H[6];
00912     h = H[7];
00913 
00914 #ifdef NOUNROLL512
00915     {
00916        int t;
00917        for (t = 0; t < 80; t+= 8) {
00918            ROUND(t+0,a,b,c,d,e,f,g,h)
00919            ROUND(t+1,h,a,b,c,d,e,f,g)
00920            ROUND(t+2,g,h,a,b,c,d,e,f)
00921            ROUND(t+3,f,g,h,a,b,c,d,e)
00922            ROUND(t+4,e,f,g,h,a,b,c,d)
00923            ROUND(t+5,d,e,f,g,h,a,b,c)
00924            ROUND(t+6,c,d,e,f,g,h,a,b)
00925            ROUND(t+7,b,c,d,e,f,g,h,a)
00926        }
00927     }
00928 #else
00929     ROUND( 0,a,b,c,d,e,f,g,h)
00930     ROUND( 1,h,a,b,c,d,e,f,g)
00931     ROUND( 2,g,h,a,b,c,d,e,f)
00932     ROUND( 3,f,g,h,a,b,c,d,e)
00933     ROUND( 4,e,f,g,h,a,b,c,d)
00934     ROUND( 5,d,e,f,g,h,a,b,c)
00935     ROUND( 6,c,d,e,f,g,h,a,b)
00936     ROUND( 7,b,c,d,e,f,g,h,a)
00937 
00938     ROUND( 8,a,b,c,d,e,f,g,h)
00939     ROUND( 9,h,a,b,c,d,e,f,g)
00940     ROUND(10,g,h,a,b,c,d,e,f)
00941     ROUND(11,f,g,h,a,b,c,d,e)
00942     ROUND(12,e,f,g,h,a,b,c,d)
00943     ROUND(13,d,e,f,g,h,a,b,c)
00944     ROUND(14,c,d,e,f,g,h,a,b)
00945     ROUND(15,b,c,d,e,f,g,h,a)
00946 
00947     ROUND(16,a,b,c,d,e,f,g,h)
00948     ROUND(17,h,a,b,c,d,e,f,g)
00949     ROUND(18,g,h,a,b,c,d,e,f)
00950     ROUND(19,f,g,h,a,b,c,d,e)
00951     ROUND(20,e,f,g,h,a,b,c,d)
00952     ROUND(21,d,e,f,g,h,a,b,c)
00953     ROUND(22,c,d,e,f,g,h,a,b)
00954     ROUND(23,b,c,d,e,f,g,h,a)
00955 
00956     ROUND(24,a,b,c,d,e,f,g,h)
00957     ROUND(25,h,a,b,c,d,e,f,g)
00958     ROUND(26,g,h,a,b,c,d,e,f)
00959     ROUND(27,f,g,h,a,b,c,d,e)
00960     ROUND(28,e,f,g,h,a,b,c,d)
00961     ROUND(29,d,e,f,g,h,a,b,c)
00962     ROUND(30,c,d,e,f,g,h,a,b)
00963     ROUND(31,b,c,d,e,f,g,h,a)
00964 
00965     ROUND(32,a,b,c,d,e,f,g,h)
00966     ROUND(33,h,a,b,c,d,e,f,g)
00967     ROUND(34,g,h,a,b,c,d,e,f)
00968     ROUND(35,f,g,h,a,b,c,d,e)
00969     ROUND(36,e,f,g,h,a,b,c,d)
00970     ROUND(37,d,e,f,g,h,a,b,c)
00971     ROUND(38,c,d,e,f,g,h,a,b)
00972     ROUND(39,b,c,d,e,f,g,h,a)
00973 
00974     ROUND(40,a,b,c,d,e,f,g,h)
00975     ROUND(41,h,a,b,c,d,e,f,g)
00976     ROUND(42,g,h,a,b,c,d,e,f)
00977     ROUND(43,f,g,h,a,b,c,d,e)
00978     ROUND(44,e,f,g,h,a,b,c,d)
00979     ROUND(45,d,e,f,g,h,a,b,c)
00980     ROUND(46,c,d,e,f,g,h,a,b)
00981     ROUND(47,b,c,d,e,f,g,h,a)
00982 
00983     ROUND(48,a,b,c,d,e,f,g,h)
00984     ROUND(49,h,a,b,c,d,e,f,g)
00985     ROUND(50,g,h,a,b,c,d,e,f)
00986     ROUND(51,f,g,h,a,b,c,d,e)
00987     ROUND(52,e,f,g,h,a,b,c,d)
00988     ROUND(53,d,e,f,g,h,a,b,c)
00989     ROUND(54,c,d,e,f,g,h,a,b)
00990     ROUND(55,b,c,d,e,f,g,h,a)
00991 
00992     ROUND(56,a,b,c,d,e,f,g,h)
00993     ROUND(57,h,a,b,c,d,e,f,g)
00994     ROUND(58,g,h,a,b,c,d,e,f)
00995     ROUND(59,f,g,h,a,b,c,d,e)
00996     ROUND(60,e,f,g,h,a,b,c,d)
00997     ROUND(61,d,e,f,g,h,a,b,c)
00998     ROUND(62,c,d,e,f,g,h,a,b)
00999     ROUND(63,b,c,d,e,f,g,h,a)
01000 
01001     ROUND(64,a,b,c,d,e,f,g,h)
01002     ROUND(65,h,a,b,c,d,e,f,g)
01003     ROUND(66,g,h,a,b,c,d,e,f)
01004     ROUND(67,f,g,h,a,b,c,d,e)
01005     ROUND(68,e,f,g,h,a,b,c,d)
01006     ROUND(69,d,e,f,g,h,a,b,c)
01007     ROUND(70,c,d,e,f,g,h,a,b)
01008     ROUND(71,b,c,d,e,f,g,h,a)
01009 
01010     ROUND(72,a,b,c,d,e,f,g,h)
01011     ROUND(73,h,a,b,c,d,e,f,g)
01012     ROUND(74,g,h,a,b,c,d,e,f)
01013     ROUND(75,f,g,h,a,b,c,d,e)
01014     ROUND(76,e,f,g,h,a,b,c,d)
01015     ROUND(77,d,e,f,g,h,a,b,c)
01016     ROUND(78,c,d,e,f,g,h,a,b)
01017     ROUND(79,b,c,d,e,f,g,h,a)
01018 #endif
01019 
01020     ADDTO(a,H[0]);
01021     ADDTO(b,H[1]);
01022     ADDTO(c,H[2]);
01023     ADDTO(d,H[3]);
01024     ADDTO(e,H[4]);
01025     ADDTO(f,H[5]);
01026     ADDTO(g,H[6]);
01027     ADDTO(h,H[7]);
01028   }
01029 }
01030 
01031 void 
01032 SHA512_Update(SHA512Context *ctx, const unsigned char *input,
01033               unsigned int inputLen)
01034 {
01035     unsigned int inBuf;
01036     if (!inputLen)
01037        return;
01038 
01039 #if defined(HAVE_LONG_LONG)
01040     inBuf = (unsigned int)ctx->sizeLo & 0x7f;
01041     /* Add inputLen into the count of bytes processed, before processing */
01042     ctx->sizeLo += inputLen;
01043 #else
01044     inBuf = (unsigned int)ctx->sizeLo.lo & 0x7f;
01045     ctx->sizeLo.lo += inputLen;
01046     if (ctx->sizeLo.lo < inputLen) ctx->sizeLo.hi++;
01047 #endif
01048 
01049     /* if data already in buffer, attemp to fill rest of buffer */
01050     if (inBuf) {
01051        unsigned int todo = SHA512_BLOCK_LENGTH - inBuf;
01052        if (inputLen < todo)
01053            todo = inputLen;
01054        memcpy(B + inBuf, input, todo);
01055        input    += todo;
01056        inputLen -= todo;
01057        if (inBuf + todo == SHA512_BLOCK_LENGTH)
01058            SHA512_Compress(ctx);
01059     }
01060 
01061     /* if enough data to fill one or more whole buffers, process them. */
01062     while (inputLen >= SHA512_BLOCK_LENGTH) {
01063        memcpy(B, input, SHA512_BLOCK_LENGTH);
01064        input    += SHA512_BLOCK_LENGTH;
01065        inputLen -= SHA512_BLOCK_LENGTH;
01066        SHA512_Compress(ctx);
01067     }
01068     /* if data left over, fill it into buffer */
01069     if (inputLen) 
01070        memcpy(B, input, inputLen);
01071 }
01072 
01073 void 
01074 SHA512_End(SHA512Context *ctx, unsigned char *digest,
01075            unsigned int *digestLen, unsigned int maxDigestLen)
01076 {
01077 #if defined(HAVE_LONG_LONG)
01078     unsigned int inBuf  = (unsigned int)ctx->sizeLo & 0x7f;
01079     unsigned int padLen = (inBuf < 112) ? (112 - inBuf) : (112 + 128 - inBuf);
01080     PRUint64 lo, t1;
01081     lo = (ctx->sizeLo << 3);
01082 #else
01083     unsigned int inBuf  = (unsigned int)ctx->sizeLo.lo & 0x7f;
01084     unsigned int padLen = (inBuf < 112) ? (112 - inBuf) : (112 + 128 - inBuf);
01085     PRUint64 lo = ctx->sizeLo;
01086     PRUint32 t1;
01087     lo.lo <<= 3;
01088 #endif
01089 
01090     SHA512_Update(ctx, pad, padLen);
01091 
01092 #if defined(HAVE_LONG_LONG)
01093     W[14] = 0;
01094 #else
01095     W[14].lo = 0;
01096     W[14].hi = 0;
01097 #endif
01098 
01099     W[15] = lo;
01100 #if defined(IS_LITTLE_ENDIAN)
01101     BYTESWAP8(W[15]);
01102 #endif
01103     SHA512_Compress(ctx);
01104 
01105     /* now output the answer */
01106 #if defined(IS_LITTLE_ENDIAN)
01107     BYTESWAP8(H[0]);
01108     BYTESWAP8(H[1]);
01109     BYTESWAP8(H[2]);
01110     BYTESWAP8(H[3]);
01111     BYTESWAP8(H[4]);
01112     BYTESWAP8(H[5]);
01113     BYTESWAP8(H[6]);
01114     BYTESWAP8(H[7]);
01115 #endif
01116     padLen = PR_MIN(SHA512_LENGTH, maxDigestLen);
01117     memcpy(digest, H, padLen);
01118     if (digestLen)
01119        *digestLen = padLen;
01120 }
01121 
01122 SECStatus 
01123 SHA512_HashBuf(unsigned char *dest, const unsigned char *src, 
01124                uint32 src_length)
01125 {
01126     SHA512Context ctx;
01127     unsigned int outLen;
01128 
01129     SHA512_Begin(&ctx);
01130     SHA512_Update(&ctx, src, src_length);
01131     SHA512_End(&ctx, dest, &outLen, SHA512_LENGTH);
01132 
01133     return SECSuccess;
01134 }
01135 
01136 
01137 SECStatus 
01138 SHA512_Hash(unsigned char *dest, const char *src)
01139 {
01140     return SHA512_HashBuf(dest, (const unsigned char *)src, PORT_Strlen(src));
01141 }
01142 
01143 
01144 void SHA512_TraceState(SHA512Context *ctx) { }
01145 
01146 unsigned int 
01147 SHA512_FlattenSize(SHA512Context *ctx)
01148 {
01149     return sizeof *ctx;
01150 }
01151 
01152 SECStatus 
01153 SHA512_Flatten(SHA512Context *ctx,unsigned char *space)
01154 {
01155     PORT_Memcpy(space, ctx, sizeof *ctx);
01156     return SECSuccess;
01157 }
01158 
01159 SHA512Context * 
01160 SHA512_Resurrect(unsigned char *space, void *arg)
01161 {
01162     SHA512Context *ctx = SHA512_NewContext();
01163     if (ctx) 
01164        PORT_Memcpy(ctx, space, sizeof *ctx);
01165     return ctx;
01166 }
01167 
01168 void SHA512_Clone(SHA512Context *dest, SHA512Context *src) 
01169 {
01170     memcpy(dest, src, sizeof *dest);
01171 }
01172 
01173 /* ======================================================================= */
01174 /* SHA384 uses a SHA512Context as the real context. 
01175 ** The only differences between SHA384 an SHA512 are:
01176 ** a) the intialization values for the context, and
01177 ** b) the number of bytes of data produced as output.
01178 */
01179 
01180 /* SHA-384 initial hash values */
01181 static const PRUint64 H384[8] = {
01182 #if PR_BYTES_PER_LONG == 8
01183      0xcbbb9d5dc1059ed8UL ,  0x629a292a367cd507UL , 
01184      0x9159015a3070dd17UL ,  0x152fecd8f70e5939UL , 
01185      0x67332667ffc00b31UL ,  0x8eb44a8768581511UL , 
01186      0xdb0c2e0d64f98fa7UL ,  0x47b5481dbefa4fa4UL 
01187 #else
01188     ULLC(cbbb9d5d,c1059ed8), ULLC(629a292a,367cd507), 
01189     ULLC(9159015a,3070dd17), ULLC(152fecd8,f70e5939), 
01190     ULLC(67332667,ffc00b31), ULLC(8eb44a87,68581511), 
01191     ULLC(db0c2e0d,64f98fa7), ULLC(47b5481d,befa4fa4)
01192 #endif
01193 };
01194 
01195 SHA384Context *
01196 SHA384_NewContext(void)
01197 {
01198     return SHA512_NewContext();
01199 }
01200 
01201 void 
01202 SHA384_DestroyContext(SHA384Context *ctx, PRBool freeit)
01203 {
01204     SHA512_DestroyContext(ctx, freeit);
01205 }
01206 
01207 void 
01208 SHA384_Begin(SHA384Context *ctx)
01209 {
01210     memset(ctx, 0, sizeof *ctx);
01211     memcpy(H, H384, sizeof H384);
01212 }
01213 
01214 void 
01215 SHA384_Update(SHA384Context *ctx, const unsigned char *input,
01216                   unsigned int inputLen)
01217 {
01218     SHA512_Update(ctx, input, inputLen);
01219 }
01220 
01221 void 
01222 SHA384_End(SHA384Context *ctx, unsigned char *digest,
01223                unsigned int *digestLen, unsigned int maxDigestLen)
01224 {
01225 #define SHA_MIN(a,b) (a < b ? a : b)
01226     unsigned int maxLen = SHA_MIN(maxDigestLen, SHA384_LENGTH);
01227     SHA512_End(ctx, digest, digestLen, maxLen);
01228 }
01229 
01230 SECStatus 
01231 SHA384_HashBuf(unsigned char *dest, const unsigned char *src,
01232                        uint32 src_length)
01233 {
01234     SHA512Context ctx;
01235     unsigned int outLen;
01236 
01237     SHA384_Begin(&ctx);
01238     SHA512_Update(&ctx, src, src_length);
01239     SHA512_End(&ctx, dest, &outLen, SHA384_LENGTH);
01240 
01241     return SECSuccess;
01242 }
01243 
01244 SECStatus 
01245 SHA384_Hash(unsigned char *dest, const char *src)
01246 {
01247     return SHA384_HashBuf(dest, (const unsigned char *)src, PORT_Strlen(src));
01248 }
01249 
01250 void SHA384_TraceState(SHA384Context *ctx) { }
01251 
01252 unsigned int 
01253 SHA384_FlattenSize(SHA384Context *ctx)
01254 {
01255     return sizeof(SHA384Context);
01256 }
01257 
01258 SECStatus 
01259 SHA384_Flatten(SHA384Context *ctx,unsigned char *space)
01260 {
01261     return SHA512_Flatten(ctx, space);
01262 }
01263 
01264 SHA384Context * 
01265 SHA384_Resurrect(unsigned char *space, void *arg)
01266 {
01267     return SHA512_Resurrect(space, arg);
01268 }
01269 
01270 void SHA384_Clone(SHA384Context *dest, SHA384Context *src) 
01271 {
01272     memcpy(dest, src, sizeof *dest);
01273 }
01274 
01275 /* ======================================================================= */
01276 #ifdef SELFTEST
01277 #include <stdio.h>
01278 
01279 static const char abc[] = { "abc" };
01280 static const char abcdbc[] = { 
01281     "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"
01282 };
01283 static const char abcdef[] = { 
01284     "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmn"
01285     "hijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu" 
01286 };
01287 
01288 void
01289 dumpHash32(const unsigned char *buf, unsigned int bufLen)
01290 {
01291     unsigned int i;
01292     for (i = 0; i < bufLen; i += 4) {
01293        printf(" %02x%02x%02x%02x", buf[i], buf[i+1], buf[i+2], buf[i+3]);
01294     }
01295     printf("\n");
01296 }
01297 
01298 void test256(void)
01299 {
01300     unsigned char outBuf[SHA256_LENGTH];
01301 
01302     printf("SHA256, input = %s\n", abc);
01303     SHA256_Hash(outBuf, abc);
01304     dumpHash32(outBuf, sizeof outBuf);
01305 
01306     printf("SHA256, input = %s\n", abcdbc);
01307     SHA256_Hash(outBuf, abcdbc);
01308     dumpHash32(outBuf, sizeof outBuf);
01309 }
01310 
01311 void
01312 dumpHash64(const unsigned char *buf, unsigned int bufLen)
01313 {
01314     unsigned int i;
01315     for (i = 0; i < bufLen; i += 8) {
01316        if (i % 32 == 0)
01317            printf("\n");
01318        printf(" %02x%02x%02x%02x%02x%02x%02x%02x", 
01319               buf[i  ], buf[i+1], buf[i+2], buf[i+3],
01320               buf[i+4], buf[i+5], buf[i+6], buf[i+7]);
01321     }
01322     printf("\n");
01323 }
01324 
01325 void test512(void)
01326 {
01327     unsigned char outBuf[SHA512_LENGTH];
01328 
01329     printf("SHA512, input = %s\n", abc);
01330     SHA512_Hash(outBuf, abc);
01331     dumpHash64(outBuf, sizeof outBuf);
01332 
01333     printf("SHA512, input = %s\n", abcdef);
01334     SHA512_Hash(outBuf, abcdef);
01335     dumpHash64(outBuf, sizeof outBuf);
01336 }
01337 
01338 void time512(void)
01339 {
01340     unsigned char outBuf[SHA512_LENGTH];
01341 
01342     SHA512_Hash(outBuf, abc);
01343     SHA512_Hash(outBuf, abcdef);
01344 }
01345 
01346 void test384(void)
01347 {
01348     unsigned char outBuf[SHA384_LENGTH];
01349 
01350     printf("SHA384, input = %s\n", abc);
01351     SHA384_Hash(outBuf, abc);
01352     dumpHash64(outBuf, sizeof outBuf);
01353 
01354     printf("SHA384, input = %s\n", abcdef);
01355     SHA384_Hash(outBuf, abcdef);
01356     dumpHash64(outBuf, sizeof outBuf);
01357 }
01358 
01359 int main (int argc, char *argv[], char *envp[])
01360 {
01361     int i = 1;
01362     if (argc > 1) {
01363        i = atoi(argv[1]);
01364     }
01365     if (i < 2) {
01366        test256();
01367        test512();
01368        test384();
01369     } else {
01370        while (i-- > 0) {
01371            time512();
01372        }
01373        printf("done\n");
01374     }
01375     return 0;
01376 }
01377 
01378 void *PORT_Alloc(size_t len)              { return malloc(len); }
01379 void PORT_Free(void *ptr)          { free(ptr); }
01380 void PORT_ZFree(void *ptr, size_t len)  { memset(ptr, 0, len); free(ptr); }
01381 #endif