Invalidate scans when the host volume is unmounted.
[chromium-blink-merge.git] / crypto / third_party / nss / sha512.cc
blob5ef4e5062dcb1d746b0d6bfc0fda50b5195d7cd7
1 /*
2 * sha512.c - implementation of SHA256, SHA384 and SHA512
4 * ***** BEGIN LICENSE BLOCK *****
5 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
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/
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.
17 * The Original Code is the Netscape security libraries.
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.
24 * Contributor(s):
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.
38 * ***** END LICENSE BLOCK ***** */
39 /* $Id: sha512.c,v 1.9 2006/10/13 16:54:04 wtchang%redhat.com Exp $ */
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
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 */
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
60 /* ============= Common constants and defines ======================= */
62 #define W ctx->u.w
63 #define B ctx->u.b
64 #define H ctx->h
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))
71 /* Padding used with all flavors of SHA */
72 static const PRUint8 pad[240] = {
73 0x80,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
74 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
75 /* compiler will fill the rest in with zeros */
78 /* ============= SHA256 implemenmtation ================================== */
80 /* SHA-256 constants, K256. */
81 static const PRUint32 K256[64] = {
82 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5,
83 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
84 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
85 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
86 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc,
87 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
88 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7,
89 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
90 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
91 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
92 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3,
93 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
94 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5,
95 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
96 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
97 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
100 /* SHA-256 initial hash values */
101 static const PRUint32 H256[8] = {
102 0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a,
103 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19
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
116 static FORCEINLINE PRUint32 FASTCALL
117 swap4b(PRUint32 dwd)
119 __asm {
120 mov eax,dwd
121 bswap eax
125 #define SHA_HTONL(x) swap4b(x)
126 #define BYTESWAP4(x) x = SHA_HTONL(x)
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)
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
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
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))
159 SHA256Context *
160 SHA256_NewContext(void)
162 SHA256Context *ctx = PORT_New(SHA256Context);
163 return ctx;
166 void
167 SHA256_DestroyContext(SHA256Context *ctx, PRBool freeit)
169 if (freeit) {
170 PORT_ZFree(ctx, sizeof *ctx);
174 void
175 SHA256_Begin(SHA256Context *ctx)
177 memset(ctx, 0, sizeof *ctx);
178 memcpy(H, H256, sizeof H256);
181 static void
182 SHA256_Compress(SHA256Context *ctx)
185 register PRUint32 t1, t2;
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
206 #define INITW(t) W[t] = (s1(W[t-2]) + W[t-7] + s0(W[t-15]) + W[t-16])
208 /* prepare the "message schedule" */
209 #ifdef NOUNROLL256
211 int t;
212 for (t = 16; t < 64; ++t) {
213 INITW(t);
216 #else
217 INITW(16);
218 INITW(17);
219 INITW(18);
220 INITW(19);
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);
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);
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);
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);
266 INITW(60);
267 INITW(61);
268 INITW(62);
269 INITW(63);
271 #endif
272 #undef INITW
275 PRUint32 a, b, c, d, e, f, g, h;
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];
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);
291 #ifdef NOUNROLL256
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)
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)
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)
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)
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)
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)
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)
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)
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
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;
388 #undef ROUND
391 #undef s0
392 #undef s1
393 #undef S0
394 #undef S1
396 void
397 SHA256_Update(SHA256Context *ctx, const unsigned char *input,
398 unsigned int inputLen)
400 unsigned int inBuf = ctx->sizeLo & 0x3f;
401 if (!inputLen)
402 return;
404 /* Add inputLen into the count of bytes processed, before processing */
405 if ((ctx->sizeLo += inputLen) < inputLen)
406 ctx->sizeHi++;
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);
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);
427 /* if data left over, fill it into buffer */
428 if (inputLen)
429 memcpy(B, input, inputLen);
432 void
433 SHA256_End(SHA256Context *ctx, unsigned char *digest,
434 unsigned int *digestLen, unsigned int maxDigestLen)
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
443 hi = (ctx->sizeHi << 3) | (ctx->sizeLo >> 29);
444 lo = (ctx->sizeLo << 3);
446 SHA256_Update(ctx, pad, padLen);
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);
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;
474 /* Comment out unused code, mostly the SHA384 and SHA512 implementations. */
475 #if 0
476 SECStatus
477 SHA256_HashBuf(unsigned char *dest, const unsigned char *src,
478 unsigned int src_length)
480 SHA256Context ctx;
481 unsigned int outLen;
483 SHA256_Begin(&ctx);
484 SHA256_Update(&ctx, src, src_length);
485 SHA256_End(&ctx, dest, &outLen, SHA256_LENGTH);
487 return SECSuccess;
491 SECStatus
492 SHA256_Hash(unsigned char *dest, const char *src)
494 return SHA256_HashBuf(dest, (const unsigned char *)src, PORT_Strlen(src));
498 void SHA256_TraceState(SHA256Context *ctx) { }
500 unsigned int
501 SHA256_FlattenSize(SHA256Context *ctx)
503 return sizeof *ctx;
506 SECStatus
507 SHA256_Flatten(SHA256Context *ctx,unsigned char *space)
509 PORT_Memcpy(space, ctx, sizeof *ctx);
510 return SECSuccess;
513 SHA256Context *
514 SHA256_Resurrect(unsigned char *space, void *arg)
516 SHA256Context *ctx = SHA256_NewContext();
517 if (ctx)
518 PORT_Memcpy(ctx, space, sizeof *ctx);
519 return ctx;
522 void SHA256_Clone(SHA256Context *dest, SHA256Context *src)
524 memcpy(dest, src, sizeof *dest);
528 /* ======= SHA512 and SHA384 common constants and defines ================= */
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)))
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))
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
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)
556 #else /* no long long */
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
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
570 /* SHA-384 and SHA-512 constants, K512. */
571 static const PRUint64 K512[80] = {
572 #if PR_BYTES_PER_LONG == 8
573 0x428a2f98d728ae22UL , 0x7137449123ef65cdUL ,
574 0xb5c0fbcfec4d3b2fUL , 0xe9b5dba58189dbbcUL ,
575 0x3956c25bf348b538UL , 0x59f111f1b605d019UL ,
576 0x923f82a4af194f9bUL , 0xab1c5ed5da6d8118UL ,
577 0xd807aa98a3030242UL , 0x12835b0145706fbeUL ,
578 0x243185be4ee4b28cUL , 0x550c7dc3d5ffb4e2UL ,
579 0x72be5d74f27b896fUL , 0x80deb1fe3b1696b1UL ,
580 0x9bdc06a725c71235UL , 0xc19bf174cf692694UL ,
581 0xe49b69c19ef14ad2UL , 0xefbe4786384f25e3UL ,
582 0x0fc19dc68b8cd5b5UL , 0x240ca1cc77ac9c65UL ,
583 0x2de92c6f592b0275UL , 0x4a7484aa6ea6e483UL ,
584 0x5cb0a9dcbd41fbd4UL , 0x76f988da831153b5UL ,
585 0x983e5152ee66dfabUL , 0xa831c66d2db43210UL ,
586 0xb00327c898fb213fUL , 0xbf597fc7beef0ee4UL ,
587 0xc6e00bf33da88fc2UL , 0xd5a79147930aa725UL ,
588 0x06ca6351e003826fUL , 0x142929670a0e6e70UL ,
589 0x27b70a8546d22ffcUL , 0x2e1b21385c26c926UL ,
590 0x4d2c6dfc5ac42aedUL , 0x53380d139d95b3dfUL ,
591 0x650a73548baf63deUL , 0x766a0abb3c77b2a8UL ,
592 0x81c2c92e47edaee6UL , 0x92722c851482353bUL ,
593 0xa2bfe8a14cf10364UL , 0xa81a664bbc423001UL ,
594 0xc24b8b70d0f89791UL , 0xc76c51a30654be30UL ,
595 0xd192e819d6ef5218UL , 0xd69906245565a910UL ,
596 0xf40e35855771202aUL , 0x106aa07032bbd1b8UL ,
597 0x19a4c116b8d2d0c8UL , 0x1e376c085141ab53UL ,
598 0x2748774cdf8eeb99UL , 0x34b0bcb5e19b48a8UL ,
599 0x391c0cb3c5c95a63UL , 0x4ed8aa4ae3418acbUL ,
600 0x5b9cca4f7763e373UL , 0x682e6ff3d6b2b8a3UL ,
601 0x748f82ee5defb2fcUL , 0x78a5636f43172f60UL ,
602 0x84c87814a1f0ab72UL , 0x8cc702081a6439ecUL ,
603 0x90befffa23631e28UL , 0xa4506cebde82bde9UL ,
604 0xbef9a3f7b2c67915UL , 0xc67178f2e372532bUL ,
605 0xca273eceea26619cUL , 0xd186b8c721c0c207UL ,
606 0xeada7dd6cde0eb1eUL , 0xf57d4f7fee6ed178UL ,
607 0x06f067aa72176fbaUL , 0x0a637dc5a2c898a6UL ,
608 0x113f9804bef90daeUL , 0x1b710b35131c471bUL ,
609 0x28db77f523047d84UL , 0x32caab7b40c72493UL ,
610 0x3c9ebe0a15c9bebcUL , 0x431d67c49c100d4cUL ,
611 0x4cc5d4becb3e42b6UL , 0x597f299cfc657e2aUL ,
612 0x5fcb6fab3ad6faecUL , 0x6c44198c4a475817UL
613 #else
614 ULLC(428a2f98,d728ae22), ULLC(71374491,23ef65cd),
615 ULLC(b5c0fbcf,ec4d3b2f), ULLC(e9b5dba5,8189dbbc),
616 ULLC(3956c25b,f348b538), ULLC(59f111f1,b605d019),
617 ULLC(923f82a4,af194f9b), ULLC(ab1c5ed5,da6d8118),
618 ULLC(d807aa98,a3030242), ULLC(12835b01,45706fbe),
619 ULLC(243185be,4ee4b28c), ULLC(550c7dc3,d5ffb4e2),
620 ULLC(72be5d74,f27b896f), ULLC(80deb1fe,3b1696b1),
621 ULLC(9bdc06a7,25c71235), ULLC(c19bf174,cf692694),
622 ULLC(e49b69c1,9ef14ad2), ULLC(efbe4786,384f25e3),
623 ULLC(0fc19dc6,8b8cd5b5), ULLC(240ca1cc,77ac9c65),
624 ULLC(2de92c6f,592b0275), ULLC(4a7484aa,6ea6e483),
625 ULLC(5cb0a9dc,bd41fbd4), ULLC(76f988da,831153b5),
626 ULLC(983e5152,ee66dfab), ULLC(a831c66d,2db43210),
627 ULLC(b00327c8,98fb213f), ULLC(bf597fc7,beef0ee4),
628 ULLC(c6e00bf3,3da88fc2), ULLC(d5a79147,930aa725),
629 ULLC(06ca6351,e003826f), ULLC(14292967,0a0e6e70),
630 ULLC(27b70a85,46d22ffc), ULLC(2e1b2138,5c26c926),
631 ULLC(4d2c6dfc,5ac42aed), ULLC(53380d13,9d95b3df),
632 ULLC(650a7354,8baf63de), ULLC(766a0abb,3c77b2a8),
633 ULLC(81c2c92e,47edaee6), ULLC(92722c85,1482353b),
634 ULLC(a2bfe8a1,4cf10364), ULLC(a81a664b,bc423001),
635 ULLC(c24b8b70,d0f89791), ULLC(c76c51a3,0654be30),
636 ULLC(d192e819,d6ef5218), ULLC(d6990624,5565a910),
637 ULLC(f40e3585,5771202a), ULLC(106aa070,32bbd1b8),
638 ULLC(19a4c116,b8d2d0c8), ULLC(1e376c08,5141ab53),
639 ULLC(2748774c,df8eeb99), ULLC(34b0bcb5,e19b48a8),
640 ULLC(391c0cb3,c5c95a63), ULLC(4ed8aa4a,e3418acb),
641 ULLC(5b9cca4f,7763e373), ULLC(682e6ff3,d6b2b8a3),
642 ULLC(748f82ee,5defb2fc), ULLC(78a5636f,43172f60),
643 ULLC(84c87814,a1f0ab72), ULLC(8cc70208,1a6439ec),
644 ULLC(90befffa,23631e28), ULLC(a4506ceb,de82bde9),
645 ULLC(bef9a3f7,b2c67915), ULLC(c67178f2,e372532b),
646 ULLC(ca273ece,ea26619c), ULLC(d186b8c7,21c0c207),
647 ULLC(eada7dd6,cde0eb1e), ULLC(f57d4f7f,ee6ed178),
648 ULLC(06f067aa,72176fba), ULLC(0a637dc5,a2c898a6),
649 ULLC(113f9804,bef90dae), ULLC(1b710b35,131c471b),
650 ULLC(28db77f5,23047d84), ULLC(32caab7b,40c72493),
651 ULLC(3c9ebe0a,15c9bebc), ULLC(431d67c4,9c100d4c),
652 ULLC(4cc5d4be,cb3e42b6), ULLC(597f299c,fc657e2a),
653 ULLC(5fcb6fab,3ad6faec), ULLC(6c44198c,4a475817)
654 #endif
657 struct SHA512ContextStr {
658 union {
659 PRUint64 w[80]; /* message schedule, input buffer, plus 64 words */
660 PRUint32 l[160];
661 PRUint8 b[640];
662 } u;
663 PRUint64 h[8]; /* 8 state variables */
664 PRUint64 sizeLo; /* 64-bit count of hashed bytes. */
667 /* =========== SHA512 implementation ===================================== */
669 /* SHA-512 initial hash values */
670 static const PRUint64 H512[8] = {
671 #if PR_BYTES_PER_LONG == 8
672 0x6a09e667f3bcc908UL , 0xbb67ae8584caa73bUL ,
673 0x3c6ef372fe94f82bUL , 0xa54ff53a5f1d36f1UL ,
674 0x510e527fade682d1UL , 0x9b05688c2b3e6c1fUL ,
675 0x1f83d9abfb41bd6bUL , 0x5be0cd19137e2179UL
676 #else
677 ULLC(6a09e667,f3bcc908), ULLC(bb67ae85,84caa73b),
678 ULLC(3c6ef372,fe94f82b), ULLC(a54ff53a,5f1d36f1),
679 ULLC(510e527f,ade682d1), ULLC(9b05688c,2b3e6c1f),
680 ULLC(1f83d9ab,fb41bd6b), ULLC(5be0cd19,137e2179)
681 #endif
685 SHA512Context *
686 SHA512_NewContext(void)
688 SHA512Context *ctx = PORT_New(SHA512Context);
689 return ctx;
692 void
693 SHA512_DestroyContext(SHA512Context *ctx, PRBool freeit)
695 if (freeit) {
696 PORT_ZFree(ctx, sizeof *ctx);
700 void
701 SHA512_Begin(SHA512Context *ctx)
703 memset(ctx, 0, sizeof *ctx);
704 memcpy(H, H512, sizeof H512);
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
719 #if defined(HAVE_LONG_LONG)
721 #define ADDTO(x,y) y += x
723 #define INITW(t) W[t] = (s1(W[t-2]) + W[t-7] + s0(W[t-15]) + W[t-16])
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)
731 #else /* use only 32-bit variables, and don't unroll loops */
733 #undef NOUNROLL512
734 #define NOUNROLL512 1
736 #define ADDTO(x,y) y.lo += x.lo; y.hi += x.hi + (x.lo > y.lo)
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))
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))
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))
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))
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))
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))
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)
771 #define ROUND(n,a,b,c,d,e,f,g,h) \
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) \
788 #endif
790 static void
791 SHA512_Compress(SHA512Context *ctx)
793 #if defined(IS_LITTLE_ENDIAN)
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]);
817 #endif
820 PRUint64 t1, t2;
821 #ifdef NOUNROLL512
823 /* prepare the "message schedule" */
824 int t;
825 for (t = 16; t < 80; ++t) {
826 INITW(t);
829 #else
830 INITW(16);
831 INITW(17);
832 INITW(18);
833 INITW(19);
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);
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);
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);
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);
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);
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
902 #ifdef SHA512_TRACE
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
913 #endif
915 PRUint64 a, b, c, d, e, f, g, h;
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];
926 #ifdef NOUNROLL512
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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
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]);
1043 void
1044 SHA512_Update(SHA512Context *ctx, const unsigned char *input,
1045 unsigned int inputLen)
1047 unsigned int inBuf;
1048 if (!inputLen)
1049 return;
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
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);
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);
1080 /* if data left over, fill it into buffer */
1081 if (inputLen)
1082 memcpy(B, input, inputLen);
1085 void
1086 SHA512_End(SHA512Context *ctx, unsigned char *digest,
1087 unsigned int *digestLen, unsigned int maxDigestLen)
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
1102 SHA512_Update(ctx, pad, padLen);
1104 #if defined(HAVE_LONG_LONG)
1105 W[14] = 0;
1106 #else
1107 W[14].lo = 0;
1108 W[14].hi = 0;
1109 #endif
1111 W[15] = lo;
1112 #if defined(IS_LITTLE_ENDIAN)
1113 BYTESWAP8(W[15]);
1114 #endif
1115 SHA512_Compress(ctx);
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;
1134 SECStatus
1135 SHA512_HashBuf(unsigned char *dest, const unsigned char *src,
1136 unsigned int src_length)
1138 SHA512Context ctx;
1139 unsigned int outLen;
1141 SHA512_Begin(&ctx);
1142 SHA512_Update(&ctx, src, src_length);
1143 SHA512_End(&ctx, dest, &outLen, SHA512_LENGTH);
1145 return SECSuccess;
1149 SECStatus
1150 SHA512_Hash(unsigned char *dest, const char *src)
1152 return SHA512_HashBuf(dest, (const unsigned char *)src, PORT_Strlen(src));
1156 void SHA512_TraceState(SHA512Context *ctx) { }
1158 unsigned int
1159 SHA512_FlattenSize(SHA512Context *ctx)
1161 return sizeof *ctx;
1164 SECStatus
1165 SHA512_Flatten(SHA512Context *ctx,unsigned char *space)
1167 PORT_Memcpy(space, ctx, sizeof *ctx);
1168 return SECSuccess;
1171 SHA512Context *
1172 SHA512_Resurrect(unsigned char *space, void *arg)
1174 SHA512Context *ctx = SHA512_NewContext();
1175 if (ctx)
1176 PORT_Memcpy(ctx, space, sizeof *ctx);
1177 return ctx;
1180 void SHA512_Clone(SHA512Context *dest, SHA512Context *src)
1182 memcpy(dest, src, sizeof *dest);
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.
1192 /* SHA-384 initial hash values */
1193 static const PRUint64 H384[8] = {
1194 #if PR_BYTES_PER_LONG == 8
1195 0xcbbb9d5dc1059ed8UL , 0x629a292a367cd507UL ,
1196 0x9159015a3070dd17UL , 0x152fecd8f70e5939UL ,
1197 0x67332667ffc00b31UL , 0x8eb44a8768581511UL ,
1198 0xdb0c2e0d64f98fa7UL , 0x47b5481dbefa4fa4UL
1199 #else
1200 ULLC(cbbb9d5d,c1059ed8), ULLC(629a292a,367cd507),
1201 ULLC(9159015a,3070dd17), ULLC(152fecd8,f70e5939),
1202 ULLC(67332667,ffc00b31), ULLC(8eb44a87,68581511),
1203 ULLC(db0c2e0d,64f98fa7), ULLC(47b5481d,befa4fa4)
1204 #endif
1207 SHA384Context *
1208 SHA384_NewContext(void)
1210 return SHA512_NewContext();
1213 void
1214 SHA384_DestroyContext(SHA384Context *ctx, PRBool freeit)
1216 SHA512_DestroyContext(ctx, freeit);
1219 void
1220 SHA384_Begin(SHA384Context *ctx)
1222 memset(ctx, 0, sizeof *ctx);
1223 memcpy(H, H384, sizeof H384);
1226 void
1227 SHA384_Update(SHA384Context *ctx, const unsigned char *input,
1228 unsigned int inputLen)
1230 SHA512_Update(ctx, input, inputLen);
1233 void
1234 SHA384_End(SHA384Context *ctx, unsigned char *digest,
1235 unsigned int *digestLen, unsigned int maxDigestLen)
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);
1242 SECStatus
1243 SHA384_HashBuf(unsigned char *dest, const unsigned char *src,
1244 unsigned int src_length)
1246 SHA512Context ctx;
1247 unsigned int outLen;
1249 SHA384_Begin(&ctx);
1250 SHA512_Update(&ctx, src, src_length);
1251 SHA512_End(&ctx, dest, &outLen, SHA384_LENGTH);
1253 return SECSuccess;
1256 SECStatus
1257 SHA384_Hash(unsigned char *dest, const char *src)
1259 return SHA384_HashBuf(dest, (const unsigned char *)src, PORT_Strlen(src));
1262 void SHA384_TraceState(SHA384Context *ctx) { }
1264 unsigned int
1265 SHA384_FlattenSize(SHA384Context *ctx)
1267 return sizeof(SHA384Context);
1270 SECStatus
1271 SHA384_Flatten(SHA384Context *ctx,unsigned char *space)
1273 return SHA512_Flatten(ctx, space);
1276 SHA384Context *
1277 SHA384_Resurrect(unsigned char *space, void *arg)
1279 return SHA512_Resurrect(space, arg);
1282 void SHA384_Clone(SHA384Context *dest, SHA384Context *src)
1284 memcpy(dest, src, sizeof *dest);
1286 #endif /* Comment out unused code. */
1288 /* ======================================================================= */
1289 #ifdef SELFTEST
1290 #include <stdio.h>
1292 static const char abc[] = { "abc" };
1293 static const char abcdbc[] = {
1294 "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"
1296 static const char abcdef[] = {
1297 "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmn"
1298 "hijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu"
1301 void
1302 dumpHash32(const unsigned char *buf, unsigned int bufLen)
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]);
1308 printf("\n");
1311 void test256(void)
1313 unsigned char outBuf[SHA256_LENGTH];
1315 printf("SHA256, input = %s\n", abc);
1316 SHA256_Hash(outBuf, abc);
1317 dumpHash32(outBuf, sizeof outBuf);
1319 printf("SHA256, input = %s\n", abcdbc);
1320 SHA256_Hash(outBuf, abcdbc);
1321 dumpHash32(outBuf, sizeof outBuf);
1324 void
1325 dumpHash64(const unsigned char *buf, unsigned int bufLen)
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]);
1335 printf("\n");
1338 void test512(void)
1340 unsigned char outBuf[SHA512_LENGTH];
1342 printf("SHA512, input = %s\n", abc);
1343 SHA512_Hash(outBuf, abc);
1344 dumpHash64(outBuf, sizeof outBuf);
1346 printf("SHA512, input = %s\n", abcdef);
1347 SHA512_Hash(outBuf, abcdef);
1348 dumpHash64(outBuf, sizeof outBuf);
1351 void time512(void)
1353 unsigned char outBuf[SHA512_LENGTH];
1355 SHA512_Hash(outBuf, abc);
1356 SHA512_Hash(outBuf, abcdef);
1359 void test384(void)
1361 unsigned char outBuf[SHA384_LENGTH];
1363 printf("SHA384, input = %s\n", abc);
1364 SHA384_Hash(outBuf, abc);
1365 dumpHash64(outBuf, sizeof outBuf);
1367 printf("SHA384, input = %s\n", abcdef);
1368 SHA384_Hash(outBuf, abcdef);
1369 dumpHash64(outBuf, sizeof outBuf);
1372 int main (int argc, char *argv[], char *envp[])
1374 int i = 1;
1375 if (argc > 1) {
1376 i = atoi(argv[1]);
1378 if (i < 2) {
1379 test256();
1380 test512();
1381 test384();
1382 } else {
1383 while (i-- > 0) {
1384 time512();
1386 printf("done\n");
1388 return 0;
1391 #endif