static TA和user TA

本文详细解析了TEE环境中会话开启的过程,包括opensession命令处理、会话初始化及TA加载流程,区分了静态TA与用户TA的不同加载方式。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

user space发送的open session命令最终是在tee_entry_std中处理的
void tee_entry_std(struct thread_smc_args *smc_args)
{

    /* Enable foreign interrupts for STD calls */
    thread_set_foreign_intr(true);
    switch (arg->cmd) {
    case OPTEE_MSG_CMD_OPEN_SESSION:
        entry_open_session(smc_args, arg, num_params);
        break;
    case OPTEE_MSG_CMD_CLOSE_SESSION:
        entry_close_session(smc_args, arg, num_params);
        break;
    case OPTEE_MSG_CMD_INVOKE_COMMAND:
        entry_invoke_command(smc_args, arg, num_params);
        break;
    case OPTEE_MSG_CMD_CANCEL:
        entry_cancel(smc_args, arg, num_params);
        break;
    default:
        EMSG("Unknown cmd 0x%x\n", arg->cmd);
        smc_args->a0 = OPTEE_SMC_RETURN_EBADCMD;
    }
}
可以看到tee_entry_std中处理的命令有三个分别是open session/close session/invoke/cancel,这里先已open session为例
在entry_open_session 中调用get_open_session_meta和copy_in_params 检查参数后,最终调用tee_ta_open_session->tee_ta_init_session 来找到session
static TEE_Result tee_ta_init_session(TEE_ErrorOrigin *err,
                struct tee_ta_session_head *open_sessions,
                const TEE_UUID *uuid,
                struct tee_ta_session **sess)
{
    TEE_Result res;
    struct tee_ta_ctx *ctx;
    struct tee_ta_session *s = calloc(1, sizeof(struct tee_ta_session));

    *err = TEE_ORIGIN_TEE;
    if (!s)
        return TEE_ERROR_OUT_OF_MEMORY;

    s->cancel_mask = true;
    condvar_init(&s->refc_cv);
    condvar_init(&s->lock_cv);
    s->lock_thread = THREAD_ID_INVALID;
    s->ref_count = 1;


    /*
     * We take the global TA mutex here and hold it while doing
     * RPC to load the TA. This big critical section should be broken
     * down into smaller pieces.
     */


    mutex_lock(&tee_ta_mutex);
    TAILQ_INSERT_TAIL(open_sessions, s, link);

    /* Look for already loaded TA */
//tee_ctxes 这个list上根据uuid 查找TA,所有已经load到dram中的TA都会在这个list中
    ctx = tee_ta_context_find(uuid);
    if (ctx) {
//如果已经找到TA,就直接返回了
        res = tee_ta_init_session_with_context(ctx, s);
        if (res == TEE_SUCCESS || res != TEE_ERROR_ITEM_NOT_FOUND)
            goto out;
    }

    /* Look for static TA */
    res = tee_ta_init_pseudo_ta_session(uuid, s);
    if (res == TEE_SUCCESS || res != TEE_ERROR_ITEM_NOT_FOUND)
        goto out;

    /* Look for user TA */
    res = tee_ta_init_user_ta_session(uuid, s);

out:
    if (res == TEE_SUCCESS) {
        *sess = s;
    } else {
        TAILQ_REMOVE(open_sessions, s, link);
        free(s);
    }
    mutex_unlock(&tee_ta_mutex);
    return res;
}
//从tee_ta_init_session 中知道TA 有两种,一种是所谓的静态TA,是和optee build在一起的,因此调用tee_ta_init_pseudo_ta_session来查找
TEE_Result tee_ta_init_pseudo_ta_session(const TEE_UUID *uuid,
            struct tee_ta_session *s)
{
    struct pseudo_ta_ctx *stc = NULL;
    struct tee_ta_ctx *ctx;
    const struct pseudo_ta_head *ta;

    DMSG("   Lookup for pseudo TA %pUl", (void *)uuid);
//可见所有的静态TA 都是放在__start_ta_head_section ~ __stop_ta_head_section 这个段中
    ta = &__start_ta_head_section;
    while (true) {
        if (ta >= &__stop_ta_head_section)
            return TEE_ERROR_ITEM_NOT_FOUND;
//根据uuid 比较是否找到TA
        if (memcmp(&ta->uuid, uuid, sizeof(TEE_UUID)) == 0)
            break;
        ta++;
    }

