OPTEE学习笔记 - IPC

    xiaoxiao2024-12-29  64

    本文学习tee_supplicant的相关内容。以下是杂记,仅用做学习记录。学习代码均取自github和《手机安全和可信应用开发指南》(帅峰云,黄腾,宋洋)

    进程间通信,是系统中进程或线程之间的通信机制,本文介绍OPTEE系统中的IPC机制

    OPTEE的IPC机制主要满足OPTEE用户空间运行的线程调用其它线程,静态TA,安全驱动的需求。其核心原理是利用系统调用来访问其他线程或者安全驱动。当线程需要进行IPC时,首先会通过系统调用陷入到OPTEE内核态,然后执行类似CA调用TA的操作,建立会话并通过调用命令的方式让其他的TA来完成相应的操作。

    TA调用TA

    OPTEE定义了3个i二口,来完成TA和TA之间的调用

    TEE_OpenTASession

    TEE_Result TEE_OpenTASession(const TEE_UUID *destination, uint32_t cancellationRequestTimeout, uint32_t paramTypes, TEE_Param params[TEE_NUM_PARAMS], TEE_TASessionHandle *session, uint32_t *returnOrigin) { TEE_Result res; struct utee_params up; uint32_t s; __utee_from_param(&up, paramTypes, params); res = utee_open_ta_session(destination, cancellationRequestTimeout, &up, &s, returnOrigin); __utee_to_param(params, NULL, &up); /* * Specification says that *session must hold TEE_HANDLE_NULL is * TEE_SUCCESS isn't returned. Set it here explicitly in case * the syscall fails before out parameters has been updated. */ if (res != TEE_SUCCESS) s = TEE_HANDLE_NULL; *session = (TEE_TASessionHandle)(uintptr_t)s; return res; } /* utee_open_ta_session 会陷入内核然后调用syscall_open_ta_session */ /* Called when a TA calls an OpenSession on another TA */ TEE_Result syscall_open_ta_session(const TEE_UUID *dest, unsigned long cancel_req_to, struct utee_params *usr_param, uint32_t *ta_sess, uint32_t *ret_orig) { TEE_Result res; uint32_t ret_o = TEE_ORIGIN_TEE; struct tee_ta_session *s = NULL; struct tee_ta_session *sess; struct mobj *mobj_param = NULL; TEE_UUID *uuid = malloc(sizeof(TEE_UUID)); struct tee_ta_param *param = malloc(sizeof(struct tee_ta_param)); TEE_Identity *clnt_id = malloc(sizeof(TEE_Identity)); void *tmp_buf_va[TEE_NUM_PARAMS]; struct user_ta_ctx *utc; if (uuid == NULL || param == NULL || clnt_id == NULL) { res = TEE_ERROR_OUT_OF_MEMORY; goto out_free_only; } memset(param, 0, sizeof(struct tee_ta_param)); res = tee_ta_get_current_session(&sess); //这里的session是在open一个ta的时候创建的,一个ta对应一个session。这里获取的是本ta的session。 if (res != TEE_SUCCESS) goto out_free_only; utc = to_user_ta_ctx(sess->ctx); res = tee_svc_copy_from_user(uuid, dest, sizeof(TEE_UUID)); if (res != TEE_SUCCESS) goto function_exit; clnt_id->login = TEE_LOGIN_TRUSTED_APP; memcpy(&clnt_id->uuid, &sess->ctx->uuid, sizeof(TEE_UUID)); res = tee_svc_copy_param(sess, NULL, usr_param, param, tmp_buf_va, &mobj_param); if (res != TEE_SUCCESS) goto function_exit; /* * Find session of a multi session TA or a static TA * In such a case, there is no need to ask the supplicant for the TA * code */ res = tee_ta_open_session(&ret_o, &s, &utc->open_sessions, uuid, clnt_id, cancel_req_to, param); //调用内核的opensession函数打开对端ta的session if (res != TEE_SUCCESS) goto function_exit; res = tee_svc_update_out_param(sess, s, param, tmp_buf_va, usr_param); function_exit: mobj_free(mobj_param); if (res == TEE_SUCCESS) tee_svc_copy_kaddr_to_uref(ta_sess, s); tee_svc_copy_to_user(ret_orig, &ret_o, sizeof(ret_o)); out_free_only: free(param); free(uuid); free(clnt_id); return res; }

    TEE_InvokeTACommand

    调用TEE_InvokeTACommand时带入命令ID就能调用TA中的具体命令,其过程与CA的命令调用操作几乎一致

    TEE_CloseTASession

    TEE_CloseTASession接口用于断开TA与其他TA之间的连接,其过程与CA的关闭会话操作几乎一致

    TA调用系统服务和安全驱动

    OPTEE中的TA调用系统服务和安全驱动和REE侧的userspace调用kernel space是类似的,都是通过触发软件中断然后陷入内核态,调用对应的系统服务来完成的,前文提到的open ta session,invoke ta command, close ta session其实也都是系统服务中的一项,下面罗列出OPTEE对外提供的系统服务函数

    /* * This array is ordered according to the SYSCALL ids TEE_SCN_xxx */ static const struct syscall_entry tee_svc_syscall_table[] = { SYSCALL_ENTRY(syscall_sys_return), SYSCALL_ENTRY(syscall_log), SYSCALL_ENTRY(syscall_panic), SYSCALL_ENTRY(syscall_get_property), SYSCALL_ENTRY(syscall_get_property_name_to_index), SYSCALL_ENTRY(syscall_open_ta_session), SYSCALL_ENTRY(syscall_close_ta_session), SYSCALL_ENTRY(syscall_invoke_ta_command), SYSCALL_ENTRY(syscall_check_access_rights), SYSCALL_ENTRY(syscall_get_cancellation_flag), SYSCALL_ENTRY(syscall_unmask_cancellation), SYSCALL_ENTRY(syscall_mask_cancellation), SYSCALL_ENTRY(syscall_wait), SYSCALL_ENTRY(syscall_get_time), SYSCALL_ENTRY(syscall_set_ta_time), SYSCALL_ENTRY(syscall_cryp_state_alloc), SYSCALL_ENTRY(syscall_cryp_state_copy), SYSCALL_ENTRY(syscall_cryp_state_free), SYSCALL_ENTRY(syscall_hash_init), SYSCALL_ENTRY(syscall_hash_update), SYSCALL_ENTRY(syscall_hash_final), SYSCALL_ENTRY(syscall_cipher_init), SYSCALL_ENTRY(syscall_cipher_update), SYSCALL_ENTRY(syscall_cipher_final), SYSCALL_ENTRY(syscall_cryp_obj_get_info), SYSCALL_ENTRY(syscall_cryp_obj_restrict_usage), SYSCALL_ENTRY(syscall_cryp_obj_get_attr), SYSCALL_ENTRY(syscall_cryp_obj_alloc), SYSCALL_ENTRY(syscall_cryp_obj_close), SYSCALL_ENTRY(syscall_cryp_obj_reset), SYSCALL_ENTRY(syscall_cryp_obj_populate), SYSCALL_ENTRY(syscall_cryp_obj_copy), SYSCALL_ENTRY(syscall_cryp_derive_key), SYSCALL_ENTRY(syscall_cryp_random_number_generate), SYSCALL_ENTRY(syscall_authenc_init), SYSCALL_ENTRY(syscall_authenc_update_aad), SYSCALL_ENTRY(syscall_authenc_update_payload), SYSCALL_ENTRY(syscall_authenc_enc_final), SYSCALL_ENTRY(syscall_authenc_dec_final), SYSCALL_ENTRY(syscall_asymm_operate), SYSCALL_ENTRY(syscall_asymm_verify), SYSCALL_ENTRY(syscall_storage_obj_open), SYSCALL_ENTRY(syscall_storage_obj_create), SYSCALL_ENTRY(syscall_storage_obj_del), SYSCALL_ENTRY(syscall_storage_obj_rename), SYSCALL_ENTRY(syscall_storage_alloc_enum), SYSCALL_ENTRY(syscall_storage_free_enum), SYSCALL_ENTRY(syscall_storage_reset_enum), SYSCALL_ENTRY(syscall_storage_start_enum), SYSCALL_ENTRY(syscall_storage_next_enum), SYSCALL_ENTRY(syscall_storage_obj_read), SYSCALL_ENTRY(syscall_storage_obj_write), SYSCALL_ENTRY(syscall_storage_obj_trunc), SYSCALL_ENTRY(syscall_storage_obj_seek), SYSCALL_ENTRY(syscall_obj_generate_key), SYSCALL_ENTRY(syscall_se_service_open), SYSCALL_ENTRY(syscall_se_service_close), SYSCALL_ENTRY(syscall_se_service_get_readers), SYSCALL_ENTRY(syscall_se_reader_get_prop), SYSCALL_ENTRY(syscall_se_reader_get_name), SYSCALL_ENTRY(syscall_se_reader_open_session), SYSCALL_ENTRY(syscall_se_reader_close_sessions), SYSCALL_ENTRY(syscall_se_session_is_closed), SYSCALL_ENTRY(syscall_se_session_get_atr), SYSCALL_ENTRY(syscall_se_session_open_channel), SYSCALL_ENTRY(syscall_se_session_close), SYSCALL_ENTRY(syscall_se_channel_select_next), SYSCALL_ENTRY(syscall_se_channel_get_select_resp), SYSCALL_ENTRY(syscall_se_channel_transmit), SYSCALL_ENTRY(syscall_se_channel_close), SYSCALL_ENTRY(syscall_cache_operation), };

    以上函数在OPTEE userspace中对应型如utee_xxxx类的接口,例如syscall_open_ta_session对应utee_open_ta_session,只要调用utee_open_ta_session函数就会调用到内核准备的syscall_open_ta_session系统服务

    最新回复(0)