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
12 extern "C" {
13 #endif
14 struct rc4_state {
15 int x, y, m[256];
16 };
CRYPT_ArcFourSetup(void * context,FX_LPCBYTE key,FX_DWORD length)17 void 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 }
CRYPT_ArcFourCrypt(void * context,unsigned char * data,FX_DWORD length)38 void 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 }
CRYPT_ArcFourCryptBlock(FX_LPBYTE pData,FX_DWORD size,FX_LPCBYTE key,FX_DWORD keylen)56 void 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 }
62 struct 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 }
md5_process(struct md5_context * ctx,const FX_BYTE data[64])81 void 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 }
CRYPT_MD5Start(void * context)186 void 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 }
CRYPT_MD5Update(FX_LPVOID pctx,FX_LPCBYTE input,FX_DWORD length)196 void 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 }
225 const 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 };
CRYPT_MD5Finish(FX_LPVOID pctx,FX_BYTE digest[16])231 void 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 }
CRYPT_MD5Generate(FX_LPCBYTE input,FX_DWORD length,FX_BYTE digest[16])247 void 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 }
254 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))255 void 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