@@ -795,6 +795,74 @@ unsafe fn volatile_set<T: Copy + Sized>(dst: *mut T, src: T, count: usize) {
795795 }
796796}
797797
798+ /// Zeroizes a flat type/struct. Only zeroizes the values that it owns, and it does not work on
799+ /// dynamically sized values or trait objects. It would be inefficient to use this function on a
800+ /// type that already implements `ZeroizeOnDrop`.
801+ ///
802+ /// # Safety
803+ /// - The type must not contain references to outside data or dynamically sized data, such as Vec<X>
804+ /// or String<X>.
805+ /// - This function can invalidate the type if it is used after this function is called on it. It is
806+ /// advisable to call this function in `impl Drop`.
807+ /// - The bit pattern of all zeroes must be valid for the data being zeroized. This may not be true for
808+ /// enums and pointers.
809+ ///
810+ /// # Incompatible data types
811+ /// Some data types that cannot be safely zeroized using `zeroize_flat_type` include, but are not
812+ /// limited to:
813+ /// - pointers such as
814+ /// - *const u8
815+ /// - *mut u8
816+ /// - references such as
817+ /// - &T
818+ /// - &mut T
819+ /// - smart pointers and collections
820+ /// - Arc<T>
821+ /// - Box<T>
822+ /// - Vec<T>
823+ /// - HashMap<T1, T2>
824+ /// - String
825+ ///
826+ /// Some data types that may be invalid after calling `zeroize_flat_type`:
827+ /// - enums
828+ ///
829+ /// # Examples
830+ /// Safe usage for a struct containing strictly flat data:
831+ /// ```
832+ /// use zeroize::{ZeroizeOnDrop, zeroize_flat_type};
833+ ///
834+ /// struct DataToZeroize {
835+ /// flat_data_1: [u8; 32],
836+ /// flat_data_2: SomeMoreFlatData,
837+ /// }
838+ ///
839+ /// struct SomeMoreFlatData(u64);
840+ ///
841+ /// impl Drop for DataToZeroize {
842+ /// fn drop(&mut self) {
843+ /// unsafe { zeroize_flat_type(self as *mut Self) }
844+ /// }
845+ /// }
846+ /// impl ZeroizeOnDrop for DataToZeroize {}
847+ ///
848+ /// let mut data = DataToZeroize {
849+ /// flat_data_1: [3u8; 32],
850+ /// flat_data_2: SomeMoreFlatData(123u64)
851+ /// };
852+ ///
853+ /// // data gets zeroized when dropped
854+ /// ```
855+ #[ inline( always) ]
856+ pub unsafe fn zeroize_flat_type < F : Sized > ( data : * mut F ) {
857+ let size = mem:: size_of :: < F > ( ) ;
858+ // Safety:
859+ //
860+ // This is safe because `mem::size_of<T>()` returns the exact size of the object in memory, and
861+ // `data_ptr` points directly to the first byte of the data.
862+ volatile_set ( data as * mut u8 , 0 , size) ;
863+ atomic_fence ( )
864+ }
865+
798866/// Internal module used as support for `AssertZeroizeOnDrop`.
799867#[ doc( hidden) ]
800868pub mod __internal {
0 commit comments