mirror of
https://github.com/AmbiML/sparrow-kata-full.git
synced 2025-08-19 13:46:54 +00:00
Merge "Add StorageManager skeleton."
GitOrigin-RevId: e776e3c357ca54ad3b74212176da8a4ebc16b372
This commit is contained in:
parent
66c03e7858
commit
bf19c88ccf
@ -67,6 +67,18 @@ DeclareCAmkESComponent(SecurityCoordinator
|
|||||||
INCLUDES interfaces
|
INCLUDES interfaces
|
||||||
)
|
)
|
||||||
|
|
||||||
|
RustAddLibrary(
|
||||||
|
kata_storage_manager
|
||||||
|
SOURCE_DIR ${CMAKE_CURRENT_LIST_DIR}/components/StorageManager
|
||||||
|
TARGET "riscv32imc-unknown-none-elf"
|
||||||
|
LIB_FILENAME libkata_storage_manager.a
|
||||||
|
)
|
||||||
|
|
||||||
|
DeclareCAmkESComponent(StorageManager
|
||||||
|
LIBS kata_storage_manager
|
||||||
|
INCLUDES interfaces
|
||||||
|
)
|
||||||
|
|
||||||
DeclareCAmkESComponent(LogFibonacci
|
DeclareCAmkESComponent(LogFibonacci
|
||||||
SOURCES
|
SOURCES
|
||||||
components/LogFibonacci/src/main.c
|
components/LogFibonacci/src/main.c
|
||||||
|
@ -4,6 +4,7 @@ import <PackageManagementInterface.camkes>;
|
|||||||
import <MlCoordinatorInterface.camkes>;
|
import <MlCoordinatorInterface.camkes>;
|
||||||
import <SecurityCoordinatorInterface.camkes>;
|
import <SecurityCoordinatorInterface.camkes>;
|
||||||
import <SeL4DebugInterface.camkes>;
|
import <SeL4DebugInterface.camkes>;
|
||||||
|
import <StorageInterface.camkes>;
|
||||||
|
|
||||||
component DebugConsole {
|
component DebugConsole {
|
||||||
control;
|
control;
|
||||||
@ -19,8 +20,10 @@ component DebugConsole {
|
|||||||
provides LoggerInterface logger;
|
provides LoggerInterface logger;
|
||||||
uses ProcessControlInterface proc_ctrl;
|
uses ProcessControlInterface proc_ctrl;
|
||||||
uses PackageManagementInterface pkg_mgmt;
|
uses PackageManagementInterface pkg_mgmt;
|
||||||
// TODO(sleffler): for debugging
|
// TODO(b/200707300): for debugging
|
||||||
uses SecurityCoordinatorInterface security;
|
uses SecurityCoordinatorInterface security;
|
||||||
|
// TODO(b/200707300): for debugging
|
||||||
|
uses StorageInterface storage;
|
||||||
uses SeL4DebugInterface sel4debug;
|
uses SeL4DebugInterface sel4debug;
|
||||||
uses MlCoordinatorInterface mlcoord;
|
uses MlCoordinatorInterface mlcoord;
|
||||||
}
|
}
|
||||||
|
@ -10,5 +10,6 @@ kata-io = { path = "../kata-io" }
|
|||||||
kata-line-reader = { path = "../kata-line-reader" }
|
kata-line-reader = { path = "../kata-line-reader" }
|
||||||
kata-proc-common = { path = "../../ProcessManager/kata-proc-common" }
|
kata-proc-common = { path = "../../ProcessManager/kata-proc-common" }
|
||||||
kata-security-common = { path = "../../SecurityCoordinator/kata-security-common" }
|
kata-security-common = { path = "../../SecurityCoordinator/kata-security-common" }
|
||||||
|
kata-storage-interface = { path = "../../StorageManager/kata-storage-interface" }
|
||||||
log = "0.4"
|
log = "0.4"
|
||||||
postcard = { version = "0.7", features = ["alloc"] }
|
postcard = { version = "0.7", features = ["alloc"] }
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
extern crate alloc;
|
extern crate alloc;
|
||||||
use alloc::string::String;
|
use alloc::string::String;
|
||||||
|
use alloc::vec::Vec;
|
||||||
use core::fmt;
|
use core::fmt;
|
||||||
use core::fmt::Write;
|
use core::fmt::Write;
|
||||||
use cstr_core::CString;
|
use cstr_core::CString;
|
||||||
@ -10,6 +11,9 @@ use postcard;
|
|||||||
use kata_io as io;
|
use kata_io as io;
|
||||||
use kata_line_reader::LineReader;
|
use kata_line_reader::LineReader;
|
||||||
use kata_proc_common::{BundleIdArray, ProcessManagerError, RAW_BUNDLE_ID_DATA_SIZE};
|
use kata_proc_common::{BundleIdArray, ProcessManagerError, RAW_BUNDLE_ID_DATA_SIZE};
|
||||||
|
use kata_storage_interface::kata_storage_delete;
|
||||||
|
use kata_storage_interface::kata_storage_read;
|
||||||
|
use kata_storage_interface::kata_storage_write;
|
||||||
|
|
||||||
/// Error type indicating why a command line is not runnable.
|
/// Error type indicating why a command line is not runnable.
|
||||||
enum CommandError {
|
enum CommandError {
|
||||||
@ -79,6 +83,9 @@ fn dispatch_command(cmdline: &str, output: &mut dyn io::Write) {
|
|||||||
"echo" => echo_command(cmdline, output),
|
"echo" => echo_command(cmdline, output),
|
||||||
"clear" => clear_command(output),
|
"clear" => clear_command(output),
|
||||||
"bundles" => bundles_command(output),
|
"bundles" => bundles_command(output),
|
||||||
|
"kvdelete" => kvdelete_command(&mut args, output),
|
||||||
|
"kvread" => kvread_command(&mut args, output),
|
||||||
|
"kvwrite" => kvwrite_command(&mut args, output),
|
||||||
"install" => install_command(&mut args, output),
|
"install" => install_command(&mut args, output),
|
||||||
"loglevel" => loglevel_command(&mut args, output),
|
"loglevel" => loglevel_command(&mut args, output),
|
||||||
"ps" => ps_command(),
|
"ps" => ps_command(),
|
||||||
@ -123,14 +130,7 @@ fn scecho_command(cmdline: &str, output: &mut dyn io::Write) -> Result<(), Comma
|
|||||||
use kata_security_common::*;
|
use kata_security_common::*;
|
||||||
let (_, request) = cmdline.split_at(7); // 'scecho'
|
let (_, request) = cmdline.split_at(7); // 'scecho'
|
||||||
let reply = &mut [0u8; SECURITY_REPLY_DATA_SIZE];
|
let reply = &mut [0u8; SECURITY_REPLY_DATA_SIZE];
|
||||||
match unsafe {
|
match kata_security_request(SecurityRequest::SrEcho, request.as_bytes(), reply) {
|
||||||
security_request(
|
|
||||||
SecurityRequest::SrEcho,
|
|
||||||
request.len() as u32,
|
|
||||||
request.as_ptr(),
|
|
||||||
reply as *mut _,
|
|
||||||
)
|
|
||||||
} {
|
|
||||||
SecurityRequestError::SreSuccess => {
|
SecurityRequestError::SreSuccess => {
|
||||||
writeln!(
|
writeln!(
|
||||||
output,
|
output,
|
||||||
@ -331,11 +331,69 @@ fn stop_command(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn kvdelete_command(
|
||||||
|
args: &mut dyn Iterator<Item = &str>,
|
||||||
|
output: &mut dyn io::Write,
|
||||||
|
) -> Result<(), CommandError> {
|
||||||
|
if let Some(key) = args.nth(0) {
|
||||||
|
match kata_storage_delete(key) {
|
||||||
|
Ok(_) => {
|
||||||
|
writeln!(output, "Delete key \"{}\".", key)?;
|
||||||
|
}
|
||||||
|
Err(status) => {
|
||||||
|
writeln!(output, "Delete key \"{}\" failed: {:?}", key, status)?;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
} else {
|
||||||
|
Err(CommandError::BadArgs)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn kvread_command(
|
||||||
|
args: &mut dyn Iterator<Item = &str>,
|
||||||
|
output: &mut dyn io::Write,
|
||||||
|
) -> Result<(), CommandError> {
|
||||||
|
if let Some(key) = args.nth(0) {
|
||||||
|
match kata_storage_read(key) {
|
||||||
|
Ok(value) => {
|
||||||
|
writeln!(output, "Read key \"{}\" = {:?}.", key, value)?;
|
||||||
|
}
|
||||||
|
Err(status) => {
|
||||||
|
writeln!(output, "Read key \"{}\" failed: {:?}", key, status)?;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
} else {
|
||||||
|
Err(CommandError::BadArgs)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn kvwrite_command(
|
||||||
|
args: &mut dyn Iterator<Item = &str>,
|
||||||
|
output: &mut dyn io::Write,
|
||||||
|
) -> Result<(), CommandError> {
|
||||||
|
if let Some(key) = args.nth(0) {
|
||||||
|
let value = args.collect::<Vec<&str>>().join(" ");
|
||||||
|
match kata_storage_write(key, value.as_bytes()) {
|
||||||
|
Ok(_) => {
|
||||||
|
writeln!(output, "Write key \"{}\" = {:?}.", key, value)?;
|
||||||
|
}
|
||||||
|
Err(status) => {
|
||||||
|
writeln!(output, "Write key \"{}\" failed: {:?}", key, status)?;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
} else {
|
||||||
|
Err(CommandError::BadArgs)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Implements a command that tests facilities that use the global allocator.
|
/// Implements a command that tests facilities that use the global allocator.
|
||||||
/// Shamelessly cribbed from https://os.phil-opp.com/heap-allocation/
|
/// Shamelessly cribbed from https://os.phil-opp.com/heap-allocation/
|
||||||
fn test_alloc_command(output: &mut dyn io::Write) -> Result<(), CommandError> {
|
fn test_alloc_command(output: &mut dyn io::Write) -> Result<(), CommandError> {
|
||||||
extern crate alloc;
|
extern crate alloc;
|
||||||
use alloc::{boxed::Box, rc::Rc, vec, vec::Vec};
|
use alloc::{boxed::Box, rc::Rc, vec};
|
||||||
|
|
||||||
// allocate a number on the heap
|
// allocate a number on the heap
|
||||||
let heap_value = Box::new(41);
|
let heap_value = Box::new(41);
|
||||||
@ -370,9 +428,6 @@ fn test_alloc_command(output: &mut dyn io::Write) -> Result<(), CommandError> {
|
|||||||
|
|
||||||
/// Implements a command that tests the global allocator error handling.
|
/// Implements a command that tests the global allocator error handling.
|
||||||
fn test_alloc_error_command(output: &mut dyn io::Write) -> Result<(), CommandError> {
|
fn test_alloc_error_command(output: &mut dyn io::Write) -> Result<(), CommandError> {
|
||||||
extern crate alloc;
|
|
||||||
use alloc::vec::Vec;
|
|
||||||
|
|
||||||
// Default heap holds 16KB.
|
// Default heap holds 16KB.
|
||||||
let mut vec = Vec::with_capacity(16384);
|
let mut vec = Vec::with_capacity(16384);
|
||||||
for i in 0..16348 {
|
for i in 0..16348 {
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
|
|
||||||
extern crate alloc;
|
extern crate alloc;
|
||||||
use alloc::string::String;
|
use alloc::string::String;
|
||||||
|
use core::slice;
|
||||||
use kata_proc_common::*;
|
use kata_proc_common::*;
|
||||||
use kata_security_common::*;
|
use kata_security_common::*;
|
||||||
use log::trace;
|
use log::trace;
|
||||||
@ -89,14 +90,11 @@ impl ProcessManagerInterface for KataManagerInterface {
|
|||||||
|
|
||||||
// This is handled by the SecurityCoordinator.
|
// This is handled by the SecurityCoordinator.
|
||||||
let reply = &mut [0u8; SECURITY_REPLY_DATA_SIZE];
|
let reply = &mut [0u8; SECURITY_REPLY_DATA_SIZE];
|
||||||
match unsafe {
|
match kata_security_request(
|
||||||
security_request(
|
SecurityRequest::SrInstall,
|
||||||
SecurityRequest::SrInstall,
|
unsafe { slice::from_raw_parts(pkg_buffer, pkg_buffer_size as usize) },
|
||||||
pkg_buffer_size,
|
reply,
|
||||||
pkg_buffer,
|
) {
|
||||||
reply as *mut _,
|
|
||||||
)
|
|
||||||
} {
|
|
||||||
SecurityRequestError::SreSuccess => {
|
SecurityRequestError::SreSuccess => {
|
||||||
fn deserialize_failure(e: postcard::Error) -> ProcessManagerError {
|
fn deserialize_failure(e: postcard::Error) -> ProcessManagerError {
|
||||||
trace!("install failed: deserialize {:?}", e);
|
trace!("install failed: deserialize {:?}", e);
|
||||||
@ -123,14 +121,7 @@ impl ProcessManagerInterface for KataManagerInterface {
|
|||||||
let mut request_data = [0u8; SECURITY_REQUEST_DATA_SIZE];
|
let mut request_data = [0u8; SECURITY_REQUEST_DATA_SIZE];
|
||||||
let _ = postcard::to_slice(&bundle_id, &mut request_data).map_err(serialize_failure)?;
|
let _ = postcard::to_slice(&bundle_id, &mut request_data).map_err(serialize_failure)?;
|
||||||
let reply = &mut [0u8; SECURITY_REPLY_DATA_SIZE];
|
let reply = &mut [0u8; SECURITY_REPLY_DATA_SIZE];
|
||||||
match unsafe {
|
match kata_security_request(SecurityRequest::SrUninstall, &request_data, reply) {
|
||||||
security_request(
|
|
||||||
SecurityRequest::SrUninstall,
|
|
||||||
request_data.len() as u32,
|
|
||||||
request_data.as_ptr(),
|
|
||||||
reply as *mut _,
|
|
||||||
)
|
|
||||||
} {
|
|
||||||
SecurityRequestError::SreSuccess => Ok(()),
|
SecurityRequestError::SreSuccess => Ok(()),
|
||||||
status => {
|
status => {
|
||||||
trace!("uninstall failed: {:?}", status);
|
trace!("uninstall failed: {:?}", status);
|
||||||
@ -139,7 +130,7 @@ impl ProcessManagerInterface for KataManagerInterface {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn start(&mut self, _bundle: &Bundle) -> Result<(), ProcessManagerError> {
|
fn start(&mut self, _bundle: &Bundle) -> Result<(), ProcessManagerError> {
|
||||||
// 1. Ask security core for application footprint with SizeBuffer
|
// 1. Ask security core for application footprint with SizeBuffer
|
||||||
// 2. Ask security core for manifest (maybe piggyback on SizeBuffer)
|
// 2. Ask security core for manifest (maybe piggyback on SizeBuffer)
|
||||||
// and parse for necessary info (e.g. whether kv Storage is
|
// and parse for necessary info (e.g. whether kv Storage is
|
||||||
// required, other privileges/capabilities)
|
// required, other privileges/capabilities)
|
||||||
|
@ -45,6 +45,8 @@ mod mut_ptr_helper {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO(sleffler): convert String to &str
|
||||||
|
|
||||||
// NB: SecurityRequestInstall is handled specially.
|
// NB: SecurityRequestInstall is handled specially.
|
||||||
|
|
||||||
// SecurityRequestUninstall
|
// SecurityRequestUninstall
|
||||||
@ -145,8 +147,8 @@ pub enum SecurityRequest {
|
|||||||
SrInstall, // Install package [pkg_buffer] -> bundle_id
|
SrInstall, // Install package [pkg_buffer] -> bundle_id
|
||||||
SrUninstall, // Uninstall package [bundle_id]
|
SrUninstall, // Uninstall package [bundle_id]
|
||||||
|
|
||||||
SrSizeBuffer, // Size application image [bundle_id] -> u32
|
SrSizeBuffer, // Size application image [bundle_id] -> u32
|
||||||
SrGetManifest, // Return application manifest [bundle_id] -> String
|
SrGetManifest, // Return application manifest [bundle_id] -> String
|
||||||
SrLoadApplication, // Load application [bundle_id]
|
SrLoadApplication, // Load application [bundle_id]
|
||||||
// TODO(sleffler): define <tag>?
|
// TODO(sleffler): define <tag>?
|
||||||
SrLoadModel, // Load ML model [bundle_id, <tag>]
|
SrLoadModel, // Load ML model [bundle_id, <tag>]
|
||||||
@ -166,14 +168,29 @@ pub trait SecurityCoordinatorInterface {
|
|||||||
) -> Result<(), SecurityRequestError>;
|
) -> Result<(), SecurityRequestError>;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Camkes-generated rpc api.
|
// TODO(sleffler): try kata_security_request<T> to lower serde work
|
||||||
// NB: this requires the SecurityCoordinator component be named "security".
|
#[inline]
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
extern "C" {
|
pub fn kata_security_request(
|
||||||
pub fn security_request(
|
request: SecurityRequest,
|
||||||
c_request: SecurityRequest,
|
request_buffer: &[u8],
|
||||||
c_request_buffer_len: u32,
|
reply_buffer: &mut SecurityReplyData,
|
||||||
c_request_buffer: *const u8,
|
) -> SecurityRequestError {
|
||||||
c_reply_buffer: *mut SecurityReplyData,
|
// NB: this assumes the SecurityCoordinator component is named "security".
|
||||||
) -> SecurityRequestError;
|
extern "C" {
|
||||||
|
pub fn security_request(
|
||||||
|
c_request: SecurityRequest,
|
||||||
|
c_request_buffer_len: u32,
|
||||||
|
c_request_buffer: *const u8,
|
||||||
|
c_reply_buffer: *mut SecurityReplyData,
|
||||||
|
) -> SecurityRequestError;
|
||||||
|
}
|
||||||
|
unsafe {
|
||||||
|
security_request(
|
||||||
|
request,
|
||||||
|
request_buffer.len() as u32,
|
||||||
|
request_buffer.as_ptr(),
|
||||||
|
reply_buffer as *mut _,
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -9,6 +9,8 @@ fake = []
|
|||||||
sel4 = []
|
sel4 = []
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
hashbrown = { version = "0.11", features = ["ahash-compile-time-rng"] }
|
||||||
kata-security-common = { path = "../kata-security-common" }
|
kata-security-common = { path = "../kata-security-common" }
|
||||||
|
kata-storage-interface = { path = "../../StorageManager/kata-storage-interface" }
|
||||||
log = "0.4"
|
log = "0.4"
|
||||||
postcard = "0.7"
|
postcard = "0.7"
|
||||||
|
@ -1,22 +1,69 @@
|
|||||||
//! Kata OS security coordinator fake support
|
//! Kata OS security coordinator fake support
|
||||||
|
|
||||||
extern crate alloc;
|
extern crate alloc;
|
||||||
use alloc::string::ToString;
|
use alloc::string::{String, ToString};
|
||||||
|
use hashbrown::HashMap;
|
||||||
use kata_security_common::*;
|
use kata_security_common::*;
|
||||||
|
use kata_storage_interface::{KeyValueData, KEY_VALUE_DATA_SIZE};
|
||||||
use log::trace;
|
use log::trace;
|
||||||
use postcard;
|
use postcard;
|
||||||
|
|
||||||
pub struct FakeSecurityCoordinatorInterface {
|
struct BundleData {
|
||||||
// TODO(sleffler): mailbox ipc state
|
pkg_size: usize,
|
||||||
|
manifest: String,
|
||||||
|
keys: HashMap<String, KeyValueData>,
|
||||||
}
|
}
|
||||||
impl FakeSecurityCoordinatorInterface {
|
impl BundleData {
|
||||||
pub fn new() -> Self {
|
fn new(pkg_size: usize) -> Self {
|
||||||
FakeSecurityCoordinatorInterface {}
|
BundleData {
|
||||||
|
pkg_size: pkg_size,
|
||||||
|
manifest: String::from(
|
||||||
|
"# Comments like this
|
||||||
|
[Manifest]
|
||||||
|
BundleId=com.google.cerebra.hw.HelloWorld
|
||||||
|
|
||||||
|
[Binaries]
|
||||||
|
App=HelloWorldBin
|
||||||
|
Model=NeuralNetworkName
|
||||||
|
|
||||||
|
[Storage]
|
||||||
|
Required=1
|
||||||
|
",
|
||||||
|
),
|
||||||
|
keys: HashMap::with_capacity(2),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub type KataSecurityCoordinatorInterface = FakeSecurityCoordinatorInterface;
|
|
||||||
|
|
||||||
impl SecurityCoordinatorInterface for FakeSecurityCoordinatorInterface {
|
pub struct FakeSecurityCoordinator {
|
||||||
|
bundles: HashMap<String, BundleData>,
|
||||||
|
}
|
||||||
|
impl FakeSecurityCoordinator {
|
||||||
|
pub fn new() -> Self {
|
||||||
|
FakeSecurityCoordinator {
|
||||||
|
bundles: HashMap::with_capacity(2),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_bundle(&self, bundle_id: &str) -> Result<&BundleData, SecurityRequestError> {
|
||||||
|
self.bundles
|
||||||
|
.get(bundle_id)
|
||||||
|
.map_or_else(|| Err(SecurityRequestError::SreBundleNotFound), |v| Ok(v))
|
||||||
|
}
|
||||||
|
fn get_bundle_mut(&mut self, bundle_id: &str) -> Result<&mut BundleData, SecurityRequestError> {
|
||||||
|
self.bundles
|
||||||
|
.get_mut(bundle_id)
|
||||||
|
.map_or_else(|| Err(SecurityRequestError::SreBundleNotFound), |v| Ok(v))
|
||||||
|
}
|
||||||
|
fn remove_bundle(&mut self, bundle_id: &str) -> Result<(), SecurityRequestError> {
|
||||||
|
self.bundles
|
||||||
|
.remove(bundle_id)
|
||||||
|
.map_or_else(|| Err(SecurityRequestError::SreBundleNotFound), |_v| Ok(()))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pub type KataSecurityCoordinatorInterface = FakeSecurityCoordinator;
|
||||||
|
|
||||||
|
impl SecurityCoordinatorInterface for FakeSecurityCoordinator {
|
||||||
fn request(
|
fn request(
|
||||||
&mut self,
|
&mut self,
|
||||||
request_id: SecurityRequest,
|
request_id: SecurityRequest,
|
||||||
@ -47,25 +94,29 @@ impl SecurityCoordinatorInterface for FakeSecurityCoordinatorInterface {
|
|||||||
request_buffer.as_ptr(),
|
request_buffer.as_ptr(),
|
||||||
request_buffer.len()
|
request_buffer.len()
|
||||||
);
|
);
|
||||||
let _ = postcard::to_slice(
|
// let bundle_id = (request_buffer.as_ptr() as usize).to_string();
|
||||||
&(request_buffer.as_ptr() as usize).to_string(),
|
// TODO(sleffler): used by kata-storage-component for kvops
|
||||||
reply_buffer,
|
let bundle_id = "fubar".to_string();
|
||||||
)
|
let _ = postcard::to_slice(&bundle_id, reply_buffer).map_err(serialize_failure)?;
|
||||||
.map_err(serialize_failure)?;
|
assert!(self
|
||||||
|
.bundles
|
||||||
|
.insert(bundle_id, BundleData::new(request_buffer.len()))
|
||||||
|
.is_none());
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
SecurityRequest::SrUninstall => {
|
SecurityRequest::SrUninstall => {
|
||||||
let request = postcard::from_bytes::<UninstallRequest>(&request_buffer[..])
|
let request = postcard::from_bytes::<UninstallRequest>(&request_buffer[..])
|
||||||
.map_err(deserialize_failure)?;
|
.map_err(deserialize_failure)?;
|
||||||
trace!("UNINSTALL {}", request.bundle_id);
|
trace!("UNINSTALL {}", request.bundle_id);
|
||||||
Ok(())
|
self.remove_bundle(&request.bundle_id)
|
||||||
}
|
}
|
||||||
SecurityRequest::SrSizeBuffer => {
|
SecurityRequest::SrSizeBuffer => {
|
||||||
let request = postcard::from_bytes::<SizeBufferRequest>(&request_buffer[..])
|
let request = postcard::from_bytes::<SizeBufferRequest>(&request_buffer[..])
|
||||||
.map_err(deserialize_failure)?;
|
.map_err(deserialize_failure)?;
|
||||||
trace!("SIZE BUFFER bundle_id {}", request.bundle_id);
|
trace!("SIZE BUFFER bundle_id {}", request.bundle_id);
|
||||||
|
let bundle = self.get_bundle(&request.bundle_id)?;
|
||||||
let _ = postcard::to_slice(
|
let _ = postcard::to_slice(
|
||||||
&0u32, // TODO(sleffler): fill-in
|
&bundle.pkg_size, // TODO(sleffler): do better
|
||||||
reply_buffer,
|
reply_buffer,
|
||||||
)
|
)
|
||||||
.map_err(serialize_failure)?;
|
.map_err(serialize_failure)?;
|
||||||
@ -75,21 +126,9 @@ impl SecurityCoordinatorInterface for FakeSecurityCoordinatorInterface {
|
|||||||
let request = postcard::from_bytes::<SizeBufferRequest>(&request_buffer[..])
|
let request = postcard::from_bytes::<SizeBufferRequest>(&request_buffer[..])
|
||||||
.map_err(deserialize_failure)?;
|
.map_err(deserialize_failure)?;
|
||||||
trace!("GET MANIFEST bundle_id {}", request.bundle_id);
|
trace!("GET MANIFEST bundle_id {}", request.bundle_id);
|
||||||
let _ = postcard::to_slice(
|
let bundle = self.get_bundle(&request.bundle_id)?;
|
||||||
"# Comments like this
|
let _ = postcard::to_slice(&bundle.manifest, reply_buffer)
|
||||||
[Manifest]
|
.map_err(serialize_failure)?;
|
||||||
BundleId=com.google.cerebra.hw.HelloWorld
|
|
||||||
|
|
||||||
[Binaries]
|
|
||||||
App=HelloWorldBin
|
|
||||||
Model=NeuralNetworkName
|
|
||||||
|
|
||||||
[Storage]
|
|
||||||
Required=1
|
|
||||||
", // TODO(sleffler): fill-in
|
|
||||||
reply_buffer,
|
|
||||||
)
|
|
||||||
.map_err(serialize_failure)?;
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
SecurityRequest::SrLoadApplication => {
|
SecurityRequest::SrLoadApplication => {
|
||||||
@ -100,6 +139,7 @@ impl SecurityCoordinatorInterface for FakeSecurityCoordinatorInterface {
|
|||||||
request.bundle_id,
|
request.bundle_id,
|
||||||
request.app_binary
|
request.app_binary
|
||||||
);
|
);
|
||||||
|
let _ = self.get_bundle(&request.bundle_id)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
SecurityRequest::SrLoadModel => {
|
SecurityRequest::SrLoadModel => {
|
||||||
@ -111,6 +151,8 @@ impl SecurityCoordinatorInterface for FakeSecurityCoordinatorInterface {
|
|||||||
request.model_id,
|
request.model_id,
|
||||||
request.model_binary
|
request.model_binary
|
||||||
);
|
);
|
||||||
|
// TODO(sleffler): check model id
|
||||||
|
let _ = self.get_bundle(&request.bundle_id)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
SecurityRequest::SrReadKey => {
|
SecurityRequest::SrReadKey => {
|
||||||
@ -121,8 +163,15 @@ impl SecurityCoordinatorInterface for FakeSecurityCoordinatorInterface {
|
|||||||
request.bundle_id,
|
request.bundle_id,
|
||||||
request.key,
|
request.key,
|
||||||
);
|
);
|
||||||
// TODO(sleffler): fill-in
|
let bundle = self.get_bundle(&request.bundle_id)?;
|
||||||
Err(SreReadFailed)
|
match bundle.keys.get(&request.key) {
|
||||||
|
Some(value) => {
|
||||||
|
// TODO(sleffler): return values are fixed size unless we serialize
|
||||||
|
reply_buffer[..value.len()].copy_from_slice(&value[..]);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
None => Err(SreKeyNotFound),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
SecurityRequest::SrWriteKey => {
|
SecurityRequest::SrWriteKey => {
|
||||||
let request = postcard::from_bytes::<WriteKeyRequest>(&request_buffer[..])
|
let request = postcard::from_bytes::<WriteKeyRequest>(&request_buffer[..])
|
||||||
@ -133,8 +182,12 @@ impl SecurityCoordinatorInterface for FakeSecurityCoordinatorInterface {
|
|||||||
request.key,
|
request.key,
|
||||||
request.value,
|
request.value,
|
||||||
);
|
);
|
||||||
// TODO(sleffler): fill-in
|
let bundle = self.get_bundle_mut(&request.bundle_id)?;
|
||||||
Err(SreWriteFailed)
|
// TODO(sleffler): optimnize with entry
|
||||||
|
let mut value = [0u8; KEY_VALUE_DATA_SIZE];
|
||||||
|
value[..request.value.len()].copy_from_slice(request.value);
|
||||||
|
let _ = bundle.keys.insert(request.key, value);
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
SecurityRequest::SrDeleteKey => {
|
SecurityRequest::SrDeleteKey => {
|
||||||
let request = postcard::from_bytes::<DeleteKeyRequest>(&request_buffer[..])
|
let request = postcard::from_bytes::<DeleteKeyRequest>(&request_buffer[..])
|
||||||
@ -144,8 +197,10 @@ impl SecurityCoordinatorInterface for FakeSecurityCoordinatorInterface {
|
|||||||
request.bundle_id,
|
request.bundle_id,
|
||||||
request.key,
|
request.key,
|
||||||
);
|
);
|
||||||
// TODO(sleffler): fill-in
|
let bundle = self.get_bundle_mut(&request.bundle_id)?;
|
||||||
Err(SreDeleteFailed)
|
// TODO(sleffler): error if no entry?
|
||||||
|
let _ = bundle.keys.remove(&request.key);
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,17 +5,17 @@ use kata_security_common::*;
|
|||||||
use log::trace;
|
use log::trace;
|
||||||
use postcard;
|
use postcard;
|
||||||
|
|
||||||
pub struct SeL4SecurityCoordinatorInterface {
|
pub struct SeL4SecurityCoordinator {
|
||||||
// TODO(sleffler): mailbox ipc state
|
// TODO(sleffler): mailbox ipc state
|
||||||
}
|
}
|
||||||
impl SeL4SecurityCoordinatorInterface {
|
impl SeL4SecurityCoordinator {
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
SeL4SecurityCoordinatorInterface {}
|
SeL4SecurityCoordinator {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub type KataSecurityCoordinatorInterface = SeL4SecurityCoordinatorInterface;
|
pub type KataSecurityCoordinatorInterface = SeL4SecurityCoordinator;
|
||||||
|
|
||||||
impl SecurityCoordinatorInterface for SeL4SecurityCoordinatorInterface {
|
impl SecurityCoordinatorInterface for SeL4SecurityCoordinator {
|
||||||
fn request(
|
fn request(
|
||||||
&mut self,
|
&mut self,
|
||||||
request_id: SecurityRequest,
|
request_id: SecurityRequest,
|
||||||
|
23
apps/system/components/StorageManager/Cargo.toml
Normal file
23
apps/system/components/StorageManager/Cargo.toml
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
[workspace]
|
||||||
|
|
||||||
|
members = [
|
||||||
|
"kata-storage-component",
|
||||||
|
"kata-storage-interface",
|
||||||
|
"kata-storage-manager",
|
||||||
|
]
|
||||||
|
|
||||||
|
[profile.dev]
|
||||||
|
opt-level = 0
|
||||||
|
debug = true
|
||||||
|
lto = "fat"
|
||||||
|
codegen-units = 1
|
||||||
|
|
||||||
|
[profile.release]
|
||||||
|
opt-level = "z"
|
||||||
|
lto = "fat"
|
||||||
|
codegen-units = 1
|
||||||
|
split-debuginfo = "unpacked"
|
||||||
|
|
||||||
|
[profile.release.build-override]
|
||||||
|
opt-level = "z"
|
||||||
|
codegen-units = 1
|
12
apps/system/components/StorageManager/StorageManager.camkes
Normal file
12
apps/system/components/StorageManager/StorageManager.camkes
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
// Kata OS StorageManager services.
|
||||||
|
|
||||||
|
import <LoggerInterface.camkes>;
|
||||||
|
import <SecurityCoordinatorInterface.camkes>;
|
||||||
|
import <StorageInterface.camkes>;
|
||||||
|
|
||||||
|
component StorageManager {
|
||||||
|
provides StorageInterface storage;
|
||||||
|
|
||||||
|
uses LoggerInterface logger;
|
||||||
|
uses SecurityCoordinatorInterface security;
|
||||||
|
}
|
7
apps/system/components/StorageManager/cbindgen.toml
Normal file
7
apps/system/components/StorageManager/cbindgen.toml
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
language = "C"
|
||||||
|
include_guard = "__STORAGE_MANAGER_BINDINGS_H__"
|
||||||
|
autogen_warning = "/* Warning, this file is autogenerated by cbindgen. Don't modify this manually. */"
|
||||||
|
no_includes = true
|
||||||
|
|
||||||
|
[export]
|
||||||
|
include = ["KeyValueData", "StorageManagerError"]
|
@ -0,0 +1,19 @@
|
|||||||
|
[package]
|
||||||
|
name = "kata-storage-component"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2018"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
cstr_core = { version = "0.2.3", default-features = false }
|
||||||
|
kata-allocator = { path = "../../DebugConsole/kata-allocator" }
|
||||||
|
kata-logger = { path = "../../DebugConsole/kata-logger" }
|
||||||
|
kata-panic = { path = "../../DebugConsole/kata-panic" }
|
||||||
|
kata-storage-interface = { path = "../kata-storage-interface" }
|
||||||
|
kata-storage-manager = { path = "../kata-storage-manager" }
|
||||||
|
log = "0.4"
|
||||||
|
postcard = "0.7"
|
||||||
|
|
||||||
|
[lib]
|
||||||
|
name = "kata_storage_manager"
|
||||||
|
path = "src/run.rs"
|
||||||
|
crate-type = ["staticlib"]
|
@ -0,0 +1,120 @@
|
|||||||
|
//! Kata OS StorageManager component support.
|
||||||
|
|
||||||
|
// Code here binds the camkes component to the rust code.
|
||||||
|
#![no_std]
|
||||||
|
|
||||||
|
extern crate alloc;
|
||||||
|
use core::slice;
|
||||||
|
use cstr_core::CStr;
|
||||||
|
extern crate kata_panic;
|
||||||
|
use kata_allocator;
|
||||||
|
use kata_logger::KataLogger;
|
||||||
|
use kata_storage_interface::KeyValueData;
|
||||||
|
use kata_storage_interface::StorageError;
|
||||||
|
use kata_storage_interface::StorageManagerInterface;
|
||||||
|
use kata_storage_interface::StorageManagerError;
|
||||||
|
use kata_storage_manager::KATA_STORAGE;
|
||||||
|
use log::trace;
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub extern "C" fn pre_init() {
|
||||||
|
static KATA_LOGGER: KataLogger = KataLogger;
|
||||||
|
log::set_logger(&KATA_LOGGER).unwrap();
|
||||||
|
// NB: set to max; the LoggerInterface will filter
|
||||||
|
log::set_max_level(log::LevelFilter::Trace);
|
||||||
|
|
||||||
|
// TODO(sleffler): temp until we integrate with seL4
|
||||||
|
static mut HEAP_MEMORY: [u8; 8 * 1024] = [0; 8 * 1024];
|
||||||
|
unsafe {
|
||||||
|
kata_allocator::ALLOCATOR.init(HEAP_MEMORY.as_mut_ptr() as usize, HEAP_MEMORY.len());
|
||||||
|
trace!(
|
||||||
|
"setup heap: start_addr {:p} size {}",
|
||||||
|
HEAP_MEMORY.as_ptr(),
|
||||||
|
HEAP_MEMORY.len()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn map_storage_error(se: StorageError, def: StorageManagerError) -> StorageManagerError {
|
||||||
|
match se {
|
||||||
|
StorageError::Success => StorageManagerError::SmeSuccess,
|
||||||
|
StorageError::BundleNotFound => StorageManagerError::SmeBundleNotFound,
|
||||||
|
StorageError::KeyNotFound => StorageManagerError::SmeKeyNotFound,
|
||||||
|
StorageError::KeyInvalid => StorageManagerError::SmeKeyInvalid,
|
||||||
|
StorageError::ValueInvalid => StorageManagerError::SmeValueInvalid,
|
||||||
|
_ => def,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// StorageInterface glue stubs.
|
||||||
|
#[no_mangle]
|
||||||
|
pub extern "C" fn storage_read(
|
||||||
|
c_key: *const cstr_core::c_char,
|
||||||
|
c_raw_value: *mut KeyValueData,
|
||||||
|
) -> StorageManagerError {
|
||||||
|
unsafe {
|
||||||
|
match CStr::from_ptr(c_key).to_str() {
|
||||||
|
Ok(key) => {
|
||||||
|
// TODO(sleffler): de-badge reply cap to get bundle_id
|
||||||
|
match KATA_STORAGE.read("fubar", key) {
|
||||||
|
// NB: no serialization, returns raw data
|
||||||
|
Ok(value) => {
|
||||||
|
(*c_raw_value).copy_from_slice(&value);
|
||||||
|
StorageManagerError::SmeSuccess
|
||||||
|
}
|
||||||
|
Err(e) => map_storage_error(e, StorageManagerError::SmeReadFailed),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Err(e) => {
|
||||||
|
trace!("read: keyinvalid {:?}", e);
|
||||||
|
StorageManagerError::SmeKeyInvalid
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub extern "C" fn storage_write(
|
||||||
|
c_key: *const cstr_core::c_char,
|
||||||
|
c_raw_value_len: usize,
|
||||||
|
c_raw_value: *const u8,
|
||||||
|
) -> StorageManagerError {
|
||||||
|
unsafe {
|
||||||
|
match CStr::from_ptr(c_key).to_str() {
|
||||||
|
Ok(key) => {
|
||||||
|
// TODO(sleffler): de-badge reply cap to get bundle_id
|
||||||
|
match KATA_STORAGE.write(
|
||||||
|
"fubar",
|
||||||
|
key,
|
||||||
|
slice::from_raw_parts(c_raw_value, c_raw_value_len),
|
||||||
|
) {
|
||||||
|
Ok(_) => StorageManagerError::SmeSuccess,
|
||||||
|
Err(e) => map_storage_error(e, StorageManagerError::SmeWriteFailed),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Err(e) => {
|
||||||
|
trace!("write: keyinvalid {:?}", e);
|
||||||
|
StorageManagerError::SmeKeyInvalid
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub extern "C" fn storage_delete(c_key: *const cstr_core::c_char) -> StorageManagerError {
|
||||||
|
unsafe {
|
||||||
|
match CStr::from_ptr(c_key).to_str() {
|
||||||
|
Ok(key) => {
|
||||||
|
// TODO(sleffler): de-badge reply cap to get bundle_id
|
||||||
|
match KATA_STORAGE.delete("fubar", key) {
|
||||||
|
Ok(_) => StorageManagerError::SmeSuccess,
|
||||||
|
Err(e) => map_storage_error(e, StorageManagerError::SmeDeleteFailed),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Err(e) => {
|
||||||
|
trace!("delete: keyinvalid {:?}", e);
|
||||||
|
StorageManagerError::SmeKeyInvalid
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,7 @@
|
|||||||
|
[package]
|
||||||
|
name = "kata-storage-interface"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2018"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
cstr_core = "0.2"
|
@ -0,0 +1,105 @@
|
|||||||
|
//! Kata OS storage management support
|
||||||
|
|
||||||
|
#![cfg_attr(not(test), no_std)]
|
||||||
|
|
||||||
|
use core::str;
|
||||||
|
use cstr_core::CString;
|
||||||
|
|
||||||
|
// TODO(sleffler): temp constraint on value part of key-value pairs
|
||||||
|
pub const KEY_VALUE_DATA_SIZE: usize = 100;
|
||||||
|
pub type KeyValueData = [u8; KEY_VALUE_DATA_SIZE];
|
||||||
|
|
||||||
|
// NB: struct's marked repr(C) are processed by cbindgen to get a .h file
|
||||||
|
// used in camkes C interfaces.
|
||||||
|
|
||||||
|
#[derive(Debug, Eq, PartialEq)]
|
||||||
|
pub enum StorageError {
|
||||||
|
Success = 0,
|
||||||
|
BundleNotFound,
|
||||||
|
KeyNotFound,
|
||||||
|
KeyInvalid,
|
||||||
|
ValueInvalid,
|
||||||
|
SerializeFailed,
|
||||||
|
// Generic errors.
|
||||||
|
ReadFailed,
|
||||||
|
WriteFailed,
|
||||||
|
DeleteFailed,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait StorageManagerInterface {
|
||||||
|
fn read(&self, bundle_id: &str, key: &str) -> Result<KeyValueData, StorageError>;
|
||||||
|
fn write(&self, bundle_id: &str, key: &str, value: &[u8]) -> Result<(), StorageError>;
|
||||||
|
fn delete(&self, bundle_id: &str, key: &str) -> Result<(), StorageError>;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Public version of StorageError presented over rpc interface.
|
||||||
|
// This is needed because the enum is exported to C users and needs to
|
||||||
|
// be unique from other enum's.
|
||||||
|
// TODO(sleffler): switch to single generic error space ala absl::StatusCode
|
||||||
|
#[repr(C)]
|
||||||
|
#[derive(Debug, Eq, PartialEq)]
|
||||||
|
pub enum StorageManagerError {
|
||||||
|
SmeSuccess = 0,
|
||||||
|
SmeBundleIdInvalid,
|
||||||
|
SmeBundleNotFound,
|
||||||
|
SmeKeyNotFound,
|
||||||
|
SmeValueInvalid,
|
||||||
|
SmeKeyInvalid,
|
||||||
|
// Generic errors.
|
||||||
|
SmeReadFailed,
|
||||||
|
SmeWriteFailed,
|
||||||
|
SmeDeleteFailed,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
#[allow(dead_code)]
|
||||||
|
pub fn kata_storage_delete(key: &str) -> Result<(), StorageManagerError> {
|
||||||
|
// NB: this assumes the StorageManager component is named "storage".
|
||||||
|
extern "C" {
|
||||||
|
pub fn storage_delete(
|
||||||
|
c_key: *const cstr_core::c_char
|
||||||
|
) -> StorageManagerError;
|
||||||
|
}
|
||||||
|
let cstr = CString::new(key)
|
||||||
|
.map_err(|_| StorageManagerError::SmeKeyInvalid)?;
|
||||||
|
match unsafe { storage_delete(cstr.as_ptr()) } {
|
||||||
|
StorageManagerError::SmeSuccess => Ok(()),
|
||||||
|
status => Err(status),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
#[allow(dead_code)]
|
||||||
|
pub fn kata_storage_read(key: &str) -> Result<KeyValueData, StorageManagerError> {
|
||||||
|
extern "C" {
|
||||||
|
fn storage_read(
|
||||||
|
c_key: *const cstr_core::c_char,
|
||||||
|
c_raw_value: *mut KeyValueData,
|
||||||
|
) -> StorageManagerError;
|
||||||
|
}
|
||||||
|
let cstr = CString::new(key)
|
||||||
|
.map_err(|_| StorageManagerError::SmeKeyInvalid)?;
|
||||||
|
let value = &mut [0u8; KEY_VALUE_DATA_SIZE];
|
||||||
|
match unsafe { storage_read(cstr.as_ptr(), value as *mut _) } {
|
||||||
|
StorageManagerError::SmeSuccess => Ok(*value),
|
||||||
|
status => Err(status),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
#[allow(dead_code)]
|
||||||
|
pub fn kata_storage_write(key: &str, value: &[u8]) -> Result<(), StorageManagerError> {
|
||||||
|
extern "C" {
|
||||||
|
fn storage_write(
|
||||||
|
c_key: *const cstr_core::c_char,
|
||||||
|
c_raw_value_len: usize,
|
||||||
|
c_raw_value: *const u8,
|
||||||
|
) -> StorageManagerError;
|
||||||
|
}
|
||||||
|
let cstr = CString::new(key)
|
||||||
|
.map_err(|_| StorageManagerError::SmeKeyInvalid)?;
|
||||||
|
match unsafe { storage_write(cstr.as_ptr(), value.len(), value.as_ptr()) } {
|
||||||
|
StorageManagerError::SmeSuccess => Ok(()),
|
||||||
|
status => Err(status),
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,10 @@
|
|||||||
|
[package]
|
||||||
|
name = "kata-storage-manager"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2018"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
kata-security-common = { path = "../../SecurityCoordinator/kata-security-common" }
|
||||||
|
kata-storage-interface = { path = "../kata-storage-interface" }
|
||||||
|
log = "0.4"
|
||||||
|
postcard = "0.7"
|
@ -0,0 +1,115 @@
|
|||||||
|
//! Kata OS storage management support
|
||||||
|
|
||||||
|
#![cfg_attr(not(test), no_std)]
|
||||||
|
|
||||||
|
extern crate alloc;
|
||||||
|
use alloc::string::String;
|
||||||
|
use kata_security_common::*;
|
||||||
|
use kata_storage_interface::{KeyValueData, KEY_VALUE_DATA_SIZE};
|
||||||
|
use kata_storage_interface::StorageError;
|
||||||
|
use kata_storage_interface::StorageManagerInterface;
|
||||||
|
use log::trace;
|
||||||
|
use postcard;
|
||||||
|
|
||||||
|
// NB: KATA_STORAGE cannot be used before setup is completed with a call to init()
|
||||||
|
#[cfg(not(test))]
|
||||||
|
pub static mut KATA_STORAGE: KataStorageManager = KataStorageManager{};
|
||||||
|
|
||||||
|
// KataStorageManager bundles an instance of the StorageManager that operates
|
||||||
|
// on KataOS interfaces. There is a two-step dance to setup an instance because
|
||||||
|
// we want KATA_STORAGE static and there is no const Box::new variant.
|
||||||
|
pub struct KataStorageManager;
|
||||||
|
impl StorageManagerInterface for KataStorageManager {
|
||||||
|
fn read(&self, bundle_id: &str, key: &str) -> Result<KeyValueData, StorageError> {
|
||||||
|
trace!("read bundle_id:{} key:{}", bundle_id, key);
|
||||||
|
|
||||||
|
fn serialize_failure(e: postcard::Error) -> StorageError {
|
||||||
|
trace!("read: serialize failure {:?}", e);
|
||||||
|
StorageError::SerializeFailed
|
||||||
|
}
|
||||||
|
|
||||||
|
// Send request to Security Core via SecurityCoordinator
|
||||||
|
let mut request = [0u8; SECURITY_REQUEST_DATA_SIZE];
|
||||||
|
let _ = postcard::to_slice(
|
||||||
|
&ReadKeyRequest {
|
||||||
|
bundle_id: String::from(bundle_id),
|
||||||
|
key: String::from(key),
|
||||||
|
},
|
||||||
|
&mut request[..],
|
||||||
|
)
|
||||||
|
.map_err(serialize_failure)?;
|
||||||
|
let result = &mut [0u8; SECURITY_REPLY_DATA_SIZE];
|
||||||
|
match kata_security_request(SecurityRequest::SrReadKey, &request, result) {
|
||||||
|
SecurityRequestError::SreSuccess => {
|
||||||
|
let mut keyval = [0u8; KEY_VALUE_DATA_SIZE];
|
||||||
|
keyval.copy_from_slice(&result[..KEY_VALUE_DATA_SIZE]);
|
||||||
|
Ok(keyval)
|
||||||
|
}
|
||||||
|
e => Err(map_security_request_error(e, StorageError::ReadFailed)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fn write(&self, bundle_id: &str, key: &str, value: &[u8]) -> Result<(), StorageError> {
|
||||||
|
trace!(
|
||||||
|
"write bundle_id:{} key:{} value:{:?}",
|
||||||
|
bundle_id,
|
||||||
|
key,
|
||||||
|
value
|
||||||
|
);
|
||||||
|
|
||||||
|
fn serialize_failure(e: postcard::Error) -> StorageError {
|
||||||
|
trace!("write: serialize failure {:?}", e);
|
||||||
|
StorageError::SerializeFailed
|
||||||
|
}
|
||||||
|
|
||||||
|
// Send request to Security Core via SecurityCoordinator
|
||||||
|
let mut request = [0u8; SECURITY_REQUEST_DATA_SIZE];
|
||||||
|
let _ = postcard::to_slice(
|
||||||
|
&WriteKeyRequest {
|
||||||
|
bundle_id: String::from(bundle_id),
|
||||||
|
key: String::from(key),
|
||||||
|
value: value,
|
||||||
|
},
|
||||||
|
&mut request[..],
|
||||||
|
)
|
||||||
|
.map_err(serialize_failure)?;
|
||||||
|
let result = &mut [0u8; SECURITY_REPLY_DATA_SIZE];
|
||||||
|
match kata_security_request(SecurityRequest::SrWriteKey, &request, result) {
|
||||||
|
SecurityRequestError::SreSuccess => Ok(()),
|
||||||
|
e => Err(map_security_request_error(e, StorageError::WriteFailed)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fn delete(&self, bundle_id: &str, key: &str) -> Result<(), StorageError> {
|
||||||
|
trace!("delete bundle_id:{} key:{}", bundle_id, key);
|
||||||
|
|
||||||
|
fn serialize_failure(e: postcard::Error) -> StorageError {
|
||||||
|
trace!("delete: serialize failure {:?}", e);
|
||||||
|
StorageError::SerializeFailed
|
||||||
|
}
|
||||||
|
|
||||||
|
// Send request to Security Core via SecurityCoordinator
|
||||||
|
let mut request = [0u8; SECURITY_REQUEST_DATA_SIZE];
|
||||||
|
let _ = postcard::to_slice(
|
||||||
|
&DeleteKeyRequest {
|
||||||
|
bundle_id: String::from(bundle_id),
|
||||||
|
key: String::from(key),
|
||||||
|
},
|
||||||
|
&mut request[..],
|
||||||
|
)
|
||||||
|
.map_err(serialize_failure)?;
|
||||||
|
let result = &mut [0u8; SECURITY_REPLY_DATA_SIZE];
|
||||||
|
match kata_security_request(SecurityRequest::SrDeleteKey, &request, result) {
|
||||||
|
SecurityRequestError::SreSuccess => Ok(()),
|
||||||
|
e => Err(map_security_request_error(e, StorageError::DeleteFailed)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Maps a SecuritRequestError to a StorageError.
|
||||||
|
fn map_security_request_error(sre: SecurityRequestError, def: StorageError) -> StorageError {
|
||||||
|
match sre {
|
||||||
|
SecurityRequestError::SreSuccess => StorageError::Success,
|
||||||
|
SecurityRequestError::SreBundleNotFound => StorageError::BundleNotFound,
|
||||||
|
SecurityRequestError::SreKeyNotFound => StorageError::KeyNotFound,
|
||||||
|
_ => def,
|
||||||
|
}
|
||||||
|
}
|
7
apps/system/interfaces/StorageInterface.camkes
Normal file
7
apps/system/interfaces/StorageInterface.camkes
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
procedure StorageInterface {
|
||||||
|
include <StorageManagerBindings.h>;
|
||||||
|
|
||||||
|
StorageManagerError read(in string key, out KeyValueData value);
|
||||||
|
StorageManagerError write(in string key, in char value[]);
|
||||||
|
StorageManagerError delete(in string key);
|
||||||
|
};
|
22
apps/system/interfaces/StorageManagerBindings.h
Normal file
22
apps/system/interfaces/StorageManagerBindings.h
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
#ifndef __STORAGE_MANAGER_BINDINGS_H__
|
||||||
|
#define __STORAGE_MANAGER_BINDINGS_H__
|
||||||
|
|
||||||
|
/* Warning, this file is autogenerated by cbindgen. Don't modify this manually. */
|
||||||
|
|
||||||
|
#define KEY_VALUE_DATA_SIZE 100
|
||||||
|
|
||||||
|
typedef enum StorageManagerError {
|
||||||
|
SmeSuccess = 0,
|
||||||
|
SmeBundleIdInvalid,
|
||||||
|
SmeBundleNotFound,
|
||||||
|
SmeKeyNotFound,
|
||||||
|
SmeValueInvalid,
|
||||||
|
SmeKeyInvalid,
|
||||||
|
SmeReadFailed,
|
||||||
|
SmeWriteFailed,
|
||||||
|
SmeDeleteFailed,
|
||||||
|
} StorageManagerError;
|
||||||
|
|
||||||
|
typedef uint8_t KeyValueData[KEY_VALUE_DATA_SIZE];
|
||||||
|
|
||||||
|
#endif /* __STORAGE_MANAGER_BINDINGS_H__ */
|
@ -20,6 +20,7 @@ import "components/DebugConsole/DebugConsole.camkes";
|
|||||||
import "components/ProcessManager/ProcessManager.camkes";
|
import "components/ProcessManager/ProcessManager.camkes";
|
||||||
import "components/MlCoordinator/MlCoordinator.camkes";
|
import "components/MlCoordinator/MlCoordinator.camkes";
|
||||||
import "components/SeL4Debug/SeL4Debug.camkes";
|
import "components/SeL4Debug/SeL4Debug.camkes";
|
||||||
|
import "components/StorageManager/StorageManager.camkes";
|
||||||
import "components/SecurityCoordinator/SecurityCoordinator.camkes";
|
import "components/SecurityCoordinator/SecurityCoordinator.camkes";
|
||||||
import "components/VectorCoreDriver/VectorCoreDriver.camkes";
|
import "components/VectorCoreDriver/VectorCoreDriver.camkes";
|
||||||
|
|
||||||
@ -51,6 +52,7 @@ assembly {
|
|||||||
component MlCoordinator ml_coordinator;
|
component MlCoordinator ml_coordinator;
|
||||||
component DebugConsole debug_console;
|
component DebugConsole debug_console;
|
||||||
component SecurityCoordinator security_coordinator;
|
component SecurityCoordinator security_coordinator;
|
||||||
|
component StorageManager storage_manager;
|
||||||
|
|
||||||
// OpenTitanUARTDriver
|
// OpenTitanUARTDriver
|
||||||
connection seL4HardwareMMIO uart_mem(from uart_driver.mmio_region,
|
connection seL4HardwareMMIO uart_mem(from uart_driver.mmio_region,
|
||||||
@ -74,6 +76,8 @@ assembly {
|
|||||||
to process_manager.pkg_mgmt);
|
to process_manager.pkg_mgmt);
|
||||||
connection seL4RPCCall shell_ml(from debug_console.mlcoord,
|
connection seL4RPCCall shell_ml(from debug_console.mlcoord,
|
||||||
to ml_coordinator.mlcoord);
|
to ml_coordinator.mlcoord);
|
||||||
|
connection seL4RPCCall shell_storage(from debug_console.storage,
|
||||||
|
to storage_manager.storage);
|
||||||
|
|
||||||
// Connect the SecurityCoordinatorInterface to each component that needs
|
// Connect the SecurityCoordinatorInterface to each component that needs
|
||||||
// access to the Security Core. Note this allocates a 4KB shared memory
|
// access to the Security Core. Note this allocates a 4KB shared memory
|
||||||
@ -82,6 +86,7 @@ assembly {
|
|||||||
from debug_console.security, // NB: for debug/test
|
from debug_console.security, // NB: for debug/test
|
||||||
from process_manager.security,
|
from process_manager.security,
|
||||||
from ml_coordinator.security, // NB: for LoadModel but not in design
|
from ml_coordinator.security, // NB: for LoadModel but not in design
|
||||||
|
from storage_manager.security,
|
||||||
to security_coordinator.security);
|
to security_coordinator.security);
|
||||||
|
|
||||||
// Connect the DebugConsole to the OpenTitanUARTDriver.
|
// Connect the DebugConsole to the OpenTitanUARTDriver.
|
||||||
@ -101,6 +106,7 @@ assembly {
|
|||||||
from process_manager.logger,
|
from process_manager.logger,
|
||||||
from ml_coordinator.logger,
|
from ml_coordinator.logger,
|
||||||
from security_coordinator.logger,
|
from security_coordinator.logger,
|
||||||
|
from storage_manager.logger,
|
||||||
to debug_console.logger);
|
to debug_console.logger);
|
||||||
|
|
||||||
// Connect the SeL4Debug interface of each component that needs access.
|
// Connect the SeL4Debug interface of each component that needs access.
|
||||||
|
Loading…
Reference in New Issue
Block a user