mirror of
https://github.com/AmbiML/sparrow-kata-full.git
synced 2025-04-27 18:35:32 +00:00
SDKRuntime: add key-val store api's
Change-Id: Ic25986719bdea04adc989f2ea5d2cedd664017d7 GitOrigin-RevId: 738e0e63de82ec0bda91e1982d32e0922a181184
This commit is contained in:
parent
fae20dcd68
commit
8b7c33c565
@ -17,6 +17,7 @@
|
||||
import <LoggerInterface.camkes>;
|
||||
import <MemoryInterface.camkes>;
|
||||
import <SDKManagerInterface.camkes>;
|
||||
import <SecurityCoordinatorInterface.camkes>;
|
||||
|
||||
component SDKRuntime {
|
||||
provides SDKManagerInterface sdk_manager;
|
||||
@ -24,6 +25,7 @@ component SDKRuntime {
|
||||
|
||||
maybe uses LoggerInterface logger;
|
||||
uses MemoryInterface memory;
|
||||
uses SecurityCoordinatorInterface security;
|
||||
|
||||
// Enable KataOS CAmkES support.
|
||||
attribute int kataos = true;
|
||||
|
@ -40,9 +40,11 @@ use kata_os_common::camkes::{seL4_CPath, Camkes};
|
||||
use kata_os_common::copyregion::CopyRegion;
|
||||
use kata_os_common::cspace_slot::CSpaceSlot;
|
||||
use kata_os_common::sel4_sys;
|
||||
use kata_sdk_interface::KeyValueData;
|
||||
use kata_sdk_interface::SDKAppId;
|
||||
use kata_sdk_interface::SDKError;
|
||||
use kata_sdk_interface::SDKReplyHeader;
|
||||
use kata_sdk_interface::SDKRuntimeError;
|
||||
use kata_sdk_interface::SDKRuntimeInterface;
|
||||
use kata_sdk_interface::SDKRuntimeRequest;
|
||||
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 {
|
||||
SDKRuntimeRequest::Ping => ping_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);
|
||||
}
|
||||
@ -207,6 +218,10 @@ pub unsafe extern "C" fn run() -> ! {
|
||||
// SDK RPC request handling: unmarshal request, dispatch to KATA_SDK,
|
||||
// and marshal reply.
|
||||
|
||||
fn serialize_failure(e: postcard::Error) -> SDKError {
|
||||
error!("serialize failed: {:?}", e);
|
||||
SDKError::SerializeFailed
|
||||
}
|
||||
fn deserialize_failure(e: postcard::Error) -> SDKError {
|
||||
error!("deserialize failed: {:?}", e);
|
||||
SDKError::DeserializeFailed
|
||||
@ -231,6 +246,50 @@ fn log_request(
|
||||
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.
|
||||
|
||||
#[no_mangle]
|
||||
|
@ -58,6 +58,11 @@ pub const SDKRUNTIME_REQUEST_DATA_SIZE: usize = PAGE_SIZE / 2;
|
||||
/// on 64-bit platforms these are 64-bits.
|
||||
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.
|
||||
#[derive(Serialize, Deserialize)]
|
||||
pub struct SDKRequestHeader {
|
||||
@ -95,11 +100,39 @@ pub struct LogRequest<'a> {
|
||||
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?
|
||||
#[derive(Clone, Copy, Eq, PartialEq, Serialize, Deserialize, Debug)]
|
||||
pub enum SDKRuntimeRequest {
|
||||
Ping = 0, // Check runtime is alive
|
||||
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.
|
||||
@ -119,6 +152,21 @@ pub trait SDKRuntimeInterface {
|
||||
|
||||
/// Logs |msg| through the system logger.
|
||||
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
|
||||
@ -195,3 +243,44 @@ pub fn kata_sdk_log(msg: &str) -> Result<(), SDKRuntimeError> {
|
||||
)?;
|
||||
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()
|
||||
}
|
||||
|
@ -20,6 +20,7 @@ edition = "2021"
|
||||
[dependencies]
|
||||
hashbrown = { version = "0.11", features = ["ahash-compile-time-rng"] }
|
||||
kata-os-common = { path = "../../kata-os-common" }
|
||||
kata-security-interface = { path = "../../SecurityCoordinator/kata-security-interface" }
|
||||
kata-sdk-interface = { path = "../kata-sdk-interface" }
|
||||
kata-sdk-manager = { path = "../kata-sdk-manager" }
|
||||
log = { version = "0.4", features = ["release_max_level_info"] }
|
||||
|
@ -18,6 +18,7 @@
|
||||
use kata_os_common::camkes::seL4_CPath;
|
||||
use kata_os_common::sel4_sys;
|
||||
use kata_sdk_interface::error::SDKError;
|
||||
use kata_sdk_interface::KeyValueData;
|
||||
use kata_sdk_interface::SDKAppId;
|
||||
use kata_sdk_interface::SDKRuntimeInterface;
|
||||
use kata_sdk_manager::SDKManagerError;
|
||||
@ -69,4 +70,30 @@ impl SDKRuntimeInterface for KataSDKRuntime {
|
||||
fn log(&self, app_id: SDKAppId, msg: &str) -> Result<(), SDKError> {
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
@ -18,10 +18,14 @@ use kata_os_common::camkes::seL4_CPath;
|
||||
use kata_os_common::cspace_slot::CSpaceSlot;
|
||||
use kata_os_common::sel4_sys;
|
||||
use kata_sdk_interface::error::SDKError;
|
||||
use kata_sdk_interface::KeyValueData;
|
||||
use kata_sdk_interface::SDKAppId;
|
||||
use kata_sdk_interface::SDKRuntimeInterface;
|
||||
use kata_sdk_manager::SDKManagerError;
|
||||
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 smallstr::SmallString;
|
||||
|
||||
@ -147,4 +151,44 @@ impl SDKRuntimeInterface for SDKRuntime {
|
||||
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),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -173,6 +173,7 @@ assembly {
|
||||
from debug_console.security, // NB: for debug/test
|
||||
from process_manager.security,
|
||||
from ml_coordinator.security, // NB: for LoadModel
|
||||
from sdk_runtime.security, // NB: for key-value store
|
||||
to security_coordinator.security);
|
||||
|
||||
// Connect the DebugConsole to the OpenTitanUARTDriver.
|
||||
|
Loading…
Reference in New Issue
Block a user