1use crate::errors::FxfsError;
6use crate::log::*;
7use crate::object_store::object_record::EncryptionKeys;
8use crate::object_store::{FSCRYPT_KEY_ID, VOLUME_DATA_KEY_ID};
9use anyhow::Error;
10use event_listener::Event;
11use fuchsia_sync::Mutex;
12use fxfs_crypto::{Cipher, CipherHolder, CipherSet, Crypt, FindKeyResult};
13use scopeguard::ScopeGuard;
14use std::cell::UnsafeCell;
15use std::collections::BTreeMap;
16use std::collections::btree_map::Entry;
17use std::future::Future;
18use std::sync::Arc;
19use std::time::Duration;
20use {fuchsia_async as fasync, zx_status as zx};
21
22const PURGE_TIMEOUT: Duration = Duration::from_secs(37);
27
28struct Cache<V> {
31 hash: BTreeMap<u64, V>,
32 pending_purge: BTreeMap<u64, V>,
33 permanent: BTreeMap<u64, V>,
34}
35
36impl<V> Cache<V> {
37 fn new() -> Self {
38 Self { hash: BTreeMap::new(), pending_purge: BTreeMap::new(), permanent: BTreeMap::new() }
39 }
40
41 fn get(&mut self, key: u64) -> Option<&V> {
42 match self.hash.entry(key) {
43 Entry::Occupied(o) => Some(o.into_mut()),
44 Entry::Vacant(v) => {
45 if let Some(value) = self.pending_purge.remove(&key) {
47 Some(v.insert(value))
48 } else {
49 self.permanent.get(&key)
50 }
51 }
52 }
53 }
54
55 fn insert(&mut self, key: u64, value: V, permanent: bool) {
56 if permanent {
57 self.permanent.insert(key, value);
58 } else {
59 self.hash.insert(key, value);
60 }
61 }
62
63 fn merge(&mut self, key: u64, merge: impl FnOnce(Option<&V>) -> V) {
64 match self.hash.entry(key) {
65 Entry::Occupied(mut o) => {
66 let new = merge(Some(o.get()));
67 *o.get_mut() = new;
68 }
69 Entry::Vacant(v) => {
70 if let Some(value) = self.pending_purge.remove(&key) {
72 v.insert(merge(Some(&value)));
73 } else {
74 v.insert(merge(None));
75 }
76 }
77 }
78 }
79
80 fn purge(&mut self) -> bool {
84 self.pending_purge = std::mem::take(&mut self.hash);
85 self.pending_purge.is_empty()
86 }
87
88 fn clear(&mut self) {
89 self.hash.clear();
90 self.pending_purge.clear();
91 self.permanent.clear();
92 }
93
94 fn remove(&mut self, key: u64) {
95 self.hash.remove(&key);
96 self.pending_purge.remove(&key);
97 self.permanent.remove(&key);
98 }
99}
100
101pub struct KeyManager {
102 inner: Arc<Mutex<Inner>>,
103}
104
105struct Inner {
106 keys: Cache<Arc<CipherSet>>,
107 unwrapping: BTreeMap<u64, Arc<UnwrapResult>>,
108 purge_task: Option<fasync::Task<()>>,
109}
110
111impl Inner {
112 fn start_purge_task(&mut self, inner: &Arc<Mutex<Inner>>) {
113 self.purge_task.get_or_insert_with(move || {
114 let inner = inner.clone();
115 fasync::Task::spawn(async move {
116 loop {
117 fasync::Timer::new(PURGE_TIMEOUT).await;
118 let mut inner = inner.lock();
119 if inner.keys.purge() {
120 inner.purge_task = None;
121 break;
122 }
123 }
124 })
125 });
126 }
127}
128
129struct UnwrapResult {
130 event: Event,
131 error: UnsafeCell<zx::Status>,
132 cancelled: UnsafeCell<bool>,
134}
135
136impl UnwrapResult {
137 fn new() -> Arc<Self> {
138 Arc::new(UnwrapResult {
139 event: Event::new(),
140 error: UnsafeCell::new(zx::Status::OK),
141 cancelled: UnsafeCell::new(false),
142 })
143 }
144
145 fn set(
147 &self,
148 inner: &Arc<Mutex<Inner>>,
149 object_id: u64,
150 permanent: bool,
151 result: Result<Option<Arc<CipherSet>>, zx::Status>,
152 ) -> bool {
153 let mut guard = inner.lock();
154 let cancelled = unsafe { *self.cancelled.get() };
156 let set_error = |error| {
157 unsafe {
159 *self.error.get() = error;
160 }
161 };
162 if cancelled {
163 set_error(zx::Status::CANCELED);
164 } else if let Err(error) = &result {
165 error!(error:?, oid = object_id; "Failed to unwrap keys");
166 set_error(*error);
167 }
168 if let Entry::Occupied(o) = guard.unwrapping.entry(object_id) {
169 if std::ptr::eq(Arc::as_ptr(o.get()), self) {
170 o.remove();
171 if !cancelled {
172 if let Ok(Some(keys)) = &result {
173 guard.keys.insert(object_id, keys.clone(), permanent);
174 guard.start_purge_task(inner);
175 }
176 }
177 }
178 }
179 self.event.notify(usize::MAX);
180 cancelled
181 }
182}
183
184unsafe impl Send for UnwrapResult {}
185unsafe impl Sync for UnwrapResult {}
186
187impl KeyManager {
188 pub fn new() -> Self {
189 let inner = Arc::new(Mutex::new(Inner {
190 keys: Cache::new(),
191 unwrapping: BTreeMap::new(),
192 purge_task: None,
193 }));
194
195 Self { inner }
196 }
197
198 pub async fn get(&self, object_id: u64) -> Result<Option<Arc<dyn Cipher>>, Error> {
204 loop {
205 let (unwrap_result, listener) = {
206 let mut inner = self.inner.lock();
207
208 if let Some(keys) = inner.keys.get(object_id) {
209 return match keys.find_key(VOLUME_DATA_KEY_ID) {
210 FindKeyResult::NotFound => Ok(None),
211 FindKeyResult::Unavailable(_) => Err(FxfsError::NoKey.into()),
212 FindKeyResult::Key(key) => Ok(Some(key)),
213 };
214 }
215 let unwrap_result = match inner.unwrapping.entry(object_id) {
216 Entry::Vacant(_) => return Ok(None),
217 Entry::Occupied(o) => o.get().clone(),
218 };
219 let listener = unwrap_result.event.listen();
220 (unwrap_result, listener)
221 };
222 listener.await;
223 let error = unsafe { *unwrap_result.error.get().clone() };
225 match error {
226 zx::Status::OK => {}
227 _ => return Err(error.into()),
228 }
229 }
230 }
231
232 pub async fn get_keys(
238 &self,
239 object_id: u64,
240 crypt: &dyn Crypt,
241 encryption_keys: &mut Option<impl AsyncFnOnce() -> Result<EncryptionKeys, Error>>,
242 permanent: bool,
243 force: bool,
244 ) -> Result<Arc<CipherSet>, Error> {
245 let inner = self.inner.clone();
246 let mut unwrap_result;
247
248 loop {
249 let listener = {
250 let mut inner = inner.lock();
251
252 if !force {
253 if let Some(keys) = inner.keys.get(object_id) {
254 return Ok(keys.clone());
255 }
256 }
257
258 match inner.unwrapping.entry(object_id) {
259 Entry::Vacant(v) => {
260 unwrap_result = UnwrapResult::new();
261 v.insert(unwrap_result.clone());
262 break;
263 }
264 Entry::Occupied(o) => {
265 unwrap_result = o.get().clone();
266 let listener = unwrap_result.event.listen();
267 listener
268 }
269 }
270 };
271
272 listener.await;
273 let error = unsafe { *unwrap_result.error.get().clone() };
276 match error {
277 zx::Status::OK => {}
278 _ => return Err(error.into()),
279 }
280 }
281
282 let mut result = scopeguard::guard(Ok(None), |result| {
284 unwrap_result.set(&inner, object_id, permanent, result);
285 });
286
287 let encryption_keys = match encryption_keys.take().unwrap()().await {
288 Ok(encryption_keys) => encryption_keys,
289 Err(error) => {
290 error!(error:?; "Failed to get key specs");
291 *result = Err(zx::Status::INTERNAL);
292 return Err(zx::Status::INTERNAL.into());
293 }
294 };
295
296 let wrapped_keys = encryption_keys.into();
299 match crypt.unwrap_keys(&wrapped_keys, object_id).await {
300 Ok(cipher_set) => {
301 let keys = Arc::new(cipher_set);
302 let _ = ScopeGuard::into_inner(result);
303 if unwrap_result.set(&inner, object_id, permanent, Ok(Some(keys.clone()))) {
304 Err(zx::Status::CANCELED.into())
305 } else {
306 Ok(keys)
307 }
308 }
309 Err(error) => {
310 *result = Err(error);
311 Err(error.into())
312 }
313 }
314 }
315
316 pub async fn get_key(
320 &self,
321 object_id: u64,
322 crypt: &dyn Crypt,
323 encryption_keys: impl AsyncFnOnce() -> Result<EncryptionKeys, Error>,
324 key_id: u64,
325 ) -> Result<Arc<dyn Cipher>, Error> {
326 let mut encryption_keys = Some(encryption_keys);
327 let mut force = false;
328 loop {
329 let keys = self
330 .get_keys(
331 object_id,
332 crypt,
333 &mut encryption_keys,
334 false,
335 force,
336 )
337 .await?;
338 return match keys.find_key(key_id) {
339 FindKeyResult::NotFound => Err(FxfsError::NotFound.into()),
340 FindKeyResult::Unavailable(_) => {
341 if force || encryption_keys.is_none() {
342 Err(FxfsError::NoKey.into())
343 } else {
344 force = true;
345 continue;
346 }
347 }
348 FindKeyResult::Key(k) => Ok(k),
349 };
350 }
351 }
352
353 pub async fn get_fscrypt_key_if_present(
358 &self,
359 object_id: u64,
360 crypt: &dyn Crypt,
361 encryption_keys: impl AsyncFnOnce() -> Result<EncryptionKeys, Error>,
362 ) -> Result<(u64, Arc<dyn Cipher>), Error> {
363 let mut encryption_keys = Some(encryption_keys);
364 let mut force = false;
365 loop {
366 let keys = self
367 .get_keys(
368 object_id,
369 crypt,
370 &mut encryption_keys,
371 false,
372 force,
373 )
374 .await?;
375 return match keys.find_key(FSCRYPT_KEY_ID) {
376 FindKeyResult::NotFound => {
377 Ok((VOLUME_DATA_KEY_ID, to_result(keys.find_key(VOLUME_DATA_KEY_ID))?))
378 }
379 FindKeyResult::Unavailable(_) => {
380 if force || encryption_keys.is_none() {
381 Err(FxfsError::NoKey.into())
382 } else {
383 force = true;
384 continue;
385 }
386 }
387 FindKeyResult::Key(k) => Ok((FSCRYPT_KEY_ID, k)),
388 };
389 }
390 }
391
392 pub async fn get_fscrypt_key(
396 &self,
397 object_id: u64,
398 crypt: &dyn Crypt,
399 encryption_keys: impl AsyncFnOnce() -> Result<EncryptionKeys, Error>,
400 ) -> Result<CipherHolder, Error> {
401 let mut encryption_keys = Some(encryption_keys);
402 let mut force = false;
403 loop {
404 let keys = self
405 .get_keys(
406 object_id,
407 crypt,
408 &mut encryption_keys,
409 false,
410 force,
411 )
412 .await?;
413 return match keys.find_key(FSCRYPT_KEY_ID) {
414 FindKeyResult::NotFound => Err(FxfsError::NotFound.into()),
415 FindKeyResult::Unavailable(key_type) => {
416 if force || encryption_keys.is_none() {
417 Ok(CipherHolder::Unavailable(key_type))
418 } else {
419 force = true;
420 continue;
421 }
422 }
423 FindKeyResult::Key(k) => Ok(CipherHolder::Cipher(k)),
424 };
425 }
426 }
427
428 pub fn insert(&self, object_id: u64, keys: Arc<CipherSet>, permanent: bool) {
431 let mut inner = self.inner.lock();
432 inner.keys.insert(object_id, keys, permanent);
433 inner.start_purge_task(&self.inner);
434 }
435
436 pub fn merge(
440 &self,
441 object_id: u64,
442 merge: impl FnOnce(Option<&Arc<CipherSet>>) -> Arc<CipherSet>,
443 ) {
444 let mut inner = self.inner.lock();
445 inner.keys.merge(object_id, merge);
446 inner.start_purge_task(&self.inner);
447 }
448
449 pub fn remove(&self, object_id: u64) -> impl Future<Output = ()> {
452 {
453 let mut inner = self.inner.lock();
454 inner.keys.remove(object_id);
455 if let Some(u) = inner.unwrapping.get(&object_id) {
456 unsafe { *u.cancelled.get() = true };
458 }
459 }
460 let inner = self.inner.clone();
461 async move {
462 let listener = {
463 if let Some(u) = inner.lock().unwrapping.get(&object_id) {
464 u.event.listen()
465 } else {
466 return;
467 }
468 };
469 listener.await;
470 }
471 }
472
473 pub fn clear(&self) {
475 let mut inner = self.inner.lock();
476 inner.keys.clear();
477 inner.unwrapping.clear();
478 }
479}
480
481fn to_result(find_key_result: FindKeyResult) -> Result<Arc<dyn Cipher>, FxfsError> {
482 match find_key_result {
483 FindKeyResult::NotFound => Err(FxfsError::NotFound),
484 FindKeyResult::Unavailable(_) => Err(FxfsError::NoKey),
485 FindKeyResult::Key(k) => Ok(k),
486 }
487}
488
489#[cfg(target_os = "fuchsia")]
490#[cfg(test)]
491mod tests {
492 use super::{EncryptionKeys, KeyManager, PURGE_TIMEOUT, to_result};
493 use crate::log::*;
494 use async_trait::async_trait;
495 use fuchsia_async::{self as fasync, MonotonicInstant, TestExecutor};
496
497 use crate::object_store::object_record::EncryptionKey;
498 use futures::channel::oneshot;
499 use futures::join;
500 use fxfs_crypto::{
501 Cipher, CipherHolder, Crypt, FXFS_KEY_SIZE, FXFS_WRAPPED_KEY_SIZE, FxfsCipher, FxfsKey,
502 KeyPurpose, ObjectType, UnwrappedKey, WrappedKey, WrappedKeyBytes, WrappingKeyId,
503 };
504 use std::future::pending;
505 use std::sync::Arc;
506 use std::sync::atomic::{AtomicBool, AtomicU8, Ordering};
507
508 const PLAIN_TEXT: &[u8] = b"The quick brown fox jumps over the lazy dog";
509 const ERROR_COUNTER: u8 = 0xff;
510
511 fn unwrapped_key(counter: u8) -> UnwrappedKey {
512 UnwrappedKey::new([counter; FXFS_KEY_SIZE].to_vec())
513 }
514 fn cipher(counter: u8) -> Arc<dyn Cipher> {
515 Arc::new(FxfsCipher::new(&unwrapped_key(counter)))
516 }
517
518 fn padded_plain_text() -> Vec<u8> {
519 let mut text = PLAIN_TEXT.to_vec();
520 text.resize(4096, 0); text
522 }
523
524 fn cipher_text(counter: u8) -> Vec<u8> {
525 let mut text = padded_plain_text();
526 cipher(counter).encrypt(0, 0, 0, &mut text).expect("encrypt failed");
527 assert_ne!(&text, &padded_plain_text());
529 text
530 }
531
532 fn encryption_keys() -> EncryptionKeys {
533 vec![(
534 0,
535 EncryptionKey::Fxfs(FxfsKey {
536 wrapping_key_id: 0x1234567812345678u128.to_le_bytes(),
537 key: WrappedKeyBytes::from([0xff; FXFS_WRAPPED_KEY_SIZE]),
538 }),
539 )]
540 .into()
541 }
542
543 struct TestCrypt {
544 counter: AtomicU8,
545 unwrap_delay: std::time::Duration,
546 }
547
548 impl TestCrypt {
549 fn new(counter: u8) -> Arc<Self> {
550 Arc::new(Self {
551 counter: AtomicU8::new(counter),
552 unwrap_delay: std::time::Duration::from_secs(1),
553 })
554 }
555
556 fn with_unwrap_delay(counter: u8, unwrap_delay: std::time::Duration) -> Arc<Self> {
557 Arc::new(Self { counter: AtomicU8::new(counter), unwrap_delay })
558 }
559 }
560
561 #[async_trait]
562 impl Crypt for TestCrypt {
563 async fn create_key(
564 &self,
565 _owner: u64,
566 _purpose: KeyPurpose,
567 ) -> Result<(FxfsKey, UnwrappedKey), zx::Status> {
568 unimplemented!("Not used in tests");
569 }
570
571 async fn create_key_with_id(
572 &self,
573 _owner: u64,
574 _wrapping_key_id: WrappingKeyId,
575 _object_type: ObjectType,
576 ) -> Result<(fxfs_crypto::EncryptionKey, UnwrappedKey), zx::Status> {
577 unimplemented!("Not used in tests");
578 }
579
580 async fn unwrap_key(
581 &self,
582 _wrapped_key: &WrappedKey,
583 _owner: u64,
584 ) -> Result<UnwrappedKey, zx::Status> {
585 if !self.unwrap_delay.is_zero() {
586 fasync::Timer::new(self.unwrap_delay).await;
587 }
588 let counter = self.counter.fetch_add(1, Ordering::Relaxed);
589 if counter == ERROR_COUNTER {
590 error!("Unwrap failed!");
591 Err(zx::Status::INTERNAL)
592 } else {
593 Ok(unwrapped_key(counter))
594 }
595 }
596 }
597
598 #[fuchsia::test(allow_stalls = false)]
599 async fn test_get_keys() {
600 TestExecutor::advance_to(MonotonicInstant::from_nanos(0)).await;
601
602 let crypt = TestCrypt::new(0);
603 let manager1 = Arc::new(KeyManager::new());
604 let manager2 = manager1.clone();
605 let manager3 = manager1.clone();
606 let crypt1 = crypt.clone();
607 let crypt2 = crypt.clone();
608
609 let task1 = fasync::Task::spawn(async move {
610 let mut buf = cipher_text(0);
611 to_result(
612 manager1
613 .get_keys(
614 1,
615 crypt1.as_ref(),
616 &mut Some(async || Ok(encryption_keys())),
617 false,
618 false,
619 )
620 .await
621 .expect("get_keys failed")
622 .find_key(0),
623 )
624 .unwrap()
625 .decrypt(0, 0, 0, &mut buf)
626 .expect("decrypt failed");
627 assert_eq!(&buf, &padded_plain_text());
628 });
629 let task2 = fasync::Task::spawn(async move {
630 let mut buf = cipher_text(0);
631 to_result(
632 manager2
633 .get_keys(
634 1,
635 crypt2.as_ref(),
636 &mut Some(async || Ok(encryption_keys())),
637 false,
638 false,
639 )
640 .await
641 .expect("get_keys failed")
642 .find_key(0),
643 )
644 .unwrap()
645 .decrypt(0, 0, 0, &mut buf)
646 .expect("decrypt failed");
647 assert_eq!(&buf, &padded_plain_text());
648 });
649 let task3 = fasync::Task::spawn(async move {
650 fasync::Timer::new(zx::MonotonicDuration::from_millis(500)).await;
652 let mut buf = cipher_text(0);
653 manager3
654 .get(1)
655 .await
656 .expect("get failed")
657 .expect("missing key")
658 .decrypt(0, 0, 0, &mut buf)
659 .expect("decrypt failed");
660 assert_eq!(&buf, &padded_plain_text());
661 });
662
663 TestExecutor::advance_to(MonotonicInstant::after(zx::MonotonicDuration::from_millis(1500)))
664 .await;
665
666 task1.await;
667 task2.await;
668 task3.await;
669 }
670
671 #[fuchsia::test]
672 async fn test_insert_and_remove() {
673 let manager = Arc::new(KeyManager::new());
674
675 manager.insert(1, Arc::new(vec![(0, CipherHolder::Cipher(cipher(0)))].into()), false);
676 let mut buf = cipher_text(0);
677 manager
678 .get(1)
679 .await
680 .expect("get failed")
681 .expect("missing key")
682 .decrypt(0, 0, 0, &mut buf)
683 .expect("decrypt failed");
684 assert_eq!(&buf, &padded_plain_text());
685 let _ = manager.remove(1);
686 assert!(manager.get(1).await.expect("get failed").is_none());
687 }
688
689 #[fuchsia::test(allow_stalls = false)]
690 async fn test_purge() {
691 TestExecutor::advance_to(MonotonicInstant::from_nanos(0)).await;
692
693 let manager = Arc::new(KeyManager::new());
694 manager.insert(1, Arc::new(vec![(0, CipherHolder::Cipher(cipher(0)))].into()), false);
695
696 TestExecutor::advance_to(MonotonicInstant::after(PURGE_TIMEOUT.into())).await;
697
698 manager.get(1).await.expect("get failed").expect("missing key");
700
701 TestExecutor::advance_to(MonotonicInstant::after(PURGE_TIMEOUT.into())).await;
702
703 manager.get(1).await.expect("get failed").expect("missing key");
705
706 TestExecutor::advance_to(MonotonicInstant::after((2 * PURGE_TIMEOUT).into())).await;
707
708 assert!(manager.get(1).await.expect("get failed").is_none());
710 }
711
712 #[fuchsia::test(allow_stalls = false)]
713 async fn test_permanent() {
714 TestExecutor::advance_to(MonotonicInstant::from_nanos(0)).await;
715
716 let manager = Arc::new(KeyManager::new());
717 manager.insert(1, Arc::new(vec![(0, CipherHolder::Cipher(cipher(0)))].into()), true);
718 manager.insert(2, Arc::new(vec![(0, CipherHolder::Cipher(cipher(0)))].into()), false);
719
720 TestExecutor::advance_to(MonotonicInstant::after((2 * PURGE_TIMEOUT).into())).await;
722
723 assert!(manager.get(1).await.expect("get failed").is_some());
724 assert!(manager.get(2).await.expect("get failed").is_none());
725 }
726
727 #[fuchsia::test(allow_stalls = false)]
728 async fn test_clear() {
729 TestExecutor::advance_to(MonotonicInstant::from_nanos(0)).await;
730
731 let manager = Arc::new(KeyManager::new());
732 manager.insert(1, Arc::new(vec![(0, CipherHolder::Cipher(cipher(0)))].into()), true);
733 manager.insert(2, Arc::new(vec![(0, CipherHolder::Cipher(cipher(0)))].into()), false);
734 manager.insert(3, Arc::new(vec![(0, CipherHolder::Cipher(cipher(0)))].into()), false);
735
736 TestExecutor::advance_to(MonotonicInstant::after(PURGE_TIMEOUT.into())).await;
738
739 assert!(manager.get(2).await.expect("get failed").is_some());
741
742 manager.clear();
743
744 assert!(manager.get(1).await.expect("get failed").is_none());
746 assert!(manager.get(2).await.expect("get failed").is_none());
747 assert!(manager.get(3).await.expect("get failed").is_none());
748 }
749
750 #[fuchsia::test(allow_stalls = false)]
751 async fn test_error() {
752 TestExecutor::advance_to(MonotonicInstant::from_nanos(0)).await;
753
754 let crypt = TestCrypt::new(ERROR_COUNTER);
755 let manager1 = Arc::new(KeyManager::new());
756 let manager2 = manager1.clone();
757 let crypt1 = crypt.clone();
758 let crypt2 = crypt.clone();
759
760 let task1 = fasync::Task::spawn(async move {
761 assert!(
762 manager1
763 .get_keys(
764 1,
765 crypt1.as_ref(),
766 &mut Some(async || Ok(encryption_keys())),
767 false,
768 false,
769 )
770 .await
771 .is_err()
772 );
773 });
774 let task2 = fasync::Task::spawn(async move {
775 assert!(
776 manager2
777 .get_keys(
778 1,
779 crypt2.as_ref(),
780 &mut Some(async || Ok(encryption_keys())),
781 false,
782 false,
783 )
784 .await
785 .is_err()
786 );
787 });
788
789 TestExecutor::advance_to(MonotonicInstant::after(zx::MonotonicDuration::from_seconds(1)))
790 .await;
791
792 task1.await;
793 task2.await;
794 }
795
796 #[fuchsia::test(allow_stalls = false)]
797 async fn test_wait_after_remove() {
798 let manager = Arc::new(KeyManager::new());
799 let crypt = TestCrypt::with_unwrap_delay(0, std::time::Duration::ZERO);
800 let (sender, receiver) = oneshot::channel();
801 let dropped = AtomicBool::new(false);
802
803 assert!(
804 join!(
805 async {
806 let mut unwrap_keys = Some(async || {
807 struct OnDrop<'a>(&'a AtomicBool);
808 impl Drop for OnDrop<'_> {
809 fn drop(&mut self) {
810 self.0.store(true, Ordering::Relaxed);
811 }
812 }
813 let _on_drop = OnDrop(&dropped);
814 sender.send(()).unwrap();
815 let _ = TestExecutor::poll_until_stalled(pending::<()>()).await;
817 Ok(encryption_keys())
818 });
819 manager.get_keys(1, crypt.as_ref(), &mut unwrap_keys, false, false).await
820 },
821 async {
822 let _ = receiver.await;
823 join!(
824 async {
825 manager.remove(1).await;
826 assert!(dropped.load(Ordering::Relaxed));
827 },
828 async {
829 manager.remove(1).await;
830 assert!(dropped.load(Ordering::Relaxed));
831 }
832 );
833 },
834 )
835 .0
836 .is_err()
837 );
838 }
839}