rust-libteec 0.4.3

Rust implementation of TEE Client API for secure communication with Trusted Applications.
Documentation
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
// SPDX-License-Identifier: Apache-2.0
// Copyright (C) 2025-2026 KylinSoft Co., Ltd. <https://www.kylinos.cn/>
// See LICENSES for license details.

#![allow(non_snake_case)]

#[cfg(test)]
mod teec_api_tests {
    use cc_teec::{
        TEEC_AllocateSharedMemory, TEEC_CloseSession, TEEC_FinalizeContext, TEEC_InitializeContext,
        TEEC_InvokeCommand, TEEC_OpenSession, TEEC_RegisterSharedMemory, TEEC_ReleaseSharedMemory,
        TEEC_RequestCancellation, raw,
    };
    use std::ptr;

    /// 测试 TEEC_InitializeContext 的参数验证,证函数对空指针的健壮性处理
    /// 预期:传入空指针应返回 TEEC_ERROR_BAD_PARAMETERS
    #[test]
    fn test_TEEC_InitializeContext() {
        // 测试1: ctx 为空指针
        let res = TEEC_InitializeContext(ptr::null(), ptr::null_mut());
        assert_eq!(res, raw::TEEC_ERROR_BAD_PARAMETERS);

        // 测试2: 有效的 ctx 指针但未连接实际TEE环境,这里主要测试参数边界
        let mut ctx = raw::TEEC_Context {
            imp: raw::TEEC_Context__Imp {
                fd: -1,
                reg_mem: false,
                memref_null: false,
            },
        };

        let res = TEEC_InitializeContext(ptr::null(), &mut ctx);
        let _ = res; // 忽略返回值,只确保不崩溃
    }

    /// 测试 TEEC_OpenSession 的参数验证,验证函数对各种无效参数的健壮性
    /// 预期:传入各种空指针应返回 TEEC_ERROR_BAD_PARAMETERS
    #[test]
    fn test_TEEC_OpenSession() {
        // 测试1: 所有参数都为空指针
        let res = TEEC_OpenSession(
            ptr::null_mut(),
            ptr::null_mut(),
            ptr::null(),
            0,
            ptr::null(),
            ptr::null_mut(),
            ptr::null_mut(),
        );
        assert_eq!(res, raw::TEEC_ERROR_BAD_PARAMETERS);

        // 测试2: 部分有效参数但 destination 为空
        let mut ctx = raw::TEEC_Context {
            imp: raw::TEEC_Context__Imp {
                fd: -1,
                reg_mem: false,
                memref_null: false,
            },
        };
        let mut session = raw::TEEC_Session {
            imp: raw::TEEC_Session__Imp {
                ctx: ptr::null_mut(),
                session_id: 0,
            },
        };
        let res = TEEC_OpenSession(
            &mut ctx,
            &mut session,
            ptr::null(),
            0,
            ptr::null(),
            ptr::null_mut(),
            ptr::null_mut(),
        );
        assert_eq!(res, raw::TEEC_ERROR_BAD_PARAMETERS);
    }

    /// 测试 TEEC_InvokeCommand 的参数验证,验证无效会话和操作参数的健壮性
    /// 预期:传入空指针应返回 TEEC_ERROR_BAD_PARAMETERS
    #[test]
    fn test_TEEC_InvokeCommand() {
        // 测试1: 所有参数都为空指针
        let res = TEEC_InvokeCommand(ptr::null_mut(), 0, ptr::null_mut(), ptr::null_mut());
        assert_eq!(res, raw::TEEC_ERROR_BAD_PARAMETERS);

        // 测试2: 有效会话结构但未初始化的上下文
        let mut session = raw::TEEC_Session {
            imp: raw::TEEC_Session__Imp {
                ctx: ptr::null_mut(),
                session_id: 0,
            },
        };
        let mut operation = raw::TEEC_Operation {
            started: 0,
            paramTypes: 0,
            params: [unsafe { std::mem::zeroed() }; 4],
            imp: raw::TEEC_Operation__Imp {
                session: ptr::null_mut(),
            },
        };
        let mut error_origin = 0u32;
        let res = TEEC_InvokeCommand(&mut session, 1, &mut operation, &mut error_origin);

        assert_eq!(res, raw::TEEC_ERROR_BAD_PARAMETERS);
    }

