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
10extern "C" {
11#endif
12struct rc4_state {
13    int x, y, m[256];
14};
15void 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}
36void 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}
54void 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}
60struct 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    }
79void 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}
184void 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}
194void 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}
223const 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};
229void 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}
245void 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}
252static FX_BOOL (*g_PubKeyDecryptor)(FX_LPCBYTE pData, FX_DWORD size, FX_LPBYTE data_buf, FX_DWORD& data_len) = NULL;
253void 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