Software Guard Extension (SGX) adds powerful security capabilities to x86-architecture based Intel CPUs enabling the creation of enclaves. Enclaves are user space areas inside the memory address space specifically protected by the CPU that prevent access even from higher privileged, kernel space processes. To implement the isolation from other processes and the operating system, SGX empowers the encryption and integrity protection of enclaved programs. This gives raise to a new, powerful programming model for application developers.
Private information such as usernames, passwords, credit records should grant access to authorized users. Generally, the operating system (OS) is able to enforce security policies to avoid unintentional leakage of those secrets. Nearly all protection mechanisms added by OS could not defend a malicious application with administration privileges. Such applications have unrestricted access to all system resources and all running applications and extract secret data directly from the memory. To defend such malicious applications and give users a higher level of protection of their secret data, Intel designed SGX.
To conclude, Intel SGX offers an extra set of CPU instructions to create Enclaves, areas that are protected by hardware and ensure confidentiality and integrity even in front of privileged operating systems.
Intel SGX — A Primer
Intel SGX was introduced by Intel in the year of 2015 with its Skylake CPU familiy. SGX is a new instruction set to provide a reserve sandbox that protects Enclaves from
- OS or hypervisor (in case of virtual machine host systems)
- BIOS, firmware, drivers
- System management module (ring‑2)
- Intel management engine (ME)
- Any remote attack
Overall, SGX is an hardware enforced security mechanism that requires a Trusted Computer Base (TCB), Hardware secrets, Remote Attestation, Sealed Storage and Memory Encryption.
The TCB is the CPU’s package boundary and SGX related software components. The hardware secrets are two 128-bit keys burned into the CPU while production, while Intel has knowledge of the Root Provisioning Key (RPK) and in contrast, the Root Seal Key (RSK) is not known by Intel. That’s the reason why most derived keys are based on RSK. Remote Attestation is applied for the client to prove to the service provider that an Enclave is running a given software, inside a given CPU, with a given security level, for a given Individual Software Vender (ISV). This is necessary before the service provider decides to provide requested secrets. With the help of sealed storage SGX is able to save secret data to untrusted media. Data and code inside Enclaves are not secrets. They are just logics that are required to process the secret and most of them are open sourced or can be reverse engineered. Therefore, secrets are provisioned later by the service provider and should be stored out of the Enclave through sealing mechanism when necessary (e.g. for future usage).
Finally, Intel SGX implements the following protections from known hardware and software attacks:
- The memory of the Enclave cannot be read or written from outside the Enclave regardless of the current privilege level and CPU mode.
- It’s not possible to debug the Production Enclaves by software or hardware debuggers.
- To call an Enclave function the only way is through a new instruction that performs several protection checks. The Enclave environment itself cannot be entered through classic function calls, jumps, register manipulation, or stack manipulation.
- SGX enables industry-standard encryption algorithms with replay protection for Enclave memory. Direct attacks on hardware level of the memory to connect another system will yield to encrypted data.
- The memory encryption key is stored within the CPU and is not accessible and changes every power cycle.
- Isolated data within Enclaves are only accessible by code that shares the Enclave.
All those advantages lead to a reduced attack surface using Intel SGX shown in Figure 1.
Enclaves from memory perspective
This section gives you a short introduction of Enclave establishment from memory scope. It covers the main architectural concepts for Enclave operation to give you a general comprehension for application design in the next section. Figure 2 illustrates a typical Enclave memory layout.
- The first step to create an Enclave to load code and data from user space into the Enclave Page Cache (EPC) and establish the Enclave entity. ECREATE is the initial command to set up the initial environment, but I’ll discuss the programming functions in the next section. The application hands over the Enclave content along with additional information required by the Enclave creation API to the Enclave creation service running at ring‑0. The commitment of memory resources is passed by ECREATE to set up the initial environment, specifying base address and size of the Enclave. While the address range (ELRANGE) is part of the application’s address space, this reserves the memory range. So the Enclave will reside in this address region, while ECREATE allocates an EPC for the SGX Enclave Control Structure (SECS).
- Consequently, the Enclave is able to add pages (EADD) and measure the committed memory content of the Enclave (EEXTEND). Measurement means, an Enclave is instantiated in a trusted environment and an accurate and protected recording of its identity is taken.
- Afterwards, the initialization of the Enclave finalizes the cryptographic log and establishes the Enclave identity and sealing identity (EINIT). A cryptographic hash of the log is stored. The Enclave is initialized by the EINIT instruction. The EINIT instruction checks the EINIT token to validate that the Enclave has been enabled on this platform. If the Enclave is not correctly constructed or the EINIT token is not valid for the platform then EINIT will fail. Until an EINIT is executed, the enclave is not permitted to execute any Enclave code (i.e. entering the Enclave by executing EENTER).
- Finally, the Enclave is able to entry and exiting using two different operations:
- Synchronous entry and exit
- Asynchronous Enclave Exit (AEX) and resuming execution after an AEX The EENTER instruction is the method to enter the Enclave under program control.
Enclaves from an application perspective
To create an application with SGX enabled Enclaves it is first necessary to internalize the three words Enclave, attestation and sealing and it’s usage.
An application with Intel SGX is separated in two components:
- Trusted component, describes the Enclave itself. The code that resides in the trusted code is the code that accesses an application’s secrets. An application can have more than one trusted component/enclave.
- Untrusted component describes the “user application”. It is important to note that, from the standpoint of an Enclave, the OS is already an untrusted component.
It is a good practice to minimize the size of the untrusted component as well as reduction of the interconnect communication between trusted and unstrusted components to reduce attack surface for malicious applications.
Attestation describes the mechanism to demonstrate to other entities that a particular environment was instantiated in the correct manner.
Sealing enables data belonging to the trusted environment to be bound to it such that it can be restored only when the trusted environment is restored. The encryption keys are derived internally on demand and are not exposed to the enclave.
To initialize an enclave, four of the new CPU instructions (ECREATE, EADD, EEXTEND, EINIT) provided by SGX architecture are used.
Initially, the ECREATE instruction, which turns a free EPC page into the SECS for the new enclave, is the beginning of a new Enclave. The instruction copies an SECS structure outside the EPC into an SECS page inside the EPC. The internal structure of SECS is not accessible to software. The Software sets the Base address, size and further attributes in the source structure. At the same time, ECREATE validates the information used to initialize the SECS.
The instruction EADD loads the initial code and data into the enclave. EADD is used to create both TCS pages and regular pages. This function copies a source page from non-enclave memory into the EPC, associates the EPC page with an SECS page inside in the EPC, and stores the linear address and security attributes in EPC Map (EPCM). EADD reads its input data from a Page Information structure, which contains the virtual address of the EPC page and further attributes. EADD ensures that the EPC page is not allocated to another Enclave, the page’s virtual address falls within the enclave’s ELRANGE and all the reserved fields are set to zero.
During loading an enclave, the system software will also use the EEXTEND instruction, which updates the enclave’s measurement used in the software attestation process. It updates the MRENCLAVE measurement register of an SECS with the measurement of an EXTEND string.
This instruction is the final punch for the execution of the Enclave build process. After EINIT, the MRENCLAVE measurement is finished and the Enclave is ready to start user execution using EENTER instruction. The INIT attribute is set to true, if initialization is successful. On the other hand, once EINIT is set to true, EADD cannot be invoked on that enclave anymore, so the system software must load all the pages that make up the enclave’s initial state before executing the EINIT instruction.
Since the Intel SGX SDK provides a wrapper for software develeopment it is common practice to define ECALL and OCALL functions in the Enclave definition language (EDL) as following:
“Enclave Call”, a call made into an interface function within the Enclave
“Out Call”, a call made from within the Enclave to the outside application
In a nutshell, ECALLs are prototyped in the trusted section, and OCALLs are prototyped in the untrusted section.
The proxy functionality of the Edger8r tool, which is included in the Intel SGX SDK and executed while building the project, parses the EDL file and generates a series of proxy functions. These proxy functions are essentially wrappers around the real functions that are prototyped in the EDL. Each ECALL and OCALL gets a pair of proxy functions: a trusted half and an untrusted half. The trusted functions go into a trusted header and trusted code-file and are included in the auto-generated Files folder of your enclave project. The untrusted proxies go into an untrusted header and untrusted code-file and are placed in the auto-generated Files folder of the project that will be interfacing with your enclave. Figure 3 illustrates the proxy mechanisms.
That means, your application does not call the ECALL and OCALL functions directly, instead the proxy functions are executed. When you make an ECALL, you call the untrusted proxy function for the ECALL, which in turn calls the trusted proxy function inside the enclave. That proxy then calls the “real” ECALL and the return value propagates back to the untrusted function. This sequence is shown in the figure above. When you make an OCALL, the sequence is reversed: you call the trusted proxy function for the OCALL, which calls an untrusted proxy function outside the enclave that, in turn, invokes the “real” OCALL.
Overall, the proxy functions are responsible for:
- Organize data into and out of the enclave.
- Placing the return value of the real ECALL or OCALL in an address referenced by a pointer parameter.
- Returning the success or failure of the ECALL or OCALL itself as a status value.
 Intel® Software Guard Extensions Programming Reference: https://software.intel.com/sites/default/files/managed/48/88/329298–002.pdf
 Intel® Software Guard Extensions Enclave Writer’s Guide: https://software.intel.com/sites/default/files/managed/ae/48/Software-Guard-Extensions-Enclave-Writers-Guide.pdf
 Intel® Software Guard Extensions (Intel® SGX) Developer Guide: https://software.intel.com/content/www/us/en/develop/download/intel-software-guard-extensions-intel-sgx-developer-guide.html
 Victor Costan and Srinivas Devadas, Intel SGX Explained. Reference: https://eprint.iacr.org/2016/086