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 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
297 } | 299 } |
298 key = input; | 300 key = input; |
299 iv = input + 16; | 301 iv = input + 16; |
300 ++i; | 302 ++i; |
301 } | 303 } |
302 FX_Free(aes); | 304 FX_Free(aes); |
303 if (hash) { | 305 if (hash) { |
304 FXSYS_memcpy(hash, input, 32); | 306 FXSYS_memcpy(hash, input, 32); |
305 } | 307 } |
306 } | 308 } |
| 309 |
307 bool CPDF_SecurityHandler::AES256_CheckPassword(const uint8_t* password, | 310 bool CPDF_SecurityHandler::AES256_CheckPassword(const uint8_t* password, |
308 uint32_t size, | 311 uint32_t size, |
309 bool bOwner, | 312 bool bOwner, |
310 uint8_t* key) { | 313 uint8_t* key) { |
311 CFX_ByteString okey = | 314 if (!m_pEncryptDict) |
312 m_pEncryptDict ? m_pEncryptDict->GetStringFor("O") : CFX_ByteString(); | |
313 if (okey.GetLength() < 48) { | |
314 return false; | 315 return false; |
315 } | 316 |
316 CFX_ByteString ukey = | 317 CFX_ByteString okey = m_pEncryptDict->GetStringFor("O"); |
317 m_pEncryptDict ? m_pEncryptDict->GetStringFor("U") : CFX_ByteString(); | 318 if (okey.GetLength() < 48) |
318 if (ukey.GetLength() < 48) { | |
319 return false; | 319 return false; |
320 } | 320 |
321 const uint8_t* pkey = (bOwner ? okey : ukey).raw_str(); | 321 CFX_ByteString ukey = m_pEncryptDict->GetStringFor("U"); |
322 uint8_t sha[128]; | 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; |
323 uint8_t digest[32]; | 327 uint8_t digest[32]; |
324 if (m_Revision >= 6) { | 328 if (m_Revision >= 6) { |
325 Revision6_Hash(password, size, (const uint8_t*)pkey + 32, | 329 Revision6_Hash(password, size, (const uint8_t*)pkey + 32, |
326 bOwner ? ukey.raw_str() : nullptr, digest); | 330 bOwner ? ukey.raw_str() : nullptr, digest); |
327 } else { | 331 } else { |
328 CRYPT_SHA256Start(sha); | 332 CRYPT_SHA256Start(&sha); |
329 CRYPT_SHA256Update(sha, password, size); | 333 CRYPT_SHA256Update(&sha, password, size); |
330 CRYPT_SHA256Update(sha, pkey + 32, 8); | 334 CRYPT_SHA256Update(&sha, pkey + 32, 8); |
331 if (bOwner) { | 335 if (bOwner) |
332 CRYPT_SHA256Update(sha, ukey.raw_str(), 48); | 336 CRYPT_SHA256Update(&sha, ukey.raw_str(), 48); |
333 } | 337 |
334 CRYPT_SHA256Finish(sha, digest); | 338 CRYPT_SHA256Finish(&sha, digest); |
335 } | 339 } |
336 if (FXSYS_memcmp(digest, pkey, 32) != 0) { | 340 if (FXSYS_memcmp(digest, pkey, 32) != 0) |
337 return false; | 341 return false; |
338 } | 342 |
339 if (!key) { | 343 if (!key) |
340 return true; | 344 return true; |
341 } | 345 |
342 if (m_Revision >= 6) { | 346 if (m_Revision >= 6) { |
343 Revision6_Hash(password, size, (const uint8_t*)pkey + 40, | 347 Revision6_Hash(password, size, (const uint8_t*)pkey + 40, |
344 bOwner ? ukey.raw_str() : nullptr, digest); | 348 bOwner ? ukey.raw_str() : nullptr, digest); |
345 } else { | 349 } else { |
346 CRYPT_SHA256Start(sha); | 350 CRYPT_SHA256Start(&sha); |
347 CRYPT_SHA256Update(sha, password, size); | 351 CRYPT_SHA256Update(&sha, password, size); |
348 CRYPT_SHA256Update(sha, pkey + 40, 8); | 352 CRYPT_SHA256Update(&sha, pkey + 40, 8); |
349 if (bOwner) { | 353 if (bOwner) |
350 CRYPT_SHA256Update(sha, ukey.raw_str(), 48); | 354 CRYPT_SHA256Update(&sha, ukey.raw_str(), 48); |
351 } | 355 |
352 CRYPT_SHA256Finish(sha, digest); | 356 CRYPT_SHA256Finish(&sha, digest); |
353 } | 357 } |
354 CFX_ByteString ekey = m_pEncryptDict | 358 CFX_ByteString ekey = m_pEncryptDict |
355 ? m_pEncryptDict->GetStringFor(bOwner ? "OE" : "UE") | 359 ? m_pEncryptDict->GetStringFor(bOwner ? "OE" : "UE") |
356 : CFX_ByteString(); | 360 : CFX_ByteString(); |
357 if (ekey.GetLength() < 32) | 361 if (ekey.GetLength() < 32) |
358 return false; | 362 return false; |
359 | 363 |
360 std::vector<uint8_t> aes(2048); | 364 std::vector<uint8_t> aes(2048); |
361 CRYPT_AESSetKey(aes.data(), 16, digest, 32, false); | 365 CRYPT_AESSetKey(aes.data(), 16, digest, 32, false); |
362 uint8_t iv[16]; | 366 uint8_t iv[16]; |
(...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
526 int cipher = 0, key_len = 0; | 530 int cipher = 0, key_len = 0; |
527 if (!LoadDict(pEncryptDict, type, cipher, key_len)) { | 531 if (!LoadDict(pEncryptDict, type, cipher, key_len)) { |
528 return; | 532 return; |
529 } | 533 } |
530 if (bDefault && (!owner_pass || owner_size == 0)) { | 534 if (bDefault && (!owner_pass || owner_size == 0)) { |
531 owner_pass = user_pass; | 535 owner_pass = user_pass; |
532 owner_size = user_size; | 536 owner_size = user_size; |
533 } | 537 } |
534 if (m_Revision >= 5) { | 538 if (m_Revision >= 5) { |
535 int t = (int)time(nullptr); | 539 int t = (int)time(nullptr); |
536 uint8_t sha[128]; | 540 CRYPT_sha256_context sha; |
537 CRYPT_SHA256Start(sha); | 541 CRYPT_SHA256Start(&sha); |
538 CRYPT_SHA256Update(sha, (uint8_t*)&t, sizeof t); | 542 CRYPT_SHA256Update(&sha, (uint8_t*)&t, sizeof t); |
539 CRYPT_SHA256Update(sha, m_EncryptKey, 32); | 543 CRYPT_SHA256Update(&sha, m_EncryptKey, 32); |
540 CRYPT_SHA256Update(sha, (uint8_t*)"there", 5); | 544 CRYPT_SHA256Update(&sha, (uint8_t*)"there", 5); |
541 CRYPT_SHA256Finish(sha, m_EncryptKey); | 545 CRYPT_SHA256Finish(&sha, m_EncryptKey); |
542 AES256_SetPassword(pEncryptDict, user_pass, user_size, false, m_EncryptKey); | 546 AES256_SetPassword(pEncryptDict, user_pass, user_size, false, m_EncryptKey); |
543 if (bDefault) { | 547 if (bDefault) { |
544 AES256_SetPassword(pEncryptDict, owner_pass, owner_size, true, | 548 AES256_SetPassword(pEncryptDict, owner_pass, owner_size, true, |
545 m_EncryptKey); | 549 m_EncryptKey); |
546 AES256_SetPerms(pEncryptDict, m_Permissions, | 550 AES256_SetPerms(pEncryptDict, m_Permissions, |
547 pEncryptDict->GetBooleanFor("EncryptMetadata", true), | 551 pEncryptDict->GetBooleanFor("EncryptMetadata", true), |
548 m_EncryptKey); | 552 m_EncryptKey); |
549 } | 553 } |
550 return; | 554 return; |
551 } | 555 } |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
625 uint32_t user_size, | 629 uint32_t user_size, |
626 uint32_t type) { | 630 uint32_t type) { |
627 OnCreate(pEncryptDict, pIdArray, user_pass, user_size, nullptr, 0, false, | 631 OnCreate(pEncryptDict, pIdArray, user_pass, user_size, nullptr, 0, false, |
628 type); | 632 type); |
629 } | 633 } |
630 void CPDF_SecurityHandler::AES256_SetPassword(CPDF_Dictionary* pEncryptDict, | 634 void CPDF_SecurityHandler::AES256_SetPassword(CPDF_Dictionary* pEncryptDict, |
631 const uint8_t* password, | 635 const uint8_t* password, |
632 uint32_t size, | 636 uint32_t size, |
633 bool bOwner, | 637 bool bOwner, |
634 const uint8_t* key) { | 638 const uint8_t* key) { |
635 uint8_t sha[128]; | 639 CRYPT_sha1_context sha; |
636 CRYPT_SHA1Start(sha); | 640 CRYPT_SHA1Start(&sha); |
637 CRYPT_SHA1Update(sha, key, 32); | 641 CRYPT_SHA1Update(&sha, key, 32); |
638 CRYPT_SHA1Update(sha, (uint8_t*)"hello", 5); | 642 CRYPT_SHA1Update(&sha, (uint8_t*)"hello", 5); |
| 643 |
639 uint8_t digest[20]; | 644 uint8_t digest[20]; |
640 CRYPT_SHA1Finish(sha, digest); | 645 CRYPT_SHA1Finish(&sha, digest); |
| 646 |
641 CFX_ByteString ukey = pEncryptDict->GetStringFor("U"); | 647 CFX_ByteString ukey = pEncryptDict->GetStringFor("U"); |
| 648 CRYPT_sha256_context sha2; |
642 uint8_t digest1[48]; | 649 uint8_t digest1[48]; |
643 if (m_Revision >= 6) { | 650 if (m_Revision >= 6) { |
644 Revision6_Hash(password, size, digest, bOwner ? ukey.raw_str() : nullptr, | 651 Revision6_Hash(password, size, digest, bOwner ? ukey.raw_str() : nullptr, |
645 digest1); | 652 digest1); |
646 } else { | 653 } else { |
647 CRYPT_SHA256Start(sha); | 654 CRYPT_SHA256Start(&sha2); |
648 CRYPT_SHA256Update(sha, password, size); | 655 CRYPT_SHA256Update(&sha2, password, size); |
649 CRYPT_SHA256Update(sha, digest, 8); | 656 CRYPT_SHA256Update(&sha2, digest, 8); |
650 if (bOwner) { | 657 if (bOwner) { |
651 CRYPT_SHA256Update(sha, ukey.raw_str(), ukey.GetLength()); | 658 CRYPT_SHA256Update(&sha2, ukey.raw_str(), ukey.GetLength()); |
652 } | 659 } |
653 CRYPT_SHA256Finish(sha, digest1); | 660 CRYPT_SHA256Finish(&sha2, digest1); |
654 } | 661 } |
655 FXSYS_memcpy(digest1 + 32, digest, 16); | 662 FXSYS_memcpy(digest1 + 32, digest, 16); |
656 pEncryptDict->SetNewFor<CPDF_String>(bOwner ? "O" : "U", | 663 pEncryptDict->SetNewFor<CPDF_String>(bOwner ? "O" : "U", |
657 CFX_ByteString(digest1, 48), false); | 664 CFX_ByteString(digest1, 48), false); |
658 if (m_Revision >= 6) { | 665 if (m_Revision >= 6) { |
659 Revision6_Hash(password, size, digest + 8, | 666 Revision6_Hash(password, size, digest + 8, |
660 bOwner ? ukey.raw_str() : nullptr, digest1); | 667 bOwner ? ukey.raw_str() : nullptr, digest1); |
661 } else { | 668 } else { |
662 CRYPT_SHA256Start(sha); | 669 CRYPT_SHA256Start(&sha2); |
663 CRYPT_SHA256Update(sha, password, size); | 670 CRYPT_SHA256Update(&sha2, password, size); |
664 CRYPT_SHA256Update(sha, digest + 8, 8); | 671 CRYPT_SHA256Update(&sha2, digest + 8, 8); |
665 if (bOwner) { | 672 if (bOwner) { |
666 CRYPT_SHA256Update(sha, ukey.raw_str(), ukey.GetLength()); | 673 CRYPT_SHA256Update(&sha2, ukey.raw_str(), ukey.GetLength()); |
667 } | 674 } |
668 CRYPT_SHA256Finish(sha, digest1); | 675 CRYPT_SHA256Finish(&sha2, digest1); |
669 } | 676 } |
670 uint8_t* aes = FX_Alloc(uint8_t, 2048); | 677 uint8_t* aes = FX_Alloc(uint8_t, 2048); |
671 CRYPT_AESSetKey(aes, 16, digest1, 32, true); | 678 CRYPT_AESSetKey(aes, 16, digest1, 32, true); |
672 uint8_t iv[16]; | 679 uint8_t iv[16]; |
673 FXSYS_memset(iv, 0, 16); | 680 FXSYS_memset(iv, 0, 16); |
674 CRYPT_AESSetIV(aes, iv); | 681 CRYPT_AESSetIV(aes, iv); |
675 CRYPT_AESEncrypt(aes, digest1, key, 32); | 682 CRYPT_AESEncrypt(aes, digest1, key, 32); |
676 FX_Free(aes); | 683 FX_Free(aes); |
677 pEncryptDict->SetNewFor<CPDF_String>(bOwner ? "OE" : "UE", | 684 pEncryptDict->SetNewFor<CPDF_String>(bOwner ? "OE" : "UE", |
678 CFX_ByteString(digest1, 32), false); | 685 CFX_ByteString(digest1, 32), false); |
(...skipping 19 matching lines...) Expand all Loading... |
698 uint8_t* aes = FX_Alloc(uint8_t, 2048); | 705 uint8_t* aes = FX_Alloc(uint8_t, 2048); |
699 CRYPT_AESSetKey(aes, 16, key, 32, true); | 706 CRYPT_AESSetKey(aes, 16, key, 32, true); |
700 uint8_t iv[16], buf1[16]; | 707 uint8_t iv[16], buf1[16]; |
701 FXSYS_memset(iv, 0, 16); | 708 FXSYS_memset(iv, 0, 16); |
702 CRYPT_AESSetIV(aes, iv); | 709 CRYPT_AESSetIV(aes, iv); |
703 CRYPT_AESEncrypt(aes, buf1, buf, 16); | 710 CRYPT_AESEncrypt(aes, buf1, buf, 16); |
704 FX_Free(aes); | 711 FX_Free(aes); |
705 pEncryptDict->SetNewFor<CPDF_String>("Perms", CFX_ByteString(buf1, 16), | 712 pEncryptDict->SetNewFor<CPDF_String>("Perms", CFX_ByteString(buf1, 16), |
706 false); | 713 false); |
707 } | 714 } |
OLD | NEW |