Add more crypto operations.
Test: keystore2_crypto_test_rust
Change-Id: Ice2facdc1b41f4e4ece839c2a3b956889e813960
diff --git a/keystore2/src/crypto/zvec.rs b/keystore2/src/crypto/zvec.rs
index 52addfc..e75e1dc 100644
--- a/keystore2/src/crypto/zvec.rs
+++ b/keystore2/src/crypto/zvec.rs
@@ -21,10 +21,15 @@
use std::ops::{Deref, DerefMut};
use std::ptr::write_volatile;
-/// A fixed size u8 vector that is zeroed when dropped. Also the data is
-/// pinned in memory with mlock.
+/// A semi fixed size u8 vector that is zeroed when dropped. It can shrink in
+/// size but cannot grow larger than the original size (and if it shrinks it
+/// still owns the entire buffer). Also the data is pinned in memory with
+/// mlock.
#[derive(Default, Eq, PartialEq)]
-pub struct ZVec(Box<[u8]>);
+pub struct ZVec {
+ elems: Box<[u8]>,
+ len: usize,
+}
impl ZVec {
/// Create a ZVec with the given size.
@@ -34,18 +39,27 @@
if size > 0 {
unsafe { mlock(b.as_ptr() as *const std::ffi::c_void, b.len()) }?;
}
- Ok(Self(b))
+ Ok(Self { elems: b, len: size })
+ }
+
+ /// Reduce the length to the given value. Does nothing if that length is
+ /// greater than the length of the vector. Note that it still owns the
+ /// original allocation even if the length is reduced.
+ pub fn reduce_len(&mut self, len: usize) {
+ if len <= self.elems.len() {
+ self.len = len;
+ }
}
}
impl Drop for ZVec {
fn drop(&mut self) {
- for i in 0..self.0.len() {
- unsafe { write_volatile(self.0.as_mut_ptr().add(i), 0) };
+ for i in 0..self.elems.len() {
+ unsafe { write_volatile(self.elems.as_mut_ptr().add(i), 0) };
}
- if !self.0.is_empty() {
+ if !self.elems.is_empty() {
if let Err(e) =
- unsafe { munlock(self.0.as_ptr() as *const std::ffi::c_void, self.0.len()) }
+ unsafe { munlock(self.elems.as_ptr() as *const std::ffi::c_void, self.elems.len()) }
{
log::error!("In ZVec::drop: `munlock` failed: {:?}.", e);
}
@@ -57,22 +71,22 @@
type Target = [u8];
fn deref(&self) -> &Self::Target {
- &self.0
+ &self.elems[0..self.len]
}
}
impl DerefMut for ZVec {
fn deref_mut(&mut self) -> &mut Self::Target {
- &mut self.0
+ &mut self.elems[0..self.len]
}
}
impl fmt::Debug for ZVec {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- if self.0.is_empty() {
+ if self.elems.is_empty() {
write!(f, "Zvec empty")
} else {
- write!(f, "Zvec size: {} [ Sensitive information redacted ]", self.0.len())
+ write!(f, "Zvec size: {} [ Sensitive information redacted ]", self.len)
}
}
}
@@ -97,6 +111,7 @@
if !b.is_empty() {
unsafe { mlock(b.as_ptr() as *const std::ffi::c_void, b.len()) }?;
}
- Ok(Self(b))
+ let len = b.len();
+ Ok(Self { elems: b, len })
}
}