Linux下SGX的使用(2)-Hello Enclave
来源:互联网 发布:阿里云搭建ss教程 编辑:程序博客网 时间:2024/06/04 01:40
在编写代码之前,我们需要定义可信和不可信的函数,我们首先建立一个文件夹,在文件夹中为了编译方便(仿照上一节的makefile写我们自己的makefie)也仿照sdk给的例子中的文件夹布局建立新的文件夹文件夹的布局如下:
其中后缀为xml,lds,pem的文件,直接从SDK中SampleEnclave中拷贝即可(在所有的案例中,xml,lds的内容一样,但是名称不一样,也可以自己更该,但是makefile也要更改,pem可以自己生成也可以使用已经存在的pem)一下文件都是参照SampleEnclave中的代码来实现的
首先配置edl文件
我们实现将hello world在enclave中替换成hello enclave!
edl的代码如下:
enclave{ trusted{ public void dck_test([in,out,size=len] char *buf,size_t len); //in或者out的修饰是必不可少的,否则无法正常读出以及写入 }; untrusted{ };};
之后编写enclave的实现,SGX中是通过enclave.cpp
enclave.cpp的内容如下:
#include "enclave_t.h" //包括edl的同名的_t.h文件#include "sgx_trts.h" //包括可信的头文件#include <string.h>void dck_test(char *buf,size_t len) //拷贝函数{ const char *secret="Hello Enclave!"; if(len>=0) { memcpy(buf,secret,strlen(secret)+1); }}
之后是函数的主体也就是test.cpp,首先先看依稀test.h
/* * Copyright (C) 2011-2017 Intel Corporation. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name of Intel Corporation nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */#ifndef _APP_H_#define _APP_H_#include <assert.h>#include <stdio.h>#include <stdlib.h>#include <stdarg.h>#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_ */
之后定义相关的test.cpp
#include <stdio.h>#include <string.h>#include <assert.h># include <unistd.h># include <pwd.h># define LEN 100 //自己添加的# define MAX_PATH FILENAME_MAX //这个定义在test.h#include "sgx_urts.h"#include "enclave_u.h"#include "test.h"/* Global EID shared by multiple threads */sgx_enclave_id_t global_eid = 0; //enclave的IDtypedef struct _sgx_errlist_t { sgx_status_t err; const char *msg; const char *sug; /* Suggestion */} sgx_errlist_t;/* Error code returned by sgx_create_enclave */static sgx_errlist_t sgx_errlist[] = { { 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 },};/* Check error conditions for loading enclave */void print_error_message(sgx_status_t ret){ size_t idx = 0; size_t ttl = sizeof sgx_errlist/sizeof sgx_errlist[0]; 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");}/* Initialize the enclave: * Step 1: try to retrieve the launch token saved by last transaction * Step 2: call sgx_create_enclave to initialize an enclave instance * Step 3: save the launch token if it is updated */int initialize_enclave(void){ char token_path[MAX_PATH] = {'\0'}; sgx_launch_token_t token = {0}; sgx_status_t ret = SGX_ERROR_UNEXPECTED; int updated = 0; /* Step 1: try to retrieve the launch token saved by last transaction * if there is no token, then create a new one. */ /* try to get the token saved in $HOME */ const char *home_dir = getpwuid(getuid())->pw_dir; if (home_dir != NULL && (strlen(home_dir)+strlen("/")+sizeof(TOKEN_FILENAME)+1) <= MAX_PATH) { /* compose the token path */ strncpy(token_path, home_dir, strlen(home_dir)); strncat(token_path, "/", strlen("/")); strncat(token_path, TOKEN_FILENAME, sizeof(TOKEN_FILENAME)+1); } else { /* if token path is too long or $HOME is NULL */ strncpy(token_path, TOKEN_FILENAME, sizeof(TOKEN_FILENAME)); } 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) { /* read the token from saved file */ 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); } } /* Step 2: call sgx_create_enclave to initialize an enclave instance */ /* Debug Support: set 2nd parameter to 1 */ ret = sgx_create_enclave(ENCLAVE_FILENAME, SGX_DEBUG_FLAG, &token, &updated, &global_eid, NULL); if (ret != SGX_SUCCESS) { print_error_message(ret); if (fp != NULL) fclose(fp); return -1; } /* Step 3: save the launch token if it is updated */ if (updated == FALSE || fp == NULL) { /* if the token is not updated, or file handler is invalid, do not perform saving */ if (fp != NULL) fclose(fp); return 0; } /* reopen the file with write capablity */ 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;}//以上内容都是必须的,都不需要更该/* Application entry */int SGX_CDECL main(int argc, char *argv[]){ (void)(argc); (void)(argv); char buffer[LEN]= "Hello world!"; /* Initialize the enclave */ if(initialize_enclave() < 0){ printf("Enter a character before exit ...\n"); getchar(); return -1; } dck_test(global_eid,buffer,LEN); //调用函数,一定要使用enclave的id printf("%s",buffer); /* Destroy the enclave */ sgx_destroy_enclave(global_eid); return 0;}
下面就是重点的makefile了
######## SGX SDK Settings ########不用更改SGX_SDK ?= /opt/intel/sgxsdkSGX_MODE ?= HWSGX_ARCH ?= x64SGX_DEBUG ?= 1ifeq ($(shell getconf LONG_BIT), 32) SGX_ARCH := x86else ifeq ($(findstring -m32, $(CXXFLAGS)), -m32) SGX_ARCH := x86endififeq ($(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_edger8relse 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_edger8rendififeq ($(SGX_DEBUG), 1)ifeq ($(SGX_PRERELEASE), 1)$(error Cannot set SGX_DEBUG and SGX_PRERELEASE at the same time!!)endifendififeq ($(SGX_DEBUG), 1) SGX_COMMON_CFLAGS += -O0 -gelse SGX_COMMON_CFLAGS += -O2endif######## App Settings ########ifneq ($(SGX_MODE), HW) Urts_Library_Name := sgx_urts_simelse Urts_Library_Name := sgx_urtsendifApp_Cpp_Files := App/test.cpp $(wildcard App/Edger8rSyntax/*.cpp) $(wildcard App/TrustedLibrary/*.cpp) #上述App/。。。更改成我们自己的cpp名称其他的不做更改App_Include_Paths := -IInclude -IApp -I$(SGX_SDK)/includeApp_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 -UEDEBUGelse ifeq ($(SGX_PRERELEASE), 1) App_C_Flags += -DNDEBUG -DEDEBUG -UDEBUGelse App_C_Flags += -DNDEBUG -UEDEBUG -UDEBUGendifApp_Cpp_Flags := $(App_C_Flags) -std=c++11App_Link_Flags := $(SGX_COMMON_CFLAGS) -L$(SGX_LIBRARY_PATH) -l$(Urts_Library_Name) -lpthread ifneq ($(SGX_MODE), HW) App_Link_Flags += -lsgx_uae_service_simelse App_Link_Flags += -lsgx_uae_serviceendifApp_Cpp_Objects := $(App_Cpp_Files:.cpp=.o)App_Name := test######## Enclave Settings ########ifneq ($(SGX_MODE), HW) Trts_Library_Name := sgx_trts_sim Service_Library_Name := sgx_tservice_simelse Trts_Library_Name := sgx_trts Service_Library_Name := sgx_tserviceendifCrypto_Library_Name := sgx_tcryptoEnclave_Cpp_Files := Enclave/enclave.cpp $(wildcard Enclave/Edger8rSyntax/*.cpp) $(wildcard Enclave/TrustedLibrary/*.cpp)#更改成我们的cpp文件Enclave_Include_Paths := -IInclude -IEnclave -I$(SGX_SDK)/include -I$(SGX_SDK)/include/tlibc -I$(SGX_SDK)/include/stlportEnclave_C_Flags := $(SGX_COMMON_CFLAGS) -nostdinc -fvisibility=hidden -fpie -fstack-protector $(Enclave_Include_Paths)Enclave_Cpp_Flags := $(Enclave_C_Flags) -std=c++03 -nostdinc++# To generate a proper enclave, it is recommended to follow below guideline to link the trusted libraries:# 1. Link sgx_trts with the `--whole-archive' and `--no-whole-archive' options,# so that the whole content of trts is included in the enclave.# 2. For other libraries, you just need to pull the required symbols.# Use `--start-group' and `--end-group' to link these libraries.# Do NOT move the libraries linked with `--start-group' and `--end-group' within `--whole-archive' and `--no-whole-archive' options.# Otherwise, you may get some undesirable errors.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 #lds文件的使用Enclave_Cpp_Objects := $(Enclave_Cpp_Files:.cpp=.o)Enclave_Name := enclave.soSigned_Enclave_Name := enclave.signed.soEnclave_Config_File := Enclave/Enclave.config.xmlifeq ($(SGX_MODE), HW)ifeq ($(SGX_DEBUG), 1) Build_Mode = HW_DEBUGelse ifeq ($(SGX_PRERELEASE), 1) Build_Mode = HW_PRERELEASEelse Build_Mode = HW_RELEASEendifelseifeq ($(SGX_DEBUG), 1) Build_Mode = SIM_DEBUGelse ifeq ($(SGX_PRERELEASE), 1) Build_Mode = SIM_PRERELEASEelse Build_Mode = SIM_RELEASEendifendif.PHONY: all runifeq ($(Build_Mode), HW_RELEASE)all: .config_$(Build_Mode)_$(SGX_ARCH) $(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 <your key> -enclave $(Enclave_Name) -out <$(Signed_Enclave_Name)> -config $(Enclave_Config_File)" @echo "You can also sign the enclave using an external signing tool." @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."elseall: .config_$(Build_Mode)_$(SGX_ARCH) $(App_Name) $(Signed_Enclave_Name)ifeq ($(Build_Mode), HW_DEBUG) @echo "The project has been built in debug hardware mode."else ifeq ($(Build_Mode), SIM_DEBUG) @echo "The project has been built in debug simulation mode."else ifeq ($(Build_Mode), HW_PRERELEASE) @echo "The project has been built in pre-release hardware mode."else ifeq ($(Build_Mode), SIM_PRERELEASE) @echo "The project has been built in pre-release simulation mode."else @echo "The project has been built in release simulation mode."endifendifrun: allifneq ($(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#更改成我们自己的edl文件,此处生成的_t.c要与我们程序中包含的文件_u.h内容以值 @cd App && $(SGX_EDGER8R) --untrusted ../Enclave/enclave.edl --search-path ../Enclave --search-path $(SGX_SDK)/include #edl要改成我们自己的文件 @echo "GEN => $@"App/enclave_u.o: App/enclave_u.c #改成上述生成的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)#改成上述步骤生成的_u.o文件 @$(CXX) $^ -o $@ $(App_Link_Flags) @echo "LINK => $@".config_$(Build_Mode)_$(SGX_ARCH): @rm -f .config_* $(App_Name) $(Enclave_Name) $(Signed_Enclave_Name) $(App_Cpp_Objects) App/enclave_u.* $(Enclave_Cpp_Objects) Enclave/enclave_t.*#修改我们生成的相关内容 @touch .config_$(Build_Mode)_$(SGX_ARCH)######## Enclave Objects ########Enclave/enclave_t.c: $(SGX_EDGER8R) Enclave/enclave.edl#更改文件内容,这部分是可信的生成文件要与我们文件中include的文件相同 @cd Enclave && $(SGX_EDGER8R) --trusted ../Enclave/enclave.edl --search-path ../Enclave --search-path $(SGX_SDK)/include#更改edl文件 @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)#签名,使用pem进行签名 @echo "SIGN => $@".PHONY: cleanclean: @rm -f .config_* $(App_Name) $(Enclave_Name) $(Signed_Enclave_Name) $(App_Cpp_Objects) App/enclave_u.* $(Enclave_Cpp_Objects) Enclave/enclave_t.*#更改成我们需要的名称
之后使用make,之后运行生成的程序,结果如下:
之后运行./test,结果如下:
我们的enclave版hello world就完成了!
阅读全文
0 0
- Linux下SGX的使用(2)-Hello Enclave
- Linux下SGX的使用(1)-makefile阅读
- Linux下SGX的使用(3)-编译多个文件
- linux下移植AM335的sgx驱动
- linux下移植AM335的sgx驱动
- Ubuntu 16.04下Intel SGX应用程序程序开发——获得Enclave函数返回值!
- Ubuntu 16.04下Intel SGX应用程序程序开发——打印Hello World!
- Ubuntu 16.04下Intel SGX应用程序程序开发——OCALL调用打印Hello World!
- linux intel SGX 安装
- Linux 下的“Hello world!”
- Linux下的“Hello world!”
- sgx 中intel ipp 加密库的使用
- linux(ubuntu)下的第一个程序 hello world
- 针对SGX的缓存攻击(Cache Attack)调研
- Linux下RPC的hello world
- Linux 下的 php Hello word
- Ubuntu 16.04下Intel SGX应用程序程序开发——获得OCALL调用的返回值
- linux下使用vim编写运行C,C++程序(以hello world为例)
- jQuery和jQuery UI的区别
- 表示学习1-word2vec
- wampServer 启动报错
- Eclipse中怎么安装TestNG单元测试框架
- Spring中的@scope注解
- Linux下SGX的使用(2)-Hello Enclave
- Spring RedisTemplate操作-List操作
- Codeforces 856A
- POSIX定时器-线程方式创建定时器
- 第2章 UNIX标准及实现
- 深入理解 Java中的深克隆与浅克隆
- java_字符串中各类型字符出现的个数统计
- linux:一些压缩命令的使用
- Spring RedisTemplate操作-Set操作