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