Intel® Software Guard Extensions (Intel® SGX)
Discussion board focused on hardware-based isolation and memory encryption to provide extended code protection in solutions.

Understanding Sample Common Loader's enclave blob

Nguyen__Minh
Beginner
1,408 Views

Hi,

I have been digging around and the only information I have is on the Enclave Common Loader APIs. Is there any information about the sample's enclave blob and what kind of enclave code does it have ? When the EENTER is executed, the execution flow goes back to the untrusted code async_exit so I am quite confused whether there is enclave code inside the enclave.

 

Best regards,

Minh

0 Kudos
7 Replies
JesusG_Intel
Moderator
1,408 Views

Hello Minh,

The enclave code in this sample doesn't actually do anything. Notice there is no EDL file because there are no ecalls or ocalls. The README.txt file states:

The project demonstrates how to use these Enclave Common Loader Layer APIs: 
- enclave_create
- enclave_load_data
- enclave_initialize
- enclave_delete

Regards,

0 Kudos
Nguyen__Minh
Beginner
1,408 Views

Hi Garcia !

 

Thank for your prompt reply! I understood your explanation. Then, how can we confirm whether the enclave is setup correctly without entering the enclave itself to execute some enclave code ? From my knowledge, unrecoverable exceptions in the enclave will also get us back to the AEP, which might indicate that the enclave is not correctly setup. Is there any published document about how to build and modify this enclave blob ?

 

Best regards,

Minh

0 Kudos
JesusG_Intel
Moderator
1,408 Views

Hello Minh, each of the enclave APIs has a parameter for enclave_error that receives error codes from the enclave. You can see how it is used in this code snippet

uint32_t enclave_error = ENCLAVE_ERROR_SUCCESS;
void *enclave_base = enclave_create(NULL, (size_t)secs->size, sgx_enclave_blob_length, ENCLAVE_TYPE_SGX1, &create_ioc, sizeof(create_ioc), &enclave_error);
if (enclave_error)
 {
     printf("create enclave error! error code - %#x\n", enclave_error);
     return false;
 }

Unfortunately, there is no documentation available for how to create that enclave blob. It looks like you have to somehow capture the assembly output from the compiler after you compile your enclave code.

Regards,

0 Kudos
Nguyen__Minh
Beginner
1,408 Views

Hi Garcia,

Thank you very much for your help! I have final question about EENTER here and would appreciate your helps!

 

I executed  the common loader program in sgx-gdb. When EENTER is executed in single step, the next instruction is the instruction after the EENTER. I observed that some registers are changed right after EENTER instruction is executed (such as RAX is set to 0x4). I also observed that the register states are very similar to ones after we execute an EEXIT. However, the control flow did not transfer to enclave code like normal EENTER would do.

So, my question is "Did the enclave code (e.g., enclave_entry routine in SGXSDK) get executed at all?" or is there some hidden link between EENTER and EEXIT when EENTER miss behaves ?

Best regards,

NGUYEN Hoang Minh

0 Kudos
JesusG_Intel
Moderator
1,408 Views

Hello Minh,

Which part of the code are you stepping into? Since there is no documentation for this sample it is impossible to know what is going on by looking at it. We will find out from engineering what it actually does.

Regards,

0 Kudos
Nguyen__Minh
Beginner
1,408 Views

My testing target is the ENCLU instruction located in the sgx_get_token function. So I set breakpoint at the ENCLU instruction. The function is as follows:

.text
    .global sgx_get_token
sgx_get_token:
    EENTER_PROLOG

    mov $0x2, %rax
    mov %rsi, %rbx
    mov frame_arg0, %rdi
    lea_pic sgx_async_exit, %rcx
sgx_async_exit:
    enclu
    nop

I intentionally added a NOP at the end of the ENCLU[ENTER] for indexing the returning instruction outside of enclave. Before executing the ENCLU[ENTER], the register states are as follows:

rax            0x2      2
rbx            0x7ffff7fb0000   140737353809920
rcx            0x555555555719   93824992237337
rdx            0x7ffff7fd8180   140737353974144
rsi            0x7ffff7fb0000   140737353809920
rdi            0x0      0
rbp            0x7fffffffcc40   0x7fffffffcc40
rsp            0x7fffffffcbf0   0x7fffffffcbf0

The RAX indicates EENTER, the RBX points to TCS VA, RCX points to the AEP. Dumping the content of TCS, I have this:

0x7ffff7fb0000: 0x0000000000000000      0x0000000000000000
0x7ffff7fb0010: 0x0000000000004000      0x0000000100000000
0x7ffff7fb0020: 0x0000000000001686      0x0000000000000000
0x7ffff7fb0030: 0x0000000000000000      0x0000000000000000

The TCS information tells us that stage is 0, flags are 0, OSSA is at offset 0x4000, CSSA is 0, NSSA is 1, and the OENTRY is at offset 0x1686. So I was expecting the enclave code is located at 0x7ffff7fb1686 and EENTER should transfer the control flow to that entry. However, when I tell the gdb to step in with "si", the next instruction is the NOP and the register states are as follows:

rax            0x4      4
rbx            0x55555555571c   93824992237340
rcx            0x555555555719   93824992237337
rdx            0x0      0
rsi            0x0      0
rdi            0x0      0
rbp            0x7fffffffcc40   0x7fffffffcc40
rsp            0x7fffffffcbf0   0x7fffffffcbf0

The RAX seems to indicate there was an EEXIT and RBX points to the next instruction after ENCLU, which is the NOP instruction. And RCX is indeed the AEP. This makes me think that the code inside the enclave was executed and then an EEXIT was triggered. However, the control flow did not transfer to the code inside the enclave. So there is a conflict.

Best regards,

Minh

0 Kudos
JesusG_Intel
Moderator
1,405 Views

Hello,


I heard back from engineering. sgx-gdb requires the debug versions of uRTS and tRTS. In the SampleCommonLoader, there is no uRTS or tRTS so you cannot debug into the enclave.


Regards,


0 Kudos
Reply