mirror of
https://github.com/AmbiML/sparrow-kata-full.git
synced 2025-09-19 01:44:40 +00:00
Add SecurityCoordinator skeleton.
- add SecurityCoordinator component (needs mailbox support, just a fake which should be enabled with a feature flag) - connect to ProcessManager & MlCoordinator - temproarily connect to DebugConsole to enable scecho test command - expand Bundle to hold application information (may need more elf) - connect ProcessManager::{install, uninstall} to SecurityCoordinator (no application binary yet, needs global page allocator) Notes: - SecurityCoordinator depends on camkes for thread synchronization - private heap is 8KB (and could possible be less; need to tune) - camkes interface connection uses seL4RPCOverMultiSharedData so ipc buffers are 4KB; the request & reply serde buffers are 2KB but could be near 4KB since they are used sequentially and the other params are a few bytes (but beware of camkes stack allocation) - the camkes SecurityCoordinator::request rpc is defined so that the request param has reasonable handling but the reply param requires a full copy (even if only partly used); haven't found a way to express the desired handling Change-Id: I686dc2d501e39bc8c27fe22db40657165a55b472 GitOrigin-RevId: db1536c241e28ddda1dc8f8da341b8c667ed6646
This commit is contained in:
@@ -55,6 +55,18 @@ DeclareCAmkESComponent(MlCoordinator
|
|||||||
INCLUDES interfaces
|
INCLUDES interfaces
|
||||||
)
|
)
|
||||||
|
|
||||||
|
RustAddLibrary(
|
||||||
|
kata_security_coordinator
|
||||||
|
SOURCE_DIR ${CMAKE_CURRENT_LIST_DIR}/components/SecurityCoordinator
|
||||||
|
TARGET "riscv32imc-unknown-none-elf"
|
||||||
|
LIB_FILENAME libkata_security_coordinator.a
|
||||||
|
)
|
||||||
|
|
||||||
|
DeclareCAmkESComponent(SecurityCoordinator
|
||||||
|
LIBS kata_security_coordinator
|
||||||
|
INCLUDES interfaces
|
||||||
|
)
|
||||||
|
|
||||||
DeclareCAmkESComponent(LogFibonacci
|
DeclareCAmkESComponent(LogFibonacci
|
||||||
SOURCES
|
SOURCES
|
||||||
components/LogFibonacci/src/main.c
|
components/LogFibonacci/src/main.c
|
||||||
|
@@ -2,6 +2,7 @@ import <LoggerInterface.camkes>;
|
|||||||
import <ProcessControlInterface.camkes>;
|
import <ProcessControlInterface.camkes>;
|
||||||
import <PackageManagementInterface.camkes>;
|
import <PackageManagementInterface.camkes>;
|
||||||
import <MlCoordinatorInterface.camkes>;
|
import <MlCoordinatorInterface.camkes>;
|
||||||
|
import <SecurityCoordinatorInterface.camkes>;
|
||||||
import <SeL4DebugInterface.camkes>;
|
import <SeL4DebugInterface.camkes>;
|
||||||
|
|
||||||
component DebugConsole {
|
component DebugConsole {
|
||||||
@@ -18,6 +19,8 @@ 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
|
||||||
|
uses SecurityCoordinatorInterface security;
|
||||||
uses SeL4DebugInterface sel4debug;
|
uses SeL4DebugInterface sel4debug;
|
||||||
uses MlCoordinatorInterface mlcoord;
|
uses MlCoordinatorInterface mlcoord;
|
||||||
}
|
}
|
||||||
|
@@ -9,5 +9,6 @@ cstr_core = "0.2"
|
|||||||
kata-io = { path = "../kata-io" }
|
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" }
|
||||||
log = "0.4"
|
log = "0.4"
|
||||||
postcard = { version = "0.7", features = ["alloc"] }
|
postcard = { version = "0.7", features = ["alloc"] }
|
||||||
|
@@ -82,6 +82,7 @@ fn dispatch_command(cmdline: &str, output: &mut dyn io::Write) {
|
|||||||
"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(),
|
||||||
|
"scecho" => scecho_command(cmdline, output),
|
||||||
"start" => start_command(&mut args, output),
|
"start" => start_command(&mut args, output),
|
||||||
"stop" => stop_command(&mut args, output),
|
"stop" => stop_command(&mut args, output),
|
||||||
"uninstall" => uninstall_command(&mut args, output),
|
"uninstall" => uninstall_command(&mut args, output),
|
||||||
@@ -117,6 +118,33 @@ fn echo_command(cmdline: &str, output: &mut dyn io::Write) -> Result<(), Command
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Implements an "scecho" command that sends arguments to the Security Core's echo service.
|
||||||
|
fn scecho_command(cmdline: &str, output: &mut dyn io::Write) -> Result<(), CommandError> {
|
||||||
|
use kata_security_common::*;
|
||||||
|
let (_, request) = cmdline.split_at(7); // 'scecho'
|
||||||
|
let reply = &mut [0u8; SECURITY_REPLY_DATA_SIZE];
|
||||||
|
match unsafe {
|
||||||
|
security_request(
|
||||||
|
SecurityRequest::SrEcho,
|
||||||
|
request.len() as u32,
|
||||||
|
request.as_ptr(),
|
||||||
|
reply as *mut _,
|
||||||
|
)
|
||||||
|
} {
|
||||||
|
SecurityRequestError::SreSuccess => {
|
||||||
|
writeln!(
|
||||||
|
output,
|
||||||
|
"{}",
|
||||||
|
String::from_utf8_lossy(&reply[..request.len()])
|
||||||
|
)?;
|
||||||
|
}
|
||||||
|
status => {
|
||||||
|
writeln!(output, "ECHO replied {:?}", status)?;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
// Set/display the max log level for the DebugConsole.
|
// Set/display the max log level for the DebugConsole.
|
||||||
fn loglevel_command(
|
fn loglevel_command(
|
||||||
args: &mut dyn Iterator<Item = &str>,
|
args: &mut dyn Iterator<Item = &str>,
|
||||||
|
@@ -1,9 +1,11 @@
|
|||||||
import <LoggerInterface.camkes>;
|
import <LoggerInterface.camkes>;
|
||||||
import <MlCoordinatorInterface.camkes>;
|
import <MlCoordinatorInterface.camkes>;
|
||||||
|
import <SecurityCoordinatorInterface.camkes>;
|
||||||
|
|
||||||
component MlCoordinator {
|
component MlCoordinator {
|
||||||
provides MlCoordinatorInterface mlcoord;
|
provides MlCoordinatorInterface mlcoord;
|
||||||
|
|
||||||
uses LoggerInterface logger;
|
uses LoggerInterface logger;
|
||||||
|
uses SecurityCoordinatorInterface security;
|
||||||
uses VectorCoreInterface vctop;
|
uses VectorCoreInterface vctop;
|
||||||
}
|
}
|
||||||
|
@@ -4,6 +4,7 @@ import <LoggerInterface.camkes>;
|
|||||||
import <PackageManagementInterface.camkes>;
|
import <PackageManagementInterface.camkes>;
|
||||||
import <ProcessControlInterface.camkes>;
|
import <ProcessControlInterface.camkes>;
|
||||||
import <SeL4DebugInterface.camkes>;
|
import <SeL4DebugInterface.camkes>;
|
||||||
|
import <SecurityCoordinatorInterface.camkes>;
|
||||||
|
|
||||||
component ProcessManager {
|
component ProcessManager {
|
||||||
provides PackageManagementInterface pkg_mgmt;
|
provides PackageManagementInterface pkg_mgmt;
|
||||||
@@ -11,4 +12,5 @@ component ProcessManager {
|
|||||||
|
|
||||||
uses LoggerInterface logger;
|
uses LoggerInterface logger;
|
||||||
uses SeL4DebugInterface sel4debug;
|
uses SeL4DebugInterface sel4debug;
|
||||||
|
uses SecurityCoordinatorInterface security;
|
||||||
}
|
}
|
||||||
|
@@ -4,4 +4,6 @@ version = "0.1.0"
|
|||||||
edition = "2018"
|
edition = "2018"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
kata-security-common = { path = "../../SecurityCoordinator/kata-security-common" }
|
||||||
postcard = { version = "0.7", features = ["alloc"] }
|
postcard = { version = "0.7", features = ["alloc"] }
|
||||||
|
serde = { version = "1.0", default-features = false, features = ["alloc", "derive"] }
|
||||||
|
@@ -6,45 +6,68 @@ extern crate alloc;
|
|||||||
use alloc::string::String;
|
use alloc::string::String;
|
||||||
use alloc::vec::Vec;
|
use alloc::vec::Vec;
|
||||||
use core::str;
|
use core::str;
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
pub type BundleIdArray = Vec<String>;
|
pub type BundleIdArray = Vec<String>;
|
||||||
|
|
||||||
// NB: struct's marked repr(C) are processed by cbindgen to get a .h file
|
// Size of the data buffer used to pass a serialized BundleIdArray between Rust <> C.
|
||||||
// used in camkes C interfaces.
|
|
||||||
|
|
||||||
// BundleId capcity before spillover to the heap.
|
|
||||||
// TODO(sleffler): hide this; it's part of the implementation
|
|
||||||
pub const DEFAULT_BUNDLE_ID_CAPACITY: usize = 64;
|
|
||||||
|
|
||||||
// Size of the data buffer used to pass BundleIdArray data between Rust <> C.
|
|
||||||
// The data structure size is bounded by the camkes ipc buffer (120 bytes!)
|
// The data structure size is bounded by the camkes ipc buffer (120 bytes!)
|
||||||
// and also by it being allocated on the stack of the rpc glue code.
|
// and also by it being allocated on the stack of the rpc glue code.
|
||||||
// So we need to balance these against being able to return all values.
|
// So we need to balance these against being able to return all values.
|
||||||
pub const RAW_BUNDLE_ID_DATA_SIZE: usize = 100;
|
pub const RAW_BUNDLE_ID_DATA_SIZE: usize = 100;
|
||||||
pub type RawBundleIdData = [u8; RAW_BUNDLE_ID_DATA_SIZE];
|
pub type RawBundleIdData = [u8; RAW_BUNDLE_ID_DATA_SIZE];
|
||||||
|
|
||||||
// TODO(sleffler): fill-in
|
// BundleId capacity before spillover to the heap.
|
||||||
#[derive(Clone, Debug)]
|
// TODO(sleffler): hide this; it's part of the implementation
|
||||||
|
pub const DEFAULT_BUNDLE_ID_CAPACITY: usize = 64;
|
||||||
|
|
||||||
|
mod ptr_helper {
|
||||||
|
use super::*;
|
||||||
|
use serde::{Deserializer, Serializer};
|
||||||
|
|
||||||
|
pub fn serialize<T, S>(ptr: &*const T, serializer: S) -> Result<S::Ok, S::Error>
|
||||||
|
where
|
||||||
|
S: Serializer,
|
||||||
|
{
|
||||||
|
(*ptr as usize).serialize(serializer)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn deserialize<'de, T, D>(deserializer: D) -> Result<*const T, D::Error>
|
||||||
|
where
|
||||||
|
D: Deserializer<'de>,
|
||||||
|
{
|
||||||
|
Ok(usize::deserialize(deserializer)? as *const T)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||||
pub struct Bundle {
|
pub struct Bundle {
|
||||||
|
// NB: application & ML binaries use well-known paths relative to bundle_id
|
||||||
|
// NB: ProcessManager owns loaded application's memory
|
||||||
|
|
||||||
// Bundle id extracted from manifest
|
// Bundle id extracted from manifest
|
||||||
pub app_id: String,
|
pub app_id: String,
|
||||||
pub data: [u8; 64], // TODO(sleffler): placeholder
|
|
||||||
|
// Raw memory address of loaded application
|
||||||
|
#[serde(with = "ptr_helper")]
|
||||||
|
pub app_memory_address: *const u8,
|
||||||
|
|
||||||
|
// Size (bytes) of loaded application
|
||||||
|
pub app_memory_size: u32,
|
||||||
}
|
}
|
||||||
impl Bundle {
|
impl Bundle {
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
Bundle {
|
Bundle {
|
||||||
app_id: String::with_capacity(DEFAULT_BUNDLE_ID_CAPACITY),
|
app_id: String::with_capacity(DEFAULT_BUNDLE_ID_CAPACITY),
|
||||||
data: [0u8; 64],
|
app_memory_address: 0 as *const u8,
|
||||||
|
app_memory_size: 0u32,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub fn as_ptr(&self) -> *const u8 {
|
|
||||||
self.data.as_ptr()
|
|
||||||
}
|
|
||||||
pub fn as_mut_ptr(&mut self) -> *mut u8 {
|
|
||||||
self.data.as_mut_ptr()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NB: struct's marked repr(C) are processed by cbindgen to get a .h file
|
||||||
|
// used in camkes C interfaces.
|
||||||
|
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
|
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
|
||||||
pub enum ProcessManagerError {
|
pub enum ProcessManagerError {
|
||||||
@@ -70,7 +93,7 @@ pub trait ProcessManagerInterface {
|
|||||||
&mut self,
|
&mut self,
|
||||||
pkg_buffer: *const u8,
|
pkg_buffer: *const u8,
|
||||||
pkg_buffer_size: u32,
|
pkg_buffer_size: u32,
|
||||||
) -> Result<Bundle, ProcessManagerError>;
|
) -> Result<String, ProcessManagerError>;
|
||||||
fn uninstall(&mut self, bundle_id: &str) -> Result<(), ProcessManagerError>;
|
fn uninstall(&mut self, bundle_id: &str) -> Result<(), ProcessManagerError>;
|
||||||
fn start(&mut self, bundle: &Bundle) -> Result<(), ProcessManagerError>;
|
fn start(&mut self, bundle: &Bundle) -> Result<(), ProcessManagerError>;
|
||||||
fn stop(&mut self, bundle: &Bundle) -> Result<(), ProcessManagerError>;
|
fn stop(&mut self, bundle: &Bundle) -> Result<(), ProcessManagerError>;
|
||||||
|
@@ -5,9 +5,10 @@ description = "Kata OS ProcessManager services"
|
|||||||
edition = "2018"
|
edition = "2018"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
cstr_core = { version = "0.2.3", default-features = false, features = ["alloc"] }
|
|
||||||
hashbrown = { version = "0.11", features = ["ahash-compile-time-rng"] }
|
hashbrown = { version = "0.11", features = ["ahash-compile-time-rng"] }
|
||||||
kata-proc-common = { path = "../kata-proc-common" }
|
kata-proc-common = { path = "../kata-proc-common" }
|
||||||
|
kata-security-common = { path = "../../SecurityCoordinator/kata-security-common" }
|
||||||
log = "0.4"
|
log = "0.4"
|
||||||
|
postcard = "0.7"
|
||||||
smallstr = "0.2"
|
smallstr = "0.2"
|
||||||
spin = "0.9"
|
spin = "0.9"
|
||||||
|
@@ -3,9 +3,11 @@
|
|||||||
#![cfg_attr(not(test), no_std)]
|
#![cfg_attr(not(test), no_std)]
|
||||||
|
|
||||||
extern crate alloc;
|
extern crate alloc;
|
||||||
use alloc::string::{String, ToString};
|
use alloc::string::String;
|
||||||
use kata_proc_common as proc;
|
use kata_proc_common::*;
|
||||||
use proc::*;
|
use kata_security_common::*;
|
||||||
|
use log::trace;
|
||||||
|
use postcard;
|
||||||
use spin::Mutex;
|
use spin::Mutex;
|
||||||
|
|
||||||
mod proc_manager;
|
mod proc_manager;
|
||||||
@@ -77,48 +79,99 @@ impl ProcessManagerInterface for KataManagerInterface {
|
|||||||
fn install(
|
fn install(
|
||||||
&mut self,
|
&mut self,
|
||||||
pkg_buffer: *const u8,
|
pkg_buffer: *const u8,
|
||||||
_pkg_buffer_size: u32,
|
pkg_buffer_size: u32,
|
||||||
) -> Result<Bundle, ProcessManagerError> {
|
) -> Result<String, ProcessManagerError> {
|
||||||
// Package contains: application manifest, application binary, and
|
// Package contains: application manifest, application binary, and
|
||||||
// (optional) ML workload binary to run on vector core.
|
// (optional) ML workload binary to run on vector core.
|
||||||
// Manifest contains bundle_id.
|
// Manifest contains bundle_id.
|
||||||
// Resulting flash file/pathname is fixed (1 app / bundle), only need bundle_id.
|
// Resulting flash file/pathname is fixed (1 app / bundle), only need bundle_id.
|
||||||
// Store a generated "access key" (for Tock) for start ops; this is
|
// Pass opaque package contents through; get back bundle_id.
|
||||||
// "bound via capability badging to seL4 capabilities".
|
|
||||||
let bundle = Bundle {
|
// This is handled by the SecurityCoordinator.
|
||||||
// NB: temporarily fill-in app_id
|
let reply = &mut [0u8; SECURITY_REPLY_DATA_SIZE];
|
||||||
app_id: (pkg_buffer as usize).to_string(),
|
match unsafe {
|
||||||
data: [0u8; 64],
|
security_request(
|
||||||
};
|
SecurityRequest::SrInstall,
|
||||||
Ok(bundle)
|
pkg_buffer_size,
|
||||||
|
pkg_buffer,
|
||||||
|
reply as *mut _,
|
||||||
|
)
|
||||||
|
} {
|
||||||
|
SecurityRequestError::SreSuccess => {
|
||||||
|
fn deserialize_failure(e: postcard::Error) -> ProcessManagerError {
|
||||||
|
trace!("install failed: deserialize {:?}", e);
|
||||||
|
ProcessManagerError::BundleDataInvalid
|
||||||
|
}
|
||||||
|
postcard::from_bytes::<String>(reply).map_err(deserialize_failure)
|
||||||
|
}
|
||||||
|
status => {
|
||||||
|
trace!("install failed: {:?}", status);
|
||||||
|
Err(ProcessManagerError::InstallFailed)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fn uninstall(&mut self, bundle_id: &str) -> Result<(), ProcessManagerError> {
|
||||||
|
fn serialize_failure(e: postcard::Error) -> ProcessManagerError {
|
||||||
|
trace!("uninstall failed: serialize {:?}", e);
|
||||||
|
ProcessManagerError::UninstallFailed
|
||||||
|
}
|
||||||
|
|
||||||
|
// NB: the caller has already checked no running application exists
|
||||||
|
// NB: the Security Core is assumed to invalidate/remove any kv store
|
||||||
|
|
||||||
|
// This is handled by the SecurityCoordinator.
|
||||||
|
let mut request_data = [0u8; SECURITY_REQUEST_DATA_SIZE];
|
||||||
|
let _ = postcard::to_slice(&bundle_id, &mut request_data).map_err(serialize_failure)?;
|
||||||
|
let reply = &mut [0u8; SECURITY_REPLY_DATA_SIZE];
|
||||||
|
match unsafe {
|
||||||
|
security_request(
|
||||||
|
SecurityRequest::SrUninstall,
|
||||||
|
request_data.len() as u32,
|
||||||
|
request_data.as_ptr(),
|
||||||
|
reply as *mut _,
|
||||||
|
)
|
||||||
|
} {
|
||||||
|
SecurityRequestError::SreSuccess => Ok(()),
|
||||||
|
status => {
|
||||||
|
trace!("uninstall failed: {:?}", status);
|
||||||
|
Err(ProcessManagerError::UninstallFailed)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
fn uninstall(&mut self, _bundle_id: &str) -> Result<(), ProcessManagerError> {
|
|
||||||
// This is handled with the StorageManager::Installer::uninstall.
|
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
fn start(&mut self, _bundle: &Bundle) -> Result<(), ProcessManagerError> {
|
fn start(&mut self, _bundle: &Bundle) -> Result<(), ProcessManagerError> {
|
||||||
// 1. Allocate shared memory for the program image
|
// 1. Ask security core for application footprint with SizeBuffer
|
||||||
// 2. Poke security core (via mailbox) to VerifyAndLoad data and load
|
// 2. Ask security core for manifest (maybe piggyback on SizeBuffer)
|
||||||
// into shared memory
|
// and parse for necessary info (e.g. whether kv Storage is
|
||||||
// 3. Security core responds (via mailbox) with success/failure &
|
// required, other privileges/capabilities)
|
||||||
// mailbox handler sends interrupt
|
// 3. Ask MemoryManager for shared memory pages for the application
|
||||||
// 4. Request completed with validated program in shared memory.
|
// (model handled separately by MlCoordinator since we do not know
|
||||||
// 5. On success allocate seL4 resources: VSpace, TCB & necessary
|
// which model will be used)
|
||||||
// capabiltiies; setup application system context and start thread
|
// 4. Allocate other seL4 resources:
|
||||||
// (or should resources be allocated before Verify?).
|
// - VSpace, TCB & necessary capabiltiies
|
||||||
// TODO: set up access to StorageManager? (badge seL4 cap w/ bundle_id)
|
// 5. Ask security core to VerifyAndLoad app into shared memory pages
|
||||||
|
// 6. Complete seL4 setup:
|
||||||
|
// - Setup application system context and start thread
|
||||||
|
// - Badge seL4 recv cap w/ bundle_id for (optional) StorageManager
|
||||||
|
// access
|
||||||
|
//
|
||||||
|
// Applications with an ML workload use the MlCoordinator to request
|
||||||
|
// data be loaded for the vector core.
|
||||||
|
//
|
||||||
|
// TBD where stuff normally in ELF headers comes from (e.g. starting pc,
|
||||||
|
// text size for marking pages executable, bss size).
|
||||||
|
//
|
||||||
|
// May want stack size parameterized.
|
||||||
//
|
//
|
||||||
// Applications with an ML workload use the MLCoordinator to request
|
|
||||||
// data be written to the vector core.
|
|
||||||
// TODO(sleffler): fill-in
|
// TODO(sleffler): fill-in
|
||||||
// Err(ProcessManagerError::StartFailed)
|
// Err(ProcessManagerError::StartFailed)
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
fn stop(&mut self, _bundle: &Bundle) -> Result<(), ProcessManagerError> {
|
fn stop(&mut self, _bundle: &Bundle) -> Result<(), ProcessManagerError> {
|
||||||
// 1. If thread is running, notify application so it can do cleanup;
|
// 0. Assume thread is running (caller verifies)
|
||||||
// e.g. ask the MLCoordinator to stop any ML workloads
|
// 1. Notify application so it can do cleanup; e.g. ask the
|
||||||
// 2. If thread notified, wait some period of time for ack.
|
// MLCoordinator to stop any ML workloads
|
||||||
// 3. If thread is running, stop thread.
|
// 2. Wait some period of time for an ack from application
|
||||||
|
// 3. Stop thread
|
||||||
// 4. Reclaim seL4 resources: TCB, VSpace, memory, capabilities, etc.
|
// 4. Reclaim seL4 resources: TCB, VSpace, memory, capabilities, etc.
|
||||||
// TODO(sleffler): fill-in
|
// TODO(sleffler): fill-in
|
||||||
// Err(ProcessManagerError::StopFailed)
|
// Err(ProcessManagerError::StopFailed)
|
||||||
|
@@ -6,6 +6,7 @@ use alloc::string::String;
|
|||||||
use core::convert::TryFrom;
|
use core::convert::TryFrom;
|
||||||
use core::marker::Sync;
|
use core::marker::Sync;
|
||||||
use hashbrown::HashMap;
|
use hashbrown::HashMap;
|
||||||
|
use kata_proc_common::{Bundle, DEFAULT_BUNDLE_ID_CAPACITY};
|
||||||
use log::trace;
|
use log::trace;
|
||||||
use smallstr::SmallString;
|
use smallstr::SmallString;
|
||||||
|
|
||||||
@@ -81,21 +82,23 @@ impl PackageManagementInterface for ProcessManager {
|
|||||||
|
|
||||||
// We assume the seL4 capability for the memory associated with
|
// We assume the seL4 capability for the memory associated with
|
||||||
// pkg_buffer has been setup for us so we can pass it along (as needed)
|
// pkg_buffer has been setup for us so we can pass it along (as needed)
|
||||||
// to the StorageManager.
|
// to the Security Core.
|
||||||
//
|
//
|
||||||
// NB: defer to StorageManager for handling an install of a previously
|
// NB: defer to StorageManager for handling an install of a previously
|
||||||
// installed app. We do not have the app_id to check locally so if the
|
// installed app. We do not have the app_id to check locally so if the
|
||||||
// StorageManager disallows re-install then we'll return it's error;
|
// StorageManager disallows re-install then we'll return it's error;
|
||||||
// otherwise we update the returned Bundle state.
|
// otherwise we update the returned Bundle state.
|
||||||
// TODO(sleffler): owner's public key?
|
// TODO(sleffler): owner's public key?
|
||||||
let bundle = self.manager.install(pkg_buffer, pkg_buffer_size)?;
|
let bundle_id = self.manager.install(pkg_buffer, pkg_buffer_size)?;
|
||||||
trace!(
|
trace!(
|
||||||
"install pkg {:p}:{} => bundle_id:{}",
|
"install pkg {:p}:{} => bundle_id:{}",
|
||||||
pkg_buffer,
|
pkg_buffer,
|
||||||
pkg_buffer_size,
|
pkg_buffer_size,
|
||||||
&bundle.app_id
|
bundle_id
|
||||||
);
|
);
|
||||||
|
|
||||||
|
let mut bundle = Bundle::new();
|
||||||
|
bundle.app_id = bundle_id;
|
||||||
assert!(self
|
assert!(self
|
||||||
.bundles
|
.bundles
|
||||||
.insert(BundleId::from_str(&bundle.app_id), BundleData::new(&bundle))
|
.insert(BundleId::from_str(&bundle.app_id), BundleData::new(&bundle))
|
||||||
@@ -315,6 +318,4 @@ mod tests {
|
|||||||
let running = mgr.get_running_bundles().unwrap();
|
let running = mgr.get_running_bundles().unwrap();
|
||||||
assert_eq!(running.len(), 0);
|
assert_eq!(running.len(), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO(sleffler): check uninstall stops a running thread
|
|
||||||
}
|
}
|
||||||
|
23
apps/system/components/SecurityCoordinator/Cargo.toml
Normal file
23
apps/system/components/SecurityCoordinator/Cargo.toml
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
[workspace]
|
||||||
|
|
||||||
|
members = [
|
||||||
|
"kata-security-common",
|
||||||
|
"kata-security-component",
|
||||||
|
"kata-security-coordinator",
|
||||||
|
]
|
||||||
|
|
||||||
|
[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
|
@@ -0,0 +1,10 @@
|
|||||||
|
// Kata OS SecurityCoordinator services.
|
||||||
|
|
||||||
|
import <LoggerInterface.camkes>;
|
||||||
|
import <SecurityCoordinatorInterface.camkes>;
|
||||||
|
|
||||||
|
component SecurityCoordinator {
|
||||||
|
provides SecurityCoordinatorInterface security;
|
||||||
|
|
||||||
|
uses LoggerInterface logger;
|
||||||
|
}
|
7
apps/system/components/SecurityCoordinator/cbindgen.toml
Normal file
7
apps/system/components/SecurityCoordinator/cbindgen.toml
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
language = "C"
|
||||||
|
include_guard = "__SECURITY_COORDINATOR_BINDINGS_H__"
|
||||||
|
autogen_warning = "/* Warning, this file is autogenerated by cbindgen. Don't modify this manually. */"
|
||||||
|
no_includes = true
|
||||||
|
|
||||||
|
[export]
|
||||||
|
include = ["SecurityRequestData", "SecurityReplyData", "SecurityRequest", "SecurityRequestError"]
|
@@ -0,0 +1,8 @@
|
|||||||
|
[package]
|
||||||
|
name = "kata-security-common"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2018"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
serde = { version = "1.0", default-features = false, features = ["alloc", "derive"] }
|
||||||
|
serde-big-array = "0.3"
|
@@ -0,0 +1,174 @@
|
|||||||
|
//! Kata OS Security Coordinator support
|
||||||
|
|
||||||
|
#![cfg_attr(not(test), no_std)]
|
||||||
|
|
||||||
|
extern crate alloc;
|
||||||
|
use alloc::string::String;
|
||||||
|
use core::str;
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
// NB: serde helper for arrays w/ >32 elements
|
||||||
|
// c.f. https://github.com/serde-rs/serde/pull/1860
|
||||||
|
use serde_big_array::big_array;
|
||||||
|
big_array! { BigArray; }
|
||||||
|
|
||||||
|
// Size of the buffers used to pass serialized data between Rust <> C.
|
||||||
|
// The data structure size is bounded by the camkes ipc buffer (2K bytes!)
|
||||||
|
// and also by it being allocated on the stack of the rpc glue code.
|
||||||
|
// So we need to balance these against being able to handle all values.
|
||||||
|
|
||||||
|
pub const SECURITY_REQUEST_DATA_SIZE: usize = 2048;
|
||||||
|
pub type SecurityRequestData = [u8; SECURITY_REQUEST_DATA_SIZE];
|
||||||
|
|
||||||
|
pub const SECURITY_REPLY_DATA_SIZE: usize = 2048;
|
||||||
|
pub type SecurityReplyData = [u8; SECURITY_REPLY_DATA_SIZE];
|
||||||
|
|
||||||
|
// NB: struct's marked repr(C) are processed by cbindgen to get a .h file
|
||||||
|
// used in camkes C interfaces.
|
||||||
|
|
||||||
|
mod mut_ptr_helper {
|
||||||
|
use super::*;
|
||||||
|
use serde::{Deserializer, Serializer};
|
||||||
|
|
||||||
|
pub fn serialize<T, S>(ptr: &*mut T, serializer: S) -> Result<S::Ok, S::Error>
|
||||||
|
where
|
||||||
|
S: Serializer,
|
||||||
|
{
|
||||||
|
(*ptr as usize).serialize(serializer)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn deserialize<'de, T, D>(deserializer: D) -> Result<*mut T, D::Error>
|
||||||
|
where
|
||||||
|
D: Deserializer<'de>,
|
||||||
|
{
|
||||||
|
Ok(usize::deserialize(deserializer)? as *mut T)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NB: SecurityRequestInstall is handled specially.
|
||||||
|
|
||||||
|
// SecurityRequestUninstall
|
||||||
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
|
pub struct UninstallRequest {
|
||||||
|
pub bundle_id: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
// SecurityRequestSizeBuffer
|
||||||
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
|
pub struct SizeBufferRequest {
|
||||||
|
pub bundle_id: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
// SecurityRequestGetManifest
|
||||||
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
|
pub struct GetManifestRequest {
|
||||||
|
pub bundle_id: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
// SecurityRequestLoadApplication
|
||||||
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
|
pub struct LoadApplicationRequest {
|
||||||
|
pub bundle_id: String,
|
||||||
|
|
||||||
|
// Scatter-list of shared memory pages where application should be loaded.
|
||||||
|
// TODO(sleffler) scatter list
|
||||||
|
#[serde(with = "mut_ptr_helper")]
|
||||||
|
pub app_binary: *mut u8,
|
||||||
|
}
|
||||||
|
|
||||||
|
// SecurityRequestLoadModel
|
||||||
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
|
pub struct LoadModelRequest {
|
||||||
|
pub bundle_id: String,
|
||||||
|
pub model_id: String,
|
||||||
|
|
||||||
|
// Scatter-list of shared memory pages where model should be loaded.
|
||||||
|
// TODO(sleffler) scatter list
|
||||||
|
#[serde(with = "mut_ptr_helper")]
|
||||||
|
pub model_binary: *mut u8,
|
||||||
|
}
|
||||||
|
|
||||||
|
// SecurityRequestReadKey
|
||||||
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
|
pub struct ReadKeyRequest {
|
||||||
|
pub bundle_id: String,
|
||||||
|
pub key: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
// SecurityRequestWriteKey
|
||||||
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
|
pub struct WriteKeyRequest<'a> {
|
||||||
|
pub bundle_id: String,
|
||||||
|
pub key: String,
|
||||||
|
pub value: &'a [u8],
|
||||||
|
}
|
||||||
|
|
||||||
|
// SecurityRequestDeleteKey
|
||||||
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
|
pub struct DeleteKeyRequest {
|
||||||
|
pub bundle_id: String,
|
||||||
|
pub key: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
// NB: this is the union of InstallInterface & StorageInterface because
|
||||||
|
// the camkes-generated interface code uses basic C which does not
|
||||||
|
// tolerate overlapping member names.
|
||||||
|
#[repr(C)]
|
||||||
|
#[derive(Debug, Eq, PartialEq)]
|
||||||
|
pub enum SecurityRequestError {
|
||||||
|
SreSuccess = 0,
|
||||||
|
SreBundleIdInvalid,
|
||||||
|
SreBundleDataInvalid,
|
||||||
|
SreBundleNotFound,
|
||||||
|
SreKeyNotFound,
|
||||||
|
SrePackageBufferLenInvalid,
|
||||||
|
SreValueInvalid,
|
||||||
|
SreKeyInvalid,
|
||||||
|
// Generic errors, mostly used in unit tests
|
||||||
|
SreInstallFailed,
|
||||||
|
SreUninstallFailed,
|
||||||
|
SreReadFailed,
|
||||||
|
SreWriteFailed,
|
||||||
|
SreDeleteFailed,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[repr(C)]
|
||||||
|
#[derive(Debug, Eq, PartialEq)]
|
||||||
|
pub enum SecurityRequest {
|
||||||
|
SrEcho = 0, // Security core replies with request payload
|
||||||
|
|
||||||
|
SrInstall, // Install package [pkg_buffer] -> bundle_id
|
||||||
|
SrUninstall, // Uninstall package [bundle_id]
|
||||||
|
|
||||||
|
SrSizeBuffer, // Size application image [bundle_id] -> u32
|
||||||
|
SrGetManifest, // Return application manifest [bundle_id] -> String
|
||||||
|
SrLoadApplication, // Load application [bundle_id]
|
||||||
|
// TODO(sleffler): define <tag>?
|
||||||
|
SrLoadModel, // Load ML model [bundle_id, <tag>]
|
||||||
|
|
||||||
|
SrReadKey, // Read key value [bundle_id, key] -> value
|
||||||
|
SrWriteKey, // Write key value [bundle_id, key, value]
|
||||||
|
SrDeleteKey, // Delete key [bundle_id, key]
|
||||||
|
}
|
||||||
|
|
||||||
|
// Interface to underlying facilities; also used to inject fakes for unit tests.
|
||||||
|
pub trait SecurityCoordinatorInterface {
|
||||||
|
fn request(
|
||||||
|
&mut self,
|
||||||
|
request_id: SecurityRequest,
|
||||||
|
request_buffer: &[u8],
|
||||||
|
reply_buffer: &mut [u8],
|
||||||
|
) -> Result<(), SecurityRequestError>;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Camkes-generated rpc api.
|
||||||
|
// NB: this requires the SecurityCoordinator component be named "security".
|
||||||
|
#[allow(dead_code)]
|
||||||
|
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;
|
||||||
|
}
|
@@ -0,0 +1,17 @@
|
|||||||
|
[package]
|
||||||
|
name = "kata-security-component"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2018"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
kata-allocator = { path = "../../DebugConsole/kata-allocator" }
|
||||||
|
kata-logger = { path = "../../DebugConsole/kata-logger" }
|
||||||
|
kata-panic = { path = "../../DebugConsole/kata-panic" }
|
||||||
|
kata-security-common = { path = "../kata-security-common" }
|
||||||
|
kata-security-coordinator = { path = "../kata-security-coordinator" }
|
||||||
|
log = "0.4"
|
||||||
|
|
||||||
|
[lib]
|
||||||
|
name = "kata_security_coordinator"
|
||||||
|
path = "src/run.rs"
|
||||||
|
crate-type = ["staticlib"]
|
@@ -0,0 +1,55 @@
|
|||||||
|
//! Kata OS Security Coordinator component support.
|
||||||
|
|
||||||
|
// Code here binds the camkes component to the rust code.
|
||||||
|
#![no_std]
|
||||||
|
|
||||||
|
use core::slice;
|
||||||
|
use kata_allocator;
|
||||||
|
use kata_logger::KataLogger;
|
||||||
|
extern crate kata_panic;
|
||||||
|
use kata_security_common::*;
|
||||||
|
use kata_security_coordinator::KATA_SECURITY;
|
||||||
|
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
|
||||||
|
// TODO(sleffler): should be used rarely
|
||||||
|
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()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Complete KATA_SECURITY setup. This is as early as we can do it given that
|
||||||
|
// it needs the GlobalAllocator.
|
||||||
|
unsafe {
|
||||||
|
KATA_SECURITY.init();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub extern "C" fn security_request(
|
||||||
|
c_request: SecurityRequest,
|
||||||
|
c_request_buffer_len: u32,
|
||||||
|
c_request_buffer: *const u8,
|
||||||
|
c_reply_buffer: *mut SecurityReplyData,
|
||||||
|
) -> SecurityRequestError {
|
||||||
|
unsafe {
|
||||||
|
KATA_SECURITY.request(
|
||||||
|
c_request,
|
||||||
|
slice::from_raw_parts(c_request_buffer, c_request_buffer_len as usize),
|
||||||
|
&mut (*c_reply_buffer)[..],
|
||||||
|
)
|
||||||
|
}
|
||||||
|
.map_or_else(|e| e, |_v| SecurityRequestError::SreSuccess)
|
||||||
|
}
|
@@ -0,0 +1,9 @@
|
|||||||
|
[package]
|
||||||
|
name = "kata-security-coordinator"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2018"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
kata-security-common = { path = "../kata-security-common" }
|
||||||
|
log = "0.4"
|
||||||
|
postcard = "0.7"
|
@@ -0,0 +1,150 @@
|
|||||||
|
//! Kata OS security coordinator support
|
||||||
|
|
||||||
|
#![cfg_attr(not(test), no_std)]
|
||||||
|
// NB: "error[E0658]: trait bounds other than `Sized` on const fn parameters are unstable"
|
||||||
|
#![feature(const_fn_trait_bound)]
|
||||||
|
|
||||||
|
extern crate alloc;
|
||||||
|
use alloc::boxed::Box;
|
||||||
|
use alloc::string::ToString;
|
||||||
|
use kata_security_common::*;
|
||||||
|
use log::trace;
|
||||||
|
use postcard;
|
||||||
|
|
||||||
|
#[cfg(not(test))]
|
||||||
|
pub static mut KATA_SECURITY: KataSecurityCoordinator = KataSecurityCoordinator::empty();
|
||||||
|
|
||||||
|
// KataSecurityCoordinator bundles an instance of the SecurityCoordinator that operates
|
||||||
|
// on KataOS interfaces. There is a two-step dance to setup an instance because we want
|
||||||
|
// KATA_STORAGE static.
|
||||||
|
// NB: no locking is done; we assume the caller/user is single-threaded
|
||||||
|
pub struct KataSecurityCoordinator {
|
||||||
|
manager: Option<Box<dyn SecurityCoordinatorInterface + Sync>>,
|
||||||
|
// TODO(sleffler): mailbox ipc state
|
||||||
|
}
|
||||||
|
impl KataSecurityCoordinator {
|
||||||
|
// Constructs a partially-initialized instance; to complete call init().
|
||||||
|
// This is needed because we need a const fn for static setup.
|
||||||
|
const fn empty() -> KataSecurityCoordinator {
|
||||||
|
KataSecurityCoordinator { manager: None }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn init(&mut self) {
|
||||||
|
self.manager = Some(Box::new(KataSecurityCoordinatorInterface));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl SecurityCoordinatorInterface for KataSecurityCoordinator {
|
||||||
|
fn request(
|
||||||
|
&mut self,
|
||||||
|
request_id: SecurityRequest,
|
||||||
|
request_buffer: &[u8],
|
||||||
|
reply_buffer: &mut [u8],
|
||||||
|
) -> Result<(), SecurityRequestError> {
|
||||||
|
self.manager
|
||||||
|
.as_mut()
|
||||||
|
.unwrap()
|
||||||
|
.request(request_id, request_buffer, reply_buffer)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct KataSecurityCoordinatorInterface;
|
||||||
|
// TODO(sleffler): move this to a feature-controlled fake
|
||||||
|
impl SecurityCoordinatorInterface for KataSecurityCoordinatorInterface {
|
||||||
|
fn request(
|
||||||
|
&mut self,
|
||||||
|
request_id: SecurityRequest,
|
||||||
|
request_buffer: &[u8],
|
||||||
|
reply_buffer: &mut [u8],
|
||||||
|
) -> Result<(), SecurityRequestError> {
|
||||||
|
fn serialize_failure(e: postcard::Error) -> SecurityRequestError {
|
||||||
|
trace!("serialize failed: {:?}", e);
|
||||||
|
SecurityRequestError::SreBundleDataInvalid
|
||||||
|
}
|
||||||
|
fn deserialize_failure(e: postcard::Error) -> SecurityRequestError {
|
||||||
|
trace!("deserialize failed: {:?}", e);
|
||||||
|
SecurityRequestError::SreBundleDataInvalid
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO(sleffler): mailbox ipc
|
||||||
|
match request_id {
|
||||||
|
SecurityRequest::SrEcho => {
|
||||||
|
trace!("ECHO {:?}", request_buffer);
|
||||||
|
reply_buffer[0..request_buffer.len()].copy_from_slice(&request_buffer[..]);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
SecurityRequest::SrInstall => {
|
||||||
|
trace!(
|
||||||
|
"INSTALL addr {:p} len {}",
|
||||||
|
request_buffer.as_ptr(),
|
||||||
|
request_buffer.len()
|
||||||
|
);
|
||||||
|
let _ = postcard::to_slice(
|
||||||
|
&(request_buffer.as_ptr() as usize).to_string(),
|
||||||
|
reply_buffer,
|
||||||
|
)
|
||||||
|
.map_err(serialize_failure)?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
SecurityRequest::SrUninstall => {
|
||||||
|
let request = postcard::from_bytes::<UninstallRequest>(&request_buffer[..])
|
||||||
|
.map_err(deserialize_failure)?;
|
||||||
|
trace!("UNINSTALL {}", request.bundle_id);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
SecurityRequest::SrSizeBuffer => {
|
||||||
|
let request = postcard::from_bytes::<SizeBufferRequest>(&request_buffer[..])
|
||||||
|
.map_err(deserialize_failure)?;
|
||||||
|
trace!("SIZE BUFFER bundle_id {}", request.bundle_id);
|
||||||
|
let _ = postcard::to_slice(
|
||||||
|
&0u32, // TODO(sleffler): fill-in
|
||||||
|
reply_buffer
|
||||||
|
).map_err(serialize_failure)?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
SecurityRequest::SrGetManifest => {
|
||||||
|
let request = postcard::from_bytes::<SizeBufferRequest>(&request_buffer[..])
|
||||||
|
.map_err(deserialize_failure)?;
|
||||||
|
trace!("GET MANIFEST bundle_id {}", request.bundle_id);
|
||||||
|
let _ = postcard::to_slice(
|
||||||
|
"# Comments like this
|
||||||
|
[Manifest]
|
||||||
|
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(())
|
||||||
|
}
|
||||||
|
SecurityRequest::SrLoadApplication => {
|
||||||
|
let request = postcard::from_bytes::<LoadApplicationRequest>(&request_buffer[..])
|
||||||
|
.map_err(deserialize_failure)?;
|
||||||
|
trace!(
|
||||||
|
"LOAD APPLICATION bundle_id {} addr {:p}",
|
||||||
|
request.bundle_id,
|
||||||
|
request.app_binary
|
||||||
|
);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
SecurityRequest::SrLoadModel => {
|
||||||
|
let request = postcard::from_bytes::<LoadModelRequest>(&request_buffer[..])
|
||||||
|
.map_err(deserialize_failure)?;
|
||||||
|
trace!(
|
||||||
|
"LOAD MODEL bundle_id {} model_id {} addr {:p}",
|
||||||
|
request.bundle_id,
|
||||||
|
request.model_id,
|
||||||
|
request.model_binary
|
||||||
|
);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
SecurityRequest::SrReadKey => Err(SecurityRequestError::SreReadFailed),
|
||||||
|
SecurityRequest::SrWriteKey => Err(SecurityRequestError::SreWriteFailed),
|
||||||
|
SecurityRequest::SrDeleteKey => Err(SecurityRequestError::SreDeleteFailed),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -3,10 +3,10 @@
|
|||||||
|
|
||||||
/* Warning, this file is autogenerated by cbindgen. Don't modify this manually. */
|
/* Warning, this file is autogenerated by cbindgen. Don't modify this manually. */
|
||||||
|
|
||||||
#define DEFAULT_BUNDLE_ID_CAPACITY 64
|
|
||||||
|
|
||||||
#define RAW_BUNDLE_ID_DATA_SIZE 100
|
#define RAW_BUNDLE_ID_DATA_SIZE 100
|
||||||
|
|
||||||
|
#define DEFAULT_BUNDLE_ID_CAPACITY 64
|
||||||
|
|
||||||
typedef enum ProcessManagerError {
|
typedef enum ProcessManagerError {
|
||||||
Success = 0,
|
Success = 0,
|
||||||
BundleIdInvalid,
|
BundleIdInvalid,
|
||||||
|
41
apps/system/interfaces/SecurityCoordinatorBindings.h
Normal file
41
apps/system/interfaces/SecurityCoordinatorBindings.h
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
#ifndef __SECURITY_COORDINATOR_BINDINGS_H__
|
||||||
|
#define __SECURITY_COORDINATOR_BINDINGS_H__
|
||||||
|
|
||||||
|
/* Warning, this file is autogenerated by cbindgen. Don't modify this manually. */
|
||||||
|
|
||||||
|
#define SECURITY_REQUEST_DATA_SIZE 2048
|
||||||
|
|
||||||
|
#define SECURITY_REPLY_DATA_SIZE 2048
|
||||||
|
|
||||||
|
typedef enum SecurityRequest {
|
||||||
|
SrEcho = 0,
|
||||||
|
SrInstall,
|
||||||
|
SrUninstall,
|
||||||
|
SrLoadApplication,
|
||||||
|
SrLoadModel,
|
||||||
|
SrReadKey,
|
||||||
|
SrWriteKey,
|
||||||
|
SrDeleteKey,
|
||||||
|
} SecurityRequest;
|
||||||
|
|
||||||
|
typedef enum SecurityRequestError {
|
||||||
|
SreSuccess = 0,
|
||||||
|
SreBundleIdInvalid,
|
||||||
|
SreBundleDataInvalid,
|
||||||
|
SreBundleNotFound,
|
||||||
|
SreKeyNotFound,
|
||||||
|
SrePackageBufferLenInvalid,
|
||||||
|
SreValueInvalid,
|
||||||
|
SreKeyInvalid,
|
||||||
|
SreInstallFailed,
|
||||||
|
SreUninstallFailed,
|
||||||
|
SreReadFailed,
|
||||||
|
SreWriteFailed,
|
||||||
|
SreDeleteFailed,
|
||||||
|
} SecurityRequestError;
|
||||||
|
|
||||||
|
typedef uint8_t SecurityRequestData[SECURITY_REQUEST_DATA_SIZE];
|
||||||
|
|
||||||
|
typedef uint8_t SecurityReplyData[SECURITY_REPLY_DATA_SIZE];
|
||||||
|
|
||||||
|
#endif /* __SECURITY_COORDINATOR_BINDINGS_H__ */
|
@@ -0,0 +1,5 @@
|
|||||||
|
procedure SecurityCoordinatorInterface {
|
||||||
|
include <SecurityCoordinatorBindings.h>;
|
||||||
|
|
||||||
|
SecurityRequestError request(in int request_id, in char request[], out SecurityReplyData reply);
|
||||||
|
};
|
@@ -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/SecurityCoordinator/SecurityCoordinator.camkes";
|
||||||
import "components/VectorCoreDriver/VectorCoreDriver.camkes";
|
import "components/VectorCoreDriver/VectorCoreDriver.camkes";
|
||||||
|
|
||||||
component OpenTitanUART {
|
component OpenTitanUART {
|
||||||
@@ -49,6 +50,7 @@ assembly {
|
|||||||
component ProcessManager process_manager;
|
component ProcessManager process_manager;
|
||||||
component MlCoordinator ml_coordinator;
|
component MlCoordinator ml_coordinator;
|
||||||
component DebugConsole debug_console;
|
component DebugConsole debug_console;
|
||||||
|
component SecurityCoordinator security_coordinator;
|
||||||
|
|
||||||
// OpenTitanUARTDriver
|
// OpenTitanUARTDriver
|
||||||
connection seL4HardwareMMIO uart_mem(from uart_driver.mmio_region,
|
connection seL4HardwareMMIO uart_mem(from uart_driver.mmio_region,
|
||||||
@@ -73,6 +75,15 @@ assembly {
|
|||||||
connection seL4RPCCall shell_ml(from debug_console.mlcoord,
|
connection seL4RPCCall shell_ml(from debug_console.mlcoord,
|
||||||
to ml_coordinator.mlcoord);
|
to ml_coordinator.mlcoord);
|
||||||
|
|
||||||
|
// Connect the SecurityCoordinatorInterface to each component that needs
|
||||||
|
// access to the Security Core. Note this allocates a 4KB shared memory
|
||||||
|
// region to each component and copies data between components.
|
||||||
|
connection seL4RPCOverMultiSharedData multi_security(
|
||||||
|
from debug_console.security, // NB: for debug/test
|
||||||
|
from process_manager.security,
|
||||||
|
from ml_coordinator.security, // NB: for LoadModel but not in design
|
||||||
|
to security_coordinator.security);
|
||||||
|
|
||||||
// Connect the DebugConsole to the OpenTitanUARTDriver.
|
// Connect the DebugConsole to the OpenTitanUARTDriver.
|
||||||
connection seL4SharedData tx_channel(
|
connection seL4SharedData tx_channel(
|
||||||
from debug_console.tx_dataport, to uart_driver.tx_dataport);
|
from debug_console.tx_dataport, to uart_driver.tx_dataport);
|
||||||
@@ -89,6 +100,7 @@ assembly {
|
|||||||
connection seL4RPCOverMultiSharedData multi_logger(
|
connection seL4RPCOverMultiSharedData multi_logger(
|
||||||
from process_manager.logger,
|
from process_manager.logger,
|
||||||
from ml_coordinator.logger,
|
from ml_coordinator.logger,
|
||||||
|
from security_coordinator.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.
|
||||||
|
Reference in New Issue
Block a user