kdbx4/encryption/kdf/
aes.rs

1use 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}