1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
use crate::*;
use block_modes::BlockMode;
#[cfg(feature = "parallel")]
use rayon::prelude::*;
#[inline]
fn decrypt_page((index, mut page): (usize, &mut [u8]), key: &[u8]) -> Result<()> {
if index == 0 {
page = &mut page[16..];
}
let page_len = page.len();
let reserve_bytes = &page[page_len - 48..];
let iv = &reserve_bytes[..16];
let aes = Aes::new_var(&key, iv)?;
let page_content = &mut page[..page_len - 48];
aes.decrypt(page_content)?;
Ok(())
}
#[cfg(not(feature = "parallel"))]
#[inline]
fn decrypt_pages(data: &mut [u8], key: &[u8], page: usize) -> Result<()> {
data.chunks_exact_mut(page)
.enumerate()
.try_for_each(|x| {
decrypt_page(x, key)
})?;
Ok(())
}
#[cfg(feature = "parallel")]
#[inline]
fn decrypt_pages(data: &mut [u8], key: &[u8], page: usize) -> Result<()> {
data.par_chunks_exact_mut(page)
.enumerate()
.try_for_each(|x| decrypt_page(x, key))?;
Ok(())
}
pub fn decrypt(data: &mut [u8], key: &[u8], page: usize) -> Result<()> {
let salt = &data[..16];
let (key, _) = key_derive(key, salt, false);
data[..16].copy_from_slice(b"SQLite format 3\0");
decrypt_pages(data, &key, page)?;
Ok(())
}