Writing Enclave Functions
Describe each function that may be called from outside of the enclave in the .edl file.
The functions can use special versions of the C/C++ runtime libraries (available in the SDK).
System calls are not allowed (use
ocallsinstead; C linkage only!).Not all C/C++ language features are available!
The
sgx_edger8rtool will take care of the details of making the execution flow enter or leave an enclave.Pointer arguments in
ecallfunctions must point to untrusted memory.Pointer arguments in
ocallfunctions must point to trusted memory.You may need to copy the buffer from untrusted memory to trusted memory.
Keep in mind that the enclave will be statically linked.
Some available trusted libraries
libsgx_tstdc.a(standard C library, math, strings, etc.).libsgx_tcxx.a(standard C++ libraries, STL)libsgx_tservice.a(seal/unseal, EC DH library, etc.)libsgx_tcrypto.alibsgx_tkey_exchange.alibsgx_tpcl.a(Protected Code Loader, for enclave code confidentiality).
One enclave function printf_helloworld prints the text "Hello World".
It cannot do this directly, so it calls an untrusted function, ocall_printf_string to do the actual printing.
In this example, for the enclave code, the printf function is re-implemented so that its output goes to a string.
In the untrusted part, the enclave is loaded and the printf_helloworld function is called.
List of files.
MakefileApp/App.cppApp/App.hEnclave/Enclave.config.xmlEnclave/Enclave.cppEnclave/Enclave.edlEnclave/Enclave.hEnclave/Enclave.ldsEnclave/Enclave_private.pem
Relevant parts of the Makefile:
SGX_SDK ?= /opt/intel/sgxsdkSGX_MODE ?= HWSGX_ARCH ?= x64SGX_DEBUG ?= 1
You can also add:
SGX_PRERELEASE ?= 0
List your untrusted source code files (the application) in the ######## App Settings ######## section.
List your trusted source code files (the SGX enclave) in the ######## Enclave Settings ######## section.
Relevant parts of
App/App.h
#include "sgx_error.h" /* sgx_status_t */
#include "sgx_eid.h" /* sgx_enclave_id_t */
# define TOKEN_FILENAME "enclave.token"
# define ENCLAVE_FILENAME "enclave.signed.so"
extern sgx_enclave_id_t global_eid; /* global enclave id */App/App.cpp
int initialize_enclave(void) { /*...*/ }
void ocall_print_string(const char *str){ printf("%s",str); }
int SGX_CDECL main(int argc, char *argv[])
{
if(initialize_enclave() < 0) return -1;
printf_helloworld(global_eid);
sgx_destroy_enclave(global_eid);
}Enclave/Enclave_config.xml
<EnclaveConfiguration>
<ProdID>0</ProdID>
<ISVSVN>0</ISVSVN>
<StackMaxSize>0x40000</StackMaxSize>
<HeapMaxSize>0x100000</HeapMaxSize>
<TCSNum>10</TCSNum>
<TCSPolicy>1</TCSPolicy>
<DisableDebug>0</DisableDebug>
<MiscSelect>0</MiscSelect>
<MiscMask>0xFFFFFFFF</MiscMask>
</EnclaveConfiguration>Enclave/Enclave.edl
enclave {
trusted {
public void printf_helloworld();
};
untrusted {
void ocall_print_string([in,string] const char *str);
};
};Enclave/Enclave.h
#include <stdlib.h>
#include <assert.h>
#if defined(__cplusplus)
extern "C" {
#endif
void printf(const char *fmt, ...);
void printf_helloworld();
#if defined(__cplusplus)
}
#endifEnclave/Enclave.cpp
##include <stdarg.h>
#include <stdio.h> /* vsnprintf */
#include "Enclave.h"
#include "Enclave_t.h" /* print_string */
void printf(const char *fmt, ...) { char buf[BUFSIZ];
va_list ap; va_start(ap, fmt);
vsnprintf(buf, BUFSIZ, fmt, ap);
va_end(ap); ocall_print_string(buf); }
void printf_helloworld() { printf("Hello World\n"); }Last updated