    /// 测试 TEEC_RegisterSharedMemory 的参数验证,验证共享内存注册时的参数检查
    /// 预期:传入空指针应返回 TEEC_ERROR_BAD_PARAMETERS
    #[test]
    fn test_TEEC_RegisterSharedMemory() {
        // 测试1: 所有参数都为空指针
        let res = TEEC_RegisterSharedMemory(ptr::null_mut(), ptr::null_mut());
        assert_eq!(res, raw::TEEC_ERROR_BAD_PARAMETERS);

        // 测试2: 有效的上下文和共享内存结构,但缓冲区为空
        let mut ctx = raw::TEEC_Context {
            imp: raw::TEEC_Context__Imp {
                fd: -1,
                reg_mem: false,
                memref_null: false,
            },
        };
        let mut shm = raw::TEEC_SharedMemory {
            buffer: ptr::null_mut(),
            size: 1024,
            flags: raw::TEEC_MEM_INPUT,
            imp: raw::TEEC_SharedMemory__Imp {
                id: -1,
                alloced_size: 0,
                shadow_buffer: ptr::null_mut(),
                registered_fd: -1,
                flags: 0,
            },
        };
        let res = TEEC_RegisterSharedMemory(&mut ctx, &mut shm);

        assert_eq!(res, raw::TEEC_ERROR_BAD_PARAMETERS);
    }

    /// 测试 TEEC_AllocateSharedMemory 的参数验证,验证共享内存分配时的参数检查
    /// 预期:传入空指针应返回 TEEC_ERROR_BAD_PARAMETERS
    #[test]
    fn test_TEEC_AllocateSharedMemory() {
        // 测试1: 所有参数都为空指针
        let res = TEEC_AllocateSharedMemory(ptr::null_mut(), ptr::null_mut());
        assert_eq!(res, raw::TEEC_ERROR_BAD_PARAMETERS);

        // 测试2: 分配零字节内存(边界测试)
        let mut ctx = raw::TEEC_Context {
            imp: raw::TEEC_Context__Imp {
                fd: -1,
                reg_mem: false,
                memref_null: false,
            },
        };
        let mut shm = raw::TEEC_SharedMemory {
            buffer: ptr::null_mut(),
            size: 0,
            flags: raw::TEEC_MEM_INPUT,
            imp: raw::TEEC_SharedMemory__Imp {
                id: -1,
                alloced_size: 0,
                shadow_buffer: ptr::null_mut(),
                registered_fd: -1,
                flags: 0,
            },
        };
        let res = TEEC_AllocateSharedMemory(&mut ctx, &mut shm);
        // 分配大小不能为0
        assert_eq!(res, raw::TEEC_ERROR_BAD_PARAMETERS);
    }

    /// 测试 TEEC_CloseSession 的空指针安全性,验证关闭会话函数对空指针的健壮性
    /// 预期:传入空指针不应导致崩溃
    #[test]
    fn test_TEEC_CloseSession() {
        // 测试1: 传入空指针(应安全处理)
        TEEC_CloseSession(ptr::null_mut());

        // 测试2: 传入未初始化的会话结构
        let mut session = raw::TEEC_Session {
            imp: raw::TEEC_Session__Imp {
                ctx: ptr::null_mut(),
                session_id: 0,
            },
        };
        TEEC_CloseSession(&mut session);
        // 不应崩溃,会话 ID 应保持为 0
        assert_eq!(session.imp.session_id, 0);
    }

    /// 测试 TEEC_FinalizeContext 的空指针安全性,验证销毁上下文函数对空指针的健壮性
    /// 预期:传入空指针不应导致崩溃
    #[test]
    fn test_TEEC_FinalizeContext() {
        // 测试1: 传入空指针(应安全处理)
        TEEC_FinalizeContext(ptr::null_mut());

        // 测试2: 传入已初始化的上下文(虽然实际未连接)
        let mut ctx = raw::TEEC_Context {
            imp: raw::TEEC_Context__Imp {
                fd: 123, // 模拟已分配ID
                reg_mem: true,
                memref_null: true,
            },
        };

        TEEC_FinalizeContext(&mut ctx);
        // 这里只确保函数调用不会崩溃
    }

