时间API(GP Internal API)
GP标准中的时间函数提供了对三个时间源的访问:
1、系统时间
- 系统时间的起源是任意的,依赖于具体实现,不同的TA甚至有不同的系统时间。唯一的保证是,在给定的TA实例的生命周期内,系统时间不会重置或回滚,因此可以用于计算时间差和操作限期。
- 系统时间与TEE_Wait函数有关,该函数等待给定的超时或取消。
- TA对系统时间的信任级别由具体实现决定,可以通过属性gpd.tee.systemTime.protectionLevel来查询。典型的,REE的时钟的可信级别为100,专用的安全硬件时钟的可信级别为1000。
2、TA持续时间:一个实时的时间源。
- 该时间的起点是由每个TA分别设置的,并且重启后能够保持。
- 可以通过属性gpd.tee.TAPersistentTime.protectionLevel查询TA持续时间的信任级别。
3、REE时间:其可信度与REE本身一样,可能会被用户篡改
所有时间函数都使用毫秒分辨率,并将时间划分为结构TEE_Time的两个字段:一个字段表示秒,一个字段表示毫秒。
数据结构
typedef struct {
uint32_t seconds;
uint32_t millis;
} TEE_Time;
用于表示时间值,该数据结构可以表示截至2106年2月7日星期日06:28:15的UTC时间。
时间函数
1、void TEE_GetSystemTime([out] TEE_Time* time);
该函数获取当前的系统时间。
系统时间具有任意定义的起源,该起源可以在TA实例之间变化。对于给定的TA实例,系统时间必须是单调的。
2、TEE_ResultTEE_Wait(uint32_t timeout);
该函数等待指定的毫秒数,如果参数timeout等于TEE_TIMEOUT_INFINITE(0xFFFFFFFF),则永远等待。
当此函数返回成功时,GP实现必须保证在调用TEE_Wait之前和之后两次调用TEE_GetSystemTime之间的时间差大于或等于请求的超时。由于TEE任务的调度,可能存在其他相关的延迟。
此函数是可取消的,如果设置了当前任务的cancelled flag,并且TA处理了取消操作,则此函数的返回时间比请求的超时要早,返回码为TEE_ERROR_CANCEL。
3、TEE_Result TEE_GetTAPersistentTime([out] TEE_Time* time);
该函数获取TA的持续时间,即自调用TEE_SetTAPersistentTime函数设置的任意起点以来的秒数和毫秒数。该函数有以下返回值:
- TEE_SUCCESS:持久时间已正确设置,并已获取到参数time中
- TEE_ERROR_TIME_NOT_SET:初始状态,表示持久时间未设置。TA必须要通过TEE_SetTAPersistentTime函数来设置其持久时间
- TEE_ERROR_TIME_NEEDS_RESET:持久时间已设置,但可能已损坏且不能再被信任。在这种情况下,建议TA通过调用函数TEE_SetTAPersistentTime重新同步持久时间。在重置永久时间之前,将始终返回状态TEE_ERROR_TIME_NEEDS_RESET。
状态图如下,初始为TEE_ERROR_TIME_NOT_SET,调用函数TEE_SetTAPersistentTime后状态为TEE_SUCCESS或TEE_ERROR_TIME_NEEDS_RESET。一旦变为TEE_ERROR_TIME_NEEDS_RESET,将保持状态不变,直到调用TEE_SetTAPersistentTime同步TA持久时间。
状态TEE_ERROR_TIME_NEEDS_RESET的含义取决于硬件实现和底层实时时钟(RTC)提供的保护级别,保护级别可以通过gpd.tee.TAPersistentTime.protectionLevel属性获取。
value | meaning |
100 |
持久时间基于REE控制的RTC时钟,和TEE可信存储保存的时间源 GP实现必须确保在受信任存储允许的最大范围内检测到回退持久时间 |
1000 |
持久时间基于TEE控制的实时时钟和TEE可信存储,实时时钟必须超出REE的软件攻击范围 用户仍然可能引起实时时钟的复位,但是必须由GP实现检测到。 |
TA持久时间中的秒数可能超出了uint32_t整数类型的范围,在这种情况下,函数必须返回错误TEE_ERROR_OVERFLOW,但仍按上面指定的那样计算TA持久时间,除了在写入time-> seconds之前将秒数截断为32bits之外。
例如,如果TA将其持久时间设置为232-100秒,则在100秒后,TA持久时间为232,这用uint32_t无法表示。在这种情况下,函数TEE_GetTAPersistentTime必须返回TEE_ERROR_OVERFLOW,并设置参数time为0(它被232截断为32位)。
4、TEE_Result TEE_SetTAPersistentTime([in] TEE_Time* time);
该函数设置当前TA的持续时间。其只修改当前TA的持续时间,而不改其他TA的持续时间。
这将影响当前TA程序的所有实例,修改是原子性的,并且在设备重新启动后永久存在。
5、void TEE_GetREETime([out] TEE_Time* time);
该函数获取当前REE的系统时间。REE系统时间是从REE角度来看的系统时间,以自1970年1月1日午夜以来的秒数表示。
在正常操作中,返回值应对应实时时间,但不能将其视为可信的,因为它可能被用户或REE软件篡改。