1use crate::{EncryptionKey, UnwrappedKey, WrappedKey};
5use anyhow::Error;
6use std::collections::BTreeMap;
7use std::sync::Arc;
8pub use storage_ptr_slice::{MutPtrByteSlice, PtrByteSlice};
9pub use storage_xts::{Tweak, XtsInPlaceProcessor, XtsProcessor};
10use zx_status as zx;
11
12pub mod fscrypt_ino_lblk32;
13#[cfg(test)]
14mod fscrypt_test_data;
15pub(crate) mod fxfs;
16
17pub const FSCRYPT_PADDING: usize = 16;
22const SECTOR_SIZE: u64 = 512;
25
26pub trait Cipher: std::fmt::Debug + Send + Sync {
28 fn encrypt(
35 &self,
36 ino: u64,
37 attribute_id: u64,
38 device_offset: u64,
39 file_offset: u64,
40 buffer: MutPtrByteSlice<'_>,
41 ) -> Result<(), Error>;
42
43 fn decrypt(
50 &self,
51 ino: u64,
52 attribute_id: u64,
53 device_offset: u64,
54 file_offset: u64,
55 buffer: MutPtrByteSlice<'_>,
56 ) -> Result<(), Error>;
57
58 fn decrypt_to(
64 &self,
65 ino: u64,
66 attribute_id: u64,
67 device_offset: u64,
68 file_offset: u64,
69 src: PtrByteSlice<'_>,
70 mut dst: MutPtrByteSlice<'_>,
71 ) -> Result<(), Error> {
72 dst.copy_from_ptr_slice(src);
73 self.decrypt(ino, attribute_id, device_offset, file_offset, dst)
74 }
75
76 fn encrypt_filename(&self, object_id: u64, buffer: &mut Vec<u8>) -> Result<(), Error>;
78
79 fn decrypt_filename(&self, object_id: u64, buffer: &mut Vec<u8>) -> Result<(), Error>;
81
82 fn encrypt_symlink(&self, object_id: u64, buffer: &mut Vec<u8>) -> Result<(), Error> {
84 self.encrypt_filename(object_id, buffer)
85 }
86
87 fn decrypt_symlink(&self, object_id: u64, buffer: &mut Vec<u8>) -> Result<(), Error> {
89 self.decrypt_filename(object_id, buffer)
90 }
91
92 fn hash_code(&self, _raw_filename: &[u8], filename: &str) -> Option<u32>;
95
96 fn hash_code_casefold(&self, _filename: &str) -> u32;
98
99 fn supports_inline_encryption(&self) -> bool;
101
102 fn crypt_ctx(&self, ino: u64, attribute_id: u64, file_offset: u64) -> Option<(u64, u8)>;
105}
106
107#[derive(Clone, Copy, Debug, PartialEq, Eq)]
108pub enum KeyType {
109 Fxfs,
110 FscryptInoLblk32Dir,
111 FscryptInoLblk32File,
112}
113
114pub trait ToKeyType {
115 fn to_key_type(&self) -> Option<KeyType>;
116}
117
118impl ToKeyType for WrappedKey {
119 fn to_key_type(&self) -> Option<KeyType> {
120 match self {
121 WrappedKey::Fxfs(_) => Some(KeyType::Fxfs),
122 WrappedKey::FscryptInoLblk32Dir { .. } => Some(KeyType::FscryptInoLblk32Dir),
123 WrappedKey::FscryptInoLblk32File { .. } => Some(KeyType::FscryptInoLblk32File),
124 _ => None,
125 }
126 }
127}
128
129impl ToKeyType for EncryptionKey {
130 fn to_key_type(&self) -> Option<KeyType> {
131 match self {
132 EncryptionKey::LegacyFxfs(_) => unreachable!(),
133 EncryptionKey::Fxfs(_) => Some(KeyType::Fxfs),
134 EncryptionKey::FscryptInoLblk32Dir { .. } => Some(KeyType::FscryptInoLblk32Dir),
135 EncryptionKey::FscryptInoLblk32File { .. } => Some(KeyType::FscryptInoLblk32File),
136 }
137 }
138}
139
140impl ToKeyType for KeyType {
141 fn to_key_type(&self) -> Option<KeyType> {
142 Some(*self)
143 }
144}
145
146#[inline]
150pub fn key_to_cipher(
151 key_type: &impl ToKeyType,
152 unwrapped_key: &UnwrappedKey,
153) -> Result<Arc<dyn Cipher>, zx::Status> {
154 key_type
155 .to_key_type()
156 .map(|key_type| match key_type {
157 KeyType::Fxfs => Arc::new(fxfs::FxfsCipher::new(&unwrapped_key)) as Arc<dyn Cipher>,
158 KeyType::FscryptInoLblk32Dir => {
159 Arc::new(fscrypt_ino_lblk32::FscryptInoLblk32DirCipher::new(&unwrapped_key))
160 }
161 KeyType::FscryptInoLblk32File => {
162 Arc::new(fscrypt_ino_lblk32::FscryptInoLblk32FileCipher::new(&unwrapped_key))
163 }
164 })
165 .ok_or(zx::Status::NOT_SUPPORTED)
166}
167
168#[derive(Clone, Debug)]
169pub enum CipherHolder {
170 Cipher(Arc<dyn Cipher>),
171 Unavailable,
172}
173
174impl CipherHolder {
175 pub fn into_cipher(self) -> Option<Arc<dyn Cipher>> {
176 match self {
177 CipherHolder::Cipher(c) => Some(c),
178 _ => None,
179 }
180 }
181}
182
183#[derive(Clone, Debug, Default)]
185pub struct CipherSet(BTreeMap<u64, CipherHolder>);
186impl CipherSet {
187 pub fn find_key(self: &Arc<Self>, id: u64) -> FindKeyResult {
188 match self.0.get(&id) {
189 Some(CipherHolder::Cipher(cipher)) => FindKeyResult::Key(Arc::clone(cipher)),
190 Some(CipherHolder::Unavailable) => FindKeyResult::Unavailable,
191 None => FindKeyResult::NotFound,
192 }
193 }
194
195 pub fn add_key(&mut self, id: u64, cipher: CipherHolder) {
196 self.0.insert(id, cipher);
197 }
198}
199impl From<Vec<(u64, CipherHolder)>> for CipherSet {
200 fn from(keys: Vec<(u64, CipherHolder)>) -> Self {
201 Self(keys.into_iter().collect())
202 }
203}
204impl From<BTreeMap<u64, CipherHolder>> for CipherSet {
205 fn from(keys: BTreeMap<u64, CipherHolder>) -> Self {
206 Self(keys)
207 }
208}
209
210pub enum FindKeyResult {
211 NotFound,
213 Unavailable,
215 Key(Arc<dyn Cipher>),
216}