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/fpdfapi/parser/cpdf_security_handler.h" 8 9 #include <time.h> 10 11 #include <algorithm> 12 #include <utility> 13 #include <vector> 14 15 #include "core/fdrm/crypto/fx_crypt.h" 16 #include "core/fpdfapi/parser/cpdf_array.h" 17 #include "core/fpdfapi/parser/cpdf_crypto_handler.h" 18 #include "core/fpdfapi/parser/cpdf_dictionary.h" 19 #include "core/fpdfapi/parser/cpdf_object.h" 20 #include "core/fpdfapi/parser/cpdf_parser.h" 21 #include "core/fpdfapi/parser/cpdf_string.h" 22 23 namespace { 24 25 const uint8_t defpasscode[32] = { 26 0x28, 0xbf, 0x4e, 0x5e, 0x4e, 0x75, 0x8a, 0x41, 0x64, 0x00, 0x4e, 27 0x56, 0xff, 0xfa, 0x01, 0x08, 0x2e, 0x2e, 0x00, 0xb6, 0xd0, 0x68, 28 0x3e, 0x80, 0x2f, 0x0c, 0xa9, 0xfe, 0x64, 0x53, 0x69, 0x7a}; 29 30 void CalcEncryptKey(CPDF_Dictionary* pEncrypt, 31 const uint8_t* password, 32 uint32_t pass_size, 33 uint8_t* key, 34 int keylen, 35 bool bIgnoreMeta, 36 CPDF_Array* pIdArray) { 37 int revision = pEncrypt->GetIntegerFor("R"); 38 uint8_t passcode[32]; 39 for (uint32_t i = 0; i < 32; i++) { 40 passcode[i] = i < pass_size ? password[i] : defpasscode[i - pass_size]; 41 } 42 CRYPT_md5_context md5; 43 CRYPT_MD5Start(&md5); 44 CRYPT_MD5Update(&md5, passcode, 32); 45 CFX_ByteString okey = pEncrypt->GetStringFor("O"); 46 CRYPT_MD5Update(&md5, (uint8_t*)okey.c_str(), okey.GetLength()); 47 uint32_t perm = pEncrypt->GetIntegerFor("P"); 48 CRYPT_MD5Update(&md5, (uint8_t*)&perm, 4); 49 if (pIdArray) { 50 CFX_ByteString id = pIdArray->GetStringAt(0); 51 CRYPT_MD5Update(&md5, (uint8_t*)id.c_str(), id.GetLength()); 52 } 53 if (!bIgnoreMeta && revision >= 3 && 54 !pEncrypt->GetIntegerFor("EncryptMetadata", 1)) { 55 uint32_t tag = (uint32_t)-1; 56 CRYPT_MD5Update(&md5, (uint8_t*)&tag, 4); 57 } 58 uint8_t digest[16]; 59 CRYPT_MD5Finish(&md5, digest); 60 uint32_t copy_len = keylen; 61 if (copy_len > sizeof(digest)) { 62 copy_len = sizeof(digest); 63 } 64 if (revision >= 3) { 65 for (int i = 0; i < 50; i++) { 66 CRYPT_MD5Generate(digest, copy_len, digest); 67 } 68 } 69 FXSYS_memset(key, 0, keylen); 70 FXSYS_memcpy(key, digest, copy_len); 71 } 72 73 } // namespace 74 75 CPDF_SecurityHandler::CPDF_SecurityHandler() 76 : m_Version(0), 77 m_Revision(0), 78 m_pParser(nullptr), 79 m_pEncryptDict(nullptr), 80 m_Permissions(0), 81 m_Cipher(FXCIPHER_NONE), 82 m_KeyLen(0), 83 m_bOwnerUnlocked(false) {} 84 85 CPDF_SecurityHandler::~CPDF_SecurityHandler() {} 86 87 CPDF_CryptoHandler* CPDF_SecurityHandler::CreateCryptoHandler() { 88 return new CPDF_CryptoHandler; 89 } 90 91 bool CPDF_SecurityHandler::OnInit(CPDF_Parser* pParser, 92 CPDF_Dictionary* pEncryptDict) { 93 m_pParser = pParser; 94 if (!LoadDict(pEncryptDict)) { 95 return false; 96 } 97 if (m_Cipher == FXCIPHER_NONE) { 98 return true; 99 } 100 return CheckSecurity(m_KeyLen); 101 } 102 103 bool CPDF_SecurityHandler::CheckSecurity(int32_t key_len) { 104 CFX_ByteString password = m_pParser->GetPassword(); 105 if (!password.IsEmpty() && 106 CheckPassword(password.raw_str(), password.GetLength(), true, 107 m_EncryptKey, key_len)) { 108 m_bOwnerUnlocked = true; 109 return true; 110 } 111 return CheckPassword(password.raw_str(), password.GetLength(), false, 112 m_EncryptKey, key_len); 113 } 114 115 uint32_t CPDF_SecurityHandler::GetPermissions() { 116 return m_bOwnerUnlocked ? 0xFFFFFFFF : m_Permissions; 117 } 118 119 static bool LoadCryptInfo(CPDF_Dictionary* pEncryptDict, 120 const CFX_ByteString& name, 121 int& cipher, 122 int& keylen) { 123 int Version = pEncryptDict->GetIntegerFor("V"); 124 cipher = FXCIPHER_RC4; 125 keylen = 0; 126 if (Version >= 4) { 127 CPDF_Dictionary* pCryptFilters = pEncryptDict->GetDictFor("CF"); 128 if (!pCryptFilters) { 129 return false; 130 } 131 if (name == "Identity") { 132 cipher = FXCIPHER_NONE; 133 } else { 134 CPDF_Dictionary* pDefFilter = pCryptFilters->GetDictFor(name); 135 if (!pDefFilter) { 136 return false; 137 } 138 int nKeyBits = 0; 139 if (Version == 4) { 140 nKeyBits = pDefFilter->GetIntegerFor("Length", 0); 141 if (nKeyBits == 0) { 142 nKeyBits = pEncryptDict->GetIntegerFor("Length", 128); 143 } 144 } else { 145 nKeyBits = pEncryptDict->GetIntegerFor("Length", 256); 146 } 147 if (nKeyBits < 40) { 148 nKeyBits *= 8; 149 } 150 keylen = nKeyBits / 8; 151 CFX_ByteString cipher_name = pDefFilter->GetStringFor("CFM"); 152 if (cipher_name == "AESV2" || cipher_name == "AESV3") { 153 cipher = FXCIPHER_AES; 154 } 155 } 156 } else { 157 keylen = Version > 1 ? pEncryptDict->GetIntegerFor("Length", 40) / 8 : 5; 158 } 159 if (keylen > 32 || keylen < 0) { 160 return false; 161 } 162 return true; 163 } 164 165 bool CPDF_SecurityHandler::LoadDict(CPDF_Dictionary* pEncryptDict) { 166 m_pEncryptDict = pEncryptDict; 167 m_Version = pEncryptDict->GetIntegerFor("V"); 168 m_Revision = pEncryptDict->GetIntegerFor("R"); 169 m_Permissions = pEncryptDict->GetIntegerFor("P", -1); 170 if (m_Version < 4) 171 return LoadCryptInfo(pEncryptDict, CFX_ByteString(), m_Cipher, m_KeyLen); 172 173 CFX_ByteString stmf_name = pEncryptDict->GetStringFor("StmF"); 174 CFX_ByteString strf_name = pEncryptDict->GetStringFor("StrF"); 175 if (stmf_name != strf_name) 176 return false; 177 178 return LoadCryptInfo(pEncryptDict, strf_name, m_Cipher, m_KeyLen); 179 } 180 181 bool CPDF_SecurityHandler::LoadDict(CPDF_Dictionary* pEncryptDict, 182 uint32_t type, 183 int& cipher, 184 int& key_len) { 185 m_pEncryptDict = pEncryptDict; 186 m_Version = pEncryptDict->GetIntegerFor("V"); 187 m_Revision = pEncryptDict->GetIntegerFor("R"); 188 m_Permissions = pEncryptDict->GetIntegerFor("P", -1); 189 190 CFX_ByteString strf_name; 191 CFX_ByteString stmf_name; 192 if (m_Version >= 4) { 193 stmf_name = pEncryptDict->GetStringFor("StmF"); 194 strf_name = pEncryptDict->GetStringFor("StrF"); 195 if (stmf_name != strf_name) 196 return false; 197 } 198 if (!LoadCryptInfo(pEncryptDict, strf_name, cipher, key_len)) 199 return false; 200 201 m_Cipher = cipher; 202 m_KeyLen = key_len; 203 return true; 204 } 205 206 bool CPDF_SecurityHandler::GetCryptInfo(int& cipher, 207 const uint8_t*& buffer, 208 int& keylen) { 209 cipher = m_Cipher; 210 buffer = m_EncryptKey; 211 keylen = m_KeyLen; 212 return true; 213 } 214 #define FX_GET_32WORD(n, b, i) \ 215 { \ 216 (n) = (uint32_t)( \ 217 ((uint64_t)(b)[(i)] << 24) | ((uint64_t)(b)[(i) + 1] << 16) | \ 218 ((uint64_t)(b)[(i) + 2] << 8) | ((uint64_t)(b)[(i) + 3])); \ 219 } 220 int BigOrder64BitsMod3(uint8_t* data) { 221 uint64_t ret = 0; 222 for (int i = 0; i < 4; ++i) { 223 uint32_t value; 224 FX_GET_32WORD(value, data, 4 * i); 225 ret <<= 32; 226 ret |= value; 227 ret %= 3; 228 } 229 return (int)ret; 230 } 231 232 void Revision6_Hash(const uint8_t* password, 233 uint32_t size, 234 const uint8_t* salt, 235 const uint8_t* vector, 236 uint8_t* hash) { 237 CRYPT_sha256_context sha; 238 CRYPT_SHA256Start(&sha); 239 CRYPT_SHA256Update(&sha, password, size); 240 CRYPT_SHA256Update(&sha, salt, 8); 241 if (vector) 242 CRYPT_SHA256Update(&sha, vector, 48); 243 244 uint8_t digest[32]; 245 CRYPT_SHA256Finish(&sha, digest); 246 247 CFX_ByteTextBuf buf; 248 uint8_t* input = digest; 249 uint8_t* key = input; 250 uint8_t* iv = input + 16; 251 uint8_t* E = buf.GetBuffer(); 252 int iBufLen = buf.GetLength(); 253 CFX_ByteTextBuf interDigest; 254 int i = 0; 255 int iBlockSize = 32; 256 uint8_t* aes = FX_Alloc(uint8_t, 2048); 257 while (i < 64 || i < E[iBufLen - 1] + 32) { 258 int iRoundSize = size + iBlockSize; 259 if (vector) { 260 iRoundSize += 48; 261 } 262 iBufLen = iRoundSize * 64; 263 buf.EstimateSize(iBufLen); 264 E = buf.GetBuffer(); 265 CFX_ByteTextBuf content; 266 for (int j = 0; j < 64; ++j) { 267 content.AppendBlock(password, size); 268 content.AppendBlock(input, iBlockSize); 269 if (vector) { 270 content.AppendBlock(vector, 48); 271 } 272 } 273 CRYPT_AESSetKey(aes, 16, key, 16, true); 274 CRYPT_AESSetIV(aes, iv); 275 CRYPT_AESEncrypt(aes, E, content.GetBuffer(), iBufLen); 276 int iHash = 0; 277 switch (BigOrder64BitsMod3(E)) { 278 case 0: 279 iHash = 0; 280 iBlockSize = 32; 281 break; 282 case 1: 283 iHash = 1; 284 iBlockSize = 48; 285 break; 286 default: 287 iHash = 2; 288 iBlockSize = 64; 289 break; 290 } 291 interDigest.EstimateSize(iBlockSize); 292 input = interDigest.GetBuffer(); 293 if (iHash == 0) { 294 CRYPT_SHA256Generate(E, iBufLen, input); 295 } else if (iHash == 1) { 296 CRYPT_SHA384Generate(E, iBufLen, input); 297 } else if (iHash == 2) { 298 CRYPT_SHA512Generate(E, iBufLen, input); 299 } 300 key = input; 301 iv = input + 16; 302 ++i; 303 } 304 FX_Free(aes); 305 if (hash) { 306 FXSYS_memcpy(hash, input, 32); 307 } 308 } 309 310 bool CPDF_SecurityHandler::AES256_CheckPassword(const uint8_t* password, 311 uint32_t size, 312 bool bOwner, 313 uint8_t* key) { 314 if (!m_pEncryptDict) 315 return false; 316 317 CFX_ByteString okey = m_pEncryptDict->GetStringFor("O"); 318 if (okey.GetLength() < 48) 319 return false; 320 321 CFX_ByteString ukey = m_pEncryptDict->GetStringFor("U"); 322 if (ukey.GetLength() < 48) 323 return false; 324 325 const uint8_t* pkey = bOwner ? okey.raw_str() : ukey.raw_str(); 326 CRYPT_sha256_context sha; 327 uint8_t digest[32]; 328 if (m_Revision >= 6) { 329 Revision6_Hash(password, size, (const uint8_t*)pkey + 32, 330 bOwner ? ukey.raw_str() : nullptr, digest); 331 } else { 332 CRYPT_SHA256Start(&sha); 333 CRYPT_SHA256Update(&sha, password, size); 334 CRYPT_SHA256Update(&sha, pkey + 32, 8); 335 if (bOwner) 336 CRYPT_SHA256Update(&sha, ukey.raw_str(), 48); 337 338 CRYPT_SHA256Finish(&sha, digest); 339 } 340 if (FXSYS_memcmp(digest, pkey, 32) != 0) 341 return false; 342 343 if (!key) 344 return true; 345 346 if (m_Revision >= 6) { 347 Revision6_Hash(password, size, (const uint8_t*)pkey + 40, 348 bOwner ? ukey.raw_str() : nullptr, digest); 349 } else { 350 CRYPT_SHA256Start(&sha); 351 CRYPT_SHA256Update(&sha, password, size); 352 CRYPT_SHA256Update(&sha, pkey + 40, 8); 353 if (bOwner) 354 CRYPT_SHA256Update(&sha, ukey.raw_str(), 48); 355 356 CRYPT_SHA256Finish(&sha, digest); 357 } 358 CFX_ByteString ekey = m_pEncryptDict 359 ? m_pEncryptDict->GetStringFor(bOwner ? "OE" : "UE") 360 : CFX_ByteString(); 361 if (ekey.GetLength() < 32) 362 return false; 363 364 std::vector<uint8_t> aes(2048); 365 CRYPT_AESSetKey(aes.data(), 16, digest, 32, false); 366 uint8_t iv[16]; 367 FXSYS_memset(iv, 0, 16); 368 CRYPT_AESSetIV(aes.data(), iv); 369 CRYPT_AESDecrypt(aes.data(), key, ekey.raw_str(), 32); 370 CRYPT_AESSetKey(aes.data(), 16, key, 32, false); 371 CRYPT_AESSetIV(aes.data(), iv); 372 CFX_ByteString perms = m_pEncryptDict->GetStringFor("Perms"); 373 if (perms.IsEmpty()) 374 return false; 375 376 uint8_t perms_buf[16]; 377 FXSYS_memset(perms_buf, 0, sizeof(perms_buf)); 378 size_t copy_len = 379 std::min(sizeof(perms_buf), static_cast<size_t>(perms.GetLength())); 380 FXSYS_memcpy(perms_buf, perms.raw_str(), copy_len); 381 uint8_t buf[16]; 382 CRYPT_AESDecrypt(aes.data(), buf, perms_buf, 16); 383 if (buf[9] != 'a' || buf[10] != 'd' || buf[11] != 'b') 384 return false; 385 386 if (FXDWORD_GET_LSBFIRST(buf) != m_Permissions) 387 return false; 388 389 // Relax this check as there appear to be some non-conforming documents 390 // in the wild. The value in the buffer is the truth; if it requires us 391 // to encrypt metadata, but the dictionary says otherwise, then we may 392 // have a tampered doc. Otherwise, give it a pass. 393 return buf[8] == 'F' || IsMetadataEncrypted(); 394 } 395 396 bool CPDF_SecurityHandler::CheckPassword(const uint8_t* password, 397 uint32_t size, 398 bool bOwner, 399 uint8_t* key, 400 int32_t key_len) { 401 if (m_Revision >= 5) 402 return AES256_CheckPassword(password, size, bOwner, key); 403 404 uint8_t keybuf[32]; 405 if (!key) 406 key = keybuf; 407 408 if (bOwner) 409 return CheckOwnerPassword(password, size, key, key_len); 410 411 return CheckUserPassword(password, size, false, key, key_len) || 412 CheckUserPassword(password, size, true, key, key_len); 413 } 414 bool CPDF_SecurityHandler::CheckUserPassword(const uint8_t* password, 415 uint32_t pass_size, 416 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 = 422 m_pEncryptDict ? m_pEncryptDict->GetStringFor("U") : CFX_ByteString(); 423 if (ukey.GetLength() < 16) { 424 return false; 425 } 426 uint8_t ukeybuf[32]; 427 if (m_Revision == 2) { 428 FXSYS_memcpy(ukeybuf, defpasscode, 32); 429 CRYPT_ArcFourCryptBlock(ukeybuf, 32, key, key_len); 430 } else { 431 uint8_t test[32], tmpkey[32]; 432 uint32_t copy_len = sizeof(test); 433 if (copy_len > (uint32_t)ukey.GetLength()) { 434 copy_len = ukey.GetLength(); 435 } 436 FXSYS_memset(test, 0, sizeof(test)); 437 FXSYS_memset(tmpkey, 0, sizeof(tmpkey)); 438 FXSYS_memcpy(test, ukey.c_str(), copy_len); 439 for (int32_t i = 19; i >= 0; i--) { 440 for (int j = 0; j < key_len; j++) 441 tmpkey[j] = key[j] ^ static_cast<uint8_t>(i); 442 CRYPT_ArcFourCryptBlock(test, 32, tmpkey, key_len); 443 } 444 CRYPT_md5_context md5; 445 CRYPT_MD5Start(&md5); 446 CRYPT_MD5Update(&md5, defpasscode, 32); 447 CPDF_Array* pIdArray = m_pParser->GetIDArray(); 448 if (pIdArray) { 449 CFX_ByteString id = pIdArray->GetStringAt(0); 450 CRYPT_MD5Update(&md5, (uint8_t*)id.c_str(), id.GetLength()); 451 } 452 CRYPT_MD5Finish(&md5, ukeybuf); 453 return FXSYS_memcmp(test, ukeybuf, 16) == 0; 454 } 455 if (FXSYS_memcmp((void*)ukey.c_str(), ukeybuf, 16) == 0) { 456 return true; 457 } 458 return false; 459 } 460 CFX_ByteString CPDF_SecurityHandler::GetUserPassword(const uint8_t* owner_pass, 461 uint32_t pass_size, 462 int32_t key_len) { 463 CFX_ByteString okey = m_pEncryptDict->GetStringFor("O"); 464 uint8_t passcode[32]; 465 for (uint32_t i = 0; i < 32; i++) { 466 passcode[i] = i < pass_size ? owner_pass[i] : defpasscode[i - pass_size]; 467 } 468 uint8_t digest[16]; 469 CRYPT_MD5Generate(passcode, 32, digest); 470 if (m_Revision >= 3) { 471 for (uint32_t i = 0; i < 50; i++) { 472 CRYPT_MD5Generate(digest, 16, digest); 473 } 474 } 475 uint8_t enckey[32]; 476 FXSYS_memset(enckey, 0, sizeof(enckey)); 477 uint32_t copy_len = key_len; 478 if (copy_len > sizeof(digest)) { 479 copy_len = sizeof(digest); 480 } 481 FXSYS_memcpy(enckey, digest, copy_len); 482 int okeylen = okey.GetLength(); 483 if (okeylen > 32) { 484 okeylen = 32; 485 } 486 uint8_t okeybuf[64]; 487 FXSYS_memset(okeybuf, 0, sizeof(okeybuf)); 488 FXSYS_memcpy(okeybuf, okey.c_str(), okeylen); 489 if (m_Revision == 2) { 490 CRYPT_ArcFourCryptBlock(okeybuf, okeylen, enckey, key_len); 491 } else { 492 for (int32_t i = 19; i >= 0; i--) { 493 uint8_t tempkey[32]; 494 FXSYS_memset(tempkey, 0, sizeof(tempkey)); 495 for (int j = 0; j < m_KeyLen; j++) 496 tempkey[j] = enckey[j] ^ static_cast<uint8_t>(i); 497 CRYPT_ArcFourCryptBlock(okeybuf, okeylen, tempkey, key_len); 498 } 499 } 500 int len = 32; 501 while (len && defpasscode[len - 1] == okeybuf[len - 1]) { 502 len--; 503 } 504 return CFX_ByteString(okeybuf, len); 505 } 506 bool CPDF_SecurityHandler::CheckOwnerPassword(const uint8_t* password, 507 uint32_t pass_size, 508 uint8_t* key, 509 int32_t key_len) { 510 CFX_ByteString user_pass = GetUserPassword(password, pass_size, key_len); 511 if (CheckUserPassword(user_pass.raw_str(), user_pass.GetLength(), false, key, 512 key_len)) { 513 return true; 514 } 515 return CheckUserPassword(user_pass.raw_str(), user_pass.GetLength(), true, 516 key, key_len); 517 } 518 519 bool CPDF_SecurityHandler::IsMetadataEncrypted() const { 520 return m_pEncryptDict->GetBooleanFor("EncryptMetadata", true); 521 } 522 523 void CPDF_SecurityHandler::OnCreate(CPDF_Dictionary* pEncryptDict, 524 CPDF_Array* pIdArray, 525 const uint8_t* user_pass, 526 uint32_t user_size, 527 const uint8_t* owner_pass, 528 uint32_t owner_size, 529 bool bDefault, 530 uint32_t type) { 531 int cipher = 0, key_len = 0; 532 if (!LoadDict(pEncryptDict, type, cipher, key_len)) { 533 return; 534 } 535 if (bDefault && (!owner_pass || owner_size == 0)) { 536 owner_pass = user_pass; 537 owner_size = user_size; 538 } 539 if (m_Revision >= 5) { 540 int t = (int)time(nullptr); 541 CRYPT_sha256_context sha; 542 CRYPT_SHA256Start(&sha); 543 CRYPT_SHA256Update(&sha, (uint8_t*)&t, sizeof t); 544 CRYPT_SHA256Update(&sha, m_EncryptKey, 32); 545 CRYPT_SHA256Update(&sha, (uint8_t*)"there", 5); 546 CRYPT_SHA256Finish(&sha, m_EncryptKey); 547 AES256_SetPassword(pEncryptDict, user_pass, user_size, false, m_EncryptKey); 548 if (bDefault) { 549 AES256_SetPassword(pEncryptDict, owner_pass, owner_size, true, 550 m_EncryptKey); 551 AES256_SetPerms(pEncryptDict, m_Permissions, 552 pEncryptDict->GetBooleanFor("EncryptMetadata", true), 553 m_EncryptKey); 554 } 555 return; 556 } 557 if (bDefault) { 558 uint8_t passcode[32]; 559 for (uint32_t i = 0; i < 32; i++) { 560 passcode[i] = 561 i < owner_size ? owner_pass[i] : defpasscode[i - owner_size]; 562 } 563 uint8_t digest[16]; 564 CRYPT_MD5Generate(passcode, 32, digest); 565 if (m_Revision >= 3) { 566 for (uint32_t i = 0; i < 50; i++) 567 CRYPT_MD5Generate(digest, 16, digest); 568 } 569 uint8_t enckey[32]; 570 FXSYS_memcpy(enckey, digest, key_len); 571 for (uint32_t i = 0; i < 32; i++) { 572 passcode[i] = i < user_size ? user_pass[i] : defpasscode[i - user_size]; 573 } 574 CRYPT_ArcFourCryptBlock(passcode, 32, enckey, key_len); 575 uint8_t tempkey[32]; 576 if (m_Revision >= 3) { 577 for (uint8_t i = 1; i <= 19; i++) { 578 for (int j = 0; j < key_len; j++) 579 tempkey[j] = enckey[j] ^ i; 580 CRYPT_ArcFourCryptBlock(passcode, 32, tempkey, key_len); 581 } 582 } 583 pEncryptDict->SetNewFor<CPDF_String>("O", CFX_ByteString(passcode, 32), 584 false); 585 } 586 CalcEncryptKey(m_pEncryptDict, (uint8_t*)user_pass, user_size, m_EncryptKey, 587 key_len, false, pIdArray); 588 if (m_Revision < 3) { 589 uint8_t tempbuf[32]; 590 FXSYS_memcpy(tempbuf, defpasscode, 32); 591 CRYPT_ArcFourCryptBlock(tempbuf, 32, m_EncryptKey, key_len); 592 pEncryptDict->SetNewFor<CPDF_String>("U", CFX_ByteString(tempbuf, 32), 593 false); 594 } else { 595 CRYPT_md5_context md5; 596 CRYPT_MD5Start(&md5); 597 CRYPT_MD5Update(&md5, defpasscode, 32); 598 if (pIdArray) { 599 CFX_ByteString id = pIdArray->GetStringAt(0); 600 CRYPT_MD5Update(&md5, (uint8_t*)id.c_str(), id.GetLength()); 601 } 602 uint8_t digest[32]; 603 CRYPT_MD5Finish(&md5, digest); 604 CRYPT_ArcFourCryptBlock(digest, 16, m_EncryptKey, key_len); 605 uint8_t tempkey[32]; 606 for (uint8_t i = 1; i <= 19; i++) { 607 for (int j = 0; j < key_len; j++) { 608 tempkey[j] = m_EncryptKey[j] ^ i; 609 } 610 CRYPT_ArcFourCryptBlock(digest, 16, tempkey, key_len); 611 } 612 CRYPT_MD5Generate(digest, 16, digest + 16); 613 pEncryptDict->SetNewFor<CPDF_String>("U", CFX_ByteString(digest, 32), 614 false); 615 } 616 } 617 void CPDF_SecurityHandler::OnCreate(CPDF_Dictionary* pEncryptDict, 618 CPDF_Array* pIdArray, 619 const uint8_t* user_pass, 620 uint32_t user_size, 621 const uint8_t* owner_pass, 622 uint32_t owner_size, 623 uint32_t type) { 624 OnCreate(pEncryptDict, pIdArray, user_pass, user_size, owner_pass, owner_size, 625 true, type); 626 } 627 void CPDF_SecurityHandler::OnCreate(CPDF_Dictionary* pEncryptDict, 628 CPDF_Array* pIdArray, 629 const uint8_t* user_pass, 630 uint32_t user_size, 631 uint32_t type) { 632 OnCreate(pEncryptDict, pIdArray, user_pass, user_size, nullptr, 0, false, 633 type); 634 } 635 void CPDF_SecurityHandler::AES256_SetPassword(CPDF_Dictionary* pEncryptDict, 636 const uint8_t* password, 637 uint32_t size, 638 bool bOwner, 639 const uint8_t* key) { 640 CRYPT_sha1_context sha; 641 CRYPT_SHA1Start(&sha); 642 CRYPT_SHA1Update(&sha, key, 32); 643 CRYPT_SHA1Update(&sha, (uint8_t*)"hello", 5); 644 645 uint8_t digest[20]; 646 CRYPT_SHA1Finish(&sha, digest); 647 648 CFX_ByteString ukey = pEncryptDict->GetStringFor("U"); 649 CRYPT_sha256_context sha2; 650 uint8_t digest1[48]; 651 if (m_Revision >= 6) { 652 Revision6_Hash(password, size, digest, bOwner ? ukey.raw_str() : nullptr, 653 digest1); 654 } else { 655 CRYPT_SHA256Start(&sha2); 656 CRYPT_SHA256Update(&sha2, password, size); 657 CRYPT_SHA256Update(&sha2, digest, 8); 658 if (bOwner) { 659 CRYPT_SHA256Update(&sha2, ukey.raw_str(), ukey.GetLength()); 660 } 661 CRYPT_SHA256Finish(&sha2, digest1); 662 } 663 FXSYS_memcpy(digest1 + 32, digest, 16); 664 pEncryptDict->SetNewFor<CPDF_String>(bOwner ? "O" : "U", 665 CFX_ByteString(digest1, 48), false); 666 if (m_Revision >= 6) { 667 Revision6_Hash(password, size, digest + 8, 668 bOwner ? ukey.raw_str() : nullptr, digest1); 669 } else { 670 CRYPT_SHA256Start(&sha2); 671 CRYPT_SHA256Update(&sha2, password, size); 672 CRYPT_SHA256Update(&sha2, digest + 8, 8); 673 if (bOwner) { 674 CRYPT_SHA256Update(&sha2, ukey.raw_str(), ukey.GetLength()); 675 } 676 CRYPT_SHA256Finish(&sha2, digest1); 677 } 678 uint8_t* aes = FX_Alloc(uint8_t, 2048); 679 CRYPT_AESSetKey(aes, 16, digest1, 32, true); 680 uint8_t iv[16]; 681 FXSYS_memset(iv, 0, 16); 682 CRYPT_AESSetIV(aes, iv); 683 CRYPT_AESEncrypt(aes, digest1, key, 32); 684 FX_Free(aes); 685 pEncryptDict->SetNewFor<CPDF_String>(bOwner ? "OE" : "UE", 686 CFX_ByteString(digest1, 32), false); 687 } 688 689 void CPDF_SecurityHandler::AES256_SetPerms(CPDF_Dictionary* pEncryptDict, 690 uint32_t permissions, 691 bool bEncryptMetadata, 692 const uint8_t* key) { 693 uint8_t buf[16]; 694 buf[0] = (uint8_t)permissions; 695 buf[1] = (uint8_t)(permissions >> 8); 696 buf[2] = (uint8_t)(permissions >> 16); 697 buf[3] = (uint8_t)(permissions >> 24); 698 buf[4] = 0xff; 699 buf[5] = 0xff; 700 buf[6] = 0xff; 701 buf[7] = 0xff; 702 buf[8] = bEncryptMetadata ? 'T' : 'F'; 703 buf[9] = 'a'; 704 buf[10] = 'd'; 705 buf[11] = 'b'; 706 uint8_t* aes = FX_Alloc(uint8_t, 2048); 707 CRYPT_AESSetKey(aes, 16, key, 32, true); 708 uint8_t iv[16], buf1[16]; 709 FXSYS_memset(iv, 0, 16); 710 CRYPT_AESSetIV(aes, iv); 711 CRYPT_AESEncrypt(aes, buf1, buf, 16); 712 FX_Free(aes); 713 pEncryptDict->SetNewFor<CPDF_String>("Perms", CFX_ByteString(buf1, 16), 714 false); 715 } 716