- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
I have setup nodejs and I am using node-gyp (node-api) which allows me to use C++ code with nodejs.
I have two projects within the same solution in Visual Studio. One is Nodejs based and the other is SGX
However, when I use my node-api c++ file to call my create_enclave function which typically sets up the enclave. The enclave fails to create.
I have verified if I try to create the enclave without node being involved then it creates.
So my assumption is that the SGX code somehow knows that is being called from another project and therefore does not allow it.
Is there a way to allow my "external" function to interact with the SGX code so that an enclave is created? I have tried using a proxy that was part of the trusted section in the EDL but that generated the same result.
I got error code 8237. But no other details.
- Tags:
- General Support
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi Scott,
That error code, 8237, which is 0x202D, does not appear to come from SGX.
Please give us more details:
- SGX SDK version
- OS version
- Visual Studio version
- Which function call specifically sent the error code?
- Screenshot of the error
Regards,
Jesus
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Error code changed to #8206.
Don't seem able to add screenshot at present but full text is:
"Failed to create enclave: Error #8206"
Error is returned by this line:
sgx_status = sgx_create_enclave(ENCLAVE_FILE, SGX_DEBUG_FLAG, &launch_token, &updated, &enclaveId, NULL);
1. SGX is 2.7.101
2. Windows 10 64bit
3.VS 2017 Version 15.9.4
Node-Api code:
//Declaring NAPI c++ function Napi::String addition(const Napi::CallbackInfo& info) { Napi::Env env = info.Env(); //std::string arg0 = (std::string) info[0].ToString(); //int result = enc(); string name = (std::string) info[0].ToString(); int n = enc(); //return Napi::String::New(env, name); Napi::String retvals = Napi::String::New(env, name); return retvals; } //Napi object which calls addition function above (initialisation) Napi::Object Init(Napi::Env env, Napi::Object exports) { //Napi exports.Set( Napi::String::New(env, "addition"), Napi::Function::New(env, addition) ); return exports; } //Exposing module to be called by other js files. NODE_API_MODULE(make_sum, Init)
SGX code:
static int create_enclave(sgx_enclave_id_t *eid) { sgx_status = sgx_create_enclave(ENCLAVE_FILE, SGX_DEBUG_FLAG, &launch_token, &updated, &enclaveId, NULL); cout << sgx_status << '\n'; cout << eid << '\n'; if (sgx_status == SGX_SUCCESS) { if (eid != NULL) *eid = enclaveId; cout << eid; launched = 1; return 1; } return 0; }
The enc() function referenced in the node code just runs the above SGX code.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I am just not sure if I can trigger the enclave creation this way.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Scott,
You should be able to create the enclave from your node code.
Error 8206 is 0x200e (hex), which, according to sgx_error.h is SGX_ERROR_MODE_INCOMPATIBLE = SGX_MK_ERROR(0x200e), /* The target enclave 32/64 bit mode or sim/hw mode is incompatible with the mode of current uRTS. */
The SGX Developer Reference states that:
SGX_ERROR_MODE_INCOMPATIBLE: The target enclave mode is incompatible with the mode of the current RTS. For example, a 64-bit application tries to load a 32-bit enclave or a simulation uRTS tries to load a hardware enclave.
Does this help?
Regards,
Jesus
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Oddly, yes. I worked out that the node code was using a library that made it seem like i was trying to run HW mode. So I changed that.
However, new problem. I now have status 7 returned when trying to do the addition with node which i believe maps to error: SGX_ERROR_HYPERV_ENABLED
But I do not have hyper-v enabled. (I double checked in windows features).
Relevant code:
sgx_status_t enclaveAdd(sgx_enclave_id_t eid, int x, int y) { sgx_status_t status; ms_enclaveAdd_t ms; ms.ms_x = x; ms.ms_y = y; status = sgx_ecall(eid, 1, &ocall_table_EnclaveAddition3, &ms); return status; }
Again this is only shown when triggering the enclave via node.
These are the libraries I am using with node for SGX:
"C:\\Program Files (x86)\\Intel\\IntelSGXSDK\\bin\\x64\\Debug\\sgx_urts_sim.lib",
"C:\\Program Files (x86)\\Intel\\IntelSGXSDK\\bin\\x64\\Debug\\sgx_uae_service_sim.lib",
"C:\\Program Files (x86)\\Intel\\IntelSGXSDK\\bin\\x64\\Debug\\sgx_launch_sim.lib",
"C:\\Program Files (x86)\\Intel\\IntelSGXSDK\\bin\\x64\\Debug\\sgx_platform_sim.lib",
"C:\\Program Files (x86)\\Intel\\IntelSGXSDK\\bin\\x64\\Debug\\sgx_quote_ex_sim.lib",
"C:\\Program Files (x86)\\Intel\\IntelSGXSDK\\bin\\x64\\Debug\\sgx_enclave_common.lib",
"C:\\Program Files (x86)\\Intel\\IntelSGXSDK\\bin\\x64\\Debug\\sgx_tservice_sim.lib",
"C:\\Program Files (x86)\\Intel\\IntelSGXSDK\\bin\\x64\\Debug\\sgx_epid_sim.lib"
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi Scott,
I created an enclaveAdd ecall just like you and it works fine without node. I even got the same ecall definition in my enclave_u.c file that you posted (yours is called EnclaveAddition3_u.c). I am not familiar with working with node.js but I will try to help you get to the root of your problem.
To debug, open your EnclaveAddition3_t.c file which you will find in the "Generated Files" of your EnclaveAddition3 project. Insert a breakpoint in the first line of the function "status sgx_status_t SGX_CDECL sgx_enclaveAdd(void* pms). When you execute your application, determine where exactly your error is generated. If you do not reach this breakpoint then your proxy functions in EnclaveAddition3_u.c are not properly calling the proxys in EnclaveAddition3_t.c.
Regards,
Jesus
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I appreciate that.
Running the debug doesn't help as the breakpoints on the sgx side are ignored when I execute the node code.
https://github.com/nodejs/node-addon-api
I'll have to share the code so you can understand the crazy a little better.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
I have changed tactics a little bit and got further with Go.
So, I am at a point when trying to pass ints to the enclave but this seems to fail.
At present I have a 4097 error which matches to SGX_ERROR_INVALID_FUNCTION.
I never seem to reach the enclave code as the string doesn't print out either. I think my problem is with the ecall/ocalls
APP
int test(void) { if (initialize_enclave(&global_eid, "enclave.token", "enclave.signed.so") < 0) { std::cout << "Failed to initialize enclave." << std::endl; return 1; } sgx_status_t ret; int a = 5; int retVal = 0; int some = 1; int s = 0; print_error_message(ret); s=sumAdd(global_eid,&some,a,&retVal); if(!is_ecall_successful(ret,"Failed",ret)); std::cout<<retVal<<"\n"; std::cout<<some<<"\n"; std::cout<<s<<"\n"; print_error_message(ret); return 0; }
EDL
enclave { from "sgx_tae_service.edl" import *; trusted { public int sumAdd(int a,[out] int* res); }; untrusted { /* define OCALLs here. */ void ocall_print_int([in] int* num); void ocall_print([in, string]const char* str); }; };
Enclave
void sumAdd(int a,int *result){ sgx_status_t ret; int busy_retry_times = 2; do { ret = sgx_create_pse_session(); } while (ret == SGX_ERROR_BUSY && busy_retry_times--); if (ret != SGX_SUCCESS) return ret; int b =6; ocall_print("ENCLAVE"); check_sgx_status(ret); sgx_close_pse_session(); *result = 26; return b; }
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi Scott,
I see a few problems.
1. The return type of your ecall function in your EDL file must match the return type in Enclave.cpp/.h. Make your ecall declaration in the EDL file public void sumAdd. It should look like this:
trusted { public void sumAdd(int a, [out] int* res); };
In app.cpp, you are assigning to s the status of the ecall sumAdd. I think you meant to use ret like this:
sgx_status_t ret; ret = sumAdd(global_eid…); if(!is_ecall_successful(ret,"Failed",ret));
If you want to use "s" then "s" should be of type sgx_status_t. Your is_ecall_successfull should check "s" since that is the variable that holds the status of the ecall.
2. When you are calling sumAdd in app.cpp, whether you use four variables or three depends on whether the return type of sumAdd is int or void. If you sumAdd is void, then you do not need to pass the second pointer &some. If your return type is int, then you need &some to hold the returned value from sumAdd.
Here is where things can get tricky.
If you want the return type of sumAdd to be int rather than void, this is how your files must look...
EDL
trusted { public int enclaveAdd(int x, [out] int *res); };
Enclave.h
int enclaveAdd(int x, int *res);
Enclave.cpp
int enclaveAdd(int x, int *result) { *result = x + 10; //this is the [out] variable you declared in the EDL int z = 5; return z + x; //this value gets returned via &resultAdd argument in app.cpp }
App.cpp
In app.cpp, when you call an ecall with a return type other than void, you have to add an extra argument that will hold the returned value. See below how I use &resultAdd to hold the returned value from sumAdd. If your return type is void, then you do not need this extra argument.
int x = 2; int retVal = 0; int resultAdd; //this will hold the return value from enclaveAdd sgx_status_t ret; ret = enclaveAdd(global_eid, &resultAdd, x, &retVal); //&resultAdd holds value returned via the return statement in eclave.cpp
After this code runs the values are:
resultAdd = 7 //z + x = 5 + 2 from enclave.cpp retVal = 12 //2 + 10 from enclave.cpp
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
So I modified the code to mirror yours but for some reason I don't get the same results.
resultAdd returns different values each time similar to this 32583
retVal returns 0
It's as if the pointers are never updated.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hello Scott,
Please send the relevant code from EDL, enclave.cpp, and app.cpp.
Regards,
Jesus
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Sure, thank you for your help thus far.
app.cpp
int test() { if (initialize_enclave(&global_eid, "enclave.token", "enclave.signed.so") < 0) { std::cout << "Fail to initialize enclave." << std::endl; return 1; } int x = 5; int retVal = 0; int resultAdd; sgx_status_t ret; ret = sumAdd(global_eid,&resultAdd,x,&retVal); std::cout<<resultAdd<<std::endl; std::cout<<retVal<<std::endl; return 0; }
Enclave.cpp
int sumAdd(int x, int *result){ *result = x+10; int z = 5; return z + x; }
EDL
enclave { from "sgx_tae_service.edl" import *; trusted { /* define ECALLs here. */ public int sumAdd(int x,[out] int* result); }; untrusted { /* define OCALLs here. */ void ocall_print([in, string]const char* str); }; };
I am using the enclave_t.h for the prototype.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi Scott, you code is perfect from the perspective of SGX. It works. Are you testing the enclave directly in C++/C or are you abstracting with Go?
Regards,
Jesus
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
The go function simply calls the C++ code. Nothing too fancy.
Go code below:
/* #include "./App/TEE.h" #cgo LDFLAGS: -L. -ltee */ import "C" import ( "fmt" ) func main() { fmt.Println("Intel SGX starting") C.test() }
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hey,
Out of curiosity, are you aware of any abstracted examples similar to what I am trying to do?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hello Scott,
We have not seen this before. Have you seen this project on Github, https://github.com/rupc/go-with-intel-sgx -> https://github.com/rupc/go-with-intel-sgx/tree/master/SampleCode/SampleEnclave? It might help you.
I have been having some problems getting my hands on a Linux machine with SGX support so I can try to setup the SampleEnclave Go example from the link above. I do not have experience with Go.
Regards,
Jesus
Intel Customer Support
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page