OP-TEE / optee_os

Trusted side of the TEE
Other
1.61k stars 1.07k forks source link

How to move from the normal world to the secure world #3895

Closed 21212124 closed 4 years ago

21212124 commented 4 years ago

Hi, I want to know where is the code that the Hello World example or another example uses to go from NW to SC, what call does it make to the SMC? What interruption does Qemu do? Thanks

jforissier commented 4 years ago

where is the code that the Hello World example or another example uses to go from NW to SC

https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/tee/optee/call.c?h=v5.7-rc7#n115

21212124 commented 4 years ago

@jforissier I know that input to the monitor can be activated by executing a dedicated instruction, the Secure Monitor Call (SMC) instruction, or the IRQ, FIQ exceptions. Do you know how the hello world example is done? Or who variable activates it?

etienne-lms commented 4 years ago

Hello @21212124, Maybe you should have a look at LCU14-103: How to create and run Trusted Applications on OP-TEE and HKG15-311 - OP-TEE for Beginners and Porting Review. You should find other informattion from OP-TEE presentations refs and more generally in OP-TEE documentation at https://optee.readthedocs.io/.

21212124 commented 4 years ago

@etienne-lms when TEEC_FinalizeContext () and TEEC_InitializeContext () enter "TEE Driver" invoke an ioctl call?

etienne-lms commented 4 years ago

I think almost all TEEC_XxxxxXxxxx() API functions do perform an ioctl to OP-TEE driver in the kernel.

TEEC_InitializeContext(), calling teec_open_dev() do ioctls to the TEE driver in the Linux kernel. TEEC_FinalizeContext() only closes the opened Linux device handle.

21212124 commented 4 years ago

@etienne-lms ioctl is the only system call that uses the client API to access the secure monitor? are there some more?

thanks for helping me

etienne-lms commented 4 years ago

Yes, OP-TEE Client library uses IOCTLs to request services from the Linux kernel OP-TEE driver. OP-TEE drivers is registered in the TEE driver framework, you will find the supported IOCTLs from the Linux kernel tee_core.c source file. Most of these IOCTLs end in Linux kernel invoking the secure world.

As far as I known, the only other syscall that can lead to an invocation of the secure world is the device close function. When called, the Linux kernel (I mean the OP-TEE Linux driver) will likely invoke secure world to notify that some allocated resources can be freed (session context, shared memory references, etc...).

21212124 commented 4 years ago

@etienne-lms when TA_CreateEntryPoint is called? when TEEC_InitializeContext is called does the TEE framework call TA_CreateEntryPoint?

etienne-lms commented 4 years ago

TEEC_InitializeContext() finds OP-TEE interface. TEEC_OpenSession() invokes the TA. It does many things, see below. TEEC_InvokeCommand() obviously invokes the TA for a specific command with parameters. TEEC_CloseSession() invokes the TA to close the client session. TEEC_FinalizeContext() releases allocated OP-TEE interface resources. TEEC_XxxSharedMemory() do not invoke the TA but may invoke OP-TEE Core to register references.

TEEC_OpenSession() does many things. If the target TA is not already loaded, this function will make OP-TEE Core and Linux exchaging to get the TA loaded in secure world and its TA_CreateEntryPoint entry executed. Upon TEEC_OpenSession(), once TA instance created/found, its TA_OpenSessionEntryPoint entry is executed.

Similarly TEEC_CloseSession() may lead to TA instance being unloaded and destroyed from secure world in which case TA_DestroyEntryPoint is called after session closure.

Below a sumup of client app (CA) calls and trusted app (TA) entry points: CA TEEC_OpenSession() --> TA TA_OpenSessionEntryPoint, possibly TA_CreateEntryPoint CA TEEC_InvokeCommand() --> TA TA_InvokeCommandEntryPoint CA TEEC_CloseSession() --> TA TA_CloseSessionEntryPoint, possibly TA_DestroyEntryPoint

chandni commented 1 year ago

This is a trace of the optee_example_hello_world() function lifecycle showing all the functions calls (entry and exit) in normal world and secure world for TEEC_InvokeCommand entry point. Ignore the timestamp data in the middle column. The last column shows the context the current function is invoked (user space, cl;ient API, driver, secure OS) vs where the control lands after the function call. This doesn't show the order in which the NW and SW functions are interleaved. Working on that.

NW trace:

TEEC_InvokeCommand entry             (946382063)             Client user app, client TEE API
TEE_IOC_INVOKE entry                      946432016         TEE Client API, TEE driver (IOCTL)
[   12.512973] optee_smcc_smc entry   946516160         TEE Driver, SMC
[   12.514138] optee_smcc_smc exit    946588845         TEE Driver, SMC
[   12.514667] tee_ioctl_invoke entry     946620909         IOCTL, TEE Linux driver
[   12.515213] optee_invoke_func entry                          IOCTL, Linux TEE driver
[   12.515417] optee_do_call_with_arg 
SMCC OPTEE MSG                            946669254         Linux TEE driver, OPTEE Secure OS
[   12.515641] optee_smcc_smc entry   946683285         TEE Driver, SMC
[   12.521518] optee_smcc_smc exit    947050370         TEE Driver, SMC
[   12.521735] OPTEE Secure OS exit   947064125         OPTEE Secure OS, Linux TEE driver, 
[   12.521947] optee_invoke_func exit                                    Linux TEE driver, TEE Client API
TEE_IOC_INVOKE exit                    947148629            TEE driver (IOCTL), TEE Client API
[   12.524133] optee_smcc_smc entry    947213668            TEE Driver, SMC
[   12.525194] optee_smcc_smc exit     947279845            TEE Driver, SMC
TEEC_InvokeCommand exit                 (947307714)              client TEE API, Client user app

SW trace:

D/TC:0 0 call_entry_std:169              tee_entry_std entry            946720638           optee OS, TEE Internal API
D/TC:? 0 __tee_entry_std:574             entry_invoke_command entry 946737484               tee internal api, tee internal api
I/TA: TA_InvokeCommandEntryPoint    entry                                                                           user mode TA
D/TA:  inc_value:111 has been called
I/TA: Got value: 42 from NW
I/TA: Got timestamp value 1073862672 from NW
I/TA: Increase value to: 43
I/TA: TA_InvokeCommandEntryPoint    leave                                                                            user mode TA
D/TC:? 0 __tee_entry_std:578            entry_invoke_command leave      947000436                tee internal api, tee internal api
D/TC:? 0 call_entry_std:177             tee_entry_std leave                 947017418           TEE Internal API, optee OS