1#![allow(dead_code)]
9#![allow(non_camel_case_types)]
10#![allow(non_upper_case_globals)]
11#![allow(non_snake_case)]
12
13use std::{
14 ffi::{c_char, c_void},
15 ptr,
16 sync::{
17 Arc, Mutex,
18 atomic::{AtomicI32, Ordering},
19 },
20};
21
22use dashmap::DashMap;
23use log::{debug, warn};
24use once_cell::sync::Lazy;
25use postcard::{take_from_bytes, to_allocvec};
26use uuid::Uuid;
27
28use crate::cc_client::client::CcClient;
29use crate::common::protocol::{
30 PacketType, TEE_ParamType, TEE_Parameters, TEE_Request, TEE_Response,
31};
32use crate::{Error, ErrorKind, ErrorOrigin, Result, raw};
33
34const SHM_FLAG_BUFFER_ALLOCED: u32 = 1 << 0;
35
36type ContextMap = DashMap<i32, Arc<Mutex<CcClient>>>;
37type SharedMemoryMap = DashMap<i32, Vec<u8>>;
38
39static TEEC_MUTEX: Lazy<Mutex<()>> = Lazy::new(|| Mutex::new(()));
40static CONTEXT_ID_COUNTER: Lazy<AtomicI32> = Lazy::new(|| AtomicI32::new(-1));
41static CONTEXTS: Lazy<ContextMap> = Lazy::new(DashMap::new);
42static SHMS: Lazy<SharedMemoryMap> = Lazy::new(DashMap::new);
43
44mod safe_ptr {
46 use super::{Error, ErrorKind, ErrorOrigin, Result};
47 use std::ptr::NonNull;
48
49 pub fn deref_mut<T>(ptr: *mut T) -> Result<NonNull<T>> {
51 NonNull::new(ptr).ok_or(Error::new(ErrorKind::BadParameters).with_origin(ErrorOrigin::API))
52 }
53
54 pub fn deref<T>(ptr: *const T) -> Result<NonNull<T>> {
56 NonNull::new(ptr as *mut T)
57 .ok_or(Error::new(ErrorKind::BadParameters).with_origin(ErrorOrigin::API))
58 }
59
60 pub fn write_raw<T>(ptr: *mut T, value: T) -> Result<()> {
62 let nn = NonNull::new(ptr)
63 .ok_or(Error::new(ErrorKind::BadParameters).with_origin(ErrorOrigin::API))?;
64 unsafe { nn.as_ptr().write(value) };
68 Ok(())
69 }
70
71 pub fn read_raw<T: Copy>(ptr: *const T) -> Result<T> {
73 let nn = NonNull::new(ptr as *mut T)
74 .ok_or(Error::new(ErrorKind::BadParameters).with_origin(ErrorOrigin::API))?;
75 Ok(unsafe { *nn.as_ptr() })
78 }
79
80 pub fn read_to_vec<T: Copy>(src: *const T, len: usize) -> Result<Vec<T>> {
82 if src.is_null() && len > 0 {
83 return Err(Error::new(ErrorKind::BadParameters).with_origin(ErrorOrigin::API));
84 }
85 let _nn = NonNull::new(src as *mut T)
86 .ok_or(Error::new(ErrorKind::BadParameters).with_origin(ErrorOrigin::API))?;
87 let slice = unsafe { std::slice::from_raw_parts(src, len) };
90 Ok(slice.to_vec())
91 }
92
93 pub fn write_from_slice<T: Copy>(dst: *mut T, src: &[T]) -> Result<()> {
95 if dst.is_null() && !src.is_empty() {
96 return Err(Error::new(ErrorKind::BadParameters).with_origin(ErrorOrigin::API));
97 }
98
99 if src.is_empty() {
100 return Err(Error::new(ErrorKind::BadFormat).with_origin(ErrorOrigin::API));
101 }
102
103 let _nn = NonNull::new(dst)
104 .ok_or(Error::new(ErrorKind::BadParameters).with_origin(ErrorOrigin::API))?;
105 let dst_slice = unsafe { std::slice::from_raw_parts_mut(dst, src.len()) };
108 dst_slice.copy_from_slice(src);
109 Ok(())
110 }
111
112 pub fn add_ptr<T>(ptr: *const T, offset: usize) -> *const T {
114 unsafe { ptr.add(offset) }
117 }
118
119 pub fn add_ptr_mut<T>(ptr: *mut T, offset: usize) -> *mut T {
121 unsafe { ptr.add(offset) }
124 }
125}
126
127struct ContextManager;
129
130impl ContextManager {
131 fn add_context(ctx: *mut raw::TEEC_Context, client: CcClient) -> Result<()> {
133 let mut ctx_nn = safe_ptr::deref_mut(ctx)?;
134 let ctx_ref = unsafe { ctx_nn.as_mut() };
138 let ctx_id: i32 = ctx_ref.imp.fd;
139 let client_arc = Arc::new(Mutex::new(client));
140
141 CONTEXTS.insert(ctx_id, client_arc);
142 Ok(())
143 }
144
145 fn remove_context(ctx: *mut raw::TEEC_Context) {
147 if let Ok(mut ctx_nn) = safe_ptr::deref_mut(ctx) {
148 let ctx_ref = unsafe { ctx_nn.as_mut() };
151 let ctx_id = ctx_ref.imp.fd;
152 CONTEXTS.remove(&ctx_id);
153 ctx_ref.imp.fd = -1;
154 }
155 }
156
157 fn get_client(ctx: *mut raw::TEEC_Context) -> Result<Arc<Mutex<CcClient>>> {
159 let ctx_nn = safe_ptr::deref_mut(ctx)?;
160 let ctx_ref = unsafe { ctx_nn.as_ref() };
163 let ctx_id = ctx_ref.imp.fd;
164
165 CONTEXTS
166 .get(&ctx_id)
167 .map(|entry| entry.value().clone())
168 .ok_or_else(|| Error::new(ErrorKind::Generic).with_origin(ErrorOrigin::API))
169 }
170}
171
172struct SharedMemoryManager;
174
175impl SharedMemoryManager {
176 fn allocate(
178 ctx: *mut raw::TEEC_Context,
179 shm: *mut raw::TEEC_SharedMemory,
180 registe: bool,
181 ) -> Result<()> {
182 let mut shm_nn = safe_ptr::deref_mut(shm)?;
183 let ctx_nn = safe_ptr::deref(ctx)?;
184 let shm_ref = unsafe { shm_nn.as_mut() };
187 let ctx_ref = unsafe { ctx_nn.as_ref() };
189 let flags = shm_ref.flags;
190 let size = shm_ref.size;
191
192 if size == 0 || flags == 0 || flags & !(raw::TEEC_MEM_INPUT | raw::TEEC_MEM_OUTPUT) != 0 {
193 return Err(Error::new(ErrorKind::BadParameters));
194 }
195
196 let mut buffer = vec![0u8; size];
197
198 if registe {
199 if shm_ref.buffer.is_null() {
200 return Err(Error::new(ErrorKind::BadParameters));
201 }
202
203 buffer = safe_ptr::read_to_vec(shm_ref.buffer as *const u8, size)?;
204 }
205
206 let ptr = buffer.as_mut_ptr() as *mut c_void;
207
208 if ptr.is_null() {
209 return Err(Error::new(ErrorKind::OutOfMemory));
210 }
211
212 let id = ctx_ref.imp.fd;
213
214 shm_ref.buffer = ptr;
215 shm_ref.imp.id = id;
216 shm_ref.imp.registered_fd = -1;
217 shm_ref.imp.shadow_buffer = ptr::null_mut();
218 shm_ref.imp.alloced_size = size;
219 shm_ref.imp.flags = SHM_FLAG_BUFFER_ALLOCED;
220
221 SHMS.insert(id, buffer);
222
223 Ok(())
224 }
225
226 fn release(shm: *mut raw::TEEC_SharedMemory) {
228 if let Ok(mut shm_nn) = safe_ptr::deref_mut(shm) {
229 let shm_ref = unsafe { shm_nn.as_mut() };
231 if shm_ref.imp.id < 0 {
232 return;
233 }
234
235 let id = shm_ref.imp.id;
236
237 shm_ref.imp.id = -1;
238 shm_ref.size = 0;
239 shm_ref.flags = 0;
240 shm_ref.buffer = ptr::null_mut();
241
242 SHMS.remove(&id);
243 }
244 }
245
246 fn get_buffer(shm: *const raw::TEEC_SharedMemory) -> Option<Vec<u8>> {
248 if shm.is_null() {
249 return None;
250 }
251
252 let id = unsafe { (*shm).imp.id };
254 SHMS.get(&id).map(|entry| entry.value().clone())
255 }
256}
257
258fn uuid_to_string(uuid: &raw::TEEC_UUID) -> Result<String> {
260 let bytes: [u8; 16] = [
261 (uuid.timeLow >> 24) as u8,
262 (uuid.timeLow >> 16) as u8,
263 (uuid.timeLow >> 8) as u8,
264 uuid.timeLow as u8,
265 (uuid.timeMid >> 8) as u8,
266 uuid.timeMid as u8,
267 (uuid.timeHiAndVersion >> 8) as u8,
268 uuid.timeHiAndVersion as u8,
269 uuid.clockSeqAndNode[0],
270 uuid.clockSeqAndNode[1],
271 uuid.clockSeqAndNode[2],
272 uuid.clockSeqAndNode[3],
273 uuid.clockSeqAndNode[4],
274 uuid.clockSeqAndNode[5],
275 uuid.clockSeqAndNode[6],
276 uuid.clockSeqAndNode[7],
277 ];
278
279 Uuid::from_slice(&bytes)
280 .map(|u| u.to_string())
281 .map_err(|_| Error::new(ErrorKind::BadFormat))
282}
283
284struct OperationParams {
286 operation: *mut raw::TEEC_Operation,
287}
288
289impl OperationParams {
290 fn new(operation: *mut raw::TEEC_Operation) -> Result<Self> {
291 let _ = safe_ptr::deref_mut(operation)?;
292 Ok(Self { operation })
293 }
294
295 fn param_types(&self) -> Result<u32> {
297 let op_nn = safe_ptr::deref(self.operation)?;
298 let op_ref = unsafe { op_nn.as_ref() };
301 Ok(op_ref.paramTypes)
302 }
303
304 fn get_value(&self, idx: usize) -> Result<(u32, u32)> {
306 if idx >= raw::TEEC_CONFIG_PAYLOAD_REF_COUNT {
307 return Err(Error::new(ErrorKind::BadParameters));
308 }
309
310 let op_nn = safe_ptr::deref(self.operation)?;
311 let op_ref = unsafe { op_nn.as_ref() };
314 let param = &op_ref.params[idx];
315 unsafe { Ok((param.value.a, param.value.b)) }
317 }
318
319 fn set_value(&self, idx: usize, a: u32, b: u32) -> Result<()> {
321 if idx >= raw::TEEC_CONFIG_PAYLOAD_REF_COUNT {
322 return Err(Error::new(ErrorKind::BadParameters));
323 }
324
325 let mut op_nn = safe_ptr::deref_mut(self.operation)?;
326 let op_ref = unsafe { op_nn.as_mut() };
329 let param = &mut op_ref.params[idx];
330
331 param.value.a = a;
332 param.value.b = b;
333
334 Ok(())
335 }
336
337 fn get_tmpref_data(&self, idx: usize) -> Result<Vec<u8>> {
339 if idx >= raw::TEEC_CONFIG_PAYLOAD_REF_COUNT {
340 return Err(Error::new(ErrorKind::BadParameters));
341 }
342
343 let op_nn = safe_ptr::deref(self.operation)?;
344 let op_ref = unsafe { op_nn.as_ref() };
347 let tmp = unsafe { &op_ref.params[idx].tmpref };
348
349 if tmp.buffer.is_null() && tmp.size > 0 {
350 return Err(Error::new(ErrorKind::BadParameters));
351 }
352
353 if tmp.size > 0 && !tmp.buffer.is_null() {
354 safe_ptr::read_to_vec(tmp.buffer as *const u8, tmp.size)
355 } else {
356 Ok(Vec::new())
357 }
358 }
359
360 fn set_tmpref_data(&self, idx: usize, data: &[u8]) -> Result<()> {
362 if idx >= raw::TEEC_CONFIG_PAYLOAD_REF_COUNT {
363 return Err(Error::new(ErrorKind::BadParameters));
364 }
365
366 let mut op_nn = safe_ptr::deref_mut(self.operation)?;
367 let op_ref = unsafe { op_nn.as_mut() };
371 let tmp = unsafe { &mut op_ref.params[idx].tmpref };
372
373 if tmp.buffer.is_null() {
374 return Err(Error::new(ErrorKind::BadParameters));
375 }
376
377 let dest_len = data.len().min(tmp.size);
378 if dest_len > 0 {
379 safe_ptr::write_from_slice(tmp.buffer as *mut u8, &data[..dest_len])?;
380 }
381 tmp.size = dest_len;
382
383 Ok(())
384 }
385
386 fn get_memref_parent_flags(&self, idx: usize) -> Result<u32> {
388 if idx >= raw::TEEC_CONFIG_PAYLOAD_REF_COUNT {
389 return Err(Error::new(ErrorKind::BadParameters));
390 }
391
392 let op_nn = safe_ptr::deref(self.operation)?;
393 let op_ref = unsafe { op_nn.as_ref() };
396 let mem: &raw::TEEC_RegisteredMemoryReference = unsafe { &op_ref.params[idx].memref };
397
398 if mem.parent.is_null() {
399 return Err(Error::new(ErrorKind::BadParameters));
400 }
401
402 let parent_nn = safe_ptr::deref(mem.parent)?;
403 let parent = unsafe { parent_nn.as_ref() };
406
407 Ok(parent.flags)
408 }
409
410 fn get_memref_data_whole(&self, idx: usize) -> Result<Vec<u8>> {
412 if idx >= raw::TEEC_CONFIG_PAYLOAD_REF_COUNT {
413 return Err(Error::new(ErrorKind::BadParameters));
414 }
415
416 let op_nn = safe_ptr::deref(self.operation)?;
417 let op_ref = unsafe { op_nn.as_ref() };
420 let mem: &raw::TEEC_RegisteredMemoryReference = unsafe { &op_ref.params[idx].memref };
421
422 if mem.parent.is_null() {
423 return Err(Error::new(ErrorKind::BadParameters));
424 }
425
426 let parent_nn = safe_ptr::deref(mem.parent)?;
427 let parent = unsafe { parent_nn.as_ref() };
430 let mem_size = mem.size;
431
432 if !parent.buffer.is_null() {
433 safe_ptr::read_to_vec(parent.buffer as *const u8, mem_size)
434 } else {
435 Ok(SharedMemoryManager::get_buffer(mem.parent).unwrap_or_else(|| vec![0u8; mem_size]))
436 }
437 }
438
439 fn set_memref_data_whole(&self, idx: usize, data: &[u8]) -> Result<()> {
441 if idx >= raw::TEEC_CONFIG_PAYLOAD_REF_COUNT {
442 return Err(Error::new(ErrorKind::BadParameters));
443 }
444
445 let op_nn = safe_ptr::deref(self.operation)?;
446 let op_ref = unsafe { op_nn.as_ref() };
449 let mem = unsafe { &op_ref.params[idx].memref };
450
451 if mem.parent.is_null() {
452 return Err(Error::new(ErrorKind::BadParameters));
453 }
454
455 let mut parent_nn = safe_ptr::deref_mut(mem.parent)?;
456 let parent = unsafe { parent_nn.as_mut() };
459
460 if parent.buffer.is_null() {
461 return Err(Error::new(ErrorKind::BadParameters));
462 }
463
464 if !data.is_empty() {
465 safe_ptr::write_from_slice(parent.buffer as *mut u8, data)?;
466 }
467 Ok(())
468 }
469
470 fn get_memref_data_partial(&self, idx: usize, req_flags: u32) -> Result<Vec<u8>> {
472 if idx >= raw::TEEC_CONFIG_PAYLOAD_REF_COUNT {
473 return Err(Error::new(ErrorKind::BadParameters));
474 }
475
476 let op_nn = safe_ptr::deref(self.operation)?;
477 let op_ref = unsafe { op_nn.as_ref() };
480 let mem: &raw::TEEC_RegisteredMemoryReference = unsafe { &op_ref.params[idx].memref };
481
482 if mem.parent.is_null() {
483 return Err(Error::new(ErrorKind::BadParameters));
484 }
485
486 let parent_nn = safe_ptr::deref(mem.parent)?;
487 let parent = unsafe { parent_nn.as_ref() };
490
491 if parent.flags & req_flags != req_flags {
492 return Err(Error::new(ErrorKind::BadParameters));
493 }
494
495 if mem.offset.saturating_add(mem.size) > parent.size {
496 return Err(Error::new(ErrorKind::BadParameters));
497 }
498
499 let mem_size = mem.size;
500 let offset = mem.offset;
501
502 if !parent.buffer.is_null() {
503 let start_ptr = safe_ptr::add_ptr(parent.buffer as *const u8, offset);
504 safe_ptr::read_to_vec(start_ptr, mem_size)
505 } else {
506 Err(Error::new(ErrorKind::BadParameters))
507 }
508 }
509
510 fn set_memref_data_partial(&self, idx: usize, data: &[u8]) -> Result<()> {
512 if idx >= raw::TEEC_CONFIG_PAYLOAD_REF_COUNT {
513 return Err(Error::new(ErrorKind::BadParameters));
514 }
515
516 let op_nn = safe_ptr::deref(self.operation)?;
517 let op_ref = unsafe { op_nn.as_ref() };
520 let mem = unsafe { &op_ref.params[idx].memref };
521
522 if mem.parent.is_null() {
523 return Err(Error::new(ErrorKind::BadParameters));
524 }
525
526 let mut parent_nn = safe_ptr::deref_mut(mem.parent)?;
527 let parent = unsafe { parent_nn.as_mut() };
530
531 if parent.buffer.is_null() {
532 return Err(Error::new(ErrorKind::BadParameters));
533 }
534
535 if !data.is_empty() {
536 let offset = mem.offset;
537 let start_ptr = safe_ptr::add_ptr_mut(parent.buffer as *mut u8, offset);
538 safe_ptr::write_from_slice(start_ptr, data)?;
539 }
540 Ok(())
541 }
542}
543
544fn set_ret_origin(p: *mut u32, v: u32) -> Result<()> {
546 safe_ptr::write_raw(p, v)
547}
548
549fn handle_error<T>(result: Result<T>, ret_origin: *mut u32) -> u32 {
551 match result {
552 Ok(_) => raw::TEEC_SUCCESS,
553 Err(e) => {
554 let _ = set_ret_origin(ret_origin, e.origin().unwrap_or(ErrorOrigin::API).into());
555 e.raw_code()
556 }
557 }
558}
559
560fn build_parameters_from_operation(operation: *mut raw::TEEC_Operation) -> Result<TEE_Parameters> {
562 let op_params = OperationParams::new(operation)?;
563 let param_types = op_params.param_types()?;
564 let mut params = TEE_Parameters::default();
565
566 let param_tuples = [
567 (&mut params.0, 0),
568 (&mut params.1, 1),
569 (&mut params.2, 2),
570 (&mut params.3, 3),
571 ];
572
573 for (param, idx) in param_tuples {
574 let param_type = raw::TEEC_PARAM_TYPE_GET(param_types, idx);
575
576 match param_type {
577 raw::TEEC_NONE => {
578 param.param_type = TEE_ParamType::None;
579 }
580 raw::TEEC_VALUE_INPUT => {
581 param.param_type = TEE_ParamType::ValueInput;
582 if let Ok((a, b)) = op_params.get_value(idx) {
583 param.param.value.a = a;
584 param.param.value.b = b;
585 }
586 }
587 raw::TEEC_VALUE_OUTPUT => {
588 param.param_type = TEE_ParamType::ValueOutput;
590 }
591 raw::TEEC_VALUE_INOUT => {
592 param.param_type = TEE_ParamType::ValueInout;
593 if let Ok((a, b)) = op_params.get_value(idx) {
594 param.param.value.a = a;
595 param.param.value.b = b;
596 }
597 }
598 raw::TEEC_MEMREF_TEMP_INPUT => {
599 param.param_type = TEE_ParamType::MemrefInput;
600 if let Ok(data) = op_params.get_tmpref_data(idx) {
601 param.param.data = data;
602 }
603 }
604 raw::TEEC_MEMREF_TEMP_OUTPUT => {
605 param.param_type = TEE_ParamType::MemrefOutput;
606
607 let op_nn = safe_ptr::deref(operation)?;
609 let op_ref = unsafe { op_nn.as_ref() };
614 let tmp = unsafe { &op_ref.params[idx].tmpref };
618
619 param.param.value.a = tmp.size as u32;
622 debug!(
623 "TEEC_MEMREF_TEMP_OUTPUT: size={}, value.a={}",
624 tmp.size, param.param.value.a
625 );
626 }
627 raw::TEEC_MEMREF_TEMP_INOUT => {
628 param.param_type = TEE_ParamType::MemrefInout;
629 if let Ok(data) = op_params.get_tmpref_data(idx) {
630 param.param.data = data;
631 }
632 }
633 raw::TEEC_MEMREF_WHOLE => {
634 const INOUT: u32 = raw::TEEC_MEM_INPUT | raw::TEEC_MEM_OUTPUT;
636 let flags = op_params.get_memref_parent_flags(idx)? & INOUT;
637
638 if flags == INOUT {
639 param.param_type = TEE_ParamType::MemrefInout;
640 } else if flags & raw::TEEC_MEM_INPUT != 0 {
641 param.param_type = TEE_ParamType::MemrefInput;
642 } else if flags & raw::TEEC_MEM_OUTPUT != 0 {
643 param.param_type = TEE_ParamType::MemrefOutput;
644
645 let op_nn = safe_ptr::deref(operation)?;
647 let op_ref = unsafe { op_nn.as_ref() };
652 let mem = unsafe { &op_ref.params[idx].memref };
656 param.param.value.a = mem.size as u32;
657 debug!(
658 "TEEC_MEMREF_WHOLE OUTPUT: size={}, value.a={}",
659 mem.size, param.param.value.a
660 );
661 } else {
662 return Err(Error::new(ErrorKind::BadParameters));
663 }
664
665 if flags & raw::TEEC_MEM_INPUT != 0
666 && let Ok(data) = op_params.get_memref_data_whole(idx)
667 {
668 param.param.data = data;
669 }
670 }
671 raw::TEEC_MEMREF_PARTIAL_INPUT => {
672 param.param_type = TEE_ParamType::MemrefInput;
673 let req_flags = raw::TEEC_MEM_INPUT;
674 if let Ok(data) = op_params.get_memref_data_partial(idx, req_flags) {
675 param.param.data = data;
676 }
677 }
678 raw::TEEC_MEMREF_PARTIAL_OUTPUT => {
679 param.param_type = TEE_ParamType::MemrefOutput;
680
681 let op_nn = safe_ptr::deref(operation)?;
683 let op_ref = unsafe { op_nn.as_ref() };
688 let mem = unsafe { &op_ref.params[idx].memref };
692
693 param.param.value.a = mem.size as u32;
695 debug!(
696 "TEEC_MEMREF_PARTIAL_OUTPUT: size={}, value.a={}",
697 mem.size, param.param.value.a
698 );
699 }
700 raw::TEEC_MEMREF_PARTIAL_INOUT => {
701 param.param_type = TEE_ParamType::MemrefInout;
702 let req_flags = raw::TEEC_MEM_INPUT | raw::TEEC_MEM_OUTPUT;
703 if let Ok(data) = op_params.get_memref_data_partial(idx, req_flags) {
704 param.param.data = data;
705 }
706 }
707 _ => {
708 debug!("Unsupported parameter type: {param_type}");
709 return Err(Error::new(ErrorKind::BadParameters));
710 }
711 }
712 }
713
714 Ok(params)
715}
716
717fn update_operation_from_parameters(
719 operation: *mut raw::TEEC_Operation,
720 params: TEE_Parameters,
721) -> Result<()> {
722 let op_params = OperationParams::new(operation)?;
723 let param_types = op_params.param_types()?;
724 let param_slice = [¶ms.0, ¶ms.1, ¶ms.2, ¶ms.3];
725
726 for (idx, param) in param_slice
727 .iter()
728 .enumerate()
729 .take(raw::TEEC_CONFIG_PAYLOAD_REF_COUNT)
730 {
731 let param_type = raw::TEEC_PARAM_TYPE_GET(param_types, idx);
732
733 match param_type {
734 raw::TEEC_NONE
735 | raw::TEEC_VALUE_INPUT
736 | raw::TEEC_MEMREF_TEMP_INPUT
737 | raw::TEEC_MEMREF_PARTIAL_INPUT => {
738 }
740 raw::TEEC_VALUE_OUTPUT | raw::TEEC_VALUE_INOUT => {
741 let value = ¶m.param.value;
742 op_params.set_value(idx, value.a, value.b)?;
743 }
744 raw::TEEC_MEMREF_TEMP_OUTPUT | raw::TEEC_MEMREF_TEMP_INOUT => {
745 let data = ¶m.param.data;
746 op_params.set_tmpref_data(idx, data)?;
747 }
748 raw::TEEC_MEMREF_WHOLE => {
749 let data = ¶m.param.data;
750 op_params.set_memref_data_whole(idx, data)?;
751 }
752 raw::TEEC_MEMREF_PARTIAL_OUTPUT | raw::TEEC_MEMREF_PARTIAL_INOUT => {
753 let data = ¶m.param.data;
754 op_params.set_memref_data_partial(idx, data)?;
755 }
756 _ => {
757 debug!("Unsupported parameter type: {param_type}");
758 return Err(Error::new(ErrorKind::BadParameters));
759 }
760 }
761 }
762
763 Ok(())
764}
765
766fn send_request_and_recv_response(
768 ctx: *mut raw::TEEC_Context,
769 packet_type: PacketType,
770 request: &TEE_Request,
771) -> Result<TEE_Response> {
772 let client_arc = ContextManager::get_client(ctx)?;
773 let mut client = client_arc
774 .lock()
775 .map_err(|_| Error::new(ErrorKind::Generic).with_origin(ErrorOrigin::API))?;
776
777 let request_data = to_allocvec(request).map_err(|e| {
778 warn!("序列化请求失败:{e}");
779 Error::new(ErrorKind::BadFormat).with_origin(ErrorOrigin::API)
780 })?;
781
782 client
783 .send_data_with_header(packet_type, &request_data)
784 .map_err(|e| {
785 warn!("发送请求失败:{e}");
786 Error::new(ErrorKind::Communication).with_origin(ErrorOrigin::COMMS)
787 })?;
788
789 let mut len_buf = [0u8; 4];
790 client.recv_data(&mut len_buf).map_err(|e| {
791 warn!("接收响应长度失败:{e}");
792 Error::new(ErrorKind::Communication).with_origin(ErrorOrigin::COMMS)
793 })?;
794
795 let response_len = u32::from_ne_bytes(len_buf) as usize;
796 let mut response_data = vec![0u8; response_len];
797 client.recv_data(&mut response_data).map_err(|e| {
798 warn!("接收响应数据失败:{e}");
799 Error::new(ErrorKind::Communication).with_origin(ErrorOrigin::COMMS)
800 })?;
801
802 take_from_bytes::<TEE_Response>(&response_data)
803 .map(|(response, _)| response)
804 .map_err(|e| {
805 warn!("反序列化响应失败:{e}");
806 Error::new(ErrorKind::BadFormat).with_origin(ErrorOrigin::API)
807 })
808}
809
810#[unsafe(no_mangle)]
820pub extern "C" fn TEEC_InitializeContext(
821 _name: *const c_char,
822 ctx: *mut raw::TEEC_Context,
823) -> raw::TEEC_Result {
824 debug!("TEEC_InitializeContext");
825
826 let result = (|| -> Result<()> {
827 let mut ctx_nn = safe_ptr::deref_mut(ctx)?;
828 let ctx_ref = unsafe { ctx_nn.as_mut() };
831
832 let client = CcClient::init().map_err(|e| {
833 warn!("TEEC_InitializeContext:初始化机密通信上下文失败:{e}");
834 Error::new(ErrorKind::Communication)
835 })?;
836
837 let id = CONTEXT_ID_COUNTER.fetch_add(1, Ordering::SeqCst);
838
839 ctx_ref.imp.fd = id;
840 ctx_ref.imp.reg_mem = true;
841 ctx_ref.imp.memref_null = true;
842
843 ContextManager::add_context(ctx, client)
844 })();
845
846 match result {
847 Ok(_) => raw::TEEC_SUCCESS,
848 Err(e) => e.raw_code(),
849 }
850}
851
852#[unsafe(no_mangle)]
859pub extern "C" fn TEEC_FinalizeContext(ctx: *mut raw::TEEC_Context) {
860 debug!("TEEC_FinalizeContext");
861 ContextManager::remove_context(ctx);
862}
863
864#[unsafe(no_mangle)]
878pub extern "C" fn TEEC_OpenSession(
879 ctx: *mut raw::TEEC_Context,
880 session: *mut raw::TEEC_Session,
881 destination: *const raw::TEEC_UUID,
882 connection_method: u32,
883 _connection_data: *const c_void,
884 operation: *mut raw::TEEC_Operation,
885 ret_origin: *mut u32,
886) -> raw::TEEC_Result {
887 debug!("TEEC_OpenSession");
888
889 let result = (|| -> Result<u32> {
890 let _ = safe_ptr::deref_mut(ctx)?;
891 let _ = safe_ptr::deref_mut(session)?;
892 let uuid_nn = safe_ptr::deref(destination)?;
893 let uuid = unsafe { uuid_nn.as_ref() };
896
897 let uuid_str = uuid_to_string(uuid)?;
898 let params = if operation.is_null() {
899 TEE_Parameters::default()
900 } else {
901 build_parameters_from_operation(operation)?
902 };
903
904 let request = TEE_Request::OpenSession {
905 uuid: uuid_str,
906 connection_method,
907 params,
908 };
909
910 let mut session_nn = safe_ptr::deref_mut(session)?;
911 let session_ref = unsafe { session_nn.as_mut() };
914
915 let response = send_request_and_recv_response(ctx, PacketType::OpenSession, &request)?;
916
917 match response {
918 TEE_Response::OpenSession { session_id, result } => {
919 debug!("TEEC_OpenSession: 接收 session_id 和结果: {session_id}, {result}");
920
921 session_ref.imp.ctx = ctx;
922 session_ref.imp.session_id = session_id;
923
924 let _ = set_ret_origin(ret_origin, ErrorOrigin::TEE.into());
925 Ok(result)
926 }
927 _ => Err(Error::new(ErrorKind::BadParameters).with_origin(ErrorOrigin::API)),
928 }
929 })();
930
931 handle_error(result, ret_origin)
932}
933
934#[unsafe(no_mangle)]
938pub extern "C" fn TEEC_CloseSession(session: *mut raw::TEEC_Session) {
939 debug!("TEEC_CloseSession");
940
941 let result = (|| -> Result<()> {
942 let mut session_nn = safe_ptr::deref_mut(session)?;
943 let session_ref = unsafe { session_nn.as_mut() };
946 let session_id = session_ref.imp.session_id;
947 let ctx = session_ref.imp.ctx;
948
949 if ctx.is_null() {
950 return Err(Error::new(ErrorKind::BadParameters));
951 }
952
953 let request = TEE_Request::CloseSession { session_id };
954 let response = send_request_and_recv_response(ctx, PacketType::CloseSession, &request)?;
955
956 match response {
957 TEE_Response::CloseSession { result } => {
958 debug!("TEEC_CloseSession: 接收结果: {result}");
959 session_ref.imp.ctx = ptr::null_mut();
960 session_ref.imp.session_id = 0;
961 Ok(())
962 }
963 _ => Err(Error::new(ErrorKind::BadParameters)),
964 }
965 })();
966
967 if let Err(e) = result {
968 warn!("TEEC_CloseSession:{e}");
969 }
970}
971
972#[unsafe(no_mangle)]
982pub extern "C" fn TEEC_InvokeCommand(
983 session: *mut raw::TEEC_Session,
984 cmd_id: u32,
985 operation: *mut raw::TEEC_Operation,
986 error_origin: *mut u32,
987) -> raw::TEEC_Result {
988 debug!("TEEC_InvokeCommand");
989
990 let result = (|| -> Result<u32> {
991 let mut session_nn = safe_ptr::deref_mut(session)?;
992 let session_ref = unsafe { session_nn.as_mut() };
995 let session_id = session_ref.imp.session_id;
996 let ctx = session_ref.imp.ctx;
997
998 if ctx.is_null() {
999 return Err(Error::new(ErrorKind::BadParameters));
1000 }
1001
1002 let params = if operation.is_null() {
1003 TEE_Parameters::default()
1004 } else {
1005 let mut operation_nn = safe_ptr::deref_mut(operation)?;
1006 let operation_ref = unsafe { operation_nn.as_mut() };
1009 let _lock = TEEC_MUTEX
1010 .lock()
1011 .map_err(|_| Error::new(ErrorKind::Generic))?;
1012 operation_ref.imp.session = session;
1013 drop(_lock);
1014
1015 build_parameters_from_operation(operation)?
1016 };
1017
1018 let request = TEE_Request::InvokeCommand {
1019 session_id,
1020 cmd_id,
1021 params,
1022 };
1023
1024 let response = send_request_and_recv_response(ctx, PacketType::InvokeCommand, &request)?;
1025
1026 match response {
1027 TEE_Response::InvokeCommand { params, result } => {
1028 if result != raw::TEEC_SUCCESS {
1029 return Err(Error::new(ErrorKind::from(result)).with_origin(ErrorOrigin::API));
1030 }
1031
1032 if !operation.is_null() {
1033 update_operation_from_parameters(operation, params)?;
1034 }
1035 Ok(result)
1036 }
1037 _ => Err(Error::new(ErrorKind::BadParameters).with_origin(ErrorOrigin::API)),
1038 }
1039 })();
1040
1041 handle_error(result, error_origin)
1042}
1043
1044#[unsafe(no_mangle)]
1054pub extern "C" fn TEEC_RegisterSharedMemory(
1055 ctx: *mut raw::TEEC_Context,
1056 shm: *mut raw::TEEC_SharedMemory,
1057) -> raw::TEEC_Result {
1058 debug!("TEEC_RegisterSharedMemory");
1059
1060 let result = SharedMemoryManager::allocate(ctx, shm, true);
1061
1062 match result {
1063 Ok(_) => raw::TEEC_SUCCESS,
1064 Err(e) => e.raw_code(),
1065 }
1066}
1067
1068#[unsafe(no_mangle)]
1069pub extern "C" fn TEEC_RegisterSharedMemoryFileDescriptor(
1070 _ctx: *mut raw::TEEC_Context,
1071 _shm: *mut raw::TEEC_SharedMemory,
1072 _fd: i32,
1073) -> raw::TEEC_Result {
1074 ErrorKind::NotImplemented.into()
1076}
1077
1078#[unsafe(no_mangle)]
1087pub extern "C" fn TEEC_AllocateSharedMemory(
1088 ctx: *mut raw::TEEC_Context,
1089 shm: *mut raw::TEEC_SharedMemory,
1090) -> raw::TEEC_Result {
1091 debug!("TEEC_AllocateSharedMemory");
1092
1093 match SharedMemoryManager::allocate(ctx, shm, false) {
1094 Ok(_) => raw::TEEC_SUCCESS,
1095 Err(e) => e.raw_code(),
1096 }
1097}
1098
1099#[unsafe(no_mangle)]
1103pub extern "C" fn TEEC_ReleaseSharedMemory(shm: *mut raw::TEEC_SharedMemory) {
1104 debug!("TEEC_ReleaseSharedMemory");
1105 SharedMemoryManager::release(shm);
1106}
1107
1108#[unsafe(no_mangle)]
1112pub extern "C" fn TEEC_RequestCancellation(operation: *mut raw::TEEC_Operation) {
1113 debug!("TEEC_RequestCancellation");
1114
1115 let result = (|| -> Result<()> {
1116 let mut operation_nn = safe_ptr::deref_mut(operation)?;
1117 let operation_ref = unsafe { operation_nn.as_mut() };
1120 let _lock = TEEC_MUTEX
1121 .lock()
1122 .map_err(|_| Error::new(ErrorKind::Generic))?;
1123 let session = operation_ref.imp.session;
1124 drop(_lock);
1125
1126 if session.is_null() {
1127 return Ok(());
1128 }
1129
1130 let mut session_nn = safe_ptr::deref_mut(session)?;
1131 let session_ref = unsafe { session_nn.as_mut() };
1134 let session_id = session_ref.imp.session_id;
1135 let ctx = session_ref.imp.ctx;
1136
1137 if ctx.is_null() {
1138 return Ok(());
1139 }
1140
1141 let request = TEE_Request::RequestCancellation { session_id };
1142 let response =
1143 send_request_and_recv_response(ctx, PacketType::RequestCancellation, &request)?;
1144
1145 match response {
1146 TEE_Response::RequestCancellation { result: _ } => {
1147 debug!("TEEC_RequestCancellation: 接收结果");
1148 Ok(())
1149 }
1150 _ => Err(Error::new(ErrorKind::BadParameters)),
1151 }
1152 })();
1153
1154 if let Err(e) = result {
1155 warn!("TEEC_RequestCancellation:{e}");
1156 }
1157}
1158
1159#[cfg(test)]
1160mod teec_priv_tests {
1161 #[allow(unused_imports)]
1162 use super::*;
1163 use crate::common::protocol::{CHUNK_SIZE, PacketHeader, PacketType};
1164
1165 #[test]
1166 fn test_write_and_read_raw() {
1167 let mut v: u32 = 0;
1170 let p: *mut u32 = &mut v as *mut u32;
1171
1172 safe_ptr::write_raw(p, 0xDEADBEEF).expect("写入原始数据应该成功");
1173 let r = safe_ptr::read_raw(p as *const u32).expect("读取原始数据应该成功");
1174 assert_eq!(r, 0xDEADBEEF, "写入后读取的值应该与写入值相同");
1175 }
1176
1177 #[test]
1178 fn test_read_to_vec_and_write_from_slice() {
1179 let arr = [1u8, 2, 3, 4, 5];
1182 let vec =
1183 safe_ptr::read_to_vec(arr.as_ptr(), arr.len()).expect("从指针读取到 Vec 应该成功");
1184 assert_eq!(vec, arr.to_vec(), "从数组读取的数据应该与原始数组相同");
1185
1186 let mut buf = [0u8; 5];
1187 safe_ptr::write_from_slice(buf.as_mut_ptr(), &vec).expect("从切片写入指针应该成功");
1188 assert_eq!(buf.to_vec(), vec, "写入缓冲区后应该与原始数据相同");
1189 }
1190
1191 #[test]
1192 fn test_add_ptr() {
1193 let arr = [10u8, 20, 30, 40];
1196 let p = arr.as_ptr();
1197 let p2 = safe_ptr::add_ptr(p, 2);
1198
1199 assert_eq!(unsafe { *p2 }, 30, "偏移2个元素后应该指向第3个元素");
1200 }
1201
1202 #[test]
1203 fn test_add_ptr_mut_and_read() {
1204 let mut arr = [5u8, 6, 7, 8];
1207 let p = arr.as_mut_ptr();
1208 let p2 = safe_ptr::add_ptr_mut(p, 1);
1209 assert_eq!(unsafe { *p2 }, 6, "偏移1个元素后应该指向第2个元素");
1210 }
1211
1212 #[test]
1213 fn test_uuid_to_string_roundtrip() {
1214 let uuid = raw::TEEC_UUID {
1217 timeLow: 0x00112233,
1218 timeMid: 0x4455,
1219 timeHiAndVersion: 0x6677,
1220 clockSeqAndNode: [0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff],
1221 };
1222
1223 let s = uuid_to_string(&uuid).expect("UUID转换应该成功");
1224 assert_eq!(
1225 s, "00112233-4455-6677-8899-aabbccddeeff",
1226 "转换后的UUID字符串应该符合标准格式"
1227 );
1228 }
1229
1230 #[test]
1231 fn test_deref_and_deref_mut_null() {
1232 use std::ptr;
1235
1236 assert!(
1237 safe_ptr::deref(ptr::null::<u8>()).is_err(),
1238 "对空指针解引用应该失败"
1239 );
1240 assert!(
1241 safe_ptr::deref_mut(ptr::null_mut::<u8>()).is_err(),
1242 "对空可变指针解引用应该失败"
1243 );
1244 }
1245
1246 #[test]
1247 fn test_read_raw_and_read_to_vec_null_errors() {
1248 use std::ptr;
1251
1252 assert!(
1253 safe_ptr::read_raw(ptr::null::<u32>()).is_err(),
1254 "从空指针读取值应该失败"
1255 );
1256 assert!(
1257 safe_ptr::read_to_vec(ptr::null::<u8>(), 1).is_err(),
1258 "从空指针读取向量应该失败"
1259 );
1260 }
1261
1262 #[test]
1263 fn test_write_from_slice_null_dst_behaviour() {
1264 use std::ptr;
1267
1268 let src = [9u8, 8, 7];
1269 assert!(
1270 safe_ptr::write_from_slice(ptr::null_mut(), &src).is_err(),
1271 "向空指针写入非空切片应该失败"
1272 );
1273
1274 let empty: [u8; 0] = [];
1276 assert!(
1277 safe_ptr::write_from_slice(ptr::null_mut(), &empty).is_err(),
1278 "向空指针写入空切片也应该失败(根据实现逻辑)"
1279 );
1280 }
1281
1282 #[test]
1283 fn test_shared_memory_allocate_release_get_buffer() {
1284 let mut ctx = raw::TEEC_Context {
1289 imp: raw::TEEC_Context__Imp {
1290 fd: 4242, reg_mem: false,
1292 memref_null: false,
1293 },
1294 };
1295
1296 let mut shm = raw::TEEC_SharedMemory {
1298 buffer: std::ptr::null_mut(),
1299 size: 8, flags: raw::TEEC_MEM_INPUT,
1301 imp: raw::TEEC_SharedMemory__Imp {
1302 id: -1, alloced_size: 0,
1304 shadow_buffer: std::ptr::null_mut(),
1305 registered_fd: -1,
1306 flags: 0,
1307 },
1308 };
1309
1310 SharedMemoryManager::allocate(&mut ctx as *mut _, &mut shm as *mut _, false)
1312 .expect("共享内存分配应该成功");
1313
1314 assert_eq!(shm.imp.id, 4242, "共享内存ID应该与上下文ID匹配");
1315 assert!(!shm.buffer.is_null(), "分配的缓冲区指针不应该为空");
1316 assert_eq!(shm.imp.alloced_size, 8usize, "分配的缓冲区大小应该正确");
1317
1318 let buf =
1320 SharedMemoryManager::get_buffer(&shm as *const _).expect("应该能获取到共享内存缓冲区");
1321 assert_eq!(buf.len(), 8, "获取的缓冲区大小应该正确");
1322 assert_eq!(buf, vec![0u8; 8], "新分配的缓冲区应该初始化为0");
1323
1324 SharedMemoryManager::release(&mut shm as *mut _);
1326
1327 assert!(shm.buffer.is_null(), "释放后缓冲区指针应该置空");
1328 assert_eq!(shm.flags, 0, "释放后标志位应该清零");
1329 assert_eq!(shm.imp.id, -1, "释放后ID应该重置为-1");
1330 }
1331
1332 #[test]
1333 fn test_operation_params_value_and_tmpref_and_memref() {
1334 use std::ffi::c_void;
1338
1339 let mut op = raw::TEEC_Operation {
1341 started: 0,
1342 paramTypes: 0,
1343 params: [raw::TEEC_Parameter {
1344 value: raw::TEEC_Value { a: 1, b: 2 },
1345 }; raw::TEEC_CONFIG_PAYLOAD_REF_COUNT],
1346 imp: raw::TEEC_Operation__Imp {
1347 session: std::ptr::null_mut(),
1348 },
1349 };
1350
1351 let op_ptr: *mut raw::TEEC_Operation = &mut op;
1352 let op_params = OperationParams::new(op_ptr).unwrap();
1353
1354 let (a, b) = op_params.get_value(0).unwrap();
1356 assert_eq!((a, b), (1, 2), "应该能正确读取值参数");
1357
1358 op_params.set_value(0, 10, 20).unwrap();
1360 let (a2, b2) = op_params.get_value(0).unwrap();
1361 assert_eq!((a2, b2), (10, 20), "应该能正确设置值参数");
1362
1363 let mut tmp_buf = vec![0u8; 6];
1365 let mut op2 = op;
1366 op2.params[1] = raw::TEEC_Parameter {
1367 tmpref: raw::TEEC_TempMemoryReference {
1368 buffer: tmp_buf.as_mut_ptr() as *mut c_void,
1369 size: tmp_buf.len(),
1370 },
1371 };
1372 let op2_ptr: *mut raw::TEEC_Operation = &mut op2;
1373 let op2_params = OperationParams::new(op2_ptr).unwrap();
1374
1375 let to_write = [9u8, 8, 7];
1377 op2_params.set_tmpref_data(1, &to_write).unwrap();
1378 assert_eq!(tmp_buf[0..3], to_write[..], "应该正确写入临时内存");
1379
1380 let got = op2_params.get_tmpref_data(1).unwrap();
1382 assert_eq!(got, vec![9u8, 8, 7], "应该正确读取临时内存");
1383
1384 let mut parent_buf = vec![1u8, 2, 3, 4, 5, 6];
1386 let mut parent = raw::TEEC_SharedMemory {
1387 buffer: parent_buf.as_mut_ptr() as *mut c_void,
1388 size: parent_buf.len(),
1389 flags: raw::TEEC_MEM_INPUT | raw::TEEC_MEM_OUTPUT,
1390 imp: raw::TEEC_SharedMemory__Imp {
1391 id: 7777,
1392 alloced_size: parent_buf.len(),
1393 shadow_buffer: std::ptr::null_mut(),
1394 registered_fd: -1,
1395 flags: 0,
1396 },
1397 };
1398
1399 let memref = raw::TEEC_RegisteredMemoryReference {
1401 parent: &mut parent as *mut _,
1402 size: 3,
1403 offset: 2, };
1405
1406 let mut op3 = op2;
1407 op3.params[2] = raw::TEEC_Parameter { memref };
1408 let op3_ptr: *mut raw::TEEC_Operation = &mut op3;
1409 let op3_params = OperationParams::new(op3_ptr).unwrap();
1410
1411 let memdata = op3_params
1413 .get_memref_data_partial(2, raw::TEEC_MEM_INPUT)
1414 .unwrap();
1415 assert_eq!(
1416 memdata,
1417 parent_buf[2..5].to_vec(),
1418 "应该正确读取部分内存引用"
1419 );
1420
1421 let to_set = [7u8, 7u8];
1423 op3_params.set_memref_data_partial(2, &to_set).unwrap();
1424
1425 unsafe {
1427 let start = parent.buffer as *mut u8;
1428 assert_eq!(*start.add(2), 7u8, "偏移2处的值应该被修改");
1430 assert_eq!(*start.add(3), 7u8, "偏移3处的值应该被修改");
1432 assert_eq!(*start.add(4), 5u8, "偏移4处的值应该保持不变");
1434 }
1435 }
1436
1437 #[test]
1438 fn test_build_and_update_operation_parameters() {
1439 use crate::common::protocol::TEE_ParamType;
1442
1443 let mut ctx = raw::TEEC_Context {
1445 imp: raw::TEEC_Context__Imp {
1446 fd: 1001,
1447 reg_mem: false,
1448 memref_null: false,
1449 },
1450 };
1451
1452 let mut shm = raw::TEEC_SharedMemory {
1453 buffer: std::ptr::null_mut(),
1454 size: 10,
1455 flags: raw::TEEC_MEM_INPUT | raw::TEEC_MEM_OUTPUT,
1456 imp: raw::TEEC_SharedMemory__Imp {
1457 id: 1001,
1458 alloced_size: 10,
1459 shadow_buffer: std::ptr::null_mut(),
1460 registered_fd: -1,
1461 flags: 0,
1462 },
1463 };
1464
1465 SharedMemoryManager::allocate(&mut ctx as *mut _, &mut shm as *mut _, false)
1467 .expect("共享内存分配应该成功");
1468
1469 unsafe {
1471 let buf_ptr = shm.buffer as *mut u8;
1472 for i in 0..10 {
1473 *buf_ptr.add(i) = i as u8;
1474 }
1475 }
1476
1477 let mut op = raw::TEEC_Operation {
1479 started: 0,
1480 paramTypes: 0,
1481 params: [
1482 raw::TEEC_Parameter {
1484 value: raw::TEEC_Value {
1485 a: 0x1234,
1486 b: 0x5678,
1487 },
1488 },
1489 raw::TEEC_Parameter {
1491 tmpref: raw::TEEC_TempMemoryReference {
1492 buffer: [1u8, 2, 3, 4].as_ptr() as *mut std::ffi::c_void,
1493 size: 4,
1494 },
1495 },
1496 raw::TEEC_Parameter {
1498 memref: raw::TEEC_RegisteredMemoryReference {
1499 parent: &mut shm as *mut _,
1500 size: 3,
1501 offset: 2, },
1503 },
1504 raw::TEEC_Parameter {
1506 value: raw::TEEC_Value { a: 0, b: 0 },
1507 },
1508 ],
1509 imp: raw::TEEC_Operation__Imp {
1510 session: std::ptr::null_mut(),
1511 },
1512 };
1513
1514 let param_types = raw::TEEC_PARAM_TYPES(
1516 raw::TEEC_VALUE_INPUT,
1517 raw::TEEC_MEMREF_TEMP_INPUT,
1518 raw::TEEC_MEMREF_PARTIAL_INPUT,
1519 raw::TEEC_NONE,
1520 );
1521 op.paramTypes = param_types;
1522
1523 let op_ptr: *mut raw::TEEC_Operation = &mut op;
1524
1525 let params = build_parameters_from_operation(op_ptr).unwrap();
1527
1528 assert_eq!(
1530 params.0.param_type,
1531 TEE_ParamType::ValueInput,
1532 "参数0应该是值输入类型"
1533 );
1534 assert_eq!(params.0.param.value.a, 0x1234, "值参数a应该正确");
1535 assert_eq!(params.0.param.value.b, 0x5678, "值参数b应该正确");
1536
1537 assert_eq!(
1538 params.1.param_type,
1539 TEE_ParamType::MemrefInput,
1540 "参数1应该是临时内存输入类型"
1541 );
1542 assert_eq!(
1543 params.1.param.data,
1544 vec![1, 2, 3, 4],
1545 "临时内存数据应该正确"
1546 );
1547
1548 assert_eq!(
1549 params.2.param_type,
1550 TEE_ParamType::MemrefInput,
1551 "参数2应该是内存引用输入类型"
1552 );
1553 assert_eq!(
1554 params.2.param.data,
1555 vec![2, 3, 4],
1556 "部分内存引用数据应该正确"
1557 );
1558
1559 assert_eq!(
1560 params.3.param_type,
1561 TEE_ParamType::None,
1562 "参数3应该是无参数类型"
1563 );
1564
1565 SharedMemoryManager::release(&mut shm as *mut _);
1567 }
1568
1569 #[test]
1570 fn test_error_handling_functions() {
1571 let mut ret_origin = 0u32;
1574
1575 let success_result: Result<()> = Ok(());
1577 let success_code = handle_error(success_result, &mut ret_origin as *mut u32);
1578 assert_eq!(
1579 success_code,
1580 raw::TEEC_SUCCESS,
1581 "成功结果应该返回TEEC_SUCCESS"
1582 );
1583
1584 let error_result: Result<()> =
1586 Err(Error::new(ErrorKind::BadParameters).with_origin(ErrorOrigin::API));
1587 let error_code = handle_error(error_result, &mut ret_origin as *mut u32);
1588 assert_ne!(
1589 error_code,
1590 raw::TEEC_SUCCESS,
1591 "错误结果不应该返回TEEC_SUCCESS"
1592 );
1593 assert_eq!(ret_origin, ErrorOrigin::API.into(), "错误来源应该正确设置");
1594 }
1595
1596 #[test]
1597 fn test_edge_cases_and_boundary_conditions() {
1598 let mut op = raw::TEEC_Operation {
1603 started: 0,
1604 paramTypes: 0,
1605 params: [raw::TEEC_Parameter {
1606 value: raw::TEEC_Value { a: 0, b: 0 },
1607 }; raw::TEEC_CONFIG_PAYLOAD_REF_COUNT],
1608 imp: raw::TEEC_Operation__Imp {
1609 session: std::ptr::null_mut(),
1610 },
1611 };
1612
1613 let op_ptr: *mut raw::TEEC_Operation = &mut op;
1614 let op_params = OperationParams::new(op_ptr).unwrap();
1615
1616 assert!(
1618 op_params
1619 .get_value(raw::TEEC_CONFIG_PAYLOAD_REF_COUNT)
1620 .is_err(),
1621 "超出范围的索引应该返回错误"
1622 );
1623
1624 assert!(
1625 op_params
1626 .set_value(raw::TEEC_CONFIG_PAYLOAD_REF_COUNT, 1, 2)
1627 .is_err(),
1628 "超出范围的索引设置应该返回错误"
1629 );
1630
1631 op.params[0] = raw::TEEC_Parameter {
1633 tmpref: raw::TEEC_TempMemoryReference {
1634 buffer: std::ptr::null_mut(),
1635 size: 10, },
1637 };
1638
1639 assert!(
1640 op_params.get_tmpref_data(0).is_err(),
1641 "缓冲区为空但有大小应该返回错误"
1642 );
1643 }
1644
1645 #[test]
1646 fn test_context_manager_operations() {
1647 let mut ctx = raw::TEEC_Context {
1651 imp: raw::TEEC_Context__Imp {
1652 fd: 9999,
1653 reg_mem: false,
1654 memref_null: false,
1655 },
1656 };
1657
1658 ctx.imp.fd = -1; ContextManager::remove_context(&mut ctx);
1664 assert_eq!(ctx.imp.fd, -1);
1668 }
1669
1670 #[test]
1671 fn test_shared_memory_manager_allocate_errors() {
1672 let mut ctx = raw::TEEC_Context {
1676 imp: raw::TEEC_Context__Imp {
1677 fd: 100,
1678 reg_mem: false,
1679 memref_null: false,
1680 },
1681 };
1682 let mut shm = raw::TEEC_SharedMemory {
1683 buffer: std::ptr::null_mut(),
1684 size: 0, flags: raw::TEEC_MEM_INPUT,
1686 imp: raw::TEEC_SharedMemory__Imp {
1687 id: -1,
1688 alloced_size: 0,
1689 shadow_buffer: std::ptr::null_mut(),
1690 registered_fd: -1,
1691 flags: 0,
1692 },
1693 };
1694
1695 let result = SharedMemoryManager::allocate(&mut ctx, &mut shm, false);
1696 assert!(result.is_err());
1697
1698 shm.size = 100;
1700 shm.flags = 0; let result = SharedMemoryManager::allocate(&mut ctx, &mut shm, false);
1702 assert!(result.is_err());
1703
1704 shm.flags = 0xFFFFFFFF; let result = SharedMemoryManager::allocate(&mut ctx, &mut shm, false);
1707 assert!(result.is_err());
1708 }
1709
1710 #[test]
1711 fn test_shared_memory_manager_release_edge_cases() {
1712 let mut shm = raw::TEEC_SharedMemory {
1716 buffer: std::ptr::null_mut(),
1717 size: 100,
1718 flags: raw::TEEC_MEM_INPUT,
1719 imp: raw::TEEC_SharedMemory__Imp {
1720 id: -1, alloced_size: 100,
1722 shadow_buffer: std::ptr::null_mut(),
1723 registered_fd: -1,
1724 flags: 0,
1725 },
1726 };
1727
1728 SharedMemoryManager::release(&mut shm);
1729 assert_eq!(shm.imp.id, -1); }
1732
1733 #[test]
1734 fn test_get_buffer_null_pointer() {
1735 let result = SharedMemoryManager::get_buffer(std::ptr::null());
1737 assert!(result.is_none());
1738 }
1739
1740 #[test]
1741 fn test_uuid_to_string_invalid_format() {
1742 let uuid = raw::TEEC_UUID {
1748 timeLow: 0x12345678,
1749 timeMid: 0x1234,
1750 timeHiAndVersion: 0x5678,
1751 clockSeqAndNode: [0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0],
1752 };
1753
1754 let result = uuid_to_string(&uuid);
1755 assert!(result.is_ok());
1756 let uuid_str = result.unwrap();
1757 assert!(!uuid_str.is_empty());
1758 }
1759
1760 #[test]
1761 fn test_operation_params_index_boundary() {
1762 let mut op = raw::TEEC_Operation {
1764 started: 0,
1765 paramTypes: 0,
1766 params: [raw::TEEC_Parameter {
1767 value: raw::TEEC_Value { a: 0, b: 0 },
1768 }; raw::TEEC_CONFIG_PAYLOAD_REF_COUNT],
1769 imp: raw::TEEC_Operation__Imp {
1770 session: std::ptr::null_mut(),
1771 },
1772 };
1773
1774 let op_ptr: *mut raw::TEEC_Operation = &mut op;
1775 let op_params = OperationParams::new(op_ptr).unwrap();
1776
1777 for i in 0..raw::TEEC_CONFIG_PAYLOAD_REF_COUNT {
1779 let _ = op_params.get_value(i);
1781 }
1782
1783 assert!(
1785 op_params
1786 .get_value(raw::TEEC_CONFIG_PAYLOAD_REF_COUNT)
1787 .is_err()
1788 );
1789 assert!(
1790 op_params
1791 .set_value(raw::TEEC_CONFIG_PAYLOAD_REF_COUNT, 1, 2)
1792 .is_err()
1793 );
1794 }
1795
1796 #[test]
1797 fn test_set_ret_origin_function() {
1798 let mut origin = 0u32;
1800 let result = set_ret_origin(&mut origin as *mut u32, 123);
1801 assert!(result.is_ok());
1802 assert_eq!(origin, 123);
1803 }
1804
1805 #[test]
1806 fn test_handle_error_success_case() {
1807 let mut ret_origin = 0u32;
1809 let success_result: Result<()> = Ok(());
1810
1811 let code = handle_error(success_result, &mut ret_origin as *mut u32);
1812 assert_eq!(code, raw::TEEC_SUCCESS);
1813 assert_eq!(ret_origin, 0);
1815 }
1816
1817 #[test]
1818 fn test_build_parameters_with_all_param_types() {
1819 use crate::common::protocol::TEE_ParamType;
1821
1822 let mut op = raw::TEEC_Operation {
1824 started: 0,
1825 paramTypes: 0,
1826 params: [unsafe { std::mem::zeroed() }; 4],
1827 imp: raw::TEEC_Operation__Imp {
1828 session: std::ptr::null_mut(),
1829 },
1830 };
1831
1832 op.paramTypes = raw::TEEC_PARAM_TYPES(
1834 raw::TEEC_NONE,
1835 raw::TEEC_NONE,
1836 raw::TEEC_NONE,
1837 raw::TEEC_NONE,
1838 );
1839
1840 let params = build_parameters_from_operation(&mut op).unwrap();
1841 assert_eq!(params.0.param_type, TEE_ParamType::None);
1842 assert_eq!(params.1.param_type, TEE_ParamType::None);
1843 assert_eq!(params.2.param_type, TEE_ParamType::None);
1844 assert_eq!(params.3.param_type, TEE_ParamType::None);
1845 }
1846
1847 #[test]
1848 fn test_update_operation_with_output_params() {
1849 use crate::common::protocol::{TEE_Param, TEE_ParamType, TEE_Parameter, TEE_Value};
1851
1852 let mut tmp_buffer = [0u8; 10];
1854
1855 let mut op = raw::TEEC_Operation {
1856 started: 0,
1857 paramTypes: raw::TEEC_PARAM_TYPES(
1858 raw::TEEC_VALUE_OUTPUT,
1859 raw::TEEC_MEMREF_TEMP_OUTPUT,
1860 raw::TEEC_NONE,
1861 raw::TEEC_NONE,
1862 ),
1863 params: [
1864 raw::TEEC_Parameter {
1866 value: raw::TEEC_Value { a: 0, b: 0 },
1867 },
1868 raw::TEEC_Parameter {
1870 tmpref: raw::TEEC_TempMemoryReference {
1871 buffer: tmp_buffer.as_mut_ptr() as *mut std::ffi::c_void,
1872 size: tmp_buffer.len(),
1873 },
1874 },
1875 raw::TEEC_Parameter {
1877 value: raw::TEEC_Value { a: 0, b: 0 },
1878 },
1879 raw::TEEC_Parameter {
1881 value: raw::TEEC_Value { a: 0, b: 0 },
1882 },
1883 ],
1884 imp: raw::TEEC_Operation__Imp {
1885 session: std::ptr::null_mut(),
1886 },
1887 };
1888
1889 let params = TEE_Parameters(
1891 TEE_Parameter {
1892 param_type: TEE_ParamType::ValueOutput,
1893 param: TEE_Param {
1894 value: TEE_Value { a: 100, b: 200 },
1895 data: vec![],
1896 },
1897 },
1898 TEE_Parameter {
1899 param_type: TEE_ParamType::MemrefOutput,
1900 param: TEE_Param {
1901 value: TEE_Value::default(),
1902 data: vec![1, 2, 3],
1903 },
1904 },
1905 TEE_Parameter::default(),
1906 TEE_Parameter::default(),
1907 );
1908
1909 let result = update_operation_from_parameters(&mut op, params);
1910 assert!(result.is_ok());
1911
1912 unsafe {
1914 assert_eq!(op.params[0].value.a, 100);
1915 assert_eq!(op.params[0].value.b, 200);
1916 }
1917 }
1918
1919 #[test]
1921 fn test_packet_type_comprehensive() {
1922 assert_eq!(PacketType::from(0), PacketType::Unknown);
1924 assert_eq!(PacketType::from(1), PacketType::OpenSession);
1925 assert_eq!(PacketType::from(2), PacketType::CloseSession);
1926 assert_eq!(PacketType::from(3), PacketType::InvokeCommand);
1927 assert_eq!(PacketType::from(4), PacketType::RequestCancellation);
1928 assert_eq!(PacketType::from(999), PacketType::Unknown); assert_eq!(u64::from(PacketType::Unknown), 0);
1932 assert_eq!(u64::from(PacketType::OpenSession), 1);
1933 assert_eq!(u64::from(PacketType::CloseSession), 2);
1934 assert_eq!(u64::from(PacketType::InvokeCommand), 3);
1935 assert_eq!(u64::from(PacketType::RequestCancellation), 4);
1936
1937 let header = PacketHeader {
1939 data_type: 1,
1940 data_size: 1024,
1941 };
1942 let bytes = header.as_bytes();
1943 assert_eq!(bytes.len(), 16);
1944
1945 let restored = PacketHeader::from_bytes(bytes);
1947 assert_eq!(restored.data_type, 1);
1948 assert_eq!(restored.data_size, 1024);
1949
1950 assert!(CHUNK_SIZE > 0);
1952 }
1953
1954 #[test]
1956 fn test_tee_cancellation_error_paths() {
1957 let mut operation = raw::TEEC_Operation {
1959 started: 0,
1960 paramTypes: 0,
1961 params: [unsafe { std::mem::zeroed() }; 4],
1962 imp: raw::TEEC_Operation__Imp {
1963 session: std::ptr::null_mut(), },
1965 };
1966
1967 super::TEEC_RequestCancellation(&mut operation);
1969 }
1971
1972 #[test]
1974 fn test_shared_memory_edge_cases() {
1975 let mut shm = raw::TEEC_SharedMemory {
1977 buffer: std::ptr::null_mut(),
1978 size: 100,
1979 flags: raw::TEEC_MEM_INPUT,
1980 imp: raw::TEEC_SharedMemory__Imp {
1981 id: -1, alloced_size: 0,
1983 shadow_buffer: std::ptr::null_mut(),
1984 registered_fd: -1,
1985 flags: 0,
1986 },
1987 };
1988
1989 SharedMemoryManager::release(&mut shm);
1990 assert_eq!(shm.imp.id, -1);
1992 }
1993
1994 #[test]
1996 fn test_uuid_conversion_edge_cases() {
1997 let zero_uuid = raw::TEEC_UUID {
1999 timeLow: 0,
2000 timeMid: 0,
2001 timeHiAndVersion: 0,
2002 clockSeqAndNode: [0; 8],
2003 };
2004
2005 let result = uuid_to_string(&zero_uuid);
2006 assert!(result.is_ok());
2007 let uuid_str = result.unwrap();
2008 assert!(!uuid_str.is_empty());
2009
2010 let max_uuid = raw::TEEC_UUID {
2012 timeLow: u32::MAX,
2013 timeMid: u16::MAX,
2014 timeHiAndVersion: u16::MAX,
2015 clockSeqAndNode: [u8::MAX; 8],
2016 };
2017
2018 let result = uuid_to_string(&max_uuid);
2019 assert!(result.is_ok());
2020 }
2021
2022 #[test]
2024 fn test_operation_params_null_pointer_handling() {
2025 use std::ptr;
2026
2027 let null_op: *mut raw::TEEC_Operation = ptr::null_mut();
2029 let result = OperationParams::new(null_op);
2030 assert!(result.is_err());
2031 }
2032
2033 #[test]
2035 fn test_build_parameters_error_paths() {
2036 let mut op = raw::TEEC_Operation {
2040 started: 0,
2041 paramTypes: raw::TEEC_PARAM_TYPES(
2042 raw::TEEC_MEMREF_WHOLE, raw::TEEC_NONE,
2044 raw::TEEC_NONE,
2045 raw::TEEC_NONE,
2046 ),
2047 params: [
2048 raw::TEEC_Parameter {
2050 memref: raw::TEEC_RegisteredMemoryReference {
2051 parent: std::ptr::null_mut(), size: 100,
2053 offset: 0,
2054 },
2055 },
2056 raw::TEEC_Parameter {
2058 value: raw::TEEC_Value { a: 0, b: 0 },
2059 },
2060 raw::TEEC_Parameter {
2061 value: raw::TEEC_Value { a: 0, b: 0 },
2062 },
2063 raw::TEEC_Parameter {
2064 value: raw::TEEC_Value { a: 0, b: 0 },
2065 },
2066 ],
2067 imp: raw::TEEC_Operation__Imp {
2068 session: std::ptr::null_mut(),
2069 },
2070 };
2071
2072 let result = build_parameters_from_operation(&mut op);
2073 assert!(result.is_err());
2074 }
2075
2076 #[test]
2078 fn test_update_operation_error_paths() {
2079 use crate::common::protocol::{TEE_ParamType, TEE_Parameter};
2080
2081 let mut op = raw::TEEC_Operation {
2085 started: 0,
2086 paramTypes: raw::TEEC_PARAM_TYPES(
2087 raw::TEEC_VALUE_OUTPUT, raw::TEEC_NONE,
2089 raw::TEEC_NONE,
2090 raw::TEEC_NONE,
2091 ),
2092 params: [raw::TEEC_Parameter {
2093 value: raw::TEEC_Value { a: 0, b: 0 },
2094 }; 4],
2095 imp: raw::TEEC_Operation__Imp {
2096 session: std::ptr::null_mut(),
2097 },
2098 };
2099
2100 let params = TEE_Parameters(
2102 TEE_Parameter {
2103 param_type: TEE_ParamType::ValueOutput,
2104 param: crate::common::protocol::TEE_Param {
2105 value: crate::common::protocol::TEE_Value { a: 100, b: 200 },
2106 data: vec![],
2107 },
2108 },
2109 TEE_Parameter::default(),
2110 TEE_Parameter::default(),
2111 TEE_Parameter::default(),
2112 );
2113
2114 let result = update_operation_from_parameters(&mut op, params);
2116 assert!(result.is_ok());
2117
2118 unsafe {
2120 assert_eq!(op.params[0].value.a, 100);
2121 assert_eq!(op.params[0].value.b, 200);
2122 }
2123 }
2124
2125 #[test]
2127 fn test_safe_ptr_error_conditions() {
2128 use std::ptr;
2129
2130 let read_result = safe_ptr::read_raw::<u32>(ptr::null());
2132 assert!(read_result.is_err());
2133
2134 let write_result = safe_ptr::write_raw(ptr::null_mut(), 42u32);
2136 assert!(write_result.is_err());
2137
2138 let vec_result = safe_ptr::read_to_vec(ptr::null::<u8>(), 10);
2140 assert!(vec_result.is_err());
2141
2142 let data = [1u8, 2, 3];
2144 let slice_result = safe_ptr::write_from_slice(ptr::null_mut(), &data);
2145 assert!(slice_result.is_err());
2146 }
2147
2148 #[test]
2150 fn test_tee_c_result_to_error_conversion() {
2151 assert_eq!(raw::TEEC_SUCCESS, 0);
2156
2157 assert_ne!(raw::TEEC_ERROR_GENERIC, 0);
2159 assert_ne!(raw::TEEC_ERROR_BAD_PARAMETERS, 0);
2160
2161 let success_code: u32 = raw::TEEC_SUCCESS;
2164 let error_code: u32 = raw::TEEC_ERROR_GENERIC;
2165
2166 assert_eq!(success_code == 0, true);
2168 assert_eq!(error_code != 0, true);
2169 }
2170
2171 #[test]
2173 fn test_session_error_handling() {
2174 use std::ptr;
2175
2176 let null_session: *mut raw::TEEC_Session = ptr::null_mut();
2178
2179 assert!(null_session.is_null());
2181
2182 let _session = raw::TEEC_Session {
2185 imp: raw::TEEC_Session__Imp {
2186 ctx: ptr::null_mut(),
2187 session_id: 0,
2188 },
2189 };
2190 }
2191
2192 #[test]
2194 fn test_shared_memory_normal_allocation_release() {
2195 use std::ptr;
2196
2197 let mut ctx = raw::TEEC_Context {
2199 imp: raw::TEEC_Context__Imp {
2200 fd: -1, reg_mem: false, memref_null: false, },
2204 };
2205
2206 let mut shm = raw::TEEC_SharedMemory {
2208 buffer: ptr::null_mut(),
2209 size: 1024,
2210 flags: raw::TEEC_MEM_INPUT,
2211 imp: raw::TEEC_SharedMemory__Imp {
2212 id: -1,
2213 alloced_size: 0,
2214 shadow_buffer: ptr::null_mut(),
2215 registered_fd: -1,
2216 flags: 0,
2217 },
2218 };
2219
2220 let _result = SharedMemoryManager::allocate(&mut ctx, &mut shm, false);
2222 SharedMemoryManager::release(&mut shm);
2226 }
2228
2229 #[test]
2231 fn test_uuid_to_string_format() {
2232 let uuid = raw::TEEC_UUID {
2233 timeLow: 0x12345678,
2234 timeMid: 0xABCD,
2235 timeHiAndVersion: 0xEF01,
2236 clockSeqAndNode: [0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, 0x01],
2237 };
2238
2239 let result = uuid_to_string(&uuid);
2240 assert!(result.is_ok());
2241
2242 let uuid_str = result.unwrap();
2243 assert_eq!(uuid_str.len(), 36);
2245 assert!(uuid_str.contains('-'));
2247 }
2248
2249 #[test]
2251 fn test_build_parameters_memref_temp_input() {
2252 let mut buffer = [0x01u8, 0x02, 0x03, 0x04];
2253 let mut op = raw::TEEC_Operation {
2254 started: 0,
2255 paramTypes: raw::TEEC_PARAM_TYPES(
2256 raw::TEEC_MEMREF_TEMP_INPUT,
2257 raw::TEEC_NONE,
2258 raw::TEEC_NONE,
2259 raw::TEEC_NONE,
2260 ),
2261 params: [
2262 raw::TEEC_Parameter {
2263 tmpref: raw::TEEC_TempMemoryReference {
2264 buffer: buffer.as_mut_ptr() as *mut std::ffi::c_void,
2265 size: buffer.len(),
2266 },
2267 },
2268 raw::TEEC_Parameter {
2269 value: raw::TEEC_Value { a: 0, b: 0 },
2270 },
2271 raw::TEEC_Parameter {
2272 value: raw::TEEC_Value { a: 0, b: 0 },
2273 },
2274 raw::TEEC_Parameter {
2275 value: raw::TEEC_Value { a: 0, b: 0 },
2276 },
2277 ],
2278 imp: raw::TEEC_Operation__Imp {
2279 session: std::ptr::null_mut(),
2280 },
2281 };
2282
2283 let result = build_parameters_from_operation(&mut op);
2284 assert!(result.is_ok());
2285
2286 let params = result.unwrap();
2287 assert_eq!(params.0.param_type, TEE_ParamType::MemrefInput);
2288 assert_eq!(params.0.param.data.len(), 4);
2289 }
2290
2291 #[test]
2293 fn test_get_memref_parent_flags_null_parent() {
2294 let mut op = raw::TEEC_Operation {
2296 started: 0,
2297 paramTypes: raw::TEEC_PARAM_TYPES(
2298 raw::TEEC_MEMREF_WHOLE,
2299 raw::TEEC_NONE,
2300 raw::TEEC_NONE,
2301 raw::TEEC_NONE,
2302 ),
2303 params: [
2304 raw::TEEC_Parameter {
2305 memref: raw::TEEC_RegisteredMemoryReference {
2306 parent: std::ptr::null_mut(), size: 100,
2308 offset: 0,
2309 },
2310 },
2311 raw::TEEC_Parameter {
2312 value: raw::TEEC_Value { a: 0, b: 0 },
2313 },
2314 raw::TEEC_Parameter {
2315 value: raw::TEEC_Value { a: 0, b: 0 },
2316 },
2317 raw::TEEC_Parameter {
2318 value: raw::TEEC_Value { a: 0, b: 0 },
2319 },
2320 ],
2321 imp: raw::TEEC_Operation__Imp {
2322 session: std::ptr::null_mut(),
2323 },
2324 };
2325
2326 let op_params = OperationParams::new(&mut op).unwrap();
2327 let result = op_params.get_memref_parent_flags(0);
2328 assert!(result.is_err());
2329 }
2330
2331 #[test]
2333 fn test_set_tmpref_data_null_buffer() {
2334 let mut op = raw::TEEC_Operation {
2336 started: 0,
2337 paramTypes: raw::TEEC_PARAM_TYPES(
2338 raw::TEEC_MEMREF_TEMP_INPUT,
2339 raw::TEEC_NONE,
2340 raw::TEEC_NONE,
2341 raw::TEEC_NONE,
2342 ),
2343 params: [
2344 raw::TEEC_Parameter {
2345 tmpref: raw::TEEC_TempMemoryReference {
2346 buffer: std::ptr::null_mut(), size: 100,
2348 },
2349 },
2350 raw::TEEC_Parameter {
2351 value: raw::TEEC_Value { a: 0, b: 0 },
2352 },
2353 raw::TEEC_Parameter {
2354 value: raw::TEEC_Value { a: 0, b: 0 },
2355 },
2356 raw::TEEC_Parameter {
2357 value: raw::TEEC_Value { a: 0, b: 0 },
2358 },
2359 ],
2360 imp: raw::TEEC_Operation__Imp {
2361 session: std::ptr::null_mut(),
2362 },
2363 };
2364
2365 let op_params = OperationParams::new(&mut op).unwrap();
2366 let result = op_params.get_tmpref_data(0);
2367 assert!(result.is_err());
2368 }
2369
2370 #[test]
2372 fn test_build_parameters_value_inout() {
2373 let mut op = raw::TEEC_Operation {
2374 started: 0,
2375 paramTypes: raw::TEEC_PARAM_TYPES(
2376 raw::TEEC_VALUE_INOUT,
2377 raw::TEEC_NONE,
2378 raw::TEEC_NONE,
2379 raw::TEEC_NONE,
2380 ),
2381 params: [
2382 raw::TEEC_Parameter {
2383 value: raw::TEEC_Value { a: 123, b: 456 },
2384 },
2385 raw::TEEC_Parameter {
2386 value: raw::TEEC_Value { a: 0, b: 0 },
2387 },
2388 raw::TEEC_Parameter {
2389 value: raw::TEEC_Value { a: 0, b: 0 },
2390 },
2391 raw::TEEC_Parameter {
2392 value: raw::TEEC_Value { a: 0, b: 0 },
2393 },
2394 ],
2395 imp: raw::TEEC_Operation__Imp {
2396 session: std::ptr::null_mut(),
2397 },
2398 };
2399
2400 let result = build_parameters_from_operation(&mut op);
2401 assert!(result.is_ok());
2402
2403 let params = result.unwrap();
2404 assert_eq!(params.0.param_type, TEE_ParamType::ValueInout);
2405 assert_eq!(params.0.param.value.a, 123);
2406 assert_eq!(params.0.param.value.b, 456);
2407 }
2408}