Looking for enclaive's confidential multi-cloud solution. Click here.


Get­ting Start­ed: Key Vault with Intel SGX SDK


This arti­cle aims at intro­duc­ing the new pro­gram­ming par­a­digm of secure enclaves enabled by Intel’s SGX tech­nol­o­gy. I will give a tuto­r­i­al of imple­ment­ing a key vault with sign­ing capabilites.

Set up the devel­op­ment environment

To devel­op appli­ca­tions with Intel SGX fol­low­ing soft­ware com­po­nents are required:

● Visu­al Studio

● Intel SGX SDK

● Intel SGX Plat­form Soft­ware (This is need­ed to exe­cute SGX applications)

SGX appli­ca­tions can be devel­oped and debugged with­out SGX hard­ware. A sim­u­la­tor is shipped with the SGX SDK.

Let’s say hel­lo to the Enclave World

Appli­ca­tions devel­oped for SGX need to incor­po­rate spe­cial con­sid­er­a­tions. SGX appli­ca­tions are divid­ed into two parts. The trust­ed part of an SGX appli­ca­tion is exe­cut­ed with­in the enclave, while the untrust­ed part is exe­cut­ed out­side. All parts of the appli­ca­tion deal­ing with sen­si­tive data need to be placed with­in the trust­ed part.

Between the trust­ed and untrust­ed part an inter­face is imple­ment­ed. This inter­face con­sists of e‑calls and o‑calls. E‑calls are func­tions with­in the enclave called from untrust­ed code, mean­while o‑calls are func­tions of the untrust­ed code called from with­in the enclave.

These inter­faces are defined with a spe­cial file for­mat, called the EDL-file. Inter­faces are defined by their sig­na­ture. The sig­na­ture is assigned to the trust­ed part of the appli­ca­tion if it is an inter­face of the enclave. Oth­er­wise it is assigned to the untrust­ed part.

Spe­cial con­sid­er­a­tions need to be tak­en for buffers or point­ers passed as para­me­ters. With­in the squared brack­ets in front of a para­me­ter the direc­tion and the size of a buffer are defined. On the trust­ed site enclave inter­face buffers with the direc­tion “in” are read from the nor­mal appli­ca­tion mem­o­ry to the enclave mem­o­ry, while the direc­tion “out” results in data being passed from enclave mem­o­ry to the nor­mal appli­ca­tion. Untrust­ed inter­face direc­tions are oppo­site to their trust­ed equivalents.


The first step of the imple­men­ta­tion is to set up two projects in Visu­al Stu­dio. An C++-application con­tain­ing the untrust­ed code and a sep­a­rate project for the enclave. The Intel SGX SDK pro­vides a wiz­ard for Visu­al Stu­dio that sets up the enclave project correctly.

After cre­at­ing the projects, the EDL file needs to be filled with the inter­faces. These inter­faces need to be imple­ment­ed with­in the enclave and inside the nor­mal application.

From with­in the appli­ca­tion SGX needs to be enabled with:

Fur­ther the enclave must be cre­at­ed, with signed library com­piled from the enclaves code:

Now the enclave can be used by call­ing any of the enclaves e‑calls.

The usage of e‑calls dif­fers from call­ing nor­mal meth­ods. Two addi­tion­al para­me­ters have to be pro­vid­ed, first the id of the enclave (eid) and a point­er to a vari­able that will hold the result of the e‑call. The actu­al return val­ue of the e‑call will only indi­cate, whether the e‑call itself was suc­cess­ful, which does not nec­es­sar­i­ly indi­cate the suc­cess­ful execution.

To invoke an o‑call from with­in the enclave, the cor­re­spond­ing method has to be defined in our untrust­ed appli­ca­tion, after that it can be called like a nor­mal function.

Exam­ple: Sig­na­ture Key Vault

As an exam­ple, an appli­ca­tion to sign mes­sages with ECDSA (Ellip­tic Curve Dig­i­tal Sig­na­ture Algo­rithm) will be devel­oped. All cryp­to­graph­ic func­tion­al­i­ty like key gen­er­a­tion, sign­ing and ver­i­fi­ca­tion will be han­dled with­in the enclave. Pri­vate keys will only be stored with­in the enclave or sealed and stored on the filesys­tem. That means untrust­ed code don’t has access to it. All cryp­to­graph­ic func­tion­al­i­ty will be imple­ment­ed with the help of SGXs cryp­to­graph­ic API.


The enclave pro­vides five inter­faces, named: esv_init, esv_sealkeys, esv_sign, esv_verify and esv_close. With two inter­faces from the untrust­ed appli­ca­tion esv_read_data and esv_write_data, the enclave is able to read and write files.


Esv_init ini­tial­izes every­thing nec­es­sary to use the sign­ing and ver­i­fy­ing inter­faces. It receives a option­al file­name for load­ing sealed keys from filesystem.

First the con­text for the ellip­tic curve cryp­tog­ra­phy is retrieved. This con­text has to be used with all calls to cryp­to­graph­ic meth­ods for ellip­tic curves.

If a file name was pro­vid­ed (sealed_data_file), the file is loaded with the o‑call esv_read_data. Then the data is copied into the mem­o­ry of the enclave, unseal­ing can­not work if the pro­vid­ed buffer is locat­ed out­side of the enclave. The size of the unsealed data is deter­mined with sgx_get_encrypt_txt_len, which result is used to reserve a buffer for the unsealed data. After the buffer is allo­cat­ed the data is unsealed and writ­ten into the des­tined buffer.

If no sealed data is pro­vid­ed, a new key pair (pub­lic, pri­vate key) is gen­er­at­ed with sgx_ecc256_create_key_pair.

Either way the pub­lic and pri­vate key are stored in glob­al vari­ables of the enclave.


Esv_sign receives as para­me­ters a mes­sage to sign. The mes­sage is passed on to sgx_ecdsa_sign, which signs the mes­sage and saves the sig­na­ture in the pro­vid­ed sig­na­ture buffer. The sig­na­ture is saved to a file with the file­name con­sist­ing of the mes­sage and the exten­sion “.sig”. It should be not­ed that strings passed as para­me­ters to o- and e‑calls can­not be altered in size, oth­er­wise the method will crash when return­ing. There­fore the file­name is cre­at­ed with snprintf and saved to a new string. The o‑call esv_write_data is used to write to the file. For the sake of sim­plic­i­ty we use only strings in our exam­ple but you could of course also sign oth­er forms of data.


Esv_verify takes a mes­sage and its sig­na­ture. The sig­na­ture for the mes­sage is then verified.

The method sgx_ecdsa_verify exe­cutes the sig­na­ture ver­i­fi­ca­tion, its result is returned by the ecall. If the sig­na­ture is valid, the result will be zero, oth­er­wise unequal to zero.


Esv_seal_keys saves the cur­rent pub­lic and pri­vate key stored in the enclave to a file. We use a data struc­ture for that, called “esv_sealed_data_t”. The file­name is pro­vid­ed as para­me­ter. To avoid third par­ties from out­side the enclave to access the keys, they are sealed with SGXs data seal­ing feature.

First the size of the sealed data is cal­cu­lat­ed with sgx_calc_sealed_data_size. Then a cor­re­spond­ing buffer is allo­cat­ed. With sgx_seal_data the data is encrypt­ed and saved to the allo­cat­ed buffer. If the seal­ing was suc­cess­ful the data is saved to a file, with the o‑call esv_write_data.

If the appli­ca­tion ends you can use the method sgx_destroy_enclave to destroy an enclave and release its asso­ci­at­ed resources and inval­i­dates the enclave ID or handle.

Contact us

Cookie Consent with Real Cookie Banner