1pub mod direntry;
5pub mod hkdf;
6pub mod proxy_filename;
7
8use anyhow::{anyhow, ensure, Error};
9use zerocopy::{FromBytes, Immutable, IntoBytes, KnownLayout, Unaligned};
10
11pub const POLICY_FLAGS_PAD_16: u8 = 0x02;
12pub const POLICY_FLAGS_INO_LBLK_32: u8 = 0x10;
13const SUPPORTED_POLICY_FLAGS: u8 = POLICY_FLAGS_PAD_16 | POLICY_FLAGS_INO_LBLK_32;
14
15pub const ENCRYPTION_MODE_AES_256_XTS: u8 = 1;
16pub const ENCRYPTION_MODE_AES_256_CTS: u8 = 4;
17
18#[repr(C, packed)]
21#[derive(Copy, Clone, Debug, Immutable, KnownLayout, FromBytes, IntoBytes, Unaligned)]
22pub struct Context {
23 pub version: u8, pub contents_encryption_mode: u8, pub filenames_encryption_mode: u8, pub flags: u8, pub log2_data_unit_size: u8, _reserved: [u8; 3],
29 pub main_key_identifier: [u8; 16],
30 pub nonce: [u8; 16],
31}
32
33impl Context {
34 pub fn try_from_bytes(raw_context: &[u8]) -> Result<Option<Self>, Error> {
35 let this = Context::read_from_bytes(raw_context)
36 .map_err(|_| anyhow!("Bad sized crypto context"))?;
37 ensure!(this.version == 2, "Bad version number in crypto context");
38 ensure!(
39 this.contents_encryption_mode == ENCRYPTION_MODE_AES_256_XTS,
40 "Unsupported contents_encryption_mode",
41 );
42 ensure!(
43 this.filenames_encryption_mode == ENCRYPTION_MODE_AES_256_CTS,
44 "Unsupported filenames_encryption_mode"
45 );
46 ensure!(this.flags & !SUPPORTED_POLICY_FLAGS == 0, "Unsupported flags in crypto context");
49 ensure!(this.log2_data_unit_size == 0, "Unsupported custom DUN size");
51 Ok(Some(this))
52 }
53}
54
55pub fn main_key_to_identifier(main_key: &[u8; 64]) -> [u8; 16] {
57 hkdf::fscrypt_hkdf::<16>(main_key, &[], 1)
58}
59
60#[cfg(test)]
61mod tests {
62 use super::*;
63
64 #[test]
65 fn test_main_key_to_identifier() {
66 let key_digest = "dc34d175ba21b27e2e92829b0dc12666ce8bfbcbae387014c6bb0d8b7678dafa6466bd7565b1a5999cd3f8a39a470528fa6816768e6985f0b10804af7d657810";
68 let key: [u8; 64] = hex::decode(&key_digest).unwrap().try_into().unwrap();
69 assert_eq!(hex::encode(main_key_to_identifier(&key)), "fc7f69a149f89a7529374cf9e96a6d13");
70 }
71}