1use aes_gcm_siv::aead::Aead as _;
11use aes_gcm_siv::{Aes128GcmSiv, Key, KeyInit as _, Nonce};
12use fidl::endpoints::{ClientEnd, create_request_stream};
13use fidl_fuchsia_security_keymint::{
14 AdminMarker, AdminRequest, AdminRequestStream, DeleteError, SealError, SealingKeysMarker,
15 SealingKeysRequest, SealingKeysRequestStream, UnsealError, UpgradeError,
16};
17use fuchsia_sync::Mutex;
18use futures::{FutureExt as _, TryStreamExt as _};
19use log::warn;
20use std::collections::BTreeMap;
21use std::future::Future;
22use std::pin::pin;
23
24use futures::future::BoxFuture;
25use std::sync::Arc;
26
27type KeyInfo = Vec<u8>;
28
29struct SealingKey {
34 cipher: Aes128GcmSiv,
35 key_blobs: Vec<Vec<u8>>,
39}
40
41type DeleteHook = Arc<dyn Fn(Vec<u8>) -> BoxFuture<'static, Option<DeleteError>> + Send + Sync>;
42
43#[derive(Default)]
44struct Inner {
45 sealing_keys: BTreeMap<KeyInfo, SealingKey>,
46 epoch: u64,
49
50 delete_hook: Option<DeleteHook>,
56}
57
58fn blob_for_key(key_info: &KeyInfo, epoch: u64) -> Vec<u8> {
60 format!("bL0b_F0r_t3$t_{}|{epoch}", String::from_utf8_lossy(key_info)).into_bytes().to_vec()
61}
62
63fn epoch_from_blob(blob: &[u8]) -> Option<u64> {
65 let blob_str = String::from_utf8_lossy(blob);
66 blob_str.split('|').last().and_then(|s| s.parse().ok())
67}
68
69impl Inner {
70 const IV: [u8; 12] = [0u8; 12];
71
72 fn derive_key(key_info: &KeyInfo, epoch: u64) -> SealingKey {
77 let mut key_bytes = [0u8; 16];
78 let len = key_info.len().min(16);
79 key_bytes[..len].copy_from_slice(&key_info[..len]);
80
81 let cipher = Aes128GcmSiv::new(Key::<Aes128GcmSiv>::from_slice(&key_bytes));
84 let key_blobs = vec![blob_for_key(key_info, epoch)];
85 SealingKey { cipher, key_blobs }
86 }
87
88 fn handle_create_request(&mut self, key_info: KeyInfo) -> Vec<u8> {
89 let epoch = self.epoch;
90 let sealing_key = self
91 .sealing_keys
92 .entry(key_info.clone())
93 .or_insert_with(|| Self::derive_key(&key_info, epoch));
94 if !sealing_key.key_blobs.iter().any(|b| epoch_from_blob(b) == Some(epoch)) {
95 sealing_key.key_blobs.push(blob_for_key(&key_info, epoch));
96 }
97 sealing_key.key_blobs.iter().find(|b| epoch_from_blob(b) == Some(epoch)).unwrap().clone()
98 }
99
100 fn handle_seal_request(
105 &mut self,
106 key_info: KeyInfo,
107 key_blob: Vec<u8>,
108 secret: Vec<u8>,
109 ) -> Result<Vec<u8>, SealError> {
110 let sealing_key = self.sealing_keys.get(&key_info).ok_or_else(|| SealError::FailedSeal)?;
111 if !sealing_key.key_blobs.contains(&key_blob) {
112 warn!("Wrong key blob");
113 return Err(SealError::FailedSeal);
114 }
115 let epoch = epoch_from_blob(&key_blob).ok_or_else(|| {
116 warn!("Invalid key blob");
117 SealError::FailedSeal
118 })?;
119 if epoch < self.epoch {
120 warn!("Key requires upgrade");
121 return Err(SealError::KeyRequiresUpgrade);
122 }
123 let sealed_secret = sealing_key
124 .cipher
125 .encrypt(&Nonce::from_slice(&Self::IV), &secret[..])
126 .map_err(|e| {
127 warn!("Failed to seal secret: {}", e);
128 SealError::FailedSeal
129 })?;
130 Ok(sealed_secret)
131 }
132
133 fn handle_unseal_request(
138 &mut self,
139 key_info: KeyInfo,
140 key_blob: Vec<u8>,
141 sealed_secret: Vec<u8>,
142 ) -> Result<Vec<u8>, UnsealError> {
143 let sealing_key = self
144 .sealing_keys
145 .entry(key_info.clone())
146 .or_insert_with(|| Self::derive_key(&key_info, self.epoch));
147 if !sealing_key.key_blobs.contains(&key_blob) {
148 warn!("Unknown keyblob");
149 return Err(UnsealError::FailedUnseal);
150 }
151 let epoch = epoch_from_blob(&key_blob).ok_or_else(|| {
152 warn!("Invalid key blob");
153 UnsealError::FailedUnseal
154 })?;
155 if epoch < self.epoch {
156 warn!("Key requires upgrade");
157 return Err(UnsealError::KeyRequiresUpgrade);
158 }
159 let secret = sealing_key
160 .cipher
161 .decrypt(&Nonce::from_slice(&Self::IV), &sealed_secret[..])
162 .map_err(|e| {
163 warn!("Failed to unseal secret: {}", e);
164 UnsealError::FailedUnseal
165 })?;
166 Ok(secret)
167 }
168
169 fn handle_delete_all_keys_request(&mut self) {
170 self.sealing_keys.clear();
171 self.epoch += 1;
172 }
173
174 fn bump_epoch(&mut self) {
176 self.epoch += 1;
177 }
178
179 fn handle_upgrade_request(
185 &mut self,
186 key_info: KeyInfo,
187 key_blob: Vec<u8>,
188 ) -> Result<Vec<u8>, UpgradeError> {
189 let epoch = self.epoch;
190 let sealing_key = self
191 .sealing_keys
192 .entry(key_info.clone())
193 .or_insert_with(|| Self::derive_key(&key_info, epoch));
194 if !sealing_key.key_blobs.contains(&key_blob) {
195 warn!("Wrong key blob for upgrade");
196 return Err(UpgradeError::FailedUpgrade);
197 }
198 let upgraded = blob_for_key(&key_info, self.epoch);
199 if !sealing_key.key_blobs.contains(&upgraded) {
200 sealing_key.key_blobs.push(upgraded.clone());
201 }
202 Ok(upgraded)
203 }
204
205 fn handle_delete_request(&mut self, key_blob: &[u8]) -> Result<(), DeleteError> {
211 let mut removed = false;
212 self.sealing_keys.retain(|_, sealing_key| {
213 let initial_len = sealing_key.key_blobs.len();
214 sealing_key.key_blobs.retain(|kb| kb != key_blob);
215 if sealing_key.key_blobs.len() < initial_len {
216 removed = true;
217 }
218 !sealing_key.key_blobs.is_empty()
219 });
220
221 if removed { Ok(()) } else { Err(DeleteError::FailedDelete) }
222 }
223
224 fn has_key_blob(&self, key_blob: &[u8]) -> bool {
225 self.sealing_keys.values().any(|sk| sk.key_blobs.iter().any(|b| b == key_blob))
226 }
227}
228
229#[derive(Default, Clone)]
230pub struct FakeKeymint {
231 inner: Arc<Mutex<Inner>>,
232}
233
234impl FakeKeymint {
235 pub fn set_delete_hook<F>(&self, hook: F)
237 where
238 F: Fn(Vec<u8>) -> BoxFuture<'static, Option<DeleteError>> + Send + Sync + 'static,
239 {
240 self.inner.lock().delete_hook = Some(Arc::new(hook));
241 }
242
243 pub fn has_key_blob(&self, key_blob: &[u8]) -> bool {
245 self.inner.lock().has_key_blob(key_blob)
246 }
247
248 pub fn bump_epoch(&self) {
250 self.inner.lock().bump_epoch();
251 }
252
253 pub fn insert_sealing_key(&self, key_info: &[u8], blobs: Vec<Vec<u8>>) {
256 let mut inner = self.inner.lock();
257 if let Some(existing) = inner.sealing_keys.get_mut(key_info) {
258 for blob in blobs {
259 if !existing.key_blobs.contains(&blob) {
260 existing.key_blobs.push(blob);
261 }
262 }
263 } else {
264 inner.sealing_keys.insert(
265 key_info.to_vec(),
266 SealingKey {
267 cipher: Inner::derive_key(&key_info.to_vec(), 0).cipher,
268 key_blobs: blobs,
269 },
270 );
271 }
272 }
273
274 pub fn generate_static_sealing_key(&self, key_info: &[u8]) -> Vec<u8> {
276 self.inner.lock().handle_create_request(key_info.to_vec()).to_vec()
277 }
278
279 pub fn generate_static_sealed_data(
281 &self,
282 key_info: &[u8],
283 key_blob: &[u8],
284 secret: &[u8],
285 ) -> Vec<u8> {
286 self.inner
287 .lock()
288 .handle_seal_request(key_info.to_vec(), key_blob.to_vec(), secret.to_vec())
289 .expect("Failed static seal request")
290 .to_vec()
291 }
292
293 pub async fn run_sealing_keys_service(
295 &self,
296 stream: SealingKeysRequestStream,
297 ) -> Result<(), fidl::Error> {
298 stream
299 .try_for_each_concurrent(None, move |request| async move {
300 match request {
301 SealingKeysRequest::CreateSealingKey { key_info, responder } => {
302 responder.send(Ok(&*self.inner.lock().handle_create_request(key_info)))?;
303 }
304 SealingKeysRequest::Seal { key_info, key_blob, secret, responder } => {
305 match self.inner.lock().handle_seal_request(key_info, key_blob, secret) {
306 Ok(sealed_secret) => responder.send(Ok(&*sealed_secret))?,
307 Err(err) => responder.send(Err(err))?,
308 }
309 }
310 SealingKeysRequest::Unseal { key_info, key_blob, sealed_secret, responder } => {
311 match self.inner.lock().handle_unseal_request(
312 key_info,
313 key_blob,
314 sealed_secret,
315 ) {
316 Ok(secret) => responder.send(Ok(&*secret))?,
317 Err(err) => responder.send(Err(err))?,
318 }
319 }
320 SealingKeysRequest::UpgradeSealingKey { key_info, key_blob, responder } => {
321 match self.inner.lock().handle_upgrade_request(key_info, key_blob) {
322 Ok(key) => responder.send(Ok(&*key))?,
323 Err(err) => responder.send(Err(err))?,
324 }
325 }
326 SealingKeysRequest::DeleteSealingKey { key_blob, responder } => {
327 let hook = self.inner.lock().delete_hook.clone();
328 let hook_result =
329 if let Some(hook) = hook { hook(key_blob.clone()).await } else { None };
330
331 if let Some(err) = hook_result {
332 responder.send(Err(err))?;
333 } else {
334 let result = self.inner.lock().handle_delete_request(&key_blob);
335 match result {
336 Ok(()) => responder.send(Ok(()))?,
337 Err(e) => responder.send(Err(e))?,
338 }
339 }
340 }
341 }
342 Ok(())
343 })
344 .await
345 }
346
347 pub async fn run_admin_service(&self, stream: AdminRequestStream) -> Result<(), fidl::Error> {
349 stream
350 .try_for_each_concurrent(None, move |request| async move {
351 match request {
352 AdminRequest::DeleteAllKeys { responder } => {
353 responder.send(Ok(self.inner.lock().handle_delete_all_keys_request()))?;
354 }
355 }
356 Ok(())
357 })
358 .await
359 }
360}
361
362pub async fn with_keymint_service<R, Fut: Future<Output = anyhow::Result<R>>>(
365 f: impl FnOnce(ClientEnd<SealingKeysMarker>, ClientEnd<AdminMarker>) -> Fut,
366) -> anyhow::Result<R> {
367 let (sealing_keys_client, sealing_keys_stream) = create_request_stream::<SealingKeysMarker>();
368 let (admin_client, admin_stream) = create_request_stream::<AdminMarker>();
369 let fake_keymint = FakeKeymint::default();
370 let mut sealing_keys_service =
371 pin!(async { fake_keymint.run_sealing_keys_service(sealing_keys_stream).await }.fuse());
372 let mut admin_service =
373 pin!(async { fake_keymint.run_admin_service(admin_stream).await }.fuse());
374 let mut fut = pin!(f(sealing_keys_client, admin_client).fuse());
375
376 loop {
377 futures::select! {
378 _ = sealing_keys_service => {}
379 _ = admin_service => {}
380 result = fut => return result,
381 }
382 }
383}
384
385#[cfg(test)]
386mod tests {
387 use super::*;
388
389 #[fuchsia::test]
390 async fn create_seal_unseal() {
391 with_keymint_service(|keymint, _| async {
392 let keymint = keymint.into_proxy();
393 const KEY_INFO: [u8; 16] = [1u8; 16];
394 let key_blob = keymint
395 .create_sealing_key(&KEY_INFO[..])
396 .await
397 .expect("FIDL error")
398 .expect("create error");
399 const SECRET: [u8; 16] = [0xffu8; 16];
400 let sealed = keymint
401 .seal(&KEY_INFO[..], &key_blob[..], &SECRET[..])
402 .await
403 .expect("FIDL error")
404 .expect("seal error");
405 assert_ne!(sealed, SECRET);
406 let unsealed = keymint
407 .unseal(&KEY_INFO[..], &key_blob[..], &sealed[..])
408 .await
409 .expect("FIDL error")
410 .expect("unseal error");
411 assert_eq!(unsealed, SECRET);
412 Ok(())
413 })
414 .await
415 .unwrap();
416 }
417
418 #[fuchsia::test]
419 async fn seal_failure_on_wrong_key_info() {
420 with_keymint_service(|keymint, _| async {
421 let keymint = keymint.into_proxy();
422 const KEY_INFO: [u8; 16] = [1u8; 16];
423 let key_blob = keymint
424 .create_sealing_key(&KEY_INFO[..])
425 .await
426 .expect("FIDL error")
427 .expect("create error");
428 const SECRET: [u8; 16] = [0xffu8; 16];
429 keymint
430 .seal(&[2u8; 16], &key_blob[..], &SECRET[..])
431 .await
432 .expect("FIDL error")
433 .expect_err("seal should fail");
434 Ok(())
435 })
436 .await
437 .unwrap();
438 }
439
440 #[fuchsia::test]
441 async fn unseal_failure_on_wrong_sealing_key() {
442 with_keymint_service(|keymint, _| async {
443 let keymint = keymint.into_proxy();
444 const KEY_INFO: [u8; 16] = [1u8; 16];
445 let key_blob = keymint
446 .create_sealing_key(&KEY_INFO[..])
447 .await
448 .expect("FIDL error")
449 .expect("create error");
450 const SECRET: [u8; 16] = [0xffu8; 16];
451 let sealed = keymint
452 .seal(&KEY_INFO[..], &key_blob[..], &SECRET[..])
453 .await
454 .expect("FIDL error")
455 .expect("seal error");
456 assert_ne!(sealed, SECRET);
457 keymint
458 .unseal(&[2u8; 16], &key_blob[..], &sealed[..])
459 .await
460 .expect("FIDL error")
461 .expect_err("unseal should fail");
462 Ok(())
463 })
464 .await
465 .unwrap();
466 }
467
468 #[fuchsia::test]
469 async fn unseal_failure_on_wrong_secret_blob() {
470 with_keymint_service(|keymint, _| async {
471 let keymint = keymint.into_proxy();
472 const KEY_INFO: [u8; 16] = [1u8; 16];
473 let key_blob = keymint
474 .create_sealing_key(&KEY_INFO[..])
475 .await
476 .expect("FIDL error")
477 .expect("create error");
478 const SECRET: [u8; 16] = [0xffu8; 16];
479 let _ = keymint
480 .seal(&KEY_INFO[..], &key_blob[..], &SECRET[..])
481 .await
482 .expect("FIDL error")
483 .expect("seal error");
484 keymint
485 .unseal(&KEY_INFO[..], &key_blob[..], &[0u8; 16])
486 .await
487 .expect("FIDL error")
488 .expect_err("unseal should fail");
489 Ok(())
490 })
491 .await
492 .unwrap();
493 }
494
495 #[fuchsia::test]
496 async fn delete_all_keys_renders_key_unusable() {
497 with_keymint_service(|keymint, admin| async {
498 let keymint = keymint.into_proxy();
499 const KEY_INFO: [u8; 16] = [1u8; 16];
500 let key_blob = keymint
501 .create_sealing_key(&KEY_INFO[..])
502 .await
503 .expect("FIDL error")
504 .expect("create error");
505
506 let admin = admin.into_proxy();
507 admin.delete_all_keys().await.expect("FIDL error").expect("create error");
508
509 const SECRET: [u8; 16] = [0xffu8; 16];
510 let _ = keymint
511 .seal(&KEY_INFO[..], &key_blob[..], &SECRET[..])
512 .await
513 .expect("FIDL error")
514 .expect_err("seal should fail");
515 Ok(())
516 })
517 .await
518 .unwrap();
519 }
520
521 #[fuchsia::test]
522 async fn delete_keys_succeeds() {
523 with_keymint_service(|keymint, _admin| async {
524 let keymint = keymint.into_proxy();
525 const KEY_INFO: [u8; 16] = [1u8; 16];
526 let key_blob = keymint
527 .create_sealing_key(&KEY_INFO[..])
528 .await
529 .expect("FIDL error")
530 .expect("create error");
531
532 keymint.delete_sealing_key(&key_blob).await.expect("FIDL error").expect("delete error");
533 Ok(())
534 })
535 .await
536 .unwrap();
537 }
538
539 #[fuchsia::test]
540 async fn delete_keys_fails_bad_key_blob() {
541 with_keymint_service(|keymint, _admin| async {
542 let keymint = keymint.into_proxy();
543 const KEY_INFO: [u8; 16] = [1u8; 16];
544 let mut key_blob = keymint
545 .create_sealing_key(&KEY_INFO[..])
546 .await
547 .expect("FIDL error")
548 .expect("create error");
549
550 key_blob[0] ^= 0xffu8;
551
552 keymint
553 .delete_sealing_key(&key_blob)
554 .await
555 .expect("FIDL error")
556 .expect_err("delete success");
557 Ok(())
558 })
559 .await
560 .unwrap();
561 }
562
563 #[fuchsia::test]
564 async fn set_delete_hook_error() {
565 let fake_keymint = FakeKeymint::default();
566 let (sealing_keys_client, sealing_keys_stream) =
567 create_request_stream::<SealingKeysMarker>();
568 let fake_keymint_clone = fake_keymint.clone();
569 let mut sealing_keys_service = pin!(
570 async { fake_keymint_clone.run_sealing_keys_service(sealing_keys_stream).await }.fuse()
571 );
572 let keymint = sealing_keys_client.into_proxy();
573
574 const KEY_INFO: [u8; 16] = [1u8; 16];
575 let key_blob = fake_keymint.generate_static_sealing_key(&KEY_INFO[..]);
576
577 fake_keymint.set_delete_hook(|_| async { Some(DeleteError::FailedDelete) }.boxed());
578
579 let mut fut = pin!(
580 async {
581 keymint
582 .delete_sealing_key(&key_blob)
583 .await
584 .expect("FIDL error")
585 .expect_err("delete success")
586 }
587 .fuse()
588 );
589
590 futures::select! {
591 _ = sealing_keys_service => panic!("service ended"),
592 err = fut => {
593 assert_eq!(err, DeleteError::FailedDelete);
594 }
595 }
596 }
597
598 #[fuchsia::test]
599 async fn set_delete_hook_success() {
600 let fake_keymint = FakeKeymint::default();
601 let (sealing_keys_client, sealing_keys_stream) =
602 create_request_stream::<SealingKeysMarker>();
603 let fake_keymint_clone = fake_keymint.clone();
604 let mut sealing_keys_service = pin!(
605 async { fake_keymint_clone.run_sealing_keys_service(sealing_keys_stream).await }.fuse()
606 );
607 let keymint = sealing_keys_client.into_proxy();
608
609 const KEY_INFO: [u8; 16] = [1u8; 16];
610 let key_blob = fake_keymint.generate_static_sealing_key(&KEY_INFO[..]);
611
612 fake_keymint.set_delete_hook(|_| async { None }.boxed());
613
614 let mut fut = pin!(
615 async {
616 keymint
617 .delete_sealing_key(&key_blob)
618 .await
619 .expect("FIDL error")
620 .expect("delete error");
621 }
622 .fuse()
623 );
624
625 futures::select! {
626 _ = sealing_keys_service => panic!("service ended"),
627 _ = fut => {}
628 }
629
630 assert!(!fake_keymint.has_key_blob(&key_blob));
631 }
632
633 #[fuchsia::test]
634 async fn set_delete_hook_hang_before() {
635 let fake_keymint = FakeKeymint::default();
636 let (sealing_keys_client, sealing_keys_stream) =
637 create_request_stream::<SealingKeysMarker>();
638 let fake_keymint_clone = fake_keymint.clone();
639 let mut sealing_keys_service = pin!(
640 async { fake_keymint_clone.run_sealing_keys_service(sealing_keys_stream).await }.fuse()
641 );
642 let keymint = sealing_keys_client.into_proxy();
643
644 const KEY_INFO: [u8; 16] = [1u8; 16];
645 let key_blob = fake_keymint.generate_static_sealing_key(&KEY_INFO[..]);
646
647 let (tx, mut rx) = futures::channel::oneshot::channel();
648 let tx = Arc::new(Mutex::new(Some(tx)));
649 fake_keymint.set_delete_hook(move |_| {
650 let tx_clone = tx.clone();
651 async move {
652 if let Some(tx) = tx_clone.lock().take() {
653 let _ = tx.send(());
654 }
655 std::future::pending::<()>().await;
656 None
657 }
658 .boxed()
659 });
660
661 let mut fut = pin!(
662 async {
663 let _ = keymint.delete_sealing_key(&key_blob).await;
664 }
665 .fuse()
666 );
667
668 futures::select! {
669 _ = sealing_keys_service => panic!("service ended"),
670 _ = fut => panic!("delete should hang"),
671 res = rx => {
672 res.expect("channel dropped");
673 }
674 }
675
676 assert!(fake_keymint.has_key_blob(&key_blob));
677 }
678
679 #[fuchsia::test]
680 async fn bump_epoch_and_upgrade() {
681 let fake_keymint = FakeKeymint::default();
682 let (sealing_keys_client, sealing_keys_stream) =
683 create_request_stream::<SealingKeysMarker>();
684 let fake_keymint_clone = fake_keymint.clone();
685 let mut sealing_keys_service = pin!(
686 async { fake_keymint_clone.run_sealing_keys_service(sealing_keys_stream).await }.fuse()
687 );
688 let keymint = sealing_keys_client.into_proxy();
689
690 const KEY_INFO: [u8; 16] = [1u8; 16];
691 let key_blob_v1 = fake_keymint.generate_static_sealing_key(&KEY_INFO[..]);
692 const SECRET: [u8; 16] = [0xffu8; 16];
693 let sealed = fake_keymint.generate_static_sealed_data(&KEY_INFO[..], &key_blob_v1, &SECRET);
694
695 fake_keymint.bump_epoch();
696
697 let mut fut = pin!(
698 async {
699 let err = keymint
700 .unseal(&KEY_INFO[..], &key_blob_v1, &sealed)
701 .await
702 .expect("FIDL error")
703 .expect_err("should require upgrade");
704 assert_eq!(err, UnsealError::KeyRequiresUpgrade);
705
706 let key_blob_v2 = keymint
707 .upgrade_sealing_key(&KEY_INFO[..], &key_blob_v1)
708 .await
709 .expect("FIDL error")
710 .expect("upgrade error");
711 let unsealed = keymint
713 .unseal(&KEY_INFO[..], &key_blob_v2, &sealed)
714 .await
715 .expect("FIDL error")
716 .expect("unseal error");
717 assert_eq!(unsealed, SECRET);
718 key_blob_v2
719 }
720 .fuse()
721 );
722
723 let key_blob_v2 = futures::select! {
724 _ = sealing_keys_service => panic!("service ended"),
725 res = fut => res,
726 };
727
728 assert!(fake_keymint.has_key_blob(&key_blob_v2));
729 assert!(fake_keymint.has_key_blob(&key_blob_v1));
730 }
731
732 #[fuchsia::test]
733 async fn insert_sealing_key_test() {
734 let fake_keymint = FakeKeymint::default();
735 const KEY_INFO: [u8; 16] = [2u8; 16];
736 let blob1 = vec![1, 2, 3];
737 let blob2 = vec![4, 5, 6];
738 fake_keymint.insert_sealing_key(&KEY_INFO[..], vec![blob1.clone(), blob2.clone()]);
739 assert!(fake_keymint.has_key_blob(&blob1));
740 assert!(fake_keymint.has_key_blob(&blob2));
741 assert!(!fake_keymint.has_key_blob(&vec![7, 8, 9]));
742 }
743
744 #[fuchsia::test]
745 async fn insert_sealing_key_append_test() {
746 let fake_keymint = FakeKeymint::default();
747 const KEY_INFO: [u8; 16] = [2u8; 16];
748 let blob1 = vec![1, 2, 3];
749 let blob2 = vec![4, 5, 6];
750 fake_keymint.insert_sealing_key(&KEY_INFO[..], vec![blob1.clone()]);
751 fake_keymint.insert_sealing_key(&KEY_INFO[..], vec![blob2.clone()]);
752 assert!(fake_keymint.has_key_blob(&blob1));
753 assert!(fake_keymint.has_key_blob(&blob2));
754 }
755
756 #[fuchsia::test]
757 async fn bump_epoch_seal_requires_upgrade() {
758 let fake_keymint = FakeKeymint::default();
759 const KEY_INFO: [u8; 16] = [1u8; 16];
760 let key_blob_v1 = fake_keymint.generate_static_sealing_key(&KEY_INFO[..]);
761
762 fake_keymint.bump_epoch();
763
764 const SECRET: [u8; 16] = [0xffu8; 16];
765 let (sealing_keys_client, sealing_keys_stream) =
766 create_request_stream::<SealingKeysMarker>();
767 let mut sealing_keys_service =
768 pin!(async { fake_keymint.run_sealing_keys_service(sealing_keys_stream).await }.fuse());
769 let keymint = sealing_keys_client.into_proxy();
770
771 let mut fut = pin!(
772 async {
773 let err = keymint
774 .seal(&KEY_INFO[..], &key_blob_v1, &SECRET)
775 .await
776 .expect("FIDL error")
777 .expect_err("should require upgrade");
778 assert_eq!(err, SealError::KeyRequiresUpgrade);
779 }
780 .fuse()
781 );
782
783 futures::select! {
784 _ = sealing_keys_service => panic!("service ended"),
785 _ = fut => {},
786 }
787 }
788
789 #[fuchsia::test]
790 async fn upgrade_wrong_key_blob() {
791 let fake_keymint = FakeKeymint::default();
792 let (sealing_keys_client, sealing_keys_stream) =
793 create_request_stream::<SealingKeysMarker>();
794 let fake_keymint_clone = fake_keymint.clone();
795 let mut sealing_keys_service = pin!(
796 async { fake_keymint_clone.run_sealing_keys_service(sealing_keys_stream).await }.fuse()
797 );
798 let keymint = sealing_keys_client.into_proxy();
799
800 const KEY_INFO: [u8; 16] = [1u8; 16];
801 let _key_blob = fake_keymint.generate_static_sealing_key(&KEY_INFO[..]);
802
803 let mut fut = pin!(
804 async {
805 let err = keymint
806 .upgrade_sealing_key(&KEY_INFO[..], &[9u8; 16])
807 .await
808 .expect("FIDL error")
809 .expect_err("should fail to upgrade");
810 assert_eq!(err, UpgradeError::FailedUpgrade);
811 }
812 .fuse()
813 );
814
815 futures::select! {
816 _ = sealing_keys_service => panic!("service ended"),
817 _ = fut => {},
818 }
819 }
820}