1
0
mirror of https://github.com/AmbiML/sparrow-kata-full.git synced 2025-05-04 13:36:49 +00:00

SDKRuntime: add key-val store api's

Change-Id: Ic25986719bdea04adc989f2ea5d2cedd664017d7
GitOrigin-RevId: 738e0e63de82ec0bda91e1982d32e0922a181184
This commit is contained in:
Sam Leffler 2022-09-19 23:18:22 +00:00
parent fae20dcd68
commit 8b7c33c565
7 changed files with 223 additions and 0 deletions
apps/system
components/SDKRuntime
SDKRuntime.camkes
kata-sdk-component/src
kata-sdk-interface/src
kata-sdk-runtime
system.camkes

View File

@ -17,6 +17,7 @@
import <LoggerInterface.camkes>; import <LoggerInterface.camkes>;
import <MemoryInterface.camkes>; import <MemoryInterface.camkes>;
import <SDKManagerInterface.camkes>; import <SDKManagerInterface.camkes>;
import <SecurityCoordinatorInterface.camkes>;
component SDKRuntime { component SDKRuntime {
provides SDKManagerInterface sdk_manager; provides SDKManagerInterface sdk_manager;
@ -24,6 +25,7 @@ component SDKRuntime {
maybe uses LoggerInterface logger; maybe uses LoggerInterface logger;
uses MemoryInterface memory; uses MemoryInterface memory;
uses SecurityCoordinatorInterface security;
// Enable KataOS CAmkES support. // Enable KataOS CAmkES support.
attribute int kataos = true; attribute int kataos = true;

View File

@ -40,9 +40,11 @@ use kata_os_common::camkes::{seL4_CPath, Camkes};
use kata_os_common::copyregion::CopyRegion; use kata_os_common::copyregion::CopyRegion;
use kata_os_common::cspace_slot::CSpaceSlot; use kata_os_common::cspace_slot::CSpaceSlot;
use kata_os_common::sel4_sys; use kata_os_common::sel4_sys;
use kata_sdk_interface::KeyValueData;
use kata_sdk_interface::SDKAppId; use kata_sdk_interface::SDKAppId;
use kata_sdk_interface::SDKError; use kata_sdk_interface::SDKError;
use kata_sdk_interface::SDKReplyHeader; use kata_sdk_interface::SDKReplyHeader;
use kata_sdk_interface::SDKRuntimeError;
use kata_sdk_interface::SDKRuntimeInterface; use kata_sdk_interface::SDKRuntimeInterface;
use kata_sdk_interface::SDKRuntimeRequest; use kata_sdk_interface::SDKRuntimeRequest;
use kata_sdk_interface::SDKRUNTIME_REQUEST_DATA_SIZE; use kata_sdk_interface::SDKRUNTIME_REQUEST_DATA_SIZE;
@ -185,6 +187,15 @@ pub unsafe extern "C" fn run() -> ! {
if let Err(status) = match header.request { if let Err(status) = match header.request {
SDKRuntimeRequest::Ping => ping_request(app_id, args_slice, reply_slice), SDKRuntimeRequest::Ping => ping_request(app_id, args_slice, reply_slice),
SDKRuntimeRequest::Log => log_request(app_id, args_slice, reply_slice), SDKRuntimeRequest::Log => log_request(app_id, args_slice, reply_slice),
SDKRuntimeRequest::ReadKey => {
read_key_request(app_id, args_slice, reply_slice)
}
SDKRuntimeRequest::WriteKey => {
write_key_request(app_id, args_slice, reply_slice)
}
SDKRuntimeRequest::DeleteKey => {
delete_key_request(app_id, args_slice, reply_slice)
}
} { } {
reply_error(status, reply_slice); reply_error(status, reply_slice);
} }
@ -207,6 +218,10 @@ pub unsafe extern "C" fn run() -> ! {
// SDK RPC request handling: unmarshal request, dispatch to KATA_SDK, // SDK RPC request handling: unmarshal request, dispatch to KATA_SDK,
// and marshal reply. // and marshal reply.
fn serialize_failure(e: postcard::Error) -> SDKError {
error!("serialize failed: {:?}", e);
SDKError::SerializeFailed
}
fn deserialize_failure(e: postcard::Error) -> SDKError { fn deserialize_failure(e: postcard::Error) -> SDKError {
error!("deserialize failed: {:?}", e); error!("deserialize failed: {:?}", e);
SDKError::DeserializeFailed SDKError::DeserializeFailed
@ -231,6 +246,50 @@ fn log_request(
unsafe { KATA_SDK.log(app_id, msg) } unsafe { KATA_SDK.log(app_id, msg) }
} }
fn read_key_request(
app_id: SDKAppId,
request_slice: &[u8],
reply_slice: &mut [u8],
) -> Result<(), SDKError> {
let request = postcard::from_bytes::<kata_sdk_interface::ReadKeyRequest>(request_slice)
.map_err(deserialize_failure)?;
#[allow(clippy::uninit_assumed_init)]
let mut keyval: KeyValueData = unsafe { ::core::mem::MaybeUninit::uninit().assume_init() };
let value = unsafe { KATA_SDK.read_key(app_id, request.key, &mut keyval)? };
let _ = postcard::to_slice(
&kata_sdk_interface::ReadKeyResponse {
header: SDKReplyHeader::new(SDKRuntimeError::SDKSuccess),
value,
},
reply_slice,
)
.map_err(serialize_failure)?;
Ok(())
}
fn write_key_request(
app_id: SDKAppId,
request_slice: &[u8],
_reply_slice: &mut [u8],
) -> Result<(), SDKError> {
let request = postcard::from_bytes::<kata_sdk_interface::WriteKeyRequest>(request_slice)
.map_err(deserialize_failure)?;
// NB: the serialized data are variable length so copy to convert
let mut keyval = [0u8; kata_sdk_interface::KEY_VALUE_DATA_SIZE];
keyval[..request.value.len()].copy_from_slice(request.value);
unsafe { KATA_SDK.write_key(app_id, request.key, &keyval) }
}
fn delete_key_request(
app_id: SDKAppId,
request_slice: &[u8],
_reply_slice: &mut [u8],
) -> Result<(), SDKError> {
let request = postcard::from_bytes::<kata_sdk_interface::DeleteKeyRequest>(request_slice)
.map_err(deserialize_failure)?;
unsafe { KATA_SDK.delete_key(app_id, request.key) }
}
// SDKManager RPC handling; these arrive via CAmkES so have a C linkage. // SDKManager RPC handling; these arrive via CAmkES so have a C linkage.
#[no_mangle] #[no_mangle]

View File

@ -58,6 +58,11 @@ pub const SDKRUNTIME_REQUEST_DATA_SIZE: usize = PAGE_SIZE / 2;
/// on 64-bit platforms these are 64-bits. /// on 64-bit platforms these are 64-bits.
pub type SDKAppId = usize; pub type SDKAppId = usize;
// TODO(sleffler): temp constraint on value part of key-value pairs
// TOOD(sleffler): dup's security coordinator but we don't want a dependency
pub const KEY_VALUE_DATA_SIZE: usize = 100;
pub type KeyValueData = [u8; KEY_VALUE_DATA_SIZE];
/// All RPC request must have an SDKRequestHeader at the front. /// All RPC request must have an SDKRequestHeader at the front.
#[derive(Serialize, Deserialize)] #[derive(Serialize, Deserialize)]
pub struct SDKRequestHeader { pub struct SDKRequestHeader {
@ -95,11 +100,39 @@ pub struct LogRequest<'a> {
pub msg: &'a [u8], pub msg: &'a [u8],
} }
/// SDKRuntimeRequest::ReadKey
#[derive(Serialize, Deserialize)]
pub struct ReadKeyRequest<'a> {
pub key: &'a str,
}
#[derive(Serialize, Deserialize)]
pub struct ReadKeyResponse<'a> {
pub header: SDKReplyHeader,
pub value: &'a [u8],
}
/// SDKRuntimeRequest::WriteKey
#[derive(Serialize, Deserialize)]
pub struct WriteKeyRequest<'a> {
pub key: &'a str,
pub value: &'a [u8],
}
/// SDKRuntimeRequest::DeleteKey
#[derive(Serialize, Deserialize)]
pub struct DeleteKeyRequest<'a> {
pub key: &'a str,
}
#[repr(C)] // XXX needed? #[repr(C)] // XXX needed?
#[derive(Clone, Copy, Eq, PartialEq, Serialize, Deserialize, Debug)] #[derive(Clone, Copy, Eq, PartialEq, Serialize, Deserialize, Debug)]
pub enum SDKRuntimeRequest { pub enum SDKRuntimeRequest {
Ping = 0, // Check runtime is alive Ping = 0, // Check runtime is alive
Log, // Log message: [msg: &str] Log, // Log message: [msg: &str]
ReadKey, // Read key: [key: &str, &mut [u8]] -> value: &[u8]
WriteKey, // Write key: [key: &str, value: &KeyValueData]
DeleteKey, // Delete key: [key: &str]
} }
/// Rust interface for the SDKRuntime. /// Rust interface for the SDKRuntime.
@ -119,6 +152,21 @@ pub trait SDKRuntimeInterface {
/// Logs |msg| through the system logger. /// Logs |msg| through the system logger.
fn log(&self, app_id: SDKAppId, msg: &str) -> Result<(), SDKError>; fn log(&self, app_id: SDKAppId, msg: &str) -> Result<(), SDKError>;
/// Returns any value for the specified |key| in the app's private key-value store.
/// Data are written to |keyval| and returned as a slice.
fn read_key<'a>(
&self,
app_id: SDKAppId,
key: &str,
keyval: &'a mut [u8],
) -> Result<&'a [u8], SDKError>;
/// Writes |value| for the specified |key| in the app's private key-value store.
fn write_key(&self, app_id: SDKAppId, key: &str, value: &KeyValueData) -> Result<(), SDKError>;
/// Deletes the specified |key| in the app's private key-value store.
fn delete_key(&self, app_id: SDKAppId, key: &str) -> Result<(), SDKError>;
} }
/// Rust client-side request processing. Note there is no CAmkES stub to /// Rust client-side request processing. Note there is no CAmkES stub to
@ -195,3 +243,44 @@ pub fn kata_sdk_log(msg: &str) -> Result<(), SDKRuntimeError> {
)?; )?;
header.into() header.into()
} }
/// Rust client-side wrapper for the read key method.
// TODO(sleffler): _mut variant?
#[inline]
#[allow(dead_code)]
pub fn kata_sdk_read_key<'a>(key: &str, keyval: &'a mut [u8]) -> Result<&'a [u8], SDKRuntimeError> {
let response = kata_sdk_request::<ReadKeyRequest, ReadKeyResponse>(
SDKRuntimeRequest::ReadKey,
&ReadKeyRequest { key },
)?;
match response.header.status {
SDKRuntimeError::SDKSuccess => {
let (left, _) = keyval.split_at_mut(response.value.len());
left.copy_from_slice(response.value);
Ok(left)
}
e => Err(e),
}
}
/// Rust client-side wrapper for the write key method.
#[inline]
#[allow(dead_code)]
pub fn kata_sdk_write_key(key: &str, value: &[u8]) -> Result<(), SDKRuntimeError> {
let header = kata_sdk_request::<WriteKeyRequest, SDKReplyHeader>(
SDKRuntimeRequest::WriteKey,
&WriteKeyRequest { key, value },
)?;
header.into()
}
/// Rust client-side wrapper for the delete key method.
#[inline]
#[allow(dead_code)]
pub fn kata_sdk_delete_key(key: &str) -> Result<(), SDKRuntimeError> {
let header = kata_sdk_request::<DeleteKeyRequest, SDKReplyHeader>(
SDKRuntimeRequest::DeleteKey,
&DeleteKeyRequest { key },
)?;
header.into()
}