    /// 测试 TEEC_RequestCancellation 的空指针安全性,验证取消请求函数对空指针的健壮性
    /// 预期:传入空指针不应导致崩溃
    #[test]
    fn test_TEEC_RequestCancellation() {
        // 测试1: 传入空指针(应安全处理)
        TEEC_RequestCancellation(ptr::null_mut());

        // 测试2: 传入未关联会话的操作
        let mut operation = raw::TEEC_Operation {
            started: 1, // 模拟已开始的操作
            paramTypes: 0,
            params: [unsafe { std::mem::zeroed() }; 4],
            imp: raw::TEEC_Operation__Imp {
                session: ptr::null_mut(), // 无关联会话
            },
        };
        TEEC_RequestCancellation(&mut operation);
        // 不应崩溃
    }

    /// 测试 TEEC_ReleaseSharedMemory 的空指针安全性,验证释放共享内存函数对空指针的健壮性
    /// 预期:传入空指针不应导致崩溃
    #[test]
    fn test_TEEC_ReleaseSharedMemory() {
        // 测试1: 传入空指针(应安全处理)
        TEEC_ReleaseSharedMemory(ptr::null_mut());

        // 测试2: 传入已分配的共享内存(模拟清理)
        let buffer = Box::new([0u8; 1024]);
        let raw_ptr = Box::into_raw(buffer) as *mut std::ffi::c_void;

        let mut shm = raw::TEEC_SharedMemory {
            buffer: raw_ptr,
            size: 1024,
            flags: raw::TEEC_MEM_INPUT,
            imp: raw::TEEC_SharedMemory__Imp {
                id: 456, // 模拟已分配 ID
                alloced_size: 1024,
                shadow_buffer: ptr::null_mut(),
                registered_fd: -1,
                flags: 1, // 模拟已分配标志
            },
        };

        TEEC_ReleaseSharedMemory(&mut shm);
        // 不应崩溃

        // 清理:重新获取Box并释放内存(安全操作)
        let _ = unsafe { Box::from_raw(raw_ptr as *mut [u8; 1024]) };
    }

    /// 测试参数编码宏的正确性,验证 TEEC_PARAM_TYPES 和 TEEC_PARAM_TYPE_GET 的功能
    #[test]
    fn test_param_macros() {
        // 测试参数类型编码
        let param_types = raw::TEEC_PARAM_TYPES(
            raw::TEEC_VALUE_INPUT,
            raw::TEEC_VALUE_OUTPUT,
            raw::TEEC_MEMREF_TEMP_INPUT,
            raw::TEEC_MEMREF_WHOLE,
        );

        // 验证各参数位的解码
        assert_eq!(
            raw::TEEC_PARAM_TYPE_GET(param_types, 0),
            raw::TEEC_VALUE_INPUT
        );
        assert_eq!(
            raw::TEEC_PARAM_TYPE_GET(param_types, 1),
            raw::TEEC_VALUE_OUTPUT
        );
        assert_eq!(
            raw::TEEC_PARAM_TYPE_GET(param_types, 2),
            raw::TEEC_MEMREF_TEMP_INPUT
        );
        assert_eq!(
            raw::TEEC_PARAM_TYPE_GET(param_types, 3),
            raw::TEEC_MEMREF_WHOLE
        );

        // 测试边界:索引超出范围
        let param_type = raw::TEEC_PARAM_TYPE_GET(param_types, 4);
        // 超出范围的索引应该返回0(因为移位后超出边界)
        assert_eq!(param_type, 0);
    }

    /// 测试共享内存管理器的边界条件,验证共享内存分配和释放的边界情况
    #[test]
    fn test_shared_memory_boundary_conditions() {
        // 测试:无效的标志位
        let mut ctx = raw::TEEC_Context {
            imp: raw::TEEC_Context__Imp {
                fd: 1,
                reg_mem: true,
                memref_null: false,
            },
        };
        let mut shm = raw::TEEC_SharedMemory {
            buffer: ptr::null_mut(),
            size: 1024,
            flags: 0xFFFFFFFF, // 无效标志位
            imp: raw::TEEC_SharedMemory__Imp {
                id: -1,
                alloced_size: 0,
                shadow_buffer: ptr::null_mut(),
                registered_fd: -1,
                flags: 0,
            },
        };
        let res = TEEC_AllocateSharedMemory(&mut ctx, &mut shm);
        // 预期返回参数错误(标志位无效)
        assert_eq!(res, raw::TEEC_ERROR_BAD_PARAMETERS);
    }

