1use aes_gcm_siv::aead::Aead;
6use aes_gcm_siv::{Aes256GcmSiv, Key, KeyInit as _, Nonce};
7use async_trait::async_trait;
8use fuchsia_sync::Mutex;
9use fxfs_crypto::{Crypt, KeyPurpose, UnwrappedKey, WrappedKey, WrappedKeyBytes};
10use log::error;
11use rand::rngs::StdRng;
12use rand::{RngCore, SeedableRng};
13use rustc_hash::FxHashMap as HashMap;
14use std::sync::atomic::{AtomicBool, Ordering};
15use zx_status as zx;
16
17pub const DATA_KEY: [u8; 32] = [
18 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf, 0x10, 0x11,
19 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
20];
21pub const METADATA_KEY: [u8; 32] = [
22 0xff, 0xfe, 0xfd, 0xfc, 0xfb, 0xfa, 0xf9, 0xf8, 0xf7, 0xf6, 0xf5, 0xf4, 0xf3, 0xf2, 0xf1, 0xf0,
23 0xef, 0xee, 0xed, 0xec, 0xeb, 0xea, 0xe9, 0xe8, 0xe7, 0xe6, 0xe5, 0xe4, 0xe3, 0xe2, 0xe1, 0xe0,
24];
25
26#[derive(Default)]
30pub struct InsecureCrypt {
31 ciphers: Mutex<HashMap<u128, Aes256GcmSiv>>,
32 active_data_key: Option<u128>,
33 active_metadata_key: Option<u128>,
34 shutdown: AtomicBool,
35}
36impl InsecureCrypt {
37 pub fn new() -> Self {
38 Self {
39 ciphers: Mutex::new(HashMap::from_iter([
40 (0, Aes256GcmSiv::new(Key::<Aes256GcmSiv>::from_slice(&DATA_KEY))),
41 (1, Aes256GcmSiv::new(Key::<Aes256GcmSiv>::from_slice(&METADATA_KEY))),
42 ])),
43 active_data_key: Some(0),
44 active_metadata_key: Some(1),
45 ..Default::default()
46 }
47 }
48
49 pub fn shutdown(&self) {
51 self.shutdown.store(true, Ordering::Relaxed);
52 }
53
54 pub fn add_wrapping_key(&self, id: u128, key: [u8; 32]) {
55 self.ciphers.lock().insert(id, Aes256GcmSiv::new(Key::<Aes256GcmSiv>::from_slice(&key)));
56 }
57
58 pub fn remove_wrapping_key(&self, id: u128) {
59 let _key = self.ciphers.lock().remove(&id);
60 }
61}
62
63#[async_trait]
64impl Crypt for InsecureCrypt {
65 async fn create_key(
66 &self,
67 owner: u64,
68 purpose: KeyPurpose,
69 ) -> Result<(WrappedKey, UnwrappedKey), zx::Status> {
70 if self.shutdown.load(Ordering::Relaxed) {
71 error!("Crypt was shut down");
72 return Err(zx::Status::INTERNAL);
73 }
74 let wrapping_key_id = match purpose {
75 KeyPurpose::Data => self.active_data_key.as_ref(),
76 KeyPurpose::Metadata => self.active_metadata_key.as_ref(),
77 }
78 .ok_or(zx::Status::INVALID_ARGS)?;
79 let ciphers = self.ciphers.lock();
80 let cipher = ciphers.get(wrapping_key_id).ok_or(zx::Status::NOT_FOUND)?;
81 let mut nonce = Nonce::default();
82 nonce.as_mut_slice()[..8].copy_from_slice(&owner.to_le_bytes());
83
84 let mut key = [0u8; 32];
85 StdRng::from_entropy().fill_bytes(&mut key);
86
87 let wrapped: Vec<u8> = cipher.encrypt(&nonce, &key[..]).map_err(|e| {
88 error!("Failed to wrap key: {:?}", e);
89 zx::Status::INTERNAL
90 })?;
91 let wrapped = WrappedKeyBytes::try_from(wrapped).map_err(|_| zx::Status::INTERNAL)?;
92 Ok((WrappedKey { wrapping_key_id: *wrapping_key_id, key: wrapped }, UnwrappedKey::new(key)))
93 }
94
95 async fn create_key_with_id(
96 &self,
97 owner: u64,
98 wrapping_key_id: u128,
99 ) -> Result<(WrappedKey, UnwrappedKey), zx::Status> {
100 if self.shutdown.load(Ordering::Relaxed) {
101 error!("Crypt was shut down");
102 return Err(zx::Status::INTERNAL);
103 }
104 let ciphers = self.ciphers.lock();
105 let cipher = ciphers.get(&(wrapping_key_id as u128)).ok_or(zx::Status::NOT_FOUND)?;
106 let mut nonce = Nonce::default();
107 nonce.as_mut_slice()[..8].copy_from_slice(&owner.to_le_bytes());
108
109 let mut key = [0u8; 32];
110 StdRng::from_entropy().fill_bytes(&mut key);
111
112 let wrapped: Vec<u8> = cipher.encrypt(&nonce, &key[..]).map_err(|e| {
113 error!("Failed to wrap key: {:?}", e);
114 zx::Status::INTERNAL
115 })?;
116 let wrapped = WrappedKeyBytes::try_from(wrapped).map_err(|_| zx::Status::BAD_STATE)?;
117 Ok((
118 WrappedKey { wrapping_key_id: wrapping_key_id as u128, key: wrapped },
119 UnwrappedKey::new(key),
120 ))
121 }
122 async fn unwrap_key(
123 &self,
124 wrapped_key: &WrappedKey,
125 owner: u64,
126 ) -> Result<UnwrappedKey, zx::Status> {
127 if self.shutdown.load(Ordering::Relaxed) {
128 error!("Crypt was shut down");
129 return Err(zx::Status::INTERNAL);
130 }
131 let ciphers = self.ciphers.lock();
132 let cipher = ciphers.get(&wrapped_key.wrapping_key_id).ok_or(zx::Status::NOT_FOUND)?;
133 let mut nonce = Nonce::default();
134 nonce.as_mut_slice()[..8].copy_from_slice(&owner.to_le_bytes());
135 Ok(UnwrappedKey::new(
136 cipher
137 .decrypt(&nonce, &wrapped_key.key.0[..])
138 .map_err(|e| {
139 error!("unwrap keys failed: {:?}", e);
140 zx::Status::INTERNAL
141 })?
142 .try_into()
143 .map_err(|_| {
144 error!("Unexpected wrapped key length");
145 zx::Status::INTERNAL
146 })?,
147 ))
148 }
149}