Home | History | Annotate | Download | only in fpdf_parser
      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};
     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 }
     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;
     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 }
     78 CPDF_StandardSecurityHandler::~CPDF_StandardSecurityHandler() {}
     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 }
     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 }
    106 FX_DWORD CPDF_StandardSecurityHandler::GetPermissions() {
    107   return m_Permissions;
    108 }
    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 }
    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 }
    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 }
    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   }
    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 }
    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 }
    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 }
    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 }
    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 }
    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 }
    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 }
    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 }
    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 }
    526 FX_BOOL CPDF_StandardSecurityHandler::IsMetadataEncrypted() {
    527   return m_pEncryptDict->GetBoolean("EncryptMetadata", TRUE);
    528 }
    529 CPDF_SecurityHandler* FPDF_CreateStandardSecurityHandler() {
    530   return new CPDF_StandardSecurityHandler;
    531 }
    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 }
    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 }
    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 }
    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 }
    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 }
    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;
    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 }
    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 }
    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 }
    936 void* CPDF_StandardCryptoHandler::DecryptStart(FX_DWORD objnum,
    937                                                FX_DWORD gennum) {
    938   return CryptStart(objnum, gennum, FALSE);
    939 }
    940 FX_DWORD CPDF_StandardCryptoHandler::DecryptGetSize(FX_DWORD src_size) {
    941   return m_Cipher == FXCIPHER_AES ? src_size - 16 : src_size;
    942 }
    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 }
    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 }
    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 }
   1000 FX_BOOL CPDF_StandardCryptoHandler::DecryptFinish(void* context,
   1001                                                   CFX_BinaryBuf& dest_buf) {
   1002   return CryptFinish(context, dest_buf, FALSE);
   1003 }
   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 }
   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 }
   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 }
   1031 CPDF_StandardCryptoHandler::CPDF_StandardCryptoHandler() {
   1032   m_pAESContext = NULL;
   1033   m_Cipher = FXCIPHER_NONE;
   1034   m_KeyLen = 0;
   1035 }
   1036 CPDF_StandardCryptoHandler::~CPDF_StandardCryptoHandler() {
   1037   FX_Free(m_pAESContext);
   1038 }
   1039