参考sgxsdk的samplecode中的sampleEnclave
包含文件夹: App,Enclave,Include
包含文件:Makefile,Readme.txt
1.App:
外部程序,在enclave外部运行的代码
外部应用程序源码
2.Enclave:
tag | description | defaule value |
ProdID | ISV assigned Product ID | 0 |
ISVSVN | ISV assigned ISV | 0 |
TCSNum | Number of TCS | 1 |
TCSPolicy | TCS bound to untrusted thread = 1 TCS not bound to untrusted thread = 0 |
1 |
StackMaxSize | the max stack size per thread(4kb aligned) | 0x40000 |
HeapMaxSize | the max heap size for the process(4kb aligned) | 0x100000 |
DisableDebug | whether can debug enclave | 0/1 yes/no |
MiscSelect | the desired MISC feature | 0 |
MiscMask | mask bits for the Misc feature | 0xFFFFFFFF |
配置enclave的堆栈大小,链接数,
enclave_entry | entry point to enclave |
g_global_data_sim | link to tRTS simulathion for running enclave |
g_peak_heap_used | the size of enclave heap |
3.Include:
外部应用程序和enclave程序共享的头文件,大多是公用的数据类型的定义
4.Makefile
构建项目
app.h
#ifndef _APP_H_
#define _APP_H_
#include
#include
#include
#include
#include "sgx_error.h" /* sgx_status_t */
#include "sgx_eid.h" /* sgx_enclave_id_t */
#ifndef TRUE
# define TRUE 1
#endif
#ifndef FALSE
# define FALSE 0
#endif
# define TOKEN_FILENAME "enclave.token"
# define ENCLAVE_FILENAME "enclave.signed.so"
extern sgx_enclave_id_t global_eid; /* global enclave id */
#if defined(__cplusplus)
extern "C" {
#endif
#if defined(__cplusplus)
}
#endif
#endif /* !_APP_H_ */
简单封装一下enclave操作
创建一个文件夹enclave
进入
enclave.h
#ifndef ENCLAVE_H_
#define ENCLAVE_H_
#include
#include
#include
#include
#include
#include
#include
#define MAX_PATH FILENAME_MAX
#include "sgx_urts.h"
#include "App.h"
#include "Enclave_u.h"
#define errlist_len 15
using namespace std;
typedef struct _sgx_errlist_t {
sgx_status_t err;
const char *msg;
const char *sug; /* Suggestion */
} sgx_errlist_t;
class enclave
{
private:
sgx_errlist_t sgx_errlist[errlist_len] = {
{
SGX_ERROR_UNEXPECTED,
"Unexpected error occurred.",
NULL
},
{
SGX_ERROR_INVALID_PARAMETER,
"Invalid parameter.",
NULL
},
{
SGX_ERROR_OUT_OF_MEMORY,
"Out of memory.",
NULL
},
{
SGX_ERROR_ENCLAVE_LOST,
"Power transition occurred.",
"Please refer to the sample \"PowerTransition\" for details."
},
{
SGX_ERROR_INVALID_ENCLAVE,
"Invalid enclave image.",
NULL
},
{
SGX_ERROR_INVALID_ENCLAVE_ID,
"Invalid enclave identification.",
NULL
},
{
SGX_ERROR_INVALID_SIGNATURE,
"Invalid enclave signature.",
NULL
},
{
SGX_ERROR_OUT_OF_EPC,
"Out of EPC memory.",
NULL
},
{
SGX_ERROR_NO_DEVICE,
"Invalid SGX device.",
"Please make sure SGX module is enabled in the BIOS, and install SGX driver afterwards."
},
{
SGX_ERROR_MEMORY_MAP_CONFLICT,
"Memory map conflicted.",
NULL
},
{
SGX_ERROR_INVALID_METADATA,
"Invalid enclave metadata.",
NULL
},
{
SGX_ERROR_DEVICE_BUSY,
"SGX device was busy.",
NULL
},
{
SGX_ERROR_INVALID_VERSION,
"Enclave version was invalid.",
NULL
},
{
SGX_ERROR_INVALID_ATTRIBUTE,
"Enclave was not authorized.",
NULL
},
{
SGX_ERROR_ENCLAVE_FILE_ACCESS,
"Can't open enclave file.",
NULL
}
};
public:
enclave(string tfn,string efn);
sgx_enclave_id_t enclave_id;
string token_filename;
string p_token_path;
string enclave_filename;
void print_error_message(sgx_status_t ret);
int init(char* token_path);
int destroy(void);
};
#endif
encalve.cpp
#include "enclave.h"
enclave::enclave(string tfn,string efn)
{
token_filename=tfn;
enclave_filename=efn;
//enclave_id=global_eid;
}
int enclave::destroy()
{
sgx_status_t ret;
ret = sgx_destroy_enclave(enclave_id);
if(SGX_SUCCESS==ret){
printf("Enclave %d destroy success\n",enclave_id);
}else{
print_error_message(ret);
printf("Enclave %d destroy failure\n",enclave_id);
}
return 0;
}
void enclave::print_error_message(sgx_status_t ret)
{
size_t idx = 0;
size_t ttl = errlist_len;
for (idx = 0; idx < ttl; idx++) {
if(ret == sgx_errlist[idx].err) {
if(NULL != sgx_errlist[idx].sug)
printf("Info: %s\n", sgx_errlist[idx].sug);
printf("Error: %s\n", sgx_errlist[idx].msg);
break;
}
}
if (idx == ttl)
printf("Error: Unexpected error occurred.\n");
}
int enclave::init(char* token_path)
{
//char token_path[MAX_PATH] = {'\0'};
sgx_launch_token_t token = {0};
sgx_status_t ret = SGX_ERROR_UNEXPECTED;
int updated = 0;
const char *home_dir = getpwuid(getuid())->pw_dir;
//set token
if(token_path==NULL){
token_path=(char*)malloc(MAX_PATH);
memset(token_path,0, MAX_PATH);
if (home_dir != NULL &&
(strlen(home_dir)+strlen("/")+sizeof(token_filename)+1) <= MAX_PATH) {
strncpy(token_path, home_dir, strlen(home_dir));
strncat(token_path, "/", strlen("/"));
strncat(token_path, token_filename.c_str(), sizeof(token_filename)+1);
} else {
/* if token path is too long or $HOME is NULL */
strncpy(token_path, token_filename.c_str(), sizeof(token_filename));
}
}
//load token
p_token_path=token_path;
FILE *fp = fopen(token_path, "rb");
if (fp == NULL && (fp = fopen(token_path, "wb")) == NULL) {
printf("Warning: Failed to create/open the launch token file \"%s\".\n", token_path);
}
if (fp != NULL) {
size_t read_num = fread(token, 1, sizeof(sgx_launch_token_t), fp);
if (read_num != 0 && read_num != sizeof(sgx_launch_token_t)) {
/* if token is invalid, clear the buffer */
memset(&token, 0x0, sizeof(sgx_launch_token_t));
printf("Warning: Invalid launch token read from \"%s\".\n", token_path);
}
}
//create
ret = sgx_create_enclave(enclave_filename.c_str(), SGX_DEBUG_FLAG, &token, &updated, &global_eid, NULL);
if (ret != SGX_SUCCESS) {
enclave_id=0;
print_error_message(ret);
if (fp != NULL) fclose(fp);
return -1;
}
enclave_id=global_eid;
if (updated == FALSE || fp == NULL) {
if (fp != NULL) fclose(fp);
return 0;
}
fp = freopen(token_path, "wb", fp);
if (fp == NULL) return 0;
size_t write_num = fwrite(token, 1, sizeof(sgx_launch_token_t), fp);
if (write_num != sizeof(sgx_launch_token_t))
printf("Warning: Failed to save launch token to \"%s\".\n", token_path);
fclose(fp);
return 0;
}
写一个简单的程序模块
创建文件夹function
进入
print.cpp
#include "../App.h"
#include "Enclave_u.h"
/* OCall functions */
void ocall_print_string(const char *str)
{
printf("==in ocall_print:%s", str);
}
因为该模块要给enclave调用,所以要定义edl接口
print.edl
enclave {
untrusted {
//ocall generally not add a public-attribut
void ocall_print_string([in, string] const char *str);
};
};
外部应用程序的主程序:
app.cpp
#include
#include
#include
# include
# include
#include
# define MAX_PATH FILENAME_MAX
#include "sgx_urts.h"
#include "App.h"
#include "Enclave_u.h"
#include "enclave.h"
sgx_enclave_id_t global_eid = 0;
/* Application entry */
int SGX_CDECL main(int argc, char *argv[])
{
(void)(argc);
(void)(argv);
enclave ecv=enclave(TOKEN_FILENAME,ENCLAVE_FILENAME);
/* Initialize the enclave */
if(ecv.init(NULL) < 0){
printf("init failed and exit ...\n");
getchar();
return -1;
}
//-1
char* start[3];
start[0]="start\n";
start[1]="in\n";
start[2]="app\n";
encall_print(global_eid,start);
printf("global eid:%d\n",global_eid);
std::cout<<"enclave id:"<< ecv.enclave_id<<std::endl;
std::cout<<"token:"<":"<std::endl;
std::cout<<"enclave file:"<std::endl;
//std::cout<<<
ecv.destroy();
return 0;
}
在Enclave文件夹中
创建enclave程序:
#ifndef _ENCLAVE_H_
#define _ENCLAVE_H_
#include
#include
#if defined(__cplusplus)
extern "C" {
#endif
#if defined(__cplusplus)
}
#endif
#endif /* !_ENCLAVE_H_ */
enclave.cpp
#include
#include /* vsnprintf */
#include "Enclave.h"
#include "Enclave_t.h" /* print_string */
# include
#include
void encall_print(char **fmt)
{
char buf[BUFSIZ] = {'\0'};
char* a="\tnow is in encall\n";
strncat(buf,fmt[0],100);
strncat(buf,(fmt[1]),100);
strncat(buf,(fmt[2]),100);
strncat(buf,a,100);
ocall_print_string(buf);
}
创建给外部程序的接口:
Encalve.edl
/* Enclave.edl - Top EDL file. */
enclave {
include "user_types.h" /* buffer_t */
from "../App/function/print.edl" import *;
trusted{
public void encall_print([user_check] char** fmt);
};
};
链接文件
Enclave.lds
enclave.so
{
global:
g_global_data_sim;
g_global_data;
enclave_entry;
local:
*;
};
配置文件
Enclave.config.xml
<EnclaveConfiguration>
<ProdID>0ProdID>
<ISVSVN>0ISVSVN>
<StackMaxSize>0x40000StackMaxSize>
<HeapMaxSize>0x100000HeapMaxSize>
<TCSNum>10TCSNum>
<TCSPolicy>1TCSPolicy>
<DisableDebug>0DisableDebug>
<MiscSelect>0MiscSelect>
<MiscMask>0xFFFFFFFFMiscMask>
EnclaveConfiguration>
进入Include文件夹
user_types.h
/* User defined types */
#define LOOPS_PER_THREAD 500
typedef void *buffer_t;
typedef int array_t[10];
Makefile
######## SGX SDK Settings ########
SGX_SDK ?= /opt/intel/sgxsdk
SGX_MODE ?= SIM
SGX_ARCH ?= x64
ifeq ($(shell getconf LONG_BIT), 32)
SGX_ARCH := x86
else ifeq ($(findstring -m32, $(CXXFLAGS)), -m32)
SGX_ARCH := x86
endif
ifeq ($(SGX_ARCH), x86)
SGX_COMMON_CFLAGS := -m32
SGX_LIBRARY_PATH := $(SGX_SDK)/lib
SGX_ENCLAVE_SIGNER := $(SGX_SDK)/bin/x86/sgx_sign
SGX_EDGER8R := $(SGX_SDK)/bin/x86/sgx_edger8r
else
SGX_COMMON_CFLAGS := -m64
SGX_LIBRARY_PATH := $(SGX_SDK)/lib64
SGX_ENCLAVE_SIGNER := $(SGX_SDK)/bin/x64/sgx_sign
SGX_EDGER8R := $(SGX_SDK)/bin/x64/sgx_edger8r
endif
ifeq ($(SGX_DEBUG), 1)
ifeq ($(SGX_PRERELEASE), 1)
$(error Cannot set SGX_DEBUG and SGX_PRERELEASE at the same time!!)
endif
endif
ifeq ($(SGX_DEBUG), 1)
SGX_COMMON_CFLAGS += -O0 -g
else
SGX_COMMON_CFLAGS += -O2
endif
######## App Settings ########
ifneq ($(SGX_MODE), HW)
Urts_Library_Name := sgx_urts_sim
else
Urts_Library_Name := sgx_urts
endif
App_Cpp_Files := App/App.cpp $(wildcard App/enclave/*.cpp) $(wildcard App/function/*.cpp)
#add more dir in APP: $(wildcard App/dir_name/*.cpp)
App_Include_Paths := -IInclude -IApp -I$(SGX_SDK)/include -IApp/enclave
App_C_Flags := $(SGX_COMMON_CFLAGS) -fPIC -Wno-attributes $(App_Include_Paths)
# Three configuration modes - Debug, prerelease, release
# Debug - Macro DEBUG enabled.
# Prerelease - Macro NDEBUG and EDEBUG enabled.
# Release - Macro NDEBUG enabled.
ifeq ($(SGX_DEBUG), 1)
App_C_Flags += -DDEBUG -UNDEBUG -UEDEBUG
else ifeq ($(SGX_PRERELEASE), 1)
App_C_Flags += -DNDEBUG -DEDEBUG -UDEBUG
else
App_C_Flags += -DNDEBUG -UEDEBUG -UDEBUG
endif
App_Cpp_Flags := $(App_C_Flags) -std=c++11
App_Link_Flags := $(SGX_COMMON_CFLAGS) -L$(SGX_LIBRARY_PATH) -l$(Urts_Library_Name) -lpthread
ifneq ($(SGX_MODE), HW)
App_Link_Flags += -lsgx_uae_service_sim
else
App_Link_Flags += -lsgx_uae_service
endif
App_Cpp_Objects := $(App_Cpp_Files:.cpp=.o)
App_Name := app
######## Enclave Settings ########
ifneq ($(SGX_MODE), HW)
Trts_Library_Name := sgx_trts_sim
Service_Library_Name := sgx_tservice_sim
else
Trts_Library_Name := sgx_trts
Service_Library_Name := sgx_tservice
endif
Crypto_Library_Name := sgx_tcrypto
Enclave_Cpp_Files := Enclave/Enclave.cpp
#add more Enclave dir $(wildcard Enclave/dir_name/*.cpp)
Enclave_Include_Paths := -IInclude -IEnclave -I$(SGX_SDK)/include -I$(SGX_SDK)/include/tlibc -I$(SGX_SDK)/include/stlport
Enclave_C_Flags := $(SGX_COMMON_CFLAGS) -nostdinc -fvisibility=hidden -fpie -fstack-protector $(Enclave_Include_Paths)
Enclave_Cpp_Flags := $(Enclave_C_Flags) -std=c++03 -nostdinc++
Enclave_Link_Flags := $(SGX_COMMON_CFLAGS) -Wl,--no-undefined -nostdlib -nodefaultlibs -nostartfiles -L$(SGX_LIBRARY_PATH) \
-Wl,--whole-archive -l$(Trts_Library_Name) -Wl,--no-whole-archive \
-Wl,--start-group -lsgx_tstdc -lsgx_tstdcxx -l$(Crypto_Library_Name) -l$(Service_Library_Name) -Wl,--end-group \
-Wl,-Bstatic -Wl,-Bsymbolic -Wl,--no-undefined \
-Wl,-pie,-eenclave_entry -Wl,--export-dynamic \
-Wl,--defsym,__ImageBase=0 \
-Wl,--version-script=Enclave/Enclave.lds
Enclave_Cpp_Objects := $(Enclave_Cpp_Files:.cpp=.o)
Enclave_Name := enclave.so
Signed_Enclave_Name := enclave.signed.so
Enclave_Config_File := Enclave/Enclave.config.xml
ifeq ($(SGX_MODE), HW)
ifneq ($(SGX_DEBUG), 1)
ifneq ($(SGX_PRERELEASE), 1)
Build_Mode = HW_RELEASE
endif
endif
endif
.PHONY: all run
ifeq ($(Build_Mode), HW_RELEASE)
all: $(App_Name) $(Enclave_Name)
@echo "The project has been built in release hardware mode."
@echo "Please sign the $(Enclave_Name) first with your signing key before you run the $(App_Name) to launch and access the enclave."
@echo "To sign the enclave use the command:"
@echo " $(SGX_ENCLAVE_SIGNER) sign -key -enclave $(Enclave_Name) -out <$(Signed_Enclave_Name)> -config $(Enclave_Config_File)"
@echo "You can also sign the enclave using an external signing tool. See User's Guide for more details."
@echo "To build the project in simulation mode set SGX_MODE=SIM. To build the project in prerelease mode set SGX_PRERELEASE=1 and SGX_MODE=HW."
else
all: $(App_Name) $(Signed_Enclave_Name)
endif
run: all
ifneq ($(Build_Mode), HW_RELEASE)
@$(CURDIR)/$(App_Name)
@echo "RUN => $(App_Name) [$(SGX_MODE)|$(SGX_ARCH), OK]"
endif
######## App Objects ########
App/Enclave_u.c: $(SGX_EDGER8R) Enclave/Enclave.edl
@cd App && $(SGX_EDGER8R) --untrusted ../Enclave/Enclave.edl --search-path ../Enclave --search-path $(SGX_SDK)/include
@echo "GEN => $@"
App/Enclave_u.o: App/Enclave_u.c
@$(CC) $(App_C_Flags) -c $< -o $@
@echo "CC <= $<"
App/%.o: App/%.cpp
@$(CXX) $(App_Cpp_Flags) -c $< -o $@
@echo "CXX <= $<"
$(App_Name): App/Enclave_u.o $(App_Cpp_Objects)
@$(CXX) $^ -o $@ $(App_Link_Flags)
@echo "LINK => $@"
######## Enclave Objects ########
Enclave/Enclave_t.c: $(SGX_EDGER8R) Enclave/Enclave.edl
@cd Enclave && $(SGX_EDGER8R) --trusted ../Enclave/Enclave.edl --search-path ../Enclave --search-path $(SGX_SDK)/include
@echo "GEN => $@"
Enclave/Enclave_t.o: Enclave/Enclave_t.c
@$(CC) $(Enclave_C_Flags) -c $< -o $@
@echo "CC <= $<"
Enclave/%.o: Enclave/%.cpp
@$(CXX) $(Enclave_Cpp_Flags) -c $< -o $@
@echo "CXX <= $<"
$(Enclave_Name): Enclave/Enclave_t.o $(Enclave_Cpp_Objects)
@$(CXX) $^ -o $@ $(Enclave_Link_Flags)
@echo "LINK => $@"
$(Signed_Enclave_Name): $(Enclave_Name)
@$(SGX_ENCLAVE_SIGNER) sign -key Enclave/Enclave_private.pem -enclave $(Enclave_Name) -out $@ -config $(Enclave_Config_File)
@echo "SIGN => $@"
.PHONY: clean
clean:
@rm -f $(App_Name) $(Enclave_Name) $(Signed_Enclave_Name) $(App_Cpp_Objects) App/Enclave_u.* $(Enclave_Cpp_Objects) Enclave/Enclave_t.*