    /* Load a new TA and create a session */
    DMSG("      Open %s", ta->name);

找到后对struct tee_ta_ctx *ctx; 赋值
    stc = calloc(1, sizeof(struct pseudo_ta_ctx));
    if (!stc)
        return TEE_ERROR_OUT_OF_MEMORY;
    ctx = &stc->ctx;

    ctx->ref_count = 1;
    s->ctx = ctx;
    ctx->flags = ta->flags;
    stc->pseudo_ta = ta;
    ctx->uuid = ta->uuid;
    ctx->ops = &pseudo_ta_ops;
    TAILQ_INSERT_TAIL(&tee_ctxes, ctx, link);

    DMSG("      %s : %pUl", stc->pseudo_ta->name, (void *)&ctx->uuid);

    return TEE_SUCCESS;
}
第二中是user TA在tee_ta_init_session 中通过tee_ta_init_user_ta_session 来查找
    /* Look for user TA */
    res = tee_ta_init_user_ta_session(uuid, s);

TEE_Result tee_ta_init_user_ta_session(const TEE_UUID *uuid,
            struct tee_ta_session *s)
{
    TEE_Result res;

    if (!user_ta_store)
        return TEE_ERROR_ITEM_NOT_FOUND;

    DMSG("Load user TA %pUl", (void *)uuid);
可见调用ta_load来加载
    res = ta_load(uuid, user_ta_store, &s->ctx);
    if (res == TEE_SUCCESS)
        s->ctx->ops = &user_ta_ops;
    return res;
}
在ta_load 中会调用user_ta_store的open函数
而这里的
TEE_Result tee_ta_register_ta_store(const struct user_ta_store_ops *ops)
{
    user_ta_store = ops;
    return TEE_SUCCESS;
}

static const struct user_ta_store_ops ops = {
    .open = ta_open,
    .get_size = ta_get_size,
    .read = ta_read,
    .close = ta_close,
};

static TEE_Result register_supplicant_user_ta(void)
{
    return tee_ta_register_ta_store(&ops);
}
可见这里的user_ta_store 就是ops
static TEE_Result ta_load(const TEE_UUID *uuid,
              const struct user_ta_store_ops *ta_store,
              struct tee_ta_ctx **ta_ctx)
{
    TEE_Result res;
    uint32_t mandatory_flags = TA_FLAG_USER_MODE | TA_FLAG_EXEC_DDR;
    uint32_t optional_flags = mandatory_flags | TA_FLAG_SINGLE_INSTANCE |
        TA_FLAG_MULTI_SESSION | TA_FLAG_SECURE_DATA_PATH |
        TA_FLAG_INSTANCE_KEEP_ALIVE | TA_FLAG_CACHE_MAINTENANCE;
    struct user_ta_ctx *utc = NULL;
    struct ta_head *ta_head;
    struct user_ta_store_handle *ta_handle = NULL;
//调用ops的open 函数得到ta_handle
    res = ta_store->open(uuid, &ta_handle);
    if (res != TEE_SUCCESS)
        return res;

    /* Register context */
//申请注册的struct user_ta_ctx *utc
    utc = calloc(1, sizeof(struct user_ta_ctx));
    if (!utc) {
        res = TEE_ERROR_OUT_OF_MEMORY;
        goto error_return;
    }
    TAILQ_INIT(&utc->open_sessions);
    TAILQ_INIT(&utc->cryp_states);
    TAILQ_INIT(&utc->objects);
    TAILQ_INIT(&utc->storage_enums);
//调用load_elf 来装载ta_handle对应的elf
    res = load_elf(utc, ta_store, ta_handle);
    if (res != TEE_SUCCESS)
        goto error_return;

    utc->load_addr = tee_mmu_get_load_addr(&utc->ctx);
    ta_head = (struct ta_head *)(vaddr_t)utc->load_addr;

    if (memcmp(&ta_head->uuid, uuid, sizeof(TEE_UUID)) != 0) {
        res = TEE_ERROR_SECURITY;
        goto error_return;
    }

    /* check input flags bitmask consistency and save flags */
    if ((ta_head->flags & optional_flags) != ta_head->flags ||
        (ta_head->flags & mandatory_flags) != mandatory_flags) {
        EMSG("TA flag issue: flags=%x optional=%x mandatory=%x",
             ta_head->flags, optional_flags, mandatory_flags);
        res = TEE_ERROR_BAD_FORMAT;
        goto error_return;
    }


}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值