Merge "Revert "Keystore 2.0: Add CREATE_DATETIME unconditionally.""
diff --git a/keystore2/src/crypto/error.rs b/keystore2/src/crypto/error.rs
index a369012..c6476f9 100644
--- a/keystore2/src/crypto/error.rs
+++ b/keystore2/src/crypto/error.rs
@@ -13,6 +13,7 @@
 // limitations under the License.
 
 //! This module implements Error for the keystore2_crypto library.
+use crate::zvec;
 
 /// Crypto specific error codes.
 #[derive(Debug, thiserror::Error, Eq, PartialEq)]
@@ -93,4 +94,8 @@
     /// This is returned if the C implementation of extractSubjectFromCertificate failed.
     #[error("Failed to extract certificate subject.")]
     ExtractSubjectFailed,
+
+    /// Zvec error.
+    #[error(transparent)]
+    ZVec(#[from] zvec::Error),
 }
diff --git a/keystore2/src/crypto/lib.rs b/keystore2/src/crypto/lib.rs
index 5f8a2ef..92da965 100644
--- a/keystore2/src/crypto/lib.rs
+++ b/keystore2/src/crypto/lib.rs
@@ -16,7 +16,7 @@
 //! Keystore 2.0.
 
 mod error;
-mod zvec;
+pub mod zvec;
 pub use error::Error;
 use keystore2_crypto_bindgen::{
     extractSubjectFromCertificate, generateKeyFromPassword, randomBytes, AES_gcm_decrypt,
diff --git a/keystore2/src/crypto/zvec.rs b/keystore2/src/crypto/zvec.rs
index 78b474e..5a173c3 100644
--- a/keystore2/src/crypto/zvec.rs
+++ b/keystore2/src/crypto/zvec.rs
@@ -12,7 +12,9 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-use crate::error::Error;
+//! Implements ZVec, a vector that is mlocked during its lifetime and zeroed
+//! when dropped.
+
 use nix::sys::mman::{mlock, munlock};
 use std::convert::TryFrom;
 use std::fmt;
@@ -29,6 +31,14 @@
     len: usize,
 }
 
+/// ZVec specific error codes.
+#[derive(Debug, thiserror::Error, Eq, PartialEq)]
+pub enum Error {
+    /// Underlying libc error.
+    #[error(transparent)]
+    NixError(#[from] nix::Error),
+}
+
 impl ZVec {
     /// Create a ZVec with the given size.
     pub fn new(size: usize) -> Result<Self, Error> {
@@ -48,6 +58,14 @@
             self.len = len;
         }
     }
+
+    /// Attempts to make a clone of the Zvec. This may fail due trying to mlock
+    /// the new memory region.
+    pub fn try_clone(&self) -> Result<Self, Error> {
+        let mut result = Self::new(self.len())?;
+        result[..].copy_from_slice(&self[..]);
+        Ok(result)
+    }
 }
 
 impl Drop for ZVec {