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_crypto_handler.h" 8 9 #include <time.h> 10 11 #include <algorithm> 12 #include <stack> 13 #include <utility> 14 15 #include "core/fdrm/crypto/fx_crypt.h" 16 #include "core/fpdfapi/edit/cpdf_encryptor.h" 17 #include "core/fpdfapi/edit/cpdf_flateencoder.h" 18 #include "core/fpdfapi/parser/cpdf_dictionary.h" 19 #include "core/fpdfapi/parser/cpdf_number.h" 20 #include "core/fpdfapi/parser/cpdf_object_walker.h" 21 #include "core/fpdfapi/parser/cpdf_parser.h" 22 #include "core/fpdfapi/parser/cpdf_security_handler.h" 23 #include "core/fpdfapi/parser/cpdf_simple_parser.h" 24 #include "core/fpdfapi/parser/cpdf_stream.h" 25 #include "core/fpdfapi/parser/cpdf_stream_acc.h" 26 #include "core/fpdfapi/parser/cpdf_string.h" 27 28 namespace { 29 30 constexpr char kContentsKey[] = "Contents"; 31 constexpr char kTypeKey[] = "Type"; 32 constexpr char kFTKey[] = "FT"; 33 constexpr char kSignTypeValue[] = "Sig"; 34 35 } // namespace 36 37 // static 38 bool CPDF_CryptoHandler::IsSignatureDictionary( 39 const CPDF_Dictionary* dictionary) { 40 if (!dictionary) 41 return false; 42 const CPDF_Object* type_obj = dictionary->GetDirectObjectFor(kTypeKey); 43 if (!type_obj) 44 type_obj = dictionary->GetDirectObjectFor(kFTKey); 45 return type_obj && type_obj->GetString() == kSignTypeValue; 46 } 47 48 void CPDF_CryptoHandler::CryptBlock(bool bEncrypt, 49 uint32_t objnum, 50 uint32_t gennum, 51 const uint8_t* src_buf, 52 uint32_t src_size, 53 uint8_t* dest_buf, 54 uint32_t& dest_size) { 55 if (m_Cipher == FXCIPHER_NONE) { 56 memcpy(dest_buf, src_buf, src_size); 57 return; 58 } 59 uint8_t realkey[16]; 60 int realkeylen = 16; 61 if (m_Cipher != FXCIPHER_AES || m_KeyLen != 32) { 62 uint8_t key1[32]; 63 PopulateKey(objnum, gennum, key1); 64 65 if (m_Cipher == FXCIPHER_AES) { 66 memcpy(key1 + m_KeyLen + 5, "sAlT", 4); 67 } 68 CRYPT_MD5Generate( 69 key1, m_Cipher == FXCIPHER_AES ? m_KeyLen + 9 : m_KeyLen + 5, realkey); 70 realkeylen = m_KeyLen + 5; 71 if (realkeylen > 16) { 72 realkeylen = 16; 73 } 74 } 75 if (m_Cipher == FXCIPHER_AES) { 76 CRYPT_AESSetKey(m_pAESContext.get(), 16, 77 m_KeyLen == 32 ? m_EncryptKey : realkey, m_KeyLen, 78 bEncrypt); 79 if (bEncrypt) { 80 uint8_t iv[16]; 81 for (int i = 0; i < 16; i++) { 82 iv[i] = (uint8_t)rand(); 83 } 84 CRYPT_AESSetIV(m_pAESContext.get(), iv); 85 memcpy(dest_buf, iv, 16); 86 int nblocks = src_size / 16; 87 CRYPT_AESEncrypt(m_pAESContext.get(), dest_buf + 16, src_buf, 88 nblocks * 16); 89 uint8_t padding[16]; 90 memcpy(padding, src_buf + nblocks * 16, src_size % 16); 91 memset(padding + src_size % 16, 16 - src_size % 16, 16 - src_size % 16); 92 CRYPT_AESEncrypt(m_pAESContext.get(), dest_buf + nblocks * 16 + 16, 93 padding, 16); 94 dest_size = 32 + nblocks * 16; 95 } else { 96 CRYPT_AESSetIV(m_pAESContext.get(), src_buf); 97 CRYPT_AESDecrypt(m_pAESContext.get(), dest_buf, src_buf + 16, 98 src_size - 16); 99 dest_size = src_size - 16; 100 dest_size -= dest_buf[dest_size - 1]; 101 } 102 } else { 103 ASSERT(dest_size == src_size); 104 if (dest_buf != src_buf) { 105 memcpy(dest_buf, src_buf, src_size); 106 } 107 CRYPT_ArcFourCryptBlock(dest_buf, dest_size, realkey, realkeylen); 108 } 109 } 110 111 struct AESCryptContext { 112 bool m_bIV; 113 uint8_t m_Block[16]; 114 uint32_t m_BlockOffset; 115 CRYPT_aes_context m_Context; 116 }; 117 118 void* CPDF_CryptoHandler::CryptStart(uint32_t objnum, 119 uint32_t gennum, 120 bool bEncrypt) { 121 if (m_Cipher == FXCIPHER_NONE) { 122 return this; 123 } 124 if (m_Cipher == FXCIPHER_AES && m_KeyLen == 32) { 125 AESCryptContext* pContext = FX_Alloc(AESCryptContext, 1); 126 pContext->m_bIV = true; 127 pContext->m_BlockOffset = 0; 128 CRYPT_AESSetKey(&pContext->m_Context, 16, m_EncryptKey, 32, bEncrypt); 129 if (bEncrypt) { 130 for (int i = 0; i < 16; i++) { 131 pContext->m_Block[i] = (uint8_t)rand(); 132 } 133 CRYPT_AESSetIV(&pContext->m_Context, pContext->m_Block); 134 } 135 return pContext; 136 } 137 uint8_t key1[48]; 138 PopulateKey(objnum, gennum, key1); 139 140 if (m_Cipher == FXCIPHER_AES) { 141 memcpy(key1 + m_KeyLen + 5, "sAlT", 4); 142 } 143 uint8_t realkey[16]; 144 CRYPT_MD5Generate( 145 key1, m_Cipher == FXCIPHER_AES ? m_KeyLen + 9 : m_KeyLen + 5, realkey); 146 int realkeylen = m_KeyLen + 5; 147 if (realkeylen > 16) { 148 realkeylen = 16; 149 } 150 if (m_Cipher == FXCIPHER_AES) { 151 AESCryptContext* pContext = FX_Alloc(AESCryptContext, 1); 152 pContext->m_bIV = true; 153 pContext->m_BlockOffset = 0; 154 CRYPT_AESSetKey(&pContext->m_Context, 16, realkey, 16, bEncrypt); 155 if (bEncrypt) { 156 for (int i = 0; i < 16; i++) { 157 pContext->m_Block[i] = (uint8_t)rand(); 158 } 159 CRYPT_AESSetIV(&pContext->m_Context, pContext->m_Block); 160 } 161 return pContext; 162 } 163 CRYPT_rc4_context* pContext = FX_Alloc(CRYPT_rc4_context, 1); 164 CRYPT_ArcFourSetup(pContext, realkey, realkeylen); 165 return pContext; 166 } 167 168 bool CPDF_CryptoHandler::CryptStream(void* context, 169 const uint8_t* src_buf, 170 uint32_t src_size, 171 CFX_BinaryBuf& dest_buf, 172 bool bEncrypt) { 173 if (!context) { 174 return false; 175 } 176 if (m_Cipher == FXCIPHER_NONE) { 177 dest_buf.AppendBlock(src_buf, src_size); 178 return true; 179 } 180 if (m_Cipher == FXCIPHER_RC4) { 181 int old_size = dest_buf.GetSize(); 182 dest_buf.AppendBlock(src_buf, src_size); 183 CRYPT_ArcFourCrypt(reinterpret_cast<CRYPT_rc4_context*>(context), 184 dest_buf.GetBuffer() + old_size, src_size); 185 return true; 186 } 187 AESCryptContext* pContext = reinterpret_cast<AESCryptContext*>(context); 188 if (pContext->m_bIV && bEncrypt) { 189 dest_buf.AppendBlock(pContext->m_Block, 16); 190 pContext->m_bIV = false; 191 } 192 uint32_t src_off = 0; 193 uint32_t src_left = src_size; 194 while (1) { 195 uint32_t copy_size = 16 - pContext->m_BlockOffset; 196 if (copy_size > src_left) { 197 copy_size = src_left; 198 } 199 memcpy(pContext->m_Block + pContext->m_BlockOffset, src_buf + src_off, 200 copy_size); 201 src_off += copy_size; 202 src_left -= copy_size; 203 pContext->m_BlockOffset += copy_size; 204 if (pContext->m_BlockOffset == 16) { 205 if (!bEncrypt && pContext->m_bIV) { 206 CRYPT_AESSetIV(&pContext->m_Context, pContext->m_Block); 207 pContext->m_bIV = false; 208 pContext->m_BlockOffset = 0; 209 } else if (src_off < src_size) { 210 uint8_t block_buf[16]; 211 if (bEncrypt) { 212 CRYPT_AESEncrypt(&pContext->m_Context, block_buf, pContext->m_Block, 213 16); 214 } else { 215 CRYPT_AESDecrypt(&pContext->m_Context, block_buf, pContext->m_Block, 216 16); 217 } 218 dest_buf.AppendBlock(block_buf, 16); 219 pContext->m_BlockOffset = 0; 220 } 221 } 222 if (!src_left) { 223 break; 224 } 225 } 226 return true; 227 } 228 bool CPDF_CryptoHandler::CryptFinish(void* context, 229 CFX_BinaryBuf& dest_buf, 230 bool bEncrypt) { 231 if (!context) { 232 return false; 233 } 234 if (m_Cipher == FXCIPHER_NONE) { 235 return true; 236 } 237 if (m_Cipher == FXCIPHER_RC4) { 238 FX_Free(context); 239 return true; 240 } 241 AESCryptContext* pContext = (AESCryptContext*)context; 242 if (bEncrypt) { 243 uint8_t block_buf[16]; 244 if (pContext->m_BlockOffset == 16) { 245 CRYPT_AESEncrypt(&pContext->m_Context, block_buf, pContext->m_Block, 16); 246 dest_buf.AppendBlock(block_buf, 16); 247 pContext->m_BlockOffset = 0; 248 } 249 memset(pContext->m_Block + pContext->m_BlockOffset, 250 (uint8_t)(16 - pContext->m_BlockOffset), 251 16 - pContext->m_BlockOffset); 252 CRYPT_AESEncrypt(&pContext->m_Context, block_buf, pContext->m_Block, 16); 253 dest_buf.AppendBlock(block_buf, 16); 254 } else if (pContext->m_BlockOffset == 16) { 255 uint8_t block_buf[16]; 256 CRYPT_AESDecrypt(&pContext->m_Context, block_buf, pContext->m_Block, 16); 257 if (block_buf[15] <= 16) { 258 dest_buf.AppendBlock(block_buf, 16 - block_buf[15]); 259 } 260 } 261 FX_Free(pContext); 262 return true; 263 } 264 265 ByteString CPDF_CryptoHandler::Decrypt(uint32_t objnum, 266 uint32_t gennum, 267 const ByteString& str) { 268 CFX_BinaryBuf dest_buf; 269 void* context = DecryptStart(objnum, gennum); 270 DecryptStream(context, str.raw_str(), str.GetLength(), dest_buf); 271 DecryptFinish(context, dest_buf); 272 return ByteString(dest_buf.GetBuffer(), dest_buf.GetSize()); 273 } 274 275 void* CPDF_CryptoHandler::DecryptStart(uint32_t objnum, uint32_t gennum) { 276 return CryptStart(objnum, gennum, false); 277 } 278 uint32_t CPDF_CryptoHandler::DecryptGetSize(uint32_t src_size) { 279 return m_Cipher == FXCIPHER_AES ? src_size - 16 : src_size; 280 } 281 282 bool CPDF_CryptoHandler::IsCipherAES() const { 283 return m_Cipher == FXCIPHER_AES; 284 } 285 286 std::unique_ptr<CPDF_Object> CPDF_CryptoHandler::DecryptObjectTree( 287 std::unique_ptr<CPDF_Object> object) { 288 if (!object) 289 return nullptr; 290 291 struct MayBeSignature { 292 const CPDF_Dictionary* parent; 293 CPDF_Object* contents; 294 }; 295 296 std::stack<MayBeSignature> may_be_sign_dictionaries; 297 const uint32_t obj_num = object->GetObjNum(); 298 const uint32_t gen_num = object->GetGenNum(); 299 300 CPDF_Object* object_to_decrypt = object.get(); 301 while (object_to_decrypt) { 302 CPDF_NonConstObjectWalker walker(object_to_decrypt); 303 object_to_decrypt = nullptr; 304 while (CPDF_Object* child = walker.GetNext()) { 305 const CPDF_Dictionary* parent_dict = 306 walker.GetParent() ? walker.GetParent()->GetDict() : nullptr; 307 if (walker.dictionary_key() == kContentsKey && 308 (parent_dict->KeyExist(kTypeKey) || parent_dict->KeyExist(kFTKey))) { 309 // This object may be contents of signature dictionary. 310 // But now values of 'Type' and 'FT' of dictionary keys are encrypted, 311 // and we can not check this. 312 // Temporary skip it, to prevent signature corruption. 313 // It will be decrypted on next interations, if this is not contents of 314 // signature dictionary. 315 may_be_sign_dictionaries.push(MayBeSignature({parent_dict, child})); 316 walker.SkipWalkIntoCurrentObject(); 317 continue; 318 } 319 // Strings decryption. 320 if (child->IsString()) { 321 // TODO(art-snake): Move decryption into the CPDF_String class. 322 CPDF_String* str = child->AsString(); 323 str->SetString(Decrypt(obj_num, gen_num, str->GetString())); 324 } 325 // Stream decryption. 326 if (child->IsStream()) { 327 // TODO(art-snake): Move decryption into the CPDF_Stream class. 328 CPDF_Stream* stream = child->AsStream(); 329 auto stream_access = pdfium::MakeRetain<CPDF_StreamAcc>(stream); 330 stream_access->LoadAllDataRaw(); 331 332 if (IsCipherAES() && stream_access->GetSize() < 16) { 333 stream->SetData(nullptr, 0); 334 continue; 335 } 336 337 CFX_BinaryBuf decrypted_buf; 338 decrypted_buf.EstimateSize(DecryptGetSize(stream_access->GetSize())); 339 340 void* context = DecryptStart(obj_num, gen_num); 341 bool decrypt_result = 342 DecryptStream(context, stream_access->GetData(), 343 stream_access->GetSize(), decrypted_buf); 344 decrypt_result &= DecryptFinish(context, decrypted_buf); 345 if (decrypt_result) { 346 const uint32_t decrypted_size = decrypted_buf.GetSize(); 347 stream->SetData(decrypted_buf.DetachBuffer(), decrypted_size); 348 } else { 349 // Decryption failed, set the stream to empty 350 stream->SetData(nullptr, 0); 351 } 352 } 353 } 354 // Signature dictionaries check. 355 while (!may_be_sign_dictionaries.empty()) { 356 auto dict_and_contents = std::move(may_be_sign_dictionaries.top()); 357 may_be_sign_dictionaries.pop(); 358 if (!IsSignatureDictionary(dict_and_contents.parent)) { 359 // This is not signature dictionary. Do decrypt its contents. 360 object_to_decrypt = dict_and_contents.contents; 361 break; 362 } 363 } 364 } 365 return object; 366 } 367 368 bool CPDF_CryptoHandler::DecryptStream(void* context, 369 const uint8_t* src_buf, 370 uint32_t src_size, 371 CFX_BinaryBuf& dest_buf) { 372 return CryptStream(context, src_buf, src_size, dest_buf, false); 373 } 374 375 bool CPDF_CryptoHandler::DecryptFinish(void* context, CFX_BinaryBuf& dest_buf) { 376 return CryptFinish(context, dest_buf, false); 377 } 378 uint32_t CPDF_CryptoHandler::EncryptGetSize(uint32_t objnum, 379 uint32_t version, 380 const uint8_t* src_buf, 381 uint32_t src_size) { 382 if (m_Cipher == FXCIPHER_AES) { 383 return src_size + 32; 384 } 385 return src_size; 386 } 387 388 bool CPDF_CryptoHandler::EncryptContent(uint32_t objnum, 389 uint32_t gennum, 390 const uint8_t* src_buf, 391 uint32_t src_size, 392 uint8_t* dest_buf, 393 uint32_t& dest_size) { 394 CryptBlock(true, objnum, gennum, src_buf, src_size, dest_buf, dest_size); 395 return true; 396 } 397 398 CPDF_CryptoHandler::CPDF_CryptoHandler(int cipher, 399 const uint8_t* key, 400 int keylen) 401 : m_KeyLen(std::min(keylen, 32)), m_Cipher(cipher) { 402 ASSERT(cipher != FXCIPHER_AES || keylen == 16 || keylen == 24 || 403 keylen == 32); 404 ASSERT(cipher != FXCIPHER_AES2 || keylen == 32); 405 ASSERT(cipher != FXCIPHER_RC4 || (keylen >= 5 && keylen <= 16)); 406 407 if (m_Cipher != FXCIPHER_NONE) 408 memcpy(m_EncryptKey, key, m_KeyLen); 409 410 if (m_Cipher == FXCIPHER_AES) 411 m_pAESContext.reset(FX_Alloc(CRYPT_aes_context, 1)); 412 } 413 414 CPDF_CryptoHandler::~CPDF_CryptoHandler() {} 415 416 void CPDF_CryptoHandler::PopulateKey(uint32_t objnum, 417 uint32_t gennum, 418 uint8_t* key) { 419 memcpy(key, m_EncryptKey, m_KeyLen); 420 key[m_KeyLen + 0] = (uint8_t)objnum; 421 key[m_KeyLen + 1] = (uint8_t)(objnum >> 8); 422 key[m_KeyLen + 2] = (uint8_t)(objnum >> 16); 423 key[m_KeyLen + 3] = (uint8_t)gennum; 424 key[m_KeyLen + 4] = (uint8_t)(gennum >> 8); 425 } 426