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