# Enclave Development Platform (EDP) The Fortanix EDP is the preferred way for writing Intel® SGX applications from scratch. https://edp.fortanix.com/ Links: [[Rust]], [[Fortanix]], [[SGX]], [[AWS Nitro Enclaves|Nitro Enclaves]] - Developed by [[Fortanix]] - Works for [[SGX]] and [[AWS Nitro Enclaves]] - Works for [[Rust]] applications - Cannot use: - files - processes - links to native applications in other languages - [Github](https://github.com/fortanix/rust-sgx) ([[Rust]]) - [website](https://edp.fortanix.com/) - [Docs](https://edp.fortanix.com/docs/) - [Installation guide](https://edp.fortanix.com/docs/installation/guide/) - Concepts - Tasks - [Deployment](https://edp.fortanix.com/docs/tasks/deployment/) - [[EDP - Using crates.io dependencies]] - Debugging - Examples - Well-documented examples (includes code as well) - Sealing - Attestation - Multithreading (`mpsc-crypto-mining`) - Unit testing (`unit_tests`) - [TLS echo server](https://edp.fortanix.com/docs/examples/tls/) - Other [examples on GitHub](https://github.com/fortanix/rust-sgx/tree/master/examples): - `backtrace_panic - `usercall-extension-bind` - `usercall-extension` - [Rust docs](https://edp.fortanix.com/docs/api/enclave_runner/index.html) ## See also ### - [[EDP on Azure Ubuntu 20.04]] (full installation instructions) ### - [[EDP - Using Rust's std]] ### - [[EDP - Building Rust std from source]] ## Resources ### (Talk) [Developing for the AWS Nitro Enclave Platform](https://fosdem.org/2022/schedule/event/tee_edp_nitro/) by [[Raoul Strackx]] ## Partial Install ### [Install Fortanix EDP utilities from source](https://edp.fortanix.com/docs/installation/guide/) (for Linux) Requires: [[Rust]] You will need to install the OpenSSL development package and the Protobuf compiler. For example, on Debian/Ubuntu: ```bash sudo apt-get install pkg-config libssl-dev protobuf-compiler ``` Then, you can use cargo to install the utilities from source: ```bash cargo install fortanix-sgx-tools sgxs-tools ``` ## General ### [record.gif](https://dingelish.com/record.gif) - A demonstrated attack on the [[Rust]] helloworld program when run with EDP Linked from a GitHub [issue](https://github.com/apache/tvm/issues/2887#issuecomment-480147860) on Apache TVM ![](https://dingelish.com/record.gif) Last frame:![[Screen Shot 2022-05-01 at 12.06.18 AM.png]] ## [Docs](https://edp.fortanix.com/docs/) ### [Docs > Sealing](https://edp.fortanix.com/docs/concepts/sgx/) Enclaves don't have an intrinsic way to persistently store data. As an alternative, an enclave can obtain a key tied to its own identity and that of the CPU. This key is called a _sealing key_, and it can be used to encrypt data in such a way that it can only later be decrypted by the exact same enclave program running on the exact same CPU. If the program changes, the enclave identity is different, and the sealing key will be different. If the program runs on a different CPU, the CPU identity is different, and the sealing key will again be different. The sealing key can be used to perform authenticated encryption on data. The encrypted data, the _sealed blob_, can then be handed to an untrusted service for persistent storage. Later, an enclave application can request the sealed blob from the service and decrypt it. With the Fortanix EDP, you write your enclave like you would any other application, starting with a main function: ```rust fn main() { println!("Hello, world!"); } ``` The EDP provides all the necessary abstractions and interfaces to launch the enclave and take the output from the enclave and send it to the OS. In this case, that means taking the string `Hello, world!` and printing it to the terminal. This simple example showcases the power of the different components of the EDP, shown in this diagram: ![[Pasted image 20220412173859.png]] The [usercall interface (see below)](https://edp.fortanix.com/docs/concepts/architecture/#usercall-interface) is implemented inside the enclave directly in Rust's standard library. This means you can use most of the primitives you're used to, such as collections and networking. The small changes to support enclaves are explained in [_Using Rust's `std`_](https://edp.fortanix.com/docs/concepts/rust-std/). Outside the enclave, the [`enclave-runner` crate](https://edp.fortanix.com/docs/api/enclave_runner/) takes care of loading the enclave. Once the enclave is loaded, it provides a shim layer between the usercalls coming from the enclave, and the system calls needed to talk to the outside world. `ftxsgx-runner` is an executable based on `enclave-runner` which should be suitable for most enclave applications. However, you can easily implement your own runner using the [`enclave-runner` crate](https://edp.fortanix.com/docs/api/enclave_runner/). ### Service architecture EDP applications should be thought of as providing a service to other parts of your system. An EDP application might interact with other services which themselves might be EDP applications. The service may be implemented as a gRPC server, an HTTPS server with REST APIs, or any other service protocol. To ensure that a client can verify it's talking to a legitimate enclave service, it's imperative that the client set up a secure channel directly with the enclave, and that it authenticate the server using remote attestation. Both the establishment of the secure channel and the authentication can be provided by TLS. See the [examples chapter](https://edp.fortanix.com/docs/examples/tls/) on how to run a TLS server inside the enclave. ### Usercall interface Just like a normal OS, the Fortanix EDP defines an API and ABI that applications use to interact with the environment. Just like most Linux programmers will never call the `syscall` function, EDP programmers will generally not need to dive into the specifics of usercalls. [The usercall API](https://edp.fortanix.com/docs/api/fortanix_sgx_abi/) has been specifically designed for use with SGX and consists of less than 20 calls. Common patterns such as buffer-passing are implemented consistently across all the calls. The interface is kept small intentionally to aid security audits. The interface has been specifically designed to avoid known attacks on enclave interfaces, such as Iago attacks and information leakage through structure padding. In addition, [the Rust type system is used](https://edp.fortanix.com/docs/api/std/os/fortanix_sgx/usercalls/alloc/) to disallow direct access to user memory from the enclave and avoid TOCTTOU issues. ## [Website](https://edp.fortanix.com/) - SGX secures from outside, - Rust secures from inside. - Build once, run anywhere. - Build using standard Rust. - No need to partition your code. - Just compile for SGX. ### Be secure with the Rust programming language The code you put in a secure enclave is the most security-critical part of your application. That code should be written in a language that is reliable. Rust's advanced static analysis built right into the compiler makes it easy to have confidence in the security of your program. ### Compatible with existing Rust code The Fortanix EDP is fully integrated with the Rust compiler. Rust code that doesn't link to native libraries and that doesn't use processes or files should compile out of the box. If new features are added to the Rust language in a new compiler release, you'll be able to use them immediately. Thanks to Rust's stability guarantee, old code will always continue to work after upgrading your compiler. ### Easy to Use Rust EDP applications are just like native applications. They have a main function, can have multiple threads, and can make network connections. You don't have to write any “untrusted” code that runs outside the enclave, this is all provided for you. ### Designed for SGX The Fortanix EDP gives you full access to SGX features. It comes with crates that are designed to make the most out of running on the SGX platform. ### Battle Tested Rust EDP is what Fortanix uses in-house for various products, such as the award-winning Data Security Manager (DSM). Our years of experience running secure enclaves in production have informed the design of the EDP to fit application developers's needs. ### Portable Build your code once, and run it on all supported operating systems and hardware platforms. ### Designed for Network Services Runtime Encryption®'s ability to operate in untrusted environments shines in the cloud. With Rust EDP, you can take your existing Rust microservice and compile and run it in SGX in no time. ### Code example ```rust use sgx_isa::{Report, Targetinfo}; /// A simple TCP server that will generate local attestations on request. fn main() -> io::Result<()> { for stream in TcpListener::bind("localhost:0")?.incoming() { let mut stream = stream?; // Read targetinfo from stream let targetinfo: Targetinfo = read_targetinfo(&mut stream)?; // Issue local SGX attestation report (uses EREPORT instruction) let report = Report::for_target(&targetinfo, &[0; 64]); // Write report to stream stream.write_all(report.as_ref())?; } Ok(()) } ``` ### Compatible with existing Rust code - The Fortanix EDP is fully integrated with the Rust compiler. - Rust code that doesn't link to native libraries and that doesn't use processes or files should compile out of the box. ```rust extern crate serde; use serde::{Serialize, Deserialize}; /// This example, uses a simple structure `Point` that is /// serialized and deserialized to `JSON` using Rust's serde. #[derive(Serialize, Deserialize, Debug, PartialEq)] struct Point { pub x: i32, pub y: i32, } impl Point { fn as_json(&self) -> String { serde_json::to_string(&self).unwrap() } fn from_json(s: &str) -> Self { serde_json::from_str(s).unwrap() } } ```