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 };
CRYPT_ArcFourSetup(void * context,FX_LPCBYTE key,FX_DWORD length)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 }
CRYPT_ArcFourCrypt(void * context,unsigned char * data,FX_DWORD length)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 }
CRYPT_ArcFourCryptBlock(FX_LPBYTE pData,FX_DWORD size,FX_LPCBYTE key,FX_DWORD keylen)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 }
md5_process(struct md5_context * ctx,const FX_BYTE data[64])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 }
CRYPT_MD5Start(void * context)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 }
CRYPT_MD5Update(FX_LPVOID pctx,FX_LPCBYTE input,FX_DWORD length)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 };
CRYPT_MD5Finish(FX_LPVOID pctx,FX_BYTE digest[16])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 }
CRYPT_MD5Generate(FX_LPCBYTE input,FX_DWORD length,FX_BYTE digest[16])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;
CRYPT_SetPubKeyDecryptor(FX_BOOL (* func)(FX_LPCBYTE pData,FX_DWORD size,FX_LPBYTE data_buf,FX_DWORD & data_len))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