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