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 })
     }
 }