    /// 测试操作参数构建函数的错误处理,验证 OperationParams 对各种异常情况的处理
    #[test]
    fn test_operation_params_error_handling() {
        // 测试:无效的参数类型
        let mut operation = raw::TEEC_Operation {
            started: 0,
            paramTypes: 0xFFFFFFFF, // 包含无效参数类型
            params: [unsafe { std::mem::zeroed() }; 4],
            imp: raw::TEEC_Operation__Imp {
                session: ptr::null_mut(),
            },
        };

        let mut session = raw::TEEC_Session {
            imp: raw::TEEC_Session__Imp {
                ctx: ptr::null_mut(),
                session_id: 0,
            },
        };
        let mut error_origin = 0u32;
        let res = TEEC_InvokeCommand(&mut session, 1, &mut operation, &mut error_origin);
        // 预期返回参数错误
        assert_eq!(res, raw::TEEC_ERROR_BAD_PARAMETERS);
    }

    /// 测试 UUID 转换功能,验证 UUID 结构到字符串的转换
    #[test]
    fn test_uuid_conversion() {
        // 创建一个已知的 UUID
        let uuid = raw::TEEC_UUID {
            timeLow: 0x00112233,
            timeMid: 0x4455,
            timeHiAndVersion: 0x6677,
            clockSeqAndNode: [0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF],
        };

        let mut ctx = raw::TEEC_Context {
            imp: raw::TEEC_Context__Imp {
                fd: -1,
                reg_mem: false,
                memref_null: false,
            },
        };
        let mut session = raw::TEEC_Session {
            imp: raw::TEEC_Session__Imp {
                ctx: ptr::null_mut(),
                session_id: 0,
            },
        };

        // 使用有效的 UUID 结构调用 OpenSession
        let res = TEEC_OpenSession(
            &mut ctx,
            &mut session,
            &uuid,
            raw::TEEC_LOGIN_PUBLIC,
            ptr::null(),
            ptr::null_mut(),
            ptr::null_mut(),
        );

        // 期望返回错误,但不应是参数错误,表明 UUID 转换成功
        assert!(res != raw::TEEC_ERROR_BAD_PARAMETERS);
    }

    /// 测试会话和操作的生命周期管理,验证会话和操作结构的正确清理
    #[test]
    fn test_session_and_operation_lifecycle() {
        // 创建并初始化一个操作结构
        let mut operation = raw::TEEC_Operation {
            started: 0,
            paramTypes: raw::TEEC_PARAM_TYPES(
                raw::TEEC_VALUE_INPUT,
                raw::TEEC_VALUE_OUTPUT,
                raw::TEEC_NONE,
                raw::TEEC_NONE,
            ),
            params: [unsafe { std::mem::zeroed() }; 4],
            imp: raw::TEEC_Operation__Imp {
                session: ptr::null_mut(),
            },
        };

        // 设置值参数
        operation.params[0].value.a = 123;
        operation.params[0].value.b = 456;

        // 验证参数类型设置正确
        assert_eq!(
            raw::TEEC_PARAM_TYPE_GET(operation.paramTypes, 0),
            raw::TEEC_VALUE_INPUT
        );
        assert_eq!(
            raw::TEEC_PARAM_TYPE_GET(operation.paramTypes, 1),
            raw::TEEC_VALUE_OUTPUT
        );

        // 验证值参数设置正确
        unsafe {
            assert_eq!(operation.params[0].value.a, 123);
            assert_eq!(operation.params[0].value.b, 456);
        }

        // 创建一个会话结构
        let mut session = raw::TEEC_Session {
            imp: raw::TEEC_Session__Imp {
                ctx: ptr::null_mut(),
                session_id: 999, // 模拟会话 ID
            },
        };

        // 将操作与会话关联
        operation.imp.session = &mut session;

        // 验证关联成功
        assert_eq!(operation.imp.session as *const _, &mut session as *const _);

        // 清理:关闭会话
        TEEC_CloseSession(&mut session);
    }
}