#![allow(dead_code)]
#![allow(non_camel_case_types)]
use bytemuck::{Pod, Zeroable};
use serde::{Deserialize, Serialize};
pub const CHUNK_SIZE: u64 = 32 * 1024;
pub const MAX_MESSAGE_SIZE: usize = 10 * 1024 * 1024;
#[derive(Debug, PartialEq, Eq, Default)]
pub enum PacketType {
#[default]
Unknown = 0,
OpenSession = 1,
CloseSession = 2,
InvokeCommand = 3,
RequestCancellation = 4,
}
impl From<u64> for PacketType {
fn from(value: u64) -> Self {
match value {
0 => PacketType::Unknown,
1 => PacketType::OpenSession,
2 => PacketType::CloseSession,
3 => PacketType::InvokeCommand,
4 => PacketType::RequestCancellation,
_ => PacketType::Unknown,
}
}
}
impl From<PacketType> for u64 {
fn from(value: PacketType) -> Self {
match value {
PacketType::Unknown => 0,
PacketType::OpenSession => 1,
PacketType::CloseSession => 2,
PacketType::InvokeCommand => 3,
PacketType::RequestCancellation => 4,
}
}
}
#[repr(C)]
#[derive(Debug, Copy, Clone, Pod, Zeroable)]
pub struct PacketHeader {
pub data_type: u64,
pub data_size: u64,
}
impl PacketHeader {
pub const SIZE: usize = size_of::<PacketHeader>();
pub fn as_bytes(&self) -> &[u8] {
bytemuck::bytes_of(self)
}
pub fn from_bytes(buf: &[u8]) -> Self {
*bytemuck::from_bytes(buf)
}
}
#[derive(Serialize, Deserialize, Debug)]
pub enum TARequest {
Register { uuid: String },
}
#[derive(Serialize, Deserialize)]
pub enum TEE_Request {
OpenSession {
uuid: String,
connection_method: u32,
params: TEE_Parameters,
#[serde(default)]
ca_auth_info: Option<CaAuthInfo>,
},
CloseSession {
session_id: u32,
},
InvokeCommand {
session_id: u32,
cmd_id: u32,
params: TEE_Parameters,
},
RequestCancellation {
session_id: u32,
},
}
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct CaAuthInfo {
pub ca_uuid: String,
pub verified: bool,
}
#[derive(Serialize, Deserialize)]
pub enum TEE_Response {
OpenSession { session_id: u32, result: u32 },
CloseSession { result: u32 },
InvokeCommand { params: TEE_Parameters, result: u32 },
RequestCancellation { result: u32 },
}
#[derive(Serialize, Deserialize, Default)]
pub struct TEE_Parameters(
pub TEE_Parameter,
pub TEE_Parameter,
pub TEE_Parameter,
pub TEE_Parameter,
);
#[derive(Serialize, Deserialize, Default)]
pub struct TEE_Parameter {
pub param: TEE_Param,
pub param_type: TEE_ParamType,
}
#[derive(Serialize, Deserialize, Default)]
pub struct TEE_Param {
pub data: Vec<u8>,
pub values: TEE_Value,
}
#[derive(Serialize, Deserialize, Clone, Copy, Default)]
pub struct TEE_Value {
pub a: u32,
pub b: u32,
}
#[derive(Serialize, Deserialize, Default, Debug, PartialEq, Eq, Clone, Copy)]
pub enum TEE_ParamType {
#[default]
None = 0,
ValueInput = 1,
ValueOutput = 2,
ValueInout = 3,
MemrefInput = 5,
MemrefOutput = 6,
MemrefInout = 7,
}
impl From<u32> for TEE_ParamType {
fn from(value: u32) -> Self {
match value {
0 => TEE_ParamType::None,
1 => TEE_ParamType::ValueInput,
2 => TEE_ParamType::ValueOutput,
3 => TEE_ParamType::ValueInout,
5 => TEE_ParamType::MemrefInput,
6 => TEE_ParamType::MemrefOutput,
7 => TEE_ParamType::MemrefInout,
_ => TEE_ParamType::None,
}
}
}
impl From<TEE_ParamType> for u32 {
fn from(value: TEE_ParamType) -> Self {
match value {
TEE_ParamType::None => 0,
TEE_ParamType::ValueInput => 1,
TEE_ParamType::ValueOutput => 2,
TEE_ParamType::ValueInout => 3,
TEE_ParamType::MemrefInput => 5,
TEE_ParamType::MemrefOutput => 6,
TEE_ParamType::MemrefInout => 7,
}
}
}
pub fn path_to_uuid(path: &str) -> String {
use uuid::Uuid;
let namespace = Uuid::nil();
Uuid::new_v5(&namespace, path.as_bytes()).to_string()
}
pub use TEE_ParamType as ParamType;
pub use TEE_Parameter as Parameter;
pub use TEE_Parameters as Parameters;
pub use TEE_Value as Value;
#[cfg(test)]
mod protocol_tests {
use super::*;
#[test]
fn test_tee_param_type_from_u32() {
assert_eq!(TEE_ParamType::from(0), TEE_ParamType::None);
assert_eq!(TEE_ParamType::from(1), TEE_ParamType::ValueInput);
assert_eq!(TEE_ParamType::from(2), TEE_ParamType::ValueOutput);
assert_eq!(TEE_ParamType::from(3), TEE_ParamType::ValueInout);
assert_eq!(TEE_ParamType::from(4), TEE_ParamType::None); assert_eq!(TEE_ParamType::from(5), TEE_ParamType::MemrefInput);
assert_eq!(TEE_ParamType::from(6), TEE_ParamType::MemrefOutput);
assert_eq!(TEE_ParamType::from(7), TEE_ParamType::MemrefInout);
assert_eq!(TEE_ParamType::from(8), TEE_ParamType::None); assert_eq!(TEE_ParamType::from(99), TEE_ParamType::None); assert_eq!(TEE_ParamType::from(255), TEE_ParamType::None); }
#[test]
fn test_tee_param_type_into_u32() {
assert_eq!(u32::from(TEE_ParamType::None), 0);
assert_eq!(u32::from(TEE_ParamType::ValueInput), 1);
assert_eq!(u32::from(TEE_ParamType::ValueOutput), 2);
assert_eq!(u32::from(TEE_ParamType::ValueInout), 3);
assert_eq!(u32::from(TEE_ParamType::MemrefInput), 5);
assert_eq!(u32::from(TEE_ParamType::MemrefOutput), 6);
assert_eq!(u32::from(TEE_ParamType::MemrefInout), 7);
}
#[test]
fn test_tee_param_type_roundtrip() {
let values = vec![0, 1, 2, 3, 5, 6, 7];
for value in values {
let param_type = TEE_ParamType::from(value);
let back_to_u32: u32 = param_type.into();
assert_eq!(value, back_to_u32);
}
}
#[test]
fn test_tee_value_default() {
let default_val = TEE_Value::default();
assert_eq!(default_val.a, 0);
assert_eq!(default_val.b, 0);
}
#[test]
fn test_tee_parameter_default() {
let default_param = TEE_Parameter::default();
assert_eq!(default_param.param_type, TEE_ParamType::None);
assert_eq!(default_param.param.value.a, 0);
assert_eq!(default_param.param.value.b, 0);
assert!(default_param.param.data.is_empty());
}
#[test]
fn test_packet_header_serialization_roundtrip() {
let original = PacketHeader {
data_type: 0x1234_5678_9ABC_DEF0,
data_size: 0xFEDC_BA98_7654_3210,
};
let bytes = original.as_bytes();
let restored = PacketHeader::from_bytes(bytes);
assert_eq!(original.data_type, restored.data_type);
assert_eq!(original.data_size, restored.data_size);
}
#[test]
fn test_packet_type_conversion() {
assert_eq!(PacketType::from(0), PacketType::Unknown);
assert_eq!(PacketType::from(1), PacketType::OpenSession);
assert_eq!(PacketType::from(2), PacketType::CloseSession);
assert_eq!(PacketType::from(3), PacketType::InvokeCommand);
assert_eq!(PacketType::from(4), PacketType::RequestCancellation);
assert_eq!(PacketType::from(5), PacketType::Unknown); assert_eq!(PacketType::from(0xFFFFFFFF), PacketType::Unknown);
assert_eq!(u64::from(PacketType::Unknown), 0);
assert_eq!(u64::from(PacketType::OpenSession), 1);
assert_eq!(u64::from(PacketType::CloseSession), 2);
assert_eq!(u64::from(PacketType::InvokeCommand), 3);
assert_eq!(u64::from(PacketType::RequestCancellation), 4);
}
#[test]
fn test_packet_header_size() {
use core::mem;
let packet0 = PacketHeader {
data_type: u64::from(PacketType::OpenSession),
data_size: CHUNK_SIZE,
};
let packet1 = PacketHeader {
data_type: u64::from(PacketType::CloseSession),
data_size: 44,
};
assert_eq!(mem::size_of_val(&packet0), PacketHeader::SIZE);
assert_eq!(mem::size_of_val(&packet1), PacketHeader::SIZE);
assert_eq!(PacketHeader::SIZE, mem::size_of::<PacketHeader>());
}
#[test]
fn test_path_to_uuid_consistency() {
let uuid1 = path_to_uuid("/usr/bin/test");
let uuid2 = path_to_uuid("/usr/bin/test");
assert_eq!(uuid1, uuid2);
}
#[test]
fn test_path_to_uuid_uniqueness() {
let uuid1 = path_to_uuid("/usr/bin/test1");
let uuid2 = path_to_uuid("/usr/bin/test2");
assert_ne!(uuid1, uuid2);
}
#[test]
fn test_path_to_uuid_deterministic() {
assert_eq!(
path_to_uuid("/usr/bin/test"),
"f2d62525-c975-5075-8bfd-ea1a7c98adc3"
);
assert_ne!(path_to_uuid("/usr/bin/test"), path_to_uuid("/usr/bin/ls"));
}
}