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