teec_api_types/lib.rs
1// Licensed to the Apache Software Foundation (ASF) under one
2// or more contributor license agreements. See the NOTICE file
3// distributed with this work for additional information
4// regarding copyright ownership. The ASF licenses this file
5// to you under the Apache License, Version 2.0 (the
6// "License"); you may not use this file except in compliance
7// with the License. You may obtain a copy of the License at
8//
9// http://www.apache.org/licenses/LICENSE-2.0
10//
11// Unless required by applicable law or agreed to in writing,
12// software distributed under the License is distributed on an
13// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14// KIND, either express or implied. See the License for the
15// specific language governing permissions and limitations
16// under the License.
17//
18// This file was modified by KylinSoft Co., Ltd. on 2025.
19
20//! 此模块定义了 GlobalPlatform TEE 客户端 API 规范的常量、类型和结构体。
21
22#![allow(non_camel_case_types, non_snake_case)]
23
24use std::ffi::{c_int, c_void};
25
26/// 定义在打开会话或调用命令的操作负载中可用的内存引用数量。
27pub const TEEC_CONFIG_PAYLOAD_REF_COUNT: usize = 4;
28
29/// 定义单个数据内存块(包括 API 分配和 API 注册内存)的最大字节大小。
30/// 这里没有一个通用的合理值(限制取决于具体配置),因此在本实现中
31/// 不会强制任何限制。
32pub const TEEC_CONFIG_SHAREDMEM_MAX_SIZE: u64 = u64::MAX;
33
34/// 未使用该参数
35pub const TEEC_NONE: u32 = 0x00000000;
36
37/// 参数为 TEEC_Value,作为输入传递
38pub const TEEC_VALUE_INPUT: u32 = 0x00000001;
39
40/// 参数为 TEEC_Value,作为输出传递
41pub const TEEC_VALUE_OUTPUT: u32 = 0x00000002;
42
43/// 参数为 TEEC_Value,既作为输入又作为输出,同时具备 TEEC_VALUE_INPUT 和 TEEC_VALUE_OUTPUT 的语义
44pub const TEEC_VALUE_INOUT: u32 = 0x00000003;
45
46/// 参数为 TEEC_TempMemoryReference,描述一段在操作期间需要临时注册的内存区域,且为输入
47pub const TEEC_MEMREF_TEMP_INPUT: u32 = 0x00000005;
48
49/// 与 TEEC_MEMREF_TEMP_INPUT 类似,但内存引用为输出。实现可以在某些用例中更新 size 字段以反映所需的输出大小
50pub const TEEC_MEMREF_TEMP_OUTPUT: u32 = 0x00000006;
51
52/// 临时内存引用,同时作为输入和输出
53pub const TEEC_MEMREF_TEMP_INOUT: u32 = 0x00000007;
54
55/// 参数为已注册的内存引用,指向其父内存块的整个区域。该参数结构为 TEEC_RegisteredMemoryReference,
56/// 实现必须只读取 parent 字段,并且在操作完成后可选择更新 size 字段
57pub const TEEC_MEMREF_WHOLE: u32 = 0x0000000C;
58
59/// 已注册内存引用,指向父内存块的部分区域,且为输入
60pub const TEEC_MEMREF_PARTIAL_INPUT: u32 = 0x0000000D;
61
62/// 已注册内存引用,指向父内存块的部分区域,且为输出
63pub const TEEC_MEMREF_PARTIAL_OUTPUT: u32 = 0x0000000E;
64
65/// 已注册内存引用,指向父内存块的部分区域,同时作为输入和输出
66pub const TEEC_MEMREF_PARTIAL_INOUT: u32 = 0x0000000F;
67
68/// 内存可用于将数据从客户端应用传递给受信任应用(TA)
69pub const TEEC_MEM_INPUT: u32 = 0x00000001;
70
71/// 内存可用于将数据从受信任应用(TA)传回客户端应用
72pub const TEEC_MEM_OUTPUT: u32 = 0x00000002;
73
74/// 操作成功
75pub const TEEC_SUCCESS: u32 = 0x00000000;
76
77/// 一般性错误,原因不明确
78pub const TEEC_ERROR_GENERIC: u32 = 0xFFFF0000;
79
80/// 访问权限不足
81pub const TEEC_ERROR_ACCESS_DENIED: u32 = 0xFFFF0001;
82
83/// 操作被取消
84pub const TEEC_ERROR_CANCEL: u32 = 0xFFFF0002;
85
86/// 并发访问导致冲突
87pub const TEEC_ERROR_ACCESS_CONFLICT: u32 = 0xFFFF0003;
88
89/// 传入的数据超过请求操作允许的大小
90pub const TEEC_ERROR_EXCESS_DATA: u32 = 0xFFFF0004;
91
92/// 输入数据格式无效
93pub const TEEC_ERROR_BAD_FORMAT: u32 = 0xFFFF0005;
94
95/// 输入参数无效
96pub const TEEC_ERROR_BAD_PARAMETERS: u32 = 0xFFFF0006;
97
98/// 当前状态下不允许执行该操作
99pub const TEEC_ERROR_BAD_STATE: u32 = 0xFFFF0007;
100
101/// 未找到请求的数据项
102pub const TEEC_ERROR_ITEM_NOT_FOUND: u32 = 0xFFFF0008;
103
104/// 请求的操作应存在但尚未实现
105pub const TEEC_ERROR_NOT_IMPLEMENTED: u32 = 0xFFFF0009;
106
107/// 请求的操作在本实现中不受支持
108pub const TEEC_ERROR_NOT_SUPPORTED: u32 = 0xFFFF000A;
109
110/// 缺少预期的数据
111pub const TEEC_ERROR_NO_DATA: u32 = 0xFFFF000B;
112
113/// 系统资源耗尽
114pub const TEEC_ERROR_OUT_OF_MEMORY: u32 = 0xFFFF000C;
115
116/// 系统正忙于处理其他任务
117pub const TEEC_ERROR_BUSY: u32 = 0xFFFF000D;
118
119/// 与远端通信失败
120pub const TEEC_ERROR_COMMUNICATION: u32 = 0xFFFF000E;
121
122/// 检测到安全错误
123pub const TEEC_ERROR_SECURITY: u32 = 0xFFFF000F;
124
125/// 提供的缓冲区太短,无法容纳输出
126pub const TEEC_ERROR_SHORT_BUFFER: u32 = 0xFFFF0010;
127
128/// 由 Trusted User Interface 规范定义:外部事件导致用户界面操作被中止
129pub const TEEC_ERROR_EXTERNAL_CANCEL: u32 = 0xFFFF0011;
130
131/// TA 已终止
132pub const TEEC_ERROR_TARGET_DEAD: u32 = 0xFFFF3024;
133
134/// 错误来源于 TEE 客户端 API 的实现
135pub const TEEC_ORIGIN_API: u32 = 0x00000001;
136
137/// 错误来源于底层通信栈(负责连接 rich OS 与 TEE)
138pub const TEEC_ORIGIN_COMMS: u32 = 0x00000002;
139
140/// 错误来源于通用的 TEE 代码
141pub const TEEC_ORIGIN_TEE: u32 = 0x00000003;
142
143/// 错误来源于受信任应用(TA)代码
144pub const TEEC_ORIGIN_TRUSTED_APP: u32 = 0x00000004;
145
146/// 不提供登录数据
147pub const TEEC_LOGIN_PUBLIC: u32 = 0x00000000;
148
149/// 提供关于运行客户端进程的用户的登录数据
150pub const TEEC_LOGIN_USER: u32 = 0x00000001;
151
152/// 提供关于运行客户端进程的组的登录数据
153pub const TEEC_LOGIN_GROUP: u32 = 0x00000002;
154
155/// 提供关于运行的客户端应用自身的登录数据
156pub const TEEC_LOGIN_APPLICATION: u32 = 0x00000004;
157
158/// 提供关于用户和运行的客户端应用自身的登录数据
159pub const TEEC_LOGIN_USER_APPLICATION: u32 = 0x00000005;
160
161/// 提供关于组和运行的客户端应用自身的登录数据
162pub const TEEC_LOGIN_GROUP_APPLICATION: u32 = 0x00000006;
163
164/// 根据提供的类型对 `paramTypes` 进行编码
165///
166/// 该函数根据四个参数的类型值,将它们编码为一个组合的参数类型值,
167/// 用于描述 TEEC_Operation 中参数数组中每个参数的类型。
168///
169/// # 参数
170///
171/// * `p0` - 第一个参数的类型
172/// * `p1` - 第二个参数的类型
173/// * `p2` - 第三个参数的类型
174/// * `p3` - 第四个参数的类型
175///
176/// # 返回值
177///
178/// 返回编码后的参数类型组合值
179#[inline]
180pub fn TEEC_PARAM_TYPES(p0: u32, p1: u32, p2: u32, p3: u32) -> u32 {
181 let tmp = p1 << 4 | p2 << 8 | p3 << 12;
182 p0 | tmp
183}
184
185/// 从 `paramType` 中获取第 i 个参数的类型
186///
187/// 该函数从组合的参数类型值中提取指定位置参数的类型,
188/// 用于解析 TEEC_Operation 中参数数组中特定参数的类型。
189///
190/// # 参数
191///
192/// * `p` - `paramType` 的值
193/// * `i` - 要获取类型的第 i 个参数(从 0 开始)
194///
195/// # 返回值
196///
197/// 返回指定位置参数的类型值
198#[inline]
199pub fn TEEC_PARAM_TYPE_GET(p: u32, i: usize) -> u32 {
200 (p >> ((i as u32) * 4)) & 0xF
201}
202
203/// TEE 操作返回值类型(u32)。
204///
205/// 大多数 TEE Client API 函数返回此类型的值,指示操作的成功或失败。
206/// 成功时为 `TEEC_SUCCESS`(0),失败时为各类 `TEEC_ERROR_*` 错误码。
207#[allow(non_camel_case_types)]
208pub type TEEC_Result = u32;
209
210/// 表示客户端应用与 TEE 之间的连接上下文
211///
212/// `TEEC_Context` 结构体用于保存与可信执行环境(TEE)的连接信息,
213/// 它是所有 TEE 操作的基础,用于管理客户端应用与 TEE 之间的通信会话。
214#[derive(Debug)]
215#[repr(C)]
216pub struct TEEC_Context {
217 pub imp: TEEC_Context__Imp,
218}
219
220/// `TEEC_Context` 的实现定义字段。
221///
222/// - `fd`:上下文 ID(唯一标识符),由 `CONTEXT_ID_COUNTER` 原子递增分配
223/// - `reg_mem`:是否已启用共享内存注册功能
224/// - `memref_null`:MEMREF 类型参数是否允许 NULL 缓冲区
225#[derive(Debug)]
226#[repr(C)]
227pub struct TEEC_Context__Imp {
228 pub fd: c_int,
229 pub reg_mem: bool,
230 pub memref_null: bool,
231}
232
233/// 按照 RFC4122 定义的全局唯一资源标识符(UUID)
234///
235/// `TEEC_UUID` 结构体用于标识受信任应用(TA),
236/// 它是识别特定可信应用的重要标识符,确保客户端能够连接到正确的可信应用。
237#[derive(Debug)]
238#[repr(C)]
239pub struct TEEC_UUID {
240 pub timeLow: u32,
241 pub timeMid: u16,
242 pub timeHiAndVersion: u16,
243 pub clockSeqAndNode: [u8; 8usize],
244}
245
246/// 在客户端应用和受信任代码之间传输数据的共享内存
247///
248/// `TEEC_SharedMemory` 结构体定义了客户端应用与可信应用之间共享的内存区域,
249/// 用于高效的数据传输。共享内存块是在客户端应用程序地址空间中分配的一段内存,
250/// 可用于在客户端应用与受信任应用之间传输数据。
251///
252/// # 字段
253///
254/// * `buffer` - 要与 TEE 共享或已共享的内存缓冲区
255/// * `size` - 缓冲区的字节大小
256/// * `flags` - 表示缓冲区属性的位向量,可以包含 TEEC_MEM_INPUT 和/或 TEEC_MEM_OUTPUT 标志
257#[derive(Debug)]
258#[repr(C)]
259pub struct TEEC_SharedMemory {
260 pub buffer: *mut c_void,
261 pub size: usize,
262 pub flags: u32,
263 pub imp: TEEC_SharedMemory__Imp,
264}
265
266/// `TEEC_SharedMemory` 的实现定义字段。
267///
268/// - `id`:共享内存唯一 ID,由 `SHM_ID_COUNTER` 原子递增分配,
269/// `-1` 表示已释放
270/// - `alloced_size`:实际分配的内存大小(字节)
271/// - `shadow_buffer`:保留,当前未使用
272/// - `registered_fd`:保留,当前固定为 `-1`
273/// - `flags`:内部标志位(如 `SHM_FLAG_BUFFER_ALLOCED`)
274#[derive(Debug)]
275#[repr(C)]
276pub struct TEEC_SharedMemory__Imp {
277 pub id: c_int,
278 pub alloced_size: usize,
279 pub shadow_buffer: *mut c_void,
280 pub registered_fd: c_int,
281 pub flags: u32,
282}
283
284/// 临时内存引用,用于在客户端应用和受信任代码之间传输数据
285///
286/// `TEEC_TempMemoryReference` 结构体表示在单次操作的持续期间有效的临时内存引用,
287/// 用于在客户端应用和可信应用之间传输数据。该结构表示在操作期间临时注册的内存缓冲区。
288///
289/// # 字段
290///
291/// * `buffer` - 要传输数据给 TEE 的内存缓冲区
292/// * `size` - 缓冲区的字节大小
293#[derive(Copy, Clone, Debug)]
294#[repr(C)]
295pub struct TEEC_TempMemoryReference {
296 pub buffer: *mut c_void,
297 pub size: usize,
298}
299
300/// 使用预先注册或预分配的内存块在客户端应用和受信任代码之间传输数据
301///
302/// `TEEC_RegisteredMemoryReference` 结构体用于使用预先注册或预分配的内存块
303/// 在客户端应用和可信应用之间传输数据,提供了对已注册内存块的引用机制。
304///
305/// # 字段
306///
307/// * `parent` - 指向一个 `TEEC_SharedMemory` 结构,该内存引用可以表示整个内存或其中的一部分,不得为 NULL
308/// * `size` - 引用区域的字节大小
309/// * `offset` - 从内存块起始处到被引用区域的字节偏移量
310#[derive(Copy, Clone, Debug)]
311#[repr(C)]
312pub struct TEEC_RegisteredMemoryReference {
313 pub parent: *mut TEEC_SharedMemory,
314 pub size: usize,
315 pub offset: usize,
316}
317
318/// 小型原始数据容器
319///
320/// `TEEC_Value` 结构体可用于在客户端应用与受信任代码之间传递少量原始数据,
321/// 作为一种替代分配共享内存缓冲区的轻量级机制,减少了系统开销。
322///
323/// # 字段
324///
325/// * `a` - 第一个整数字段
326/// * `b` - 第二个整数字段
327#[derive(Copy, Clone, Debug)]
328#[repr(C)]
329pub struct TEEC_Value {
330 pub a: u32,
331 pub b: u32,
332}
333
334/// 传递数据时使用的内存容器
335///
336/// `TEEC_Parameter` 联合体用于在TEE客户端API操作中传递不同类型的数据,
337/// 可以包含共享内存引用、其部分区域或小型原始数据容器,提供了灵活的数据传递机制。
338///
339/// # 成员
340///
341/// * `tmpref` - 临时内存引用,仅在操作期间有效
342/// * `memref` - 整个内存或其部分区域的引用
343/// * `value` - 小型原始数据容器
344#[derive(Copy, Clone)]
345#[repr(C)]
346pub union TEEC_Parameter {
347 pub tmpref: TEEC_TempMemoryReference,
348 pub memref: TEEC_RegisteredMemoryReference,
349 pub value: TEEC_Value,
350}
351
352/// 表示客户端应用与受信任应用之间的会话连接
353///
354/// `TEEC_Session` 结构体用于管理客户端应用与特定可信应用之间的会话,
355/// 一旦会话建立,就可以通过该会话执行各种操作和命令调用。
356#[derive(Debug)]
357#[repr(C)]
358pub struct TEEC_Session {
359 pub imp: TEEC_Session__Imp,
360}
361
362/// `TEEC_Session` 的实现定义字段。
363///
364/// - `ctx`:指向关联 `TEEC_Context` 的指针,会话关闭后置为 NULL
365/// - `session_id`:TA 侧分配的唯一会话标识符
366#[derive(Debug)]
367#[repr(C)]
368pub struct TEEC_Session__Imp {
369 pub ctx: *mut TEEC_Context,
370 pub session_id: u32,
371}
372
373/// 保存用于 `TEEC_InvokeCommand()` 的信息和内存引用
374///
375/// `TEEC_Operation` 结构体用于保存调用命令所需的信息和内存引用,
376/// 包括参数类型、参数值以及与操作关联的会话信息,是执行可信应用命令的核心数据结构。
377///
378/// # 字段
379///
380/// * `started` - 如果客户端希望能够取消即将执行的操作,必须将该字段初始化为 0
381/// * `paramTypes` - 表示传递参数类型,使用 `TEEC_PARAM_TYPES` 来生成正确的标志,若为 0,则表示所有参数均为 `TEEC_NONE`
382/// * `params` - 类型为 `TEEC_Parameter` 的参数数组
383/// * `imp` - 实现定义字段,包含 `session` 字段,表示与该操作关联的最近一次会话的内部指针
384#[repr(C)]
385pub struct TEEC_Operation {
386 pub started: u32,
387 pub paramTypes: u32,
388 pub params: [TEEC_Parameter; TEEC_CONFIG_PAYLOAD_REF_COUNT],
389 pub imp: TEEC_Operation__Imp,
390}
391
392/// `TEEC_Operation` 的实现定义字段。
393///
394/// - `session`:指向与本次操作关联的 `TEEC_Session` 的指针,
395/// 用于 `TEEC_RequestCancellation` 中定位目标会话
396#[derive(Debug)]
397#[repr(C)]
398pub struct TEEC_Operation__Imp {
399 pub session: *mut TEEC_Session,
400}