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 <time.h>
8#include "../../../include/fpdfapi/fpdf_parser.h"
9#include "../../../include/fdrm/fx_crypt.h"
10const FX_BYTE defpasscode[32] = {
11    0x28, 0xbf, 0x4e, 0x5e, 0x4e, 0x75, 0x8a, 0x41,
12    0x64, 0x00, 0x4e, 0x56, 0xff, 0xfa, 0x01, 0x08,
13    0x2e, 0x2e, 0x00, 0xb6, 0xd0, 0x68, 0x3e, 0x80,
14    0x2f, 0x0c, 0xa9, 0xfe, 0x64, 0x53, 0x69, 0x7a
15};
16void CalcEncryptKey(CPDF_Dictionary* pEncrypt, FX_LPCBYTE password, FX_DWORD pass_size,
17                    FX_LPBYTE key, int keylen, FX_BOOL bIgnoreMeta, CPDF_Array* pIdArray)
18{
19    int revision = pEncrypt->GetInteger(FX_BSTRC("R"));
20    FX_BYTE passcode[32];
21    for (FX_DWORD i = 0; i < 32; i ++) {
22        passcode[i] = i < pass_size ? password[i] : defpasscode[i - pass_size];
23    }
24    FX_BYTE md5[100];
25    CRYPT_MD5Start(md5);
26    CRYPT_MD5Update(md5, passcode, 32);
27    CFX_ByteString okey = pEncrypt->GetString(FX_BSTRC("O"));
28    CRYPT_MD5Update(md5, (FX_LPBYTE)(FX_LPCSTR)okey, okey.GetLength());
29    FX_DWORD perm = pEncrypt->GetInteger(FX_BSTRC("P"));
30    CRYPT_MD5Update(md5, (FX_LPBYTE)&perm, 4);
31    if (pIdArray) {
32        CFX_ByteString id = pIdArray->GetString(0);
33        CRYPT_MD5Update(md5, (FX_LPBYTE)(FX_LPCSTR)id, id.GetLength());
34    }
35    if (!bIgnoreMeta && revision >= 3 && !pEncrypt->GetInteger(FX_BSTRC("EncryptMetadata"), 1)) {
36        FX_DWORD tag = (FX_DWORD) - 1;
37        CRYPT_MD5Update(md5, (FX_LPBYTE)&tag, 4);
38    }
39    FX_BYTE digest[16];
40    CRYPT_MD5Finish(md5, digest);
41    FX_DWORD copy_len = keylen;
42    if (copy_len > sizeof(digest)) {
43        copy_len = sizeof(digest);
44    }
45    if (revision >= 3) {
46        for (int i = 0; i < 50; i ++) {
47            CRYPT_MD5Generate(digest, copy_len, digest);
48        }
49    }
50    FXSYS_memset32(key, 0, keylen);
51    FXSYS_memcpy32(key, digest, copy_len);
52}
53CPDF_CryptoHandler* CPDF_StandardSecurityHandler::CreateCryptoHandler()
54{
55    return FX_NEW CPDF_StandardCryptoHandler;
56}
57typedef struct _PDF_CRYPTOITEM : public CFX_Object {
58    FX_INT32	m_Cipher;
59    FX_INT32	m_KeyLen;
60    FX_BOOL		m_bChecked;
61    CPDF_StandardCryptoHandler*	m_pCryptoHandler;
62} PDF_CRYPTOITEM;
63CPDF_StandardSecurityHandler::CPDF_StandardSecurityHandler()
64{
65    m_Version = 0;
66    m_Revision = 0;
67    m_pParser = NULL;
68    m_pEncryptDict = NULL;
69    m_bOwner = FALSE;
70    m_Permissions = 0;
71    m_Cipher = FXCIPHER_NONE;
72    m_KeyLen = 0;
73}
74CPDF_StandardSecurityHandler::~CPDF_StandardSecurityHandler()
75{
76}
77FX_BOOL CPDF_StandardSecurityHandler::OnInit(CPDF_Parser* pParser, CPDF_Dictionary* pEncryptDict)
78{
79    m_pParser = pParser;
80    if (!LoadDict(pEncryptDict)) {
81        return FALSE;
82    }
83    if (m_Cipher == FXCIPHER_NONE) {
84        return TRUE;
85    }
86    return CheckSecurity(m_KeyLen);
87}
88FX_BOOL CPDF_StandardSecurityHandler::CheckSecurity(FX_INT32 key_len)
89{
90    CFX_ByteString password = m_pParser->GetPassword();
91    if (CheckPassword(password, password.GetLength(), TRUE, m_EncryptKey, key_len)) {
92        if (password.IsEmpty()) {
93            if (!CheckPassword(password, password.GetLength(), FALSE, m_EncryptKey, key_len)) {
94                return FALSE;
95            }
96        }
97        m_bOwner = TRUE;
98        return TRUE;
99    }
100    return CheckPassword(password, password.GetLength(), FALSE, m_EncryptKey, key_len);
101}
102FX_DWORD CPDF_StandardSecurityHandler::GetPermissions()
103{
104    return m_Permissions;
105}
106static FX_BOOL _LoadCryptInfo(CPDF_Dictionary* pEncryptDict, FX_BSTR name, int& cipher, int& keylen)
107{
108    int Version = pEncryptDict->GetInteger(FX_BSTRC("V"));
109    int Revision = pEncryptDict->GetInteger(FX_BSTRC("R"));
110    cipher = FXCIPHER_RC4;
111    keylen = 0;
112    if (Version >= 4) {
113        CPDF_Dictionary* pCryptFilters = pEncryptDict->GetDict(FX_BSTRC("CF"));
114        if (pCryptFilters == NULL) {
115            return FALSE;
116        }
117        if (name == FX_BSTRC("Identity")) {
118            cipher = FXCIPHER_NONE;
119        } else {
120            CPDF_Dictionary* pDefFilter = pCryptFilters->GetDict(name);
121            if (pDefFilter == NULL) {
122                return FALSE;
123            }
124            int nKeyBits = 0;
125            if (Version == 4) {
126                nKeyBits = pDefFilter->GetInteger(FX_BSTRC("Length"), 0);
127                if (nKeyBits == 0) {
128                    nKeyBits = pEncryptDict->GetInteger(FX_BSTRC("Length"), 128);
129                }
130            } else {
131                nKeyBits = pEncryptDict->GetInteger(FX_BSTRC("Length"), 256);
132            }
133            if (nKeyBits < 40) {
134                nKeyBits *= 8;
135            }
136            keylen = nKeyBits / 8;
137            CFX_ByteString cipher_name = pDefFilter->GetString(FX_BSTRC("CFM"));
138            if (cipher_name == FX_BSTRC("AESV2") || cipher_name == FX_BSTRC("AESV3")) {
139                cipher = FXCIPHER_AES;
140            }
141        }
142    } else {
143        keylen = Version > 1 ? pEncryptDict->GetInteger(FX_BSTRC("Length"), 40) / 8 : 5;
144    }
145    if (keylen > 32 || keylen < 0) {
146        return FALSE;
147    }
148    return TRUE;
149}
150FX_BOOL CPDF_StandardSecurityHandler::LoadDict(CPDF_Dictionary* pEncryptDict)
151{
152    m_pEncryptDict = pEncryptDict;
153    m_bOwner = FALSE;
154    m_Version = pEncryptDict->GetInteger(FX_BSTRC("V"));
155    m_Revision = pEncryptDict->GetInteger(FX_BSTRC("R"));
156    m_Permissions = pEncryptDict->GetInteger(FX_BSTRC("P"), -1);
157    if (m_Version < 4) {
158        return _LoadCryptInfo(pEncryptDict, CFX_ByteString(), m_Cipher, m_KeyLen);
159    }
160    CFX_ByteString stmf_name = pEncryptDict->GetString(FX_BSTRC("StmF"));
161    CFX_ByteString strf_name = pEncryptDict->GetString(FX_BSTRC("StrF"));
162    if (stmf_name != strf_name) {
163        return FALSE;
164    }
165    if (!_LoadCryptInfo(pEncryptDict, strf_name, m_Cipher, m_KeyLen)) {
166        return FALSE;
167    }
168    return TRUE;
169}
170FX_BOOL CPDF_StandardSecurityHandler::LoadDict(CPDF_Dictionary* pEncryptDict, FX_DWORD type, int& cipher, int& key_len)
171{
172    m_pEncryptDict = pEncryptDict;
173    m_bOwner = FALSE;
174    m_Version = pEncryptDict->GetInteger(FX_BSTRC("V"));
175    m_Revision = pEncryptDict->GetInteger(FX_BSTRC("R"));
176    m_Permissions = pEncryptDict->GetInteger(FX_BSTRC("P"), -1);
177    CFX_ByteString strf_name, stmf_name;
178    if (m_Version >= 4) {
179        stmf_name = pEncryptDict->GetString(FX_BSTRC("StmF"));
180        strf_name = pEncryptDict->GetString(FX_BSTRC("StrF"));
181        if (stmf_name != strf_name) {
182            return FALSE;
183        }
184    }
185    if (!_LoadCryptInfo(pEncryptDict, strf_name, cipher, key_len)) {
186        return FALSE;
187    }
188    m_Cipher = cipher;
189    m_KeyLen = key_len;
190    return TRUE;
191    return TRUE;
192}
193FX_BOOL CPDF_StandardSecurityHandler::GetCryptInfo(int& cipher, FX_LPCBYTE& buffer, int& keylen)
194{
195    cipher = m_Cipher;
196    buffer = m_EncryptKey;
197    keylen = m_KeyLen;
198    return TRUE;
199}
200#define FX_GET_32WORD(n,b,i)								\
201    {														\
202        (n) = (FX_DWORD)(( (FX_UINT64) (b)[(i)] << 24 )			\
203                         | ( (FX_UINT64) (b)[(i) + 1] << 16 )					\
204                         | ( (FX_UINT64) (b)[(i) + 2] <<  8 )					\
205                         | ( (FX_UINT64) (b)[(i) + 3]       ));					\
206    }
207int BigOrder64BitsMod3(FX_LPBYTE data)
208{
209    FX_UINT64 ret = 0;
210    for (int i = 0; i < 4; ++i) {
211        FX_DWORD value;
212        FX_GET_32WORD(value, data, 4 * i);
213        ret <<= 32;
214        ret |= value;
215        ret %= 3;
216    }
217    return (int)ret;
218}
219void Revision6_Hash(FX_LPCBYTE password, FX_DWORD size, FX_LPCBYTE salt, FX_LPCBYTE vector, FX_LPBYTE hash)
220{
221    int iBlockSize = 32;
222    FX_BYTE sha[128];
223    CRYPT_SHA256Start(sha);
224    CRYPT_SHA256Update(sha, password, size);
225    CRYPT_SHA256Update(sha, salt, 8);
226    if (vector) {
227        CRYPT_SHA256Update(sha, vector, 48);
228    }
229    FX_BYTE digest[32];
230    CRYPT_SHA256Finish(sha, digest);
231    CFX_ByteTextBuf buf;
232    FX_LPBYTE input = digest;
233    FX_LPBYTE key = input;
234    FX_LPBYTE iv = input + 16;
235    FX_LPBYTE E = buf.GetBuffer();
236    int iBufLen = buf.GetLength();
237    CFX_ByteTextBuf interDigest;
238    int i = 0;
239    FX_LPBYTE aes = FX_Alloc(FX_BYTE, 2048);
240    while (i < 64 || i < E[iBufLen - 1]  + 32) {
241        int iRoundSize = size + iBlockSize;
242        if (vector) {
243            iRoundSize += 48;
244        }
245        iBufLen = iRoundSize * 64;
246        buf.EstimateSize(iBufLen);
247        E = buf.GetBuffer();
248        CFX_ByteTextBuf content;
249        for (int j = 0; j < 64; ++j) {
250            content.AppendBlock(password, size);
251            content.AppendBlock(input, iBlockSize);
252            if (vector) {
253                content.AppendBlock(vector, 48);
254            }
255        }
256        CRYPT_AESSetKey(aes, 16, key, 16, TRUE);
257        CRYPT_AESSetIV(aes, iv);
258        CRYPT_AESEncrypt(aes, E, content.GetBuffer(), iBufLen);
259        int iHash = 0;
260        switch (BigOrder64BitsMod3(E)) {
261            case 0:
262                iHash = 0;
263                iBlockSize = 32;
264                break;
265            case 1:
266                iHash = 1;
267                iBlockSize = 48;
268                break;
269            default:
270                iHash = 2;
271                iBlockSize = 64;
272                break;
273        }
274        interDigest.EstimateSize(iBlockSize);
275        input = interDigest.GetBuffer();
276        if (iHash == 0) {
277            CRYPT_SHA256Generate(E, iBufLen, input);
278        } else if (iHash == 1) {
279            CRYPT_SHA384Generate(E, iBufLen, input);
280        } else if (iHash == 2) {
281            CRYPT_SHA512Generate(E, iBufLen, input);
282        }
283        key = input;
284        iv = input + 16;
285        ++i;
286    }
287    FX_Free(aes);
288    if (hash) {
289        FXSYS_memcpy32(hash, input, 32);
290    }
291}
292FX_BOOL CPDF_StandardSecurityHandler::AES256_CheckPassword(FX_LPCBYTE password, FX_DWORD size,
293        FX_BOOL bOwner, FX_LPBYTE key)
294{
295    CFX_ByteString okey = m_pEncryptDict->GetString(FX_BSTRC("O"));
296    if (okey.GetLength() < 48) {
297        return FALSE;
298    }
299    CFX_ByteString ukey = m_pEncryptDict->GetString(FX_BSTRC("U"));
300    if (ukey.GetLength() < 48) {
301        return FALSE;
302    }
303    FX_LPCBYTE pkey = bOwner ? (FX_LPCBYTE)okey : (FX_LPCBYTE)ukey;
304    FX_BYTE sha[128];
305    FX_BYTE digest[32];
306    if (m_Revision >= 6) {
307        Revision6_Hash(password, size, (FX_LPCBYTE)pkey + 32, (bOwner ? (FX_LPCBYTE)ukey : NULL), digest);
308    } else {
309        CRYPT_SHA256Start(sha);
310        CRYPT_SHA256Update(sha, password, size);
311        CRYPT_SHA256Update(sha, pkey + 32, 8);
312        if (bOwner) {
313            CRYPT_SHA256Update(sha, ukey, 48);
314        }
315        CRYPT_SHA256Finish(sha, digest);
316    }
317    if (FXSYS_memcmp32(digest, pkey, 32) != 0) {
318        return FALSE;
319    }
320    if (key == NULL) {
321        return TRUE;
322    }
323    if (m_Revision >= 6) {
324        Revision6_Hash(password, size, (FX_LPCBYTE)pkey + 40, (bOwner ? (FX_LPCBYTE)ukey : NULL), digest);
325    } else {
326        CRYPT_SHA256Start(sha);
327        CRYPT_SHA256Update(sha, password, size);
328        CRYPT_SHA256Update(sha, pkey + 40, 8);
329        if (bOwner) {
330            CRYPT_SHA256Update(sha, ukey, 48);
331        }
332        CRYPT_SHA256Finish(sha, digest);
333    }
334    CFX_ByteString ekey = m_pEncryptDict->GetString(bOwner ? FX_BSTRC("OE") : FX_BSTRC("UE"));
335    if (ekey.GetLength() < 32) {
336        return FALSE;
337    }
338    FX_BYTE* aes = FX_Alloc(FX_BYTE, 2048);
339    CRYPT_AESSetKey(aes, 16, digest, 32, FALSE);
340    FX_BYTE iv[16];
341    FXSYS_memset32(iv, 0, 16);
342    CRYPT_AESSetIV(aes, iv);
343    CRYPT_AESDecrypt(aes, key, ekey, 32);
344    CRYPT_AESSetKey(aes, 16, key, 32, FALSE);
345    CRYPT_AESSetIV(aes, iv);
346    CFX_ByteString perms = m_pEncryptDict->GetString(FX_BSTRC("Perms"));
347    if (perms.IsEmpty()) {
348        return FALSE;
349    }
350    FX_BYTE perms_buf[16];
351    FXSYS_memset32(perms_buf, 0, sizeof(perms_buf));
352    FX_DWORD copy_len = sizeof(perms_buf);
353    if (copy_len > (FX_DWORD)perms.GetLength()) {
354        copy_len = perms.GetLength();
355    }
356    FXSYS_memcpy32(perms_buf, (FX_LPCBYTE)perms, copy_len);
357    FX_BYTE buf[16];
358    CRYPT_AESDecrypt(aes, buf, perms_buf, 16);
359    FX_Free(aes);
360    if (buf[9] != 'a' || buf[10] != 'd' || buf[11] != 'b') {
361        return FALSE;
362    }
363    if (FXDWORD_GET_LSBFIRST(buf) != m_Permissions) {
364        return FALSE;
365    }
366    if ((buf[8] == 'T' && !IsMetadataEncrypted()) || (buf[8] == 'F' && IsMetadataEncrypted())) {
367        return FALSE;
368    }
369    return TRUE;
370}
371int CPDF_StandardSecurityHandler::CheckPassword(FX_LPCBYTE password, FX_DWORD pass_size, FX_BOOL bOwner, FX_LPBYTE key)
372{
373    return CheckPassword(password, pass_size, bOwner, key, m_KeyLen);
374}
375int CPDF_StandardSecurityHandler::CheckPassword(FX_LPCBYTE password, FX_DWORD size, FX_BOOL bOwner, FX_LPBYTE key, FX_INT32 key_len)
376{
377    if (m_Revision >= 5) {
378        return AES256_CheckPassword(password, size, bOwner, key);
379    }
380    FX_BYTE keybuf[32];
381    if (key == NULL) {
382        key = keybuf;
383    }
384    if (bOwner) {
385        return CheckOwnerPassword(password, size, key, key_len);
386    }
387    return CheckUserPassword(password, size, FALSE, key, key_len) || CheckUserPassword(password, size, TRUE, key, key_len);
388}
389FX_BOOL CPDF_StandardSecurityHandler::CheckUserPassword(FX_LPCBYTE password, FX_DWORD pass_size,
390        FX_BOOL bIgnoreEncryptMeta, FX_LPBYTE key, FX_INT32 key_len)
391{
392    CalcEncryptKey(m_pEncryptDict, password, pass_size, key, key_len, bIgnoreEncryptMeta,
393                   m_pParser->GetIDArray());
394    CFX_ByteString ukey = m_pEncryptDict->GetString(FX_BSTRC("U"));
395    if (ukey.GetLength() < 16) {
396        return FALSE;
397    }
398    FX_BYTE ukeybuf[32];
399    if (m_Revision == 2) {
400        FXSYS_memcpy32(ukeybuf, defpasscode, 32);
401        CRYPT_ArcFourCryptBlock(ukeybuf, 32, key, key_len);
402    } else {
403        FX_BYTE test[32], tmpkey[32];
404        FX_DWORD copy_len = sizeof(test);
405        if (copy_len > (FX_DWORD)ukey.GetLength()) {
406            copy_len = ukey.GetLength();
407        }
408        FXSYS_memset32(test, 0, sizeof(test));
409        FXSYS_memcpy32(test, (FX_LPCSTR)ukey, copy_len);
410        for (int i = 19; i >= 0; i --) {
411            for (int j = 0; j < key_len; j ++) {
412                tmpkey[j] = key[j] ^ i;
413            }
414            CRYPT_ArcFourCryptBlock(test, 32, tmpkey, key_len);
415        }
416        FX_BYTE md5[100];
417        CRYPT_MD5Start(md5);
418        CRYPT_MD5Update(md5, defpasscode, 32);
419        CPDF_Array* pIdArray = m_pParser->GetIDArray();
420        if (pIdArray) {
421            CFX_ByteString id = pIdArray->GetString(0);
422            CRYPT_MD5Update(md5, (FX_LPBYTE)(FX_LPCSTR)id, id.GetLength());
423        }
424        CRYPT_MD5Finish(md5, ukeybuf);
425        return FXSYS_memcmp32(test, ukeybuf, 16) == 0;
426    }
427    if (FXSYS_memcmp32((FX_LPVOID)(FX_LPCSTR)ukey, ukeybuf, 16) == 0) {
428        return TRUE;
429    }
430    return FALSE;
431}
432CFX_ByteString CPDF_StandardSecurityHandler::GetUserPassword(FX_LPCBYTE owner_pass, FX_DWORD pass_size)
433{
434    return GetUserPassword(owner_pass, pass_size, m_KeyLen);
435}
436CFX_ByteString CPDF_StandardSecurityHandler::GetUserPassword(FX_LPCBYTE owner_pass, FX_DWORD pass_size, FX_INT32 key_len)
437{
438    CFX_ByteString okey = m_pEncryptDict->GetString(FX_BSTRC("O"));
439    FX_BYTE passcode[32];
440    FX_DWORD i;
441    for (i = 0; i < 32; i ++) {
442        passcode[i] = i < pass_size ? owner_pass[i] : defpasscode[i - pass_size];
443    }
444    FX_BYTE digest[16];
445    CRYPT_MD5Generate(passcode, 32, digest);
446    if (m_Revision >= 3) {
447        for (int i = 0; i < 50; i ++) {
448            CRYPT_MD5Generate(digest, 16, digest);
449        }
450    }
451    FX_BYTE enckey[32];
452    FXSYS_memset32(enckey, 0, sizeof(enckey));
453    FX_DWORD copy_len = key_len;
454    if (copy_len > sizeof(digest)) {
455        copy_len = sizeof(digest);
456    }
457    FXSYS_memcpy32(enckey, digest, copy_len);
458    int okeylen = okey.GetLength();
459    if (okeylen > 32) {
460        okeylen = 32;
461    }
462    FX_BYTE okeybuf[64];
463    FXSYS_memcpy32(okeybuf, (FX_LPCSTR)okey, okeylen);
464    if (m_Revision == 2) {
465        CRYPT_ArcFourCryptBlock(okeybuf, okeylen, enckey, key_len);
466    } else {
467        for (int i = 19; i >= 0; i --) {
468            FX_BYTE tempkey[32];
469            for (int j = 0; j < m_KeyLen; j ++) {
470                tempkey[j] = enckey[j] ^ i;
471            }
472            CRYPT_ArcFourCryptBlock(okeybuf, okeylen, tempkey, key_len);
473        }
474    }
475    int len = 32;
476    while (len && defpasscode[len - 1] == okeybuf[len - 1]) {
477        len --;
478    }
479    return CFX_ByteString(okeybuf, len);
480}
481FX_BOOL CPDF_StandardSecurityHandler::CheckOwnerPassword(FX_LPCBYTE password, FX_DWORD pass_size,
482        FX_LPBYTE key, FX_INT32 key_len)
483{
484    CFX_ByteString user_pass = GetUserPassword(password, pass_size, key_len);
485    if (CheckUserPassword(user_pass, user_pass.GetLength(), FALSE, key, key_len)) {
486        return TRUE;
487    }
488    return CheckUserPassword(user_pass, user_pass.GetLength(), TRUE, key, key_len);
489}
490FX_BOOL CPDF_StandardSecurityHandler::IsMetadataEncrypted()
491{
492    return m_pEncryptDict->GetBoolean(FX_BSTRC("EncryptMetadata"), TRUE);
493}
494CPDF_SecurityHandler* FPDF_CreateStandardSecurityHandler()
495{
496    return FX_NEW CPDF_StandardSecurityHandler;
497}
498void CPDF_StandardSecurityHandler::OnCreate(CPDF_Dictionary* pEncryptDict, CPDF_Array* pIdArray,
499        FX_LPCBYTE user_pass, FX_DWORD user_size,
500        FX_LPCBYTE owner_pass, FX_DWORD owner_size, FX_BOOL bDefault, FX_DWORD type)
501{
502    int cipher = 0, key_len = 0;
503    if (!LoadDict(pEncryptDict, type, cipher, key_len)) {
504        return;
505    }
506    if (bDefault && (owner_pass == NULL || owner_size == 0)) {
507        owner_pass = user_pass;
508        owner_size = user_size;
509    }
510    if (m_Revision >= 5) {
511        int t = (int)time(NULL);
512        FX_BYTE sha[128];
513        CRYPT_SHA256Start(sha);
514        CRYPT_SHA256Update(sha, (FX_BYTE*)&t, sizeof t);
515        CRYPT_SHA256Update(sha, m_EncryptKey, 32);
516        CRYPT_SHA256Update(sha, (FX_BYTE*)"there", 5);
517        CRYPT_SHA256Finish(sha, m_EncryptKey);
518        AES256_SetPassword(pEncryptDict, user_pass, user_size, FALSE, m_EncryptKey);
519        if (bDefault) {
520            AES256_SetPassword(pEncryptDict, owner_pass, owner_size, TRUE, m_EncryptKey);
521            AES256_SetPerms(pEncryptDict, m_Permissions, pEncryptDict->GetBoolean(FX_BSTRC("EncryptMetadata"), TRUE), m_EncryptKey);
522        }
523        return;
524    }
525    if (bDefault) {
526        FX_BYTE passcode[32];
527        FX_DWORD i;
528        for (i = 0; i < 32; i ++) {
529            passcode[i] = i < owner_size ? owner_pass[i] : defpasscode[i - owner_size];
530        }
531        FX_BYTE digest[16];
532        CRYPT_MD5Generate(passcode, 32, digest);
533        if (m_Revision >= 3) {
534            for (int i = 0; i < 50; i ++) {
535                CRYPT_MD5Generate(digest, 16, digest);
536            }
537        }
538        FX_BYTE enckey[32];
539        FXSYS_memcpy32(enckey, digest, key_len);
540        for (i = 0; i < 32; i ++) {
541            passcode[i] = i < user_size ? user_pass[i] : defpasscode[i - user_size];
542        }
543        CRYPT_ArcFourCryptBlock(passcode, 32, enckey, key_len);
544        FX_BYTE tempkey[32];
545        if (m_Revision >= 3) {
546            for (i = 1; i <= 19; i ++) {
547                for (int j = 0; j < key_len; j ++) {
548                    tempkey[j] = enckey[j] ^ (FX_BYTE)i;
549                }
550                CRYPT_ArcFourCryptBlock(passcode, 32, tempkey, key_len);
551            }
552        }
553        pEncryptDict->SetAtString(FX_BSTRC("O"), CFX_ByteString(passcode, 32));
554    }
555    CalcEncryptKey(m_pEncryptDict, (FX_LPBYTE)user_pass, user_size, m_EncryptKey, key_len, FALSE, pIdArray);
556    if (m_Revision < 3) {
557        FX_BYTE tempbuf[32];
558        FXSYS_memcpy32(tempbuf, defpasscode, 32);
559        CRYPT_ArcFourCryptBlock(tempbuf, 32, m_EncryptKey, key_len);
560        pEncryptDict->SetAtString(FX_BSTRC("U"), CFX_ByteString(tempbuf, 32));
561    } else {
562        FX_BYTE md5[100];
563        CRYPT_MD5Start(md5);
564        CRYPT_MD5Update(md5, defpasscode, 32);
565        if (pIdArray) {
566            CFX_ByteString id = pIdArray->GetString(0);
567            CRYPT_MD5Update(md5, (FX_LPBYTE)(FX_LPCSTR)id, id.GetLength());
568        }
569        FX_BYTE digest[32];
570        CRYPT_MD5Finish(md5, digest);
571        CRYPT_ArcFourCryptBlock(digest, 16, m_EncryptKey, key_len);
572        FX_BYTE tempkey[32];
573        for (int i = 1; i <= 19; i ++) {
574            for (int j = 0; j < key_len; j ++) {
575                tempkey[j] = m_EncryptKey[j] ^ (FX_BYTE)i;
576            }
577            CRYPT_ArcFourCryptBlock(digest, 16, tempkey, key_len);
578        }
579        CRYPT_MD5Generate(digest, 16, digest + 16);
580        pEncryptDict->SetAtString(FX_BSTRC("U"), CFX_ByteString(digest, 32));
581    }
582}
583void CPDF_StandardSecurityHandler::OnCreate(CPDF_Dictionary* pEncryptDict, CPDF_Array* pIdArray,
584        FX_LPCBYTE user_pass, FX_DWORD user_size,
585        FX_LPCBYTE owner_pass, FX_DWORD owner_size, FX_DWORD type)
586{
587    OnCreate(pEncryptDict, pIdArray, user_pass, user_size, owner_pass, owner_size, TRUE, type);
588}
589void CPDF_StandardSecurityHandler::OnCreate(CPDF_Dictionary* pEncryptDict, CPDF_Array* pIdArray, FX_LPCBYTE user_pass, FX_DWORD user_size, FX_DWORD type)
590{
591    OnCreate(pEncryptDict, pIdArray, user_pass, user_size, NULL, 0, FALSE, type);
592}
593void CPDF_StandardSecurityHandler::AES256_SetPassword(CPDF_Dictionary* pEncryptDict, FX_LPCBYTE password, FX_DWORD size, FX_BOOL bOwner, FX_LPCBYTE key)
594{
595    FX_BYTE sha[128];
596    CRYPT_SHA1Start(sha);
597    CRYPT_SHA1Update(sha, key, 32);
598    CRYPT_SHA1Update(sha, (FX_BYTE*)"hello", 5);
599    FX_BYTE digest[20];
600    CRYPT_SHA1Finish(sha, digest);
601    CFX_ByteString ukey = pEncryptDict->GetString(FX_BSTRC("U"));
602    FX_BYTE digest1[48];
603    if (m_Revision >= 6) {
604        Revision6_Hash(password, size, digest, (bOwner ? (FX_LPCBYTE)ukey : NULL), digest1);
605    } else {
606        CRYPT_SHA256Start(sha);
607        CRYPT_SHA256Update(sha, password, size);
608        CRYPT_SHA256Update(sha, digest, 8);
609        if (bOwner) {
610            CRYPT_SHA256Update(sha, ukey, ukey.GetLength());
611        }
612        CRYPT_SHA256Finish(sha, digest1);
613    }
614    FXSYS_memcpy32(digest1 + 32, digest, 16);
615    pEncryptDict->SetAtString(bOwner ? FX_BSTRC("O") : FX_BSTRC("U"), CFX_ByteString(digest1, 48));
616    if (m_Revision >= 6) {
617        Revision6_Hash(password, size, digest + 8, (bOwner ? (FX_LPCBYTE)ukey : NULL), digest1);
618    } else {
619        CRYPT_SHA256Start(sha);
620        CRYPT_SHA256Update(sha, password, size);
621        CRYPT_SHA256Update(sha, digest + 8, 8);
622        if (bOwner) {
623            CRYPT_SHA256Update(sha, ukey, ukey.GetLength());
624        }
625        CRYPT_SHA256Finish(sha, digest1);
626    }
627    FX_BYTE* aes = FX_Alloc(FX_BYTE, 2048);
628    CRYPT_AESSetKey(aes, 16, digest1, 32, TRUE);
629    FX_BYTE iv[16];
630    FXSYS_memset32(iv, 0, 16);
631    CRYPT_AESSetIV(aes, iv);
632    CRYPT_AESEncrypt(aes, digest1, key, 32);
633    FX_Free(aes);
634    pEncryptDict->SetAtString(bOwner ? FX_BSTRC("OE") : FX_BSTRC("UE"), CFX_ByteString(digest1, 32));
635}
636void CPDF_StandardSecurityHandler::AES256_SetPerms(CPDF_Dictionary* pEncryptDict, FX_DWORD permissions,
637        FX_BOOL bEncryptMetadata, FX_LPCBYTE key)
638{
639    FX_BYTE buf[16];
640    buf[0] = (FX_BYTE)permissions;
641    buf[1] = (FX_BYTE)(permissions >> 8);
642    buf[2] = (FX_BYTE)(permissions >> 16);
643    buf[3] = (FX_BYTE)(permissions >> 24);
644    buf[4] = 0xff;
645    buf[5] = 0xff;
646    buf[6] = 0xff;
647    buf[7] = 0xff;
648    buf[8] = bEncryptMetadata ? 'T' : 'F';
649    buf[9] = 'a';
650    buf[10] = 'd';
651    buf[11] = 'b';
652    FX_BYTE* aes = FX_Alloc(FX_BYTE, 2048);
653    CRYPT_AESSetKey(aes, 16, key, 32, TRUE);
654    FX_BYTE iv[16], buf1[16];
655    FXSYS_memset32(iv, 0, 16);
656    CRYPT_AESSetIV(aes, iv);
657    CRYPT_AESEncrypt(aes, buf1, buf, 16);
658    FX_Free(aes);
659    pEncryptDict->SetAtString(FX_BSTRC("Perms"), CFX_ByteString(buf1, 16));
660}
661void CPDF_StandardCryptoHandler::CryptBlock(FX_BOOL bEncrypt, FX_DWORD objnum, FX_DWORD gennum, FX_LPCBYTE src_buf, FX_DWORD src_size,
662        FX_LPBYTE dest_buf, FX_DWORD& dest_size)
663{
664    if (m_Cipher == FXCIPHER_NONE) {
665        FXSYS_memcpy32(dest_buf, src_buf, src_size);
666        return;
667    }
668    FX_BYTE realkey[16];
669    int realkeylen = 16;
670    if (m_Cipher != FXCIPHER_AES || m_KeyLen != 32) {
671        FX_BYTE key1[32];
672        FXSYS_memcpy32(key1, m_EncryptKey, m_KeyLen);
673        key1[m_KeyLen + 0] = (FX_BYTE)objnum;
674        key1[m_KeyLen + 1] = (FX_BYTE)(objnum >> 8);
675        key1[m_KeyLen + 2] = (FX_BYTE)(objnum >> 16);
676        key1[m_KeyLen + 3] = (FX_BYTE)gennum;
677        key1[m_KeyLen + 4] = (FX_BYTE)(gennum >> 8);
678        FXSYS_memcpy32(key1 + m_KeyLen, &objnum, 3);
679        FXSYS_memcpy32(key1 + m_KeyLen + 3, &gennum, 2);
680        if (m_Cipher == FXCIPHER_AES) {
681            FXSYS_memcpy32(key1 + m_KeyLen + 5, "sAlT", 4);
682        }
683        CRYPT_MD5Generate(key1, m_Cipher == FXCIPHER_AES ? m_KeyLen + 9 : m_KeyLen + 5, realkey);
684        realkeylen = m_KeyLen + 5;
685        if (realkeylen > 16) {
686            realkeylen = 16;
687        }
688    }
689    if (m_Cipher == FXCIPHER_AES) {
690        CRYPT_AESSetKey(m_pAESContext, 16, m_KeyLen == 32 ? m_EncryptKey : realkey, m_KeyLen, bEncrypt);
691        if (bEncrypt) {
692            FX_BYTE iv[16];
693            for (int i = 0; i < 16; i ++) {
694                iv[i] = (FX_BYTE)rand();
695            }
696            CRYPT_AESSetIV(m_pAESContext, iv);
697            FXSYS_memcpy32(dest_buf, iv, 16);
698            int nblocks = src_size / 16;
699            CRYPT_AESEncrypt(m_pAESContext, dest_buf + 16, src_buf, nblocks * 16);
700            FX_BYTE padding[16];
701            FXSYS_memcpy32(padding, src_buf + nblocks * 16, src_size % 16);
702            FXSYS_memset8(padding + src_size % 16, 16 - src_size % 16, 16 - src_size % 16);
703            CRYPT_AESEncrypt(m_pAESContext, dest_buf + nblocks * 16 + 16, padding, 16);
704            dest_size = 32 + nblocks * 16;
705        } else {
706            CRYPT_AESSetIV(m_pAESContext, src_buf);
707            CRYPT_AESDecrypt(m_pAESContext, dest_buf, src_buf + 16, src_size - 16);
708            dest_size = src_size - 16;
709            dest_size -= dest_buf[dest_size - 1];
710        }
711    } else {
712        ASSERT(dest_size == src_size);
713        if (dest_buf != src_buf) {
714            FXSYS_memcpy32(dest_buf, src_buf, src_size);
715        }
716        CRYPT_ArcFourCryptBlock(dest_buf, dest_size, realkey, realkeylen);
717    }
718}
719typedef struct _AESCryptContext {
720    FX_BYTE		m_Context[2048];
721    FX_BOOL		m_bIV;
722    FX_BYTE		m_Block[16];
723    FX_DWORD	m_BlockOffset;
724} AESCryptContext;
725FX_LPVOID CPDF_StandardCryptoHandler::CryptStart(FX_DWORD objnum, FX_DWORD gennum, FX_BOOL bEncrypt)
726{
727    if (m_Cipher == FXCIPHER_NONE) {
728        return this;
729    }
730    if (m_Cipher == FXCIPHER_AES && m_KeyLen == 32) {
731        AESCryptContext* pContext = FX_Alloc(AESCryptContext, 1);
732        pContext->m_bIV = TRUE;
733        pContext->m_BlockOffset = 0;
734        CRYPT_AESSetKey(pContext->m_Context, 16, m_EncryptKey, 32, bEncrypt);
735        if (bEncrypt) {
736            for (int i = 0; i < 16; i ++) {
737                pContext->m_Block[i] = (FX_BYTE)rand();
738            }
739            CRYPT_AESSetIV(pContext->m_Context, pContext->m_Block);
740        }
741        return pContext;
742    }
743    FX_BYTE key1[48];
744    FXSYS_memcpy32(key1, m_EncryptKey, m_KeyLen);
745    FXSYS_memcpy32(key1 + m_KeyLen, &objnum, 3);
746    FXSYS_memcpy32(key1 + m_KeyLen + 3, &gennum, 2);
747    if (m_Cipher == FXCIPHER_AES) {
748        FXSYS_memcpy32(key1 + m_KeyLen + 5, "sAlT", 4);
749    }
750    FX_BYTE realkey[16];
751    CRYPT_MD5Generate(key1, m_Cipher == FXCIPHER_AES ? m_KeyLen + 9 : m_KeyLen + 5, realkey);
752    int realkeylen = m_KeyLen + 5;
753    if (realkeylen > 16) {
754        realkeylen = 16;
755    }
756    if (m_Cipher == FXCIPHER_AES) {
757        AESCryptContext* pContext = FX_Alloc(AESCryptContext, 1);
758        pContext->m_bIV = TRUE;
759        pContext->m_BlockOffset = 0;
760        CRYPT_AESSetKey(pContext->m_Context, 16, realkey, 16, bEncrypt);
761        if (bEncrypt) {
762            for (int i = 0; i < 16; i ++) {
763                pContext->m_Block[i] = (FX_BYTE)rand();
764            }
765            CRYPT_AESSetIV(pContext->m_Context, pContext->m_Block);
766        }
767        return pContext;
768    }
769    void* pContext = FX_Alloc(FX_BYTE, 1040);
770    CRYPT_ArcFourSetup(pContext, realkey, realkeylen);
771    return pContext;
772}
773FX_BOOL CPDF_StandardCryptoHandler::CryptStream(FX_LPVOID context, FX_LPCBYTE src_buf, FX_DWORD src_size, CFX_BinaryBuf& dest_buf, FX_BOOL bEncrypt)
774{
775    if (!context) {
776        return FALSE;
777    }
778    if (m_Cipher == FXCIPHER_NONE) {
779        dest_buf.AppendBlock(src_buf, src_size);
780        return TRUE;
781    }
782    if (m_Cipher == FXCIPHER_RC4) {
783        int old_size = dest_buf.GetSize();
784        dest_buf.AppendBlock(src_buf, src_size);
785        CRYPT_ArcFourCrypt(context, dest_buf.GetBuffer() + old_size, src_size);
786        return TRUE;
787    }
788    AESCryptContext* pContext = (AESCryptContext*)context;
789    if (pContext->m_bIV && bEncrypt) {
790        dest_buf.AppendBlock(pContext->m_Block, 16);
791        pContext->m_bIV = FALSE;
792    }
793    FX_DWORD src_off = 0;
794    FX_DWORD src_left = src_size;
795    while (1) {
796        FX_DWORD copy_size = 16 - pContext->m_BlockOffset;
797        if (copy_size > src_left) {
798            copy_size = src_left;
799        }
800        FXSYS_memcpy32(pContext->m_Block + pContext->m_BlockOffset, src_buf + src_off, copy_size);
801        src_off += copy_size;
802        src_left -= copy_size;
803        pContext->m_BlockOffset += copy_size;
804        if (pContext->m_BlockOffset == 16) {
805            if (!bEncrypt && pContext->m_bIV) {
806                CRYPT_AESSetIV(pContext->m_Context, pContext->m_Block);
807                pContext->m_bIV = FALSE;
808                pContext->m_BlockOffset = 0;
809            } else if (src_off < src_size) {
810                FX_BYTE block_buf[16];
811                if (bEncrypt) {
812                    CRYPT_AESEncrypt(pContext->m_Context, block_buf, pContext->m_Block, 16);
813                } else {
814                    CRYPT_AESDecrypt(pContext->m_Context, block_buf, pContext->m_Block, 16);
815                }
816                dest_buf.AppendBlock(block_buf, 16);
817                pContext->m_BlockOffset = 0;
818            }
819        }
820        if (!src_left) {
821            break;
822        }
823    }
824    return TRUE;
825}
826FX_BOOL CPDF_StandardCryptoHandler::CryptFinish(FX_LPVOID context, CFX_BinaryBuf& dest_buf, FX_BOOL bEncrypt)
827{
828    if (!context) {
829        return FALSE;
830    }
831    if (m_Cipher == FXCIPHER_NONE) {
832        return TRUE;
833    }
834    if (m_Cipher == FXCIPHER_RC4) {
835        FX_Free(context);
836        return TRUE;
837    }
838    AESCryptContext* pContext = (AESCryptContext*)context;
839    if (bEncrypt) {
840        FX_BYTE block_buf[16];
841        if (pContext->m_BlockOffset == 16) {
842            CRYPT_AESEncrypt(pContext->m_Context, block_buf, pContext->m_Block, 16);
843            dest_buf.AppendBlock(block_buf, 16);
844            pContext->m_BlockOffset = 0;
845        }
846        FXSYS_memset8(pContext->m_Block + pContext->m_BlockOffset, (FX_BYTE)(16 - pContext->m_BlockOffset), 16 - pContext->m_BlockOffset);
847        CRYPT_AESEncrypt(pContext->m_Context, block_buf, pContext->m_Block, 16);
848        dest_buf.AppendBlock(block_buf, 16);
849    } else if (pContext->m_BlockOffset == 16) {
850        FX_BYTE block_buf[16];
851        CRYPT_AESDecrypt(pContext->m_Context, block_buf, pContext->m_Block, 16);
852        if (block_buf[15] <= 16) {
853            dest_buf.AppendBlock(block_buf, 16 - block_buf[15]);
854        }
855    }
856    FX_Free(pContext);
857    return TRUE;
858}
859FX_LPVOID CPDF_StandardCryptoHandler::DecryptStart(FX_DWORD objnum, FX_DWORD gennum)
860{
861    return CryptStart(objnum, gennum, FALSE);
862}
863FX_DWORD CPDF_StandardCryptoHandler::DecryptGetSize(FX_DWORD src_size)
864{
865    return m_Cipher == FXCIPHER_AES ? src_size - 16 : src_size;
866}
867FX_BOOL CPDF_StandardCryptoHandler::Init(CPDF_Dictionary* pEncryptDict, CPDF_SecurityHandler* pSecurityHandler)
868{
869    FX_LPCBYTE key;
870    if (!pSecurityHandler->GetCryptInfo(m_Cipher, key, m_KeyLen)) {
871        return FALSE;
872    }
873    if (m_KeyLen > 32 || m_KeyLen < 0) {
874        return FALSE;
875    }
876    if (m_Cipher != FXCIPHER_NONE) {
877        FXSYS_memcpy32(m_EncryptKey, key, m_KeyLen);
878    }
879    if (m_Cipher == FXCIPHER_AES) {
880        m_pAESContext = FX_Alloc(FX_BYTE, 2048);
881    }
882    return TRUE;
883}
884FX_BOOL CPDF_StandardCryptoHandler::Init(int cipher, FX_LPCBYTE key, int keylen)
885{
886    if (cipher == FXCIPHER_AES) {
887        switch(keylen) {
888            case 16:
889            case 24:
890            case 32:
891                break;
892            default:
893                return FALSE;
894        }
895    } else if (cipher == FXCIPHER_AES2) {
896        if (keylen != 32) {
897            return FALSE;
898        }
899    } else if (cipher == FXCIPHER_RC4) {
900        if (keylen < 5 || keylen > 16) {
901            return FALSE;
902        }
903    } else {
904        if (keylen > 32) {
905            keylen = 32;
906        }
907    }
908    m_Cipher = cipher;
909    m_KeyLen = keylen;
910    FXSYS_memcpy32(m_EncryptKey, key, keylen);
911    if (m_Cipher == FXCIPHER_AES) {
912        m_pAESContext = FX_Alloc(FX_BYTE, 2048);
913    }
914    return TRUE;
915}
916FX_BOOL CPDF_StandardCryptoHandler::DecryptStream(FX_LPVOID context, FX_LPCBYTE src_buf, FX_DWORD src_size,
917        CFX_BinaryBuf& dest_buf)
918{
919    return CryptStream(context, src_buf, src_size, dest_buf, FALSE);
920}
921FX_BOOL CPDF_StandardCryptoHandler::DecryptFinish(FX_LPVOID context, CFX_BinaryBuf& dest_buf)
922{
923    return CryptFinish(context, dest_buf, FALSE);
924}
925FX_DWORD CPDF_StandardCryptoHandler::EncryptGetSize(FX_DWORD objnum, FX_DWORD version, FX_LPCBYTE src_buf, FX_DWORD src_size)
926{
927    if (m_Cipher == FXCIPHER_AES) {
928        return src_size + 32;
929    }
930    return src_size;
931}
932FX_BOOL CPDF_StandardCryptoHandler::EncryptContent(FX_DWORD objnum, FX_DWORD gennum, FX_LPCBYTE src_buf, FX_DWORD src_size,
933        FX_LPBYTE dest_buf, FX_DWORD& dest_size)
934{
935    CryptBlock(TRUE, objnum, gennum, src_buf, src_size, dest_buf, dest_size);
936    return TRUE;
937}
938void CPDF_CryptoHandler::Decrypt(FX_DWORD objnum, FX_DWORD gennum, CFX_ByteString& str)
939{
940    CFX_BinaryBuf dest_buf;
941    FX_LPVOID context = DecryptStart(objnum, gennum);
942    DecryptStream(context, (FX_LPCBYTE)str, str.GetLength(), dest_buf);
943    DecryptFinish(context, dest_buf);
944    str = dest_buf;
945}
946CPDF_StandardCryptoHandler::CPDF_StandardCryptoHandler()
947{
948    m_pAESContext = NULL;
949    m_Cipher = FXCIPHER_NONE;
950    m_KeyLen = 0;
951}
952CPDF_StandardCryptoHandler::~CPDF_StandardCryptoHandler()
953{
954    if (m_pAESContext) {
955        FX_Free(m_pAESContext);
956    }
957}
958