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