/src/serenity/Userland/Libraries/LibPDF/Encryption.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | * Copyright (c) 2022, Matthew Olsson <mattco@serenityos.org> |
3 | | * |
4 | | * SPDX-License-Identifier: BSD-2-Clause |
5 | | */ |
6 | | |
7 | | #include <AK/ByteBuffer.h> |
8 | | #include <AK/Debug.h> |
9 | | #include <AK/Random.h> |
10 | | #include <AK/UFixedBigIntDivision.h> |
11 | | #include <LibCrypto/Cipher/AES.h> |
12 | | #include <LibCrypto/Hash/HashManager.h> |
13 | | #include <LibCrypto/Hash/MD5.h> |
14 | | #include <LibPDF/CommonNames.h> |
15 | | #include <LibPDF/Document.h> |
16 | | #include <LibPDF/Encryption.h> |
17 | | |
18 | | namespace PDF { |
19 | | |
20 | | static constexpr Array<u8, 32> standard_encryption_key_padding_bytes = { |
21 | | 0x28, |
22 | | 0xBF, |
23 | | 0x4E, |
24 | | 0x5E, |
25 | | 0x4E, |
26 | | 0x75, |
27 | | 0x8A, |
28 | | 0x41, |
29 | | 0x64, |
30 | | 0x00, |
31 | | 0x4E, |
32 | | 0x56, |
33 | | 0xFF, |
34 | | 0xFA, |
35 | | 0x01, |
36 | | 0x08, |
37 | | 0x2E, |
38 | | 0x2E, |
39 | | 0x00, |
40 | | 0xB6, |
41 | | 0xD0, |
42 | | 0x68, |
43 | | 0x3E, |
44 | | 0x80, |
45 | | 0x2F, |
46 | | 0x0C, |
47 | | 0xA9, |
48 | | 0xFE, |
49 | | 0x64, |
50 | | 0x53, |
51 | | 0x69, |
52 | | 0x7A, |
53 | | }; |
54 | | |
55 | | PDFErrorOr<NonnullRefPtr<SecurityHandler>> SecurityHandler::create(Document* document, NonnullRefPtr<DictObject> encryption_dict) |
56 | 0 | { |
57 | 0 | auto filter = TRY(encryption_dict->get_name(document, CommonNames::Filter))->name(); |
58 | 0 | if (filter == "Standard") |
59 | 0 | return TRY(StandardSecurityHandler::create(document, encryption_dict)); |
60 | | |
61 | 0 | dbgln("Unrecognized security handler filter: {}", filter); |
62 | 0 | TODO(); |
63 | 0 | } |
64 | | |
65 | | struct CryptFilter { |
66 | | CryptFilterMethod method { CryptFilterMethod::None }; |
67 | | int length_in_bits { 0 }; |
68 | | }; |
69 | | |
70 | | static PDFErrorOr<CryptFilter> parse_v4_or_newer_crypt(Document* document, NonnullRefPtr<DictObject> encryption_dict, ByteString filter) |
71 | 0 | { |
72 | | // See 3.5 Encryption, Table 3.18 "Entries common to all encryption dictionaries" for StmF and StrF, |
73 | | // and 3.5.4 Crypt Filters in the 1.7 spec, in particular Table 3.22 "Entries common to all crypt filter dictionaries". |
74 | |
|
75 | 0 | if (filter == "Identity") |
76 | 0 | return CryptFilter {}; |
77 | | |
78 | | // "Every crypt filter used in the document must have an entry in this dictionary" |
79 | 0 | if (!encryption_dict->contains(CommonNames::CF)) |
80 | 0 | return Error(Error::Type::Parse, "Missing CF key in encryption dict for v4"); |
81 | | |
82 | 0 | auto crypt_filter_dicts = TRY(encryption_dict->get_dict(document, CommonNames::CF)); |
83 | 0 | if (!crypt_filter_dicts->contains(filter)) |
84 | 0 | return Error(Error::Type::Parse, "Missing key in CF dict for v4"); |
85 | | |
86 | 0 | auto crypt_filter_dict = TRY(crypt_filter_dicts->get_dict(document, filter)); |
87 | | |
88 | | // "Default value: None" |
89 | 0 | if (!crypt_filter_dict->contains(CommonNames::CFM)) |
90 | 0 | return CryptFilter {}; |
91 | 0 | auto crypt_filter_method = TRY(crypt_filter_dict->get_name(document, CommonNames::CFM))->name(); |
92 | 0 | if (crypt_filter_method == "None") |
93 | 0 | return CryptFilter {}; |
94 | | |
95 | | // Table 3.22 in the 1.7 spec says this is optional but doesn't give a default value. |
96 | | // But the 2.0 spec (ISO 32000 2020) says it's required. |
97 | | // The 2.0 spec also says "The standard security handler expresses the Length entry in bytes" (!). |
98 | 0 | if (!crypt_filter_dict->contains(CommonNames::Length)) |
99 | 0 | return Error(Error::Type::Parse, "crypt filter /Length missing"); |
100 | 0 | auto length_in_bits = crypt_filter_dict->get_value(CommonNames::Length).get<int>() * 8; |
101 | | |
102 | | // NOTE: /CFM's /AuthEvent should be ignored for /StmF, /StrF. |
103 | |
|
104 | 0 | if (crypt_filter_method == "V2") |
105 | 0 | return CryptFilter { CryptFilterMethod::V2, length_in_bits }; |
106 | | |
107 | 0 | if (crypt_filter_method == "AESV2") { |
108 | | // "the AES algorithm in Cipher Block Chaining (CBC) mode with a 16-byte block size [...] The key size (Length) shall be 128 bits." |
109 | 0 | if (length_in_bits != 128) |
110 | 0 | return Error(Error::Type::Parse, "Unexpected bit size for AESV2"); |
111 | 0 | return CryptFilter { CryptFilterMethod::AESV2, length_in_bits }; |
112 | 0 | } |
113 | | |
114 | 0 | if (crypt_filter_method == "AESV3") { |
115 | | // "the AES-256 algorithm in Cipher Block Chaining (CBC) with padding mode with a 16-byte block size [...] The key size (Length) shall be 256 bits." |
116 | 0 | if (length_in_bits != 256) |
117 | 0 | return Error(Error::Type::Parse, "Unexpected bit size for AESV3"); |
118 | 0 | return CryptFilter { CryptFilterMethod::AESV3, length_in_bits }; |
119 | 0 | } |
120 | | |
121 | 0 | return Error(Error::Type::Parse, "Unknown crypt filter method"); |
122 | 0 | } |
123 | | |
124 | | PDFErrorOr<NonnullRefPtr<StandardSecurityHandler>> StandardSecurityHandler::create(Document* document, NonnullRefPtr<DictObject> encryption_dict) |
125 | 0 | { |
126 | 0 | auto revision = encryption_dict->get_value(CommonNames::R).get<int>(); |
127 | 0 | auto o = TRY(encryption_dict->get_string(document, CommonNames::O))->string(); |
128 | 0 | auto u = TRY(encryption_dict->get_string(document, CommonNames::U))->string(); |
129 | 0 | auto p = encryption_dict->get_value(CommonNames::P).get<int>(); |
130 | | |
131 | | // V, number: [...] 1 "Algorithm 1 Encryption of data using the RC4 or AES algorithms" in 7.6.2, |
132 | | // "General Encryption Algorithm," with an encryption key length of 40 bits, see below [...] |
133 | | // Length, integer: (Optional; PDF 1.4; only if V is 2 or 3) The length of the encryption key, in bits. |
134 | | // The value shall be a multiple of 8, in the range 40 to 128. Default value: 40. |
135 | 0 | auto v = encryption_dict->get_value(CommonNames::V).get<int>(); |
136 | |
|
137 | 0 | auto method = CryptFilterMethod::V2; |
138 | 0 | size_t length_in_bits = 40; |
139 | |
|
140 | 0 | if (v >= 4) { |
141 | | // "Default value: Identity" |
142 | 0 | ByteString stream_filter = "Identity"; |
143 | 0 | if (encryption_dict->contains(CommonNames::StmF)) |
144 | 0 | stream_filter = TRY(encryption_dict->get_name(document, CommonNames::StmF))->name(); |
145 | | |
146 | 0 | ByteString string_filter = "Identity"; |
147 | 0 | if (encryption_dict->contains(CommonNames::StrF)) |
148 | 0 | string_filter = TRY(encryption_dict->get_name(document, CommonNames::StrF))->name(); |
149 | | |
150 | 0 | if (stream_filter != string_filter) |
151 | 0 | return Error(Error::Type::Parse, "Can't handle StmF and StrF being different"); |
152 | | |
153 | 0 | auto crypt_filter = TRY(parse_v4_or_newer_crypt(document, encryption_dict, stream_filter)); |
154 | 0 | method = crypt_filter.method; |
155 | 0 | length_in_bits = crypt_filter.length_in_bits; |
156 | 0 | } else if (encryption_dict->contains(CommonNames::Length)) |
157 | 0 | length_in_bits = encryption_dict->get_value(CommonNames::Length).get<int>(); |
158 | 0 | else if (v != 1) |
159 | 0 | return Error(Error::Type::Parse, "Can't determine length of encryption key"); |
160 | | |
161 | 0 | auto length = length_in_bits / 8; |
162 | |
|
163 | 0 | dbgln_if(PDF_DEBUG, "encryption v{}, method {}, length {}", v, (int)method, length); |
164 | |
|
165 | 0 | bool encrypt_metadata = true; |
166 | 0 | if (encryption_dict->contains(CommonNames::EncryptMetadata)) |
167 | 0 | encryption_dict->get_value(CommonNames::EncryptMetadata).get<bool>(); |
168 | |
|
169 | 0 | ByteString oe, ue, perms; |
170 | 0 | if (v >= 5) { |
171 | 0 | oe = TRY(encryption_dict->get_string(document, CommonNames::OE))->string(); |
172 | 0 | ue = TRY(encryption_dict->get_string(document, CommonNames::UE))->string(); |
173 | 0 | perms = TRY(encryption_dict->get_string(document, CommonNames::Perms))->string(); |
174 | | |
175 | | // O and U are 48 bytes for V == 5, but some files pad them with nul bytes to 127 bytes. So trim them, if necessary. |
176 | 0 | if (o.length() > 48) |
177 | 0 | o = o.substring(0, 48); |
178 | 0 | if (u.length() > 48) |
179 | 0 | u = u.substring(0, 48); |
180 | |
|
181 | 0 | if (o.length() != 48) |
182 | 0 | return Error(Error::Type::Parse, "Invalid O size"); |
183 | 0 | if (oe.length() != 32) |
184 | 0 | return Error(Error::Type::Parse, "Invalid OE size"); |
185 | 0 | if (u.length() != 48) |
186 | 0 | return Error(Error::Type::Parse, "Invalid U size"); |
187 | 0 | if (ue.length() != 32) |
188 | 0 | return Error(Error::Type::Parse, "Invalid UE size"); |
189 | 0 | if (perms.length() != 16) |
190 | 0 | return Error(Error::Type::Parse, "Invalid Perms size"); |
191 | 0 | } |
192 | | |
193 | 0 | return adopt_ref(*new StandardSecurityHandler(document, revision, o, oe, u, ue, perms, p, encrypt_metadata, length, method)); |
194 | 0 | } |
195 | | |
196 | | StandardSecurityHandler::StandardSecurityHandler(Document* document, size_t revision, ByteString const& o_entry, ByteString const& oe_entry, ByteString const& u_entry, ByteString const& ue_entry, ByteString const& perms_entry, u32 flags, bool encrypt_metadata, size_t length, CryptFilterMethod method) |
197 | 0 | : m_document(document) |
198 | 0 | , m_revision(revision) |
199 | 0 | , m_o_entry(o_entry) |
200 | 0 | , m_oe_entry(oe_entry) |
201 | 0 | , m_u_entry(u_entry) |
202 | 0 | , m_ue_entry(ue_entry) |
203 | 0 | , m_perms_entry(perms_entry) |
204 | 0 | , m_flags(flags) |
205 | 0 | , m_encrypt_metadata(encrypt_metadata) |
206 | 0 | , m_length(length) |
207 | 0 | , m_method(method) |
208 | 0 | { |
209 | 0 | } |
210 | | |
211 | | ByteBuffer StandardSecurityHandler::compute_user_password_value_r2(ByteBuffer password_string) |
212 | 0 | { |
213 | | // Algorithm 4: Computing the encryption dictionary's U (user password) |
214 | | // value (Security handlers of revision 2) |
215 | | |
216 | | // a) Create an encryption key based on the user password string, as |
217 | | // described in [Algorithm 2] |
218 | 0 | auto encryption_key = compute_encryption_key_r2_to_r5(password_string); |
219 | | |
220 | | // b) Encrypt the 32-byte padding string shown in step (a) of [Algorithm 2], |
221 | | // using an RC4 encryption function with the encryption key from the |
222 | | // preceding step. |
223 | 0 | RC4 rc4(encryption_key); |
224 | 0 | auto output = rc4.encrypt(standard_encryption_key_padding_bytes); |
225 | | |
226 | | // c) Store the result of step (b) as the value of the U entry in the |
227 | | // encryption dictionary. |
228 | 0 | return output; |
229 | 0 | } |
230 | | |
231 | | ByteBuffer StandardSecurityHandler::compute_user_password_value_r3_to_r5(ByteBuffer password_string) |
232 | 0 | { |
233 | | // Algorithm 5: Computing the encryption dictionary's U (user password) |
234 | | // value (Security handlers of revision 3 or greater) |
235 | | |
236 | | // a) Create an encryption key based on the user password string, as |
237 | | // described in [Algorithm 2] |
238 | 0 | auto encryption_key = compute_encryption_key_r2_to_r5(password_string); |
239 | | |
240 | | // b) Initialize the MD5 hash function and pass the 32-byte padding string |
241 | | // shown in step (a) of [Algorithm 2] as input to this function |
242 | 0 | Crypto::Hash::MD5 md5; |
243 | 0 | md5.update(standard_encryption_key_padding_bytes); |
244 | | |
245 | | // e) Pass the first element of the file's file identifier array to the MD5 |
246 | | // hash function. |
247 | 0 | auto id_array = m_document->trailer()->get_array(m_document, CommonNames::ID).release_value_but_fixme_should_propagate_errors(); |
248 | 0 | auto first_element_string = id_array->get_string_at(m_document, 0).release_value_but_fixme_should_propagate_errors()->string(); |
249 | 0 | md5.update(first_element_string); |
250 | | |
251 | | // d) Encrypt the 16-byte result of the hash, using an RC4 encryption function |
252 | | // with the encryption key from step (a). |
253 | 0 | RC4 rc4(encryption_key); |
254 | 0 | auto out = md5.peek(); |
255 | 0 | auto buffer = rc4.encrypt(out.bytes()); |
256 | | |
257 | | // e) Do the following 19 times: |
258 | | // |
259 | | // Take the output from the previous invocation of the RC4 function and pass |
260 | | // it as input to a new invocation of the function; use an encryption key generated |
261 | | // by taking each byte of the original encryption key obtained in step (a) and |
262 | | // performing an XOR operation between the that byte and the single-byte value of |
263 | | // the iteration counter (from 1 to 19). |
264 | 0 | auto new_encryption_key = ByteBuffer::create_uninitialized(encryption_key.size()).release_value_but_fixme_should_propagate_errors(); |
265 | 0 | for (size_t i = 1; i <= 19; i++) { |
266 | 0 | for (size_t j = 0; j < encryption_key.size(); j++) |
267 | 0 | new_encryption_key[j] = encryption_key[j] ^ i; |
268 | |
|
269 | 0 | RC4 new_rc4(new_encryption_key); |
270 | 0 | buffer = new_rc4.encrypt(buffer); |
271 | 0 | } |
272 | | |
273 | | // f) Append 16 bytes of the arbitrary padding to the output from the final invocation |
274 | | // of the RC4 function and store the 32-byte result as the value of the U entry in |
275 | | // the encryption dictionary. |
276 | 0 | VERIFY(buffer.size() == 16); |
277 | 0 | for (size_t i = 0; i < 16; i++) |
278 | 0 | buffer.append(0xab); |
279 | |
|
280 | 0 | return buffer; |
281 | 0 | } |
282 | | |
283 | | bool StandardSecurityHandler::authenticate_user_password_r2_to_r5(StringView password_string) |
284 | 0 | { |
285 | | // Algorithm 6: Authenticating the user password |
286 | | |
287 | | // a) Perform all but the last step of [Algorithm 4] or [Algorithm 5] using the |
288 | | // supplied password string. |
289 | 0 | ByteBuffer password_buffer = ByteBuffer::copy(password_string.bytes()).release_value_but_fixme_should_propagate_errors(); |
290 | 0 | if (m_revision == 2) { |
291 | 0 | password_buffer = compute_user_password_value_r2(password_buffer); |
292 | 0 | } else { |
293 | 0 | password_buffer = compute_user_password_value_r3_to_r5(password_buffer); |
294 | 0 | } |
295 | | |
296 | | // b) If the result of step (a) is equal to the value of the encryption |
297 | | // dictionary's "U" entry (comparing the first 16 bytes in the case of security |
298 | | // handlers of revision 3 or greater), the password supplied is the correct user |
299 | | // password. |
300 | 0 | auto u_bytes = m_u_entry.bytes(); |
301 | 0 | if (m_revision >= 3) |
302 | 0 | return u_bytes.slice(0, 16) == password_buffer.bytes().slice(0, 16); |
303 | 0 | return u_bytes == password_buffer.bytes(); |
304 | 0 | } |
305 | | |
306 | | bool StandardSecurityHandler::authenticate_user_password_r6_and_later(StringView password) |
307 | 0 | { |
308 | | // ISO 32000 (PDF 2.0), 7.6.4.4.10 Algorithm 11: Authenticating the user password (Security handlers of |
309 | | // revision 6) |
310 | | |
311 | | // a) Test the password against the user key by computing the 32-byte hash using 7.6.4.3.4, "Algorithm 2.B: |
312 | | // Computing a hash (revision 6 or later)" with an input string consisting of the UTF-8 password |
313 | | // concatenated with the 8 bytes of User Validation Salt (see 7.6.4.4.7, "Algorithm 8: Computing the |
314 | | // encryption dictionary's U (user password) and UE (user encryption) values (Security handlers of |
315 | | // revision 6)"). If the 32- byte result matches the first 32 bytes of the U string, this is the user password. |
316 | 0 | ByteBuffer input; |
317 | 0 | input.append(password.bytes()); |
318 | 0 | input.append(m_u_entry.bytes().slice(32, 8)); // See comment in compute_encryption_key_r6_and_later() re "Validation Salt". |
319 | 0 | auto hash = computing_a_hash_r6_and_later(input, password, HashKind::User); |
320 | |
|
321 | 0 | return hash == m_u_entry.bytes().trim(32); |
322 | 0 | } |
323 | | |
324 | | bool StandardSecurityHandler::authenticate_owner_password_r6_and_later(StringView password) |
325 | 0 | { |
326 | | // ISO 32000 (PDF 2.0), 7.6.4.4.11 Algorithm 12: Authenticating the owner password (Security handlers of |
327 | | // revision 6) |
328 | | |
329 | | // a) Test the password against the owner key by computing the 32-byte hash using algorithm 2.B with an |
330 | | // input string consisting of the UTF-8 password concatenated with the 8 bytes of Owner Validation Salt |
331 | | // and the 48 byte U string. If the 32- byte result matches the first 32 bytes of the O string, this is the owner |
332 | | // password. |
333 | 0 | ByteBuffer input; |
334 | 0 | input.append(password.bytes()); |
335 | 0 | input.append(m_o_entry.bytes().slice(32, 8)); // See comment in compute_encryption_key_r6_and_later() re "Validation Salt". |
336 | 0 | input.append(m_u_entry.bytes()); |
337 | 0 | auto hash = computing_a_hash_r6_and_later(input, password, HashKind::Owner); |
338 | |
|
339 | 0 | return hash == m_o_entry.bytes().trim(32); |
340 | 0 | } |
341 | | |
342 | | bool StandardSecurityHandler::try_provide_user_password(StringView password_string) |
343 | 0 | { |
344 | 0 | bool has_user_password; |
345 | 0 | if (m_revision >= 6) { |
346 | | // This checks both owner and user password. |
347 | 0 | auto password = ByteBuffer::copy(password_string.bytes()).release_value_but_fixme_should_propagate_errors(); |
348 | 0 | has_user_password = compute_encryption_key_r6_and_later(move(password)); |
349 | 0 | } else { |
350 | 0 | has_user_password = authenticate_user_password_r2_to_r5(password_string); |
351 | 0 | } |
352 | |
|
353 | 0 | if (!has_user_password) |
354 | 0 | m_encryption_key = {}; |
355 | 0 | return has_user_password; |
356 | 0 | } |
357 | | |
358 | | ByteBuffer StandardSecurityHandler::compute_encryption_key_r2_to_r5(ByteBuffer password_string) |
359 | 0 | { |
360 | | // This function should never be called after we have a valid encryption key. |
361 | 0 | VERIFY(!m_encryption_key.has_value()); |
362 | | |
363 | | // 7.6.3.3 Encryption Key Algorithm |
364 | | |
365 | | // Algorithm 2: Computing an encryption key |
366 | | |
367 | | // a) Pad or truncate the password string to exactly 32 bytes. If the password string |
368 | | // is more than 32 bytes long, use only its first 32 bytes; if it is less than 32 |
369 | | // bytes long, pad it by appending the required number of additional bytes from the |
370 | | // beginning of the following padding string: [omitted] |
371 | | |
372 | 0 | if (password_string.size() > 32) { |
373 | 0 | password_string.resize(32); |
374 | 0 | } else { |
375 | 0 | password_string.append(standard_encryption_key_padding_bytes.data(), 32 - password_string.size()); |
376 | 0 | } |
377 | | |
378 | | // b) Initialize the MD5 hash function and pass the result of step (a) as input to |
379 | | // this function. |
380 | 0 | Crypto::Hash::MD5 md5; |
381 | 0 | md5.update(password_string); |
382 | | |
383 | | // c) Pass the value of the encryption dictionary's "O" entry to the MD5 hash function. |
384 | 0 | md5.update(m_o_entry); |
385 | | |
386 | | // d) Convert the integer value of the P entry to a 32-bit unsigned binary number and pass |
387 | | // these bytes to the MD5 hash function, low-order byte first. |
388 | 0 | md5.update(reinterpret_cast<u8 const*>(&m_flags), sizeof(m_flags)); |
389 | | |
390 | | // e) Pass the first element of the file's file identifier array to the MD5 hash function. |
391 | 0 | auto id_array = m_document->trailer()->get_array(m_document, CommonNames::ID).release_value_but_fixme_should_propagate_errors(); |
392 | 0 | auto first_element_string = id_array->get_string_at(m_document, 0).release_value_but_fixme_should_propagate_errors()->string(); |
393 | 0 | md5.update(first_element_string); |
394 | | |
395 | | // f) (Security handlers of revision 4 or greater) if the document metadata is not being |
396 | | // encrypted, pass 4 bytes with the value 0xffffffff to the MD5 hash function. |
397 | 0 | if (m_revision >= 4 && !m_encrypt_metadata) { |
398 | 0 | u32 value = 0xffffffff; |
399 | 0 | md5.update(reinterpret_cast<u8 const*>(&value), 4); |
400 | 0 | } |
401 | | |
402 | | // g) Finish the hash. |
403 | | // h) (Security handlers of revision 3 or greater) Do the following 50 times: |
404 | | // |
405 | | // Take the output from the previous MD5 hash and pass the first n bytes |
406 | | // of the output as input into a new MD5 hash, where n is the number of |
407 | | // bytes of the encryption key as defined by the value of the encryption |
408 | | // dictionary's Length entry. |
409 | 0 | if (m_revision >= 3) { |
410 | 0 | ByteBuffer n_bytes; |
411 | |
|
412 | 0 | for (u32 i = 0; i < 50; i++) { |
413 | 0 | Crypto::Hash::MD5 new_md5; |
414 | 0 | n_bytes.ensure_capacity(m_length); |
415 | |
|
416 | 0 | while (n_bytes.size() < m_length) { |
417 | 0 | auto out = md5.peek(); |
418 | 0 | for (size_t j = 0; j < out.data_length() && n_bytes.size() < m_length; j++) |
419 | 0 | n_bytes.append(out.data[j]); |
420 | 0 | } |
421 | |
|
422 | 0 | VERIFY(n_bytes.size() == m_length); |
423 | 0 | new_md5.update(n_bytes); |
424 | 0 | md5 = move(new_md5); |
425 | 0 | n_bytes.clear(); |
426 | 0 | } |
427 | 0 | } |
428 | | |
429 | | // i) Set the encryption key to the first n bytes of the output from the final MD5 |
430 | | // hash, where n shall always be 5 for security handlers of revision 2 but, for |
431 | | // security handlers of revision 3 or greater, shall depend on the value of the |
432 | | // encryption dictionary's Length entry. |
433 | 0 | size_t n; |
434 | 0 | if (m_revision == 2) { |
435 | 0 | n = 5; |
436 | 0 | } else if (m_revision >= 3) { |
437 | 0 | n = m_length; |
438 | 0 | } else { |
439 | 0 | VERIFY_NOT_REACHED(); |
440 | 0 | } |
441 | | |
442 | 0 | ByteBuffer encryption_key; |
443 | 0 | encryption_key.ensure_capacity(n); |
444 | 0 | while (encryption_key.size() < n) { |
445 | 0 | auto out = md5.peek(); |
446 | 0 | for (size_t i = 0; encryption_key.size() < n && i < out.data_length(); i++) |
447 | 0 | encryption_key.append(out.bytes()[i]); |
448 | 0 | } |
449 | |
|
450 | 0 | m_encryption_key = encryption_key; |
451 | |
|
452 | 0 | return encryption_key; |
453 | 0 | } |
454 | | |
455 | | bool StandardSecurityHandler::compute_encryption_key_r6_and_later(ByteBuffer password_string) |
456 | 0 | { |
457 | | // This function should never be called after we have a valid encryption key. |
458 | 0 | VERIFY(!m_encryption_key.has_value()); |
459 | | |
460 | 0 | auto const zero_iv = ByteBuffer::create_zeroed(16).release_value_but_fixme_should_propagate_errors(); |
461 | | |
462 | | // ISO 32000 (PDF 2.0), 7.6.4.3.3 Algorithm 2.A: Retrieving the file encryption key from an encrypted |
463 | | // document in order to decrypt it (revision 6 or later) |
464 | | |
465 | | // "It is necessary to treat the 48-bytes of the O and U strings in the |
466 | | // Encrypt dictionary as made up of three sections [...]. The first 32 bytes |
467 | | // are a hash value (explained below). The next 8 bytes are called the Validation Salt. The final 8 bytes are |
468 | | // called the Key Salt." |
469 | | |
470 | | // a) The UTF-8 password string shall be generated from Unicode input by processing the input string with |
471 | | // the SASLprep (Internet RFC 4013) profile of stringprep (Internet RFC 3454) using the Normalize and BiDi |
472 | | // options, and then converting to a UTF-8 representation. |
473 | | // FIXME |
474 | | |
475 | | // b) Truncate the UTF-8 representation to 127 bytes if it is longer than 127 bytes. |
476 | 0 | if (password_string.size() > 127) |
477 | 0 | password_string.resize(127); |
478 | | |
479 | | // c) Test the password against the owner key by computing a hash using algorithm 2.B with an input string |
480 | | // consisting of the UTF-8 password concatenated with the 8 bytes of owner Validation Salt, concatenated |
481 | | // with the 48-byte U string. If the 32-byte result matches the first 32 bytes of the O string, this is the owner |
482 | | // password. |
483 | | // [Implementor's note: This is the same as Algorithm 12 in the spec.] |
484 | 0 | if (authenticate_owner_password_r6_and_later(password_string)) { |
485 | | // d) Compute an intermediate owner key by computing a hash using algorithm 2.B with an input string |
486 | | // consisting of the UTF-8 owner password concatenated with the 8 bytes of owner Key Salt, concatenated |
487 | | // with the 48-byte U string. The 32-byte result is the key used to decrypt the 32-byte OE string using AES- |
488 | | // 256 in CBC mode with no padding and an initialization vector of zero. The 32-byte result is the file |
489 | | // encryption key. |
490 | 0 | ByteBuffer input; |
491 | 0 | input.append(password_string); |
492 | 0 | input.append(m_o_entry.bytes().slice(40, 8)); |
493 | 0 | input.append(m_u_entry.bytes()); |
494 | 0 | auto key = computing_a_hash_r6_and_later(input, password_string, HashKind::Owner); |
495 | | |
496 | | // [Implementor's note: PaddingMode doesn't matter here since input is block-aligned.] |
497 | 0 | auto cipher = Crypto::Cipher::AESCipher::CBCMode(key, 256, Crypto::Cipher::Intent::Decryption, Crypto::Cipher::PaddingMode::Null); |
498 | 0 | auto decrypted = cipher.create_aligned_buffer(m_oe_entry.length()).release_value_but_fixme_should_propagate_errors(); |
499 | 0 | Bytes decrypted_span = decrypted.bytes(); |
500 | 0 | cipher.decrypt(m_oe_entry.bytes(), decrypted_span, zero_iv); |
501 | 0 | m_encryption_key = ByteBuffer::copy(decrypted_span).release_value_but_fixme_should_propagate_errors(); |
502 | 0 | } |
503 | | // [Implementor's note: The spec seems to miss a step like c) but for the user password here.] |
504 | 0 | else if (authenticate_user_password_r6_and_later(password_string)) { |
505 | | // e) Compute an intermediate user key by computing a hash using algorithm 2.B with an input string |
506 | | // consisting of the UTF-8 user password concatenated with the 8 bytes of user Key Salt. The 32-byte result |
507 | | // is the key used to decrypt the 32-byte UE string using AES-256 in CBC mode with no padding and an |
508 | | // initialization vector of zero. The 32-byte result is the file encryption key. |
509 | 0 | ByteBuffer input; |
510 | 0 | input.append(password_string); |
511 | 0 | input.append(m_u_entry.bytes().slice(40, 8)); |
512 | 0 | auto key = computing_a_hash_r6_and_later(input, password_string, HashKind::User); |
513 | | |
514 | | // [Implementor's note: PaddingMode doesn't matter here since input is block-aligned.] |
515 | 0 | auto cipher = Crypto::Cipher::AESCipher::CBCMode(key, 256, Crypto::Cipher::Intent::Decryption, Crypto::Cipher::PaddingMode::Null); |
516 | 0 | auto decrypted = cipher.create_aligned_buffer(m_ue_entry.length()).release_value_but_fixme_should_propagate_errors(); |
517 | 0 | Bytes decrypted_span = decrypted.bytes(); |
518 | 0 | cipher.decrypt(m_ue_entry.bytes(), decrypted_span, zero_iv); |
519 | 0 | m_encryption_key = ByteBuffer::copy(decrypted_span).release_value_but_fixme_should_propagate_errors(); |
520 | 0 | } |
521 | | // [Implementor's note: No explicit step for this in the spec, but if we get here the password was neither owner nor user password.] |
522 | 0 | else { |
523 | 0 | return false; |
524 | 0 | } |
525 | | |
526 | | // f) Decrypt the 16-byte Perms string using AES-256 in ECB mode with an initialization vector of zero and |
527 | | // the file encryption key as the key. Verify that bytes 9-11 of the result are the characters "a", "d", "b". Bytes |
528 | | // 0-3 of the decrypted Perms entry, treated as a little-endian integer, are the user permissions. They shall |
529 | | // match the value in the P key. |
530 | | // [Implementor's note: For 16-byte long messages, CBC with an IV of zero is the same as ECB. ECB with an IV doesn't make a lot of sense (?) Maybe the spec means CBC.] |
531 | 0 | auto cipher = Crypto::Cipher::AESCipher::CBCMode(m_encryption_key.value(), 256, Crypto::Cipher::Intent::Decryption, Crypto::Cipher::PaddingMode::Null); |
532 | 0 | auto decrypted = cipher.create_aligned_buffer(m_perms_entry.length()).release_value_but_fixme_should_propagate_errors(); |
533 | 0 | Bytes decrypted_span = decrypted.bytes(); |
534 | 0 | cipher.decrypt(m_perms_entry.bytes(), decrypted_span, zero_iv); |
535 | |
|
536 | 0 | return decrypted_span[9] == 'a' && decrypted_span[10] == 'd' && decrypted_span[11] == 'b' && *bit_cast<LittleEndian<u32>*>(decrypted_span.data()) == m_flags; |
537 | 0 | } |
538 | | |
539 | | ByteBuffer StandardSecurityHandler::computing_a_hash_r6_and_later(ByteBuffer original_input, StringView input_password, HashKind kind) |
540 | 0 | { |
541 | | // ISO 32000 (PDF 2.0), 7.6.4.3.4 Algorithm 2.B: Computing a hash (revision 6 or later) |
542 | | |
543 | | // Take the SHA-256 hash of the original input to the algorithm and name the resulting 32 bytes, K. |
544 | 0 | static_assert(Crypto::Hash::SHA256::DigestType::Size == 32); |
545 | 0 | Crypto::Hash::SHA256 sha; |
546 | 0 | sha.update(original_input); |
547 | 0 | auto K = ByteBuffer::copy(sha.digest().bytes()).release_value_but_fixme_should_propagate_errors(); |
548 | | |
549 | | // Perform the following steps (a)-(d) 64 times: |
550 | 0 | int round_number; |
551 | 0 | for (round_number = 0;; ++round_number) { |
552 | | // a) Make a new string, K1, consisting of 64 repetitions of the sequence: Input password, K, the 48-byte user |
553 | | // key. The 48 byte user key is only used when checking the owner password or creating the owner key. If |
554 | | // checking the user password or creating the user key, K1 is the concatenation of the input password and K. |
555 | 0 | ByteBuffer K1_part; |
556 | 0 | K1_part.append(input_password.bytes()); |
557 | 0 | K1_part.append(K.bytes()); |
558 | 0 | if (kind == HashKind::Owner) |
559 | 0 | K1_part.append(m_u_entry.bytes()); |
560 | |
|
561 | 0 | ByteBuffer K1; |
562 | 0 | for (int i = 0; i < 64; ++i) |
563 | 0 | K1.append(K1_part); |
564 | | |
565 | | // b) Encrypt K1 with the AES-128 (CBC, no padding) algorithm, using the first 16 bytes of K as the key and |
566 | | // the second 16 bytes of K as the initialization vector. The result of this encryption is E. |
567 | 0 | ReadonlyBytes key = K.bytes().trim(16); |
568 | 0 | ReadonlyBytes initialization_vector = K.bytes().slice(16); |
569 | | |
570 | | // [Implementor's note: PaddingMode doesn't matter here since input is block-aligned.] |
571 | 0 | auto cipher = Crypto::Cipher::AESCipher::CBCMode(key, 128, Crypto::Cipher::Intent::Encryption, Crypto::Cipher::PaddingMode::Null); |
572 | 0 | auto E = cipher.create_aligned_buffer(K1.size()).release_value_but_fixme_should_propagate_errors(); |
573 | 0 | Bytes E_span = E.bytes(); |
574 | 0 | cipher.encrypt(K1, E_span, initialization_vector); |
575 | | |
576 | | // c) Taking the first 16 bytes of E as an unsigned big-endian integer, compute the remainder, modulo 3. If the |
577 | | // result is 0, the next hash used is SHA-256, if the result is 1, the next hash used is SHA-384, if the result is |
578 | | // 2, the next hash used is SHA-512. |
579 | 0 | u128 remainder(0); |
580 | 0 | for (int i = 0; i < 16; ++i) |
581 | 0 | remainder = (remainder << 8) | E[i]; |
582 | 0 | remainder %= u128(3); |
583 | |
|
584 | 0 | Crypto::Hash::HashKind hash_kind; |
585 | 0 | switch (u8 { remainder }) { |
586 | 0 | case 0: |
587 | 0 | hash_kind = Crypto::Hash::HashKind::SHA256; |
588 | 0 | break; |
589 | 0 | case 1: |
590 | 0 | hash_kind = Crypto::Hash::HashKind::SHA384; |
591 | 0 | break; |
592 | 0 | case 2: |
593 | 0 | hash_kind = Crypto::Hash::HashKind::SHA512; |
594 | 0 | break; |
595 | 0 | } |
596 | | |
597 | | // d) Using the hash algorithm determined in step c, take the hash of E. The result is a new value of K, which |
598 | | // will be 32, 48, or 64 bytes in length. |
599 | 0 | Crypto::Hash::Manager hash(hash_kind); |
600 | 0 | hash.update(E); |
601 | 0 | K = ByteBuffer::copy(hash.digest().bytes()).release_value_but_fixme_should_propagate_errors(); |
602 | | |
603 | | // Repeat the process (a-d) with this new value of K. Following 64 rounds (round number 0 to round |
604 | | // number 63), do the following, starting with round number 64: |
605 | | |
606 | | // [Implementor's note: Conceptually, steps e)-f) are at the top of the loop for rounds >= 64, so this has to continue for < 63, not for < 64.] |
607 | 0 | if (round_number < 63) |
608 | 0 | continue; |
609 | | |
610 | | // NOTE 2 The reason for multiple rounds is to defeat the possibility of running all paths in parallel. With 64 |
611 | | // rounds (minimum) there are 3^64 paths through the algorithm. |
612 | | |
613 | | // e) Look at the very last byte of E. If the value of that byte (taken as an unsigned integer) is greater than the |
614 | | // round number - 32, repeat steps (a-d) again. |
615 | | |
616 | | // f) Repeat from steps (a-e) until the value of the last byte is <= (round number) - 32. |
617 | | |
618 | | // NOTE 3 Tests indicate that the total number of rounds will most likely be between 65 and 80. |
619 | | |
620 | 0 | if (E.bytes().last() <= round_number - 32) |
621 | 0 | break; |
622 | 0 | } |
623 | | |
624 | | // The first 32 bytes of the final K are the output of the algorithm. |
625 | 0 | VERIFY(K.size() >= 32); |
626 | 0 | K.resize(32); |
627 | 0 | return K; |
628 | 0 | } |
629 | | |
630 | | void StandardSecurityHandler::crypt(NonnullRefPtr<Object> object, Reference reference, Crypto::Cipher::Intent direction) const |
631 | 0 | { |
632 | 0 | VERIFY(m_encryption_key.has_value()); |
633 | | |
634 | 0 | if (m_method == CryptFilterMethod::None) |
635 | 0 | return; |
636 | | |
637 | 0 | auto aes = [&](ReadonlyBytes bytes, ByteBuffer const& key) { |
638 | 0 | auto cipher = Crypto::Cipher::AESCipher::CBCMode(key, m_length * 8, direction, Crypto::Cipher::PaddingMode::CMS); |
639 | | |
640 | | // "The block size parameter is 16 bytes, and the initialization vector is a 16-byte random number |
641 | | // that is stored as the first 16 bytes of the encrypted stream or string." |
642 | 0 | static_assert(Crypto::Cipher::AESCipher::block_size() == 16); |
643 | 0 | if (direction == Crypto::Cipher::Intent::Encryption) { |
644 | 0 | auto output = cipher.create_aligned_buffer(16 + bytes.size()).release_value_but_fixme_should_propagate_errors(); |
645 | 0 | auto iv_span = output.bytes().trim(16); |
646 | 0 | auto encrypted_span = output.bytes().slice(16); |
647 | |
|
648 | 0 | fill_with_random(iv_span); |
649 | 0 | cipher.encrypt(bytes, encrypted_span, iv_span); |
650 | |
|
651 | 0 | return output; |
652 | 0 | } else { |
653 | 0 | VERIFY(direction == Crypto::Cipher::Intent::Decryption); |
654 | | |
655 | 0 | auto iv = bytes.trim(16); |
656 | 0 | bytes = bytes.slice(16); |
657 | |
|
658 | 0 | auto decrypted = cipher.create_aligned_buffer(bytes.size()).release_value_but_fixme_should_propagate_errors(); |
659 | 0 | auto decrypted_span = decrypted.bytes(); |
660 | 0 | cipher.decrypt(bytes, decrypted_span, iv); |
661 | 0 | decrypted.resize(decrypted_span.size()); |
662 | |
|
663 | 0 | return decrypted; |
664 | 0 | } |
665 | 0 | }; |
666 | |
|
667 | 0 | ReadonlyBytes bytes; |
668 | 0 | Function<void(ByteBuffer)> assign; |
669 | |
|
670 | 0 | if (object->is<StreamObject>()) { |
671 | 0 | auto stream = object->cast<StreamObject>(); |
672 | 0 | bytes = stream->bytes(); |
673 | |
|
674 | 0 | assign = [&object](ByteBuffer buffer) { |
675 | 0 | object->cast<StreamObject>()->buffer() = move(buffer); |
676 | 0 | }; |
677 | |
|
678 | 0 | if (stream->dict()->contains(CommonNames::Filter)) { |
679 | | // ISO 32000 (PDF 2.0), 7.4.10 Crypt filter |
680 | | // "The Crypt filter shall be the first filter in the Filter array entry." |
681 | 0 | auto filters = m_document->read_filters(stream->dict()).release_value_but_fixme_should_propagate_errors(); |
682 | 0 | if (!filters.is_empty() && filters[0] == "Crypt") |
683 | 0 | TODO(); |
684 | 0 | } |
685 | 0 | } else if (object->is<StringObject>()) { |
686 | 0 | auto string = object->cast<StringObject>(); |
687 | 0 | bytes = string->string().bytes(); |
688 | 0 | assign = [&object](ByteBuffer buffer) { |
689 | 0 | object->cast<StringObject>()->set_string(ByteString(buffer.bytes())); |
690 | 0 | }; |
691 | 0 | } else { |
692 | 0 | VERIFY_NOT_REACHED(); |
693 | 0 | } |
694 | | |
695 | 0 | if (m_method == CryptFilterMethod::AESV3) { |
696 | | // ISO 32000 (PDF 2.0), 7.6.3.3 Algorithm 1.A: Encryption of data using the AES algorithms |
697 | | |
698 | | // a) Use the 32-byte file encryption key for the AES-256 symmetric key algorithm, along with the string or |
699 | | // stream data to be encrypted. |
700 | | // |
701 | | // Use the AES algorithm in Cipher Block Chaining (CBC) mode, which requires an initialization |
702 | | // vector. The block size parameter is set to 16 bytes, and the initialization vector is a 16-byte random |
703 | | // number that is stored as the first 16 bytes of the encrypted stream or string. |
704 | 0 | assign(aes(bytes, m_encryption_key.value())); |
705 | 0 | return; |
706 | 0 | } |
707 | | |
708 | | // 7.6.2 General Encryption Algorithm |
709 | | // Algorithm 1: Encryption of data using the RC3 or AES algorithms |
710 | | |
711 | | // a) Obtain the object number and generation number from the object identifier of |
712 | | // the string or stream to be encrypted. If the string is a direct object, use |
713 | | // the identifier of the indirect object containing it. |
714 | | // |
715 | | // Note: This is always passed in at parse time because objects don't know their own |
716 | | // object number. |
717 | | |
718 | | // b) For all strings and streams with crypt filter specifier; treating the object |
719 | | // number as binary integers, extend the original n-byte encryption key to n + 5 |
720 | | // bytes by appending the low-order 3 bytes of the object number and the low-order |
721 | | // 2 bytes of the generation number in that order, low-order byte first. ... |
722 | | |
723 | 0 | auto encryption_key = m_encryption_key.value(); |
724 | 0 | auto index = reference.as_ref_index(); |
725 | 0 | auto generation = reference.as_ref_generation_index(); |
726 | |
|
727 | 0 | encryption_key.append(index & 0xff); |
728 | 0 | encryption_key.append((index >> 8) & 0xff); |
729 | 0 | encryption_key.append((index >> 16) & 0xff); |
730 | 0 | encryption_key.append(generation & 0xff); |
731 | 0 | encryption_key.append((generation >> 8) & 0xff); |
732 | |
|
733 | 0 | if (m_method == CryptFilterMethod::AESV2) { |
734 | 0 | encryption_key.append('s'); |
735 | 0 | encryption_key.append('A'); |
736 | 0 | encryption_key.append('l'); |
737 | 0 | encryption_key.append('T'); |
738 | 0 | } |
739 | | |
740 | | // c) Initialize the MD5 hash function and pass the result of step (b) as input to this |
741 | | // function. |
742 | 0 | Crypto::Hash::MD5 md5; |
743 | 0 | md5.update(encryption_key); |
744 | | |
745 | | // d) Use the first (n + 5) bytes, up to a maximum of 16, of the output from the MD5 |
746 | | // hash as the key for the RC4 or AES symmetric key algorithms, along with the string |
747 | | // or stream data to be encrypted. |
748 | 0 | auto key = ByteBuffer::copy(md5.peek().bytes()).release_value_but_fixme_should_propagate_errors(); |
749 | |
|
750 | 0 | if (key.size() > min(encryption_key.size(), 16)) |
751 | 0 | key.resize(encryption_key.size()); |
752 | |
|
753 | 0 | if (m_method == CryptFilterMethod::AESV2) { |
754 | 0 | assign(aes(bytes, key)); |
755 | 0 | return; |
756 | 0 | } |
757 | | |
758 | | // RC4 is symmetric, so decryption is the same as encryption. |
759 | 0 | VERIFY(m_method == CryptFilterMethod::V2); |
760 | 0 | RC4 rc4(key); |
761 | 0 | auto output = rc4.encrypt(bytes); |
762 | |
|
763 | 0 | assign(move(output)); |
764 | 0 | } |
765 | | |
766 | | void StandardSecurityHandler::encrypt(NonnullRefPtr<Object> object, Reference reference) const |
767 | 0 | { |
768 | 0 | crypt(object, reference, Crypto::Cipher::Intent::Encryption); |
769 | 0 | } |
770 | | |
771 | | void StandardSecurityHandler::decrypt(NonnullRefPtr<Object> object, Reference reference) const |
772 | 0 | { |
773 | 0 | crypt(object, reference, Crypto::Cipher::Intent::Decryption); |
774 | 0 | } |
775 | | |
776 | | static constexpr auto identity_permutation = iota_array<size_t, 256>(0); |
777 | | |
778 | | RC4::RC4(ReadonlyBytes key) |
779 | 0 | : m_bytes(identity_permutation) |
780 | 0 | { |
781 | 0 | size_t j = 0; |
782 | 0 | for (size_t i = 0; i < 256; i++) { |
783 | 0 | j = (j + m_bytes[i] + key[i % key.size()]) & 0xff; |
784 | 0 | swap(m_bytes[i], m_bytes[j]); |
785 | 0 | } |
786 | 0 | } |
787 | | |
788 | | void RC4::generate_bytes(ByteBuffer& bytes) |
789 | 0 | { |
790 | 0 | size_t i = 0; |
791 | 0 | size_t j = 0; |
792 | |
|
793 | 0 | for (size_t count = 0; count < bytes.size(); count++) { |
794 | 0 | i = (i + 1) % 256; |
795 | 0 | j = (j + m_bytes[i]) % 256; |
796 | 0 | swap(m_bytes[i], m_bytes[j]); |
797 | 0 | bytes[count] = m_bytes[(m_bytes[i] + m_bytes[j]) % 256]; |
798 | 0 | } |
799 | 0 | } |
800 | | |
801 | | ByteBuffer RC4::encrypt(ReadonlyBytes bytes) |
802 | 0 | { |
803 | 0 | auto output = ByteBuffer::create_uninitialized(bytes.size()).release_value_but_fixme_should_propagate_errors(); |
804 | 0 | generate_bytes(output); |
805 | 0 | for (size_t i = 0; i < bytes.size(); i++) |
806 | 0 | output[i] ^= bytes[i]; |
807 | 0 | return output; |
808 | 0 | } |
809 | | |
810 | | } |