Are you in control of your IoT devices? Have you invested in their security or will they turn against you?
In this article, we will talk about a technology developed by Intel named Software Guard eXtensions (SGX), how Operating Systems have evolved to reduce privilege escalation problems, what are some documented potential vulnerabilities with Intel SGX, and how you can port your application to Intel SGX using a Library Operating System.
Software Guard Extensions
Intel introduced the Software Guard Extensions CPU instruction code in 2015 within the 6th generation of their CPU Architecture, known as Skylake microarchitecture. These instruction codes provide the capability of either a User Space application or an Operating System to define private and encrypted regions of memory (RAM). These private regions of memory can’t be read by any other user space process or privilege level process, such as a kernel space thread.
The CPU is the actor which encrypts these regions of memory and decrypts them on the fly within the same CPU core when it has to read that region of the memory, protecting the process code of being examined.
This Intel SGX technology is not unique, as AMD introduced a similar technology called Secure Encrypted Virtualization (SEV), which provides encryption to all memory assigned to a Virtual Machine, avoiding the Hypervisor to read in those regions of memory.
Currently, for Cloud Infrastructure workloads, Microsoft Azure provides a product named Confidential Computing, that enables applications SGX ready to be run on this resource.
Intel SGX can be used in several use cases, such as:
Keys Management: The encrypted memory regions can be used to help manage cryptographic keys and provide functionality similar to a Hardware Security Module.
Blockchains: It can help increase privacy and security for transaction processing, consensus and smart contracts.
Secure Isolation: It provides additional privacy for multi-party computation on sensitive data.
Edge Computing: Helps secure the communication between IoT devices and Cloud infrastructure.
Digital Wallets: It provides a defense to help secure payments and transactions.
Communication and Messaging: Helps secure the communication between the sender and recipient.
To use SGX and implement an encrypted memory region, the application has to be written in a way that speaks SGX. To do that, an understanding of how user applications and operating systems interact with each other.
A story about Operating Systems…
The Operating Systems have evolved their implementations to make them more secure and to prevent applications to read memory of others. Operating Systems try their best to provide classic protection mechanisms with the help of CPU instructions — if the CPU Architecture provides them. However, SGX provides a more enhanced security mechanism that the classic designs of Operating Systems can’t.
One of the most implemented designs in Operating Systems development is the monolithic approach, where you have two separations: the user space in the third protection ring in Intel x86 architecture; and the kernel space, or supervisor, that runs in the zero protection ring.
This design approach is one of the most implemented, and it is the design for Linux, FreeBSD and other Unix-like operating systems. With this implementation, the operating system is in charge of separating applications data in different memory regions and doesn’t permit that any application can see the contents of another application in memory. When a vulnerability is discovered in an application or in an operating system structure, the vulnerability can escalate to Supervisor Space and be able to read any data in memory, accessing any secrets.
Memory in this implementation is not encrypted at all and it just depends on the standard privileges semantics. For example, a user space application that is focused on security that requests a memory allocation to the Operating System Kernel of a specific size, and the application encrypts this requested memory space by itself and finally releases it when it is no longer needed or when the application exists, there might be several race conditions and exploitable stages when this application does this operations, that they might read the contents of the encrypted memory.
The Operating Systems have evolved to provide security to applications using isolation techniques. One of these techniques is Lightweight Virtualization, which is now heavily in use.
Lightweight Virtualization is not rather new, but has become popular with the Docker engine in Linux. This implementation allows to isolate different user spaces processes in their own sandbox by using namespaces provided by the Operating System Kernel.
In described implementations, it is encouraged that the applications should not be rewritten to provide an expected natural behaviour while keeping the compatibility with current Operating System design. These implementations don’t provide a more secure mechanism that Intel SGX is providing.
How does the Operating System provide a Virtual Memory Management to Applications?
Several Operating Systems provide the same mechanism of Virtual Memory management to their user space applications, providing them a Memory Stack model:
All user space applications try to allocate and release memory the whole time, at request (like C
applications with the classical
free() functions and relatives) or dynamically,
with a garbage collector. At memory release there can be some conditions where a vulnerability can
happen when another user application can read the released memory region from another application,
or even at kernel space this kind of situation can happen. There are several ongoing efforts to
make the Operating Systems and applications more secure while fixing discovered vulnerabilities,
but those fixes are applied only after the vulnerability discovery, there is no foolproof mechanism
that proactively reduces these attacks, and that is what Intel SGX is trying to solve.
How does Intel SGX Works?
The mechanism of Intel SGX in an application is that the execution code is split in two main parts: an insecure part and a secure part.
The interaction between the insecure (untrusted) part and the secure (trusted) part is as follows:
Application is built with trusted and untrusted parts.
Application runs and creates an enclave which is placed in trusted memory.
Trusted function is called; code running inside the enclave sees data in clear, external access to data is denied.
Trusted function handles data within the enclave.
Trusted function exits; enclave data remains in trusted memory.
The data inside the enclave is encrypted in memory and is decrypted on the fly by the CPU. Neither the kernel or supervisor can’t read the contents of the enclave, as they are encrypted in this region of memory, and unencrypted online in CPU when requested.
How can you trust an SGX enabled application?
Intel SGX is designed that only the Enclave is trusted by the Processor and nothing else, so the operating system, applications outside of enclave and hypervisors are treated as hostile so they can’t execute any CPU instruction to decrypt the Enclave and see it’s contents. But, how can you trust an application that in fact is storing secrets in an Enclave? That is where Attestation mechanism comes to function.
The Attestation feature is a way to provide a secure communication between enclaves (local attestation) or to provide a chain of trust to validate that the Enclave is verified and not tampered (remote attestation). When the enclave is initialized, it can send a report to a server which can validate if the report was generated by a SGX instruction set, establishing a chain of trust. The vendor can request Intel to be added to a list of certified implementations so the user can fully validate that the software in question has not been tampered by a malicious software.
Can I run my favorite application in an SGX Enclave?
The short answer is No, the long answer is ‘it depends’. In order to port an application to be SGX Ready, several parts, if it is technically possible, have to be rewritten in the application’s source code. These parts have to be linked against Intel’s SGX SDK to make them run. A lot of popular service applications are simply incompatible with Intel SGX, as they were designed before SGX even existed, so they have their own security implementations, so porting them would take much effort in reengineering.
This is where a Library Operating System can help with this.
Graphene SGX Library Operating System
A Library Operating System is a software that provides an abstraction of all the services that one classic Operating System provides, such as a system calls interface or network stack in the form of libraries that one user space application can link against them to provide an operating system image that can be deployed as one binary.
With the Graphene SGX Library Operating System, the application is linked against it at compilation time and then it is loaded with a Platform Adaptation Layer, which takes care of Enclave initialization to run the whole application inside it.
Graphene LibOS provides the following advantages:
It allows to run almost any application inside an SGX enclave without modifications
The System Calls are implemented inside the Enclave
Enhance the Trusted Computing Base
So, is Intel SGX really secure?
Intel SGX provides a new security layer at processor level, and improves the security of applications, but it is not infallible. There are different vulnerabilities that are documented.
Memory Corruption Attack. This happens when there is a buffer overflow in which a routine return address on a call is replaced by an address of a routine that is present in an executable region, bypassing the no-execute bit feature if present. This can be solved enabling Address Space Layout Randomization (ASLR) in SGX enabled programs.
Uninitialized Memory. This happens when there is a Memory Page that is not initialized yet by the Operating System, allowing the Operating System to inject data inside an enclave. This is called SGX Bleed, this can be solved by enabling Address Space Layout Randomization (ASLR) in Kernel Space.
Page Table Attack. This happens when the page table is manipulated, so a page access pattern is observed. This can be solved by improving the Trusted Execution Environment in SGX at compilation time.
Cache Attack. This happens when trying to access cached and non-cached data in the processor. As the Enclaves share the processor cache with other processes, this vulnerability is by SGX design, so there are no remeditions about it, although this kind of attacks are very hard to accomplish.
Branch Shadow. With a vulnerable SGX SDK, the application compiled has a shadow code that exposes data outside of the Enclave. This can be solved with an updated SGX SDK and with an updated Intel microcode.
Row Hammer Attack. This happens with faulty DRAM modules, affecting the memory where the enclave is residing, and then blocking the processor. This can be solved with updated DRAM module hardware.
As described, Intel SGX provides a security solution at hardware level to provide a Trusted Computing Base. As all technologies that are based on Hardware, it provides some new challenges in software development. Fortunately, there are solutions like Graphene SGX OS Library that can help ease the software porting to this technology. It is important to keep in mind that Intel SGX has some documented vulnerabilities, so having a good software development practice based on security first can help reduce vulnerabilities, even if at the end you decide to not use SGX at all and take another approach.
These are all the references used to write this article, sorted by known security attacks and technologies.
Attacks & Vulnerabilities
Links of the aforementioned security breaches related to Intel SGX