CFX_ByteString CPDF_StandardSecurityHandler::GetUserPassword( const uint8_t* owner_pass, FX_DWORD pass_size, int32_t key_len) { CFX_ByteString okey = m_pEncryptDict->GetString(FX_BSTRC("O")); uint8_t passcode[32]; FX_DWORD i; for (i = 0; i < 32; i++) { passcode[i] = i < pass_size ? owner_pass[i] : defpasscode[i - pass_size]; } uint8_t digest[16]; CRYPT_MD5Generate(passcode, 32, digest); if (m_Revision >= 3) { for (int i = 0; i < 50; i++) { CRYPT_MD5Generate(digest, 16, digest); } } uint8_t enckey[32]; FXSYS_memset(enckey, 0, sizeof(enckey)); FX_DWORD copy_len = key_len; if (copy_len > sizeof(digest)) { copy_len = sizeof(digest); } FXSYS_memcpy(enckey, digest, copy_len); int okeylen = okey.GetLength(); if (okeylen > 32) { okeylen = 32; } uint8_t okeybuf[64]; FXSYS_memset(okeybuf, 0, sizeof(okeybuf)); FXSYS_memcpy(okeybuf, okey.c_str(), okeylen); if (m_Revision == 2) { CRYPT_ArcFourCryptBlock(okeybuf, okeylen, enckey, key_len); } else { for (int i = 19; i >= 0; i--) { uint8_t tempkey[32]; FXSYS_memset(tempkey, 0, sizeof(tempkey)); for (int j = 0; j < m_KeyLen; j++) { tempkey[j] = enckey[j] ^ i; } CRYPT_ArcFourCryptBlock(okeybuf, okeylen, tempkey, key_len); } } int len = 32; while (len && defpasscode[len - 1] == okeybuf[len - 1]) { len--; } return CFX_ByteString(okeybuf, len); }
void CPDF_StandardCryptoHandler::CryptBlock(FX_BOOL bEncrypt, FX_DWORD objnum, FX_DWORD gennum, FX_LPCBYTE src_buf, FX_DWORD src_size, FX_LPBYTE dest_buf, FX_DWORD& dest_size) { if (m_Cipher == FXCIPHER_NONE) { FXSYS_memcpy32(dest_buf, src_buf, src_size); return; } FX_BYTE realkey[16]; int realkeylen = 16; if (m_Cipher != FXCIPHER_AES || m_KeyLen != 32) { FX_BYTE key1[32]; FXSYS_memcpy32(key1, m_EncryptKey, m_KeyLen); key1[m_KeyLen + 0] = (FX_BYTE)objnum; key1[m_KeyLen + 1] = (FX_BYTE)(objnum >> 8); key1[m_KeyLen + 2] = (FX_BYTE)(objnum >> 16); key1[m_KeyLen + 3] = (FX_BYTE)gennum; key1[m_KeyLen + 4] = (FX_BYTE)(gennum >> 8); FXSYS_memcpy32(key1 + m_KeyLen, &objnum, 3); FXSYS_memcpy32(key1 + m_KeyLen + 3, &gennum, 2); if (m_Cipher == FXCIPHER_AES) { FXSYS_memcpy32(key1 + m_KeyLen + 5, "sAlT", 4); } CRYPT_MD5Generate(key1, m_Cipher == FXCIPHER_AES ? m_KeyLen + 9 : m_KeyLen + 5, realkey); realkeylen = m_KeyLen + 5; if (realkeylen > 16) { realkeylen = 16; } }
void CPDF_CryptoHandler::CryptBlock(bool bEncrypt, uint32_t objnum, uint32_t gennum, const uint8_t* src_buf, uint32_t src_size, uint8_t* dest_buf, uint32_t& dest_size) { if (m_Cipher == FXCIPHER_NONE) { FXSYS_memcpy(dest_buf, src_buf, src_size); return; } uint8_t realkey[16]; int realkeylen = 16; if (m_Cipher != FXCIPHER_AES || m_KeyLen != 32) { uint8_t key1[32]; PopulateKey(objnum, gennum, key1); if (m_Cipher == FXCIPHER_AES) { FXSYS_memcpy(key1 + m_KeyLen + 5, "sAlT", 4); } CRYPT_MD5Generate( key1, m_Cipher == FXCIPHER_AES ? m_KeyLen + 9 : m_KeyLen + 5, realkey); realkeylen = m_KeyLen + 5; if (realkeylen > 16) { realkeylen = 16; } } if (m_Cipher == FXCIPHER_AES) { CRYPT_AESSetKey(m_pAESContext, 16, m_KeyLen == 32 ? m_EncryptKey : realkey, m_KeyLen, bEncrypt); if (bEncrypt) { uint8_t iv[16]; for (int i = 0; i < 16; i++) { iv[i] = (uint8_t)rand(); } CRYPT_AESSetIV(m_pAESContext, iv); FXSYS_memcpy(dest_buf, iv, 16); int nblocks = src_size / 16; CRYPT_AESEncrypt(m_pAESContext, dest_buf + 16, src_buf, nblocks * 16); uint8_t padding[16]; FXSYS_memcpy(padding, src_buf + nblocks * 16, src_size % 16); FXSYS_memset(padding + src_size % 16, 16 - src_size % 16, 16 - src_size % 16); CRYPT_AESEncrypt(m_pAESContext, dest_buf + nblocks * 16 + 16, padding, 16); dest_size = 32 + nblocks * 16; } else { CRYPT_AESSetIV(m_pAESContext, src_buf); CRYPT_AESDecrypt(m_pAESContext, dest_buf, src_buf + 16, src_size - 16); dest_size = src_size - 16; dest_size -= dest_buf[dest_size - 1]; } } else { ASSERT(dest_size == src_size); if (dest_buf != src_buf) { FXSYS_memcpy(dest_buf, src_buf, src_size); } CRYPT_ArcFourCryptBlock(dest_buf, dest_size, realkey, realkeylen); } }
void* CPDF_CryptoHandler::CryptStart(uint32_t objnum, uint32_t gennum, bool bEncrypt) { if (m_Cipher == FXCIPHER_NONE) { return this; } if (m_Cipher == FXCIPHER_AES && m_KeyLen == 32) { AESCryptContext* pContext = FX_Alloc(AESCryptContext, 1); pContext->m_bIV = true; pContext->m_BlockOffset = 0; CRYPT_AESSetKey(pContext->m_Context, 16, m_EncryptKey, 32, bEncrypt); if (bEncrypt) { for (int i = 0; i < 16; i++) { pContext->m_Block[i] = (uint8_t)rand(); } CRYPT_AESSetIV(pContext->m_Context, pContext->m_Block); } return pContext; } uint8_t key1[48]; PopulateKey(objnum, gennum, key1); if (m_Cipher == FXCIPHER_AES) { FXSYS_memcpy(key1 + m_KeyLen + 5, "sAlT", 4); } uint8_t realkey[16]; CRYPT_MD5Generate( key1, m_Cipher == FXCIPHER_AES ? m_KeyLen + 9 : m_KeyLen + 5, realkey); int realkeylen = m_KeyLen + 5; if (realkeylen > 16) { realkeylen = 16; } if (m_Cipher == FXCIPHER_AES) { AESCryptContext* pContext = FX_Alloc(AESCryptContext, 1); pContext->m_bIV = true; pContext->m_BlockOffset = 0; CRYPT_AESSetKey(pContext->m_Context, 16, realkey, 16, bEncrypt); if (bEncrypt) { for (int i = 0; i < 16; i++) { pContext->m_Block[i] = (uint8_t)rand(); } CRYPT_AESSetIV(pContext->m_Context, pContext->m_Block); } return pContext; } CRYPT_rc4_context* pContext = FX_Alloc(CRYPT_rc4_context, 1); CRYPT_ArcFourSetup(pContext, realkey, realkeylen); return pContext; }
void CalcEncryptKey(CPDF_Dictionary* pEncrypt, const uint8_t* password, FX_DWORD pass_size, uint8_t* key, int keylen, FX_BOOL bIgnoreMeta, CPDF_Array* pIdArray) { int revision = pEncrypt->GetInteger(FX_BSTRC("R")); uint8_t passcode[32]; for (FX_DWORD i = 0; i < 32; i++) { passcode[i] = i < pass_size ? password[i] : defpasscode[i - pass_size]; } uint8_t md5[100]; CRYPT_MD5Start(md5); CRYPT_MD5Update(md5, passcode, 32); CFX_ByteString okey = pEncrypt->GetString(FX_BSTRC("O")); CRYPT_MD5Update(md5, (uint8_t*)okey.c_str(), okey.GetLength()); FX_DWORD perm = pEncrypt->GetInteger(FX_BSTRC("P")); CRYPT_MD5Update(md5, (uint8_t*)&perm, 4); if (pIdArray) { CFX_ByteString id = pIdArray->GetString(0); CRYPT_MD5Update(md5, (uint8_t*)id.c_str(), id.GetLength()); } if (!bIgnoreMeta && revision >= 3 && !pEncrypt->GetInteger(FX_BSTRC("EncryptMetadata"), 1)) { FX_DWORD tag = (FX_DWORD)-1; CRYPT_MD5Update(md5, (uint8_t*)&tag, 4); } uint8_t digest[16]; CRYPT_MD5Finish(md5, digest); FX_DWORD copy_len = keylen; if (copy_len > sizeof(digest)) { copy_len = sizeof(digest); } if (revision >= 3) { for (int i = 0; i < 50; i++) { CRYPT_MD5Generate(digest, copy_len, digest); } } FXSYS_memset(key, 0, keylen); FXSYS_memcpy(key, digest, copy_len); }
void CPDF_SecurityHandler::OnCreate(CPDF_Dictionary* pEncryptDict, CPDF_Array* pIdArray, const uint8_t* user_pass, uint32_t user_size, const uint8_t* owner_pass, uint32_t owner_size, FX_BOOL bDefault, uint32_t type) { int cipher = 0, key_len = 0; if (!LoadDict(pEncryptDict, type, cipher, key_len)) { return; } if (bDefault && (!owner_pass || owner_size == 0)) { owner_pass = user_pass; owner_size = user_size; } if (m_Revision >= 5) { int t = (int)time(nullptr); uint8_t sha[128]; CRYPT_SHA256Start(sha); CRYPT_SHA256Update(sha, (uint8_t*)&t, sizeof t); CRYPT_SHA256Update(sha, m_EncryptKey, 32); CRYPT_SHA256Update(sha, (uint8_t*)"there", 5); CRYPT_SHA256Finish(sha, m_EncryptKey); AES256_SetPassword(pEncryptDict, user_pass, user_size, FALSE, m_EncryptKey); if (bDefault) { AES256_SetPassword(pEncryptDict, owner_pass, owner_size, TRUE, m_EncryptKey); AES256_SetPerms(pEncryptDict, m_Permissions, pEncryptDict->GetBooleanBy("EncryptMetadata", true), m_EncryptKey); } return; } if (bDefault) { uint8_t passcode[32]; for (uint32_t i = 0; i < 32; i++) { passcode[i] = i < owner_size ? owner_pass[i] : defpasscode[i - owner_size]; } uint8_t digest[16]; CRYPT_MD5Generate(passcode, 32, digest); if (m_Revision >= 3) { for (uint32_t i = 0; i < 50; i++) CRYPT_MD5Generate(digest, 16, digest); } uint8_t enckey[32]; FXSYS_memcpy(enckey, digest, key_len); for (uint32_t i = 0; i < 32; i++) { passcode[i] = i < user_size ? user_pass[i] : defpasscode[i - user_size]; } CRYPT_ArcFourCryptBlock(passcode, 32, enckey, key_len); uint8_t tempkey[32]; if (m_Revision >= 3) { for (uint8_t i = 1; i <= 19; i++) { for (int j = 0; j < key_len; j++) tempkey[j] = enckey[j] ^ i; CRYPT_ArcFourCryptBlock(passcode, 32, tempkey, key_len); } } pEncryptDict->SetAtString("O", CFX_ByteString(passcode, 32)); } CalcEncryptKey(m_pEncryptDict, (uint8_t*)user_pass, user_size, m_EncryptKey, key_len, FALSE, pIdArray); if (m_Revision < 3) { uint8_t tempbuf[32]; FXSYS_memcpy(tempbuf, defpasscode, 32); CRYPT_ArcFourCryptBlock(tempbuf, 32, m_EncryptKey, key_len); pEncryptDict->SetAtString("U", CFX_ByteString(tempbuf, 32)); } else { uint8_t md5[100]; CRYPT_MD5Start(md5); CRYPT_MD5Update(md5, defpasscode, 32); if (pIdArray) { CFX_ByteString id = pIdArray->GetStringAt(0); CRYPT_MD5Update(md5, (uint8_t*)id.c_str(), id.GetLength()); } uint8_t digest[32]; CRYPT_MD5Finish(md5, digest); CRYPT_ArcFourCryptBlock(digest, 16, m_EncryptKey, key_len); uint8_t tempkey[32]; for (uint8_t i = 1; i <= 19; i++) { for (int j = 0; j < key_len; j++) { tempkey[j] = m_EncryptKey[j] ^ i; } CRYPT_ArcFourCryptBlock(digest, 16, tempkey, key_len); } CRYPT_MD5Generate(digest, 16, digest + 16); pEncryptDict->SetAtString("U", CFX_ByteString(digest, 32)); } }
void CPDF_StandardSecurityHandler::OnCreate(CPDF_Dictionary* pEncryptDict, CPDF_Array* pIdArray, FX_LPCBYTE user_pass, FX_DWORD user_size, FX_LPCBYTE owner_pass, FX_DWORD owner_size, FX_BOOL bDefault, FX_DWORD type) { int cipher = 0, key_len = 0; if (!LoadDict(pEncryptDict, type, cipher, key_len)) { return; } if (bDefault && (owner_pass == NULL || owner_size == 0)) { owner_pass = user_pass; owner_size = user_size; } if (m_Revision >= 5) { int t = (int)time(NULL); FX_BYTE sha[128]; CRYPT_SHA256Start(sha); CRYPT_SHA256Update(sha, (FX_BYTE*)&t, sizeof t); CRYPT_SHA256Update(sha, m_EncryptKey, 32); CRYPT_SHA256Update(sha, (FX_BYTE*)"there", 5); CRYPT_SHA256Finish(sha, m_EncryptKey); AES256_SetPassword(pEncryptDict, user_pass, user_size, FALSE, m_EncryptKey); if (bDefault) { AES256_SetPassword(pEncryptDict, owner_pass, owner_size, TRUE, m_EncryptKey); AES256_SetPerms(pEncryptDict, m_Permissions, pEncryptDict->GetBoolean(FX_BSTRC("EncryptMetadata"), TRUE), m_EncryptKey); } return; } if (bDefault) { FX_BYTE passcode[32]; FX_DWORD i; for (i = 0; i < 32; i ++) { passcode[i] = i < owner_size ? owner_pass[i] : defpasscode[i - owner_size]; } FX_BYTE digest[16]; CRYPT_MD5Generate(passcode, 32, digest); if (m_Revision >= 3) { for (int i = 0; i < 50; i ++) { CRYPT_MD5Generate(digest, 16, digest); } } FX_BYTE enckey[32]; FXSYS_memcpy32(enckey, digest, key_len); for (i = 0; i < 32; i ++) { passcode[i] = i < user_size ? user_pass[i] : defpasscode[i - user_size]; } CRYPT_ArcFourCryptBlock(passcode, 32, enckey, key_len); FX_BYTE tempkey[32]; if (m_Revision >= 3) { for (i = 1; i <= 19; i ++) { for (int j = 0; j < key_len; j ++) { tempkey[j] = enckey[j] ^ (FX_BYTE)i; } CRYPT_ArcFourCryptBlock(passcode, 32, tempkey, key_len); } } pEncryptDict->SetAtString(FX_BSTRC("O"), CFX_ByteString(passcode, 32)); } CalcEncryptKey(m_pEncryptDict, (FX_LPBYTE)user_pass, user_size, m_EncryptKey, key_len, FALSE, pIdArray); if (m_Revision < 3) { FX_BYTE tempbuf[32]; FXSYS_memcpy32(tempbuf, defpasscode, 32); CRYPT_ArcFourCryptBlock(tempbuf, 32, m_EncryptKey, key_len); pEncryptDict->SetAtString(FX_BSTRC("U"), CFX_ByteString(tempbuf, 32)); } else { FX_BYTE md5[100]; CRYPT_MD5Start(md5); CRYPT_MD5Update(md5, defpasscode, 32); if (pIdArray) { CFX_ByteString id = pIdArray->GetString(0); CRYPT_MD5Update(md5, (FX_LPBYTE)(FX_LPCSTR)id, id.GetLength()); } FX_BYTE digest[32]; CRYPT_MD5Finish(md5, digest); CRYPT_ArcFourCryptBlock(digest, 16, m_EncryptKey, key_len); FX_BYTE tempkey[32]; for (int i = 1; i <= 19; i ++) { for (int j = 0; j < key_len; j ++) { tempkey[j] = m_EncryptKey[j] ^ (FX_BYTE)i; } CRYPT_ArcFourCryptBlock(digest, 16, tempkey, key_len); } CRYPT_MD5Generate(digest, 16, digest + 16); pEncryptDict->SetAtString(FX_BSTRC("U"), CFX_ByteString(digest, 32)); } }