1use corecrypto::key::vec_to_arr;
2use corecrypto::primitives::Algorithm;
3use corecrypto::primitives::ENCRYPTED_MASTER_KEY_LEN;
4use corecrypto::primitives::MASTER_KEY_LEN;
5use corecrypto::protected::Protected;
6use corecrypto::Zeroize;
7use corecrypto::{cipher::Ciphers, header::Keyslot};
8
9pub mod add;
10pub mod change;
11pub mod delete;
12pub mod verify;
13
14#[derive(Debug)]
15pub enum Error {
16 HeaderSizeParse,
17 Unsupported,
18 IncorrectKey,
19 MasterKeyEncrypt,
20 TooManyKeyslots,
21 KeyHash,
22 CipherInit,
23 HeaderDeserialize,
24 HeaderWrite,
25 Seek,
26}
27
28impl std::fmt::Display for Error {
29 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
30 match self {
31 Error::HeaderSizeParse => f.write_str("Cannot parse header size"),
32 Error::Seek => f.write_str("Unable to seek the data's cursor"),
33 Error::HeaderWrite => f.write_str("Unable to write the header"),
34 Error::HeaderDeserialize => f.write_str("Unable to deserialize the header"),
35 Error::CipherInit => f.write_str("Unable to initialize a cipher"),
36 Error::KeyHash => f.write_str("Unable to hash your key"),
37 Error::TooManyKeyslots => {
38 f.write_str("There are already too many populated keyslots within this file")
39 }
40 Error::MasterKeyEncrypt => f.write_str("Unable to encrypt master key"),
41 Error::Unsupported => {
42 f.write_str("The provided request is unsupported with this header version")
43 }
44 Error::IncorrectKey => f.write_str("The provided key is incorrect"),
45 }
46 }
47}
48
49pub fn decrypt_v5_master_key_with_index(
50 keyslots: &[Keyslot],
51 raw_key_old: Protected<Vec<u8>>,
52 algorithm: &Algorithm,
53) -> Result<(Protected<[u8; MASTER_KEY_LEN]>, usize), Error> {
54 let mut index = 0;
55 let mut master_key = [0u8; MASTER_KEY_LEN];
56
57 for (i, keyslot) in keyslots.iter().enumerate() {
59 let key_old = keyslot
60 .hash_algorithm
61 .hash(raw_key_old.clone(), &keyslot.salt)
62 .map_err(|_| Error::KeyHash)?;
63 let cipher = Ciphers::initialize(key_old, algorithm).map_err(|_| Error::CipherInit)?;
64
65 let master_key_result = cipher.decrypt(&keyslot.nonce, keyslot.encrypted_key.as_slice());
66
67 if master_key_result.is_err() {
68 continue;
69 }
70
71 let mut master_key_decrypted = master_key_result.unwrap();
72 let len = MASTER_KEY_LEN.min(master_key_decrypted.len());
73 master_key[..len].copy_from_slice(&master_key_decrypted[..len]);
74 master_key_decrypted.zeroize();
75
76 index = i;
77
78 drop(cipher);
79 break;
80 }
81
82 drop(raw_key_old);
83
84 if master_key == [0u8; MASTER_KEY_LEN] {
85 return Err(Error::IncorrectKey);
86 }
87
88 Ok((Protected::new(master_key), index))
89}
90
91impl std::error::Error for Error {}
92
93pub fn encrypt_master_key(
95 master_key: Protected<[u8; MASTER_KEY_LEN]>,
96 key_new: Protected<[u8; 32]>,
97 nonce: &[u8],
98 algorithm: &Algorithm,
99) -> Result<[u8; ENCRYPTED_MASTER_KEY_LEN], Error> {
100 let cipher = Ciphers::initialize(key_new, algorithm).map_err(|_| Error::CipherInit)?;
101
102 let master_key_result = cipher.encrypt(nonce, master_key.expose().as_slice());
103
104 drop(master_key);
105
106 let master_key_encrypted = master_key_result.map_err(|_| Error::MasterKeyEncrypt)?;
107
108 Ok(vec_to_arr(master_key_encrypted))
109}