optee os syscall

以 TEE_OpenTASession 为例

secure EL0

TEE_OpenTASession	// lib\libutee\tee_api.c
	_utee_open_ta_session(destination, cancellationRequestTimeout,
				    	  &up, &s, returnOrigin);
		UTEE_SYSCALL _utee_open_ta_session, TEE_SCN_OPEN_TA_SESSION, 5

在定义一个syscall的时候,在userspace层需要通过UTEE_SYSCALL宏来实现,在optee中所有的 utee_xxx类似的接口都使用该宏定义。在 lib\libutee\arch\arm\utee_syscalls_a64.S 中实现

.macro UTEE_SYSCALL name, scn, num_args
        mov     x8, #(\scn)
        svc #0  //触发svc异常,陷入EL1
        ret

该宏相当于实现吧了 utee_xxx 的函数,宏的参数 name 相当于 utee_xxx,scn是系统调用的index,numargs参数个数,小于或等于4则表示不需要传递参数给system call。

secure EL1

从el0的svc陷入到optee os内核,首先走到optee os的异常向量表

//core\arch\arm\kernel\thread_a64.S
	el0_sync_a64
		b el0_sync_a64_finish
			b.eq el0_svc
				bl thread_svc_handler
					sess->handle_svc(regs)
						user_ta_handle_svc //core\kernel\user_ta.c
							// 根据 scn 从 tee_svc_syscall_table 中找到入口函数
							scf = get_tee_syscall_func(scn)
							set_svc_retval(regs, tee_svc_do_call(regs, scf))
								tee_svc_do_call // 跳转到optee os 中的 syscall entry
									/* Call the svc function */
									ldr	x16, [x19, #SC_REC_X1]
									blr	x16

根据 scn 从 tee_svc_syscall_table 中找到入口函数。tee_svc_syscall_table定义如下

// core\arch\arm\tee\arch_svc.c
static const struct syscall_entry tee_svc_syscall_table[] = {
	///....
	SYSCALL_ENTRY(syscall_open_ta_session)
	///...
};

例子:
触发方式,linux终端输入以下命令
xtest 1011

TA_InvokeCommandEntryPoint	//imx-optee-test\ta\rpc_test\ta_entry.c
	switch (nCommandID) {
		case TA_RPC_CMD_CRYPT_SHA256:
			return rpc_sha256(false, nParamTypes, pParams);
				// imx-optee-test\ta\rpc_test\ta_rpc.c
				rpc_call_cryp(sec_mem, nParamTypes, pParams, TA_CRYPT_CMD_SHA256);
			    	TEE_OpenTASession(&cryp_uuid, TEE_TIMEOUT_INFINITE, types,
						params, &cryp_session, &origin);
				

以上,在uta中打开另外一个 CRYPT pta。

总结:
最总会调用 tee_svc_do_call 来执行 tee_svc_syscall_table[scn] 中定义的函数。在真正执行tee_svc_syscall_table[scn]之前会保存相关寄存器以便执行完成之后恢复到 userspace,而且还需要将userspcae中带入的数据拷贝到kernel spacetee_svc_syscall_table[scn]中的函数使用。

你可能感兴趣的:(信息安全,安全架构)