Revert "FX Bool considered harmful, part 3"
[pdfium.git] / core / src / fdrm / crypto / fx_crypt_sha.cpp
1 // Copyright 2014 PDFium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
6
7 #include "../../../include/fdrm/fx_crypt.h"
8 #ifdef __cplusplus
9 extern "C" {
10 #endif
11 typedef struct {
12     unsigned int h[5];
13     unsigned char block[64];
14     int blkused;
15     unsigned int lenhi, lenlo;
16 } SHA_State;
17 #define rol(x,y) ( ((x) << (y)) | (((unsigned int)x) >> (32-y)) )
18 static void SHA_Core_Init(unsigned int h[5])
19 {
20     h[0] = 0x67452301;
21     h[1] = 0xefcdab89;
22     h[2] = 0x98badcfe;
23     h[3] = 0x10325476;
24     h[4] = 0xc3d2e1f0;
25 }
26 static void SHATransform(unsigned int * digest, unsigned int * block)
27 {
28     unsigned int w[80];
29     unsigned int a, b, c, d, e;
30     int t;
31     for (t = 0; t < 16; t++) {
32         w[t] = block[t];
33     }
34     for (t = 16; t < 80; t++) {
35         unsigned int tmp = w[t - 3] ^ w[t - 8] ^ w[t - 14] ^ w[t - 16];
36         w[t] = rol(tmp, 1);
37     }
38     a = digest[0];
39     b = digest[1];
40     c = digest[2];
41     d = digest[3];
42     e = digest[4];
43     for (t = 0; t < 20; t++) {
44         unsigned int tmp =
45             rol(a, 5) + ((b & c) | (d & ~b)) + e + w[t] + 0x5a827999;
46         e = d;
47         d = c;
48         c = rol(b, 30);
49         b = a;
50         a = tmp;
51     }
52     for (t = 20; t < 40; t++) {
53         unsigned int tmp = rol(a, 5) + (b ^ c ^ d) + e + w[t] + 0x6ed9eba1;
54         e = d;
55         d = c;
56         c = rol(b, 30);
57         b = a;
58         a = tmp;
59     }
60     for (t = 40; t < 60; t++) {
61         unsigned int tmp = rol(a,
62                                5) + ((b & c) | (b & d) | (c & d)) + e + w[t] +
63                            0x8f1bbcdc;
64         e = d;
65         d = c;
66         c = rol(b, 30);
67         b = a;
68         a = tmp;
69     }
70     for (t = 60; t < 80; t++) {
71         unsigned int tmp = rol(a, 5) + (b ^ c ^ d) + e + w[t] + 0xca62c1d6;
72         e = d;
73         d = c;
74         c = rol(b, 30);
75         b = a;
76         a = tmp;
77     }
78     digest[0] += a;
79     digest[1] += b;
80     digest[2] += c;
81     digest[3] += d;
82     digest[4] += e;
83 }
84 void CRYPT_SHA1Start(void* context)
85 {
86     SHA_State * s = (SHA_State*)context;
87     SHA_Core_Init(s->h);
88     s->blkused = 0;
89     s->lenhi = s->lenlo = 0;
90 }
91 void CRYPT_SHA1Update(void* context, const uint8_t* data, FX_DWORD size)
92 {
93     SHA_State * s = (SHA_State*)context;
94     unsigned char *q = (unsigned char *)data;
95     unsigned int wordblock[16];
96     int len = size;
97     unsigned int lenw = len;
98     int i;
99     s->lenlo += lenw;
100     s->lenhi += (s->lenlo < lenw);
101     if (s->blkused && s->blkused + len < 64) {
102         FXSYS_memcpy(s->block + s->blkused, q, len);
103         s->blkused += len;
104     } else {
105         while (s->blkused + len >= 64) {
106             FXSYS_memcpy(s->block + s->blkused, q, 64 - s->blkused);
107             q += 64 - s->blkused;
108             len -= 64 - s->blkused;
109             for (i = 0; i < 16; i++) {
110                 wordblock[i] =
111                     (((unsigned int) s->block[i * 4 + 0]) << 24) |
112                     (((unsigned int) s->block[i * 4 + 1]) << 16) |
113                     (((unsigned int) s->block[i * 4 + 2]) << 8) |
114                     (((unsigned int) s->block[i * 4 + 3]) << 0);
115             }
116             SHATransform(s->h, wordblock);
117             s->blkused = 0;
118         }
119         FXSYS_memcpy(s->block, q, len);
120         s->blkused = len;
121     }
122 }
123 void CRYPT_SHA1Finish(void* context, uint8_t digest[20])
124 {
125     SHA_State * s = (SHA_State*)context;
126     int i;
127     int pad;
128     unsigned char c[64];
129     unsigned int lenhi, lenlo;
130     if (s->blkused >= 56) {
131         pad = 56 + 64 - s->blkused;
132     } else {
133         pad = 56 - s->blkused;
134     }
135     lenhi = (s->lenhi << 3) | (s->lenlo >> (32 - 3));
136     lenlo = (s->lenlo << 3);
137     FXSYS_memset(c, 0, pad);
138     c[0] = 0x80;
139     CRYPT_SHA1Update(s, c, pad);
140     c[0] = (lenhi >> 24) & 0xFF;
141     c[1] = (lenhi >> 16) & 0xFF;
142     c[2] = (lenhi >> 8) & 0xFF;
143     c[3] = (lenhi >> 0) & 0xFF;
144     c[4] = (lenlo >> 24) & 0xFF;
145     c[5] = (lenlo >> 16) & 0xFF;
146     c[6] = (lenlo >> 8) & 0xFF;
147     c[7] = (lenlo >> 0) & 0xFF;
148     CRYPT_SHA1Update(s, c, 8);
149     for (i = 0; i < 5; i++) {
150         digest[i * 4] = (s->h[i] >> 24) & 0xFF;
151         digest[i * 4 + 1] = (s->h[i] >> 16) & 0xFF;
152         digest[i * 4 + 2] = (s->h[i] >> 8) & 0xFF;
153         digest[i * 4 + 3] = (s->h[i]) & 0xFF;
154     }
155 }
156 void CRYPT_SHA1Generate(const uint8_t* data, FX_DWORD size, uint8_t digest[20])
157 {
158     SHA_State s;
159     CRYPT_SHA1Start(&s);
160     CRYPT_SHA1Update(&s, data, size);
161     CRYPT_SHA1Finish(&s, digest);
162 }
163 typedef struct {
164     FX_DWORD total[2];
165     FX_DWORD state[8];
166     uint8_t buffer[64];
167 }
168 sha256_context;
169 #define GET_FX_DWORD(n,b,i)                       \
170     {                                               \
171         (n) = ( (FX_DWORD) (b)[(i)    ] << 24 )       \
172               | ( (FX_DWORD) (b)[(i) + 1] << 16 )       \
173               | ( (FX_DWORD) (b)[(i) + 2] <<  8 )       \
174               | ( (FX_DWORD) (b)[(i) + 3]       );      \
175     }
176 #define PUT_FX_DWORD(n,b,i)                       \
177     {                                               \
178         (b)[(i)    ] = (uint8_t) ( (n) >> 24 );       \
179         (b)[(i) + 1] = (uint8_t) ( (n) >> 16 );       \
180         (b)[(i) + 2] = (uint8_t) ( (n) >>  8 );       \
181         (b)[(i) + 3] = (uint8_t) ( (n)       );       \
182     }
183 void CRYPT_SHA256Start( void* context )
184 {
185     sha256_context *ctx = (sha256_context *)context;
186     ctx->total[0] = 0;
187     ctx->total[1] = 0;
188     ctx->state[0] = 0x6A09E667;
189     ctx->state[1] = 0xBB67AE85;
190     ctx->state[2] = 0x3C6EF372;
191     ctx->state[3] = 0xA54FF53A;
192     ctx->state[4] = 0x510E527F;
193     ctx->state[5] = 0x9B05688C;
194     ctx->state[6] = 0x1F83D9AB;
195     ctx->state[7] = 0x5BE0CD19;
196 }
197 static void sha256_process( sha256_context *ctx, const uint8_t data[64] )
198 {
199     FX_DWORD temp1, temp2, W[64];
200     FX_DWORD A, B, C, D, E, F, G, H;
201     GET_FX_DWORD( W[0],  data,  0 );
202     GET_FX_DWORD( W[1],  data,  4 );
203     GET_FX_DWORD( W[2],  data,  8 );
204     GET_FX_DWORD( W[3],  data, 12 );
205     GET_FX_DWORD( W[4],  data, 16 );
206     GET_FX_DWORD( W[5],  data, 20 );
207     GET_FX_DWORD( W[6],  data, 24 );
208     GET_FX_DWORD( W[7],  data, 28 );
209     GET_FX_DWORD( W[8],  data, 32 );
210     GET_FX_DWORD( W[9],  data, 36 );
211     GET_FX_DWORD( W[10], data, 40 );
212     GET_FX_DWORD( W[11], data, 44 );
213     GET_FX_DWORD( W[12], data, 48 );
214     GET_FX_DWORD( W[13], data, 52 );
215     GET_FX_DWORD( W[14], data, 56 );
216     GET_FX_DWORD( W[15], data, 60 );
217 #define  SHR(x,n) ((x & 0xFFFFFFFF) >> n)
218 #define ROTR(x,n) (SHR(x,n) | (x << (32 - n)))
219 #define S0(x) (ROTR(x, 7) ^ ROTR(x,18) ^  SHR(x, 3))
220 #define S1(x) (ROTR(x,17) ^ ROTR(x,19) ^  SHR(x,10))
221 #define S2(x) (ROTR(x, 2) ^ ROTR(x,13) ^ ROTR(x,22))
222 #define S3(x) (ROTR(x, 6) ^ ROTR(x,11) ^ ROTR(x,25))
223 #define F0(x,y,z) ((x & y) | (z & (x | y)))
224 #define F1(x,y,z) (z ^ (x & (y ^ z)))
225 #define R(t)                                    \
226     (                                               \
227             W[t] = S1(W[t -  2]) + W[t -  7] +          \
228                    S0(W[t - 15]) + W[t - 16]            \
229     )
230 #define P(a,b,c,d,e,f,g,h,x,K)                  \
231     {                                               \
232         temp1 = h + S3(e) + F1(e,f,g) + K + x;      \
233         temp2 = S2(a) + F0(a,b,c);                  \
234         d += temp1; h = temp1 + temp2;              \
235     }
236     A = ctx->state[0];
237     B = ctx->state[1];
238     C = ctx->state[2];
239     D = ctx->state[3];
240     E = ctx->state[4];
241     F = ctx->state[5];
242     G = ctx->state[6];
243     H = ctx->state[7];
244     P( A, B, C, D, E, F, G, H, W[ 0], 0x428A2F98 );
245     P( H, A, B, C, D, E, F, G, W[ 1], 0x71374491 );
246     P( G, H, A, B, C, D, E, F, W[ 2], 0xB5C0FBCF );
247     P( F, G, H, A, B, C, D, E, W[ 3], 0xE9B5DBA5 );
248     P( E, F, G, H, A, B, C, D, W[ 4], 0x3956C25B );
249     P( D, E, F, G, H, A, B, C, W[ 5], 0x59F111F1 );
250     P( C, D, E, F, G, H, A, B, W[ 6], 0x923F82A4 );
251     P( B, C, D, E, F, G, H, A, W[ 7], 0xAB1C5ED5 );
252     P( A, B, C, D, E, F, G, H, W[ 8], 0xD807AA98 );
253     P( H, A, B, C, D, E, F, G, W[ 9], 0x12835B01 );
254     P( G, H, A, B, C, D, E, F, W[10], 0x243185BE );
255     P( F, G, H, A, B, C, D, E, W[11], 0x550C7DC3 );
256     P( E, F, G, H, A, B, C, D, W[12], 0x72BE5D74 );
257     P( D, E, F, G, H, A, B, C, W[13], 0x80DEB1FE );
258     P( C, D, E, F, G, H, A, B, W[14], 0x9BDC06A7 );
259     P( B, C, D, E, F, G, H, A, W[15], 0xC19BF174 );
260     P( A, B, C, D, E, F, G, H, R(16), 0xE49B69C1 );
261     P( H, A, B, C, D, E, F, G, R(17), 0xEFBE4786 );
262     P( G, H, A, B, C, D, E, F, R(18), 0x0FC19DC6 );
263     P( F, G, H, A, B, C, D, E, R(19), 0x240CA1CC );
264     P( E, F, G, H, A, B, C, D, R(20), 0x2DE92C6F );
265     P( D, E, F, G, H, A, B, C, R(21), 0x4A7484AA );
266     P( C, D, E, F, G, H, A, B, R(22), 0x5CB0A9DC );
267     P( B, C, D, E, F, G, H, A, R(23), 0x76F988DA );
268     P( A, B, C, D, E, F, G, H, R(24), 0x983E5152 );
269     P( H, A, B, C, D, E, F, G, R(25), 0xA831C66D );
270     P( G, H, A, B, C, D, E, F, R(26), 0xB00327C8 );
271     P( F, G, H, A, B, C, D, E, R(27), 0xBF597FC7 );
272     P( E, F, G, H, A, B, C, D, R(28), 0xC6E00BF3 );
273     P( D, E, F, G, H, A, B, C, R(29), 0xD5A79147 );
274     P( C, D, E, F, G, H, A, B, R(30), 0x06CA6351 );
275     P( B, C, D, E, F, G, H, A, R(31), 0x14292967 );
276     P( A, B, C, D, E, F, G, H, R(32), 0x27B70A85 );
277     P( H, A, B, C, D, E, F, G, R(33), 0x2E1B2138 );
278     P( G, H, A, B, C, D, E, F, R(34), 0x4D2C6DFC );
279     P( F, G, H, A, B, C, D, E, R(35), 0x53380D13 );
280     P( E, F, G, H, A, B, C, D, R(36), 0x650A7354 );
281     P( D, E, F, G, H, A, B, C, R(37), 0x766A0ABB );
282     P( C, D, E, F, G, H, A, B, R(38), 0x81C2C92E );
283     P( B, C, D, E, F, G, H, A, R(39), 0x92722C85 );
284     P( A, B, C, D, E, F, G, H, R(40), 0xA2BFE8A1 );
285     P( H, A, B, C, D, E, F, G, R(41), 0xA81A664B );
286     P( G, H, A, B, C, D, E, F, R(42), 0xC24B8B70 );
287     P( F, G, H, A, B, C, D, E, R(43), 0xC76C51A3 );
288     P( E, F, G, H, A, B, C, D, R(44), 0xD192E819 );
289     P( D, E, F, G, H, A, B, C, R(45), 0xD6990624 );
290     P( C, D, E, F, G, H, A, B, R(46), 0xF40E3585 );
291     P( B, C, D, E, F, G, H, A, R(47), 0x106AA070 );
292     P( A, B, C, D, E, F, G, H, R(48), 0x19A4C116 );
293     P( H, A, B, C, D, E, F, G, R(49), 0x1E376C08 );
294     P( G, H, A, B, C, D, E, F, R(50), 0x2748774C );
295     P( F, G, H, A, B, C, D, E, R(51), 0x34B0BCB5 );
296     P( E, F, G, H, A, B, C, D, R(52), 0x391C0CB3 );
297     P( D, E, F, G, H, A, B, C, R(53), 0x4ED8AA4A );
298     P( C, D, E, F, G, H, A, B, R(54), 0x5B9CCA4F );
299     P( B, C, D, E, F, G, H, A, R(55), 0x682E6FF3 );
300     P( A, B, C, D, E, F, G, H, R(56), 0x748F82EE );
301     P( H, A, B, C, D, E, F, G, R(57), 0x78A5636F );
302     P( G, H, A, B, C, D, E, F, R(58), 0x84C87814 );
303     P( F, G, H, A, B, C, D, E, R(59), 0x8CC70208 );
304     P( E, F, G, H, A, B, C, D, R(60), 0x90BEFFFA );
305     P( D, E, F, G, H, A, B, C, R(61), 0xA4506CEB );
306     P( C, D, E, F, G, H, A, B, R(62), 0xBEF9A3F7 );
307     P( B, C, D, E, F, G, H, A, R(63), 0xC67178F2 );
308     ctx->state[0] += A;
309     ctx->state[1] += B;
310     ctx->state[2] += C;
311     ctx->state[3] += D;
312     ctx->state[4] += E;
313     ctx->state[5] += F;
314     ctx->state[6] += G;
315     ctx->state[7] += H;
316 }
317 void CRYPT_SHA256Update( void* context, const uint8_t* input, FX_DWORD length )
318 {
319     sha256_context *ctx = (sha256_context *)context;
320     FX_DWORD left, fill;
321     if( ! length ) {
322         return;
323     }
324     left = ctx->total[0] & 0x3F;
325     fill = 64 - left;
326     ctx->total[0] += length;
327     ctx->total[0] &= 0xFFFFFFFF;
328     if( ctx->total[0] < length ) {
329         ctx->total[1]++;
330     }
331     if( left && length >= fill ) {
332         FXSYS_memcpy( (void *) (ctx->buffer + left),
333                         (void *) input, fill );
334         sha256_process( ctx, ctx->buffer );
335         length -= fill;
336         input  += fill;
337         left = 0;
338     }
339     while( length >= 64 ) {
340         sha256_process( ctx, input );
341         length -= 64;
342         input  += 64;
343     }
344     if( length ) {
345         FXSYS_memcpy( (void *) (ctx->buffer + left),
346                         (void *) input, length );
347     }
348 }
349 static const uint8_t sha256_padding[64] = {
350     0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
351     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
352     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
353     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
354 };
355 void CRYPT_SHA256Finish( void* context, uint8_t digest[32] )
356 {
357     sha256_context *ctx = (sha256_context *)context;
358     FX_DWORD last, padn;
359     FX_DWORD high, low;
360     uint8_t msglen[8];
361     high = ( ctx->total[0] >> 29 )
362            | ( ctx->total[1] <<  3 );
363     low  = ( ctx->total[0] <<  3 );
364     PUT_FX_DWORD( high, msglen, 0 );
365     PUT_FX_DWORD( low,  msglen, 4 );
366     last = ctx->total[0] & 0x3F;
367     padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last );
368     CRYPT_SHA256Update( ctx, sha256_padding, padn );
369     CRYPT_SHA256Update( ctx, msglen, 8 );
370     PUT_FX_DWORD( ctx->state[0], digest,  0 );
371     PUT_FX_DWORD( ctx->state[1], digest,  4 );
372     PUT_FX_DWORD( ctx->state[2], digest,  8 );
373     PUT_FX_DWORD( ctx->state[3], digest, 12 );
374     PUT_FX_DWORD( ctx->state[4], digest, 16 );
375     PUT_FX_DWORD( ctx->state[5], digest, 20 );
376     PUT_FX_DWORD( ctx->state[6], digest, 24 );
377     PUT_FX_DWORD( ctx->state[7], digest, 28 );
378 }
379 void CRYPT_SHA256Generate(const uint8_t* data, FX_DWORD size, uint8_t digest[32])
380 {
381     sha256_context ctx;
382     CRYPT_SHA256Start(&ctx);
383     CRYPT_SHA256Update(&ctx, data, size);
384     CRYPT_SHA256Finish(&ctx, digest);
385 }
386 typedef struct {
387     uint64_t    total[2];
388     uint64_t    state[8];
389     uint8_t             buffer[128];
390 } sha384_context;
391 uint64_t FX_ato64i(const FX_CHAR* str)
392 {
393     FXSYS_assert(str != NULL);
394     uint64_t ret = 0;
395     int len = (int)FXSYS_strlen(str);
396     len = len > 16 ? 16 : len;
397     for (int i = 0; i < len; ++i) {
398         if (i) {
399             ret <<= 4;
400         }
401         if (str[i] >= '0' && str[i] <= '9') {
402             ret |= (str[i] - '0') & 0xFF;
403         } else if (str[i] >= 'a' && str[i] <= 'f') {
404             ret |= (str[i] - 'a' + 10) & 0xFF;
405         } else if (str[i] >= 'A' && str[i] <= 'F') {
406             ret |= (str[i] - 'A' + 10) & 0xFF;
407         } else {
408             FXSYS_assert(FALSE);
409         }
410     }
411     return ret;
412 }
413 void CRYPT_SHA384Start(void* context)
414 {
415     if (context == NULL) {
416         return;
417     }
418     sha384_context *ctx = (sha384_context *)context;
419     FXSYS_memset(ctx, 0, sizeof(sha384_context));
420     ctx->state[0] = FX_ato64i("cbbb9d5dc1059ed8");
421     ctx->state[1] = FX_ato64i("629a292a367cd507");
422     ctx->state[2] = FX_ato64i("9159015a3070dd17");
423     ctx->state[3] = FX_ato64i("152fecd8f70e5939");
424     ctx->state[4] = FX_ato64i("67332667ffc00b31");
425     ctx->state[5] = FX_ato64i("8eb44a8768581511");
426     ctx->state[6] = FX_ato64i("db0c2e0d64f98fa7");
427     ctx->state[7] = FX_ato64i("47b5481dbefa4fa4");
428 }
429 #define SHA384_F0(x,y,z) ((x & y) | (z & (x | y)))
430 #define SHA384_F1(x,y,z) (z ^ (x & (y ^ z)))
431 #define SHA384_SHR(x,n) (x >> n)
432 #define SHA384_ROTR(x,n) (SHA384_SHR(x, n) | x << (64 - n))
433 #define SHA384_S0(x) (SHA384_ROTR(x, 1) ^ SHA384_ROTR(x, 8) ^  SHA384_SHR(x, 7))
434 #define SHA384_S1(x) (SHA384_ROTR(x,19) ^ SHA384_ROTR(x, 61) ^  SHA384_SHR(x, 6))
435 #define SHA384_S2(x) (SHA384_ROTR(x, 28) ^ SHA384_ROTR(x, 34) ^ SHA384_ROTR(x, 39))
436 #define SHA384_S3(x) (SHA384_ROTR(x, 14) ^ SHA384_ROTR(x,18) ^ SHA384_ROTR(x, 41))
437 #define SHA384_P(a,b,c,d,e,f,g,h,x,K)                                                   \
438     {                                                                                                                           \
439         temp1 = h + SHA384_S3(e) + SHA384_F1(e,f,g) + K + x;            \
440         temp2 = SHA384_S2(a) + SHA384_F0(a,b,c);                                        \
441         d += temp1; h = temp1 + temp2;                                                          \
442     }
443 static const uint8_t sha384_padding[128] = {
444     0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
445     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
446     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
447     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
448     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
449     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
450     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
451     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
452 };
453 #define SHA384_R(t) (W[t] = SHA384_S1(W[t -  2]) + W[t -  7] + SHA384_S0(W[t - 15]) + W[t - 16])
454 static const FX_CHAR* constants[] = {
455     "428a2f98d728ae22",
456     "7137449123ef65cd",
457     "b5c0fbcfec4d3b2f",
458     "e9b5dba58189dbbc",
459     "3956c25bf348b538",
460     "59f111f1b605d019",
461     "923f82a4af194f9b",
462     "ab1c5ed5da6d8118",
463     "d807aa98a3030242",
464     "12835b0145706fbe",
465     "243185be4ee4b28c",
466     "550c7dc3d5ffb4e2",
467     "72be5d74f27b896f",
468     "80deb1fe3b1696b1",
469     "9bdc06a725c71235",
470     "c19bf174cf692694",
471     "e49b69c19ef14ad2",
472     "efbe4786384f25e3",
473     "0fc19dc68b8cd5b5",
474     "240ca1cc77ac9c65",
475     "2de92c6f592b0275",
476     "4a7484aa6ea6e483",
477     "5cb0a9dcbd41fbd4",
478     "76f988da831153b5",
479     "983e5152ee66dfab",
480     "a831c66d2db43210",
481     "b00327c898fb213f",
482     "bf597fc7beef0ee4",
483     "c6e00bf33da88fc2",
484     "d5a79147930aa725",
485     "06ca6351e003826f",
486     "142929670a0e6e70",
487     "27b70a8546d22ffc",
488     "2e1b21385c26c926",
489     "4d2c6dfc5ac42aed",
490     "53380d139d95b3df",
491     "650a73548baf63de",
492     "766a0abb3c77b2a8",
493     "81c2c92e47edaee6",
494     "92722c851482353b",
495     "a2bfe8a14cf10364",
496     "a81a664bbc423001",
497     "c24b8b70d0f89791",
498     "c76c51a30654be30",
499     "d192e819d6ef5218",
500     "d69906245565a910",
501     "f40e35855771202a",
502     "106aa07032bbd1b8",
503     "19a4c116b8d2d0c8",
504     "1e376c085141ab53",
505     "2748774cdf8eeb99",
506     "34b0bcb5e19b48a8",
507     "391c0cb3c5c95a63",
508     "4ed8aa4ae3418acb",
509     "5b9cca4f7763e373",
510     "682e6ff3d6b2b8a3",
511     "748f82ee5defb2fc",
512     "78a5636f43172f60",
513     "84c87814a1f0ab72",
514     "8cc702081a6439ec",
515     "90befffa23631e28",
516     "a4506cebde82bde9",
517     "bef9a3f7b2c67915",
518     "c67178f2e372532b",
519     "ca273eceea26619c",
520     "d186b8c721c0c207",
521     "eada7dd6cde0eb1e",
522     "f57d4f7fee6ed178",
523     "06f067aa72176fba",
524     "0a637dc5a2c898a6",
525     "113f9804bef90dae",
526     "1b710b35131c471b",
527     "28db77f523047d84",
528     "32caab7b40c72493",
529     "3c9ebe0a15c9bebc",
530     "431d67c49c100d4c",
531     "4cc5d4becb3e42b6",
532     "597f299cfc657e2a",
533     "5fcb6fab3ad6faec",
534     "6c44198c4a475817",
535 };
536 #define GET_FX_64WORD(n,b,i)                       \
537     {                                               \
538         (n) = ( (uint64_t) (b)[(i)    ] << 56 )       \
539               | ( (uint64_t) (b)[(i) + 1] << 48 )       \
540               | ( (uint64_t) (b)[(i) + 2] << 40 )       \
541               | ( (uint64_t) (b)[(i) + 3] << 32 )      \
542               | ( (uint64_t) (b)[(i) + 4] << 24 )       \
543               | ( (uint64_t) (b)[(i) + 5] << 16 )       \
544               | ( (uint64_t) (b)[(i) + 6] <<  8 )       \
545               | ( (uint64_t) (b)[(i) + 7]       );      \
546     }
547 #define PUT_FX_64DWORD(n,b,i)                       \
548     {                                               \
549         (b)[(i)    ] = (uint8_t) ( (n) >> 56 );       \
550         (b)[(i) + 1] = (uint8_t) ( (n) >> 48 );       \
551         (b)[(i) + 2] = (uint8_t) ( (n) >> 40 );       \
552         (b)[(i) + 3] = (uint8_t) ( (n) >> 32 );       \
553         (b)[(i) + 4] = (uint8_t) ( (n) >> 24 );       \
554         (b)[(i) + 5] = (uint8_t) ( (n) >> 16 );       \
555         (b)[(i) + 6] = (uint8_t) ( (n) >>  8 );       \
556         (b)[(i) + 7] = (uint8_t) ( (n) );       \
557     }
558 static void sha384_process( sha384_context *ctx, const uint8_t data[128] )
559 {
560     uint64_t temp1, temp2;
561     uint64_t A, B, C, D, E, F, G, H;
562     uint64_t W[80];
563     GET_FX_64WORD(W[0], data, 0);
564     GET_FX_64WORD(W[1], data, 8);
565     GET_FX_64WORD(W[2], data, 16);
566     GET_FX_64WORD(W[3], data, 24);
567     GET_FX_64WORD(W[4], data, 32);
568     GET_FX_64WORD(W[5], data, 40);
569     GET_FX_64WORD(W[6], data, 48);
570     GET_FX_64WORD(W[7], data, 56);
571     GET_FX_64WORD(W[8], data, 64);
572     GET_FX_64WORD(W[9], data, 72);
573     GET_FX_64WORD(W[10], data, 80);
574     GET_FX_64WORD(W[11], data, 88);
575     GET_FX_64WORD(W[12], data, 96);
576     GET_FX_64WORD(W[13], data, 104);
577     GET_FX_64WORD(W[14], data, 112);
578     GET_FX_64WORD(W[15], data, 120);
579     A = ctx->state[0];
580     B = ctx->state[1];
581     C = ctx->state[2];
582     D = ctx->state[3];
583     E = ctx->state[4];
584     F = ctx->state[5];
585     G = ctx->state[6];
586     H = ctx->state[7];
587     for (int i = 0; i < 10; ++i) {
588         uint64_t temp[8];
589         if (i < 2) {
590             temp[0] = W[i * 8];
591             temp[1] = W[i * 8 + 1];
592             temp[2] = W[i * 8 + 2];
593             temp[3] = W[i * 8 + 3];
594             temp[4] = W[i * 8 + 4];
595             temp[5] = W[i * 8 + 5];
596             temp[6] = W[i * 8 + 6];
597             temp[7] = W[i * 8 + 7];
598         } else {
599             temp[0] = SHA384_R(i * 8);
600             temp[1] = SHA384_R(i * 8 + 1);
601             temp[2] = SHA384_R(i * 8 + 2);
602             temp[3] = SHA384_R(i * 8 + 3);
603             temp[4] = SHA384_R(i * 8 + 4);
604             temp[5] = SHA384_R(i * 8 + 5);
605             temp[6] = SHA384_R(i * 8 + 6);
606             temp[7] = SHA384_R(i * 8 + 7);
607         }
608         SHA384_P( A, B, C, D, E, F, G, H, temp[ 0], FX_ato64i(constants[i * 8    ]) );
609         SHA384_P( H, A, B, C, D, E, F, G, temp[ 1], FX_ato64i(constants[i * 8 + 1]) );
610         SHA384_P( G, H, A, B, C, D, E, F, temp[ 2], FX_ato64i(constants[i * 8 + 2]) );
611         SHA384_P( F, G, H, A, B, C, D, E, temp[ 3], FX_ato64i(constants[i * 8 + 3]) );
612         SHA384_P( E, F, G, H, A, B, C, D, temp[ 4], FX_ato64i(constants[i * 8 + 4]) );
613         SHA384_P( D, E, F, G, H, A, B, C, temp[ 5], FX_ato64i(constants[i * 8 + 5]) );
614         SHA384_P( C, D, E, F, G, H, A, B, temp[ 6], FX_ato64i(constants[i * 8 + 6]) );
615         SHA384_P( B, C, D, E, F, G, H, A, temp[ 7], FX_ato64i(constants[i * 8 + 7]) );
616     }
617     ctx->state[0] += A;
618     ctx->state[1] += B;
619     ctx->state[2] += C;
620     ctx->state[3] += D;
621     ctx->state[4] += E;
622     ctx->state[5] += F;
623     ctx->state[6] += G;
624     ctx->state[7] += H;
625 }
626 void CRYPT_SHA384Update(void* context, const uint8_t* input, FX_DWORD length)
627 {
628     sha384_context *ctx = (sha384_context *)context;
629     FX_DWORD left, fill;
630     if( ! length ) {
631         return;
632     }
633     left = (FX_DWORD)ctx->total[0] & 0x7F;
634     fill = 128 - left;
635     ctx->total[0] += length;
636     if( ctx->total[0] < length ) {
637         ctx->total[1]++;
638     }
639     if( left && length >= fill ) {
640         FXSYS_memcpy( (void *) (ctx->buffer + left),
641                         (void *) input, fill );
642         sha384_process( ctx, ctx->buffer );
643         length -= fill;
644         input  += fill;
645         left = 0;
646     }
647     while( length >= 128 ) {
648         sha384_process( ctx, input );
649         length -= 128;
650         input  += 128;
651     }
652     if( length ) {
653         FXSYS_memcpy( (void *) (ctx->buffer + left),
654                         (void *) input, length );
655     }
656 }
657 void CRYPT_SHA384Finish(void* context, uint8_t digest[48])
658 {
659     sha384_context *ctx = (sha384_context *)context;
660     FX_DWORD last, padn;
661     uint8_t msglen[16];
662     FXSYS_memset(msglen, 0, 16);
663     uint64_t high, low;
664     high = ( ctx->total[0] >> 29 )
665            | ( ctx->total[1] <<  3 );
666     low  = ( ctx->total[0] <<  3 );
667     PUT_FX_64DWORD( high, msglen, 0 );
668     PUT_FX_64DWORD( low,  msglen, 8 );
669     last = (FX_DWORD)ctx->total[0] & 0x7F;
670     padn = ( last < 112 ) ? ( 112 - last ) : ( 240 - last );
671     CRYPT_SHA384Update( ctx, sha384_padding, padn );
672     CRYPT_SHA384Update( ctx, msglen, 16 );
673     PUT_FX_64DWORD(ctx->state[0], digest, 0);
674     PUT_FX_64DWORD(ctx->state[1], digest, 8);
675     PUT_FX_64DWORD(ctx->state[2], digest, 16);
676     PUT_FX_64DWORD(ctx->state[3], digest, 24);
677     PUT_FX_64DWORD(ctx->state[4], digest, 32);
678     PUT_FX_64DWORD(ctx->state[5], digest, 40);
679 }
680 void CRYPT_SHA384Generate(const uint8_t* data, FX_DWORD size, uint8_t digest[64])
681 {
682     sha384_context context;
683     CRYPT_SHA384Start(&context);
684     CRYPT_SHA384Update(&context, data, size);
685     CRYPT_SHA384Finish(&context, digest);
686 }
687 void CRYPT_SHA512Start(void* context)
688 {
689     if (context == NULL) {
690         return;
691     }
692     sha384_context *ctx = (sha384_context *)context;
693     FXSYS_memset(ctx, 0, sizeof(sha384_context));
694     ctx->state[0] = FX_ato64i("6a09e667f3bcc908");
695     ctx->state[1] = FX_ato64i("bb67ae8584caa73b");
696     ctx->state[2] = FX_ato64i("3c6ef372fe94f82b");
697     ctx->state[3] = FX_ato64i("a54ff53a5f1d36f1");
698     ctx->state[4] = FX_ato64i("510e527fade682d1");
699     ctx->state[5] = FX_ato64i("9b05688c2b3e6c1f");
700     ctx->state[6] = FX_ato64i("1f83d9abfb41bd6b");
701     ctx->state[7] = FX_ato64i("5be0cd19137e2179");
702 }
703 void CRYPT_SHA512Update(void* context, const uint8_t* data, FX_DWORD size)
704 {
705     CRYPT_SHA384Update(context, data, size);
706 }
707 void CRYPT_SHA512Finish(void* context, uint8_t digest[64])
708 {
709     sha384_context *ctx = (sha384_context *)context;
710     FX_DWORD last, padn;
711     uint8_t msglen[16];
712     FXSYS_memset(msglen, 0, 16);
713     uint64_t high, low;
714     high = ( ctx->total[0] >> 29 )
715            | ( ctx->total[1] <<  3 );
716     low  = ( ctx->total[0] <<  3 );
717     PUT_FX_64DWORD( high, msglen, 0 );
718     PUT_FX_64DWORD( low,  msglen, 8 );
719     last = (FX_DWORD)ctx->total[0] & 0x7F;
720     padn = ( last < 112 ) ? ( 112 - last ) : ( 240 - last );
721     CRYPT_SHA512Update( ctx, sha384_padding, padn );
722     CRYPT_SHA512Update( ctx, msglen, 16 );
723     PUT_FX_64DWORD(ctx->state[0], digest, 0);
724     PUT_FX_64DWORD(ctx->state[1], digest, 8);
725     PUT_FX_64DWORD(ctx->state[2], digest, 16);
726     PUT_FX_64DWORD(ctx->state[3], digest, 24);
727     PUT_FX_64DWORD(ctx->state[4], digest, 32);
728     PUT_FX_64DWORD(ctx->state[5], digest, 40);
729     PUT_FX_64DWORD(ctx->state[6], digest, 48);
730     PUT_FX_64DWORD(ctx->state[7], digest, 56);
731 }
732 void CRYPT_SHA512Generate(const uint8_t* data, FX_DWORD size, uint8_t digest[64])
733 {
734     sha384_context context;
735     CRYPT_SHA512Start(&context);
736     CRYPT_SHA512Update(&context, data, size);
737     CRYPT_SHA512Finish(&context, digest);
738 }
739 #ifdef __cplusplus
740 };
741 #endif