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 FxfsWrapped, KeyPurpose, WrappedKey,
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, owner: u64, wrapped_key: WrappedKey) -> CryptUnwrapKeyResult {
90 match wrapped_key {
91 WrappedKey::FxfsWrapped(FxfsWrapped { wrapping_key_id, wrapped_key }) => {
92 let wrapping_key_id = u128::from_le_bytes(wrapping_key_id);
93 let inner = self.inner.lock();
94 let cipher = inner
95 .ciphers
96 .get(&wrapping_key_id)
97 .ok_or_else(|| zx::Status::NOT_FOUND.into_raw())?;
98 let nonce = zero_extended_nonce(owner);
99
100 Ok(cipher
101 .decrypt(&nonce, &wrapped_key[..])
102 .map_err(|_| zx::Status::IO_DATA_INTEGRITY.into_raw())?)
103 }
104 _ => Err(zx::Status::NOT_SUPPORTED.into_raw()),
105 }
106 }
107
108 pub fn add_wrapping_key(
109 &self,
110 wrapping_key_id: u128,
111 key: Vec<u8>,
112 ) -> CryptManagementAddWrappingKeyResult {
113 let mut inner = self.inner.lock();
114 match inner.ciphers.entry(wrapping_key_id) {
115 Entry::Occupied(_) => Err(zx::Status::ALREADY_EXISTS.into_raw()),
116 Entry::Vacant(vacant) => {
117 info!(wrapping_key_id; "Adding wrapping key");
118 vacant.insert(Aes256GcmSiv::new(Key::<Aes256GcmSiv>::from_slice(&key[..])));
119 Ok(())
120 }
121 }
122 }
123
124 pub fn set_active_key(
125 &self,
126 purpose: KeyPurpose,
127 wrapping_key_id: u128,
128 ) -> CryptManagementSetActiveKeyResult {
129 let mut inner = self.inner.lock();
130 if !inner.ciphers.contains_key(&wrapping_key_id) {
131 return Err(zx::Status::NOT_FOUND.into_raw());
132 }
133 match purpose {
134 KeyPurpose::Data => inner.active_data_key = Some(wrapping_key_id),
135 KeyPurpose::Metadata => inner.active_metadata_key = Some(wrapping_key_id),
136 _ => return Err(zx::Status::INVALID_ARGS.into_raw()),
137 }
138 Ok(())
139 }
140
141 fn forget_wrapping_key(&self, wrapping_key_id: u128) -> CryptManagementForgetWrappingKeyResult {
142 info!(wrapping_key_id; "Removing wrapping key");
143 let mut inner = self.inner.lock();
144 if let Some(id) = &inner.active_data_key {
145 if *id == wrapping_key_id {
146 return Err(zx::Status::INVALID_ARGS.into_raw());
147 }
148 }
149 if let Some(id) = &inner.active_metadata_key {
150 if *id == wrapping_key_id {
151 return Err(zx::Status::INVALID_ARGS.into_raw());
152 }
153 }
154 inner.ciphers.remove(&wrapping_key_id);
155 Ok(())
156 }
157
158 pub async fn handle_request(&self, stream: Services) -> Result<(), Error> {
159 match stream {
160 Services::Crypt(mut stream) => {
161 while let Some(request) = stream.try_next().await.context("Reading request")? {
162 match request {
163 CryptRequest::CreateKey { owner, purpose, responder } => {
164 responder
165 .send(match &self.create_key(owner, purpose) {
166 Ok((id, ref wrapped, ref key)) => Ok((id, wrapped, key)),
167 Err(e) => Err(*e),
168 })
169 .unwrap_or_else(|e| {
170 error!(
173 error:? = e;
174 "Failed to send CreateKey response"
175 )
176 });
177 }
178 CryptRequest::CreateKeyWithId { owner, wrapping_key_id, responder } => {
179 responder
180 .send(
181 match self.create_key_with_id(
182 owner,
183 u128::from_le_bytes(wrapping_key_id),
184 ) {
185 Ok((ref wrapped, ref key)) => Ok((wrapped, key)),
186 Err(e) => Err(e),
187 },
188 )
189 .unwrap_or_else(|e| {
190 error!(
193 error:? = e;
194 "Failed to send CreateKeyWithId response"
195 )
196 });
197 }
198 CryptRequest::UnwrapKey { owner, wrapped_key, responder } => {
199 let response;
200 responder
201 .send({
202 response = self.unwrap_key(owner, wrapped_key);
203 match &response {
204 Ok(v) => Ok(&v[..]),
205 Err(e) => Err(*e),
206 }
207 })
208 .unwrap_or_else(|e| {
209 error!(
212 error:? = e;
213 "Failed to send UnwrapKey response"
214 )
215 });
216 }
217 }
218 }
219 }
220 Services::CryptManagement(mut stream) => {
221 while let Some(request) = stream.try_next().await.context("Reading request")? {
222 match request {
223 CryptManagementRequest::AddWrappingKey {
224 wrapping_key_id,
225 key,
226 responder,
227 } => {
228 let response =
229 self.add_wrapping_key(u128::from_le_bytes(wrapping_key_id), key);
230 responder.send(response).unwrap_or_else(|e| {
231 error!(
234 error:? = e;
235 "Failed to send AddWrappingKey response"
236 )
237 });
238 }
239 CryptManagementRequest::SetActiveKey {
240 purpose,
241 wrapping_key_id,
242 responder,
243 } => {
244 let response =
245 self.set_active_key(purpose, u128::from_le_bytes(wrapping_key_id));
246 responder.send(response).unwrap_or_else(
247 |e| error!(error:? = e;"Failed to send SetActiveKey response"),
250 );
251 }
252 CryptManagementRequest::ForgetWrappingKey {
253 wrapping_key_id,
254 responder,
255 } => {
256 let response =
257 self.forget_wrapping_key(u128::from_le_bytes(wrapping_key_id));
258 responder.send(response).unwrap_or_else(|e| {
259 error!(
262 error:? = e;
263 "Failed to send ForgetWrappingKey response"
264 )
265 });
266 }
267 }
268 }
269 }
270 }
271 Ok(())
272 }
273}
274
275#[cfg(test)]
276mod tests {
277 use super::CryptService;
278 use fidl_fuchsia_fxfs::{FxfsWrapped, KeyPurpose, WrappedKey};
279
280 #[test]
281 fn wrap_unwrap_key() {
282 let service = CryptService::new();
283 let key = vec![0xABu8; 32];
284 service.add_wrapping_key(1, key.clone()).expect("add_key failed");
285 service.set_active_key(KeyPurpose::Data, 1).expect("set_active_key failed");
286
287 let (wrapping_key_id, wrapped_key, unwrapped_key) =
288 service.create_key(0, KeyPurpose::Data).expect("create_key failed");
289 let wrapping_key_id_int = u128::from_le_bytes(wrapping_key_id);
290 assert_eq!(wrapping_key_id_int, 1);
291 let unwrap_result = service
292 .unwrap_key(
293 0,
294 WrappedKey::FxfsWrapped(FxfsWrapped {
295 wrapping_key_id,
296 wrapped_key: wrapped_key.try_into().unwrap(),
297 }),
298 )
299 .expect("unwrap_key failed");
300 assert_eq!(unwrap_result, unwrapped_key);
301
302 let (wrapping_key_id, wrapped_key, unwrapped_key) =
304 service.create_key(1, KeyPurpose::Data).expect("create_key failed");
305 let wrapping_key_id_int = u128::from_le_bytes(wrapping_key_id);
306 assert_eq!(wrapping_key_id_int, 1);
307 let unwrap_result = service
308 .unwrap_key(
309 1,
310 WrappedKey::FxfsWrapped(FxfsWrapped {
311 wrapping_key_id,
312 wrapped_key: wrapped_key.try_into().unwrap(),
313 }),
314 )
315 .expect("unwrap_key failed");
316 assert_eq!(unwrap_result, unwrapped_key);
317 }
318
319 #[test]
320 fn wrap_unwrap_key_with_arbitrary_wrapping_key() {
321 let service = CryptService::new();
322 let key = vec![0xABu8; 32];
323 service.add_wrapping_key(2, key.clone()).expect("add_key failed");
324
325 let (wrapped_key, unwrapped_key) =
326 service.create_key_with_id(0, 2).expect("create_key_with_id failed");
327 let unwrap_result = service
328 .unwrap_key(
329 0,
330 WrappedKey::FxfsWrapped(FxfsWrapped {
331 wrapping_key_id: 2u128.to_le_bytes(),
332 wrapped_key: wrapped_key.try_into().unwrap(),
333 }),
334 )
335 .expect("unwrap_key failed");
336 assert_eq!(unwrap_result, unwrapped_key);
337
338 let (wrapped_key, unwrapped_key) =
340 service.create_key_with_id(1, 2).expect("create_key_with_id failed");
341 let unwrap_result = service
342 .unwrap_key(
343 1,
344 WrappedKey::FxfsWrapped(FxfsWrapped {
345 wrapping_key_id: 2u128.to_le_bytes(),
346 wrapped_key: wrapped_key.try_into().unwrap(),
347 }),
348 )
349 .expect("unwrap_key failed");
350 assert_eq!(unwrap_result, unwrapped_key);
351 }
352
353 #[test]
354 fn create_key_with_wrapping_key_that_does_not_exist() {
355 let service = CryptService::new();
356 service
357 .create_key_with_id(0, 2)
358 .expect_err("create_key_with_id should fail if the wrapping key does not exist");
359
360 let wrapping_key = vec![0xABu8; 32];
361 service.add_wrapping_key(2, wrapping_key.clone()).expect("add_key failed");
362
363 let (wrapped_key, unwrapped_key) =
364 service.create_key_with_id(0, 2).expect("create_key_with_id failed");
365 let unwrap_result = service
366 .unwrap_key(
367 0,
368 WrappedKey::FxfsWrapped(FxfsWrapped {
369 wrapping_key_id: 2u128.to_le_bytes(),
370 wrapped_key: wrapped_key.try_into().unwrap(),
371 }),
372 )
373 .expect("unwrap_key failed");
374 assert_eq!(unwrap_result, unwrapped_key);
375 }
376
377 #[test]
378 fn unwrap_key_wrong_key() {
379 let service = CryptService::new();
380 let key = vec![0xABu8; 32];
381 service.add_wrapping_key(0, key.clone()).expect("add_key failed");
382 service.set_active_key(KeyPurpose::Data, 0).expect("set_active_key failed");
383
384 let (wrapping_key_id, mut wrapped_key, _) =
385 service.create_key(0, KeyPurpose::Data).expect("create_key failed");
386 for byte in &mut wrapped_key {
387 *byte ^= 0xff;
388 }
389 service
390 .unwrap_key(
391 0,
392 WrappedKey::FxfsWrapped(FxfsWrapped {
393 wrapping_key_id,
394 wrapped_key: wrapped_key.try_into().unwrap(),
395 }),
396 )
397 .expect_err("unwrap_key should fail");
398 }
399
400 #[test]
401 fn unwrap_key_wrong_owner() {
402 let service = CryptService::new();
403 let key = vec![0xABu8; 32];
404 service.add_wrapping_key(0, key.clone()).expect("add_key failed");
405 service.set_active_key(KeyPurpose::Data, 0).expect("set_active_key failed");
406
407 let (wrapping_key_id, wrapped_key, _) =
408 service.create_key(0, KeyPurpose::Data).expect("create_key failed");
409 service
410 .unwrap_key(
411 1,
412 WrappedKey::FxfsWrapped(FxfsWrapped {
413 wrapping_key_id,
414 wrapped_key: wrapped_key.try_into().unwrap(),
415 }),
416 )
417 .expect_err("unwrap_key should fail");
418 }
419
420 #[test]
421 fn add_forget_key() {
422 let service = CryptService::new();
423 let key = vec![0xABu8; 32];
424 service.add_wrapping_key(0, key.clone()).expect("add_key failed");
425 service.add_wrapping_key(0, key.clone()).expect_err("add_key should fail on a used slot");
426 service.add_wrapping_key(1, key.clone()).expect("add_key failed");
427
428 service.forget_wrapping_key(0).expect("forget_key failed");
429
430 service.add_wrapping_key(0, key.clone()).expect("add_key failed");
431 }
432
433 #[test]
434 fn set_active_key() {
435 let service = CryptService::new();
436 let key = vec![0xABu8; 32];
437
438 service
439 .set_active_key(KeyPurpose::Data, 0)
440 .expect_err("set_active_key should fail when targeting nonexistent keys");
441
442 service.add_wrapping_key(0, key.clone()).expect("add_key failed");
443 service.add_wrapping_key(1, key.clone()).expect("add_key failed");
444
445 service.set_active_key(KeyPurpose::Data, 0).expect("set_active_key failed");
446 service.set_active_key(KeyPurpose::Metadata, 1).expect("set_active_key failed");
447
448 service.forget_wrapping_key(0).expect_err("forget_key should fail on an active key");
449 service.forget_wrapping_key(1).expect_err("forget_key should fail on an active key");
450 }
451}