View File

@ -20,6 +20,7 @@ edition = "2021"
[dependencies] [dependencies]
hashbrown = { version = "0.11", features = ["ahash-compile-time-rng"] } hashbrown = { version = "0.11", features = ["ahash-compile-time-rng"] }
kata-os-common = { path = "../../kata-os-common" } kata-os-common = { path = "../../kata-os-common" }
kata-security-interface = { path = "../../SecurityCoordinator/kata-security-interface" }
kata-sdk-interface = { path = "../kata-sdk-interface" } kata-sdk-interface = { path = "../kata-sdk-interface" }
kata-sdk-manager = { path = "../kata-sdk-manager" } kata-sdk-manager = { path = "../kata-sdk-manager" }
log = { version = "0.4", features = ["release_max_level_info"] } log = { version = "0.4", features = ["release_max_level_info"] }

View File

@ -18,6 +18,7 @@
use kata_os_common::camkes::seL4_CPath; use kata_os_common::camkes::seL4_CPath;
use kata_os_common::sel4_sys; use kata_os_common::sel4_sys;
use kata_sdk_interface::error::SDKError; use kata_sdk_interface::error::SDKError;
use kata_sdk_interface::KeyValueData;
use kata_sdk_interface::SDKAppId; use kata_sdk_interface::SDKAppId;
use kata_sdk_interface::SDKRuntimeInterface; use kata_sdk_interface::SDKRuntimeInterface;
use kata_sdk_manager::SDKManagerError; use kata_sdk_manager::SDKManagerError;
@ -69,4 +70,30 @@ impl SDKRuntimeInterface for KataSDKRuntime {
fn log(&self, app_id: SDKAppId, msg: &str) -> Result<(), SDKError> { fn log(&self, app_id: SDKAppId, msg: &str) -> Result<(), SDKError> {
self.runtime.lock().as_ref().unwrap().log(app_id, msg) self.runtime.lock().as_ref().unwrap().log(app_id, msg)
} }
fn read_key<'a>(
&self,
app_id: SDKAppId,
key: &str,
keyval: &'a mut [u8],
) -> Result<&'a [u8], SDKError> {
self.runtime
.lock()
.as_ref()
.unwrap()
.read_key(app_id, key, keyval)
}
fn write_key(&self, app_id: SDKAppId, key: &str, value: &KeyValueData) -> Result<(), SDKError> {
self.runtime
.lock()
.as_ref()
.unwrap()
.write_key(app_id, key, value)
}
fn delete_key(&self, app_id: SDKAppId, key: &str) -> Result<(), SDKError> {
self.runtime
.lock()
.as_ref()
.unwrap()
.delete_key(app_id, key)
}
} }

