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