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