kdbx4/encryption/kdf/
aes.rs1use aes::{Aes256, BlockEncrypt, NewBlockCipher};
2use sha2::{Digest, Sha256};
3
4use std::sync::Arc;
5use std::thread;
6
7pub(super) fn transform(key_to_derive: &[u8], enc_key: &[u8], rounds: u64) -> Vec<u8> {
8 let mut derived = [0; 32];
9 let mut left = [0; 16];
10 let mut right = [0; 16];
11
12 left.copy_from_slice(&key_to_derive[..16]);
13 right.copy_from_slice(&key_to_derive[16..]);
14
15 let key = Arc::from(enc_key);
16
17 let handle = {
18 let key = Arc::clone(&key);
19 thread::spawn(move || transform_inner(left, rounds, &key))
20 };
21
22 let r = transform_inner(right, rounds, &key);
23 let l = handle
24 .join()
25 .expect("Could not transform key (AES-KDF: failed to join a thread).");
26
27 derived[..16].copy_from_slice(&l);
28 derived[16..].copy_from_slice(&r);
29
30 sha256(&derived)
31}
32
33fn transform_inner(mut block: [u8; 16], rounds: u64, key: &[u8]) -> [u8; 16] {
34 let enc = Aes256::new(key.into());
35 for _ in 0..rounds {
36 enc.encrypt_block(block.as_mut().into());
37 }
38 block
39}
40
41fn sha256(slice: &[u8]) -> Vec<u8> {
42 let mut h = Sha256::new();
43 h.update(&slice);
44 h.finalize().as_slice().to_vec()
45}