mirror of
https://github.com/AmbiML/sparrow-kata-full.git
synced 2025-08-31 05:06:04 +00:00
SecurityCoordinator: overhaul server side
This mostly cleans up my bad idea of how to process SecurityRequests. - accept an ObjDescBundle attached in an InstallRequest - return a BundleImage in LoadApplication & LoadNModel replies - integrate with the slot allocator - integrate with MemoryManager (for the fake) Change-Id: I695efbecabfa3e71d7d2cfdd013c113a5a915b40 GitOrigin-RevId: 623ffdf19f5550918da530b57a299659061832aa
This commit is contained in:
@@ -9,7 +9,9 @@ edition = "2021"
|
||||
kata-os-common = { path = "../../kata-os-common" }
|
||||
kata-security-interface = { path = "../kata-security-interface" }
|
||||
kata-security-coordinator = { path = "../kata-security-coordinator" }
|
||||
kata-storage-interface = { path = "../../StorageManager/kata-storage-interface" }
|
||||
log = "0.4"
|
||||
postcard = { version = "0.7", features = ["alloc"], default-features = false }
|
||||
|
||||
[lib]
|
||||
name = "kata_security_coordinator"
|
||||
|
@@ -6,12 +6,37 @@
|
||||
use core::slice;
|
||||
use kata_os_common::allocator;
|
||||
use kata_os_common::logger::KataLogger;
|
||||
use kata_os_common::sel4_sys;
|
||||
use kata_os_common::slot_allocator;
|
||||
use kata_security_coordinator::KATA_SECURITY;
|
||||
use kata_security_interface::SecurityCoordinatorInterface;
|
||||
use kata_security_interface::SecurityReplyData;
|
||||
use kata_security_interface::SecurityRequest;
|
||||
use kata_security_interface::SecurityRequestError;
|
||||
use log::trace;
|
||||
use kata_security_interface::*;
|
||||
use kata_storage_interface::KEY_VALUE_DATA_SIZE;
|
||||
use log::{info, trace};
|
||||
use postcard;
|
||||
|
||||
use SecurityRequestError::*;
|
||||
|
||||
use sel4_sys::seL4_CNode_Delete;
|
||||
use sel4_sys::seL4_CPtr;
|
||||
use sel4_sys::seL4_GetCapReceivePath;
|
||||
use sel4_sys::seL4_SetCap;
|
||||
use sel4_sys::seL4_SetCapReceivePath;
|
||||
use sel4_sys::seL4_Word;
|
||||
use sel4_sys::seL4_WordBits;
|
||||
|
||||
use slot_allocator::CSpaceSlot;
|
||||
use slot_allocator::KATA_CSPACE_SLOTS;
|
||||
|
||||
extern "C" {
|
||||
// Each CAmkES-generated CNode has a writable self-reference to itself in
|
||||
// the slot SELF_CNODE.
|
||||
static SELF_CNODE: seL4_CPtr;
|
||||
|
||||
static SELF_CNODE_FIRST_SLOT: seL4_CPtr;
|
||||
static SELF_CNODE_LAST_SLOT: seL4_CPtr;
|
||||
}
|
||||
|
||||
static mut SECURITY_RECV_SLOT: seL4_CPtr = 0;
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn pre_init() {
|
||||
@@ -20,11 +45,9 @@ pub extern "C" fn pre_init() {
|
||||
// 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 {
|
||||
allocator::ALLOCATOR.init(HEAP_MEMORY.as_mut_ptr() as usize, HEAP_MEMORY.len());
|
||||
allocator::ALLOCATOR.init(HEAP_MEMORY.as_mut_ptr() as usize, HEAP_MEMORY.len());
|
||||
trace!(
|
||||
"setup heap: start_addr {:p} size {}",
|
||||
HEAP_MEMORY.as_ptr(),
|
||||
@@ -37,6 +60,239 @@ pub extern "C" fn pre_init() {
|
||||
unsafe {
|
||||
KATA_SECURITY.init();
|
||||
}
|
||||
|
||||
unsafe {
|
||||
KATA_CSPACE_SLOTS.init(
|
||||
/*first_slot=*/ SELF_CNODE_FIRST_SLOT,
|
||||
/*size=*/ SELF_CNODE_LAST_SLOT - SELF_CNODE_FIRST_SLOT
|
||||
);
|
||||
trace!("setup cspace slots: first slot {} free {}",
|
||||
KATA_CSPACE_SLOTS.base_slot(),
|
||||
KATA_CSPACE_SLOTS.free_slots());
|
||||
|
||||
SECURITY_RECV_SLOT = KATA_CSPACE_SLOTS.alloc(1).unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn security__init() {
|
||||
unsafe {
|
||||
// Point the receive path to the well-known empty slot. This will be
|
||||
// used to receive CNode's from clients for install requests.
|
||||
//
|
||||
// NB: this must be done here (rather than someplace like pre_init)
|
||||
// so it's in the context of the SecurityCoordinatorInterface thread
|
||||
// (so we write the correct ipc buffer).
|
||||
let path = (SELF_CNODE, SECURITY_RECV_SLOT, seL4_WordBits);
|
||||
seL4_SetCapReceivePath(path.0, path.1, path.2);
|
||||
info!("security cap receive path {:?}", path);
|
||||
debug_check_empty("security__init", &path);
|
||||
}
|
||||
}
|
||||
|
||||
fn debug_check_empty(tag: &str, path: &(seL4_CPtr, seL4_CPtr, seL4_Word)) {
|
||||
sel4_sys::debug_assert_slot_empty!(path.1,
|
||||
"{}: expected slot {:?} empty but has cap type {:?}",
|
||||
tag, path, sel4_sys::cap_identify(path.1));
|
||||
}
|
||||
|
||||
// Clears any capability the specified path points to.
|
||||
fn _clear_path(path: &(seL4_CPtr, seL4_CPtr, seL4_Word)) {
|
||||
// TODO(sleffler): assert since future receives are likely to fail?
|
||||
if let Err(e) = unsafe { seL4_CNode_Delete(path.0, path.1, path.2 as u8) } {
|
||||
// NB: no error is returned if the slot is empty.
|
||||
info!("Failed to clear receive path {:?}: {:?}", path, e);
|
||||
}
|
||||
debug_check_empty("clear_path", path);
|
||||
}
|
||||
|
||||
fn serialize_failure(e: postcard::Error) -> SecurityRequestError {
|
||||
trace!("serialize failed: {:?}", e);
|
||||
SreBundleDataInvalid
|
||||
}
|
||||
fn deserialize_failure(e: postcard::Error) -> SecurityRequestError {
|
||||
trace!("deserialize failed: {:?}", e);
|
||||
SreDeserializeFailed
|
||||
}
|
||||
|
||||
fn echo_request(
|
||||
request_buffer: &[u8],
|
||||
reply_buffer: &mut [u8]
|
||||
) -> Result<(), SecurityRequestError> {
|
||||
let request = postcard::from_bytes::<EchoRequest>(&request_buffer[..])
|
||||
.map_err(deserialize_failure)?;
|
||||
|
||||
trace!("ECHO {:?}", request.value);
|
||||
// NB: cheat, bypass serde
|
||||
reply_buffer[0..request.value.len()].copy_from_slice(request.value);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn install_request(
|
||||
request_buffer: &[u8],
|
||||
reply_buffer: &mut [u8]
|
||||
) -> Result<(), SecurityRequestError> {
|
||||
let recv_path = unsafe { seL4_GetCapReceivePath() };
|
||||
sel4_sys::debug_assert_slot_cnode!(recv_path.1,
|
||||
"install_request: expected cnode in slot {:?} but found cap type {:?}",
|
||||
recv_path, sel4_sys::cap_identify(recv_path.1));
|
||||
|
||||
let mut request = postcard::from_bytes::<InstallRequest>(&request_buffer[..])
|
||||
.map_err(deserialize_failure)?; // XXX clear_path
|
||||
|
||||
// Move the container CNode so it's not clobbered.
|
||||
// XXX who should be responsible for this
|
||||
let mut container_slot = CSpaceSlot::new();
|
||||
container_slot.move_to(recv_path.0, recv_path.1, recv_path.2 as u8)
|
||||
.map_err(|_| SecurityRequestError::SreCapMoveFailed)?; // XXX expect?
|
||||
request.set_container_cap(container_slot.slot);
|
||||
container_slot.release();
|
||||
|
||||
let bundle_id = unsafe { KATA_SECURITY.install(&request.pkg_contents) }?;
|
||||
let _ = postcard::to_slice(
|
||||
&InstallResponse {
|
||||
bundle_id: &bundle_id,
|
||||
},
|
||||
reply_buffer,
|
||||
).map_err(serialize_failure)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn uninstall_request(
|
||||
request_buffer: &[u8],
|
||||
_reply_buffer: &mut [u8]
|
||||
) -> Result<(), SecurityRequestError> {
|
||||
let request = postcard::from_bytes::<UninstallRequest>(&request_buffer[..])
|
||||
.map_err(deserialize_failure)?;
|
||||
|
||||
trace!("UNINSTALL {}", request.bundle_id);
|
||||
unsafe { KATA_SECURITY.uninstall(request.bundle_id) }
|
||||
}
|
||||
|
||||
fn size_buffer_request(
|
||||
request_buffer: &[u8],
|
||||
reply_buffer: &mut [u8]
|
||||
) -> Result<(), SecurityRequestError> {
|
||||
let request = postcard::from_bytes::<SizeBufferRequest>(&request_buffer[..])
|
||||
.map_err(deserialize_failure)?;
|
||||
|
||||
trace!("SIZE BUFFER bundle_id {}", request.bundle_id);
|
||||
let buffer_size = unsafe { KATA_SECURITY.size_buffer(request.bundle_id) }?;
|
||||
let _ = postcard::to_slice(
|
||||
&SizeBufferResponse {
|
||||
buffer_size: buffer_size,
|
||||
},
|
||||
reply_buffer,
|
||||
).map_err(serialize_failure)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn get_manifest_request(
|
||||
request_buffer: &[u8],
|
||||
reply_buffer: &mut [u8]
|
||||
) -> Result<(), SecurityRequestError> {
|
||||
let request = postcard::from_bytes::<GetManifestRequest>(&request_buffer[..])
|
||||
.map_err(deserialize_failure)?;
|
||||
|
||||
trace!("GET MANIFEST bundle_id {}", request.bundle_id);
|
||||
let manifest = unsafe { KATA_SECURITY.get_manifest(request.bundle_id) }?;
|
||||
let _ = postcard::to_slice(
|
||||
&GetManifestResponse {
|
||||
manifest: &manifest,
|
||||
},
|
||||
reply_buffer
|
||||
).map_err(serialize_failure)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn load_application_request(
|
||||
request_buffer: &[u8],
|
||||
reply_buffer: &mut [u8]
|
||||
) -> Result<(), SecurityRequestError> {
|
||||
let request = postcard::from_bytes::<LoadApplicationRequest>(&request_buffer[..])
|
||||
.map_err(deserialize_failure)?;
|
||||
|
||||
trace!("LOAD APPLICATION bundle_id {}", request.bundle_id);
|
||||
let bundle_frames = unsafe {
|
||||
KATA_SECURITY.load_application(request.bundle_id)
|
||||
}?;
|
||||
postcard::to_slice(
|
||||
&LoadApplicationResponse {
|
||||
bundle_frames: bundle_frames.clone(),
|
||||
},
|
||||
reply_buffer
|
||||
).map_err(serialize_failure)?;
|
||||
trace!("LOAD APPLICATION -> {}", bundle_frames);
|
||||
unsafe { seL4_SetCap(0, bundle_frames.cnode) };
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn load_model_request(
|
||||
request_buffer: &[u8],
|
||||
reply_buffer: &mut [u8]
|
||||
) -> Result<(), SecurityRequestError> {
|
||||
let request = postcard::from_bytes::<LoadModelRequest>(&request_buffer[..])
|
||||
.map_err(deserialize_failure)?;
|
||||
|
||||
let model_frames = unsafe {
|
||||
KATA_SECURITY.load_model(request.bundle_id, request.model_id)
|
||||
}?;
|
||||
let _ = postcard::to_slice(
|
||||
&LoadApplicationResponse {
|
||||
bundle_frames: model_frames.clone(),
|
||||
},
|
||||
reply_buffer
|
||||
).map_err(serialize_failure)?;
|
||||
trace!("LOAD MODEL -> {}", model_frames);
|
||||
unsafe { seL4_SetCap(0, model_frames.cnode) };
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn read_key_request(
|
||||
request_buffer: &[u8],
|
||||
reply_buffer: &mut [u8]
|
||||
) -> Result<(), SecurityRequestError> {
|
||||
let request = postcard::from_bytes::<ReadKeyRequest>(&request_buffer[..])
|
||||
.map_err(deserialize_failure)?;
|
||||
|
||||
trace!("READ KEY bundle_id {} key {}", request.bundle_id, request.key);
|
||||
let value = unsafe {
|
||||
KATA_SECURITY.read_key(request.bundle_id, request.key)
|
||||
}?;
|
||||
let _ = postcard::to_slice(
|
||||
&ReadKeyResponse {
|
||||
value: value,
|
||||
},
|
||||
reply_buffer
|
||||
).map_err(serialize_failure);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn write_key_request(
|
||||
request_buffer: &[u8],
|
||||
_reply_buffer: &mut [u8]
|
||||
) -> Result<(), SecurityRequestError> {
|
||||
let request = postcard::from_bytes::<WriteKeyRequest>(&request_buffer[..])
|
||||
.map_err(deserialize_failure)?;
|
||||
|
||||
trace!("WRITE KEY bundle_id {} key {} value {:?}",
|
||||
request.bundle_id, request.key, request.value);
|
||||
// NB: the serialized data are variable length so copy to convert
|
||||
let mut keyval = [0u8; KEY_VALUE_DATA_SIZE];
|
||||
keyval[..request.value.len()].copy_from_slice(request.value);
|
||||
unsafe { KATA_SECURITY.write_key( request.bundle_id, request.key, &keyval) }
|
||||
}
|
||||
|
||||
fn delete_key_request(
|
||||
request_buffer: &[u8],
|
||||
_reply_buffer: &mut [u8]
|
||||
) -> Result<(), SecurityRequestError> {
|
||||
let request = postcard::from_bytes::<DeleteKeyRequest>(&request_buffer[..])
|
||||
.map_err(deserialize_failure)?;
|
||||
|
||||
trace!("DELETE KEY bundle_id {} key {}", request.bundle_id, request.key);
|
||||
unsafe { KATA_SECURITY.delete_key(request.bundle_id, request.key) }
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
@@ -46,12 +302,30 @@ pub extern "C" fn security_request(
|
||||
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)
|
||||
let request_buffer = unsafe {
|
||||
slice::from_raw_parts(c_request_buffer, c_request_buffer_len as usize)
|
||||
};
|
||||
let reply_buffer = unsafe { &mut (*c_reply_buffer)[..] };
|
||||
match c_request {
|
||||
SecurityRequest::SrEcho =>
|
||||
echo_request(request_buffer, reply_buffer),
|
||||
SecurityRequest::SrInstall =>
|
||||
install_request(request_buffer, reply_buffer),
|
||||
SecurityRequest::SrUninstall =>
|
||||
uninstall_request(request_buffer, reply_buffer),
|
||||
SecurityRequest::SrSizeBuffer =>
|
||||
size_buffer_request(request_buffer, reply_buffer),
|
||||
SecurityRequest::SrGetManifest =>
|
||||
get_manifest_request(request_buffer, reply_buffer),
|
||||
SecurityRequest::SrLoadApplication =>
|
||||
load_application_request(request_buffer, reply_buffer),
|
||||
SecurityRequest::SrLoadModel =>
|
||||
load_model_request(request_buffer, reply_buffer),
|
||||
SecurityRequest::SrReadKey =>
|
||||
read_key_request(request_buffer, reply_buffer),
|
||||
SecurityRequest::SrWriteKey =>
|
||||
write_key_request(request_buffer, reply_buffer),
|
||||
SecurityRequest::SrDeleteKey =>
|
||||
delete_key_request(request_buffer, reply_buffer),
|
||||
}.map_or_else(|e| e, |_v| SecurityRequestError::SreSuccess)
|
||||
}
|
||||
|
@@ -12,6 +12,8 @@ sel4 = []
|
||||
|
||||
[dependencies]
|
||||
hashbrown = { version = "0.11", features = ["ahash-compile-time-rng"] }
|
||||
kata-memory-interface = { path = "../../MemoryManager/kata-memory-interface" }
|
||||
kata-os-common = { path = "../../kata-os-common" }
|
||||
kata-security-interface = { path = "../kata-security-interface" }
|
||||
kata-storage-interface = { path = "../../StorageManager/kata-storage-interface" }
|
||||
log = "0.4"
|
||||
|
@@ -3,31 +3,36 @@
|
||||
extern crate alloc;
|
||||
use alloc::string::{String, ToString};
|
||||
use hashbrown::HashMap;
|
||||
use kata_security_interface::DeleteKeyRequest;
|
||||
use kata_security_interface::GetManifestRequest;
|
||||
use kata_security_interface::LoadApplicationRequest;
|
||||
use kata_security_interface::LoadModelRequest;
|
||||
use kata_security_interface::ReadKeyRequest;
|
||||
use kata_security_interface::SecurityCoordinatorInterface;
|
||||
use kata_security_interface::SecurityRequest;
|
||||
use kata_security_interface::SecurityRequestError;
|
||||
use kata_security_interface::SizeBufferRequest;
|
||||
use kata_security_interface::UninstallRequest;
|
||||
use kata_security_interface::WriteKeyRequest;
|
||||
use kata_os_common::sel4_sys;
|
||||
use kata_os_common::slot_allocator;
|
||||
use kata_memory_interface::ObjDescBundle;
|
||||
use kata_memory_interface::kata_object_free;
|
||||
use kata_security_interface::*;
|
||||
use kata_storage_interface::KeyValueData;
|
||||
use kata_storage_interface::KEY_VALUE_DATA_SIZE;
|
||||
use log::trace;
|
||||
use postcard;
|
||||
use log::error;
|
||||
|
||||
use sel4_sys::seL4_CNode_Delete;
|
||||
use sel4_sys::seL4_CPtr;
|
||||
use sel4_sys::seL4_WordBits;
|
||||
|
||||
use slot_allocator::KATA_CSPACE_SLOTS;
|
||||
|
||||
extern "C" {
|
||||
static SELF_CNODE: seL4_CPtr;
|
||||
}
|
||||
|
||||
struct BundleData {
|
||||
pkg_contents: ObjDescBundle,
|
||||
pkg_size: usize,
|
||||
manifest: String,
|
||||
keys: HashMap<String, KeyValueData>,
|
||||
}
|
||||
impl BundleData {
|
||||
fn new(pkg_size: usize) -> Self {
|
||||
fn new(pkg_contents: &ObjDescBundle) -> Self {
|
||||
let size = pkg_contents.objs.len() * 4096; // XXX
|
||||
BundleData {
|
||||
pkg_size: pkg_size,
|
||||
pkg_contents: pkg_contents.clone(),
|
||||
pkg_size: size,
|
||||
manifest: String::from(
|
||||
"# Comments like this
|
||||
[Manifest]
|
||||
@@ -45,6 +50,18 @@ impl BundleData {
|
||||
}
|
||||
}
|
||||
}
|
||||
impl Drop for BundleData {
|
||||
fn drop(&mut self) {
|
||||
let _ = kata_object_free(&self.pkg_contents);
|
||||
unsafe {
|
||||
KATA_CSPACE_SLOTS.free(self.pkg_contents.cnode, 1);
|
||||
if let Err(e) = seL4_CNode_Delete(SELF_CNODE, self.pkg_contents.cnode, seL4_WordBits as u8) {
|
||||
// XXX no bundle_id
|
||||
error!("Error deleting CNode {}, error {:?}", self.pkg_contents.cnode, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct FakeSecurityCoordinator {
|
||||
bundles: HashMap<String, BundleData>,
|
||||
@@ -75,144 +92,50 @@ impl FakeSecurityCoordinator {
|
||||
pub type KataSecurityCoordinatorInterface = FakeSecurityCoordinator;
|
||||
|
||||
impl SecurityCoordinatorInterface for FakeSecurityCoordinator {
|
||||
fn request(
|
||||
&mut self,
|
||||
request_id: SecurityRequest,
|
||||
request_buffer: &[u8],
|
||||
reply_buffer: &mut [u8],
|
||||
) -> Result<(), SecurityRequestError> {
|
||||
use SecurityRequestError::*;
|
||||
|
||||
fn serialize_failure(e: postcard::Error) -> SecurityRequestError {
|
||||
trace!("serialize failed: {:?}", e);
|
||||
SreBundleDataInvalid
|
||||
}
|
||||
fn deserialize_failure(e: postcard::Error) -> SecurityRequestError {
|
||||
trace!("deserialize failed: {:?}", e);
|
||||
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 bundle_id = (request_buffer.as_ptr() as usize).to_string();
|
||||
// TODO(sleffler): used by kata-storage-component for kvops
|
||||
let bundle_id = "fubar".to_string();
|
||||
let _ = postcard::to_slice(&bundle_id, reply_buffer).map_err(serialize_failure)?;
|
||||
assert!(self
|
||||
.bundles
|
||||
.insert(bundle_id, BundleData::new(request_buffer.len()))
|
||||
.is_none());
|
||||
Ok(())
|
||||
}
|
||||
SecurityRequest::SrUninstall => {
|
||||
let request = postcard::from_bytes::<UninstallRequest>(&request_buffer[..])
|
||||
.map_err(deserialize_failure)?;
|
||||
trace!("UNINSTALL {}", request.bundle_id);
|
||||
self.remove_bundle(&request.bundle_id)
|
||||
}
|
||||
SecurityRequest::SrSizeBuffer => {
|
||||
let request = postcard::from_bytes::<SizeBufferRequest>(&request_buffer[..])
|
||||
.map_err(deserialize_failure)?;
|
||||
trace!("SIZE BUFFER bundle_id {}", request.bundle_id);
|
||||
let bundle = self.get_bundle(&request.bundle_id)?;
|
||||
let _ = postcard::to_slice(
|
||||
&bundle.pkg_size, // TODO(sleffler): do better
|
||||
reply_buffer,
|
||||
)
|
||||
.map_err(serialize_failure)?;
|
||||
Ok(())
|
||||
}
|
||||
SecurityRequest::SrGetManifest => {
|
||||
let request = postcard::from_bytes::<GetManifestRequest>(&request_buffer[..])
|
||||
.map_err(deserialize_failure)?;
|
||||
trace!("GET MANIFEST bundle_id {}", request.bundle_id);
|
||||
let bundle = self.get_bundle(&request.bundle_id)?;
|
||||
let _ = postcard::to_slice(&bundle.manifest, 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
|
||||
);
|
||||
let _ = self.get_bundle(&request.bundle_id)?;
|
||||
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
|
||||
);
|
||||
// TODO(sleffler): check model id
|
||||
let _ = self.get_bundle(&request.bundle_id)?;
|
||||
Ok(())
|
||||
}
|
||||
SecurityRequest::SrReadKey => {
|
||||
let request = postcard::from_bytes::<ReadKeyRequest>(&request_buffer[..])
|
||||
.map_err(deserialize_failure)?;
|
||||
trace!(
|
||||
"READ KEY bundle_id {} key {}",
|
||||
request.bundle_id,
|
||||
request.key,
|
||||
);
|
||||
let bundle = self.get_bundle(&request.bundle_id)?;
|
||||
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 => {
|
||||
let request = postcard::from_bytes::<WriteKeyRequest>(&request_buffer[..])
|
||||
.map_err(deserialize_failure)?;
|
||||
trace!(
|
||||
"WRITE KEY bundle_id {} key {} value {:?}",
|
||||
request.bundle_id,
|
||||
request.key,
|
||||
request.value,
|
||||
);
|
||||
let bundle = self.get_bundle_mut(&request.bundle_id)?;
|
||||
// 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.to_string(), value);
|
||||
Ok(())
|
||||
}
|
||||
SecurityRequest::SrDeleteKey => {
|
||||
let request = postcard::from_bytes::<DeleteKeyRequest>(&request_buffer[..])
|
||||
.map_err(deserialize_failure)?;
|
||||
trace!(
|
||||
"DELETE KEY bundle_id {} key {}",
|
||||
request.bundle_id,
|
||||
request.key,
|
||||
);
|
||||
let bundle = self.get_bundle_mut(&request.bundle_id)?;
|
||||
// TODO(sleffler): error if no entry?
|
||||
let _ = bundle.keys.remove(request.key);
|
||||
Ok(())
|
||||
}
|
||||
fn install(&mut self, pkg_contents: &ObjDescBundle) -> Result<String, SecurityRequestError> {
|
||||
let bundle_id = "fubar".to_string(); // XXX
|
||||
if self.bundles.contains_key(&bundle_id) {
|
||||
return Err(SecurityRequestError::SreDeleteFirst);
|
||||
}
|
||||
assert!(self.bundles.insert(bundle_id.clone(), BundleData::new(pkg_contents)).is_none());
|
||||
Ok(bundle_id)
|
||||
}
|
||||
fn uninstall(&mut self, bundle_id: &str) -> Result<(), SecurityRequestError> {
|
||||
self.remove_bundle(bundle_id)
|
||||
}
|
||||
fn size_buffer(&self, bundle_id: &str) -> Result<usize, SecurityRequestError> {
|
||||
let bundle = self.get_bundle(bundle_id)?;
|
||||
Ok(bundle.pkg_size) // TODO(sleffler): do better
|
||||
}
|
||||
fn get_manifest(&self, bundle_id: &str) -> Result<String, SecurityRequestError> {
|
||||
let bundle = self.get_bundle(bundle_id)?;
|
||||
// return &?
|
||||
Ok(bundle.manifest.clone())
|
||||
}
|
||||
fn load_application(&self, bundle_id: &str) -> Result<ObjDescBundle, SecurityRequestError> {
|
||||
let bundle_data = self.get_bundle(bundle_id)?;
|
||||
// XXX just return the package for now
|
||||
Ok(bundle_data.pkg_contents.clone())
|
||||
}
|
||||
fn load_model(&self, bundle_id: &str, _model_id: &str) -> Result<ObjDescBundle, SecurityRequestError> {
|
||||
let bundle_data = self.get_bundle(bundle_id)?;
|
||||
// TODO(sleffler): check model id
|
||||
// XXX just return the package for now
|
||||
Ok(bundle_data.pkg_contents.clone())
|
||||
}
|
||||
fn read_key(&self, bundle_id: &str, key: &str) -> Result<&KeyValueData, SecurityRequestError> {
|
||||
let bundle = self.get_bundle(bundle_id)?;
|
||||
bundle.keys.get(key).ok_or(SecurityRequestError::SreKeyNotFound)
|
||||
}
|
||||
fn write_key(&mut self, bundle_id: &str, key: &str, value: &KeyValueData) -> Result<(), SecurityRequestError> {
|
||||
let bundle = self.get_bundle_mut(bundle_id)?;
|
||||
let _ = bundle.keys.insert(key.to_string(), *value);
|
||||
Ok(())
|
||||
}
|
||||
fn delete_key(&mut self, bundle_id: &str, key: &str) -> Result<(), SecurityRequestError> {
|
||||
let bundle = self.get_bundle_mut(&bundle_id)?;
|
||||
// TODO(sleffler): error if no entry?
|
||||
let _ = bundle.keys.remove(key);
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
@@ -7,6 +7,7 @@ use kata_security_interface::LoadModelRequest;
|
||||
use kata_security_interface::ReadKeyRequest;
|
||||
use kata_security_interface::SecurityCoordinatorInterface;
|
||||
use kata_security_interface::SecurityRequest;
|
||||
use kata_security_interface::SecurityRequestCapability;
|
||||
use kata_security_interface::SecurityRequestError;
|
||||
use kata_security_interface::SizeBufferRequest;
|
||||
use kata_security_interface::UninstallRequest;
|
||||
@@ -14,6 +15,10 @@ use kata_security_interface::WriteKeyRequest;
|
||||
use log::trace;
|
||||
use postcard;
|
||||
|
||||
extern "C" {
|
||||
static SECURITY_RECV_SLOT: seL4_CPtr;
|
||||
}
|
||||
|
||||
pub struct SeL4SecurityCoordinator {
|
||||
// TODO(sleffler): mailbox ipc state
|
||||
}
|
||||
@@ -50,11 +55,10 @@ impl SecurityCoordinatorInterface for SeL4SecurityCoordinator {
|
||||
Err(SreEchoFailed)
|
||||
}
|
||||
SecurityRequest::SrInstall => {
|
||||
trace!(
|
||||
"INSTALL addr {:p} len {}",
|
||||
request_buffer.as_ptr(),
|
||||
request_buffer.len()
|
||||
);
|
||||
let mut request = postcard::from_bytes::<InstallRequest>(&request_buffer[..])
|
||||
.map_err(deserialize_failure)?;
|
||||
request.set_container_cap(unsafe { SECURITY_RECV_SLOT });
|
||||
trace!("INSTALL pkg_contents {:?}", request.pkg_contents);
|
||||
// TODO(sleffler): fill-in
|
||||
Err(SreInstallFailed)
|
||||
}
|
||||
@@ -80,10 +84,11 @@ impl SecurityCoordinatorInterface for SeL4SecurityCoordinator {
|
||||
Err(SreGetManifestFailed)
|
||||
}
|
||||
SecurityRequest::SrLoadApplication => {
|
||||
let request = postcard::from_bytes::<LoadApplicationRequest>(&request_buffer[..])
|
||||
let mut request = postcard::from_bytes::<LoadApplicationRequest>(&request_buffer[..])
|
||||
.map_err(deserialize_failure)?;
|
||||
request.set_container_cap(unsafe { SECURITY_RECV_SLOT });
|
||||
trace!(
|
||||
"LOAD APPLICATION bundle_id {} addr {:p}",
|
||||
"LOAD APPLICATION bundle_id {} app_binary {:?}",
|
||||
request.bundle_id,
|
||||
request.app_binary
|
||||
);
|
||||
@@ -91,10 +96,11 @@ impl SecurityCoordinatorInterface for SeL4SecurityCoordinator {
|
||||
Err(SreLoadApplicationFailed)
|
||||
}
|
||||
SecurityRequest::SrLoadModel => {
|
||||
let request = postcard::from_bytes::<LoadModelRequest>(&request_buffer[..])
|
||||
let mut request = postcard::from_bytes::<LoadModelRequest>(&request_buffer[..])
|
||||
.map_err(deserialize_failure)?;
|
||||
request.set_container_cap(unsafe { SECURITY_RECV_SLOT });
|
||||
trace!(
|
||||
"LOAD MODEL bundle_id {} model_id {} addr {:p}",
|
||||
"LOAD MODEL bundle_id {} model_id {} model_binary {:?}",
|
||||
request.bundle_id,
|
||||
request.model_id,
|
||||
request.model_binary
|
||||
|
@@ -6,9 +6,11 @@
|
||||
|
||||
extern crate alloc;
|
||||
use alloc::boxed::Box;
|
||||
use alloc::string::String;
|
||||
use kata_memory_interface::ObjDescBundle;
|
||||
use kata_security_interface::SecurityCoordinatorInterface;
|
||||
use kata_security_interface::SecurityRequest;
|
||||
use kata_security_interface::SecurityRequestError;
|
||||
use kata_storage_interface::KeyValueData;
|
||||
|
||||
#[cfg(all(feature = "fake", feature = "sel4"))]
|
||||
compile_error!("features \"fake\" and \"sel4\" are mutually exclusive");
|
||||
@@ -23,7 +25,7 @@ pub static mut KATA_SECURITY: KataSecurityCoordinator = KataSecurityCoordinator:
|
||||
|
||||
// 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.
|
||||
// KATA_SECURITY static.
|
||||
// NB: no locking is done; we assume the caller/user is single-threaded
|
||||
pub struct KataSecurityCoordinator {
|
||||
manager: Option<Box<dyn SecurityCoordinatorInterface + Sync>>,
|
||||
@@ -40,15 +42,31 @@ impl KataSecurityCoordinator {
|
||||
}
|
||||
}
|
||||
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)
|
||||
fn install(&mut self, pkg_contents: &ObjDescBundle) -> Result<String, SecurityRequestError> {
|
||||
self.manager.as_mut().unwrap().install(pkg_contents)
|
||||
}
|
||||
fn uninstall(&mut self, bundle_id: &str) -> Result<(), SecurityRequestError> {
|
||||
self.manager.as_mut().unwrap().uninstall(bundle_id)
|
||||
}
|
||||
fn size_buffer(&self, bundle_id: &str) -> Result<usize, SecurityRequestError> {
|
||||
self.manager.as_ref().unwrap().size_buffer(bundle_id)
|
||||
}
|
||||
fn get_manifest(&self, bundle_id: &str) -> Result<String, SecurityRequestError> {
|
||||
self.manager.as_ref().unwrap().get_manifest(bundle_id)
|
||||
}
|
||||
fn load_application(&self, bundle_id: &str) -> Result<ObjDescBundle, SecurityRequestError> {
|
||||
self.manager.as_ref().unwrap().load_application(bundle_id)
|
||||
}
|
||||
fn load_model(&self, bundle_id: &str, model_id: &str) -> Result<ObjDescBundle, SecurityRequestError> {
|
||||
self.manager.as_ref().unwrap().load_model(bundle_id, model_id)
|
||||
}
|
||||
fn read_key(&self, bundle_id: &str, key: &str) -> Result<&KeyValueData, SecurityRequestError> {
|
||||
self.manager.as_ref().unwrap().read_key(bundle_id, key)
|
||||
}
|
||||
fn write_key(&mut self, bundle_id: &str, key: &str, value: &KeyValueData) -> Result<(), SecurityRequestError> {
|
||||
self.manager.as_mut().unwrap().write_key(bundle_id, key, value)
|
||||
}
|
||||
fn delete_key(&mut self, bundle_id: &str, key: &str) -> Result<(), SecurityRequestError> {
|
||||
self.manager.as_mut().unwrap().delete_key(bundle_id, key)
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user