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

Side by Side Diff: core/src/fpdfapi/fpdf_parser/fpdf_parser_encrypt.cpp

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

Powered by Google App Engine
This is Rietveld 408576698