1use aes::cipher::generic_array::GenericArray;
6use aes::cipher::inout::InOut;
7use aes::cipher::typenum::consts::U16;
8use aes::cipher::{
9 BlockBackend, BlockClosure, BlockDecrypt, BlockEncrypt, BlockSizeUser, KeyInit, KeyIvInit,
10 StreamCipher as _, StreamCipherSeek,
11};
12use aes::Aes256;
13use anyhow::{anyhow, Error};
14use async_trait::async_trait;
15use chacha20::{self, ChaCha20};
16use fprint::TypeFingerprint;
17use futures::stream::FuturesUnordered;
18use futures::TryStreamExt as _;
19use fxfs_macros::{migrate_nodefault, Migrate};
20use serde::de::{Error as SerdeError, Visitor};
21use serde::{Deserialize, Deserializer, Serialize, Serializer};
22use static_assertions::assert_cfg;
23use std::sync::Arc;
24use zerocopy::{FromBytes, Immutable, IntoBytes, KnownLayout};
25use zx_status as zx;
26
27pub mod ff1;
28
29pub const KEY_SIZE: usize = 256 / 8;
30pub const WRAPPED_KEY_SIZE: usize = KEY_SIZE + 16;
31pub const FSCRYPT_PADDING: usize = 16;
34
35const SECTOR_SIZE: u64 = 512;
38
39pub type KeyBytes = [u8; KEY_SIZE];
40
41#[derive(Debug)]
42pub struct UnwrappedKey {
43 key: KeyBytes,
44}
45
46impl UnwrappedKey {
47 pub fn new(key: KeyBytes) -> Self {
48 UnwrappedKey { key }
49 }
50
51 pub fn key(&self) -> &KeyBytes {
52 &self.key
53 }
54}
55
56pub type UnwrappedKeys = Vec<(u64, Option<UnwrappedKey>)>;
57
58pub type WrappedKeyBytes = WrappedKeyBytesV32;
59
60#[repr(transparent)]
61#[derive(Clone, Debug, PartialEq)]
62pub struct WrappedKeyBytesV32(pub [u8; WRAPPED_KEY_SIZE]);
63
64impl Default for WrappedKeyBytes {
65 fn default() -> Self {
66 Self([0u8; WRAPPED_KEY_SIZE])
67 }
68}
69
70impl TryFrom<Vec<u8>> for WrappedKeyBytes {
71 type Error = anyhow::Error;
72
73 fn try_from(buf: Vec<u8>) -> Result<Self, Self::Error> {
74 Ok(Self(buf.try_into().map_err(|_| anyhow!("wrapped key wrong length"))?))
75 }
76}
77
78impl From<[u8; WRAPPED_KEY_SIZE]> for WrappedKeyBytes {
79 fn from(buf: [u8; WRAPPED_KEY_SIZE]) -> Self {
80 Self(buf)
81 }
82}
83
84impl TypeFingerprint for WrappedKeyBytes {
85 fn fingerprint() -> String {
86 "WrappedKeyBytes".to_owned()
87 }
88}
89
90impl std::ops::Deref for WrappedKeyBytes {
91 type Target = [u8; WRAPPED_KEY_SIZE];
92 fn deref(&self) -> &Self::Target {
93 &self.0
94 }
95}
96
97impl std::ops::DerefMut for WrappedKeyBytes {
98 fn deref_mut(&mut self) -> &mut Self::Target {
99 &mut self.0
100 }
101}
102
103impl Serialize for WrappedKeyBytes {
106 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
107 where
108 S: Serializer,
109 {
110 serializer.serialize_bytes(&self[..])
111 }
112}
113
114impl<'de> Deserialize<'de> for WrappedKeyBytes {
115 fn deserialize<D>(deserializer: D) -> Result<WrappedKeyBytes, D::Error>
116 where
117 D: Deserializer<'de>,
118 {
119 struct WrappedKeyVisitor;
120
121 impl<'d> Visitor<'d> for WrappedKeyVisitor {
122 type Value = WrappedKeyBytes;
123
124 fn expecting(&self, formatter: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
125 formatter.write_str("Expected wrapped keys to be 48 bytes")
126 }
127
128 fn visit_bytes<E>(self, bytes: &[u8]) -> Result<WrappedKeyBytes, E>
129 where
130 E: SerdeError,
131 {
132 self.visit_byte_buf(bytes.to_vec())
133 }
134
135 fn visit_byte_buf<E>(self, bytes: Vec<u8>) -> Result<WrappedKeyBytes, E>
136 where
137 E: SerdeError,
138 {
139 let orig_len = bytes.len();
140 let bytes: [u8; WRAPPED_KEY_SIZE] =
141 bytes.try_into().map_err(|_| SerdeError::invalid_length(orig_len, &self))?;
142 Ok(WrappedKeyBytes::from(bytes))
143 }
144 }
145 deserializer.deserialize_byte_buf(WrappedKeyVisitor)
146 }
147}
148
149pub type WrappedKey = WrappedKeyV40;
150
151#[derive(Clone, Debug, Serialize, Deserialize, TypeFingerprint, PartialEq)]
152pub struct WrappedKeyV40 {
153 pub wrapping_key_id: u128,
156 pub key: WrappedKeyBytesV32,
162}
163
164#[derive(Default, Clone, Migrate, Debug, Serialize, Deserialize, TypeFingerprint)]
165#[migrate_nodefault]
166pub struct WrappedKeyV32 {
167 pub wrapping_key_id: u64,
168 pub key: WrappedKeyBytesV32,
169}
170
171pub type WrappedKeys = WrappedKeysV40;
174
175#[derive(Clone, Debug, Default, Serialize, Deserialize, PartialEq, TypeFingerprint)]
176pub struct WrappedKeysV40(Vec<(u64, WrappedKeyV40)>);
177
178impl From<WrappedKeysV32> for WrappedKeysV40 {
179 fn from(value: WrappedKeysV32) -> Self {
180 Self(value.0.into_iter().map(|(id, key)| (id, key.into())).collect())
181 }
182}
183#[derive(Clone, Debug, Serialize, Deserialize, TypeFingerprint)]
184pub struct WrappedKeysV32(pub Vec<(u64, WrappedKeyV32)>);
185
186impl From<Vec<(u64, WrappedKey)>> for WrappedKeys {
187 fn from(buf: Vec<(u64, WrappedKey)>) -> Self {
188 Self(buf)
189 }
190}
191
192impl std::ops::Deref for WrappedKeys {
193 type Target = Vec<(u64, WrappedKey)>;
194 fn deref(&self) -> &Self::Target {
195 &self.0
196 }
197}
198
199impl std::ops::DerefMut for WrappedKeys {
200 fn deref_mut(&mut self) -> &mut Self::Target {
201 &mut self.0
202 }
203}
204
205impl WrappedKeys {
206 pub fn get_wrapping_key_with_id(&self, key_id: u64) -> Option<[u8; 16]> {
207 let wrapped_key_entry = self.0.iter().find(|(x, _)| *x == key_id);
208 wrapped_key_entry.map(|(_, wrapped_key)| wrapped_key.wrapping_key_id.to_le_bytes())
209 }
210}
211
212#[derive(Clone, Debug)]
213pub struct Cipher {
214 id: u64,
215 cipher: Option<Aes256>,
217}
218
219impl Cipher {
220 pub fn new(id: u64, key: &UnwrappedKey) -> Self {
221 Self { id, cipher: Some(Aes256::new(GenericArray::from_slice(key.key()))) }
222 }
223
224 pub fn unavailable(id: u64) -> Self {
225 Cipher { id, cipher: None }
226 }
227
228 pub fn key(&self) -> Option<&Aes256> {
229 self.cipher.as_ref()
230 }
231}
232
233pub struct Key {
235 keys: Arc<CipherSet>,
236 index: usize,
238}
239
240impl Key {
241 fn key(&self) -> &Aes256 {
242 self.keys.0[self.index].cipher.as_ref().unwrap()
243 }
244
245 pub fn key_id(&self) -> u64 {
246 self.keys.0[self.index].id
247 }
248
249 pub fn encrypt(&self, offset: u64, buffer: &mut [u8]) -> Result<(), Error> {
256 fxfs_trace::duration!(c"encrypt", "len" => buffer.len());
257 assert_eq!(offset % SECTOR_SIZE, 0);
258 let cipher = &self.key();
259 let mut sector_offset = offset / SECTOR_SIZE;
260 for sector in buffer.chunks_exact_mut(SECTOR_SIZE as usize) {
261 let mut tweak = Tweak(sector_offset as u128);
262 cipher.encrypt_block(GenericArray::from_mut_slice(tweak.as_mut_bytes()));
264 cipher.encrypt_with_backend(XtsProcessor::new(tweak, sector));
265 sector_offset += 1;
266 }
267 Ok(())
268 }
269
270 pub fn decrypt(&self, offset: u64, buffer: &mut [u8]) -> Result<(), Error> {
277 fxfs_trace::duration!(c"decrypt", "len" => buffer.len());
278 assert_eq!(offset % SECTOR_SIZE, 0);
279 let cipher = &self.key();
280 let mut sector_offset = offset / SECTOR_SIZE;
281 for sector in buffer.chunks_exact_mut(SECTOR_SIZE as usize) {
282 let mut tweak = Tweak(sector_offset as u128);
283 cipher.encrypt_block(GenericArray::from_mut_slice(tweak.as_mut_bytes()));
285 cipher.decrypt_with_backend(XtsProcessor::new(tweak, sector));
286 sector_offset += 1;
287 }
288 Ok(())
289 }
290
291 pub fn encrypt_filename(&self, object_id: u64, buffer: &mut Vec<u8>) -> Result<(), Error> {
293 buffer.resize(buffer.len().next_multiple_of(FSCRYPT_PADDING), 0);
295 let cipher = self.key();
296 cipher.encrypt_with_backend(CbcEncryptProcessor::new(Tweak(object_id as u128), buffer));
297 Ok(())
298 }
299
300 pub fn decrypt_filename(&self, object_id: u64, buffer: &mut Vec<u8>) -> Result<(), Error> {
302 let cipher = self.key();
303 cipher.decrypt_with_backend(CbcDecryptProcessor::new(Tweak(object_id as u128), buffer));
304 if let Some(i) = buffer.iter().rposition(|x| *x != 0) {
306 let new_len = i + 1;
307 buffer.truncate(new_len);
308 }
309 Ok(())
310 }
311}
312
313#[derive(Clone, Debug)]
314pub struct CipherSet(Vec<Cipher>);
315
316impl From<Vec<Cipher>> for CipherSet {
317 fn from(value: Vec<Cipher>) -> Self {
318 Self(value)
319 }
320}
321
322impl CipherSet {
323 pub fn new(keys: &UnwrappedKeys) -> Self {
324 Self(
325 keys.iter()
326 .map(|(id, k)| match k {
327 Some(k) => Cipher::new(*id, k),
328 None => Cipher::unavailable(*id),
329 })
330 .collect(),
331 )
332 }
333
334 pub fn ciphers(&self) -> &[Cipher] {
335 &self.0
336 }
337
338 pub fn cipher(&self, id: u64) -> Option<(usize, &Cipher)> {
339 self.0.iter().enumerate().find(|(_, x)| x.id == id)
340 }
341
342 pub fn contains_key_id(&self, id: u64) -> bool {
343 self.0.iter().find(|x| x.id == id).is_some()
344 }
345
346 pub fn find_key(self: &Arc<Self>, id: u64) -> FindKeyResult {
347 let Some((index, cipher)) = self.0.iter().enumerate().find(|(_, x)| x.id == id) else {
348 return FindKeyResult::NotFound;
349 };
350 if cipher.key().is_some() {
351 FindKeyResult::Key(Key { keys: self.clone(), index })
352 } else {
353 FindKeyResult::Unavailable
354 }
355 }
356}
357
358pub enum FindKeyResult {
359 NotFound,
360 Unavailable,
361 Key(Key),
362}
363
364pub struct StreamCipher(ChaCha20);
368
369impl StreamCipher {
370 pub fn new(key: &UnwrappedKey, offset: u64) -> Self {
371 let mut cipher = Self(ChaCha20::new(
372 chacha20::Key::from_slice(&key.key),
373 &[0; 12].into(),
374 ));
375 cipher.0.seek(offset);
376 cipher
377 }
378
379 pub fn encrypt(&mut self, buffer: &mut [u8]) {
380 fxfs_trace::duration!(c"StreamCipher::encrypt", "len" => buffer.len());
381 self.0.apply_keystream(buffer);
382 }
383
384 pub fn decrypt(&mut self, buffer: &mut [u8]) {
385 fxfs_trace::duration!(c"StreamCipher::decrypt", "len" => buffer.len());
386 self.0.apply_keystream(buffer);
387 }
388
389 pub fn offset(&self) -> u64 {
390 self.0.current_pos()
391 }
392}
393
394pub enum KeyPurpose {
397 Data,
399 Metadata,
401}
402
403#[async_trait]
408pub trait Crypt: Send + Sync {
409 async fn create_key(
414 &self,
415 owner: u64,
416 purpose: KeyPurpose,
417 ) -> Result<(WrappedKey, UnwrappedKey), zx::Status>;
418
419 async fn create_key_with_id(
424 &self,
425 owner: u64,
426 wrapping_key_id: u128,
427 ) -> Result<(WrappedKey, UnwrappedKey), zx::Status>;
428
429 async fn unwrap_key(
431 &self,
432 wrapped_key: &WrappedKey,
433 owner: u64,
434 ) -> Result<UnwrappedKey, zx::Status>;
435
436 async fn unwrap_keys(
438 &self,
439 keys: &WrappedKeys,
440 owner: u64,
441 ) -> Result<UnwrappedKeys, zx::Status> {
442 let futures = FuturesUnordered::new();
443 for (key_id, key) in keys.iter() {
444 futures.push(async move {
445 match self.unwrap_key(key, owner).await {
446 Ok(unwrapped_key) => Ok((*key_id, Some(unwrapped_key))),
447 Err(zx::Status::NOT_FOUND) => Ok((*key_id, None)),
448 Err(e) => Err(e),
449 }
450 });
451 }
452 Ok(futures.try_collect::<UnwrappedKeys>().await?)
453 }
454}
455
456assert_cfg!(target_endian = "little");
458#[derive(IntoBytes, KnownLayout, FromBytes, Immutable)]
459#[repr(C)]
460struct Tweak(u128);
461
462pub fn xor_in_place(a: &mut [u8], b: &[u8]) {
463 for (b1, b2) in a.iter_mut().zip(b.iter()) {
464 *b1 ^= *b2;
465 }
466}
467
468struct CbcEncryptProcessor<'a> {
470 tweak: Tweak,
471 data: &'a mut [u8],
472}
473
474impl<'a> CbcEncryptProcessor<'a> {
475 fn new(tweak: Tweak, data: &'a mut [u8]) -> Self {
476 Self { tweak, data }
477 }
478}
479
480impl BlockSizeUser for CbcEncryptProcessor<'_> {
481 type BlockSize = U16;
482}
483
484impl BlockClosure for CbcEncryptProcessor<'_> {
485 fn call<B: BlockBackend<BlockSize = Self::BlockSize>>(self, backend: &mut B) {
486 let Self { mut tweak, data } = self;
487 for block in data.chunks_exact_mut(16) {
488 xor_in_place(block, &tweak.0.to_le_bytes());
489 let chunk: &mut GenericArray<u8, _> = GenericArray::from_mut_slice(block);
490 backend.proc_block(InOut::from(chunk));
491 tweak.0 = u128::from_le_bytes(block.try_into().unwrap())
492 }
493 }
494}
495
496struct CbcDecryptProcessor<'a> {
498 tweak: Tweak,
499 data: &'a mut [u8],
500}
501
502impl<'a> CbcDecryptProcessor<'a> {
503 fn new(tweak: Tweak, data: &'a mut [u8]) -> Self {
504 Self { tweak, data }
505 }
506}
507
508impl BlockSizeUser for CbcDecryptProcessor<'_> {
509 type BlockSize = U16;
510}
511
512impl BlockClosure for CbcDecryptProcessor<'_> {
513 fn call<B: BlockBackend<BlockSize = Self::BlockSize>>(self, backend: &mut B) {
514 let Self { mut tweak, data } = self;
515 for block in data.chunks_exact_mut(16) {
516 let ciphertext = block.to_vec();
517 let chunk = GenericArray::from_mut_slice(block);
518 backend.proc_block(InOut::from(chunk));
519 xor_in_place(block, &tweak.0.to_le_bytes());
520 tweak.0 = u128::from_le_bytes(ciphertext.try_into().unwrap());
521 }
522 }
523}
524
525struct XtsProcessor<'a> {
527 tweak: Tweak,
528 data: &'a mut [u8],
529}
530
531impl<'a> XtsProcessor<'a> {
532 fn new(tweak: Tweak, data: &'a mut [u8]) -> Self {
534 assert_eq!(data.as_ptr() as usize & 15, 0, "data must be 16 byte aligned");
535 Self { tweak, data }
536 }
537}
538
539impl BlockSizeUser for XtsProcessor<'_> {
540 type BlockSize = U16;
541}
542
543impl BlockClosure for XtsProcessor<'_> {
544 fn call<B: BlockBackend<BlockSize = Self::BlockSize>>(self, backend: &mut B) {
545 let Self { mut tweak, data } = self;
546 for chunk in data.chunks_exact_mut(16) {
547 let ptr = chunk.as_mut_ptr() as *mut u128;
548 unsafe {
555 *ptr ^= tweak.0;
556 let chunk = ptr as *mut GenericArray<u8, U16>;
557 backend.proc_block(InOut::from_raw(chunk, chunk));
558 *ptr ^= tweak.0;
559 }
560 tweak.0 = (tweak.0 << 1) ^ ((tweak.0 as i128 >> 127) as u128 & 0x87);
561 }
562 }
563}
564
565#[cfg(test)]
566mod tests {
567 use crate::{Cipher, CipherSet, Key};
568
569 use super::{StreamCipher, UnwrappedKey};
570
571 #[test]
572 fn test_stream_cipher_offset() {
573 let key = UnwrappedKey::new([
574 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
575 25, 26, 27, 28, 29, 30, 31, 32,
576 ]);
577 let mut cipher1 = StreamCipher::new(&key, 0);
578 let mut p1 = [1, 2, 3, 4];
579 let mut c1 = p1.clone();
580 cipher1.encrypt(&mut c1);
581
582 let mut cipher2 = StreamCipher::new(&key, 1);
583 let p2 = [5, 6, 7, 8];
584 let mut c2 = p2.clone();
585 cipher2.encrypt(&mut c2);
586
587 let xor_fn = |buf1: &mut [u8], buf2| {
588 for (b1, b2) in buf1.iter_mut().zip(buf2) {
589 *b1 ^= b2;
590 }
591 };
592
593 xor_fn(&mut c1, &c2);
596 xor_fn(&mut p1, &p2);
597 assert_ne!(c1, p1);
598 }
599
600 #[test]
605 fn test_encrypt_filename() {
606 let raw_key_hex = "1fcdf30b7d191bd95d3161fe08513b864aa15f27f910f1c66eec8cfa93e9893b";
607 let raw_key_bytes: [u8; 32] =
608 hex::decode(raw_key_hex).expect("decode failed").try_into().unwrap();
609 let unwrapped_key = UnwrappedKey::new(raw_key_bytes);
610 let cipher_set = CipherSet::from(vec![Cipher::new(0, &unwrapped_key)]);
611 let key = Key { keys: std::sync::Arc::new(cipher_set), index: 0 };
612 let object_id = 2;
613 let mut text = "filename".to_string().as_bytes().to_vec();
614 key.encrypt_filename(object_id, &mut text).expect("encrypt filename failed");
615 assert_eq!(text, hex::decode("52d56369103a39b3ea1e09c85dd51546").expect("decode failed"));
616 }
617
618 #[test]
622 fn test_decrypt_filename() {
623 let raw_key_hex = "1fcdf30b7d191bd95d3161fe08513b864aa15f27f910f1c66eec8cfa93e9893b";
624 let raw_key_bytes: [u8; 32] =
625 hex::decode(raw_key_hex).expect("decode failed").try_into().unwrap();
626 let unwrapped_key = UnwrappedKey::new(raw_key_bytes);
627 let cipher_set = CipherSet::from(vec![Cipher::new(0, &unwrapped_key)]);
628 let key = Key { keys: std::sync::Arc::new(cipher_set), index: 0 };
629 let object_id = 2;
630 let mut text = hex::decode("52d56369103a39b3ea1e09c85dd51546").expect("decode failed");
631 key.decrypt_filename(object_id, &mut text).expect("encrypt filename failed");
632 assert_eq!(text, "filename".to_string().as_bytes().to_vec());
633 }
634}