1use aes_gcm_siv::aead::Aead;
6use aes_gcm_siv::{Aes256GcmSiv, Key, KeyInit as _, Nonce};
7use anyhow::{Context, Error};
8use fidl_fuchsia_fxfs::{
9 CryptCreateKeyResult, CryptCreateKeyWithIdResult, CryptManagementAddWrappingKeyResult,
10 CryptManagementForgetWrappingKeyResult, CryptManagementRequest, CryptManagementRequestStream,
11 CryptManagementSetActiveKeyResult, CryptRequest, CryptRequestStream, CryptUnwrapKeyResult,
12 KeyPurpose,
13};
14
15use fuchsia_sync::Mutex;
16use futures::stream::TryStreamExt;
17use std::collections::hash_map::{Entry, HashMap};
18
19pub mod log;
20use log::*;
21
22pub enum Services {
23 Crypt(CryptRequestStream),
24 CryptManagement(CryptManagementRequestStream),
25}
26
27#[derive(Default)]
28struct CryptServiceInner {
29 ciphers: HashMap<u128, Aes256GcmSiv>,
30 active_data_key: Option<u128>,
31 active_metadata_key: Option<u128>,
32}
33
34pub struct CryptService {
35 inner: Mutex<CryptServiceInner>,
36}
37
38fn zero_extended_nonce(val: u64) -> Nonce {
39 let mut nonce = Nonce::default();
40 nonce.as_mut_slice()[..8].copy_from_slice(&val.to_le_bytes());
41 nonce
42}
43
44impl CryptService {
45 pub fn new() -> Self {
46 Self { inner: Mutex::new(CryptServiceInner::default()) }
47 }
48
49 fn create_key(&self, owner: u64, purpose: KeyPurpose) -> CryptCreateKeyResult {
50 let inner = self.inner.lock();
51 let wrapping_key_id = match purpose {
52 KeyPurpose::Data => inner.active_data_key.as_ref(),
53 KeyPurpose::Metadata => inner.active_metadata_key.as_ref(),
54 _ => return Err(zx::Status::INVALID_ARGS.into_raw()),
55 }
56 .ok_or_else(|| zx::Status::BAD_STATE.into_raw())?;
57 let cipher =
58 inner.ciphers.get(wrapping_key_id).ok_or_else(|| zx::Status::BAD_STATE.into_raw())?;
59 let nonce = zero_extended_nonce(owner);
60
61 let mut key = [0u8; 32];
62 zx::cprng_draw(&mut key);
63
64 let wrapped = cipher.encrypt(&nonce, &key[..]).map_err(|e| {
65 error!(error:? = e; "Failed to wrap key");
66 zx::Status::INTERNAL.into_raw()
67 })?;
68
69 Ok((wrapping_key_id.to_le_bytes(), wrapped.into(), key.into()))
70 }
71
72 fn create_key_with_id(&self, owner: u64, wrapping_key_id: u128) -> CryptCreateKeyWithIdResult {
73 let inner = self.inner.lock();
74 let cipher =
75 inner.ciphers.get(&wrapping_key_id).ok_or_else(|| zx::Status::NOT_FOUND.into_raw())?;
76 let nonce = zero_extended_nonce(owner);
77
78 let mut key = [0u8; 32];
79 zx::cprng_draw(&mut key);
80
81 let wrapped = cipher.encrypt(&nonce, &key[..]).map_err(|error| {
82 error!(error:?; "Failed to wrap key");
83 zx::Status::INTERNAL.into_raw()
84 })?;
85
86 Ok((wrapped.into(), key.into()))
87 }
88
89 fn unwrap_key(&self, wrapping_key_id: u128, owner: u64, key: Vec<u8>) -> CryptUnwrapKeyResult {
90 let inner = self.inner.lock();
91 let cipher =
92 inner.ciphers.get(&wrapping_key_id).ok_or_else(|| zx::Status::NOT_FOUND.into_raw())?;
93 let nonce = zero_extended_nonce(owner);
94
95 cipher.decrypt(&nonce, &key[..]).map_err(|_| zx::Status::IO_DATA_INTEGRITY.into_raw())
96 }
97
98 pub fn add_wrapping_key(
99 &self,
100 wrapping_key_id: u128,
101 key: Vec<u8>,
102 ) -> CryptManagementAddWrappingKeyResult {
103 let mut inner = self.inner.lock();
104 match inner.ciphers.entry(wrapping_key_id) {
105 Entry::Occupied(_) => Err(zx::Status::ALREADY_EXISTS.into_raw()),
106 Entry::Vacant(vacant) => {
107 info!(wrapping_key_id; "Adding wrapping key");
108 vacant.insert(Aes256GcmSiv::new(Key::<Aes256GcmSiv>::from_slice(&key[..])));
109 Ok(())
110 }
111 }
112 }
113
114 pub fn set_active_key(
115 &self,
116 purpose: KeyPurpose,
117 wrapping_key_id: u128,
118 ) -> CryptManagementSetActiveKeyResult {
119 let mut inner = self.inner.lock();
120 if !inner.ciphers.contains_key(&wrapping_key_id) {
121 return Err(zx::Status::NOT_FOUND.into_raw());
122 }
123 match purpose {
124 KeyPurpose::Data => inner.active_data_key = Some(wrapping_key_id),
125 KeyPurpose::Metadata => inner.active_metadata_key = Some(wrapping_key_id),
126 _ => return Err(zx::Status::INVALID_ARGS.into_raw()),
127 }
128 Ok(())
129 }
130
131 fn forget_wrapping_key(&self, wrapping_key_id: u128) -> CryptManagementForgetWrappingKeyResult {
132 info!(wrapping_key_id; "Removing wrapping key");
133 let mut inner = self.inner.lock();
134 if let Some(id) = &inner.active_data_key {
135 if *id == wrapping_key_id {
136 return Err(zx::Status::INVALID_ARGS.into_raw());
137 }
138 }
139 if let Some(id) = &inner.active_metadata_key {
140 if *id == wrapping_key_id {
141 return Err(zx::Status::INVALID_ARGS.into_raw());
142 }
143 }
144 inner.ciphers.remove(&wrapping_key_id);
145 Ok(())
146 }
147
148 pub async fn handle_request(&self, stream: Services) -> Result<(), Error> {
149 match stream {
150 Services::Crypt(mut stream) => {
151 while let Some(request) = stream.try_next().await.context("Reading request")? {
152 match request {
153 CryptRequest::CreateKey { owner, purpose, responder } => {
154 responder
155 .send(match &self.create_key(owner, purpose) {
156 Ok((id, ref wrapped, ref key)) => Ok((id, wrapped, key)),
157 Err(e) => Err(*e),
158 })
159 .unwrap_or_else(|e| {
160 error!(
163 error:? = e;
164 "Failed to send CreateKey response"
165 )
166 });
167 }
168 CryptRequest::CreateKeyWithId { owner, wrapping_key_id, responder } => {
169 responder
170 .send(
171 match self.create_key_with_id(
172 owner,
173 u128::from_le_bytes(wrapping_key_id),
174 ) {
175 Ok((ref wrapped, ref key)) => Ok((wrapped, key)),
176 Err(e) => Err(e),
177 },
178 )
179 .unwrap_or_else(|e| {
180 error!(
183 error:? = e;
184 "Failed to send CreateKeyWithId response"
185 )
186 });
187 }
188 CryptRequest::UnwrapKey { wrapping_key_id, owner, key, responder } => {
189 responder
190 .send(
191 match self.unwrap_key(
192 u128::from_le_bytes(wrapping_key_id),
193 owner,
194 key,
195 ) {
196 Ok(ref unwrapped) => Ok(unwrapped),
197 Err(e) => Err(e),
198 },
199 )
200 .unwrap_or_else(|e| {
201 error!(
204 error:? = e;
205 "Failed to send UnwrapKey response"
206 )
207 });
208 }
209 }
210 }
211 }
212 Services::CryptManagement(mut stream) => {
213 while let Some(request) = stream.try_next().await.context("Reading request")? {
214 match request {
215 CryptManagementRequest::AddWrappingKey {
216 wrapping_key_id,
217 key,
218 responder,
219 } => {
220 let response =
221 self.add_wrapping_key(u128::from_le_bytes(wrapping_key_id), key);
222 responder.send(response).unwrap_or_else(|e| {
223 error!(
226 error:? = e;
227 "Failed to send AddWrappingKey response"
228 )
229 });
230 }
231 CryptManagementRequest::SetActiveKey {
232 purpose,
233 wrapping_key_id,
234 responder,
235 } => {
236 let response =
237 self.set_active_key(purpose, u128::from_le_bytes(wrapping_key_id));
238 responder.send(response).unwrap_or_else(
239 |e| error!(error:? = e;"Failed to send SetActiveKey response"),
242 );
243 }
244 CryptManagementRequest::ForgetWrappingKey {
245 wrapping_key_id,
246 responder,
247 } => {
248 let response =
249 self.forget_wrapping_key(u128::from_le_bytes(wrapping_key_id));
250 responder.send(response).unwrap_or_else(|e| {
251 error!(
254 error:? = e;
255 "Failed to send ForgetWrappingKey response"
256 )
257 });
258 }
259 }
260 }
261 }
262 }
263 Ok(())
264 }
265}
266
267#[cfg(test)]
268mod tests {
269 use super::CryptService;
270 use fidl_fuchsia_fxfs::KeyPurpose;
271
272 #[test]
273 fn wrap_unwrap_key() {
274 let service = CryptService::new();
275 let key = vec![0xABu8; 32];
276 service.add_wrapping_key(1, key.clone()).expect("add_key failed");
277 service.set_active_key(KeyPurpose::Data, 1).expect("set_active_key failed");
278
279 let (wrapping_key_id, wrapped, unwrapped) =
280 service.create_key(0, KeyPurpose::Data).expect("create_key failed");
281 let wrapping_key_id_int = u128::from_le_bytes(wrapping_key_id);
282 assert_eq!(wrapping_key_id_int, 1);
283 let unwrap_result =
284 service.unwrap_key(wrapping_key_id_int, 0, wrapped).expect("unwrap_key failed");
285 assert_eq!(unwrap_result, unwrapped);
286
287 let (wrapping_key_id, wrapped, unwrapped) =
289 service.create_key(1, KeyPurpose::Data).expect("create_key failed");
290 let wrapping_key_id_int = u128::from_le_bytes(wrapping_key_id);
291 assert_eq!(wrapping_key_id_int, 1);
292 let unwrap_result =
293 service.unwrap_key(wrapping_key_id_int, 1, wrapped).expect("unwrap_key failed");
294 assert_eq!(unwrap_result, unwrapped);
295 }
296
297 #[test]
298 fn wrap_unwrap_key_with_arbitrary_wrapping_key() {
299 let service = CryptService::new();
300 let key = vec![0xABu8; 32];
301 service.add_wrapping_key(2, key.clone()).expect("add_key failed");
302
303 let (wrapped, unwrapped) =
304 service.create_key_with_id(0, 2).expect("create_key_with_id failed");
305 let unwrap_result = service.unwrap_key(2, 0, wrapped).expect("unwrap_key failed");
306 assert_eq!(unwrap_result, unwrapped);
307
308 let (wrapped, unwrapped) =
310 service.create_key_with_id(1, 2).expect("create_key_with_id failed");
311 let unwrap_result = service.unwrap_key(2, 1, wrapped).expect("unwrap_key failed");
312 assert_eq!(unwrap_result, unwrapped);
313 }
314
315 #[test]
316 fn create_key_with_wrapping_key_that_does_not_exist() {
317 let service = CryptService::new();
318 service
319 .create_key_with_id(0, 2)
320 .expect_err("create_key_with_id should fail if the wrapping key does not exist");
321
322 let wrapping_key = vec![0xABu8; 32];
323 service.add_wrapping_key(2, wrapping_key.clone()).expect("add_key failed");
324
325 let (wrapped, unwrapped) =
326 service.create_key_with_id(0, 2).expect("create_key_with_id failed");
327 let unwrap_result = service.unwrap_key(2, 0, wrapped).expect("unwrap_key failed");
328 assert_eq!(unwrap_result, unwrapped);
329 }
330
331 #[test]
332 fn unwrap_key_wrong_key() {
333 let service = CryptService::new();
334 let key = vec![0xABu8; 32];
335 service.add_wrapping_key(0, key.clone()).expect("add_key failed");
336 service.set_active_key(KeyPurpose::Data, 0).expect("set_active_key failed");
337
338 let (wrapping_key_id, mut wrapped, _) =
339 service.create_key(0, KeyPurpose::Data).expect("create_key failed");
340 for byte in &mut wrapped {
341 *byte ^= 0xff;
342 }
343 service
344 .unwrap_key(u128::from_le_bytes(wrapping_key_id), 0, wrapped)
345 .expect_err("unwrap_key should fail");
346 }
347
348 #[test]
349 fn unwrap_key_wrong_owner() {
350 let service = CryptService::new();
351 let key = vec![0xABu8; 32];
352 service.add_wrapping_key(0, key.clone()).expect("add_key failed");
353 service.set_active_key(KeyPurpose::Data, 0).expect("set_active_key failed");
354
355 let (wrapping_key_id, wrapped, _) =
356 service.create_key(0, KeyPurpose::Data).expect("create_key failed");
357 service
358 .unwrap_key(u128::from_le_bytes(wrapping_key_id), 1, wrapped)
359 .expect_err("unwrap_key should fail");
360 }
361
362 #[test]
363 fn add_forget_key() {
364 let service = CryptService::new();
365 let key = vec![0xABu8; 32];
366 service.add_wrapping_key(0, key.clone()).expect("add_key failed");
367 service.add_wrapping_key(0, key.clone()).expect_err("add_key should fail on a used slot");
368 service.add_wrapping_key(1, key.clone()).expect("add_key failed");
369
370 service.forget_wrapping_key(0).expect("forget_key failed");
371
372 service.add_wrapping_key(0, key.clone()).expect("add_key failed");
373 }
374
375 #[test]
376 fn set_active_key() {
377 let service = CryptService::new();
378 let key = vec![0xABu8; 32];
379
380 service
381 .set_active_key(KeyPurpose::Data, 0)
382 .expect_err("set_active_key should fail when targeting nonexistent keys");
383
384 service.add_wrapping_key(0, key.clone()).expect("add_key failed");
385 service.add_wrapping_key(1, key.clone()).expect("add_key failed");
386
387 service.set_active_key(KeyPurpose::Data, 0).expect("set_active_key failed");
388 service.set_active_key(KeyPurpose::Metadata, 1).expect("set_active_key failed");
389
390 service.forget_wrapping_key(0).expect_err("forget_key should fail on an active key");
391 service.forget_wrapping_key(1).expect_err("forget_key should fail on an active key");
392 }
393}