/rust/registry/src/index.crates.io-1949cf8c6b5b557f/zeroize-1.9.0/src/barrier.rs
Line | Count | Source |
1 | | /// Observe the referenced data and prevent the compiler from removing previous writes to it. |
2 | | /// |
3 | | /// This function acts like [`core::hint::black_box`] but takes a reference and |
4 | | /// does not return the passed value. |
5 | | /// |
6 | | /// It's implemented using the [`core::arch::asm!`] macro on target arches where `asm!` is stable, |
7 | | /// i.e. `aarch64`, `arm`, `arm64ec`, `loongarch64`, `riscv32`, `riscv64`, `s390x`, `x86`, and |
8 | | /// `x86_64`. |
9 | | /// |
10 | | /// On all other targets it's implemented using [`core::hint::black_box`] and custom `black_box` |
11 | | /// implemented using `#[inline(never)]` and `read_volatile`. |
12 | | /// |
13 | | /// # Examples |
14 | | /// ``` |
15 | | /// use core::num::NonZeroU32; |
16 | | /// use zeroize::{ZeroizeOnDrop, zeroize_flat_type}; |
17 | | /// |
18 | | /// # type ThirdPartyType = u32; |
19 | | /// |
20 | | /// struct DataToZeroize { |
21 | | /// buf: [u8; 32], |
22 | | /// // `ThirdPartyType` can be a type with private fields |
23 | | /// // defined in a third-party crate and which does not implement |
24 | | /// // `Zeroize` or zeroization on drop. |
25 | | /// data: ThirdPartyType, |
26 | | /// pos: NonZeroU32, |
27 | | /// } |
28 | | /// |
29 | | /// struct SomeMoreFlatData(u64); |
30 | | /// |
31 | | /// impl Drop for DataToZeroize { |
32 | | /// fn drop(&mut self) { |
33 | | /// self.buf = [0u8; 32]; |
34 | | /// self.data = ThirdPartyType::default(); |
35 | | /// self.pos = NonZeroU32::new(32).unwrap(); |
36 | | /// zeroize::optimization_barrier(self); |
37 | | /// } |
38 | | /// } |
39 | | /// |
40 | | /// impl zeroize::ZeroizeOnDrop for DataToZeroize {} |
41 | | /// |
42 | | /// let mut data = DataToZeroize { |
43 | | /// buf: [3u8; 32], |
44 | | /// data: ThirdPartyType::default(), |
45 | | /// pos: NonZeroU32::new(32).unwrap(), |
46 | | /// }; |
47 | | /// |
48 | | /// // data gets zeroized when dropped |
49 | | /// ``` |
50 | | /// |
51 | | /// Note that erasure of `ThirdPartyType` demonstrated above can be fragile if it contains |
52 | | /// `MaybeUninit` or `union` data. It also does not perform erasure of types like `Box` or `Vec`. |
53 | 0 | pub fn optimization_barrier<T: ?Sized>(val: &T) { |
54 | | #[cfg(all( |
55 | | not(miri), |
56 | | any( |
57 | | target_arch = "aarch64", |
58 | | target_arch = "arm", |
59 | | target_arch = "arm64ec", |
60 | | target_arch = "loongarch64", |
61 | | target_arch = "riscv32", |
62 | | target_arch = "riscv64", |
63 | | target_arch = "s390x", |
64 | | target_arch = "x86", |
65 | | target_arch = "x86_64", |
66 | | ) |
67 | | ))] |
68 | 0 | unsafe { |
69 | 0 | core::arch::asm!( |
70 | 0 | "# {}", |
71 | 0 | in(reg) core::ptr::from_ref::<T>(val).cast::<()>(), |
72 | 0 | options(readonly, preserves_flags, nostack), |
73 | 0 | ); |
74 | 0 | } |
75 | | #[cfg(not(all( |
76 | | not(miri), |
77 | | any( |
78 | | target_arch = "aarch64", |
79 | | target_arch = "arm", |
80 | | target_arch = "arm64ec", |
81 | | target_arch = "loongarch64", |
82 | | target_arch = "riscv32", |
83 | | target_arch = "riscv64", |
84 | | target_arch = "s390x", |
85 | | target_arch = "x86", |
86 | | target_arch = "x86_64", |
87 | | ) |
88 | | )))] |
89 | | { |
90 | | /// Custom version of `core::hint::black_box` implemented using |
91 | | /// `#[inline(never)]` and `read_volatile`. |
92 | | #[inline(never)] |
93 | | fn custom_black_box(p: *const u8) { |
94 | | let _ = unsafe { core::ptr::read_volatile(p) }; |
95 | | } |
96 | | |
97 | | core::hint::black_box(val); |
98 | | if size_of_val(val) > 0 { |
99 | | custom_black_box(core::ptr::from_ref(val).cast::<u8>()); |
100 | | } |
101 | | } |
102 | 0 | } Unexecuted instantiation: zeroize::barrier::optimization_barrier::<u32> Unexecuted instantiation: zeroize::barrier::optimization_barrier::<u16> Unexecuted instantiation: zeroize::barrier::optimization_barrier::<u64> Unexecuted instantiation: zeroize::barrier::optimization_barrier::<core::num::nonzero::NonZero<i8>> Unexecuted instantiation: zeroize::barrier::optimization_barrier::<core::num::nonzero::NonZero<u8>> Unexecuted instantiation: zeroize::barrier::optimization_barrier::<core::num::nonzero::NonZero<isize>> Unexecuted instantiation: zeroize::barrier::optimization_barrier::<core::num::nonzero::NonZero<usize>> Unexecuted instantiation: zeroize::barrier::optimization_barrier::<core::num::nonzero::NonZero<i32>> Unexecuted instantiation: zeroize::barrier::optimization_barrier::<core::num::nonzero::NonZero<u32>> Unexecuted instantiation: zeroize::barrier::optimization_barrier::<core::num::nonzero::NonZero<i128>> Unexecuted instantiation: zeroize::barrier::optimization_barrier::<core::num::nonzero::NonZero<u128>> Unexecuted instantiation: zeroize::barrier::optimization_barrier::<core::num::nonzero::NonZero<i16>> Unexecuted instantiation: zeroize::barrier::optimization_barrier::<core::num::nonzero::NonZero<u16>> Unexecuted instantiation: zeroize::barrier::optimization_barrier::<core::num::nonzero::NonZero<i64>> Unexecuted instantiation: zeroize::barrier::optimization_barrier::<core::num::nonzero::NonZero<u64>> Unexecuted instantiation: zeroize::barrier::optimization_barrier::<[core::mem::maybe_uninit::MaybeUninit<u8>]> Unexecuted instantiation: zeroize::barrier::optimization_barrier::<[u8]> Unexecuted instantiation: zeroize::barrier::optimization_barrier::<u8> |