use std::ptr;
use log::{debug, warn};
use postcard::{take_from_bytes, to_allocvec};
use uuid::Uuid;
#[cfg(feature = "ca-sign-verify")]
use teec_protocol::CaAuthInfo;
use teec_protocol::{PacketType, TEE_Parameters, TEE_Request, TEE_Response};
use crate::{Error, ErrorKind, ErrorOrigin, Result, raw};
use super::context::ContextManager;
#[cfg(feature = "ca-sign-verify")]
use super::get_or_verify_ca;
use super::{build_parameters_from_operation, safe_ptr, update_operation_from_parameters};
pub(crate) fn open_session_impl(
ctx: *mut raw::TEEC_Context,
session: *mut raw::TEEC_Session,
destination: *const raw::TEEC_UUID,
connection_method: u32,
operation: *mut raw::TEEC_Operation,
) -> Result<u32> {
let _ = safe_ptr::deref_mut(ctx)?;
let _ = safe_ptr::deref_mut(session)?;
let uuid_nn = safe_ptr::deref(destination)?;
let uuid = unsafe { uuid_nn.as_ref() };
let uuid_str = uuid_to_string(uuid)?;
#[cfg(feature = "ca-sign-verify")]
let ca_auth_info = {
let auth_result = get_or_verify_ca();
if !auth_result.verified {
warn!("CA 签名验证失败: ca_uuid={}", auth_result.ca_uuid);
} else {
debug!("CA 签名验证通过: ca_uuid={}", auth_result.ca_uuid);
}
Some(CaAuthInfo {
ca_uuid: auth_result.ca_uuid,
verified: auth_result.verified,
})
};
#[cfg(not(feature = "ca-sign-verify"))]
let ca_auth_info: Option<teec_protocol::CaAuthInfo> = None;
let params = if operation.is_null() {
TEE_Parameters::default()
} else {
build_parameters_from_operation(operation)?
};
let request = TEE_Request::OpenSession {
uuid: uuid_str,
connection_method,
params,
ca_auth_info,
};
let mut session_nn = safe_ptr::deref_mut(session)?;
let session_ref = unsafe { session_nn.as_mut() };
let response = send_request_and_recv_response(ctx, PacketType::OpenSession, &request)?;
match response {
TEE_Response::OpenSession { session_id, result } => {
debug!("TEEC_OpenSession: 接收 session_id 和结果: {session_id}, {result}");
session_ref.imp.ctx = ctx;
session_ref.imp.session_id = session_id;
if result != raw::TEEC_SUCCESS {
return Err(Error::new(ErrorKind::from(result)).with_origin(ErrorOrigin::TEE));
}
Ok(result)
}
_ => Err(Error::new(ErrorKind::BadParameters).with_origin(ErrorOrigin::API)),
}
}
pub(crate) fn close_session_impl(session: *mut raw::TEEC_Session) -> Result<()> {
let mut session_nn = safe_ptr::deref_mut(session)?;
let session_ref = unsafe { session_nn.as_mut() };
let session_id = session_ref.imp.session_id;
let ctx = session_ref.imp.ctx;
if ctx.is_null() {
return Err(Error::new(ErrorKind::BadParameters));
}
let request = TEE_Request::CloseSession { session_id };
let response = send_request_and_recv_response(ctx, PacketType::CloseSession, &request)?;
match response {
TEE_Response::CloseSession { result } => {
debug!("TEEC_CloseSession: 接收结果: {result}");
session_ref.imp.ctx = ptr::null_mut();
session_ref.imp.session_id = 0;
Ok(())
}
_ => Err(Error::new(ErrorKind::BadParameters)),
}
}
pub(crate) fn invoke_command_impl(
session: *mut raw::TEEC_Session,
cmd_id: u32,
operation: *mut raw::TEEC_Operation,
) -> Result<u32> {
let mut session_nn = safe_ptr::deref_mut(session)?;
let session_ref = unsafe { session_nn.as_mut() };
let session_id = session_ref.imp.session_id;
let ctx = session_ref.imp.ctx;
if ctx.is_null() {
return Err(Error::new(ErrorKind::BadParameters));
}
let params = if operation.is_null() {
TEE_Parameters::default()
} else {
let mut operation_nn = safe_ptr::deref_mut(operation)?;
let operation_ref = unsafe { operation_nn.as_mut() };
operation_ref.imp.session = session;
build_parameters_from_operation(operation)?
};
let request = TEE_Request::InvokeCommand {
session_id,
cmd_id,
params,
};
let response = send_request_and_recv_response(ctx, PacketType::InvokeCommand, &request)?;
match response {
TEE_Response::InvokeCommand { params, result } => {
if result != raw::TEEC_SUCCESS {
let origin = if result == raw::TEEC_ERROR_TARGET_DEAD {
ErrorOrigin::TEE
} else {
ErrorOrigin::API
};
return Err(Error::new(ErrorKind::from(result)).with_origin(origin));
}
if !operation.is_null() {
update_operation_from_parameters(operation, params)?;
}
Ok(result)
}
_ => Err(Error::new(ErrorKind::BadParameters).with_origin(ErrorOrigin::API)),
}
}
pub(crate) fn request_cancellation_impl(operation: *mut raw::TEEC_Operation) -> Result<()> {
let mut operation_nn = safe_ptr::deref_mut(operation)?;
let operation_ref = unsafe { operation_nn.as_mut() };
let session = operation_ref.imp.session;
if session.is_null() {
return Ok(());
}
let mut session_nn = safe_ptr::deref_mut(session)?;
let session_ref = unsafe { session_nn.as_mut() };
let session_id = session_ref.imp.session_id;
let ctx = session_ref.imp.ctx;
if ctx.is_null() {
return Ok(());
}
let request = TEE_Request::RequestCancellation { session_id };
let response = send_request_and_recv_response(ctx, PacketType::RequestCancellation, &request)?;
match response {
TEE_Response::RequestCancellation { result: _ } => {
debug!("TEEC_RequestCancellation: 接收结果");
Ok(())
}
_ => Err(Error::new(ErrorKind::BadParameters)),
}
}
fn uuid_to_string(uuid: &raw::TEEC_UUID) -> Result<String> {
Ok(Uuid::from_fields(
uuid.timeLow,
uuid.timeMid,
uuid.timeHiAndVersion,
&uuid.clockSeqAndNode,
)
.to_string())
}
fn send_request_and_recv_response(
ctx: *mut raw::TEEC_Context,
packet_type: PacketType,
request: &TEE_Request,
) -> Result<TEE_Response> {
let client_arc = ContextManager::get_client(ctx)?;
let mut client = client_arc
.lock()
.map_err(|_| Error::new(ErrorKind::Generic).with_origin(ErrorOrigin::API))?;
let request_data = to_allocvec(request).map_err(|e| {
warn!("序列化请求失败:{e}");
Error::new(ErrorKind::BadFormat).with_origin(ErrorOrigin::API)
})?;
const MAX_REQUEST_SIZE: usize = 64 * 1024 * 1024;
if request_data.len() > MAX_REQUEST_SIZE {
warn!(
"请求数据过大:{} bytes (最大允许 {} bytes)",
request_data.len(),
MAX_REQUEST_SIZE
);
return Err(Error::new(ErrorKind::BadFormat).with_origin(ErrorOrigin::API));
}
client
.send_data_with_header(packet_type, &request_data)
.map_err(|e| {
warn!("发送请求失败:{e}");
Error::new(ErrorKind::Communication).with_origin(ErrorOrigin::COMMS)
})?;
let mut len_buf = [0u8; 4];
client.recv_data(&mut len_buf).map_err(|e| {
warn!("接收响应长度失败:{e}");
Error::new(ErrorKind::Communication).with_origin(ErrorOrigin::COMMS)
})?;
let response_len_u32 = u32::from_ne_bytes(len_buf);
const MAX_RESPONSE_SIZE: usize = 64 * 1024 * 1024;
if response_len_u32 > MAX_RESPONSE_SIZE as u32 {
warn!(
"响应数据过大:{} bytes (最大允许 {} bytes)",
response_len_u32, MAX_RESPONSE_SIZE
);
return Err(Error::new(ErrorKind::BadFormat).with_origin(ErrorOrigin::COMMS));
}
let response_len = response_len_u32 as usize;
let mut response_data = vec![0u8; response_len];
client.recv_data(&mut response_data).map_err(|e| {
warn!("接收响应数据失败:{e}");
Error::new(ErrorKind::Communication).with_origin(ErrorOrigin::COMMS)
})?;
take_from_bytes::<TEE_Response>(&response_data)
.map(|(response, _)| response)
.map_err(|e| {
warn!("反序列化响应失败:{e}");
Error::new(ErrorKind::BadFormat).with_origin(ErrorOrigin::API)
})
}