欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

TEE: OP-TEE

程序员文章站 2022-07-13 16:11:23
...

OP-TEE是Linaro开发的Security OS。n年前,最终选定OP-TEE作为我们的移植目标,并最终实现。基于当年的OP-TEE版本,除增加了支持多核的功能,还基于Power state coordination interface(PSCI)协议实现了CPU的电源管理。此文档其实是自己当年的学习记录。

ARM后期期望走类似于Intel的路,抛弃Linux中的一些底层设备操作,将相关功能集成到自己的firmware中,从而诞生了secure-firmware。ARM将OP-TEE正式加入到此firmware中,作为runtime service。


OP-TEE


OP-TEE的结构流程图如下:

TEE: OP-TEE


图中的USER表示none-security-world的user space;KERNEL表示none-security-world的linux kernel space。而图的最下面部分则是security-world部分,即OP-TEE。


TEE: OP-TEE


OP-TEE支持Process以及user space。上图是Process的memory layout,包括kernel space部分和user space部分。


TEE: OP-TEE


上图则是OP-TEE的核心调度代码。也不知道OP-TEE现在的代码长啥样了。。。


User TA


在编译arm elf时,所用的链接脚本是: ./ta/arch/arm32/user_ta_elf_arm.lds

SECTIONS
{
    .ta_head : {*(.ta_head)}
.ta_func_head : {*(.ta_func_head)}
。。。。。
}

而在 ./ta/arch/arm32/user_ta_header.c 定义了TA的head:

const struct user_ta_func_head user_ta_func_head[]
    __attribute__ ((section(".ta_func_head"))) =
{
    {
    0, (uint32_t) ta_entry_open_session}, {
    0, (uint32_t) ta_entry_close_session}, {
    0, (uint32_t) ta_entry_invoke_command}, {
    TA_FLAGS, 0 /* Spare */ },
    {
TA_DATA_SIZE, TA_STACK_SIZE},};
  • ta_entry_open_session:
    —> ta_header_add_session –> TA_CreateEntryPoint
    —> TA_OpenSessionEntryPoint
  • ta_entry_invoke_command:
    —> TA_InvokeCommandEntryPoint
  • ta_entry_close_session:

Static TA


Static TA是指静态编译进TEE的TA,会将TA header保存于section(“ta_head_section”)。
TEE的链接脚本: ./core/arch/arm32/plat-orly2/tz-template.lds

SECTIONS
{
    .teecore_exec :
    {
        *(.vector_table)
        *(.text); *(.text.*)
        *(.rodata); *(.rodata.*)
        *(.got); *(.got.*)
        *(.data); *(.data.*)
        __start_ta_head_section = . ;
        *(ta_head_section)
        __stop_ta_head_section = . ;
     。。。。。
}

样例可见:./core/arch/arm32/sta/sta_helloworld.c

__attribute__ ((section("ta_head_section")))
    const ta_static_head_t sta_helloworld_head = {
    .uuid = STA_HELLOWORLD_UUID,
    .name = (char *)TA_NAME,
    .create_entry_point = create_ta,
    .destroy_entry_point = destroy_ta,
    .open_session_entry_point = open_session,
    .close_session_entry_point = close_session,
    .invoke_command_entry_point = invoke_command,
};

在load TA时,会优先从__start_ta_head_section~__stop_ta_head_section 读取
ta_static_head_t,查找是否有所需的UUID。如有,则读取信息;如没有,利用RPC向REE发起读取 TA请求,然后由TEE利用tee_ta_load解析TA并load。


Client API–> TEE     


在tee_dispatch中定义了全局链表:

/* Sessions opened from normal world */
static struct tee_ta_session_head tee_open_sessions =
TAILQ_HEAD_INITIALIZER(tee_open_sessions);

维护打开的session obj的Context。

Dispatch中有如下4种操作:

tee_dispatch_open_session
tee_dispatch_close_session
tee_dispatch_invoke_command
tee_dispatch_cancel_command

涉及到对session obj的添加,删除,查询操作。

在ta_manager定义了全局链表:

struct tee_ta_ctx_head tee_ctxes = TAILQ_HEAD_INITIALIZER(tee_ctxes);

维护已经opened TA的Context。


访问流程如下所述:

  • NS: TEEC_OpenSession–> smc CMD_TEEC_OPEN_SESSION
  • S: 对于Rpc,分配1个新的thread运行此rpc请求。

注:此时是kernel线程,运行在svc模式,共享kernel空间。如果TA是TA_FLAG_USER_MODE,后期利用tee_user_ta_enter进入user模式前,会在tee_ta_ctx中创建TA页表,且切换至此页表。TA页表的空间范围包括:

tee core space, TA data&code, TA stack&heap, TA param。

代码调用流程如下:

-> main_tee_entry -> tee_entry -> tee_entry_call_with_arg -> entry_open_session
-> tee_dispatch_open_session

  • tee_ta_open_session
    • tee_ta_init_session
      • 如果所带session ptr有效(在opened session ptr中或指示为static TA),则返回;
      • 如果UUID非0,则在Ta-context-link中查找对应的 Context。如可以找到,说明TA之前已经load。创建session对象,添加进opend-session-link,并返回。   
      • 至此,说明TA还未load,开始load TA。
      • 如果TA已经被读至Ram,则load此TA,且创建tee_ta_ctx,且将至加入到Ta-context-link中。此种情形下,默认都是user TA, 即TA_FLAG_USER_MODE。
      • 如果UUID不为0,则在static TA中查找UUID,如找到,则此TA context 添加入Ta-context-link。Static TA都具有TA_FLAG_MULTI_SESSION属性。
      • 将当前session添加进opend-session-link。如果是static TA,则调用其
        COMMAND_CREATE_ENTRY_POINT回调。
    • 如果是创建session情形,则对于static TA,则调用TA COMMAND_OPEN_SESSION;    
      对于user TA,调用TA USER_TA_FUNC_OPEN_CLIENT_SESSION。

-> 如果打开失败,且原因是TA还未读入RAM,则利用tee_ta_rpc_load请求REE取得TA文件。然后再次调用tee_ta_open_session。此时需要记录TA在NS的mem映射情况nwumap。


Fimware流程图


TEE: OP-TEE