| OLD | NEW |
| 1 // Copyright 2014 PDFium Authors. All rights reserved. | 1 // Copyright 2014 PDFium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com | 5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com |
| 6 | 6 |
| 7 #include "core/fpdfapi/parser/cpdf_security_handler.h" | 7 #include "core/fpdfapi/parser/cpdf_security_handler.h" |
| 8 | 8 |
| 9 #include <time.h> | 9 #include <time.h> |
| 10 | 10 |
| (...skipping 210 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 221 uint64_t ret = 0; | 221 uint64_t ret = 0; |
| 222 for (int i = 0; i < 4; ++i) { | 222 for (int i = 0; i < 4; ++i) { |
| 223 uint32_t value; | 223 uint32_t value; |
| 224 FX_GET_32WORD(value, data, 4 * i); | 224 FX_GET_32WORD(value, data, 4 * i); |
| 225 ret <<= 32; | 225 ret <<= 32; |
| 226 ret |= value; | 226 ret |= value; |
| 227 ret %= 3; | 227 ret %= 3; |
| 228 } | 228 } |
| 229 return (int)ret; | 229 return (int)ret; |
| 230 } | 230 } |
| 231 |
| 231 void Revision6_Hash(const uint8_t* password, | 232 void Revision6_Hash(const uint8_t* password, |
| 232 uint32_t size, | 233 uint32_t size, |
| 233 const uint8_t* salt, | 234 const uint8_t* salt, |
| 234 const uint8_t* vector, | 235 const uint8_t* vector, |
| 235 uint8_t* hash) { | 236 uint8_t* hash) { |
| 236 int iBlockSize = 32; | 237 CRYPT_sha256_context sha; |
| 237 uint8_t sha[128]; | 238 CRYPT_SHA256Start(&sha); |
| 238 CRYPT_SHA256Start(sha); | 239 CRYPT_SHA256Update(&sha, password, size); |
| 239 CRYPT_SHA256Update(sha, password, size); | 240 CRYPT_SHA256Update(&sha, salt, 8); |
| 240 CRYPT_SHA256Update(sha, salt, 8); | 241 if (vector) |
| 241 if (vector) { | 242 CRYPT_SHA256Update(&sha, vector, 48); |
| 242 CRYPT_SHA256Update(sha, vector, 48); | 243 |
| 243 } | |
| 244 uint8_t digest[32]; | 244 uint8_t digest[32]; |
| 245 CRYPT_SHA256Finish(sha, digest); | 245 CRYPT_SHA256Finish(&sha, digest); |
| 246 |
| 246 CFX_ByteTextBuf buf; | 247 CFX_ByteTextBuf buf; |
| 247 uint8_t* input = digest; | 248 uint8_t* input = digest; |
| 248 uint8_t* key = input; | 249 uint8_t* key = input; |
| 249 uint8_t* iv = input + 16; | 250 uint8_t* iv = input + 16; |
| 250 uint8_t* E = buf.GetBuffer(); | 251 uint8_t* E = buf.GetBuffer(); |
| 251 int iBufLen = buf.GetLength(); | 252 int iBufLen = buf.GetLength(); |
| 252 CFX_ByteTextBuf interDigest; | 253 CFX_ByteTextBuf interDigest; |
| 253 int i = 0; | 254 int i = 0; |
| 255 int iBlockSize = 32; |
| 254 uint8_t* aes = FX_Alloc(uint8_t, 2048); | 256 uint8_t* aes = FX_Alloc(uint8_t, 2048); |
| 255 while (i < 64 || i < E[iBufLen - 1] + 32) { | 257 while (i < 64 || i < E[iBufLen - 1] + 32) { |
| 256 int iRoundSize = size + iBlockSize; | 258 int iRoundSize = size + iBlockSize; |
| 257 if (vector) { | 259 if (vector) { |
| 258 iRoundSize += 48; | 260 iRoundSize += 48; |
| 259 } | 261 } |
| 260 iBufLen = iRoundSize * 64; | 262 iBufLen = iRoundSize * 64; |
| 261 buf.EstimateSize(iBufLen); | 263 buf.EstimateSize(iBufLen); |
| 262 E = buf.GetBuffer(); | 264 E = buf.GetBuffer(); |
| 263 CFX_ByteTextBuf content; | 265 CFX_ByteTextBuf content; |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 312 m_pEncryptDict ? m_pEncryptDict->GetStringFor("O") : CFX_ByteString(); | 314 m_pEncryptDict ? m_pEncryptDict->GetStringFor("O") : CFX_ByteString(); |
| 313 if (okey.GetLength() < 48) { | 315 if (okey.GetLength() < 48) { |
| 314 return false; | 316 return false; |
| 315 } | 317 } |
| 316 CFX_ByteString ukey = | 318 CFX_ByteString ukey = |
| 317 m_pEncryptDict ? m_pEncryptDict->GetStringFor("U") : CFX_ByteString(); | 319 m_pEncryptDict ? m_pEncryptDict->GetStringFor("U") : CFX_ByteString(); |
| 318 if (ukey.GetLength() < 48) { | 320 if (ukey.GetLength() < 48) { |
| 319 return false; | 321 return false; |
| 320 } | 322 } |
| 321 const uint8_t* pkey = (bOwner ? okey : ukey).raw_str(); | 323 const uint8_t* pkey = (bOwner ? okey : ukey).raw_str(); |
| 322 uint8_t sha[128]; | 324 CRYPT_sha256_context sha; |
| 323 uint8_t digest[32]; | 325 uint8_t digest[32]; |
| 324 if (m_Revision >= 6) { | 326 if (m_Revision >= 6) { |
| 325 Revision6_Hash(password, size, (const uint8_t*)pkey + 32, | 327 Revision6_Hash(password, size, (const uint8_t*)pkey + 32, |
| 326 bOwner ? ukey.raw_str() : nullptr, digest); | 328 bOwner ? ukey.raw_str() : nullptr, digest); |
| 327 } else { | 329 } else { |
| 328 CRYPT_SHA256Start(sha); | 330 CRYPT_SHA256Start(&sha); |
| 329 CRYPT_SHA256Update(sha, password, size); | 331 CRYPT_SHA256Update(&sha, password, size); |
| 330 CRYPT_SHA256Update(sha, pkey + 32, 8); | 332 CRYPT_SHA256Update(&sha, pkey + 32, 8); |
| 331 if (bOwner) { | 333 if (bOwner) |
| 332 CRYPT_SHA256Update(sha, ukey.raw_str(), 48); | 334 CRYPT_SHA256Update(&sha, ukey.raw_str(), 48); |
| 333 } | 335 |
| 334 CRYPT_SHA256Finish(sha, digest); | 336 CRYPT_SHA256Finish(&sha, digest); |
| 335 } | 337 } |
| 336 if (FXSYS_memcmp(digest, pkey, 32) != 0) { | 338 if (FXSYS_memcmp(digest, pkey, 32) != 0) |
| 337 return false; | 339 return false; |
| 338 } | 340 |
| 339 if (!key) { | 341 if (!key) |
| 340 return true; | 342 return true; |
| 341 } | 343 |
| 342 if (m_Revision >= 6) { | 344 if (m_Revision >= 6) { |
| 343 Revision6_Hash(password, size, (const uint8_t*)pkey + 40, | 345 Revision6_Hash(password, size, (const uint8_t*)pkey + 40, |
| 344 bOwner ? ukey.raw_str() : nullptr, digest); | 346 bOwner ? ukey.raw_str() : nullptr, digest); |
| 345 } else { | 347 } else { |
| 346 CRYPT_SHA256Start(sha); | 348 CRYPT_SHA256Start(&sha); |
| 347 CRYPT_SHA256Update(sha, password, size); | 349 CRYPT_SHA256Update(&sha, password, size); |
| 348 CRYPT_SHA256Update(sha, pkey + 40, 8); | 350 CRYPT_SHA256Update(&sha, pkey + 40, 8); |
| 349 if (bOwner) { | 351 if (bOwner) |
| 350 CRYPT_SHA256Update(sha, ukey.raw_str(), 48); | 352 CRYPT_SHA256Update(&sha, ukey.raw_str(), 48); |
| 351 } | 353 |
| 352 CRYPT_SHA256Finish(sha, digest); | 354 CRYPT_SHA256Finish(&sha, digest); |
| 353 } | 355 } |
| 354 CFX_ByteString ekey = m_pEncryptDict | 356 CFX_ByteString ekey = m_pEncryptDict |
| 355 ? m_pEncryptDict->GetStringFor(bOwner ? "OE" : "UE") | 357 ? m_pEncryptDict->GetStringFor(bOwner ? "OE" : "UE") |
| 356 : CFX_ByteString(); | 358 : CFX_ByteString(); |
| 357 if (ekey.GetLength() < 32) | 359 if (ekey.GetLength() < 32) |
| 358 return false; | 360 return false; |
| 359 | 361 |
| 360 std::vector<uint8_t> aes(2048); | 362 std::vector<uint8_t> aes(2048); |
| 361 CRYPT_AESSetKey(aes.data(), 16, digest, 32, false); | 363 CRYPT_AESSetKey(aes.data(), 16, digest, 32, false); |
| 362 uint8_t iv[16]; | 364 uint8_t iv[16]; |
| (...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 526 int cipher = 0, key_len = 0; | 528 int cipher = 0, key_len = 0; |
| 527 if (!LoadDict(pEncryptDict, type, cipher, key_len)) { | 529 if (!LoadDict(pEncryptDict, type, cipher, key_len)) { |
| 528 return; | 530 return; |
| 529 } | 531 } |
| 530 if (bDefault && (!owner_pass || owner_size == 0)) { | 532 if (bDefault && (!owner_pass || owner_size == 0)) { |
| 531 owner_pass = user_pass; | 533 owner_pass = user_pass; |
| 532 owner_size = user_size; | 534 owner_size = user_size; |
| 533 } | 535 } |
| 534 if (m_Revision >= 5) { | 536 if (m_Revision >= 5) { |
| 535 int t = (int)time(nullptr); | 537 int t = (int)time(nullptr); |
| 536 uint8_t sha[128]; | 538 CRYPT_sha256_context sha; |
| 537 CRYPT_SHA256Start(sha); | 539 CRYPT_SHA256Start(&sha); |
| 538 CRYPT_SHA256Update(sha, (uint8_t*)&t, sizeof t); | 540 CRYPT_SHA256Update(&sha, (uint8_t*)&t, sizeof t); |
| 539 CRYPT_SHA256Update(sha, m_EncryptKey, 32); | 541 CRYPT_SHA256Update(&sha, m_EncryptKey, 32); |
| 540 CRYPT_SHA256Update(sha, (uint8_t*)"there", 5); | 542 CRYPT_SHA256Update(&sha, (uint8_t*)"there", 5); |
| 541 CRYPT_SHA256Finish(sha, m_EncryptKey); | 543 CRYPT_SHA256Finish(&sha, m_EncryptKey); |
| 542 AES256_SetPassword(pEncryptDict, user_pass, user_size, false, m_EncryptKey); | 544 AES256_SetPassword(pEncryptDict, user_pass, user_size, false, m_EncryptKey); |
| 543 if (bDefault) { | 545 if (bDefault) { |
| 544 AES256_SetPassword(pEncryptDict, owner_pass, owner_size, true, | 546 AES256_SetPassword(pEncryptDict, owner_pass, owner_size, true, |
| 545 m_EncryptKey); | 547 m_EncryptKey); |
| 546 AES256_SetPerms(pEncryptDict, m_Permissions, | 548 AES256_SetPerms(pEncryptDict, m_Permissions, |
| 547 pEncryptDict->GetBooleanFor("EncryptMetadata", true), | 549 pEncryptDict->GetBooleanFor("EncryptMetadata", true), |
| 548 m_EncryptKey); | 550 m_EncryptKey); |
| 549 } | 551 } |
| 550 return; | 552 return; |
| 551 } | 553 } |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 625 uint32_t user_size, | 627 uint32_t user_size, |
| 626 uint32_t type) { | 628 uint32_t type) { |
| 627 OnCreate(pEncryptDict, pIdArray, user_pass, user_size, nullptr, 0, false, | 629 OnCreate(pEncryptDict, pIdArray, user_pass, user_size, nullptr, 0, false, |
| 628 type); | 630 type); |
| 629 } | 631 } |
| 630 void CPDF_SecurityHandler::AES256_SetPassword(CPDF_Dictionary* pEncryptDict, | 632 void CPDF_SecurityHandler::AES256_SetPassword(CPDF_Dictionary* pEncryptDict, |
| 631 const uint8_t* password, | 633 const uint8_t* password, |
| 632 uint32_t size, | 634 uint32_t size, |
| 633 bool bOwner, | 635 bool bOwner, |
| 634 const uint8_t* key) { | 636 const uint8_t* key) { |
| 635 uint8_t sha[128]; | 637 CRYPT_sha1_context sha; |
| 636 CRYPT_SHA1Start(sha); | 638 CRYPT_SHA1Start(&sha); |
| 637 CRYPT_SHA1Update(sha, key, 32); | 639 CRYPT_SHA1Update(&sha, key, 32); |
| 638 CRYPT_SHA1Update(sha, (uint8_t*)"hello", 5); | 640 CRYPT_SHA1Update(&sha, (uint8_t*)"hello", 5); |
| 641 |
| 639 uint8_t digest[20]; | 642 uint8_t digest[20]; |
| 640 CRYPT_SHA1Finish(sha, digest); | 643 CRYPT_SHA1Finish(&sha, digest); |
| 644 |
| 641 CFX_ByteString ukey = pEncryptDict->GetStringFor("U"); | 645 CFX_ByteString ukey = pEncryptDict->GetStringFor("U"); |
| 646 CRYPT_sha256_context sha2; |
| 642 uint8_t digest1[48]; | 647 uint8_t digest1[48]; |
| 643 if (m_Revision >= 6) { | 648 if (m_Revision >= 6) { |
| 644 Revision6_Hash(password, size, digest, bOwner ? ukey.raw_str() : nullptr, | 649 Revision6_Hash(password, size, digest, bOwner ? ukey.raw_str() : nullptr, |
| 645 digest1); | 650 digest1); |
| 646 } else { | 651 } else { |
| 647 CRYPT_SHA256Start(sha); | 652 CRYPT_SHA256Start(&sha2); |
| 648 CRYPT_SHA256Update(sha, password, size); | 653 CRYPT_SHA256Update(&sha2, password, size); |
| 649 CRYPT_SHA256Update(sha, digest, 8); | 654 CRYPT_SHA256Update(&sha2, digest, 8); |
| 650 if (bOwner) { | 655 if (bOwner) { |
| 651 CRYPT_SHA256Update(sha, ukey.raw_str(), ukey.GetLength()); | 656 CRYPT_SHA256Update(&sha2, ukey.raw_str(), ukey.GetLength()); |
| 652 } | 657 } |
| 653 CRYPT_SHA256Finish(sha, digest1); | 658 CRYPT_SHA256Finish(&sha2, digest1); |
| 654 } | 659 } |
| 655 FXSYS_memcpy(digest1 + 32, digest, 16); | 660 FXSYS_memcpy(digest1 + 32, digest, 16); |
| 656 pEncryptDict->SetNewFor<CPDF_String>(bOwner ? "O" : "U", | 661 pEncryptDict->SetNewFor<CPDF_String>(bOwner ? "O" : "U", |
| 657 CFX_ByteString(digest1, 48), false); | 662 CFX_ByteString(digest1, 48), false); |
| 658 if (m_Revision >= 6) { | 663 if (m_Revision >= 6) { |
| 659 Revision6_Hash(password, size, digest + 8, | 664 Revision6_Hash(password, size, digest + 8, |
| 660 bOwner ? ukey.raw_str() : nullptr, digest1); | 665 bOwner ? ukey.raw_str() : nullptr, digest1); |
| 661 } else { | 666 } else { |
| 662 CRYPT_SHA256Start(sha); | 667 CRYPT_SHA256Start(&sha2); |
| 663 CRYPT_SHA256Update(sha, password, size); | 668 CRYPT_SHA256Update(&sha2, password, size); |
| 664 CRYPT_SHA256Update(sha, digest + 8, 8); | 669 CRYPT_SHA256Update(&sha2, digest + 8, 8); |
| 665 if (bOwner) { | 670 if (bOwner) { |
| 666 CRYPT_SHA256Update(sha, ukey.raw_str(), ukey.GetLength()); | 671 CRYPT_SHA256Update(&sha2, ukey.raw_str(), ukey.GetLength()); |
| 667 } | 672 } |
| 668 CRYPT_SHA256Finish(sha, digest1); | 673 CRYPT_SHA256Finish(&sha2, digest1); |
| 669 } | 674 } |
| 670 uint8_t* aes = FX_Alloc(uint8_t, 2048); | 675 uint8_t* aes = FX_Alloc(uint8_t, 2048); |
| 671 CRYPT_AESSetKey(aes, 16, digest1, 32, true); | 676 CRYPT_AESSetKey(aes, 16, digest1, 32, true); |
| 672 uint8_t iv[16]; | 677 uint8_t iv[16]; |
| 673 FXSYS_memset(iv, 0, 16); | 678 FXSYS_memset(iv, 0, 16); |
| 674 CRYPT_AESSetIV(aes, iv); | 679 CRYPT_AESSetIV(aes, iv); |
| 675 CRYPT_AESEncrypt(aes, digest1, key, 32); | 680 CRYPT_AESEncrypt(aes, digest1, key, 32); |
| 676 FX_Free(aes); | 681 FX_Free(aes); |
| 677 pEncryptDict->SetNewFor<CPDF_String>(bOwner ? "OE" : "UE", | 682 pEncryptDict->SetNewFor<CPDF_String>(bOwner ? "OE" : "UE", |
| 678 CFX_ByteString(digest1, 32), false); | 683 CFX_ByteString(digest1, 32), false); |
| (...skipping 19 matching lines...) Expand all Loading... |
| 698 uint8_t* aes = FX_Alloc(uint8_t, 2048); | 703 uint8_t* aes = FX_Alloc(uint8_t, 2048); |
| 699 CRYPT_AESSetKey(aes, 16, key, 32, true); | 704 CRYPT_AESSetKey(aes, 16, key, 32, true); |
| 700 uint8_t iv[16], buf1[16]; | 705 uint8_t iv[16], buf1[16]; |
| 701 FXSYS_memset(iv, 0, 16); | 706 FXSYS_memset(iv, 0, 16); |
| 702 CRYPT_AESSetIV(aes, iv); | 707 CRYPT_AESSetIV(aes, iv); |
| 703 CRYPT_AESEncrypt(aes, buf1, buf, 16); | 708 CRYPT_AESEncrypt(aes, buf1, buf, 16); |
| 704 FX_Free(aes); | 709 FX_Free(aes); |
| 705 pEncryptDict->SetNewFor<CPDF_String>("Perms", CFX_ByteString(buf1, 16), | 710 pEncryptDict->SetNewFor<CPDF_String>("Perms", CFX_ByteString(buf1, 16), |
| 706 false); | 711 false); |
| 707 } | 712 } |
| OLD | NEW |