写在前面:
在SGX编程的过程中,肯定设计到使用Ecall函数使数据在enclave中调用,这里我们在调用的时候会涉及到一个关键问题,这种使用方式是SGX项目特有的,跟别的开发思路传参数不一样的地方
一、根据我前面的文章复制示例项目到你的本地文件夹
链接:intel SGX学习笔记(6)
连接:intel SGX学习笔记(7)
二、App.cpp中的main函数新增代码
注重说明一下App.cpp中的ecall函数调用,我们定义了a=1,b=2并且完成初始化,定义c为接受变量,但是我们不能采用下面这种形式来获取enclave的返回值,这里是SGX不支持的编程方式。
c=ecall_return_res(global_eid,a,b);
我们要把c变量的地址传过去,作为enclave中计算结果后,把结果存入这个地址,后面我们直接访问这个变量的地址即可,不能用一般返回值的形式来获取enclave中的函数计算结果,其中第一个变量是enclave的EID这个必传,不传不行,第二个位置放保存计算结果的变量地址,这样我们在非安全区中的App.cpp文件就可以通过printf函数打印c的值了(ecall_return_res函数)
ecall_return_res(global_eid,&c,a,b);
/* Application entry */
int SGX_CDECL main(int argc, char *argv[])
{
(void)(argc);
(void)(argv);
/* Initialize the enclave */
if(initialize_enclave() < 0){
printf("Enter a character before exit ...\n");
getchar();
return -1;
}
/* Utilize edger8r attributes */
edger8r_array_attributes();
edger8r_pointer_attributes();
edger8r_type_attributes();
edger8r_function_attributes();
/* Utilize trusted libraries */
ecall_libc_functions();
ecall_libcxx_functions();
ecall_thread_functions();
printf("+++++++++++++++++++++\n");
int a=1;
int b=2;
int c;
ecall_return_res(global_eid,&c,a,b);
printf("ecall_return_res=%d\n",c);
sgx_destroy_enclave(global_eid);
return 0;
}
三、Enclave.cpp中新增ecall_return_res函数
int ecall_return_res(int a,int b){
return a+b+10;
}
四、Enclave.edl中定义trust可信函数
/* Enclave.edl - Top EDL file. */
enclave {
include "user_types.h" /* buffer_t */
/* Import ECALL/OCALL from sub-directory EDLs.
* [from]: specifies the location of EDL file.
* [import]: specifies the functions to import,
* [*]: implies to import all functions.
*/
from "Edger8rSyntax/Types.edl" import *;
from "Edger8rSyntax/Pointers.edl" import *;
from "Edger8rSyntax/Arrays.edl" import *;
from "Edger8rSyntax/Functions.edl" import *;
from "TrustedLibrary/Libc.edl" import *;
from "TrustedLibrary/Libcxx.edl" import ecall_exception, ecall_map;
from "TrustedLibrary/Thread.edl" import *;
trusted {
public int ecall_return_res(int a,int b);
};
/*
* ocall_print_string - invokes OCALL to display string buffer inside the enclave.
* [in]: copy the string buffer to App outside.
* [string]: specifies 'str' is a NULL terminated buffer.
*/
untrusted {
void ocall_print_string([in, string] const char *str);
};
};
五、Enclave.h文件中注册ecall_return_res函数
#ifndef _ENCLAVE_H_
#define _ENCLAVE_H_
#include <assert.h>
#include <stdlib.h>
#if defined(__cplusplus)
extern "C" {
#endif
int printf(const char* fmt, ...);
int ecall_return_res(int a,int b);
#if defined(__cplusplus)
}
#endif
#endif /* !_ENCLAVE_H_ */
六、运行结果
七、总结
由于enclave中的函数运行在安全的执行环境中,因此不能直接将其返回值传递给App程序中的变量。相反,您需要将要返回的值作为指针参数传递给enclave函数,并在函数内部将要返回的值写入到该指针所指向的内存中。在App程序中,您需要在调用enclave函数时创建一个指向要接收返回值的变量的指针,并将其作为enclave函数的指针参数传递。这样,在enclave函数完成后,您就可以通过指向变量的指针来访问返回值了。