Home | History | Annotate | Download | only in crypto
      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(FX_LPVOID 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(FX_LPVOID context, FX_LPCBYTE 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_memcpy32(s->block + s->blkused, q, len);
    104         s->blkused += len;
    105     } else {
    106         while (s->blkused + len >= 64) {
    107             FXSYS_memcpy32(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_memcpy32(s->block, q, len);
    121         s->blkused = len;
    122     }
    123 }
    124 void CRYPT_SHA1Finish(FX_LPVOID context, FX_BYTE 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_memset32(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(FX_LPCBYTE data, FX_DWORD size, FX_BYTE 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     FX_BYTE 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)    ] = (FX_BYTE) ( (n) >> 24 );       \
    180         (b)[(i) + 1] = (FX_BYTE) ( (n) >> 16 );       \
    181         (b)[(i) + 2] = (FX_BYTE) ( (n) >>  8 );       \
    182         (b)[(i) + 3] = (FX_BYTE) ( (n)       );       \
    183     }
    184 void CRYPT_SHA256Start( FX_LPVOID 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 FX_BYTE 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, FX_LPCBYTE 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_memcpy32( (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_memcpy32( (void *) (ctx->buffer + left),
    347                         (void *) input, length );
    348     }
    349 }
    350 static const FX_BYTE 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( FX_LPVOID context, FX_BYTE digest[32] )
    357 {
    358     sha256_context *ctx = (sha256_context *)context;
    359     FX_DWORD last, padn;
    360     FX_DWORD high, low;
    361     FX_BYTE 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(FX_LPCBYTE data, FX_DWORD size, FX_BYTE 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     FX_UINT64	total[2];
    389     FX_UINT64	state[8];
    390     FX_BYTE		buffer[128];
    391 } sha384_context;
    392 FX_UINT64 FX_ato64i(FX_LPCSTR str)
    393 {
    394     FXSYS_assert(str != NULL);
    395     FX_UINT64 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(FX_LPVOID context)
    415 {
    416     if (context == NULL) {
    417         return;
    418     }
    419     sha384_context *ctx = (sha384_context *)context;
    420     FXSYS_memset32(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 FX_BYTE 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 FX_LPCSTR 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) = ( (FX_UINT64) (b)[(i)    ] << 56 )       \
    540               | ( (FX_UINT64) (b)[(i) + 1] << 48 )       \
    541               | ( (FX_UINT64) (b)[(i) + 2] << 40 )       \
    542               | ( (FX_UINT64) (b)[(i) + 3] << 32 )      \
    543               | ( (FX_UINT64) (b)[(i) + 4] << 24 )       \
    544               | ( (FX_UINT64) (b)[(i) + 5] << 16 )       \
    545               | ( (FX_UINT64) (b)[(i) + 6] <<  8 )       \
    546               | ( (FX_UINT64) (b)[(i) + 7]       );      \
    547     }
    548 #define PUT_FX_64DWORD(n,b,i)                       \
    549     {                                               \
    550         (b)[(i)    ] = (FX_BYTE) ( (n) >> 56 );       \
    551         (b)[(i) + 1] = (FX_BYTE) ( (n) >> 48 );       \
    552         (b)[(i) + 2] = (FX_BYTE) ( (n) >> 40 );       \
    553         (b)[(i) + 3] = (FX_BYTE) ( (n) >> 32 );       \
    554         (b)[(i) + 4] = (FX_BYTE) ( (n) >> 24 );       \
    555         (b)[(i) + 5] = (FX_BYTE) ( (n) >> 16 );       \
    556         (b)[(i) + 6] = (FX_BYTE) ( (n) >>  8 );       \
    557         (b)[(i) + 7] = (FX_BYTE) ( (n) );       \
    558     }
    559 static void sha384_process( sha384_context *ctx, const FX_BYTE data[128] )
    560 {
    561     FX_UINT64 temp1, temp2;
    562     FX_UINT64 A, B, C, D, E, F, G, H;
    563     FX_UINT64 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         FX_UINT64 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(FX_LPVOID context, FX_LPCBYTE 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_memcpy32( (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_memcpy32( (void *) (ctx->buffer + left),
    655                         (void *) input, length );
    656     }
    657 }
    658 void CRYPT_SHA384Finish(FX_LPVOID context, FX_BYTE digest[48])
    659 {
    660     sha384_context *ctx = (sha384_context *)context;
    661     FX_DWORD last, padn;
    662     FX_BYTE msglen[16];
    663     FXSYS_memset32(msglen, 0, 16);
    664     FX_UINT64 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(FX_LPCBYTE data, FX_DWORD size, FX_BYTE 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(FX_LPVOID context)
    689 {
    690     if (context == NULL) {
    691         return;
    692     }
    693     sha384_context *ctx = (sha384_context *)context;
    694     FXSYS_memset32(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(FX_LPVOID context, FX_LPCBYTE data, FX_DWORD size)
    705 {
    706     CRYPT_SHA384Update(context, data, size);
    707 }
    708 void CRYPT_SHA512Finish(FX_LPVOID context, FX_BYTE digest[64])
    709 {
    710     sha384_context *ctx = (sha384_context *)context;
    711     FX_DWORD last, padn;
    712     FX_BYTE msglen[16];
    713     FXSYS_memset32(msglen, 0, 16);
    714     FX_UINT64 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(FX_LPCBYTE data, FX_DWORD size, FX_BYTE 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
    743