1#![allow(non_camel_case_types)]
32#![allow(non_upper_case_globals)]
33#![allow(non_snake_case)]
34
35mod ca_auth;
36mod context;
37mod operation;
38mod safe_ptr;
39mod shared_memory;
40
41pub use ca_auth::{clear_cache, get_or_verify_ca};
42pub use context::ContextManager;
43pub use operation::{build_parameters_from_operation, update_operation_from_parameters};
44pub use shared_memory::SharedMemoryManager;
45
46use std::{
47 ffi::{c_char, c_void},
48 ptr,
49 sync::{
50 LazyLock,
51 atomic::{AtomicI32, Ordering},
52 },
53};
54
55use crate::{Error, ErrorKind, ErrorOrigin, Result, cc_client::client::CcClient, raw};
56use teec_protocol::{PacketType, TEE_Parameters, TEE_Request, TEE_Response};
57
58use log::{debug, warn};
59use postcard::{take_from_bytes, to_allocvec};
60use uuid::Uuid;
61
62static CONTEXT_ID_COUNTER: LazyLock<AtomicI32> = LazyLock::new(|| AtomicI32::new(-1));
63
64fn uuid_to_string(uuid: &raw::TEEC_UUID) -> Result<String> {
66 let bytes: [u8; 16] = [
67 (uuid.timeLow >> 24) as u8,
68 (uuid.timeLow >> 16) as u8,
69 (uuid.timeLow >> 8) as u8,
70 uuid.timeLow as u8,
71 (uuid.timeMid >> 8) as u8,
72 uuid.timeMid as u8,
73 (uuid.timeHiAndVersion >> 8) as u8,
74 uuid.timeHiAndVersion as u8,
75 uuid.clockSeqAndNode[0],
76 uuid.clockSeqAndNode[1],
77 uuid.clockSeqAndNode[2],
78 uuid.clockSeqAndNode[3],
79 uuid.clockSeqAndNode[4],
80 uuid.clockSeqAndNode[5],
81 uuid.clockSeqAndNode[6],
82 uuid.clockSeqAndNode[7],
83 ];
84
85 Uuid::from_slice(&bytes)
86 .map(|u| u.to_string())
87 .map_err(|_| Error::new(ErrorKind::BadFormat))
88}
89
90fn handle_error(result: Result<u32>, ret_origin: *mut u32) -> raw::TEEC_Result {
92 match result {
93 Ok(code) => code,
94 Err(e) => {
95 if !ret_origin.is_null() {
96 unsafe {
99 *ret_origin = e.origin().unwrap_or(ErrorOrigin::API) as u32;
100 }
101 }
102 e.raw_code()
103 }
104 }
105}
106
107fn send_request_and_recv_response(
109 ctx: *mut raw::TEEC_Context,
110 packet_type: PacketType,
111 request: &TEE_Request,
112) -> Result<TEE_Response> {
113 let client_arc = ContextManager::get_client(ctx)?;
114 let mut client = client_arc
115 .lock()
116 .map_err(|_| Error::new(ErrorKind::Generic).with_origin(ErrorOrigin::API))?;
117
118 let request_data = to_allocvec(request).map_err(|e| {
119 warn!("序列化请求失败:{e}");
120 Error::new(ErrorKind::BadFormat).with_origin(ErrorOrigin::API)
121 })?;
122
123 const MAX_REQUEST_SIZE: usize = 64 * 1024 * 1024; if request_data.len() > MAX_REQUEST_SIZE {
127 warn!(
128 "请求数据过大:{} bytes (最大允许 {} bytes)",
129 request_data.len(),
130 MAX_REQUEST_SIZE
131 );
132 return Err(Error::new(ErrorKind::BadFormat).with_origin(ErrorOrigin::API));
133 }
134
135 client
136 .send_data_with_header(packet_type, &request_data)
137 .map_err(|e| {
138 warn!("发送请求失败:{e}");
139 Error::new(ErrorKind::Communication).with_origin(ErrorOrigin::COMMS)
140 })?;
141
142 let mut len_buf = [0u8; 4];
143
144 client.recv_data(&mut len_buf).map_err(|e| {
145 warn!("接收响应长度失败:{e}");
146 Error::new(ErrorKind::Communication).with_origin(ErrorOrigin::COMMS)
147 })?;
148
149 let response_len_u32 = u32::from_ne_bytes(len_buf);
151 const MAX_RESPONSE_SIZE: usize = 64 * 1024 * 1024; if response_len_u32 > MAX_RESPONSE_SIZE as u32 {
154 warn!(
155 "响应数据过大:{} bytes (最大允许 {} bytes)",
156 response_len_u32, MAX_RESPONSE_SIZE
157 );
158 return Err(Error::new(ErrorKind::BadFormat).with_origin(ErrorOrigin::COMMS));
159 }
160
161 let response_len = response_len_u32 as usize;
162 let mut response_data = vec![0u8; response_len];
163
164 client.recv_data(&mut response_data).map_err(|e| {
165 warn!("接收响应数据失败:{e}");
166 Error::new(ErrorKind::Communication).with_origin(ErrorOrigin::COMMS)
167 })?;
168
169 take_from_bytes::<TEE_Response>(&response_data)
170 .map(|(response, _)| response)
171 .map_err(|e| {
172 warn!("反序列化响应失败:{e}");
173 Error::new(ErrorKind::BadFormat).with_origin(ErrorOrigin::API)
174 })
175}
176
177fn set_ret_origin(p: *mut u32, v: u32) -> Result<()> {
179 safe_ptr::write_raw(p, v)
180}
181
182#[unsafe(no_mangle)]
183pub extern "C" fn TEEC_InitializeContext(
184 _name: *const c_char,
185 ctx: *mut raw::TEEC_Context,
186) -> raw::TEEC_Result {
187 debug!("TEEC_InitializeContext");
188
189 let result = (|| -> Result<()> {
190 let mut ctx_nn = safe_ptr::deref_mut(ctx)?;
191 let ctx_ref = unsafe { ctx_nn.as_mut() };
194
195 let client = CcClient::init().map_err(|e| {
196 warn!("TEEC_InitializeContext:初始化机密通信上下文失败:{e}");
197 Error::new(ErrorKind::Communication)
198 })?;
199
200 let id = CONTEXT_ID_COUNTER.fetch_add(1, Ordering::SeqCst);
201
202 ctx_ref.imp.fd = id;
203 ctx_ref.imp.reg_mem = true;
204 ctx_ref.imp.memref_null = true;
205
206 ContextManager::add_context(ctx, client)
207 })();
208
209 match result {
210 Ok(_) => raw::TEEC_SUCCESS,
211 Err(e) => e.raw_code(),
212 }
213}
214
215#[unsafe(no_mangle)]
222pub extern "C" fn TEEC_FinalizeContext(ctx: *mut raw::TEEC_Context) {
223 debug!("TEEC_FinalizeContext");
224 ContextManager::remove_context(ctx);
225}
226
227#[unsafe(no_mangle)]
241pub extern "C" fn TEEC_OpenSession(
242 ctx: *mut raw::TEEC_Context,
243 session: *mut raw::TEEC_Session,
244 destination: *const raw::TEEC_UUID,
245 connection_method: u32,
246 _connection_data: *const c_void,
247 operation: *mut raw::TEEC_Operation,
248 ret_origin: *mut u32,
249) -> raw::TEEC_Result {
250 debug!("TEEC_OpenSession");
251
252 let result = (|| -> Result<u32> {
253 let _ = safe_ptr::deref_mut(ctx)?;
254 let _ = safe_ptr::deref_mut(session)?;
255 let uuid_nn = safe_ptr::deref(destination)?;
256 let uuid = unsafe { uuid_nn.as_ref() };
259 let uuid_str = uuid_to_string(uuid)?;
260
261 #[cfg(feature = "ca-sign-verify")]
264 let ca_auth_info = {
265 use teec_protocol::CaAuthInfo;
266
267 let auth_result = get_or_verify_ca();
268
269 if !auth_result.verified {
271 warn!("CA 签名验证失败: ca_uuid={}", auth_result.ca_uuid);
272 } else {
273 debug!("CA 签名验证通过: ca_uuid={}", auth_result.ca_uuid);
274 }
275
276 Some(CaAuthInfo {
278 ca_uuid: auth_result.ca_uuid,
279 verified: auth_result.verified,
280 })
281 };
282
283 #[cfg(not(feature = "ca-sign-verify"))]
284 let ca_auth_info: Option<crate::common::protocol::CaAuthInfo> = None;
285
286 let params = if operation.is_null() {
287 TEE_Parameters::default()
288 } else {
289 build_parameters_from_operation(operation)?
290 };
291
292 let request = TEE_Request::OpenSession {
293 uuid: uuid_str,
294 connection_method,
295 params,
296 ca_auth_info,
297 };
298
299 let mut session_nn = safe_ptr::deref_mut(session)?;
300 let session_ref = unsafe { session_nn.as_mut() };
303 let response = send_request_and_recv_response(ctx, PacketType::OpenSession, &request)?;
304
305 match response {
306 TEE_Response::OpenSession { session_id, result } => {
307 debug!("TEEC_OpenSession: 接收 session_id 和结果: {session_id}, {result}");
308
309 session_ref.imp.ctx = ctx;
310 session_ref.imp.session_id = session_id;
311
312 let _ = set_ret_origin(ret_origin, ErrorOrigin::TEE.into());
313 Ok(result)
314 }
315 _ => Err(Error::new(ErrorKind::BadParameters).with_origin(ErrorOrigin::API)),
316 }
317 })();
318
319 handle_error(result, ret_origin)
320}
321
322#[unsafe(no_mangle)]
326pub extern "C" fn TEEC_CloseSession(session: *mut raw::TEEC_Session) {
327 debug!("TEEC_CloseSession");
328
329 let result = (|| -> Result<()> {
330 let mut session_nn = safe_ptr::deref_mut(session)?;
331 let session_ref = unsafe { session_nn.as_mut() };
334 let session_id = session_ref.imp.session_id;
335 let ctx = session_ref.imp.ctx;
336
337 if ctx.is_null() {
338 return Err(Error::new(ErrorKind::BadParameters));
339 }
340
341 let request = TEE_Request::CloseSession { session_id };
342 let response = send_request_and_recv_response(ctx, PacketType::CloseSession, &request)?;
343
344 match response {
345 TEE_Response::CloseSession { result } => {
346 debug!("TEEC_CloseSession: 接收结果: {result}");
347 session_ref.imp.ctx = ptr::null_mut();
348 session_ref.imp.session_id = 0;
349 Ok(())
350 }
351 _ => Err(Error::new(ErrorKind::BadParameters)),
352 }
353 })();
354
355 if let Err(e) = result {
356 warn!("TEEC_CloseSession 失败:{e}");
358 }
359}
360
361#[unsafe(no_mangle)]
371pub extern "C" fn TEEC_InvokeCommand(
372 session: *mut raw::TEEC_Session,
373 cmd_id: u32,
374 operation: *mut raw::TEEC_Operation,
375 error_origin: *mut u32,
376) -> raw::TEEC_Result {
377 debug!("TEEC_InvokeCommand");
378
379 let result = (|| -> Result<u32> {
380 let mut session_nn = safe_ptr::deref_mut(session)?;
381 let session_ref = unsafe { session_nn.as_mut() };
384 let session_id = session_ref.imp.session_id;
385 let ctx = session_ref.imp.ctx;
386
387 if ctx.is_null() {
388 return Err(Error::new(ErrorKind::BadParameters));
389 }
390
391 let params = if operation.is_null() {
392 TEE_Parameters::default()
393 } else {
394 let mut operation_nn = safe_ptr::deref_mut(operation)?;
395 let operation_ref = unsafe { operation_nn.as_mut() };
398 operation_ref.imp.session = session;
399
400 build_parameters_from_operation(operation)?
401 };
402
403 let request = TEE_Request::InvokeCommand {
404 session_id,
405 cmd_id,
406 params,
407 };
408
409 let response = send_request_and_recv_response(ctx, PacketType::InvokeCommand, &request)?;
410
411 match response {
412 TEE_Response::InvokeCommand { params, result } => {
413 if result != raw::TEEC_SUCCESS {
414 return Err(Error::new(ErrorKind::from(result)).with_origin(ErrorOrigin::API));
415 }
416
417 if !operation.is_null() {
418 update_operation_from_parameters(operation, params)?;
419 }
420 Ok(result)
421 }
422 _ => Err(Error::new(ErrorKind::BadParameters).with_origin(ErrorOrigin::API)),
423 }
424 })();
425
426 handle_error(result, error_origin)
427}
428
429#[unsafe(no_mangle)]
439pub extern "C" fn TEEC_RegisterSharedMemory(
440 ctx: *mut raw::TEEC_Context,
441 shm: *mut raw::TEEC_SharedMemory,
442) -> raw::TEEC_Result {
443 debug!("TEEC_RegisterSharedMemory");
444
445 let result = SharedMemoryManager::allocate(ctx, shm, true);
446
447 match result {
448 Ok(_) => raw::TEEC_SUCCESS,
449 Err(e) => e.raw_code(),
450 }
451}
452
453#[unsafe(no_mangle)]
454pub extern "C" fn TEEC_RegisterSharedMemoryFileDescriptor(
455 _ctx: *mut raw::TEEC_Context,
456 _shm: *mut raw::TEEC_SharedMemory,
457 _fd: i32,
458) -> raw::TEEC_Result {
459 ErrorKind::NotImplemented.into()
461}
462
463#[unsafe(no_mangle)]
472pub extern "C" fn TEEC_AllocateSharedMemory(
473 ctx: *mut raw::TEEC_Context,
474 shm: *mut raw::TEEC_SharedMemory,
475) -> raw::TEEC_Result {
476 debug!("TEEC_AllocateSharedMemory");
477
478 match SharedMemoryManager::allocate(ctx, shm, false) {
479 Ok(_) => raw::TEEC_SUCCESS,
480 Err(e) => e.raw_code(),
481 }
482}
483
484#[unsafe(no_mangle)]
488pub extern "C" fn TEEC_ReleaseSharedMemory(shm: *mut raw::TEEC_SharedMemory) {
489 debug!("TEEC_ReleaseSharedMemory");
490 SharedMemoryManager::release(shm);
491}
492
493#[unsafe(no_mangle)]
497pub extern "C" fn TEEC_RequestCancellation(operation: *mut raw::TEEC_Operation) {
498 debug!("TEEC_RequestCancellation");
499
500 let result = (|| -> Result<()> {
501 let mut operation_nn = safe_ptr::deref_mut(operation)?;
502 let operation_ref = unsafe { operation_nn.as_mut() };
505 let session = operation_ref.imp.session;
506
507 if session.is_null() {
508 return Ok(());
509 }
510
511 let mut session_nn = safe_ptr::deref_mut(session)?;
512 let session_ref = unsafe { session_nn.as_mut() };
515 let session_id = session_ref.imp.session_id;
516 let ctx = session_ref.imp.ctx;
517
518 if ctx.is_null() {
519 return Ok(());
520 }
521
522 let request = TEE_Request::RequestCancellation { session_id };
523 let response =
524 send_request_and_recv_response(ctx, PacketType::RequestCancellation, &request)?;
525
526 match response {
527 TEE_Response::RequestCancellation { result: _ } => {
528 debug!("TEEC_RequestCancellation: 接收结果");
529 Ok(())
530 }
531 _ => Err(Error::new(ErrorKind::BadParameters)),
532 }
533 })();
534
535 if let Err(e) = result {
536 warn!("TEEC_RequestCancellation 失败:{e}");
538 }
539}