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 struct rc4_state {
     13     int x, y, m[256];
     14 };
     15 void CRYPT_ArcFourSetup(void* context,  FX_LPCBYTE key,  FX_DWORD length )
     16 {
     17     rc4_state *s = (rc4_state*)context;
     18     int i, j, k, *m, a;
     19     s->x = 0;
     20     s->y = 0;
     21     m = s->m;
     22     for( i = 0; i < 256; i++ ) {
     23         m[i] = i;
     24     }
     25     j = k = 0;
     26     for( i = 0; i < 256; i++ ) {
     27         a = m[i];
     28         j = ( j + a + key[k] ) & 0xFF;
     29         m[i] = m[j];
     30         m[j] = a;
     31         if( ++k >= (int)length ) {
     32             k = 0;
     33         }
     34     }
     35 }
     36 void CRYPT_ArcFourCrypt(void* context, unsigned char *data, FX_DWORD length )
     37 {
     38     struct rc4_state* s = (struct rc4_state*)context;
     39     int i, x, y, *m, a, b;
     40     x = s->x;
     41     y = s->y;
     42     m = s->m;
     43     for( i = 0; i < (int)length; i++ ) {
     44         x = ( x + 1 ) & 0xFF;
     45         a = m[x];
     46         y = ( y + a ) & 0xFF;
     47         m[x] = b = m[y];
     48         m[y] = a;
     49         data[i] ^= m[( a + b ) & 0xFF];
     50     }
     51     s->x = x;
     52     s->y = y;
     53 }
     54 void CRYPT_ArcFourCryptBlock(FX_LPBYTE pData, FX_DWORD size, FX_LPCBYTE key, FX_DWORD keylen)
     55 {
     56     rc4_state s;
     57     CRYPT_ArcFourSetup(&s, key, keylen);
     58     CRYPT_ArcFourCrypt(&s, pData, size);
     59 }
     60 struct md5_context {
     61     FX_DWORD total[2];
     62     FX_DWORD state[4];
     63     FX_BYTE buffer[64];
     64 };
     65 #define GET_FX_DWORD(n,b,i)                                       \
     66     {                                                               \
     67         (n) = (FX_DWORD) ((FX_BYTE *) b)[(i)]                           \
     68               | (((FX_DWORD) ((FX_BYTE *) b)[(i)+1]) <<  8)                 \
     69               | (((FX_DWORD) ((FX_BYTE *) b)[(i)+2]) << 16)                 \
     70               | (((FX_DWORD) ((FX_BYTE *) b)[(i)+3]) << 24);                \
     71     }
     72 #define PUT_FX_DWORD(n,b,i)                                       \
     73     {                                                               \
     74         (((FX_BYTE *) b)[(i)]  ) = (FX_BYTE) (((n)      ) & 0xFF);      \
     75         (((FX_BYTE *) b)[(i)+1]) = (FX_BYTE) (((n) >>  8) & 0xFF);      \
     76         (((FX_BYTE *) b)[(i)+2]) = (FX_BYTE) (((n) >> 16) & 0xFF);      \
     77         (((FX_BYTE *) b)[(i)+3]) = (FX_BYTE) (((n) >> 24) & 0xFF);      \
     78     }
     79 void md5_process( struct md5_context *ctx, const FX_BYTE data[64] )
     80 {
     81     FX_DWORD A, B, C, D, X[16];
     82     GET_FX_DWORD( X[0],  data,  0 );
     83     GET_FX_DWORD( X[1],  data,  4 );
     84     GET_FX_DWORD( X[2],  data,  8 );
     85     GET_FX_DWORD( X[3],  data, 12 );
     86     GET_FX_DWORD( X[4],  data, 16 );
     87     GET_FX_DWORD( X[5],  data, 20 );
     88     GET_FX_DWORD( X[6],  data, 24 );
     89     GET_FX_DWORD( X[7],  data, 28 );
     90     GET_FX_DWORD( X[8],  data, 32 );
     91     GET_FX_DWORD( X[9],  data, 36 );
     92     GET_FX_DWORD( X[10], data, 40 );
     93     GET_FX_DWORD( X[11], data, 44 );
     94     GET_FX_DWORD( X[12], data, 48 );
     95     GET_FX_DWORD( X[13], data, 52 );
     96     GET_FX_DWORD( X[14], data, 56 );
     97     GET_FX_DWORD( X[15], data, 60 );
     98 #define S(x,n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n)))
     99 #define P(a,b,c,d,k,s,t)                                \
    100     {                                                       \
    101         a += F(b,c,d) + X[k] + t; a = S(a,s) + b;           \
    102     }
    103     A = ctx->state[0];
    104     B = ctx->state[1];
    105     C = ctx->state[2];
    106     D = ctx->state[3];
    107 #define F(x,y,z) (z ^ (x & (y ^ z)))
    108     P( A, B, C, D,  0,  7, 0xD76AA478 );
    109     P( D, A, B, C,  1, 12, 0xE8C7B756 );
    110     P( C, D, A, B,  2, 17, 0x242070DB );
    111     P( B, C, D, A,  3, 22, 0xC1BDCEEE );
    112     P( A, B, C, D,  4,  7, 0xF57C0FAF );
    113     P( D, A, B, C,  5, 12, 0x4787C62A );
    114     P( C, D, A, B,  6, 17, 0xA8304613 );
    115     P( B, C, D, A,  7, 22, 0xFD469501 );
    116     P( A, B, C, D,  8,  7, 0x698098D8 );
    117     P( D, A, B, C,  9, 12, 0x8B44F7AF );
    118     P( C, D, A, B, 10, 17, 0xFFFF5BB1 );
    119     P( B, C, D, A, 11, 22, 0x895CD7BE );
    120     P( A, B, C, D, 12,  7, 0x6B901122 );
    121     P( D, A, B, C, 13, 12, 0xFD987193 );
    122     P( C, D, A, B, 14, 17, 0xA679438E );
    123     P( B, C, D, A, 15, 22, 0x49B40821 );
    124 #undef F
    125 #define F(x,y,z) (y ^ (z & (x ^ y)))
    126     P( A, B, C, D,  1,  5, 0xF61E2562 );
    127     P( D, A, B, C,  6,  9, 0xC040B340 );
    128     P( C, D, A, B, 11, 14, 0x265E5A51 );
    129     P( B, C, D, A,  0, 20, 0xE9B6C7AA );
    130     P( A, B, C, D,  5,  5, 0xD62F105D );
    131     P( D, A, B, C, 10,  9, 0x02441453 );
    132     P( C, D, A, B, 15, 14, 0xD8A1E681 );
    133     P( B, C, D, A,  4, 20, 0xE7D3FBC8 );
    134     P( A, B, C, D,  9,  5, 0x21E1CDE6 );
    135     P( D, A, B, C, 14,  9, 0xC33707D6 );
    136     P( C, D, A, B,  3, 14, 0xF4D50D87 );
    137     P( B, C, D, A,  8, 20, 0x455A14ED );
    138     P( A, B, C, D, 13,  5, 0xA9E3E905 );
    139     P( D, A, B, C,  2,  9, 0xFCEFA3F8 );
    140     P( C, D, A, B,  7, 14, 0x676F02D9 );
    141     P( B, C, D, A, 12, 20, 0x8D2A4C8A );
    142 #undef F
    143 #define F(x,y,z) (x ^ y ^ z)
    144     P( A, B, C, D,  5,  4, 0xFFFA3942 );
    145     P( D, A, B, C,  8, 11, 0x8771F681 );
    146     P( C, D, A, B, 11, 16, 0x6D9D6122 );
    147     P( B, C, D, A, 14, 23, 0xFDE5380C );
    148     P( A, B, C, D,  1,  4, 0xA4BEEA44 );
    149     P( D, A, B, C,  4, 11, 0x4BDECFA9 );
    150     P( C, D, A, B,  7, 16, 0xF6BB4B60 );
    151     P( B, C, D, A, 10, 23, 0xBEBFBC70 );
    152     P( A, B, C, D, 13,  4, 0x289B7EC6 );
    153     P( D, A, B, C,  0, 11, 0xEAA127FA );
    154     P( C, D, A, B,  3, 16, 0xD4EF3085 );
    155     P( B, C, D, A,  6, 23, 0x04881D05 );
    156     P( A, B, C, D,  9,  4, 0xD9D4D039 );
    157     P( D, A, B, C, 12, 11, 0xE6DB99E5 );
    158     P( C, D, A, B, 15, 16, 0x1FA27CF8 );
    159     P( B, C, D, A,  2, 23, 0xC4AC5665 );
    160 #undef F
    161 #define F(x,y,z) (y ^ (x | ~z))
    162     P( A, B, C, D,  0,  6, 0xF4292244 );
    163     P( D, A, B, C,  7, 10, 0x432AFF97 );
    164     P( C, D, A, B, 14, 15, 0xAB9423A7 );
    165     P( B, C, D, A,  5, 21, 0xFC93A039 );
    166     P( A, B, C, D, 12,  6, 0x655B59C3 );
    167     P( D, A, B, C,  3, 10, 0x8F0CCC92 );
    168     P( C, D, A, B, 10, 15, 0xFFEFF47D );
    169     P( B, C, D, A,  1, 21, 0x85845DD1 );
    170     P( A, B, C, D,  8,  6, 0x6FA87E4F );
    171     P( D, A, B, C, 15, 10, 0xFE2CE6E0 );
    172     P( C, D, A, B,  6, 15, 0xA3014314 );
    173     P( B, C, D, A, 13, 21, 0x4E0811A1 );
    174     P( A, B, C, D,  4,  6, 0xF7537E82 );
    175     P( D, A, B, C, 11, 10, 0xBD3AF235 );
    176     P( C, D, A, B,  2, 15, 0x2AD7D2BB );
    177     P( B, C, D, A,  9, 21, 0xEB86D391 );
    178 #undef F
    179     ctx->state[0] += A;
    180     ctx->state[1] += B;
    181     ctx->state[2] += C;
    182     ctx->state[3] += D;
    183 }
    184 void CRYPT_MD5Start(void* context)
    185 {
    186     struct md5_context *ctx = (struct md5_context*)context;
    187     ctx->total[0] = 0;
    188     ctx->total[1] = 0;
    189     ctx->state[0] = 0x67452301;
    190     ctx->state[1] = 0xEFCDAB89;
    191     ctx->state[2] = 0x98BADCFE;
    192     ctx->state[3] = 0x10325476;
    193 }
    194 void CRYPT_MD5Update(FX_LPVOID pctx, FX_LPCBYTE input, FX_DWORD length )
    195 {
    196     struct md5_context *ctx = (struct md5_context *)pctx;
    197     FX_DWORD left, fill;
    198     if( ! length ) {
    199         return;
    200     }
    201     left = ( ctx->total[0] >> 3 ) & 0x3F;
    202     fill = 64 - left;
    203     ctx->total[0] += length <<  3;
    204     ctx->total[1] += length >> 29;
    205     ctx->total[0] &= 0xFFFFFFFF;
    206     ctx->total[1] += ctx->total[0] < length << 3;
    207     if( left && length >= fill ) {
    208         FXSYS_memcpy32( (void *) (ctx->buffer + left), (void *) input, fill );
    209         md5_process( ctx, ctx->buffer );
    210         length -= fill;
    211         input  += fill;
    212         left = 0;
    213     }
    214     while( length >= 64 ) {
    215         md5_process( ctx, input );
    216         length -= 64;
    217         input  += 64;
    218     }
    219     if( length ) {
    220         FXSYS_memcpy32( (void *) (ctx->buffer + left), (void *) input, length );
    221     }
    222 }
    223 const FX_BYTE md5_padding[64] = {
    224     0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    225     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    226     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    227     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
    228 };
    229 void CRYPT_MD5Finish(FX_LPVOID pctx, FX_BYTE digest[16] )
    230 {
    231     struct md5_context *ctx = (struct md5_context *)pctx;
    232     FX_DWORD last, padn;
    233     FX_BYTE msglen[8];
    234     PUT_FX_DWORD( ctx->total[0], msglen, 0 );
    235     PUT_FX_DWORD( ctx->total[1], msglen, 4 );
    236     last = ( ctx->total[0] >> 3 ) & 0x3F;
    237     padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last );
    238     CRYPT_MD5Update( ctx, md5_padding, padn );
    239     CRYPT_MD5Update( ctx, msglen, 8 );
    240     PUT_FX_DWORD( ctx->state[0], digest,  0 );
    241     PUT_FX_DWORD( ctx->state[1], digest,  4 );
    242     PUT_FX_DWORD( ctx->state[2], digest,  8 );
    243     PUT_FX_DWORD( ctx->state[3], digest, 12 );
    244 }
    245 void CRYPT_MD5Generate(FX_LPCBYTE input, FX_DWORD length, FX_BYTE digest[16])
    246 {
    247     md5_context ctx;
    248     CRYPT_MD5Start(&ctx);
    249     CRYPT_MD5Update(&ctx, input, length);
    250     CRYPT_MD5Finish(&ctx, digest);
    251 }
    252 static FX_BOOL (*g_PubKeyDecryptor)(FX_LPCBYTE pData, FX_DWORD size, FX_LPBYTE data_buf, FX_DWORD& data_len) = NULL;
    253 void CRYPT_SetPubKeyDecryptor(FX_BOOL (*func)(FX_LPCBYTE pData, FX_DWORD size, FX_LPBYTE data_buf, FX_DWORD& data_len))
    254 {
    255     g_PubKeyDecryptor = func;
    256 }
    257 #ifdef __cplusplus
    258 };
    259 #endif
    260