blob: 4010ff49eeb04dab5487120b938a5be0af6583c2 [file] [log] [blame]
Philip P. Moltmann4d3acf42017-03-20 11:05:52 -07001// 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
10extern "C" {
11#endif
12
13void 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
35void 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
54void 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
78void 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
184void 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
193void 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
223const 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
228void 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
243void 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