mirror of
https://github.com/ibm-s390-linux/s390-tools.git
synced 2026-08-05 02:14:52 +00:00
rust/pv_core: Generalize Confidential
Generalize the `Confidential` impl over Vec<T> and [COUNT; T] instead of specializing T to u8. Signed-off-by: Steffen Eiden <seiden@linux.ibm.com> Reviewed-by: Marc Hartmayer <mhartmay@linux.ibm.com> Signed-off-by: Steffen Eiden <seiden@linux.ibm.com>
This commit is contained in:
@@ -13,28 +13,35 @@ pub trait Zeroize {
|
||||
}
|
||||
|
||||
// Automatically impl Zeroize for u8 arrays
|
||||
impl<const COUNT: usize> Zeroize for [u8; COUNT] {
|
||||
impl<T: Default, const COUNT: usize> Zeroize for [T; COUNT] {
|
||||
/// Reliably overwrites the given buffer with zeros,
|
||||
/// by performing a volatile write followed by a memory barrier
|
||||
fn zeroize(&mut self) {
|
||||
// SAFETY: given buffer(self) has the correct (compile time) size
|
||||
unsafe { std::ptr::write_volatile(self, [0u8; COUNT]) };
|
||||
let mut dst = self.as_mut_ptr();
|
||||
for _ in 0..self.len() {
|
||||
// SAFETY:
|
||||
// * Array allocated len elements continuously
|
||||
// * dst points always to a valid location
|
||||
unsafe {
|
||||
std::ptr::write_volatile(dst, T::default());
|
||||
dst = dst.add(1);
|
||||
}
|
||||
}
|
||||
std::sync::atomic::compiler_fence(std::sync::atomic::Ordering::SeqCst);
|
||||
}
|
||||
}
|
||||
|
||||
impl Zeroize for Vec<u8> {
|
||||
impl<T: Default> Zeroize for Vec<T> {
|
||||
/// Reliably overwrites the given buffer with zeros,
|
||||
/// by overwriting the whole vector's capacity with zeros.
|
||||
fn zeroize(&mut self) {
|
||||
// TODO use `volatile_set_memory` when stabilized
|
||||
let mut dst = self.as_mut_ptr();
|
||||
for _ in 0..self.capacity() {
|
||||
// SAFETY:
|
||||
// * Vec allocated at least capacity elements continuously
|
||||
// * dst points always to a valid location
|
||||
unsafe {
|
||||
std::ptr::write_volatile(dst, 0);
|
||||
std::ptr::write_volatile(dst, T::default());
|
||||
dst = dst.add(1);
|
||||
}
|
||||
}
|
||||
@@ -116,3 +123,49 @@ impl<C: Zeroize> Drop for Confidential<C> {
|
||||
self.0.zeroize();
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use super::*;
|
||||
|
||||
#[derive(Debug, Default, PartialEq, Eq)]
|
||||
struct DummyStruct([u32; 8]);
|
||||
|
||||
#[test]
|
||||
fn array() {
|
||||
let mut conf = Confidential::new([17; 42]);
|
||||
assert_eq!(&[17; 42], conf.value());
|
||||
conf.zeroize();
|
||||
assert_eq!(&[0; 42], conf.value());
|
||||
|
||||
let mut conf2 = Confidential::new([DummyStruct([0x12u32; 8]), DummyStruct([0x24u32; 8])]);
|
||||
assert_eq!(
|
||||
&[DummyStruct([0x12u32; 8]), DummyStruct([0x24u32; 8])],
|
||||
conf2.value()
|
||||
);
|
||||
conf2.zeroize();
|
||||
assert_eq!(
|
||||
&[DummyStruct([0x0u32; 8]), DummyStruct([0x0u32; 8])],
|
||||
conf2.value()
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn vec() {
|
||||
let mut conf = Confidential::new(vec![17; 42]);
|
||||
conf.zeroize();
|
||||
assert_eq!(&[0; 42], conf.value().as_slice());
|
||||
|
||||
let mut conf2 =
|
||||
Confidential::new(vec![DummyStruct([0x12u32; 8]), DummyStruct([0x24u32; 8])]);
|
||||
assert_eq!(
|
||||
&[DummyStruct([0x12u32; 8]), DummyStruct([0x24u32; 8])],
|
||||
conf2.value().as_slice()
|
||||
);
|
||||
conf2.zeroize();
|
||||
assert_eq!(
|
||||
&[DummyStruct([0x0u32; 8]), DummyStruct([0x0u32; 8])],
|
||||
conf2.value().as_slice()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user