1ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen/*
2ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen * sha512.c - implementation of SHA256, SHA384 and SHA512
3ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen *
4ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen * ***** BEGIN LICENSE BLOCK *****
5ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen * Version: MPL 1.1/GPL 2.0/LGPL 2.1
6ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen *
7ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen * The contents of this file are subject to the Mozilla Public License Version
8ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen * 1.1 (the "License"); you may not use this file except in compliance with
9ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen * the License. You may obtain a copy of the License at
10ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen * http://www.mozilla.org/MPL/
11ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen *
12ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen * Software distributed under the License is distributed on an "AS IS" basis,
13ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
14ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen * for the specific language governing rights and limitations under the
15ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen * License.
16ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen *
17ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen * The Original Code is the Netscape security libraries.
18ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen *
19ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen * The Initial Developer of the Original Code is
20ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen * Netscape Communications Corporation.
21ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen * Portions created by the Initial Developer are Copyright (C) 2002
22ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen * the Initial Developer. All Rights Reserved.
23ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen *
24ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen * Contributor(s):
25ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen *
26ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen * Alternatively, the contents of this file may be used under the terms of
27ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen * either the GNU General Public License Version 2 or later (the "GPL"), or
28ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
29ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen * in which case the provisions of the GPL or the LGPL are applicable instead
30ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen * of those above. If you wish to allow use of your version of this file only
31ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen * under the terms of either the GPL or the LGPL, and not to allow others to
32ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen * use your version of this file under the terms of the MPL, indicate your
33ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen * decision by deleting the provisions above and replace them with the notice
34ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen * and other provisions required by the GPL or the LGPL. If you do not delete
35ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen * the provisions above, a recipient may use your version of this file under
36ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen * the terms of any one of the MPL, the GPL or the LGPL.
37ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen *
38ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen * ***** END LICENSE BLOCK ***** */
39ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen/* $Id: sha512.c,v 1.9 2006/10/13 16:54:04 wtchang%redhat.com Exp $ */
40ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
41ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Prevent manual unrolling in the sha256 code, which reduces the binary code
42ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// size from ~10k to ~1k.  The performance should be reasonable for our use.
43ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#define NOUNROLL256 1
44ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
45ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "base/third_party/nspr/prtypes.h"  /* for PRUintXX */
46ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#if defined(_X86_) || defined(SHA_NO_LONG_LONG)
47ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#define NOUNROLL512 1
48ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#undef HAVE_LONG_LONG
49ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#endif
50ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "crypto/third_party/nss/blapi.h"
51ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "crypto/third_party/nss/sha256.h"    /* for struct SHA256ContextStr */
52ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
53ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include <stdlib.h>
54ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include <string.h>
55ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#define PORT_New(type) static_cast<type*>(malloc(sizeof(type)))
56ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#define PORT_ZFree(ptr, len) do { memset(ptr, 0, len); free(ptr); } while (0)
57ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#define PORT_Strlen(s) static_cast<unsigned int>(strlen(s))
58ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#define PORT_Memcpy memcpy
59ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
60ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen/* ============= Common constants and defines ======================= */
61ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
62ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#define W ctx->u.w
63ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#define B ctx->u.b
64ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#define H ctx->h
65ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
66ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#define SHR(x,n) (x >> n)
67ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#define SHL(x,n) (x << n)
68ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#define Ch(x,y,z)  ((x & y) ^ (~x & z))
69ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#define Maj(x,y,z) ((x & y) ^ (x & z) ^ (y & z))
70ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
71ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen/* Padding used with all flavors of SHA */
72ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenstatic const PRUint8 pad[240] = {
73ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen0x80,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,
74ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   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
75ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   /* compiler will fill the rest in with zeros */
76ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen};
77ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
78ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen/* ============= SHA256 implemenmtation ================================== */
79ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
80ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen/* SHA-256 constants, K256. */
81ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenstatic const PRUint32 K256[64] = {
82ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5,
83ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
84ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
85ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
86ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc,
87ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
88ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7,
89ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
90ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
91ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
92ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3,
93ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
94ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5,
95ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
96ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
97ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
98ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen};
99ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
100ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen/* SHA-256 initial hash values */
101ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenstatic const PRUint32 H256[8] = {
102ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a,
103ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19
104ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen};
105ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
106ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#if defined(_MSC_VER) && defined(_X86_)
107ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#ifndef FORCEINLINE
108ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#if (_MSC_VER >= 1200)
109ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#define FORCEINLINE __forceinline
110ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#else
111ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#define FORCEINLINE __inline
112ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#endif
113ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#endif
114ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#define FASTCALL __fastcall
115ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
116ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenstatic FORCEINLINE PRUint32 FASTCALL
117ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenswap4b(PRUint32 dwd)
118ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen{
119ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    __asm {
120ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    	mov   eax,dwd
121ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen	bswap eax
122ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    }
123ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
124ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
125ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#define SHA_HTONL(x) swap4b(x)
126ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#define BYTESWAP4(x)  x = SHA_HTONL(x)
127ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
128ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#elif defined(LINUX) && defined(_X86_)
129ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#undef  __OPTIMIZE__
130ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#define __OPTIMIZE__ 1
131ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#undef  __pentium__
132ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#define __pentium__ 1
133ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include <byteswap.h>
134ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#define SHA_HTONL(x) bswap_32(x)
135ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#define BYTESWAP4(x)  x = SHA_HTONL(x)
136ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
137ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#else /* neither windows nor Linux PC */
138ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#define SWAP4MASK  0x00FF00FF
139ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#define SHA_HTONL(x) (t1 = (x), t1 = (t1 << 16) | (t1 >> 16), \
140ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                      ((t1 & SWAP4MASK) << 8) | ((t1 >> 8) & SWAP4MASK))
141ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#define BYTESWAP4(x)  x = SHA_HTONL(x)
142ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#endif
143ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
144ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#if defined(_MSC_VER) && defined(_X86_)
145ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#pragma intrinsic (_lrotr, _lrotl)
146ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#define ROTR32(x,n) _lrotr(x,n)
147ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#define ROTL32(x,n) _lrotl(x,n)
148ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#else
149ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#define ROTR32(x,n) ((x >> n) | (x << ((8 * sizeof x) - n)))
150ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#define ROTL32(x,n) ((x << n) | (x >> ((8 * sizeof x) - n)))
151ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#endif
152ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
153ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen/* Capitol Sigma and lower case sigma functions */
154ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#define S0(x) (ROTR32(x, 2) ^ ROTR32(x,13) ^ ROTR32(x,22))
155ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#define S1(x) (ROTR32(x, 6) ^ ROTR32(x,11) ^ ROTR32(x,25))
156ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#define s0(x) (t1 = x, ROTR32(t1, 7) ^ ROTR32(t1,18) ^ SHR(t1, 3))
157ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#define s1(x) (t2 = x, ROTR32(t2,17) ^ ROTR32(t2,19) ^ SHR(t2,10))
158ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
159ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenSHA256Context *
160ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenSHA256_NewContext(void)
161ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen{
162ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    SHA256Context *ctx = PORT_New(SHA256Context);
163ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    return ctx;
164ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
165ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
166ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid
167ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenSHA256_DestroyContext(SHA256Context *ctx, PRBool freeit)
168ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen{
169ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    if (freeit) {
170ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        PORT_ZFree(ctx, sizeof *ctx);
171ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    }
172ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
173ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
174ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid
175ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenSHA256_Begin(SHA256Context *ctx)
176ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen{
177ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    memset(ctx, 0, sizeof *ctx);
178ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    memcpy(H, H256, sizeof H256);
179ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
180ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
181ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenstatic void
182ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenSHA256_Compress(SHA256Context *ctx)
183ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen{
184ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  {
185ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    register PRUint32 t1, t2;
186ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
187ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#if defined(IS_LITTLE_ENDIAN)
188ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    BYTESWAP4(W[0]);
189ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    BYTESWAP4(W[1]);
190ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    BYTESWAP4(W[2]);
191ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    BYTESWAP4(W[3]);
192ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    BYTESWAP4(W[4]);
193ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    BYTESWAP4(W[5]);
194ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    BYTESWAP4(W[6]);
195ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    BYTESWAP4(W[7]);
196ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    BYTESWAP4(W[8]);
197ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    BYTESWAP4(W[9]);
198ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    BYTESWAP4(W[10]);
199ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    BYTESWAP4(W[11]);
200ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    BYTESWAP4(W[12]);
201ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    BYTESWAP4(W[13]);
202ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    BYTESWAP4(W[14]);
203ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    BYTESWAP4(W[15]);
204ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#endif
205ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
206ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#define INITW(t) W[t] = (s1(W[t-2]) + W[t-7] + s0(W[t-15]) + W[t-16])
207ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
208ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    /* prepare the "message schedule"   */
209ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#ifdef NOUNROLL256
210ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    {
211ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen	int t;
212ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen	for (t = 16; t < 64; ++t) {
213ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen	    INITW(t);
214ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen	}
215ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    }
216ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#else
217ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    INITW(16);
218ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    INITW(17);
219ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    INITW(18);
220ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    INITW(19);
221ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
222ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    INITW(20);
223ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    INITW(21);
224ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    INITW(22);
225ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    INITW(23);
226ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    INITW(24);
227ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    INITW(25);
228ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    INITW(26);
229ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    INITW(27);
230ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    INITW(28);
231ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    INITW(29);
232ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
233ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    INITW(30);
234ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    INITW(31);
235ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    INITW(32);
236ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    INITW(33);
237ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    INITW(34);
238ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    INITW(35);
239ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    INITW(36);
240ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    INITW(37);
241ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    INITW(38);
242ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    INITW(39);
243ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
244ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    INITW(40);
245ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    INITW(41);
246ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    INITW(42);
247ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    INITW(43);
248ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    INITW(44);
249ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    INITW(45);
250ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    INITW(46);
251ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    INITW(47);
252ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    INITW(48);
253ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    INITW(49);
254ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
255ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    INITW(50);
256ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    INITW(51);
257ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    INITW(52);
258ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    INITW(53);
259ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    INITW(54);
260ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    INITW(55);
261ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    INITW(56);
262ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    INITW(57);
263ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    INITW(58);
264ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    INITW(59);
265ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
266ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    INITW(60);
267ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    INITW(61);
268ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    INITW(62);
269ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    INITW(63);
270ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
271ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#endif
272ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#undef INITW
273ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
274ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  {
275ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    PRUint32 a, b, c, d, e, f, g, h;
276ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
277ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    a = H[0];
278ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    b = H[1];
279ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    c = H[2];
280ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    d = H[3];
281ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    e = H[4];
282ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    f = H[5];
283ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    g = H[6];
284ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    h = H[7];
285ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
286ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#define ROUND(n,a,b,c,d,e,f,g,h) \
287ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    h += S1(e) + Ch(e,f,g) + K256[n] + W[n]; \
288ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    d += h; \
289ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    h += S0(a) + Maj(a,b,c);
290ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
291ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#ifdef NOUNROLL256
292ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    {
293ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen	int t;
294ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen	for (t = 0; t < 64; t+= 8) {
295ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen	    ROUND(t+0,a,b,c,d,e,f,g,h)
296ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen	    ROUND(t+1,h,a,b,c,d,e,f,g)
297ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen	    ROUND(t+2,g,h,a,b,c,d,e,f)
298ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen	    ROUND(t+3,f,g,h,a,b,c,d,e)
299ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen	    ROUND(t+4,e,f,g,h,a,b,c,d)
300ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen	    ROUND(t+5,d,e,f,g,h,a,b,c)
301ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen	    ROUND(t+6,c,d,e,f,g,h,a,b)
302ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen	    ROUND(t+7,b,c,d,e,f,g,h,a)
303ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen	}
304ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    }
305ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#else
306ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ROUND( 0,a,b,c,d,e,f,g,h)
307ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ROUND( 1,h,a,b,c,d,e,f,g)
308ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ROUND( 2,g,h,a,b,c,d,e,f)
309ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ROUND( 3,f,g,h,a,b,c,d,e)
310ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ROUND( 4,e,f,g,h,a,b,c,d)
311ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ROUND( 5,d,e,f,g,h,a,b,c)
312ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ROUND( 6,c,d,e,f,g,h,a,b)
313ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ROUND( 7,b,c,d,e,f,g,h,a)
314ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
315ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ROUND( 8,a,b,c,d,e,f,g,h)
316ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ROUND( 9,h,a,b,c,d,e,f,g)
317ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ROUND(10,g,h,a,b,c,d,e,f)
318ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ROUND(11,f,g,h,a,b,c,d,e)
319ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ROUND(12,e,f,g,h,a,b,c,d)
320ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ROUND(13,d,e,f,g,h,a,b,c)
321ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ROUND(14,c,d,e,f,g,h,a,b)
322ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ROUND(15,b,c,d,e,f,g,h,a)
323ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
324ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ROUND(16,a,b,c,d,e,f,g,h)
325ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ROUND(17,h,a,b,c,d,e,f,g)
326ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ROUND(18,g,h,a,b,c,d,e,f)
327ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ROUND(19,f,g,h,a,b,c,d,e)
328ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ROUND(20,e,f,g,h,a,b,c,d)
329ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ROUND(21,d,e,f,g,h,a,b,c)
330ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ROUND(22,c,d,e,f,g,h,a,b)
331ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ROUND(23,b,c,d,e,f,g,h,a)
332ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
333ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ROUND(24,a,b,c,d,e,f,g,h)
334ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ROUND(25,h,a,b,c,d,e,f,g)
335ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ROUND(26,g,h,a,b,c,d,e,f)
336ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ROUND(27,f,g,h,a,b,c,d,e)
337ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ROUND(28,e,f,g,h,a,b,c,d)
338ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ROUND(29,d,e,f,g,h,a,b,c)
339ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ROUND(30,c,d,e,f,g,h,a,b)
340ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ROUND(31,b,c,d,e,f,g,h,a)
341ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
342ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ROUND(32,a,b,c,d,e,f,g,h)
343ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ROUND(33,h,a,b,c,d,e,f,g)
344ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ROUND(34,g,h,a,b,c,d,e,f)
345ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ROUND(35,f,g,h,a,b,c,d,e)
346ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ROUND(36,e,f,g,h,a,b,c,d)
347ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ROUND(37,d,e,f,g,h,a,b,c)
348ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ROUND(38,c,d,e,f,g,h,a,b)
349ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ROUND(39,b,c,d,e,f,g,h,a)
350ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
351ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ROUND(40,a,b,c,d,e,f,g,h)
352ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ROUND(41,h,a,b,c,d,e,f,g)
353ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ROUND(42,g,h,a,b,c,d,e,f)
354ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ROUND(43,f,g,h,a,b,c,d,e)
355ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ROUND(44,e,f,g,h,a,b,c,d)
356ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ROUND(45,d,e,f,g,h,a,b,c)
357ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ROUND(46,c,d,e,f,g,h,a,b)
358ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ROUND(47,b,c,d,e,f,g,h,a)
359ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
360ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ROUND(48,a,b,c,d,e,f,g,h)
361ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ROUND(49,h,a,b,c,d,e,f,g)
362ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ROUND(50,g,h,a,b,c,d,e,f)
363ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ROUND(51,f,g,h,a,b,c,d,e)
364ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ROUND(52,e,f,g,h,a,b,c,d)
365ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ROUND(53,d,e,f,g,h,a,b,c)
366ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ROUND(54,c,d,e,f,g,h,a,b)
367ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ROUND(55,b,c,d,e,f,g,h,a)
368ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
369ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ROUND(56,a,b,c,d,e,f,g,h)
370ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ROUND(57,h,a,b,c,d,e,f,g)
371ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ROUND(58,g,h,a,b,c,d,e,f)
372ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ROUND(59,f,g,h,a,b,c,d,e)
373ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ROUND(60,e,f,g,h,a,b,c,d)
374ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ROUND(61,d,e,f,g,h,a,b,c)
375ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ROUND(62,c,d,e,f,g,h,a,b)
376ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ROUND(63,b,c,d,e,f,g,h,a)
377ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#endif
378ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
379ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    H[0] += a;
380ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    H[1] += b;
381ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    H[2] += c;
382ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    H[3] += d;
383ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    H[4] += e;
384ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    H[5] += f;
385ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    H[6] += g;
386ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    H[7] += h;
387ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
388ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#undef ROUND
389ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
390ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
391ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#undef s0
392ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#undef s1
393ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#undef S0
394ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#undef S1
395ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
396ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid
397ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenSHA256_Update(SHA256Context *ctx, const unsigned char *input,
398ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen		    unsigned int inputLen)
399ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen{
400ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    unsigned int inBuf = ctx->sizeLo & 0x3f;
401ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    if (!inputLen)
402ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    	return;
403ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
404ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    /* Add inputLen into the count of bytes processed, before processing */
405ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    if ((ctx->sizeLo += inputLen) < inputLen)
406ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    	ctx->sizeHi++;
407ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
408ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    /* if data already in buffer, attemp to fill rest of buffer */
409ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    if (inBuf) {
410ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    	unsigned int todo = SHA256_BLOCK_LENGTH - inBuf;
411ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen	if (inputLen < todo)
412ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen	    todo = inputLen;
413ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen	memcpy(B + inBuf, input, todo);
414ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen	input    += todo;
415ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen	inputLen -= todo;
416ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen	if (inBuf + todo == SHA256_BLOCK_LENGTH)
417ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen	    SHA256_Compress(ctx);
418ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    }
419ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
420ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    /* if enough data to fill one or more whole buffers, process them. */
421ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    while (inputLen >= SHA256_BLOCK_LENGTH) {
422ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    	memcpy(B, input, SHA256_BLOCK_LENGTH);
423ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen	input    += SHA256_BLOCK_LENGTH;
424ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen	inputLen -= SHA256_BLOCK_LENGTH;
425ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen	SHA256_Compress(ctx);
426ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    }
427ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    /* if data left over, fill it into buffer */
428ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    if (inputLen)
429ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    	memcpy(B, input, inputLen);
430ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
431ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
432ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid
433ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenSHA256_End(SHA256Context *ctx, unsigned char *digest,
434ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen           unsigned int *digestLen, unsigned int maxDigestLen)
435ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen{
436ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    unsigned int inBuf = ctx->sizeLo & 0x3f;
437ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    unsigned int padLen = (inBuf < 56) ? (56 - inBuf) : (56 + 64 - inBuf);
438ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    PRUint32 hi, lo;
439ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#ifdef SWAP4MASK
440ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    PRUint32 t1;
441ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#endif
442ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
443ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    hi = (ctx->sizeHi << 3) | (ctx->sizeLo >> 29);
444ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    lo = (ctx->sizeLo << 3);
445ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
446ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    SHA256_Update(ctx, pad, padLen);
447ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
448ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#if defined(IS_LITTLE_ENDIAN)
449ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    W[14] = SHA_HTONL(hi);
450ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    W[15] = SHA_HTONL(lo);
451ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#else
452ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    W[14] = hi;
453ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    W[15] = lo;
454ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#endif
455ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    SHA256_Compress(ctx);
456ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
457ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    /* now output the answer */
458ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#if defined(IS_LITTLE_ENDIAN)
459ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    BYTESWAP4(H[0]);
460ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    BYTESWAP4(H[1]);
461ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    BYTESWAP4(H[2]);
462ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    BYTESWAP4(H[3]);
463ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    BYTESWAP4(H[4]);
464ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    BYTESWAP4(H[5]);
465ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    BYTESWAP4(H[6]);
466ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    BYTESWAP4(H[7]);
467ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#endif
468ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    padLen = PR_MIN(SHA256_LENGTH, maxDigestLen);
469ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    memcpy(digest, H, padLen);
470ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    if (digestLen)
471ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen	*digestLen = padLen;
472ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
473ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
474ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen/* Comment out unused code, mostly the SHA384 and SHA512 implementations. */
475ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#if 0
476ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenSECStatus
477ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenSHA256_HashBuf(unsigned char *dest, const unsigned char *src,
478ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen               unsigned int src_length)
479ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen{
480ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    SHA256Context ctx;
481ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    unsigned int outLen;
482ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
483ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    SHA256_Begin(&ctx);
484ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    SHA256_Update(&ctx, src, src_length);
485ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    SHA256_End(&ctx, dest, &outLen, SHA256_LENGTH);
486ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
487ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    return SECSuccess;
488ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
489ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
490ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
491ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenSECStatus
492ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenSHA256_Hash(unsigned char *dest, const char *src)
493ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen{
494ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    return SHA256_HashBuf(dest, (const unsigned char *)src, PORT_Strlen(src));
495ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
496ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
497ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
498ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid SHA256_TraceState(SHA256Context *ctx) { }
499ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
500ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenunsigned int
501ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenSHA256_FlattenSize(SHA256Context *ctx)
502ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen{
503ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    return sizeof *ctx;
504ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
505ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
506ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenSECStatus
507ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenSHA256_Flatten(SHA256Context *ctx,unsigned char *space)
508ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen{
509ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    PORT_Memcpy(space, ctx, sizeof *ctx);
510ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    return SECSuccess;
511ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
512ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
513ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenSHA256Context *
514ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenSHA256_Resurrect(unsigned char *space, void *arg)
515ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen{
516ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    SHA256Context *ctx = SHA256_NewContext();
517ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    if (ctx)
518ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen	PORT_Memcpy(ctx, space, sizeof *ctx);
519ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    return ctx;
520ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
521ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
522ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid SHA256_Clone(SHA256Context *dest, SHA256Context *src)
523ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen{
524ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    memcpy(dest, src, sizeof *dest);
525ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
526ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
527ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
528ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen/* ======= SHA512 and SHA384 common constants and defines ================= */
529ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
530ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen/* common #defines for SHA512 and SHA384 */
531ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#if defined(HAVE_LONG_LONG)
532ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#define ROTR64(x,n) ((x >> n) | (x << (64 - n)))
533ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#define ROTL64(x,n) ((x << n) | (x >> (64 - n)))
534ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
535ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#define S0(x) (ROTR64(x,28) ^ ROTR64(x,34) ^ ROTR64(x,39))
536ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#define S1(x) (ROTR64(x,14) ^ ROTR64(x,18) ^ ROTR64(x,41))
537ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#define s0(x) (t1 = x, ROTR64(t1, 1) ^ ROTR64(t1, 8) ^ SHR(t1,7))
538ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#define s1(x) (t2 = x, ROTR64(t2,19) ^ ROTR64(t2,61) ^ SHR(t2,6))
539ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
540ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#if PR_BYTES_PER_LONG == 8
541ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#define ULLC(hi,lo) 0x ## hi ## lo ## UL
542ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#elif defined(_MSC_VER)
543ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#define ULLC(hi,lo) 0x ## hi ## lo ## ui64
544ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#else
545ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#define ULLC(hi,lo) 0x ## hi ## lo ## ULL
546ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#endif
547ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
548ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#define SHA_MASK16 ULLC(0000FFFF,0000FFFF)
549ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#define SHA_MASK8  ULLC(00FF00FF,00FF00FF)
550ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#define SHA_HTONLL(x) (t1 = x, \
551ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  t1 = ((t1 & SHA_MASK8 ) <<  8) | ((t1 >>  8) & SHA_MASK8 ), \
552ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  t1 = ((t1 & SHA_MASK16) << 16) | ((t1 >> 16) & SHA_MASK16), \
553ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  (t1 >> 32) | (t1 << 32))
554ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#define BYTESWAP8(x)  x = SHA_HTONLL(x)
555ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
556ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#else /* no long long */
557ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
558ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#if defined(IS_LITTLE_ENDIAN)
559ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#define ULLC(hi,lo) { 0x ## lo ## U, 0x ## hi ## U }
560ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#else
561ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#define ULLC(hi,lo) { 0x ## hi ## U, 0x ## lo ## U }
562ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#endif
563ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
564ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#define SHA_HTONLL(x) ( BYTESWAP4(x.lo), BYTESWAP4(x.hi), \
565ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   x.hi ^= x.lo ^= x.hi ^= x.lo, x)
566ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#define BYTESWAP8(x)  do { PRUint32 tmp; BYTESWAP4(x.lo); BYTESWAP4(x.hi); \
567ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen   tmp = x.lo; x.lo = x.hi; x.hi = tmp; } while (0)
568ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#endif
569ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
570ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen/* SHA-384 and SHA-512 constants, K512. */
571ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenstatic const PRUint64 K512[80] = {
572ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#if PR_BYTES_PER_LONG == 8
573ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen     0x428a2f98d728ae22UL ,  0x7137449123ef65cdUL ,
574ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen     0xb5c0fbcfec4d3b2fUL ,  0xe9b5dba58189dbbcUL ,
575ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen     0x3956c25bf348b538UL ,  0x59f111f1b605d019UL ,
576ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen     0x923f82a4af194f9bUL ,  0xab1c5ed5da6d8118UL ,
577ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen     0xd807aa98a3030242UL ,  0x12835b0145706fbeUL ,
578ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen     0x243185be4ee4b28cUL ,  0x550c7dc3d5ffb4e2UL ,
579ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen     0x72be5d74f27b896fUL ,  0x80deb1fe3b1696b1UL ,
580ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen     0x9bdc06a725c71235UL ,  0xc19bf174cf692694UL ,
581ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen     0xe49b69c19ef14ad2UL ,  0xefbe4786384f25e3UL ,
582ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen     0x0fc19dc68b8cd5b5UL ,  0x240ca1cc77ac9c65UL ,
583ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen     0x2de92c6f592b0275UL ,  0x4a7484aa6ea6e483UL ,
584ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen     0x5cb0a9dcbd41fbd4UL ,  0x76f988da831153b5UL ,
585ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen     0x983e5152ee66dfabUL ,  0xa831c66d2db43210UL ,
586ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen     0xb00327c898fb213fUL ,  0xbf597fc7beef0ee4UL ,
587ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen     0xc6e00bf33da88fc2UL ,  0xd5a79147930aa725UL ,
588ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen     0x06ca6351e003826fUL ,  0x142929670a0e6e70UL ,
589ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen     0x27b70a8546d22ffcUL ,  0x2e1b21385c26c926UL ,
590ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen     0x4d2c6dfc5ac42aedUL ,  0x53380d139d95b3dfUL ,
591ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen     0x650a73548baf63deUL ,  0x766a0abb3c77b2a8UL ,
592ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen     0x81c2c92e47edaee6UL ,  0x92722c851482353bUL ,
593ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen     0xa2bfe8a14cf10364UL ,  0xa81a664bbc423001UL ,
594ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen     0xc24b8b70d0f89791UL ,  0xc76c51a30654be30UL ,
595ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen     0xd192e819d6ef5218UL ,  0xd69906245565a910UL ,
596ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen     0xf40e35855771202aUL ,  0x106aa07032bbd1b8UL ,
597ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen     0x19a4c116b8d2d0c8UL ,  0x1e376c085141ab53UL ,
598ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen     0x2748774cdf8eeb99UL ,  0x34b0bcb5e19b48a8UL ,
599ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen     0x391c0cb3c5c95a63UL ,  0x4ed8aa4ae3418acbUL ,
600ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen     0x5b9cca4f7763e373UL ,  0x682e6ff3d6b2b8a3UL ,
601ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen     0x748f82ee5defb2fcUL ,  0x78a5636f43172f60UL ,
602ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen     0x84c87814a1f0ab72UL ,  0x8cc702081a6439ecUL ,
603ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen     0x90befffa23631e28UL ,  0xa4506cebde82bde9UL ,
604ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen     0xbef9a3f7b2c67915UL ,  0xc67178f2e372532bUL ,
605ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen     0xca273eceea26619cUL ,  0xd186b8c721c0c207UL ,
606ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen     0xeada7dd6cde0eb1eUL ,  0xf57d4f7fee6ed178UL ,
607ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen     0x06f067aa72176fbaUL ,  0x0a637dc5a2c898a6UL ,
608ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen     0x113f9804bef90daeUL ,  0x1b710b35131c471bUL ,
609ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen     0x28db77f523047d84UL ,  0x32caab7b40c72493UL ,
610ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen     0x3c9ebe0a15c9bebcUL ,  0x431d67c49c100d4cUL ,
611ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen     0x4cc5d4becb3e42b6UL ,  0x597f299cfc657e2aUL ,
612ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen     0x5fcb6fab3ad6faecUL ,  0x6c44198c4a475817UL
613ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#else
614ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ULLC(428a2f98,d728ae22), ULLC(71374491,23ef65cd),
615ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ULLC(b5c0fbcf,ec4d3b2f), ULLC(e9b5dba5,8189dbbc),
616ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ULLC(3956c25b,f348b538), ULLC(59f111f1,b605d019),
617ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ULLC(923f82a4,af194f9b), ULLC(ab1c5ed5,da6d8118),
618ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ULLC(d807aa98,a3030242), ULLC(12835b01,45706fbe),
619ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ULLC(243185be,4ee4b28c), ULLC(550c7dc3,d5ffb4e2),
620ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ULLC(72be5d74,f27b896f), ULLC(80deb1fe,3b1696b1),
621ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ULLC(9bdc06a7,25c71235), ULLC(c19bf174,cf692694),
622ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ULLC(e49b69c1,9ef14ad2), ULLC(efbe4786,384f25e3),
623ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ULLC(0fc19dc6,8b8cd5b5), ULLC(240ca1cc,77ac9c65),
624ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ULLC(2de92c6f,592b0275), ULLC(4a7484aa,6ea6e483),
625ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ULLC(5cb0a9dc,bd41fbd4), ULLC(76f988da,831153b5),
626ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ULLC(983e5152,ee66dfab), ULLC(a831c66d,2db43210),
627ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ULLC(b00327c8,98fb213f), ULLC(bf597fc7,beef0ee4),
628ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ULLC(c6e00bf3,3da88fc2), ULLC(d5a79147,930aa725),
629ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ULLC(06ca6351,e003826f), ULLC(14292967,0a0e6e70),
630ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ULLC(27b70a85,46d22ffc), ULLC(2e1b2138,5c26c926),
631ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ULLC(4d2c6dfc,5ac42aed), ULLC(53380d13,9d95b3df),
632ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ULLC(650a7354,8baf63de), ULLC(766a0abb,3c77b2a8),
633ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ULLC(81c2c92e,47edaee6), ULLC(92722c85,1482353b),
634ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ULLC(a2bfe8a1,4cf10364), ULLC(a81a664b,bc423001),
635ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ULLC(c24b8b70,d0f89791), ULLC(c76c51a3,0654be30),
636ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ULLC(d192e819,d6ef5218), ULLC(d6990624,5565a910),
637ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ULLC(f40e3585,5771202a), ULLC(106aa070,32bbd1b8),
638ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ULLC(19a4c116,b8d2d0c8), ULLC(1e376c08,5141ab53),
639ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ULLC(2748774c,df8eeb99), ULLC(34b0bcb5,e19b48a8),
640ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ULLC(391c0cb3,c5c95a63), ULLC(4ed8aa4a,e3418acb),
641ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ULLC(5b9cca4f,7763e373), ULLC(682e6ff3,d6b2b8a3),
642ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ULLC(748f82ee,5defb2fc), ULLC(78a5636f,43172f60),
643ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ULLC(84c87814,a1f0ab72), ULLC(8cc70208,1a6439ec),
644ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ULLC(90befffa,23631e28), ULLC(a4506ceb,de82bde9),
645ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ULLC(bef9a3f7,b2c67915), ULLC(c67178f2,e372532b),
646ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ULLC(ca273ece,ea26619c), ULLC(d186b8c7,21c0c207),
647ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ULLC(eada7dd6,cde0eb1e), ULLC(f57d4f7f,ee6ed178),
648ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ULLC(06f067aa,72176fba), ULLC(0a637dc5,a2c898a6),
649ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ULLC(113f9804,bef90dae), ULLC(1b710b35,131c471b),
650ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ULLC(28db77f5,23047d84), ULLC(32caab7b,40c72493),
651ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ULLC(3c9ebe0a,15c9bebc), ULLC(431d67c4,9c100d4c),
652ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ULLC(4cc5d4be,cb3e42b6), ULLC(597f299c,fc657e2a),
653ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ULLC(5fcb6fab,3ad6faec), ULLC(6c44198c,4a475817)
654ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#endif
655ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen};
656ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
657ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenstruct SHA512ContextStr {
658ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    union {
659ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen	PRUint64 w[80];	    /* message schedule, input buffer, plus 64 words */
660ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen	PRUint32 l[160];
661ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen	PRUint8  b[640];
662ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    } u;
663ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    PRUint64 h[8];	    /* 8 state variables */
664ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    PRUint64 sizeLo;	    /* 64-bit count of hashed bytes. */
665ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen};
666ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
667ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen/* =========== SHA512 implementation ===================================== */
668ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
669ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen/* SHA-512 initial hash values */
670ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenstatic const PRUint64 H512[8] = {
671ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#if PR_BYTES_PER_LONG == 8
672ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen     0x6a09e667f3bcc908UL ,  0xbb67ae8584caa73bUL ,
673ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen     0x3c6ef372fe94f82bUL ,  0xa54ff53a5f1d36f1UL ,
674ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen     0x510e527fade682d1UL ,  0x9b05688c2b3e6c1fUL ,
675ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen     0x1f83d9abfb41bd6bUL ,  0x5be0cd19137e2179UL
676ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#else
677ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ULLC(6a09e667,f3bcc908), ULLC(bb67ae85,84caa73b),
678ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ULLC(3c6ef372,fe94f82b), ULLC(a54ff53a,5f1d36f1),
679ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ULLC(510e527f,ade682d1), ULLC(9b05688c,2b3e6c1f),
680ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ULLC(1f83d9ab,fb41bd6b), ULLC(5be0cd19,137e2179)
681ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#endif
682ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen};
683ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
684ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
685ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenSHA512Context *
686ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenSHA512_NewContext(void)
687ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen{
688ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    SHA512Context *ctx = PORT_New(SHA512Context);
689ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    return ctx;
690ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
691ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
692ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid
693ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenSHA512_DestroyContext(SHA512Context *ctx, PRBool freeit)
694ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen{
695ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    if (freeit) {
696ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        PORT_ZFree(ctx, sizeof *ctx);
697ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    }
698ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
699ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
700ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid
701ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenSHA512_Begin(SHA512Context *ctx)
702ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen{
703ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    memset(ctx, 0, sizeof *ctx);
704ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    memcpy(H, H512, sizeof H512);
705ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
706ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
707ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#if defined(SHA512_TRACE)
708ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#if defined(HAVE_LONG_LONG)
709ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#define DUMP(n,a,d,e,h) printf(" t = %2d, %s = %016lx, %s = %016lx\n", \
710ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen			       n, #e, d, #a, h);
711ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#else
712ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#define DUMP(n,a,d,e,h) printf(" t = %2d, %s = %08x%08x, %s = %08x%08x\n", \
713ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen			       n, #e, d.hi, d.lo, #a, h.hi, h.lo);
714ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#endif
715ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#else
716ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#define DUMP(n,a,d,e,h)
717ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#endif
718ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
719ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#if defined(HAVE_LONG_LONG)
720ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
721ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#define ADDTO(x,y) y += x
722ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
723ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#define INITW(t) W[t] = (s1(W[t-2]) + W[t-7] + s0(W[t-15]) + W[t-16])
724ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
725ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#define ROUND(n,a,b,c,d,e,f,g,h) \
726ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    h += S1(e) + Ch(e,f,g) + K512[n] + W[n]; \
727ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    d += h; \
728ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    h += S0(a) + Maj(a,b,c); \
729ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    DUMP(n,a,d,e,h)
730ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
731ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#else /* use only 32-bit variables, and don't unroll loops */
732ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
733ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#undef  NOUNROLL512
734ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#define NOUNROLL512 1
735ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
736ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#define ADDTO(x,y) y.lo += x.lo; y.hi += x.hi + (x.lo > y.lo)
737ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
738ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#define ROTR64a(x,n,lo,hi) (x.lo >> n | x.hi << (32-n))
739ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#define ROTR64A(x,n,lo,hi) (x.lo << (64-n) | x.hi >> (n-32))
740ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#define  SHR64a(x,n,lo,hi) (x.lo >> n | x.hi << (32-n))
741ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
742ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen/* Capitol Sigma and lower case sigma functions */
743ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#define s0lo(x) (ROTR64a(x,1,lo,hi) ^ ROTR64a(x,8,lo,hi) ^ SHR64a(x,7,lo,hi))
744ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#define s0hi(x) (ROTR64a(x,1,hi,lo) ^ ROTR64a(x,8,hi,lo) ^ (x.hi >> 7))
745ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
746ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#define s1lo(x) (ROTR64a(x,19,lo,hi) ^ ROTR64A(x,61,lo,hi) ^ SHR64a(x,6,lo,hi))
747ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#define s1hi(x) (ROTR64a(x,19,hi,lo) ^ ROTR64A(x,61,hi,lo) ^ (x.hi >> 6))
748ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
749ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#define S0lo(x)(ROTR64a(x,28,lo,hi) ^ ROTR64A(x,34,lo,hi) ^ ROTR64A(x,39,lo,hi))
750ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#define S0hi(x)(ROTR64a(x,28,hi,lo) ^ ROTR64A(x,34,hi,lo) ^ ROTR64A(x,39,hi,lo))
751ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
752ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#define S1lo(x)(ROTR64a(x,14,lo,hi) ^ ROTR64a(x,18,lo,hi) ^ ROTR64A(x,41,lo,hi))
753ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#define S1hi(x)(ROTR64a(x,14,hi,lo) ^ ROTR64a(x,18,hi,lo) ^ ROTR64A(x,41,hi,lo))
754ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
755ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen/* 32-bit versions of Ch and Maj */
756ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#define Chxx(x,y,z,lo) ((x.lo & y.lo) ^ (~x.lo & z.lo))
757ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#define Majx(x,y,z,lo) ((x.lo & y.lo) ^ (x.lo & z.lo) ^ (y.lo & z.lo))
758ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
759ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#define INITW(t) \
760ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    do { \
761ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen	PRUint32 lo, tm; \
762ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen	PRUint32 cy = 0; \
763ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen	lo = s1lo(W[t-2]); \
764ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen	lo += (tm = W[t-7].lo);     if (lo < tm) cy++; \
765ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen	lo += (tm = s0lo(W[t-15])); if (lo < tm) cy++; \
766ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen	lo += (tm = W[t-16].lo);    if (lo < tm) cy++; \
767ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen	W[t].lo = lo; \
768ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen	W[t].hi = cy + s1hi(W[t-2]) + W[t-7].hi + s0hi(W[t-15]) + W[t-16].hi; \
769ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    } while (0)
770ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
771ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#define ROUND(n,a,b,c,d,e,f,g,h) \
772ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    { \
773ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen	PRUint32 lo, tm, cy; \
774ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen	lo  = S1lo(e); \
775ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen	lo += (tm = Chxx(e,f,g,lo));    cy = (lo < tm); \
776ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen	lo += (tm = K512[n].lo);	if (lo < tm) cy++; \
777ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen	lo += (tm =    W[n].lo);	if (lo < tm) cy++; \
778ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen	h.lo += lo;			if (h.lo < lo) cy++; \
779ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen	h.hi += cy + S1hi(e) + Chxx(e,f,g,hi) + K512[n].hi + W[n].hi; \
780ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen	d.lo += h.lo; \
781ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen	d.hi += h.hi + (d.lo < h.lo); \
782ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen	lo  = S0lo(a);  \
783ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen	lo += (tm = Majx(a,b,c,lo));	cy = (lo < tm); \
784ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen	h.lo += lo;			if (h.lo < lo) cy++; \
785ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen	h.hi += cy + S0hi(a) + Majx(a,b,c,hi); \
786ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen	DUMP(n,a,d,e,h) \
787ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    }
788ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#endif
789ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
790ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenstatic void
791ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenSHA512_Compress(SHA512Context *ctx)
792ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen{
793ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#if defined(IS_LITTLE_ENDIAN)
794ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  {
795ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#if defined(HAVE_LONG_LONG)
796ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    PRUint64 t1;
797ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#else
798ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    PRUint32 t1;
799ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#endif
800ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    BYTESWAP8(W[0]);
801ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    BYTESWAP8(W[1]);
802ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    BYTESWAP8(W[2]);
803ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    BYTESWAP8(W[3]);
804ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    BYTESWAP8(W[4]);
805ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    BYTESWAP8(W[5]);
806ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    BYTESWAP8(W[6]);
807ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    BYTESWAP8(W[7]);
808ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    BYTESWAP8(W[8]);
809ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    BYTESWAP8(W[9]);
810ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    BYTESWAP8(W[10]);
811ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    BYTESWAP8(W[11]);
812ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    BYTESWAP8(W[12]);
813ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    BYTESWAP8(W[13]);
814ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    BYTESWAP8(W[14]);
815ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    BYTESWAP8(W[15]);
816ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
817ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#endif
818ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
819ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  {
820ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    PRUint64 t1, t2;
821ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#ifdef NOUNROLL512
822ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    {
823ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen	/* prepare the "message schedule"   */
824ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen	int t;
825ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen	for (t = 16; t < 80; ++t) {
826ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen	    INITW(t);
827ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen	}
828ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    }
829ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#else
830ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    INITW(16);
831ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    INITW(17);
832ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    INITW(18);
833ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    INITW(19);
834ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
835ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    INITW(20);
836ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    INITW(21);
837ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    INITW(22);
838ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    INITW(23);
839ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    INITW(24);
840ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    INITW(25);
841ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    INITW(26);
842ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    INITW(27);
843ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    INITW(28);
844ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    INITW(29);
845ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
846ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    INITW(30);
847ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    INITW(31);
848ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    INITW(32);
849ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    INITW(33);
850ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    INITW(34);
851ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    INITW(35);
852ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    INITW(36);
853ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    INITW(37);
854ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    INITW(38);
855ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    INITW(39);
856ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
857ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    INITW(40);
858ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    INITW(41);
859ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    INITW(42);
860ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    INITW(43);
861ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    INITW(44);
862ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    INITW(45);
863ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    INITW(46);
864ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    INITW(47);
865ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    INITW(48);
866ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    INITW(49);
867ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
868ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    INITW(50);
869ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    INITW(51);
870ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    INITW(52);
871ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    INITW(53);
872ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    INITW(54);
873ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    INITW(55);
874ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    INITW(56);
875ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    INITW(57);
876ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    INITW(58);
877ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    INITW(59);
878ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
879ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    INITW(60);
880ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    INITW(61);
881ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    INITW(62);
882ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    INITW(63);
883ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    INITW(64);
884ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    INITW(65);
885ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    INITW(66);
886ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    INITW(67);
887ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    INITW(68);
888ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    INITW(69);
889ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
890ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    INITW(70);
891ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    INITW(71);
892ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    INITW(72);
893ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    INITW(73);
894ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    INITW(74);
895ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    INITW(75);
896ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    INITW(76);
897ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    INITW(77);
898ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    INITW(78);
899ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    INITW(79);
900ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#endif
901ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
902ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#ifdef SHA512_TRACE
903ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  {
904ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    int i;
905ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    for (i = 0; i < 80; ++i) {
906ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#ifdef HAVE_LONG_LONG
907ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen	printf("W[%2d] = %016lx\n", i, W[i]);
908ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#else
909ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen	printf("W[%2d] = %08x%08x\n", i, W[i].hi, W[i].lo);
910ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#endif
911ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    }
912ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
913ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#endif
914ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  {
915ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    PRUint64 a, b, c, d, e, f, g, h;
916ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
917ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    a = H[0];
918ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    b = H[1];
919ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    c = H[2];
920ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    d = H[3];
921ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    e = H[4];
922ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    f = H[5];
923ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    g = H[6];
924ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    h = H[7];
925ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
926ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#ifdef NOUNROLL512
927ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    {
928ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen	int t;
929ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen	for (t = 0; t < 80; t+= 8) {
930ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen	    ROUND(t+0,a,b,c,d,e,f,g,h)
931ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen	    ROUND(t+1,h,a,b,c,d,e,f,g)
932ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen	    ROUND(t+2,g,h,a,b,c,d,e,f)
933ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen	    ROUND(t+3,f,g,h,a,b,c,d,e)
934ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen	    ROUND(t+4,e,f,g,h,a,b,c,d)
935ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen	    ROUND(t+5,d,e,f,g,h,a,b,c)
936ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen	    ROUND(t+6,c,d,e,f,g,h,a,b)
937ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen	    ROUND(t+7,b,c,d,e,f,g,h,a)
938ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen	}
939ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    }
940ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#else
941ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ROUND( 0,a,b,c,d,e,f,g,h)
942ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ROUND( 1,h,a,b,c,d,e,f,g)
943ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ROUND( 2,g,h,a,b,c,d,e,f)
944ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ROUND( 3,f,g,h,a,b,c,d,e)
945ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ROUND( 4,e,f,g,h,a,b,c,d)
946ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ROUND( 5,d,e,f,g,h,a,b,c)
947ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ROUND( 6,c,d,e,f,g,h,a,b)
948ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ROUND( 7,b,c,d,e,f,g,h,a)
949ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
950ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ROUND( 8,a,b,c,d,e,f,g,h)
951ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ROUND( 9,h,a,b,c,d,e,f,g)
952ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ROUND(10,g,h,a,b,c,d,e,f)
953ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ROUND(11,f,g,h,a,b,c,d,e)
954ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ROUND(12,e,f,g,h,a,b,c,d)
955ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ROUND(13,d,e,f,g,h,a,b,c)
956ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ROUND(14,c,d,e,f,g,h,a,b)
957ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ROUND(15,b,c,d,e,f,g,h,a)
958ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
959ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ROUND(16,a,b,c,d,e,f,g,h)
960ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ROUND(17,h,a,b,c,d,e,f,g)
961ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ROUND(18,g,h,a,b,c,d,e,f)
962ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ROUND(19,f,g,h,a,b,c,d,e)
963ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ROUND(20,e,f,g,h,a,b,c,d)
964ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ROUND(21,d,e,f,g,h,a,b,c)
965ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ROUND(22,c,d,e,f,g,h,a,b)
966ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ROUND(23,b,c,d,e,f,g,h,a)
967ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
968ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ROUND(24,a,b,c,d,e,f,g,h)
969ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ROUND(25,h,a,b,c,d,e,f,g)
970ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ROUND(26,g,h,a,b,c,d,e,f)
971ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ROUND(27,f,g,h,a,b,c,d,e)
972ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ROUND(28,e,f,g,h,a,b,c,d)
973ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ROUND(29,d,e,f,g,h,a,b,c)
974ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ROUND(30,c,d,e,f,g,h,a,b)
975ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ROUND(31,b,c,d,e,f,g,h,a)
976ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
977ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ROUND(32,a,b,c,d,e,f,g,h)
978ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ROUND(33,h,a,b,c,d,e,f,g)
979ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ROUND(34,g,h,a,b,c,d,e,f)
980ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ROUND(35,f,g,h,a,b,c,d,e)
981ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ROUND(36,e,f,g,h,a,b,c,d)
982ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ROUND(37,d,e,f,g,h,a,b,c)
983ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ROUND(38,c,d,e,f,g,h,a,b)
984ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ROUND(39,b,c,d,e,f,g,h,a)
985ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
986ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ROUND(40,a,b,c,d,e,f,g,h)
987ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ROUND(41,h,a,b,c,d,e,f,g)
988ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ROUND(42,g,h,a,b,c,d,e,f)
989ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ROUND(43,f,g,h,a,b,c,d,e)
990ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ROUND(44,e,f,g,h,a,b,c,d)
991ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ROUND(45,d,e,f,g,h,a,b,c)
992ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ROUND(46,c,d,e,f,g,h,a,b)
993ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ROUND(47,b,c,d,e,f,g,h,a)
994ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
995ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ROUND(48,a,b,c,d,e,f,g,h)
996ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ROUND(49,h,a,b,c,d,e,f,g)
997ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ROUND(50,g,h,a,b,c,d,e,f)
998ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ROUND(51,f,g,h,a,b,c,d,e)
999ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ROUND(52,e,f,g,h,a,b,c,d)
1000ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ROUND(53,d,e,f,g,h,a,b,c)
1001ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ROUND(54,c,d,e,f,g,h,a,b)
1002ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ROUND(55,b,c,d,e,f,g,h,a)
1003ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1004ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ROUND(56,a,b,c,d,e,f,g,h)
1005ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ROUND(57,h,a,b,c,d,e,f,g)
1006ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ROUND(58,g,h,a,b,c,d,e,f)
1007ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ROUND(59,f,g,h,a,b,c,d,e)
1008ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ROUND(60,e,f,g,h,a,b,c,d)
1009ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ROUND(61,d,e,f,g,h,a,b,c)
1010ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ROUND(62,c,d,e,f,g,h,a,b)
1011ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ROUND(63,b,c,d,e,f,g,h,a)
1012ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1013ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ROUND(64,a,b,c,d,e,f,g,h)
1014ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ROUND(65,h,a,b,c,d,e,f,g)
1015ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ROUND(66,g,h,a,b,c,d,e,f)
1016ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ROUND(67,f,g,h,a,b,c,d,e)
1017ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ROUND(68,e,f,g,h,a,b,c,d)
1018ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ROUND(69,d,e,f,g,h,a,b,c)
1019ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ROUND(70,c,d,e,f,g,h,a,b)
1020ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ROUND(71,b,c,d,e,f,g,h,a)
1021ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1022ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ROUND(72,a,b,c,d,e,f,g,h)
1023ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ROUND(73,h,a,b,c,d,e,f,g)
1024ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ROUND(74,g,h,a,b,c,d,e,f)
1025ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ROUND(75,f,g,h,a,b,c,d,e)
1026ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ROUND(76,e,f,g,h,a,b,c,d)
1027ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ROUND(77,d,e,f,g,h,a,b,c)
1028ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ROUND(78,c,d,e,f,g,h,a,b)
1029ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ROUND(79,b,c,d,e,f,g,h,a)
1030ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#endif
1031ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1032ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ADDTO(a,H[0]);
1033ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ADDTO(b,H[1]);
1034ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ADDTO(c,H[2]);
1035ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ADDTO(d,H[3]);
1036ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ADDTO(e,H[4]);
1037ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ADDTO(f,H[5]);
1038ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ADDTO(g,H[6]);
1039ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ADDTO(h,H[7]);
1040ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
1041ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
1042ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1043ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid
1044ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenSHA512_Update(SHA512Context *ctx, const unsigned char *input,
1045ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen              unsigned int inputLen)
1046ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen{
1047ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    unsigned int inBuf;
1048ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    if (!inputLen)
1049ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    	return;
1050ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1051ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#if defined(HAVE_LONG_LONG)
1052ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    inBuf = (unsigned int)ctx->sizeLo & 0x7f;
1053ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    /* Add inputLen into the count of bytes processed, before processing */
1054ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ctx->sizeLo += inputLen;
1055ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#else
1056ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    inBuf = (unsigned int)ctx->sizeLo.lo & 0x7f;
1057ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ctx->sizeLo.lo += inputLen;
1058ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    if (ctx->sizeLo.lo < inputLen) ctx->sizeLo.hi++;
1059ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#endif
1060ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1061ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    /* if data already in buffer, attemp to fill rest of buffer */
1062ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    if (inBuf) {
1063ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    	unsigned int todo = SHA512_BLOCK_LENGTH - inBuf;
1064ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen	if (inputLen < todo)
1065ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen	    todo = inputLen;
1066ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen	memcpy(B + inBuf, input, todo);
1067ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen	input    += todo;
1068ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen	inputLen -= todo;
1069ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen	if (inBuf + todo == SHA512_BLOCK_LENGTH)
1070ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen	    SHA512_Compress(ctx);
1071ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    }
1072ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1073ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    /* if enough data to fill one or more whole buffers, process them. */
1074ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    while (inputLen >= SHA512_BLOCK_LENGTH) {
1075ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    	memcpy(B, input, SHA512_BLOCK_LENGTH);
1076ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen	input    += SHA512_BLOCK_LENGTH;
1077ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen	inputLen -= SHA512_BLOCK_LENGTH;
1078ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen	SHA512_Compress(ctx);
1079ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    }
1080ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    /* if data left over, fill it into buffer */
1081ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    if (inputLen)
1082ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    	memcpy(B, input, inputLen);
1083ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
1084ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1085ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid
1086ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenSHA512_End(SHA512Context *ctx, unsigned char *digest,
1087ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen           unsigned int *digestLen, unsigned int maxDigestLen)
1088ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen{
1089ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#if defined(HAVE_LONG_LONG)
1090ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    unsigned int inBuf  = (unsigned int)ctx->sizeLo & 0x7f;
1091ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    unsigned int padLen = (inBuf < 112) ? (112 - inBuf) : (112 + 128 - inBuf);
1092ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    PRUint64 lo, t1;
1093ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    lo = (ctx->sizeLo << 3);
1094ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#else
1095ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    unsigned int inBuf  = (unsigned int)ctx->sizeLo.lo & 0x7f;
1096ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    unsigned int padLen = (inBuf < 112) ? (112 - inBuf) : (112 + 128 - inBuf);
1097ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    PRUint64 lo = ctx->sizeLo;
1098ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    PRUint32 t1;
1099ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    lo.lo <<= 3;
1100ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#endif
1101ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1102ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    SHA512_Update(ctx, pad, padLen);
1103ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1104ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#if defined(HAVE_LONG_LONG)
1105ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    W[14] = 0;
1106ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#else
1107ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    W[14].lo = 0;
1108ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    W[14].hi = 0;
1109ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#endif
1110ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1111ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    W[15] = lo;
1112ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#if defined(IS_LITTLE_ENDIAN)
1113ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    BYTESWAP8(W[15]);
1114ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#endif
1115ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    SHA512_Compress(ctx);
1116ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1117ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    /* now output the answer */
1118ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#if defined(IS_LITTLE_ENDIAN)
1119ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    BYTESWAP8(H[0]);
1120ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    BYTESWAP8(H[1]);
1121ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    BYTESWAP8(H[2]);
1122ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    BYTESWAP8(H[3]);
1123ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    BYTESWAP8(H[4]);
1124ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    BYTESWAP8(H[5]);
1125ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    BYTESWAP8(H[6]);
1126ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    BYTESWAP8(H[7]);
1127ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#endif
1128ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    padLen = PR_MIN(SHA512_LENGTH, maxDigestLen);
1129ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    memcpy(digest, H, padLen);
1130ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    if (digestLen)
1131ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen	*digestLen = padLen;
1132ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
1133ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1134ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenSECStatus
1135ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenSHA512_HashBuf(unsigned char *dest, const unsigned char *src,
1136ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen               unsigned int src_length)
1137ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen{
1138ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    SHA512Context ctx;
1139ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    unsigned int outLen;
1140ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1141ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    SHA512_Begin(&ctx);
1142ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    SHA512_Update(&ctx, src, src_length);
1143ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    SHA512_End(&ctx, dest, &outLen, SHA512_LENGTH);
1144ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1145ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    return SECSuccess;
1146ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
1147ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1148ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1149ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenSECStatus
1150ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenSHA512_Hash(unsigned char *dest, const char *src)
1151ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen{
1152ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    return SHA512_HashBuf(dest, (const unsigned char *)src, PORT_Strlen(src));
1153ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
1154ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1155ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1156ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid SHA512_TraceState(SHA512Context *ctx) { }
1157ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1158ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenunsigned int
1159ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenSHA512_FlattenSize(SHA512Context *ctx)
1160ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen{
1161ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    return sizeof *ctx;
1162ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
1163ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1164ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenSECStatus
1165ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenSHA512_Flatten(SHA512Context *ctx,unsigned char *space)
1166ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen{
1167ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    PORT_Memcpy(space, ctx, sizeof *ctx);
1168ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    return SECSuccess;
1169ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
1170ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1171ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenSHA512Context *
1172ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenSHA512_Resurrect(unsigned char *space, void *arg)
1173ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen{
1174ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    SHA512Context *ctx = SHA512_NewContext();
1175ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    if (ctx)
1176ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen	PORT_Memcpy(ctx, space, sizeof *ctx);
1177ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    return ctx;
1178ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
1179ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1180ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid SHA512_Clone(SHA512Context *dest, SHA512Context *src)
1181ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen{
1182ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    memcpy(dest, src, sizeof *dest);
1183ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
1184ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1185ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen/* ======================================================================= */
1186ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen/* SHA384 uses a SHA512Context as the real context.
1187ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen** The only differences between SHA384 an SHA512 are:
1188ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen** a) the intialization values for the context, and
1189ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen** b) the number of bytes of data produced as output.
1190ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen*/
1191ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1192ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen/* SHA-384 initial hash values */
1193ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenstatic const PRUint64 H384[8] = {
1194ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#if PR_BYTES_PER_LONG == 8
1195ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen     0xcbbb9d5dc1059ed8UL ,  0x629a292a367cd507UL ,
1196ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen     0x9159015a3070dd17UL ,  0x152fecd8f70e5939UL ,
1197ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen     0x67332667ffc00b31UL ,  0x8eb44a8768581511UL ,
1198ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen     0xdb0c2e0d64f98fa7UL ,  0x47b5481dbefa4fa4UL
1199ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#else
1200ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ULLC(cbbb9d5d,c1059ed8), ULLC(629a292a,367cd507),
1201ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ULLC(9159015a,3070dd17), ULLC(152fecd8,f70e5939),
1202ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ULLC(67332667,ffc00b31), ULLC(8eb44a87,68581511),
1203ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ULLC(db0c2e0d,64f98fa7), ULLC(47b5481d,befa4fa4)
1204ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#endif
1205ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen};
1206ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1207ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenSHA384Context *
1208ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenSHA384_NewContext(void)
1209ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen{
1210ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    return SHA512_NewContext();
1211ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
1212ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1213ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid
1214ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenSHA384_DestroyContext(SHA384Context *ctx, PRBool freeit)
1215ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen{
1216ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    SHA512_DestroyContext(ctx, freeit);
1217ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
1218ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1219ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid
1220ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenSHA384_Begin(SHA384Context *ctx)
1221ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen{
1222ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    memset(ctx, 0, sizeof *ctx);
1223ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    memcpy(H, H384, sizeof H384);
1224ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
1225ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1226ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid
1227ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenSHA384_Update(SHA384Context *ctx, const unsigned char *input,
1228ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen		    unsigned int inputLen)
1229ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen{
1230ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    SHA512_Update(ctx, input, inputLen);
1231ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
1232ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1233ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid
1234ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenSHA384_End(SHA384Context *ctx, unsigned char *digest,
1235ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen		 unsigned int *digestLen, unsigned int maxDigestLen)
1236ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen{
1237ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#define SHA_MIN(a,b) (a < b ? a : b)
1238ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    unsigned int maxLen = SHA_MIN(maxDigestLen, SHA384_LENGTH);
1239ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    SHA512_End(ctx, digest, digestLen, maxLen);
1240ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
1241ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1242ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenSECStatus
1243ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenSHA384_HashBuf(unsigned char *dest, const unsigned char *src,
1244ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen			  unsigned int src_length)
1245ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen{
1246ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    SHA512Context ctx;
1247ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    unsigned int outLen;
1248ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1249ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    SHA384_Begin(&ctx);
1250ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    SHA512_Update(&ctx, src, src_length);
1251ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    SHA512_End(&ctx, dest, &outLen, SHA384_LENGTH);
1252ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1253ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    return SECSuccess;
1254ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
1255ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1256ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenSECStatus
1257ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenSHA384_Hash(unsigned char *dest, const char *src)
1258ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen{
1259ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    return SHA384_HashBuf(dest, (const unsigned char *)src, PORT_Strlen(src));
1260ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
1261ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1262ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid SHA384_TraceState(SHA384Context *ctx) { }
1263ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1264ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenunsigned int
1265ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenSHA384_FlattenSize(SHA384Context *ctx)
1266ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen{
1267ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    return sizeof(SHA384Context);
1268ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
1269ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1270ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenSECStatus
1271ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenSHA384_Flatten(SHA384Context *ctx,unsigned char *space)
1272ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen{
1273ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    return SHA512_Flatten(ctx, space);
1274ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
1275ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1276ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenSHA384Context *
1277ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenSHA384_Resurrect(unsigned char *space, void *arg)
1278ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen{
1279ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    return SHA512_Resurrect(space, arg);
1280ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
1281ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1282ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid SHA384_Clone(SHA384Context *dest, SHA384Context *src)
1283ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen{
1284ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    memcpy(dest, src, sizeof *dest);
1285ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
1286ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#endif  /* Comment out unused code. */
1287ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1288ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen/* ======================================================================= */
1289ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#ifdef SELFTEST
1290ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include <stdio.h>
1291ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1292ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenstatic const char abc[] = { "abc" };
1293ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenstatic const char abcdbc[] = {
1294ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"
1295ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen};
1296ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenstatic const char abcdef[] = {
1297ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmn"
1298ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    "hijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu"
1299ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen};
1300ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1301ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid
1302ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsendumpHash32(const unsigned char *buf, unsigned int bufLen)
1303ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen{
1304ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    unsigned int i;
1305ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    for (i = 0; i < bufLen; i += 4) {
1306ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen	printf(" %02x%02x%02x%02x", buf[i], buf[i+1], buf[i+2], buf[i+3]);
1307ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    }
1308ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    printf("\n");
1309ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
1310ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1311ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid test256(void)
1312ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen{
1313ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    unsigned char outBuf[SHA256_LENGTH];
1314ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1315ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    printf("SHA256, input = %s\n", abc);
1316ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    SHA256_Hash(outBuf, abc);
1317ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    dumpHash32(outBuf, sizeof outBuf);
1318ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1319ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    printf("SHA256, input = %s\n", abcdbc);
1320ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    SHA256_Hash(outBuf, abcdbc);
1321ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    dumpHash32(outBuf, sizeof outBuf);
1322ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
1323ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1324ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid
1325ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsendumpHash64(const unsigned char *buf, unsigned int bufLen)
1326ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen{
1327ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    unsigned int i;
1328ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    for (i = 0; i < bufLen; i += 8) {
1329ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    	if (i % 32 == 0)
1330ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen	    printf("\n");
1331ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen	printf(" %02x%02x%02x%02x%02x%02x%02x%02x",
1332ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen	       buf[i  ], buf[i+1], buf[i+2], buf[i+3],
1333ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen	       buf[i+4], buf[i+5], buf[i+6], buf[i+7]);
1334ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    }
1335ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    printf("\n");
1336ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
1337ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1338ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid test512(void)
1339ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen{
1340ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    unsigned char outBuf[SHA512_LENGTH];
1341ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1342ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    printf("SHA512, input = %s\n", abc);
1343ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    SHA512_Hash(outBuf, abc);
1344ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    dumpHash64(outBuf, sizeof outBuf);
1345ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1346ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    printf("SHA512, input = %s\n", abcdef);
1347ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    SHA512_Hash(outBuf, abcdef);
1348ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    dumpHash64(outBuf, sizeof outBuf);
1349ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
1350ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1351ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid time512(void)
1352ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen{
1353ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    unsigned char outBuf[SHA512_LENGTH];
1354ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1355ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    SHA512_Hash(outBuf, abc);
1356ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    SHA512_Hash(outBuf, abcdef);
1357ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
1358ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1359ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid test384(void)
1360ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen{
1361ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    unsigned char outBuf[SHA384_LENGTH];
1362ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1363ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    printf("SHA384, input = %s\n", abc);
1364ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    SHA384_Hash(outBuf, abc);
1365ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    dumpHash64(outBuf, sizeof outBuf);
1366ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1367ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    printf("SHA384, input = %s\n", abcdef);
1368ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    SHA384_Hash(outBuf, abcdef);
1369ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    dumpHash64(outBuf, sizeof outBuf);
1370ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
1371ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1372ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenint main (int argc, char *argv[], char *envp[])
1373ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen{
1374ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    int i = 1;
1375ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    if (argc > 1) {
1376ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    	i = atoi(argv[1]);
1377ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    }
1378ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    if (i < 2) {
1379ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen	test256();
1380ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen	test512();
1381ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen	test384();
1382ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    } else {
1383ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    	while (i-- > 0) {
1384ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen	    time512();
1385ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen	}
1386ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen	printf("done\n");
1387ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    }
1388ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    return 0;
1389ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
1390ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
1391ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#endif
1392