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