View File

@ -18,10 +18,14 @@ use kata_os_common::camkes::seL4_CPath;
use kata_os_common::cspace_slot::CSpaceSlot; use kata_os_common::cspace_slot::CSpaceSlot;
use kata_os_common::sel4_sys; use kata_os_common::sel4_sys;
use kata_sdk_interface::error::SDKError; use kata_sdk_interface::error::SDKError;
use kata_sdk_interface::KeyValueData;
use kata_sdk_interface::SDKAppId; use kata_sdk_interface::SDKAppId;
use kata_sdk_interface::SDKRuntimeInterface; use kata_sdk_interface::SDKRuntimeInterface;
use kata_sdk_manager::SDKManagerError; use kata_sdk_manager::SDKManagerError;
use kata_sdk_manager::SDKManagerInterface; use kata_sdk_manager::SDKManagerInterface;
use kata_security_interface::kata_security_delete_key;
use kata_security_interface::kata_security_read_key;
use kata_security_interface::kata_security_write_key;
use log::{error, info}; use log::{error, info};
use smallstr::SmallString; use smallstr::SmallString;
@ -147,4 +151,44 @@ impl SDKRuntimeInterface for SDKRuntime {
None => Err(SDKError::InvalidBadge), None => Err(SDKError::InvalidBadge),
} }
} }
/// Returns any value for the specified |key| in the app's private key-value store.
fn read_key<'a>(
&self,
app_id: SDKAppId,
key: &str,
keyval: &'a mut [u8],
) -> Result<&'a [u8], SDKError> {
match self.apps.get(&app_id) {
Some(app) => {
kata_security_read_key(&app.id, key, keyval)
.map_err(|_| SDKError::ReadKeyFailed)?; // XXX
Ok(keyval)
}
None => Err(SDKError::InvalidBadge),
}
}
/// Writes |value| for the specified |key| in the app's private key-value store.
fn write_key(&self, app_id: SDKAppId, key: &str, value: &KeyValueData) -> Result<(), SDKError> {
match self.apps.get(&app_id) {
Some(app) => {
kata_security_write_key(&app.id, key, value)
.map_err(|_| SDKError::WriteKeyFailed)?; // XXX
Ok(())
}
None => Err(SDKError::InvalidBadge),
}
}
/// Deletes the specified |key| in the app's private key-value store.
fn delete_key(&self, app_id: SDKAppId, key: &str) -> Result<(), SDKError> {
match self.apps.get(&app_id) {
Some(app) => {
kata_security_delete_key(&app.id, key).map_err(|_| SDKError::DeleteKeyFailed)?; // XXX
Ok(())
}
None => Err(SDKError::InvalidBadge),
}
}
} }

View File

@ -173,6 +173,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 from ml_coordinator.security, // NB: for LoadModel
from sdk_runtime.security, // NB: for key-value store
to security_coordinator.security); to security_coordinator.security);
// Connect the DebugConsole to the OpenTitanUARTDriver. // Connect the DebugConsole to the OpenTitanUARTDriver.