=============== Enclave Example =============== :Date: 2018-06-06 :page_order: -1 Now let’s start with an enclave Hello world coding example. Code is available under HelloEnclave `here `__. It is a simplified version of SampleEnclave example at Linux SGX SDK. .. raw:: html The ``App.h`` head file defines the application we are going to create. Here, enclave initialization token is define as the ``enclave.token`` file and the signed enclave shared object after compilation will be ``enclave.signed.so`` (line 52, 53). A global ``sgx_enclave_id_t`` is also declared to uniquely identify the enclave (line 55). Now let’s move to ``App.cpp``. .. raw:: html As it is in the untrusted application, we must include ``sgx_urts.h``, the SGX untrusted runtime system, for SGX to work correctly with the application. We also include ``Enclave_u.h``, which will include all of the ECALL proxies generated from the EDL file after compilation. Line 48-150 just summarize all the possible error code caused by enclave operation. The critical function here is ``initialize_enclave(void)`` at line 157. It first retrieves the launch token from previous transactions if available. If not, just use an empty buffer to record it. Then it calls ``sgx_create_enclave()`` function provided by urts library to officially initialize the enclave instance. The ``sgx_create_enclave()`` will performs an implicit ECALL. The implicit ECALL initiates enclave runtime initialization flow described in the Enclave Lifecycle tutorial. The actual enclave instance shared object will be saved as ``enclave.signed.so``, which is signed by the CPU as indicated by the filename. And the enclave id will be saved in ``global_eid`` for future access. We can ignore the ``ocall_print_string()`` function as it was in the original sample code. In the main body of the application, we first initialize the enclave by calling ``initialize_enclave()``. Then call our printf_helloworld() function, which will be discussed later. Finally, we destroy the enclave instance by calling ``sgx_destroy_enclave()`` provided by urts library. It will perform the implicit ECALL that performs instructions that destry the targeted enclave. Since our purpose of this example application is to print something from the enclave instead from the untrusted application directly, the enclave part should only contain the function that performs this task. .. raw:: html The enclave header file declares the ``printf_helloworld()`` function, which will be responsible for our purpose. This function call will be protected by the enclave so outside world won’t know the secret being processed. But for demonstration purposes, we will just print out the secret from the enclave to the screen by calling this function. .. raw:: html We define the ``printf_helloworld()`` function as a part of the enclave protected code path, which just prints out ``Hello World`` to the console. In reality, the secret string should be passed into the enclave from outside world, and will be protected by the enclave. Now since the untrusted application cannot access the enclave content directly, in order for the untrusted function to call enclave functions, we have to rely on the assistance of proxy functions, which will be generated by the Edger8r tool from EDL file after compilation.  The proxy functions are responsible for: - Marshaling 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 an ``sgx_status_t`` value Note that this means each ECALL or OCALL has potentially two return values. There’s the success of the ECALL or OCALL itself, meaning, were we able to successfully enter or exit the enclave, and then the return value of the function being called in the ECALL or OCALL. Additional arguments will added to the parameter list for each proxy function and the proxy functions now return a type of ``sgx_status_t`` instead of the original return types. The first additional parameter is the enclave identifier, eid. The second argument to the proxy function is a pointer to an address that will store the return value from the original enclave function if it has a return value. Since our \ ``printf_helloworld()`` function does not have a return value, the proxy function generated for it will look like  .. raw:: html We can verify that after compiling the whole project. Therefore, in order to let the ``Edger8r`` generate the corresponding proxy functions, we put our function ``printf_helloworld()`` in the trusted section of ``Enclave.edl``.  .. raw:: html By now, the whole hello world application has acquired all the required parts and should be ready to go. Compile the project by typing ``make`` inside project directory. It should output something like this: |Enclave Example| Then execute the application by typing ``./app``. ``Hello World`` should be printed to the console. And the message is coming form within the enclave to the outside world! We can verify the proxy function generated in ``Enclave_u.c`` has the signature mentioned above (line 21). .. raw:: html Congratulations you have created your first enclave application! .. |Enclave Example| image:: /assets/sgx101_pic/enclave_example.png