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
42use std::{
43 ffi::{c_char, c_void},
44 ptr,
45 sync::{
46 LazyLock,
47 atomic::{AtomicI32, Ordering},
48 },
49};
50
51use log::{debug, warn};
52use postcard::{take_from_bytes, to_allocvec};
53use uuid::Uuid;
54
55use teec_protocol::{PacketType, TEE_Parameters, TEE_Request, TEE_Response};
56
57#[cfg(feature = "ca-sign-verify")]
58pub use ca_auth::{clear_cache, get_or_verify_ca};
59pub use context::ContextManager;
60pub use operation::{build_parameters_from_operation, update_operation_from_parameters};
61pub use shared_memory::SharedMemoryManager;
62
63use crate::{Error, ErrorKind, ErrorOrigin, Result, cc_client::client::CcClient, raw};
64
65static CONTEXT_ID_COUNTER: LazyLock<AtomicI32> = LazyLock::new(|| AtomicI32::new(0));
66
67fn uuid_to_string(uuid: &raw::TEEC_UUID) -> Result<String> {
69 let bytes: [u8; 16] = [
70 (uuid.timeLow >> 24) as u8,
71 (uuid.timeLow >> 16) as u8,
72 (uuid.timeLow >> 8) as u8,
73 uuid.timeLow as u8,
74 (uuid.timeMid >> 8) as u8,
75 uuid.timeMid as u8,
76 (uuid.timeHiAndVersion >> 8) as u8,
77 uuid.timeHiAndVersion as u8,
78 uuid.clockSeqAndNode[0],
79 uuid.clockSeqAndNode[1],
80 uuid.clockSeqAndNode[2],
81 uuid.clockSeqAndNode[3],
82 uuid.clockSeqAndNode[4],
83 uuid.clockSeqAndNode[5],
84 uuid.clockSeqAndNode[6],
85 uuid.clockSeqAndNode[7],
86 ];
87
88 Uuid::from_slice(&bytes)
89 .map(|u| u.to_string())
90 .map_err(|_| Error::new(ErrorKind::BadFormat))
91}
92
93fn handle_error(result: Result<u32>, ret_origin: *mut u32) -> raw::TEEC_Result {
95 match result {
96 Ok(code) => code,
97 Err(e) => {
98 if !ret_origin.is_null() {
99 unsafe {
102 *ret_origin = e.origin().unwrap_or(ErrorOrigin::API) as u32;
103 }
104 }
105 e.raw_code()
106 }
107 }
108}
109
110fn send_request_and_recv_response(
112 ctx: *mut raw::TEEC_Context,
113 packet_type: PacketType,
114 request: &TEE_Request,
115) -> Result<TEE_Response> {
116 let client_arc = ContextManager::get_client(ctx)?;
117 let mut client = client_arc
118 .lock()
119 .map_err(|_| Error::new(ErrorKind::Generic).with_origin(ErrorOrigin::API))?;
120
121 let request_data = to_allocvec(request).map_err(|e| {
122 warn!("序列化请求失败:{e}");
123 Error::new(ErrorKind::BadFormat).with_origin(ErrorOrigin::API)
124 })?;
125
126 const MAX_REQUEST_SIZE: usize = 64 * 1024 * 1024; if request_data.len() > MAX_REQUEST_SIZE {
130 warn!(
131 "请求数据过大:{} bytes (最大允许 {} bytes)",
132 request_data.len(),
133 MAX_REQUEST_SIZE
134 );
135 return Err(Error::new(ErrorKind::BadFormat).with_origin(ErrorOrigin::API));
136 }
137
138 client
139 .send_data_with_header(packet_type, &request_data)
140 .map_err(|e| {
141 warn!("发送请求失败:{e}");
142 Error::new(ErrorKind::Communication).with_origin(ErrorOrigin::COMMS)
143 })?;
144
145 let mut len_buf = [0u8; 4];
146
147 client.recv_data(&mut len_buf).map_err(|e| {
148 warn!("接收响应长度失败:{e}");
149 Error::new(ErrorKind::Communication).with_origin(ErrorOrigin::COMMS)
150 })?;
151
152 let response_len_u32 = u32::from_ne_bytes(len_buf);
154 const MAX_RESPONSE_SIZE: usize = 64 * 1024 * 1024; if response_len_u32 > MAX_RESPONSE_SIZE as u32 {
157 warn!(
158 "响应数据过大:{} bytes (最大允许 {} bytes)",
159 response_len_u32, MAX_RESPONSE_SIZE
160 );
161 return Err(Error::new(ErrorKind::BadFormat).with_origin(ErrorOrigin::COMMS));
162 }
163
164 let response_len = response_len_u32 as usize;
165 let mut response_data = vec![0u8; response_len];
166
167 client.recv_data(&mut response_data).map_err(|e| {
168 warn!("接收响应数据失败:{e}");
169 Error::new(ErrorKind::Communication).with_origin(ErrorOrigin::COMMS)
170 })?;
171
172 take_from_bytes::<TEE_Response>(&response_data)
173 .map(|(response, _)| response)
174 .map_err(|e| {
175 warn!("反序列化响应失败:{e}");
176 Error::new(ErrorKind::BadFormat).with_origin(ErrorOrigin::API)
177 })
178}
179
180fn set_ret_origin(p: *mut u32, v: u32) -> Result<()> {
182 safe_ptr::write_raw(p, v)
183}
184
185#[unsafe(no_mangle)]
186pub extern "C" fn TEEC_InitializeContext(
187 _name: *const c_char,
188 ctx: *mut raw::TEEC_Context,
189) -> raw::TEEC_Result {
190 debug!("TEEC_InitializeContext");
191
192 let result = (|| -> Result<()> {
193 let mut ctx_nn = safe_ptr::deref_mut(ctx)?;
194 let ctx_ref = unsafe { ctx_nn.as_mut() };
197
198 let client = CcClient::init().map_err(|e| {
199 warn!("TEEC_InitializeContext:初始化机密通信上下文失败:{e}");
200 Error::new(ErrorKind::Communication)
201 })?;
202
203 let id = CONTEXT_ID_COUNTER.fetch_add(1, Ordering::SeqCst);
204
205 ctx_ref.imp.fd = id;
206 ctx_ref.imp.reg_mem = true;
207 ctx_ref.imp.memref_null = true;
208
209 ContextManager::add_context(ctx, client)
210 })();
211
212 match result {
213 Ok(_) => raw::TEEC_SUCCESS,
214 Err(e) => e.raw_code(),
215 }
216}
217
218#[unsafe(no_mangle)]
225pub extern "C" fn TEEC_FinalizeContext(ctx: *mut raw::TEEC_Context) {
226 debug!("TEEC_FinalizeContext");
227
228 if let Ok(ctx_nn) = safe_ptr::deref(ctx) {
229 let ctx_ref = unsafe { ctx_nn.as_ref() };
232 let ctx_id = ctx_ref.imp.fd;
233 if ctx_id < 0 {
234 debug!("TEEC_FinalizeContext: context already finalized (fd={ctx_id})");
235 return;
236 }
237 }
238
239 SharedMemoryManager::release_by_context(ctx);
240 ContextManager::remove_context(ctx);
241}
242
243#[unsafe(no_mangle)]
257pub extern "C" fn TEEC_OpenSession(
258 ctx: *mut raw::TEEC_Context,
259 session: *mut raw::TEEC_Session,
260 destination: *const raw::TEEC_UUID,
261 connection_method: u32,
262 _connection_data: *const c_void,
263 operation: *mut raw::TEEC_Operation,
264 ret_origin: *mut u32,
265) -> raw::TEEC_Result {
266 debug!("TEEC_OpenSession");
267
268 let result = (|| -> Result<u32> {
269 let _ = safe_ptr::deref_mut(ctx)?;
270 let _ = safe_ptr::deref_mut(session)?;
271 let uuid_nn = safe_ptr::deref(destination)?;
272 let uuid = unsafe { uuid_nn.as_ref() };
275 let uuid_str = uuid_to_string(uuid)?;
276
277 #[cfg(feature = "ca-sign-verify")]
280 let ca_auth_info = {
281 use teec_protocol::CaAuthInfo;
282
283 let auth_result = get_or_verify_ca();
284
285 if !auth_result.verified {
287 warn!("CA 签名验证失败: ca_uuid={}", auth_result.ca_uuid);
288 } else {
289 debug!("CA 签名验证通过: ca_uuid={}", auth_result.ca_uuid);
290 }
291
292 Some(CaAuthInfo {
294 ca_uuid: auth_result.ca_uuid,
295 verified: auth_result.verified,
296 })
297 };
298
299 #[cfg(not(feature = "ca-sign-verify"))]
300 let ca_auth_info: Option<teec_protocol::CaAuthInfo> = None;
301
302 let params = if operation.is_null() {
303 TEE_Parameters::default()
304 } else {
305 build_parameters_from_operation(operation)?
306 };
307
308 let request = TEE_Request::OpenSession {
309 uuid: uuid_str,
310 connection_method,
311 params,
312 ca_auth_info,
313 };
314
315 let mut session_nn = safe_ptr::deref_mut(session)?;
316 let session_ref = unsafe { session_nn.as_mut() };
319 let response = send_request_and_recv_response(ctx, PacketType::OpenSession, &request)?;
320
321 match response {
322 TEE_Response::OpenSession { session_id, result } => {
323 debug!("TEEC_OpenSession: 接收 session_id 和结果: {session_id}, {result}");
324
325 session_ref.imp.ctx = ctx;
326 session_ref.imp.session_id = session_id;
327
328 let _ = set_ret_origin(ret_origin, ErrorOrigin::TEE.into());
329 Ok(result)
330 }
331 _ => Err(Error::new(ErrorKind::BadParameters).with_origin(ErrorOrigin::API)),
332 }
333 })();
334
335 handle_error(result, ret_origin)
336}
337
338#[unsafe(no_mangle)]
342pub extern "C" fn TEEC_CloseSession(session: *mut raw::TEEC_Session) {
343 debug!("TEEC_CloseSession");
344
345 let result = (|| -> Result<()> {
346 let mut session_nn = safe_ptr::deref_mut(session)?;
347 let session_ref = unsafe { session_nn.as_mut() };
350 let session_id = session_ref.imp.session_id;
351 let ctx = session_ref.imp.ctx;
352
353 if ctx.is_null() {
354 return Err(Error::new(ErrorKind::BadParameters));
355 }
356
357 let request = TEE_Request::CloseSession { session_id };
358 let response = send_request_and_recv_response(ctx, PacketType::CloseSession, &request)?;
359
360 match response {
361 TEE_Response::CloseSession { result } => {
362 debug!("TEEC_CloseSession: 接收结果: {result}");
363 session_ref.imp.ctx = ptr::null_mut();
364 session_ref.imp.session_id = 0;
365 Ok(())
366 }
367 _ => Err(Error::new(ErrorKind::BadParameters)),
368 }
369 })();
370
371 if let Err(e) = result {
372 warn!("TEEC_CloseSession 失败:{e}");
374 }
375}
376
377#[unsafe(no_mangle)]
387pub extern "C" fn TEEC_InvokeCommand(
388 session: *mut raw::TEEC_Session,
389 cmd_id: u32,
390 operation: *mut raw::TEEC_Operation,
391 error_origin: *mut u32,
392) -> raw::TEEC_Result {
393 debug!("TEEC_InvokeCommand");
394
395 let result = (|| -> Result<u32> {
396 let mut session_nn = safe_ptr::deref_mut(session)?;
397 let session_ref = unsafe { session_nn.as_mut() };
400 let session_id = session_ref.imp.session_id;
401 let ctx = session_ref.imp.ctx;
402
403 if ctx.is_null() {
404 return Err(Error::new(ErrorKind::BadParameters));
405 }
406
407 let params = if operation.is_null() {
408 TEE_Parameters::default()
409 } else {
410 let mut operation_nn = safe_ptr::deref_mut(operation)?;
411 let operation_ref = unsafe { operation_nn.as_mut() };
414 operation_ref.imp.session = session;
415
416 build_parameters_from_operation(operation)?
417 };
418
419 let request = TEE_Request::InvokeCommand {
420 session_id,
421 cmd_id,
422 params,
423 };
424
425 let response = send_request_and_recv_response(ctx, PacketType::InvokeCommand, &request)?;
426
427 match response {
428 TEE_Response::InvokeCommand { params, result } => {
429 if result != raw::TEEC_SUCCESS {
430 let origin = if result == raw::TEEC_ERROR_TARGET_DEAD {
431 ErrorOrigin::TEE
432 } else {
433 ErrorOrigin::API
434 };
435 return Err(Error::new(ErrorKind::from(result)).with_origin(origin));
436 }
437
438 if !operation.is_null() {
439 update_operation_from_parameters(operation, params)?;
440 }
441 Ok(result)
442 }
443 _ => Err(Error::new(ErrorKind::BadParameters).with_origin(ErrorOrigin::API)),
444 }
445 })();
446
447 handle_error(result, error_origin)
448}
449
450#[unsafe(no_mangle)]
460pub extern "C" fn TEEC_RegisterSharedMemory(
461 ctx: *mut raw::TEEC_Context,
462 shm: *mut raw::TEEC_SharedMemory,
463) -> raw::TEEC_Result {
464 debug!("TEEC_RegisterSharedMemory");
465
466 let result = SharedMemoryManager::allocate(ctx, shm, true);
467
468 match result {
469 Ok(_) => raw::TEEC_SUCCESS,
470 Err(e) => e.raw_code(),
471 }
472}
473
474#[unsafe(no_mangle)]
475pub extern "C" fn TEEC_RegisterSharedMemoryFileDescriptor(
476 _ctx: *mut raw::TEEC_Context,
477 _shm: *mut raw::TEEC_SharedMemory,
478 _fd: i32,
479) -> raw::TEEC_Result {
480 ErrorKind::NotImplemented.into()
482}
483
484#[unsafe(no_mangle)]
493pub extern "C" fn TEEC_AllocateSharedMemory(
494 ctx: *mut raw::TEEC_Context,
495 shm: *mut raw::TEEC_SharedMemory,
496) -> raw::TEEC_Result {
497 debug!("TEEC_AllocateSharedMemory");
498
499 match SharedMemoryManager::allocate(ctx, shm, false) {
500 Ok(_) => raw::TEEC_SUCCESS,
501 Err(e) => e.raw_code(),
502 }
503}
504
505#[unsafe(no_mangle)]
509pub extern "C" fn TEEC_ReleaseSharedMemory(shm: *mut raw::TEEC_SharedMemory) {
510 debug!("TEEC_ReleaseSharedMemory");
511 SharedMemoryManager::release(shm);
512}
513
514#[unsafe(no_mangle)]
518pub extern "C" fn TEEC_RequestCancellation(operation: *mut raw::TEEC_Operation) {
519 debug!("TEEC_RequestCancellation");
520
521 let result = (|| -> Result<()> {
522 let mut operation_nn = safe_ptr::deref_mut(operation)?;
523 let operation_ref = unsafe { operation_nn.as_mut() };
526 let session = operation_ref.imp.session;
527
528 if session.is_null() {
529 return Ok(());
530 }
531
532 let mut session_nn = safe_ptr::deref_mut(session)?;
533 let session_ref = unsafe { session_nn.as_mut() };
536 let session_id = session_ref.imp.session_id;
537 let ctx = session_ref.imp.ctx;
538
539 if ctx.is_null() {
540 return Ok(());
541 }
542
543 let request = TEE_Request::RequestCancellation { session_id };
544 let response =
545 send_request_and_recv_response(ctx, PacketType::RequestCancellation, &request)?;
546
547 match response {
548 TEE_Response::RequestCancellation { result: _ } => {
549 debug!("TEEC_RequestCancellation: 接收结果");
550 Ok(())
551 }
552 _ => Err(Error::new(ErrorKind::BadParameters)),
553 }
554 })();
555
556 if let Err(e) = result {
557 warn!("TEEC_RequestCancellation 失败:{e}");
559 }
560}
561
562#[cfg(test)]
563mod tests {
564 use super::*;
565
566 #[test]
567 fn test_uuid_to_string_roundtrip() {
568 let uuid = raw::TEEC_UUID {
569 timeLow: 0x00112233,
570 timeMid: 0x4455,
571 timeHiAndVersion: 0x6677,
572 clockSeqAndNode: [0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff],
573 };
574
575 let s = uuid_to_string(&uuid).expect("UUID转换应该成功");
576 assert_eq!(
577 s, "00112233-4455-6677-8899-aabbccddeeff",
578 "转换后的UUID字符串应该符合标准格式"
579 );
580 }
581}