Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(41)

Side by Side Diff: core/fpdfapi/fpdf_parser/cpdf_standard_crypto_handler.cpp

Issue 1898173002: Remove IPDF_CryptoHandler and IPDF_SecurityHandler. (Closed) Base URL: https://pdfium.googlesource.com/pdfium.git@master
Patch Set: Created 4 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
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/fpdf_parser/cpdf_standard_crypto_handler.h"
8
9 #include <time.h>
10
11 #include "core/fdrm/crypto/include/fx_crypt.h"
12 #include "core/fpdfapi/fpdf_parser/include/cpdf_parser.h"
13 #include "core/fpdfapi/fpdf_parser/include/cpdf_simple_parser.h"
14 #include "core/fpdfapi/fpdf_parser/ipdf_security_handler.h"
15
16 IPDF_CryptoHandler::~IPDF_CryptoHandler() {}
17
18 void IPDF_CryptoHandler::Decrypt(uint32_t objnum,
19 uint32_t gennum,
20 CFX_ByteString& str) {
21 CFX_BinaryBuf dest_buf;
22 void* context = DecryptStart(objnum, gennum);
23 DecryptStream(context, str.raw_str(), str.GetLength(), dest_buf);
24 DecryptFinish(context, dest_buf);
25 str = CFX_ByteString(dest_buf.GetBuffer(), dest_buf.GetSize());
26 }
27
28 void CPDF_StandardCryptoHandler::CryptBlock(FX_BOOL bEncrypt,
29 uint32_t objnum,
30 uint32_t gennum,
31 const uint8_t* src_buf,
32 uint32_t src_size,
33 uint8_t* dest_buf,
34 uint32_t& dest_size) {
35 if (m_Cipher == FXCIPHER_NONE) {
36 FXSYS_memcpy(dest_buf, src_buf, src_size);
37 return;
38 }
39 uint8_t realkey[16];
40 int realkeylen = 16;
41 if (m_Cipher != FXCIPHER_AES || m_KeyLen != 32) {
42 uint8_t key1[32];
43 FXSYS_memcpy(key1, m_EncryptKey, m_KeyLen);
44 key1[m_KeyLen + 0] = (uint8_t)objnum;
45 key1[m_KeyLen + 1] = (uint8_t)(objnum >> 8);
46 key1[m_KeyLen + 2] = (uint8_t)(objnum >> 16);
47 key1[m_KeyLen + 3] = (uint8_t)gennum;
48 key1[m_KeyLen + 4] = (uint8_t)(gennum >> 8);
49 FXSYS_memcpy(key1 + m_KeyLen, &objnum, 3);
50 FXSYS_memcpy(key1 + m_KeyLen + 3, &gennum, 2);
51 if (m_Cipher == FXCIPHER_AES) {
52 FXSYS_memcpy(key1 + m_KeyLen + 5, "sAlT", 4);
53 }
54 CRYPT_MD5Generate(
55 key1, m_Cipher == FXCIPHER_AES ? m_KeyLen + 9 : m_KeyLen + 5, realkey);
56 realkeylen = m_KeyLen + 5;
57 if (realkeylen > 16) {
58 realkeylen = 16;
59 }
60 }
61 if (m_Cipher == FXCIPHER_AES) {
62 CRYPT_AESSetKey(m_pAESContext, 16, m_KeyLen == 32 ? m_EncryptKey : realkey,
63 m_KeyLen, bEncrypt);
64 if (bEncrypt) {
65 uint8_t iv[16];
66 for (int i = 0; i < 16; i++) {
67 iv[i] = (uint8_t)rand();
68 }
69 CRYPT_AESSetIV(m_pAESContext, iv);
70 FXSYS_memcpy(dest_buf, iv, 16);
71 int nblocks = src_size / 16;
72 CRYPT_AESEncrypt(m_pAESContext, dest_buf + 16, src_buf, nblocks * 16);
73 uint8_t padding[16];
74 FXSYS_memcpy(padding, src_buf + nblocks * 16, src_size % 16);
75 FXSYS_memset(padding + src_size % 16, 16 - src_size % 16,
76 16 - src_size % 16);
77 CRYPT_AESEncrypt(m_pAESContext, dest_buf + nblocks * 16 + 16, padding,
78 16);
79 dest_size = 32 + nblocks * 16;
80 } else {
81 CRYPT_AESSetIV(m_pAESContext, src_buf);
82 CRYPT_AESDecrypt(m_pAESContext, dest_buf, src_buf + 16, src_size - 16);
83 dest_size = src_size - 16;
84 dest_size -= dest_buf[dest_size - 1];
85 }
86 } else {
87 ASSERT(dest_size == src_size);
88 if (dest_buf != src_buf) {
89 FXSYS_memcpy(dest_buf, src_buf, src_size);
90 }
91 CRYPT_ArcFourCryptBlock(dest_buf, dest_size, realkey, realkeylen);
92 }
93 }
94
95 struct AESCryptContext {
96 uint8_t m_Context[2048];
97 FX_BOOL m_bIV;
98 uint8_t m_Block[16];
99 uint32_t m_BlockOffset;
100 };
101
102 void* CPDF_StandardCryptoHandler::CryptStart(uint32_t objnum,
103 uint32_t gennum,
104 FX_BOOL bEncrypt) {
105 if (m_Cipher == FXCIPHER_NONE) {
106 return this;
107 }
108 if (m_Cipher == FXCIPHER_AES && m_KeyLen == 32) {
109 AESCryptContext* pContext = FX_Alloc(AESCryptContext, 1);
110 pContext->m_bIV = TRUE;
111 pContext->m_BlockOffset = 0;
112 CRYPT_AESSetKey(pContext->m_Context, 16, m_EncryptKey, 32, bEncrypt);
113 if (bEncrypt) {
114 for (int i = 0; i < 16; i++) {
115 pContext->m_Block[i] = (uint8_t)rand();
116 }
117 CRYPT_AESSetIV(pContext->m_Context, pContext->m_Block);
118 }
119 return pContext;
120 }
121 uint8_t key1[48];
122 FXSYS_memcpy(key1, m_EncryptKey, m_KeyLen);
123 FXSYS_memcpy(key1 + m_KeyLen, &objnum, 3);
124 FXSYS_memcpy(key1 + m_KeyLen + 3, &gennum, 2);
125 if (m_Cipher == FXCIPHER_AES) {
126 FXSYS_memcpy(key1 + m_KeyLen + 5, "sAlT", 4);
127 }
128 uint8_t realkey[16];
129 CRYPT_MD5Generate(
130 key1, m_Cipher == FXCIPHER_AES ? m_KeyLen + 9 : m_KeyLen + 5, realkey);
131 int realkeylen = m_KeyLen + 5;
132 if (realkeylen > 16) {
133 realkeylen = 16;
134 }
135 if (m_Cipher == FXCIPHER_AES) {
136 AESCryptContext* pContext = FX_Alloc(AESCryptContext, 1);
137 pContext->m_bIV = TRUE;
138 pContext->m_BlockOffset = 0;
139 CRYPT_AESSetKey(pContext->m_Context, 16, realkey, 16, bEncrypt);
140 if (bEncrypt) {
141 for (int i = 0; i < 16; i++) {
142 pContext->m_Block[i] = (uint8_t)rand();
143 }
144 CRYPT_AESSetIV(pContext->m_Context, pContext->m_Block);
145 }
146 return pContext;
147 }
148 void* pContext = FX_Alloc(uint8_t, 1040);
149 CRYPT_ArcFourSetup(pContext, realkey, realkeylen);
150 return pContext;
151 }
152 FX_BOOL CPDF_StandardCryptoHandler::CryptStream(void* context,
153 const uint8_t* src_buf,
154 uint32_t src_size,
155 CFX_BinaryBuf& dest_buf,
156 FX_BOOL bEncrypt) {
157 if (!context) {
158 return FALSE;
159 }
160 if (m_Cipher == FXCIPHER_NONE) {
161 dest_buf.AppendBlock(src_buf, src_size);
162 return TRUE;
163 }
164 if (m_Cipher == FXCIPHER_RC4) {
165 int old_size = dest_buf.GetSize();
166 dest_buf.AppendBlock(src_buf, src_size);
167 CRYPT_ArcFourCrypt(context, dest_buf.GetBuffer() + old_size, src_size);
168 return TRUE;
169 }
170 AESCryptContext* pContext = (AESCryptContext*)context;
171 if (pContext->m_bIV && bEncrypt) {
172 dest_buf.AppendBlock(pContext->m_Block, 16);
173 pContext->m_bIV = FALSE;
174 }
175 uint32_t src_off = 0;
176 uint32_t src_left = src_size;
177 while (1) {
178 uint32_t copy_size = 16 - pContext->m_BlockOffset;
179 if (copy_size > src_left) {
180 copy_size = src_left;
181 }
182 FXSYS_memcpy(pContext->m_Block + pContext->m_BlockOffset, src_buf + src_off,
183 copy_size);
184 src_off += copy_size;
185 src_left -= copy_size;
186 pContext->m_BlockOffset += copy_size;
187 if (pContext->m_BlockOffset == 16) {
188 if (!bEncrypt && pContext->m_bIV) {
189 CRYPT_AESSetIV(pContext->m_Context, pContext->m_Block);
190 pContext->m_bIV = FALSE;
191 pContext->m_BlockOffset = 0;
192 } else if (src_off < src_size) {
193 uint8_t block_buf[16];
194 if (bEncrypt) {
195 CRYPT_AESEncrypt(pContext->m_Context, block_buf, pContext->m_Block,
196 16);
197 } else {
198 CRYPT_AESDecrypt(pContext->m_Context, block_buf, pContext->m_Block,
199 16);
200 }
201 dest_buf.AppendBlock(block_buf, 16);
202 pContext->m_BlockOffset = 0;
203 }
204 }
205 if (!src_left) {
206 break;
207 }
208 }
209 return TRUE;
210 }
211 FX_BOOL CPDF_StandardCryptoHandler::CryptFinish(void* context,
212 CFX_BinaryBuf& dest_buf,
213 FX_BOOL bEncrypt) {
214 if (!context) {
215 return FALSE;
216 }
217 if (m_Cipher == FXCIPHER_NONE) {
218 return TRUE;
219 }
220 if (m_Cipher == FXCIPHER_RC4) {
221 FX_Free(context);
222 return TRUE;
223 }
224 AESCryptContext* pContext = (AESCryptContext*)context;
225 if (bEncrypt) {
226 uint8_t block_buf[16];
227 if (pContext->m_BlockOffset == 16) {
228 CRYPT_AESEncrypt(pContext->m_Context, block_buf, pContext->m_Block, 16);
229 dest_buf.AppendBlock(block_buf, 16);
230 pContext->m_BlockOffset = 0;
231 }
232 FXSYS_memset(pContext->m_Block + pContext->m_BlockOffset,
233 (uint8_t)(16 - pContext->m_BlockOffset),
234 16 - pContext->m_BlockOffset);
235 CRYPT_AESEncrypt(pContext->m_Context, block_buf, pContext->m_Block, 16);
236 dest_buf.AppendBlock(block_buf, 16);
237 } else if (pContext->m_BlockOffset == 16) {
238 uint8_t block_buf[16];
239 CRYPT_AESDecrypt(pContext->m_Context, block_buf, pContext->m_Block, 16);
240 if (block_buf[15] <= 16) {
241 dest_buf.AppendBlock(block_buf, 16 - block_buf[15]);
242 }
243 }
244 FX_Free(pContext);
245 return TRUE;
246 }
247 void* CPDF_StandardCryptoHandler::DecryptStart(uint32_t objnum,
248 uint32_t gennum) {
249 return CryptStart(objnum, gennum, FALSE);
250 }
251 uint32_t CPDF_StandardCryptoHandler::DecryptGetSize(uint32_t src_size) {
252 return m_Cipher == FXCIPHER_AES ? src_size - 16 : src_size;
253 }
254
255 FX_BOOL CPDF_StandardCryptoHandler::Init(
256 CPDF_Dictionary* pEncryptDict,
257 IPDF_SecurityHandler* pSecurityHandler) {
258 const uint8_t* key;
259 if (!pSecurityHandler->GetCryptInfo(m_Cipher, key, m_KeyLen)) {
260 return FALSE;
261 }
262 if (m_KeyLen > 32 || m_KeyLen < 0) {
263 return FALSE;
264 }
265 if (m_Cipher != FXCIPHER_NONE) {
266 FXSYS_memcpy(m_EncryptKey, key, m_KeyLen);
267 }
268 if (m_Cipher == FXCIPHER_AES) {
269 m_pAESContext = FX_Alloc(uint8_t, 2048);
270 }
271 return TRUE;
272 }
273
274 FX_BOOL CPDF_StandardCryptoHandler::Init(int cipher,
275 const uint8_t* key,
276 int keylen) {
277 if (cipher == FXCIPHER_AES) {
278 switch (keylen) {
279 case 16:
280 case 24:
281 case 32:
282 break;
283 default:
284 return FALSE;
285 }
286 } else if (cipher == FXCIPHER_AES2) {
287 if (keylen != 32) {
288 return FALSE;
289 }
290 } else if (cipher == FXCIPHER_RC4) {
291 if (keylen < 5 || keylen > 16) {
292 return FALSE;
293 }
294 } else {
295 if (keylen > 32) {
296 keylen = 32;
297 }
298 }
299 m_Cipher = cipher;
300 m_KeyLen = keylen;
301 FXSYS_memcpy(m_EncryptKey, key, keylen);
302 if (m_Cipher == FXCIPHER_AES) {
303 m_pAESContext = FX_Alloc(uint8_t, 2048);
304 }
305 return TRUE;
306 }
307 FX_BOOL CPDF_StandardCryptoHandler::DecryptStream(void* context,
308 const uint8_t* src_buf,
309 uint32_t src_size,
310 CFX_BinaryBuf& dest_buf) {
311 return CryptStream(context, src_buf, src_size, dest_buf, FALSE);
312 }
313 FX_BOOL CPDF_StandardCryptoHandler::DecryptFinish(void* context,
314 CFX_BinaryBuf& dest_buf) {
315 return CryptFinish(context, dest_buf, FALSE);
316 }
317 uint32_t CPDF_StandardCryptoHandler::EncryptGetSize(uint32_t objnum,
318 uint32_t version,
319 const uint8_t* src_buf,
320 uint32_t src_size) {
321 if (m_Cipher == FXCIPHER_AES) {
322 return src_size + 32;
323 }
324 return src_size;
325 }
326 FX_BOOL CPDF_StandardCryptoHandler::EncryptContent(uint32_t objnum,
327 uint32_t gennum,
328 const uint8_t* src_buf,
329 uint32_t src_size,
330 uint8_t* dest_buf,
331 uint32_t& dest_size) {
332 CryptBlock(TRUE, objnum, gennum, src_buf, src_size, dest_buf, dest_size);
333 return TRUE;
334 }
335 CPDF_StandardCryptoHandler::CPDF_StandardCryptoHandler() {
336 m_pAESContext = NULL;
337 m_Cipher = FXCIPHER_NONE;
338 m_KeyLen = 0;
339 }
340 CPDF_StandardCryptoHandler::~CPDF_StandardCryptoHandler() {
341 FX_Free(m_pAESContext);
342 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698