After defining the trusted (enclave) and untrusted (application) components of an Intel® SGX enabled application, the developer should carefully define the interface between untrusted application and enclave. ISV trusted code is executed in the following scenarios:
- The untrusted application explicitly makes a call to an enclave interface function within the enclave, for example the application makes an ECall. Calling through an ISV interface function is the same as a regular application calling into a shared library.
- After a call made from within the enclave to the outside application (OCall) returns. Returning from an OCall is similar to what happens when a call from a shared library to another shared library returns; for instance after calling the Standard C library to perform an I/O operation. When an OCall returns, the trusted function that made the call outside the enclave continues execution.
- After an interrupts returns, the enclave code is also executed. However, the Intel SGX architecture ensures that execution within the enclave continues as if the interrupt never occurred. The same behavior is expected with interrupts that happen while a shared library function is executing.
An enclave must expose an API for applications to call in (ECalls) and advertise what services provided by the untrusted domain are needed (OCalls). The enclave writer defines the ECall and OCall functions that constitute the enclave boundary interface. Since ECalls expose the interface that an untrusted application may use, you should reduce the enclave attack surface by limiting the number of ECalls. You should also be aware that an enclave has no control on which ECall is executed, or the order in which ECalls are invoked. Thus, an enclave cannot depend on ECalls occurring in certain order. On the other hand, ISV interface functions can be invoked only after the enclave has been initialized, which means that:
- Any necessary address re-basing is performed successfully;
- Trusted global data, including security-centric data (for example, stack canary) are initialized successfully;
- Trusted thread context, including security-centric data (for example, stack guard pages) of the trusted thread the function is running on is initialized successfully;
- The implicit trusted initialization functions (for example, ISV global constructors) execute to completion.
As a special case of an ISV interface function, an ISV registered exception handler can only be invoked on a trusted thread where a supported enclave exception has happened and after the conditions above are met.