1use std::io::{Cursor, Read, Write};
7
8use aes::cipher::KeyInit;
9use aes::cipher::generic_array::GenericArray;
10use aes::cipher::{BlockDecrypt, BlockEncrypt};
11use aes::{Aes128, Aes192, Aes256};
12use base64::Engine as _;
13use quick_xml::de::from_reader as xml_from_reader;
14use rand::RngCore;
15use serde::Deserialize;
16
17use crate::constants::MAX_FIELD_LENGTH;
18use crate::errors::{
19 ErrPasswordLengthInvalid, ErrUnknownEncryptMechanism, ErrUnsupportedEncryptMechanism,
20 ErrUnsupportedHashAlgorithm, ErrWorkbookFileFormat, Result,
21};
22use crate::lib_util::count_utf16_string;
23use crate::options::Options;
24
25const BLOCK_KEY: &[u8] = &[0x14, 0x6e, 0x0b, 0xe7, 0xab, 0xac, 0xd0, 0xd6];
30#[allow(dead_code)]
31const DIF_SECT: u32 = 0xFFFFFFFC;
32#[allow(dead_code)]
33const END_OF_CHAIN: u32 = 0xFFFFFFFE;
34#[allow(dead_code)]
35const FAT_SECT: u32 = 0xFFFFFFFD;
36const ITER_COUNT: usize = 50_000;
37const PACKAGE_ENCRYPTION_CHUNK_SIZE: usize = 4096;
38const PACKAGE_OFFSET: usize = 8;
39const _SHEET_PROTECTION_SPIN_COUNT: i32 = 100_000;
40const _WORKBOOK_PROTECTION_SPIN_COUNT: i32 = 100_000;
41
42#[derive(Debug, Default, Deserialize)]
48#[serde(rename = "encryption")]
49pub struct Encryption {
50 #[serde(rename = "keyData", default)]
51 pub key_data: KeyData,
52 #[serde(rename = "dataIntegrity", default)]
53 pub data_integrity: DataIntegrity,
54 #[serde(rename = "keyEncryptors", default)]
55 pub key_encryptors: KeyEncryptors,
56}
57
58#[derive(Debug, Default, Deserialize)]
60#[serde(rename = "keyData")]
61pub struct KeyData {
62 #[serde(rename = "@saltSize", default)]
63 pub salt_size: i32,
64 #[serde(rename = "@blockSize", default)]
65 pub block_size: i32,
66 #[serde(rename = "@keyBits", default)]
67 pub key_bits: i32,
68 #[serde(rename = "@hashSize", default)]
69 pub hash_size: i32,
70 #[serde(rename = "@cipherAlgorithm", default)]
71 pub cipher_algorithm: String,
72 #[serde(rename = "@cipherChaining", default)]
73 pub cipher_chaining: String,
74 #[serde(rename = "@hashAlgorithm", default)]
75 pub hash_algorithm: String,
76 #[serde(rename = "@saltValue", default)]
77 pub salt_value: String,
78}
79
80#[derive(Debug, Default, Deserialize)]
82#[serde(rename = "dataIntegrity")]
83pub struct DataIntegrity {
84 #[serde(rename = "@encryptedHmacKey", default)]
85 pub encrypted_hmac_key: String,
86 #[serde(rename = "@encryptedHmacValue", default)]
87 pub encrypted_hmac_value: String,
88}
89
90#[derive(Debug, Default, Deserialize)]
92#[serde(rename = "keyEncryptors")]
93pub struct KeyEncryptors {
94 #[serde(rename = "keyEncryptor", default)]
95 pub key_encryptor: Vec<KeyEncryptor>,
96}
97
98#[derive(Debug, Default, Deserialize)]
100#[serde(rename = "keyEncryptor")]
101pub struct KeyEncryptor {
102 #[serde(rename = "@uri", default)]
103 pub uri: String,
104 #[serde(rename = "encryptedKey")]
105 pub encrypted_key: EncryptedKey,
106}
107
108#[derive(Debug, Default, Deserialize)]
110#[serde(rename = "encryptedKey")]
111pub struct EncryptedKey {
112 #[serde(rename = "@spinCount", default)]
113 pub spin_count: i32,
114 #[serde(rename = "@encryptedVerifierHashInput", default)]
115 pub encrypted_verifier_hash_input: String,
116 #[serde(rename = "@encryptedVerifierHashValue", default)]
117 pub encrypted_verifier_hash_value: String,
118 #[serde(rename = "@encryptedKeyValue", default)]
119 pub encrypted_key_value: String,
120 #[serde(rename = "@saltSize", default)]
123 pub salt_size: i32,
124 #[serde(rename = "@blockSize", default)]
125 pub block_size: i32,
126 #[serde(rename = "@keyBits", default)]
127 pub key_bits: i32,
128 #[serde(rename = "@hashSize", default)]
129 pub hash_size: i32,
130 #[serde(rename = "@cipherAlgorithm", default)]
131 pub cipher_algorithm: String,
132 #[serde(rename = "@cipherChaining", default)]
133 pub cipher_chaining: String,
134 #[serde(rename = "@hashAlgorithm", default)]
135 pub hash_algorithm: String,
136 #[serde(rename = "@saltValue", default)]
137 pub salt_value: String,
138}
139
140#[derive(Debug, Default)]
145pub struct StandardEncryptionHeader {
146 pub flags: u32,
147 pub size_extra: u32,
148 pub alg_id: u32,
149 pub alg_id_hash: u32,
150 pub key_size: u32,
151 pub provider_type: u32,
152 pub reserved1: u32,
153 pub reserved2: u32,
154 pub csp_name: String,
155}
156
157#[derive(Debug, Default)]
158pub struct StandardEncryptionVerifier {
159 pub salt_size: u32,
160 pub salt: Vec<u8>,
161 pub encrypted_verifier: Vec<u8>,
162 pub verifier_hash_size: u32,
163 pub encrypted_verifier_hash: Vec<u8>,
164}
165
166#[derive(Debug)]
168struct EncryptionInfo {
169 block_size: usize,
170 salt_size: usize,
171 encrypted_key_value: Vec<u8>,
172 encrypted_verifier_hash_input: Vec<u8>,
173 encrypted_verifier_hash_value: Vec<u8>,
174 salt_value: Vec<u8>,
175 key_bits: u32,
176}
177
178pub fn decrypt(raw: &[u8], opts: &Options) -> Result<Vec<u8>> {
187 let mut doc = open_cfb(raw)?;
188 let (encryption_info_buf, encrypted_package_buf) = extract_part(&mut doc)?;
189 let mechanism = encryption_mechanism(&encryption_info_buf)?;
190 match mechanism.as_str() {
191 "agile" => agile_decrypt(&encryption_info_buf, &encrypted_package_buf, opts),
192 "standard" => standard_decrypt(&encryption_info_buf, &encrypted_package_buf, opts),
193 _ => Err(Box::new(ErrUnsupportedEncryptMechanism)),
194 }
195}
196
197pub fn encrypt(raw: &[u8], opts: &Options) -> Result<Vec<u8>> {
200 let mut encryptor = EncryptionInfo {
201 encrypted_verifier_hash_input: vec![0; 16],
202 encrypted_verifier_hash_value: vec![0; 32],
203 salt_value: vec![0; 16],
204 block_size: 16,
205 key_bits: 128,
206 salt_size: 16,
207 encrypted_key_value: Vec::new(),
208 };
209
210 let encryption_info_buffer = encryptor.standard_key_encryption(&opts.password)?;
211 let mut encrypted_package: Vec<u8> = Vec::with_capacity(8 + raw.len() + 16);
212 encrypted_package.extend_from_slice(&(raw.len() as u64).to_le_bytes());
213 encrypted_package.extend_from_slice(&encryptor.encrypt(raw));
214
215 let cursor = Cursor::new(Vec::new());
216 let mut compound_file = cfb::CompoundFile::create(cursor)?;
217 {
218 let mut stream = compound_file.create_stream("/EncryptionInfo")?;
219 stream.write_all(&encryption_info_buffer)?;
220 }
221 {
222 let mut stream = compound_file.create_stream("/EncryptedPackage")?;
223 stream.write_all(&encrypted_package)?;
224 }
225 compound_file.flush()?;
226 Ok(compound_file.into_inner().into_inner())
227}
228
229fn open_cfb(raw: &[u8]) -> Result<cfb::CompoundFile<Cursor<Vec<u8>>>> {
234 let cursor = Cursor::new(raw.to_vec());
235 match cfb::CompoundFile::open(cursor) {
236 Ok(doc) => Ok(doc),
237 Err(e) => {
238 let msg = e.to_string();
239 let re = regex::Regex::new(r"FAT has (\d+) entries, but file has only (\d+) sectors")
240 .unwrap();
241 if let Some(caps) = re.captures(&msg) {
242 let fat_entries: usize = caps[1].parse().unwrap_or(0);
243 if fat_entries > 0 {
244 let sector_size = 1usize << (raw.get(0x1E).copied().unwrap_or(9) as usize);
245 let required_len = (fat_entries + 1) * sector_size;
246 if raw.len() < required_len {
247 let mut padded = raw.to_vec();
248 padded.resize(required_len, 0);
249 let cursor = Cursor::new(padded);
250 return Ok(cfb::CompoundFile::open(cursor)?);
251 }
252 }
253 }
254 Err(Box::new(e))
255 }
256 }
257}
258
259fn extract_part(doc: &mut cfb::CompoundFile<Cursor<Vec<u8>>>) -> Result<(Vec<u8>, Vec<u8>)> {
260 let mut encryption_info_buf = Vec::new();
261 let mut encrypted_package_buf = Vec::new();
262
263 if let Ok(mut stream) = doc.open_stream("/EncryptionInfo") {
264 stream.read_to_end(&mut encryption_info_buf)?;
265 }
266 if let Ok(mut stream) = doc.open_stream("/EncryptedPackage") {
267 stream.read_to_end(&mut encrypted_package_buf)?;
268 }
269
270 if encryption_info_buf.is_empty() || encrypted_package_buf.is_empty() {
271 return Err(Box::new(ErrWorkbookFileFormat));
272 }
273 Ok((encryption_info_buf, encrypted_package_buf))
274}
275
276fn encryption_mechanism(buffer: &[u8]) -> Result<String> {
277 if buffer.len() < 4 {
278 return Err(Box::new(ErrUnknownEncryptMechanism));
279 }
280 let version_major = u16::from_le_bytes([buffer[0], buffer[1]]);
281 let version_minor = u16::from_le_bytes([buffer[2], buffer[3]]);
282
283 if version_major == 4 && version_minor == 4 {
284 return Ok("agile".to_string());
285 }
286 if (2..=4).contains(&version_major) && version_minor == 2 {
287 return Ok("standard".to_string());
288 }
289 if (version_major == 3 || version_major == 4) && version_minor == 3 {
290 return Err(Box::new(ErrUnsupportedEncryptMechanism));
291 }
292 Err(Box::new(ErrUnsupportedEncryptMechanism))
293}
294
295fn standard_decrypt(
300 encryption_info_buf: &[u8],
301 encrypted_package_buf: &[u8],
302 opts: &Options,
303) -> Result<Vec<u8>> {
304 if encryption_info_buf.len() < 12 {
305 return Err(Box::new(ErrWorkbookFileFormat));
306 }
307 let encryption_header_size = u32::from_le_bytes([
308 encryption_info_buf[8],
309 encryption_info_buf[9],
310 encryption_info_buf[10],
311 encryption_info_buf[11],
312 ]) as usize;
313 if 12 + encryption_header_size > encryption_info_buf.len() {
314 return Err(Box::new(ErrWorkbookFileFormat));
315 }
316 let block = &encryption_info_buf[12..12 + encryption_header_size];
317 let header = standard_encryption_header(block)?;
318 let verifier_block = &encryption_info_buf[12 + encryption_header_size..];
319 let algorithm = if matches!(header.alg_id, 0x0000_660E | 0x0000_660F | 0x0000_6610) {
320 "AES"
321 } else {
322 "RC4"
323 };
324 let verifier = standard_encryption_verifier(algorithm, verifier_block);
325 let secret_key = standard_convert_passwd_to_key(&header, &verifier, opts)?;
326
327 let x = &encrypted_package_buf[8..];
328 let decrypted = match secret_key.len() {
329 16 => decrypt_aes_ecb(
330 Aes128::new_from_slice(&secret_key).map_err(|e| {
331 std::io::Error::new(std::io::ErrorKind::InvalidData, format!("{e:?}"))
332 })?,
333 x,
334 ),
335 24 => decrypt_aes_ecb(
336 Aes192::new_from_slice(&secret_key).map_err(|e| {
337 std::io::Error::new(std::io::ErrorKind::InvalidData, format!("{e:?}"))
338 })?,
339 x,
340 ),
341 32 => decrypt_aes_ecb(
342 Aes256::new_from_slice(&secret_key).map_err(|e| {
343 std::io::Error::new(std::io::ErrorKind::InvalidData, format!("{e:?}"))
344 })?,
345 x,
346 ),
347 _ => {
348 return Err(Box::new(std::io::Error::new(
349 std::io::ErrorKind::InvalidData,
350 format!(
351 "unsupported standard encryption key size: {}",
352 header.key_size
353 ),
354 )));
355 }
356 };
357 Ok(decrypted)
358}
359
360fn decrypt_aes_ecb<C: BlockDecrypt>(cipher: C, input: &[u8]) -> Vec<u8> {
361 let mut decrypted = vec![0u8; input.len()];
362 for (src, dst) in input.chunks(16).zip(decrypted.chunks_mut(16)) {
363 let mut block = [0u8; 16];
364 block[..src.len()].copy_from_slice(src);
365 cipher.decrypt_block(GenericArray::from_mut_slice(&mut block));
366 dst.copy_from_slice(&block);
367 }
368 decrypted
369}
370
371fn standard_encryption_header(block: &[u8]) -> Result<StandardEncryptionHeader> {
372 if block.len() < 32 {
373 return Err(Box::new(ErrWorkbookFileFormat));
374 }
375 let csp_name = String::from_utf8_lossy(&block[32..]).to_string();
376 Ok(StandardEncryptionHeader {
377 flags: u32::from_le_bytes([block[0], block[1], block[2], block[3]]),
378 size_extra: u32::from_le_bytes([block[4], block[5], block[6], block[7]]),
379 alg_id: u32::from_le_bytes([block[8], block[9], block[10], block[11]]),
380 alg_id_hash: u32::from_le_bytes([block[12], block[13], block[14], block[15]]),
381 key_size: u32::from_le_bytes([block[16], block[17], block[18], block[19]]),
382 provider_type: u32::from_le_bytes([block[20], block[21], block[22], block[23]]),
383 reserved1: u32::from_le_bytes([block[24], block[25], block[26], block[27]]),
384 reserved2: u32::from_le_bytes([block[28], block[29], block[30], block[31]]),
385 csp_name,
386 })
387}
388
389fn standard_encryption_verifier(algorithm: &str, blob: &[u8]) -> StandardEncryptionVerifier {
390 let salt_size = u32::from_le_bytes([blob[0], blob[1], blob[2], blob[3]]);
391 let salt_end = 4 + salt_size as usize;
392 let salt = blob[4..salt_end].to_vec();
393 let verifier_end = salt_end + 16;
394 let encrypted_verifier = blob[salt_end..verifier_end].to_vec();
395 let verifier_hash_size = u32::from_le_bytes([
396 blob[verifier_end],
397 blob[verifier_end + 1],
398 blob[verifier_end + 2],
399 blob[verifier_end + 3],
400 ]);
401 let hash_end = match algorithm {
402 "RC4" => verifier_end + 4 + 20,
403 _ => verifier_end + 4 + 32,
404 };
405 let encrypted_verifier_hash = blob[verifier_end + 4..hash_end].to_vec();
406 StandardEncryptionVerifier {
407 salt_size,
408 salt,
409 encrypted_verifier,
410 verifier_hash_size,
411 encrypted_verifier_hash,
412 }
413}
414
415fn standard_convert_passwd_to_key(
416 header: &StandardEncryptionHeader,
417 verifier: &StandardEncryptionVerifier,
418 opts: &Options,
419) -> Result<Vec<u8>> {
420 let password_buffer = encode_utf16le(&opts.password);
421 let mut key = hashing("sha1", &[&verifier.salt, &password_buffer]);
422 for i in 0..ITER_COUNT {
423 let iterator = create_uint32_le_buffer(i as i32, 4);
424 key = hashing("sha1", &[&iterator, &key]);
425 }
426 let block = 0i32;
427 let h_final = hashing("sha1", &[&key, &create_uint32_le_buffer(block, 4)]);
428 let cb_required_key_length = (header.key_size / 8) as usize;
429 let cb_hash = 20; let buf1 = vec![0x36u8; 64];
432 let xored = standard_xor_bytes(&h_final, &buf1[..cb_hash]);
433 let mut buf1 = Vec::with_capacity(64);
434 buf1.extend_from_slice(&xored);
435 buf1.extend_from_slice(&vec![0x36u8; 64 - cb_hash]);
436 let x1 = hashing("sha1", &[&buf1]);
437
438 let buf2 = vec![0x5cu8; 64];
439 let xored = standard_xor_bytes(&h_final, &buf2[..cb_hash]);
440 let mut buf2 = Vec::with_capacity(64);
441 buf2.extend_from_slice(&xored);
442 buf2.extend_from_slice(&vec![0x5cu8; 64 - cb_hash]);
443 let x2 = hashing("sha1", &[&buf2]);
444
445 let mut x3 = x1;
446 x3.extend_from_slice(&x2);
447 Ok(x3[..cb_required_key_length].to_vec())
448}
449
450fn standard_xor_bytes(a: &[u8], b: &[u8]) -> Vec<u8> {
451 a.iter().zip(b.iter()).map(|(x, y)| x ^ y).collect()
452}
453
454impl EncryptionInfo {
455 fn encrypt(&self, input: &[u8]) -> Vec<u8> {
456 let input_bytes = if input.len() % self.block_size == 0 {
457 input.len()
458 } else {
459 input.len() + self.block_size - (input.len() % self.block_size)
460 };
461 let cipher = Aes128::new_from_slice(&self.encrypted_key_value).expect("valid AES key");
462 let mut output = Vec::with_capacity(input_bytes);
463 for i in (0..input_bytes).step_by(self.block_size) {
464 let mut chunk = [0u8; 16];
465 let end = (i + self.block_size).min(input.len());
466 chunk[..end - i].copy_from_slice(&input[i..end]);
467 cipher.encrypt_block(GenericArray::from_mut_slice(&mut chunk));
468 output.extend_from_slice(&chunk);
469 }
470 output
471 }
472
473 fn standard_key_encryption(&mut self, password: &str) -> Result<Vec<u8>> {
474 if count_utf16_string(password) == 0 || count_utf16_string(password) > MAX_FIELD_LENGTH {
475 return Err(Box::new(ErrPasswordLengthInvalid));
476 }
477 let mut stream = ByteWriter::new();
478 stream.write_uint16(0x0003);
479 stream.write_uint16(0x0002);
480 stream.write_uint32(0x24);
481 stream.write_uint32(0xA4);
482 stream.write_uint32(0x24);
483 stream.write_uint32(0x00);
484 stream.write_uint32(0x660E);
485 stream.write_uint32(0x8004);
486 stream.write_uint32(0x80);
487 stream.write_uint32(0x18);
488 stream.write_uint64(0x00);
489 let provider_name = "Microsoft Enhanced RSA and AES Cryptographic Provider (Prototype)";
490 stream.write_utf16le(provider_name);
491 stream.write_uint16(0x00);
492 stream.write_uint32(0x10);
493
494 let key_data_salt_value = random_bytes(self.salt_size)?;
495 let verifier_hash_input = random_bytes(16)?;
496 self.salt_value = key_data_salt_value;
497 self.encrypted_key_value = standard_convert_passwd_to_key(
498 &StandardEncryptionHeader {
499 key_size: self.key_bits,
500 ..Default::default()
501 },
502 &StandardEncryptionVerifier {
503 salt: self.salt_value.clone(),
504 ..Default::default()
505 },
506 &Options {
507 password: password.to_string(),
508 ..Default::default()
509 },
510 )?;
511 let verifier_hash_input_key = hashing("sha1", &[&verifier_hash_input]);
512 self.encrypted_verifier_hash_input = self.encrypt(&verifier_hash_input);
513 self.encrypted_verifier_hash_value = self.encrypt(&verifier_hash_input_key);
514
515 stream.write_bytes(&self.salt_value);
516 stream.write_bytes(&self.encrypted_verifier_hash_input);
517 stream.write_uint32(0x14);
518 stream.write_bytes(&self.encrypted_verifier_hash_value);
519 Ok(stream.into_inner())
520 }
521}
522
523fn agile_decrypt(
528 encryption_info_buf: &[u8],
529 encrypted_package_buf: &[u8],
530 opts: &Options,
531) -> Result<Vec<u8>> {
532 let encryption_info = parse_encryption_info(&encryption_info_buf[8..])?;
533 let key = convert_passwd_to_key(&opts.password, BLOCK_KEY, &encryption_info)?;
534 let encrypted_key = &encryption_info.key_encryptors.key_encryptor[0].encrypted_key;
535 let salt_value = base64_decode(&encrypted_key.salt_value)?;
536 let encrypted_key_value = base64_decode(&encrypted_key.encrypted_key_value)?;
537 let package_key = decrypt_aes_cbc(&key, &salt_value, &encrypted_key_value)?;
538 decrypt_package(&package_key, encrypted_package_buf, &encryption_info)
539}
540
541fn convert_passwd_to_key(
542 passwd: &str,
543 block_key: &[u8],
544 encryption: &Encryption,
545) -> Result<Vec<u8>> {
546 let encrypted_key = &encryption.key_encryptors.key_encryptor[0].encrypted_key;
547 let salt_value = base64_decode(&encrypted_key.salt_value)?;
548 let mut buffer = Vec::with_capacity(salt_value.len() + passwd.len() * 2);
549 buffer.extend_from_slice(&salt_value);
550 buffer.extend_from_slice(&encode_utf16le(passwd));
551
552 let mut key = hashing(&encryption.key_data.hash_algorithm, &[&buffer]);
553 for i in 0..encrypted_key.spin_count {
554 let iterator = create_uint32_le_buffer(i, 4);
555 key = hashing(&encryption.key_data.hash_algorithm, &[&iterator, &key]);
556 }
557 key = hashing(&encryption.key_data.hash_algorithm, &[&key, block_key]);
558
559 let key_bytes = (encrypted_key.key_bits / 8) as usize;
560 if key.len() < key_bytes {
561 key.extend_from_slice(&vec![0x36u8; 0x36]);
562 } else if key.len() > key_bytes {
563 key.truncate(key_bytes);
564 }
565 Ok(key)
566}
567
568fn parse_encryption_info(encryption_info: &[u8]) -> Result<Encryption> {
569 let xml = String::from_utf8_lossy(encryption_info);
570 let stripped = strip_encryption_namespaces(&xml);
571 Ok(xml_from_reader(stripped.as_bytes())?)
572}
573
574fn strip_encryption_namespaces(xml: &str) -> String {
575 let mut s = xml.to_string();
576 for ns in [
577 "xmlns=\"http://schemas.microsoft.com/office/2006/encryption\"",
578 "xmlns:p=\"http://schemas.microsoft.com/office/2006/keyEncryptor/password\"",
579 ] {
580 s = s.replace(ns, "");
581 }
582 let re = regex::Regex::new(r#"(</?|[\s])p:"#).unwrap();
585 re.replace_all(&s, "$1").to_string()
586}
587
588fn decrypt_aes_cbc(key: &[u8], iv: &[u8], input: &[u8]) -> Result<Vec<u8>> {
589 let mut output = input.to_vec();
590 let mut iv = iv.to_vec();
591 for chunk in output.chunks_mut(16) {
592 let encrypted = chunk.to_vec();
593 match key.len() {
594 16 => {
595 let cipher = Aes128::new_from_slice(key).map_err(|e| {
596 std::io::Error::new(std::io::ErrorKind::InvalidData, format!("{e:?}"))
597 })?;
598 cipher.decrypt_block(GenericArray::from_mut_slice(chunk));
599 }
600 24 => {
601 let cipher = Aes192::new_from_slice(key).map_err(|e| {
602 std::io::Error::new(std::io::ErrorKind::InvalidData, format!("{e:?}"))
603 })?;
604 cipher.decrypt_block(GenericArray::from_mut_slice(chunk));
605 }
606 32 => {
607 let cipher = Aes256::new_from_slice(key).map_err(|e| {
608 std::io::Error::new(std::io::ErrorKind::InvalidData, format!("{e:?}"))
609 })?;
610 cipher.decrypt_block(GenericArray::from_mut_slice(chunk));
611 }
612 _ => {
613 return Err(Box::new(std::io::Error::new(
614 std::io::ErrorKind::InvalidData,
615 "invalid AES key size",
616 )));
617 }
618 }
619 for i in 0..16 {
620 chunk[i] ^= iv[i];
621 }
622 iv = encrypted;
623 }
624 Ok(output)
625}
626
627fn decrypt_package(package_key: &[u8], input: &[u8], encryption: &Encryption) -> Result<Vec<u8>> {
628 let encrypted_key = &encryption.key_data;
629 if input.len() < PACKAGE_OFFSET {
630 return Err(Box::new(ErrWorkbookFileFormat));
631 }
632 let package_size = u64::from_le_bytes([
633 input[0], input[1], input[2], input[3], input[4], input[5], input[6], input[7],
634 ]) as usize;
635 let input = &input[PACKAGE_OFFSET..];
636 let mut output_chunks = Vec::with_capacity(input.len());
637 let mut end = 0;
638 let mut i = 0;
639 while end < input.len() {
640 let start = end;
641 end = (start + PACKAGE_ENCRYPTION_CHUNK_SIZE).min(input.len());
642 let mut input_chunk = input[start..end].to_vec();
643 let remainder = input_chunk.len() % encrypted_key.block_size as usize;
644 if remainder != 0 {
645 input_chunk
646 .extend_from_slice(&vec![0u8; encrypted_key.block_size as usize - remainder]);
647 }
648 let iv = create_iv(i, encryption)?;
649 let output_chunk = decrypt_aes_cbc(package_key, &iv, &input_chunk)?;
650 output_chunks.extend_from_slice(&output_chunk);
651 i += 1;
652 }
653 if output_chunks.len() > package_size {
654 output_chunks.truncate(package_size);
655 }
656 Ok(output_chunks)
657}
658
659fn create_iv(block_key_arg: i32, encryption: &Encryption) -> Result<Vec<u8>> {
660 let encrypted_key = &encryption.key_data;
661 let block_key_buf = create_uint32_le_buffer(block_key_arg, 4);
662 let salt_value = base64_decode(&encrypted_key.salt_value)?;
663 let mut iv = hashing(
664 &encrypted_key.hash_algorithm,
665 &[&salt_value, &block_key_buf],
666 );
667 if iv.len() < encrypted_key.block_size as usize {
668 iv.extend_from_slice(&vec![0x36u8; 0x36]);
669 } else if iv.len() > encrypted_key.block_size as usize {
670 iv.truncate(encrypted_key.block_size as usize);
671 }
672 Ok(iv)
673}
674
675fn hashing(hash_algorithm: &str, buffers: &[&[u8]]) -> Vec<u8> {
680 use digest::DynDigest;
681 let mut hasher: Box<dyn DynDigest> = match hash_algorithm.to_lowercase().as_str() {
682 "md4" => Box::new(md4::Md4::default()),
683 "md5" => Box::new(md5::Md5::default()),
684 "ripemd-160" => Box::new(ripemd::Ripemd160::default()),
685 "sha1" => Box::new(sha1::Sha1::default()),
686 "sha256" => Box::new(sha2::Sha256::default()),
687 "sha384" => Box::new(sha2::Sha384::default()),
688 "sha512" => Box::new(sha2::Sha512::default()),
689 _ => return Vec::new(),
690 };
691 for buf in buffers {
692 hasher.update(buf);
693 }
694 hasher.finalize_reset().to_vec()
695}
696
697fn create_uint32_le_buffer(value: i32, buffer_size: usize) -> Vec<u8> {
698 let mut buf = vec![0u8; buffer_size];
699 let bytes = (value as u32).to_le_bytes();
700 buf[..4].copy_from_slice(&bytes);
701 buf
702}
703
704fn encode_utf16le(s: &str) -> Vec<u8> {
705 let mut out = Vec::with_capacity(s.len() * 2);
706 for unit in s.encode_utf16() {
707 out.extend_from_slice(&unit.to_le_bytes());
708 }
709 out
710}
711
712fn base64_decode(s: &str) -> Result<Vec<u8>> {
713 Ok(base64::engine::general_purpose::STANDARD.decode(s)?)
714}
715
716fn random_bytes(n: usize) -> Result<Vec<u8>> {
717 let mut buf = vec![0u8; n];
718 rand::thread_rng().fill_bytes(&mut buf);
719 Ok(buf)
720}
721
722pub fn gen_iso_passwd_hash(
728 passwd: &str,
729 hash_algorithm: &str,
730 salt: &str,
731 spin_count: i32,
732) -> Result<(String, String)> {
733 if count_utf16_string(passwd) < 1 || count_utf16_string(passwd) > MAX_FIELD_LENGTH {
734 return Err(Box::new(ErrPasswordLengthInvalid));
735 }
736 let algorithm_name = match hash_algorithm {
737 "MD4" => "md4",
738 "MD5" => "md5",
739 "SHA-1" => "sha1",
740 "SHA-256" => "sha256",
741 "SHA-384" => "sha384",
742 "SHA-512" => "sha512",
743 _ => return Err(Box::new(ErrUnsupportedHashAlgorithm)),
744 };
745 let mut s = random_bytes(16)?;
746 if !salt.is_empty() {
747 s = base64_decode(salt)?;
748 }
749 let mut buffer = Vec::with_capacity(s.len() + passwd.len() * 2);
750 buffer.extend_from_slice(&s);
751 buffer.extend_from_slice(&encode_utf16le(passwd));
752 let mut key = hashing(algorithm_name, &[&buffer]);
753 for i in 0..spin_count {
754 let iterator = create_uint32_le_buffer(i, 4);
755 key = hashing(algorithm_name, &[&key, &iterator]);
756 }
757 Ok((
758 base64::engine::general_purpose::STANDARD.encode(&key),
759 base64::engine::general_purpose::STANDARD.encode(&s),
760 ))
761}
762
763struct ByteWriter {
768 buf: Vec<u8>,
769}
770
771impl ByteWriter {
772 fn new() -> Self {
773 Self { buf: Vec::new() }
774 }
775
776 fn write_bytes(&mut self, value: &[u8]) {
777 self.buf.extend_from_slice(value);
778 }
779
780 fn write_uint16(&mut self, value: u16) {
781 self.buf.extend_from_slice(&value.to_le_bytes());
782 }
783
784 fn write_uint32(&mut self, value: u32) {
785 self.buf.extend_from_slice(&value.to_le_bytes());
786 }
787
788 fn write_uint64(&mut self, value: u64) {
789 self.buf.extend_from_slice(&value.to_le_bytes());
790 }
791
792 fn write_utf16le(&mut self, value: &str) {
793 self.write_bytes(&encode_utf16le(value));
794 }
795
796 fn into_inner(self) -> Vec<u8> {
797 self.buf
798 }
799}