//! Implementation of the `KeyValueStore` trait using Trusty secure storage. //! //! Store each secret in a file of its own (mapping the secret ID to the filename) as there are not //! expected to be many extant secrets. However, use a prefix for the filename to allow easier //! migration to a different scheme in future if this assumption changes.
use alloc::string::String; use secretkeeper_comm::data_types::error::Error; use secretkeeper_core::store::KeyValueStore; use storage::{OpenMode, Port, Session};
/// Store each secret in a file named "v1_<hex>", using the hex representation of the key/secret ID. /// Note that IDs are not confidential, so can appear in logs. const PREFIX_V1: &str = "v1_";
/// Generate the filename corresponding to a key. fn filename(key: &[u8]) -> String { letmut result = String::with_capacity(PREFIX_V1.len() + 2 * key.len());
result += PREFIX_V1; for byte in key {
result += &format!("{byte:02x}");
}
result
}
/// Create a storage session. fn create_session() -> Result<Session, Error> { // Use TD storage, which means that: // - storage is only available after Android has booted // - storage is wiped on factory reset // - size of stored data isn't problematic
Session::new(Port::TamperDetect, /* wait_for_port= */ true)
.map_err(|e| ss_err!(e, "Couldn't create storage session"))
}
/// An implementation of `KeyValueStore` backed by secure storage. #[derive(Default)] pubstruct SecureStore;
// This will overwrite the value if key is already present. letmut file = session
.open_file(&filename, OpenMode::Create)
.map_err(|e| ss_err!(e, "Couldn't create file '{filename}'"))?;
session.write_all(&mut file, val).map_err(|e| ss_err!(e, "Failed to write data"))?;
Ok(())
}
fn get(&self, key: &[u8]) -> Result<Option<Vec<u8>>, Error> { let filename = filename(key); letmut session = create_session()?; let file = match session.open_file(&filename, OpenMode::Open) {
Ok(f) => f,
Err(storage::Error::Code(trusty_sys::Error::NotFound)) => return Ok(None),
Err(e) => return Err(ss_err!(e, "Failed to open file '{filename}'")),
}; let size = session
.get_size(&file)
.map_err(|e| ss_err!(e, "Failed to get size for '{filename}'"))?; letmut buffer = vec![0; size]; let content = session
.read_all(&file, buffer.as_mut_slice())
.map_err(|e| ss_err!(e, "Failed to read '{filename}'"))?; let total_size = content.len();
buffer.resize(total_size, 0);
Ok(Some(buffer))
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.