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 "core/include/fdrm/fx_crypt.h"
8 
9 #ifdef __cplusplus
10 extern "C" {
11 #endif
12 struct rc4_state {
13   int x, y, m[256];
14 };
CRYPT_ArcFourSetup(void * context,const uint8_t * key,FX_DWORD length)15 void CRYPT_ArcFourSetup(void* context, const uint8_t* key, FX_DWORD length) {
16   rc4_state* s = (rc4_state*)context;
17   int i, j, k, *m, a;
18   s->x = 0;
19   s->y = 0;
20   m = s->m;
21   for (i = 0; i < 256; i++) {
22     m[i] = i;
23   }
24   j = k = 0;
25   for (i = 0; i < 256; i++) {
26     a = m[i];
27     j = (j + a + key[k]) & 0xFF;
28     m[i] = m[j];
29     m[j] = a;
30     if (++k >= (int)length) {
31       k = 0;
32     }
33   }
34 }
CRYPT_ArcFourCrypt(void * context,unsigned char * data,FX_DWORD length)35 void CRYPT_ArcFourCrypt(void* context, unsigned char* data, FX_DWORD length) {
36   struct rc4_state* s = (struct rc4_state*)context;
37   int i, x, y, *m, a, b;
38   x = s->x;
39   y = s->y;
40   m = s->m;
41   for (i = 0; i < (int)length; i++) {
42     x = (x + 1) & 0xFF;
43     a = m[x];
44     y = (y + a) & 0xFF;
45     m[x] = b = m[y];
46     m[y] = a;
47     data[i] ^= m[(a + b) & 0xFF];
48   }
49   s->x = x;
50   s->y = y;
51 }
CRYPT_ArcFourCryptBlock(uint8_t * pData,FX_DWORD size,const uint8_t * key,FX_DWORD keylen)52 void CRYPT_ArcFourCryptBlock(uint8_t* pData,
53                              FX_DWORD size,
54                              const uint8_t* key,
55                              FX_DWORD keylen) {
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   uint8_t buffer[64];
64 };
65 #define GET_FX_DWORD(n, b, i)                          \
66   {                                                    \
67     (n) = (FX_DWORD)((uint8_t*)b)[(i)] |               \
68           (((FX_DWORD)((uint8_t*)b)[(i) + 1]) << 8) |  \
69           (((FX_DWORD)((uint8_t*)b)[(i) + 2]) << 16) | \
70           (((FX_DWORD)((uint8_t*)b)[(i) + 3]) << 24);  \
71   }
72 #define PUT_FX_DWORD(n, b, i)                                 \
73   {                                                           \
74     (((uint8_t*)b)[(i)]) = (uint8_t)(((n)) & 0xFF);           \
75     (((uint8_t*)b)[(i) + 1]) = (uint8_t)(((n) >> 8) & 0xFF);  \
76     (((uint8_t*)b)[(i) + 2]) = (uint8_t)(((n) >> 16) & 0xFF); \
77     (((uint8_t*)b)[(i) + 3]) = (uint8_t)(((n) >> 24) & 0xFF); \
78   }
md5_process(struct md5_context * ctx,const uint8_t data[64])79 void md5_process(struct md5_context* ctx, const uint8_t data[64]) {
80   FX_DWORD A, B, C, D, X[16];
81   GET_FX_DWORD(X[0], data, 0);
82   GET_FX_DWORD(X[1], data, 4);
83   GET_FX_DWORD(X[2], data, 8);
84   GET_FX_DWORD(X[3], data, 12);
85   GET_FX_DWORD(X[4], data, 16);
86   GET_FX_DWORD(X[5], data, 20);
87   GET_FX_DWORD(X[6], data, 24);
88   GET_FX_DWORD(X[7], data, 28);
89   GET_FX_DWORD(X[8], data, 32);
90   GET_FX_DWORD(X[9], data, 36);
91   GET_FX_DWORD(X[10], data, 40);
92   GET_FX_DWORD(X[11], data, 44);
93   GET_FX_DWORD(X[12], data, 48);
94   GET_FX_DWORD(X[13], data, 52);
95   GET_FX_DWORD(X[14], data, 56);
96   GET_FX_DWORD(X[15], data, 60);
97 #define S(x, n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n)))
98 #define P(a, b, c, d, k, s, t)  \
99   {                             \
100     a += F(b, c, d) + X[k] + t; \
101     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   struct md5_context* ctx = (struct md5_context*)context;
186   ctx->total[0] = 0;
187   ctx->total[1] = 0;
188   ctx->state[0] = 0x67452301;
189   ctx->state[1] = 0xEFCDAB89;
190   ctx->state[2] = 0x98BADCFE;
191   ctx->state[3] = 0x10325476;
192 }
CRYPT_MD5Update(void * pctx,const uint8_t * input,FX_DWORD length)193 void CRYPT_MD5Update(void* pctx, const uint8_t* input, FX_DWORD length) {
194   struct md5_context* ctx = (struct md5_context*)pctx;
195   FX_DWORD left, fill;
196   if (!length) {
197     return;
198   }
199   left = (ctx->total[0] >> 3) & 0x3F;
200   fill = 64 - left;
201   ctx->total[0] += length << 3;
202   ctx->total[1] += length >> 29;
203   ctx->total[0] &= 0xFFFFFFFF;
204   ctx->total[1] += ctx->total[0] < length << 3;
205   if (left && length >= fill) {
206     FXSYS_memcpy((void*)(ctx->buffer + left), (void*)input, fill);
207     md5_process(ctx, ctx->buffer);
208     length -= fill;
209     input += fill;
210     left = 0;
211   }
212   while (length >= 64) {
213     md5_process(ctx, input);
214     length -= 64;
215     input += 64;
216   }
217   if (length) {
218     FXSYS_memcpy((void*)(ctx->buffer + left), (void*)input, length);
219   }
220 }
221 const uint8_t md5_padding[64] = {
222     0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
223     0,    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
224     0,    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
CRYPT_MD5Finish(void * pctx,uint8_t digest[16])225 void CRYPT_MD5Finish(void* pctx, uint8_t digest[16]) {
226   struct md5_context* ctx = (struct md5_context*)pctx;
227   FX_DWORD last, padn;
228   uint8_t msglen[8];
229   PUT_FX_DWORD(ctx->total[0], msglen, 0);
230   PUT_FX_DWORD(ctx->total[1], msglen, 4);
231   last = (ctx->total[0] >> 3) & 0x3F;
232   padn = (last < 56) ? (56 - last) : (120 - last);
233   CRYPT_MD5Update(ctx, md5_padding, padn);
234   CRYPT_MD5Update(ctx, msglen, 8);
235   PUT_FX_DWORD(ctx->state[0], digest, 0);
236   PUT_FX_DWORD(ctx->state[1], digest, 4);
237   PUT_FX_DWORD(ctx->state[2], digest, 8);
238   PUT_FX_DWORD(ctx->state[3], digest, 12);
239 }
CRYPT_MD5Generate(const uint8_t * input,FX_DWORD length,uint8_t digest[16])240 void CRYPT_MD5Generate(const uint8_t* input,
241                        FX_DWORD length,
242                        uint8_t digest[16]) {
243   md5_context ctx;
244   CRYPT_MD5Start(&ctx);
245   CRYPT_MD5Update(&ctx, input, length);
246   CRYPT_MD5Finish(&ctx, digest);
247 }
248 static FX_BOOL (*g_PubKeyDecryptor)(const uint8_t* pData,
249                                     FX_DWORD size,
250                                     uint8_t* data_buf,
251                                     FX_DWORD& data_len) = NULL;
CRYPT_SetPubKeyDecryptor(FX_BOOL (* func)(const uint8_t * pData,FX_DWORD size,uint8_t * data_buf,FX_DWORD & data_len))252 void CRYPT_SetPubKeyDecryptor(FX_BOOL (*func)(const uint8_t* pData,
253                                               FX_DWORD size,
254                                               uint8_t* data_buf,
255                                               FX_DWORD& data_len)) {
256   g_PubKeyDecryptor = func;
257 }
258 #ifdef __cplusplus
259 };
260 #endif
261