Merge to XFA: Use stdint.h types throughout PDFium.
[pdfium.git] / core / src / fdrm / crypto / fx_crypt.cpp
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/fdrm/fx_crypt.h"
8 #include "../../../include/fxcrt/fx_basic.h"
9 #include "../../../include/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 };
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 }
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 }
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     uint8_t buffer[64];
66 };
67 #define GET_FX_DWORD(n,b,i)                                       \
68     {                                                               \
69         (n) = (FX_DWORD) ((uint8_t *) b)[(i)]                           \
70               | (((FX_DWORD) ((uint8_t *) b)[(i)+1]) <<  8)                 \
71               | (((FX_DWORD) ((uint8_t *) b)[(i)+2]) << 16)                 \
72               | (((FX_DWORD) ((uint8_t *) b)[(i)+3]) << 24);                \
73     }
74 #define PUT_FX_DWORD(n,b,i)                                       \
75     {                                                               \
76         (((uint8_t *) b)[(i)]  ) = (uint8_t) (((n)      ) & 0xFF);      \
77         (((uint8_t *) b)[(i)+1]) = (uint8_t) (((n) >>  8) & 0xFF);      \
78         (((uint8_t *) b)[(i)+2]) = (uint8_t) (((n) >> 16) & 0xFF);      \
79         (((uint8_t *) b)[(i)+3]) = (uint8_t) (((n) >> 24) & 0xFF);      \
80     }
81 void md5_process( struct md5_context *ctx, const uint8_t 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 }
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 }
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 uint8_t 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 };
231 void CRYPT_MD5Finish(FX_LPVOID pctx, uint8_t digest[16] )
232 {
233     struct md5_context *ctx = (struct md5_context *)pctx;
234     FX_DWORD last, padn;
235     uint8_t 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 }
247 void CRYPT_MD5Generate(FX_LPCBYTE input, FX_DWORD length, uint8_t 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;
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