TEE: OP-TEE

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的结构流程图如下:

这里写图片描述


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


这里写图片描述


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


这里写图片描述


上图则是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流程图


这里写图片描述

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值