White Paper
Intel® Software Guard Extensions (Intel® SGX)
Protected File System with Intel® Software
Guard Extensions (Intel® SGX) on
Microsoft* Windows*
Scope
This article explains how to use the Intel® Protected File System (IPFS) library in Intel® Software Guard Extensions (SGX) enclaves on
Microsoft* Windows*. General information on Intel SGX can be found on the Intel SGX portal at: [Link]
Introduction
Some of the new features included in Intel SGX SDK V1.7 for Microsoft Windows are:
C Universal Run Time library support
C++ 11.0 feature support
Intel Protected File System (IPFS) Library support
The IPFS library can be used to create/delete, and operate on files from inside an enclave. The following subsections discuss the
architecture, API’s, implementation, and limitations of the IPFS library.
Intel Protected File System library overview
The IPFS library provides a protected file API for use in Intel SGX enclaves. This API supports a basic set of 15 standard C file
functions that allow applications to create/delete, and perform typical operations on files in a manner similar to a non-SGX
application in most respects.
Unlike typical file operations, however, files controlled by this library are automatically encrypted using a 128-bit key before being
saved on the untrusted disk during a write operation. During file reads, these files are verified for confidentiality and integrity and are
decrypted.
To support this file protection, the application must provide an initial 128-bit key for use as a key derivation key, to generate multiple
encryption keys. This key derivation key must be a cryptographic key. The key can be either provided by the developer or Automatic
Keys can be derived from the enclave sealing keys. (Information on cryptographic keys can be found in NIST definitions 800-108 at:
[Link]
To make use of the IPFS library in development, you need the following:
Microsoft* Visual Studio* 2015
Intel SGX SDK version V1.7
To make use of the IPFS library on a production machine, you need the following:
Intel SGX enabled machine (CPU and BIOS support Intel SGX and it is enabled in BIOS)
Intel SGX PSW (Platform SW) V1.7
Your application that includes the IPFS library
IPFS application layout
Figure 1 shows a block diagram of an Intel SGX enabled application that uses the IPFS Library. Note that some of the library resides
in the untrusted part of the application and some resides in the trusted part.
1
White Paper | Intel® SGX
Figure 1: Intel SGX protected file system - system architecture diagram
Let’s examine an application that uses an enclave for saving cryptographic keys and doing cryptographic operations.
The untrusted part of the application contains the code that requests the enclave to do things like signing plaintext with an
existing key ID, create a new key (and get a key ID), etc. These requests are made using ECALLs. This part of the application only
knows about key IDs, as it does not have access to actual keys.
The trusted part of the application is a Key Storage Enclave (KSE) that manages keys. This part of the application implements
ECALLs from the untrusted part of the application and returns data/status to the untrusted caller. It calls the trusted part of the
IPFS library when needed to save and restore keys, via a trusted API, with C-like calls such as sgx_fopen(), sgx_fwrite(),
etc.
The trusted part of the IPFS library handles calls from the KSE, performs encryption/decryption on IPFS files, and makes OCALLS
to the untrusted part of the IPFS library for reads/writes to untrusted system storage.
The untrusted part of the IPFS library contains the code that implements OCALLs from the enclave related to the actual
reading/writing of IPFS files.
The untrusted part of the application must include the untrusted part of the IPFS library and the trusted part of the application must
include the trusted part of the IPFS library.
IPFS control flow
IPFS control between from the Intel SGX Application and the enclave occurs as follows:
1. The untrusted part of the application requests an action from the enclave via an ECALL. Let’s say this action is the signing of
some plaintext with a key whose key ID the application already knows. It passes the plaintext and key ID in the call.
2. Inside the enclave, the trusted part of the application receives the ECALL. It checks its storage and determines that the key
associated with the key ID is not already loaded. So it makes a call to trusted part of the IPFS library to open the IPFS file, using a
trusted sgx_fopen() call.
3. The trusted part of the IPFS library makes a corresponding OCALL to the untrusted part of the IPFS library to open the file.
4. The untrusted IPFS library receives the OCALL, opens the file, and returns control to the trusted IPFS library in the enclave,
which returns control to the trusted application code in the library. (If the operation fails, for example, because the file does not
exist, an error code is returned all the way to the untrusted caller in Step 1.)
5. If the operation succeeds, the trusted part of the application makes an sgx_fread() call to read the data from the file.
6. The trusted part of the IPFS library again makes an OCALL to the untrusted part of the IPFS library, this time to read the data.
2
White Paper | Intel® SGX
7. The data is read by the untrusted part of the IPFS library and passed back to the enclave. (Again, if the operation fails, an error
code is returned instead.)
8. The trusted part of the IPFS library decrypts the data and passes it to the trusted part of the application.
9. The trusted part of the application signs the plaintext from Step 1 and returns the signature back to the untrusted part of the
application.
IPFS API
The PFS Library provides the following 15 C-like functions:
sgx_fopen(): Opens or creates a file using the 128-bit key provided by the application.
Return type: Returns a file handle of the type SGX_FILE pointer, otherwise NULL is returned.
sgx_fopen_auto_key(): Opens or creates a file by the key generated from the Enclave sealing key itself.
Return type: Returns a file handle of the type SGX_FILE pointer, otherwise NULL is returned.
sgx_fclose(): Closes a Protected File handle only when opened through sgx_fopen() or sgx_fopen_auto_key().
Return type: Returns 0 if file successfully closed, else returns 1.
sgx_fread(): Reads the requested amount of data from the file and extends the pointer by that amount.
Return type: Returns the no. of blocks of size read from the file of type size_t.
sgx_fwrite(): Writes the given amount of data to the file and extends the file pointer by that amount.
Return type: Returns the no. of blocks of size written to the file of type size_t.
sgx_fflush(): Saves the changes done to a file and ensures that the changes are committed to the file.
Return type: Returns 0 if successful and 1 if not successful.
sgx_ftell(): Returns an indicator that points to the current position in the file.
Return type: Returns the current value of the position indicator of the file if successful, otherwise, -1 is returned.
sgx_fseek(): Sets the current value of the position indicator of the file.
Return type: Returns 0 if successful, otherwise -1 is returned.
sgx_feof(): Specifies whether the file position pointer has reached the end of file in the previous read operation.
Return type: Returns 0 if end of file was NOT reached, otherwise 1 is returned if End-of-File is reached.
sgx_ferror(): Returns the latest operation error code.
Return type: Returns 0 if no errors, else returns the respective error code.
sgx_clearerr(): Attempts to repair a bad file status, and also clear the end of file flag.
Return type: None
sgx_remove(): Deletes a file from the file system.
Return type: Returns 0 if successful, otherwise 1 is returned.
sgx_fexport_auto_key(): Exports encrypted file created with an automatically generated key for transferring the file to another
machine.
Return type: Returns 0 if successful, otherwise 1 is returned.
sgx_fimport_auto_key(): Imports encrypted file created on another machine, which was encrypted using a key automatically
generated by the source machine.
Return type: Returns 0 if successful, otherwise 1 is returned.
sgx_fclear_cache(): Clearing the internal file cache. Scrubs cache and releases all data.
3
White Paper | Intel® SGX
Return type: Returns 0 if successful, otherwise 1 is returned.
These 15 functions are present in the IPFS trusted library and can only be called within the trusted enclave code.
IPFS implementation in Microsoft Visual Studio*
To create an application that implements Intel SGX IPFS library support, follow these steps:
1. Created the Intel SGX application and the enclave with the required trusted and untrusted libraries.
2. In Visual Studio, add the trusted IPFS library and link it with the enclave. This is done by adding sgx_tprotected_fs.lib
using the Visual Studio Project Properties options, as follows:
LinkerInputAdditional Dependencies<Edit…>
3. Similarly the untrusted IPFS library must be added and linked with the untrusted application source. This is done by adding the
sgx_uprotected_fs.lib using the Visual Studio Project Properties options, as follows:
LinkerInputAdditional Dependencies<Edit…>
3. The enclave’s EDL must import all the functions defined in the sgx_tprotected_fs.edl. The EDL can be imported using the
following command:
from "filepath/sgx_tprotected_fs.edl" import *;
4. Include the sgx_tprotected_fs.h header file in the enclave source file as follows:
#include “sgx_tprotected_fs.h”
Demonstration Console Application
A sample Console Application, named [Link], is provided with the IPFS library to demonstrate the Intel SGX
Protected File System. Figure 2 shows the Console Application screen after a simple write and read of string content to/from a file
created using Intel SGX protected file system.
Figure 2: Intel SGX protected file system – Console Application screen
4
White Paper | Intel® SGX
File transfer using IFPS API automatic keys
It is also possible to transfer files from one enclave to another enclave in the same machine or in different machines, using Automatic
Key API functions. Automatic Keys are derived from the enclave sealing key (with MRSIGNER), so the files are bound to all the
enclaves signed by the same signer on a particular machine.
To transfer files from one system to other, follow these steps:
1. Close all open handles to the file using sgx_fclose().
2. Call the sgx_fexport_auto_key() API. This function returns the latest encryption key that was used to encrypt the metadata
node of the file. (This encryption key will be sent to the destination enclave.)
3. Transfer the file to the destination enclave, and provide the encryption key in a safe method to that same enclave.
4. Call the sgx_fimport_auto_key() API. This function decrypts the previously encrypted file using the auto key that was sent.
Then it re-encrypts the metadata node with a new encryption key, derived from the local enclave seal key.
5. Open the file using sgx_fopen_auto_key(). This function opens the file using the newly-generated auto key.
Note: Attempting to open a file (created on one machine) on a different machine will fail, unless the steps provided above are
followed. This means that automatic disaster recovery may not work properly in this scenario.
Limitations of IPFS
Only one file handle can be opened for writing at any point in time (although multiple read handles can be used for reads at the
same time).
OS mechanisms are used to prevent the creation of more than one write file handle for a file. If this is violated somehow, the files
gets corrupted and cannot be opened.
If two files are created with the same name, a swapping attack is possible where the two files contain difference contents.
Summary
The Intel Protected File System library is a new feature introduced in Intel SGX SDK 1.7 Release. This library is used to create/delete
and operate on files from inside an Intel SGX enclave. Developers must add the essential libraries, header, and EDL files to the
application and enclave to invoke the supported APIs. The library supports a trusted API that provides functionality similar to typical
C language file handling functions, but provide encryption and decryption.
Using the IPFS library, files are encrypted/decrypted using keys provided by the enclave or the application to keep the content safe
and secure. IPFS also provides the support for transferring the Intel SGX protected file from one enclave to another enclave in the
same machine or different machine.
Given the IPFS limitations, developers should also be careful while performing read and write operations on the files and protect
against possible corruptions/attacks.
References
1. “Intel SGX SDK Developer Reference for Windows OS” ver 1.7 — 2016 Intel Corporation.