1 Star 0 Fork 77

blue / secGear

forked from openEuler / secGear 
加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
贡献代码
同步代码
取消
提示: 由于 Git 不支持空文件夾,创建文件夹后会生成空的 .keep 文件
Loading...
README
MulanPSL-2.0
secGear

secGear

介绍

SecGear则是面向计算产业的机密计算安全应用开发套件。旨在方便开发者在不同的硬件设备上提供统一开发框架。目前secGear支持intel SGX硬件和Trustzone itrustee。

构建、安装

开发应用和编译

开发目录 .../secGear/examples/test/

1 编写edl接口文件

enclave {
	include "secgear_urts.h"
	from "secgear_tstdc.edl" import *;
	trusted {
		public int get_string([out, size=32]char *buf);
	};
};

'include "secgear_urts.h" from "secgear_tstdc.edl" import *'是为了屏蔽SGX和iTrustee在调用libc库之间的差异。所以为了开发代码的一致性,默认导入这两个文件。 有关edl语法的详细信息,请参阅SGX开发文档定义的EDL(Enclave Definition Language)语法部分。 目前SGX和iTrustee在基本类型、指针类型和深拷贝方面是相互兼容的。对于user_check、private ecalls、switchless特性仅支持sgx硬件。

保存文件名为test.edl

2 编写最外层CMakeLists.txt文件

cmake_minimum_required(VERSION 3.10 FATAL_ERROR)
project(TEST  C)
set(CMAKE_C_STANDARD 99)
set(CURRENT_ROOT_PATH ${CMAKE_CURRENT_SOURCE_DIR})
set(EDL_FILE test.edl)
set(LOCAL_ROOT_PATH "$ENV{CC_SDK}")
    set(SECGEAR_INSTALL_PATH /usr/lib64/)
set(CODEGEN codegen)
if(CC_GP)
	set(CODETYPE trustzone)
	execute_process(COMMAND uuidgen -r OUTPUT_VARIABLE UUID)
	string(REPLACE "\n" "" UUID ${UUID})
	add_definitions(-DPATH="/data/${UUID}.sec")
endif()
if(CC_SGX)
	set(CODETYPE sgx)
	add_definitions(-DPATH="${CMAKE_CURRENT_BINARY_DIR}/enclave/enclave.signed.so")
endif()
add_subdirectory(${CURRENT_ROOT_PATH}/enclave)
add_subdirectory(${CURRENT_ROOT_PATH}/host)

EDL_FILE、CODETYPE:稍后自动构建的时候会用到这些属性。 UUID:在iTrustee中,构建安全enclave动态库需要使用UUID命名,这里由uuidgen命令自动生成。 DPATH:用于定义非安全侧使用安全侧动态库的绝对路径

3 编写非安全侧代码和CMakeLists.txt文件

3.1 创建host目录和main.c文件

#include <stdio.h>
#include "enclave.h"
#include "test_u.h"

#define BUF_LEN 32

int main()
{
	int  retval = 0;
	char *path = PATH;
	char buf[BUF_LEN];
	cc_enclave_t *context = NULL;
	cc_enclave_result_t res;
	
	res = cc_enclave_create(path, AUTO_ENCLAVE_TYPE, 0, SECGEAR_DEBUG_FLAG, NULL, 0, &context);
	...

	res = get_string(context, &retval, buf);
	if (res != CC_SUCCESS || retval != (int)CC_SUCCESS) {
		printf("Ecall enclave error\n");
	} else {
		printf("%s\n", buf);
	}

	if (context != NULL) {
		res = cc_enclave_destroy(context);
		...
	}
	return res;
}

enclave.h: secGear库头文件 test_u.h: 根据edl文件自动生成的非安全侧头文件。 cc_enclave_create: 用于创建enclave安全上下文。 get_string: 根据edl中trusted定义的安全侧代理函数,该代理函数用于进入到安全侧执行安全代码。 cc_enclave_destroy: 用于销毁enclave安全上下文。

注意:这里调用的get_string函数与在edl中定义的get_string函数有些不同,这里的参数比edl中定义的多了前两个参数,分别是enclave安全上下文 和retval参数。这是因为codegen(自动生成代码工具)通过edl生成的非安全侧代理函数,其声明在test_u.h中。 如果在edl中定义的函数无返回值时,例如"public void get_string([out,size=32] char *buf);"则非安全侧代理函数为 "res=get_string(context, buf)"(这里就不在有retval参数)

3.2 编写非安全侧CMakeLists.txt

    #set auto code prefix
set(PREFIX test)
#set host exec name
set(OUTPUT secgear_test)
#set host src code
set(SOURCE_FILE ${CMAKE_CURRENT_SOURCE_DIR}/main.c)    

设置预备的基础变量

    #set auto code
if(CC_GP)
	set(AUTO_FILES  ${CMAKE_CURRENT_BINARY_DIR}/${PREFIX}_u.h ${CMAKE_CURRENT_BINARY_DIR}/${PREFIX}_u.c ${CMAKE_CURRENT_BINARY_DIR}/${PREFIX}_args.h)
	add_custom_command(OUTPUT ${AUTO_FILES}
	DEPENDS ${CURRENT_ROOT_PATH}/${EDL_FILE}
	COMMAND ${CODEGEN} --${CODETYPE} --untrusted ${CURRENT_ROOT_PATH}/${EDL_FILE} --search-path ${LOCAL_ROOT_PATH}/inc/host_inc/gp)
endif()

if(CC_SGX)
	set(AUTO_FILES  ${CMAKE_CURRENT_BINARY_DIR}/${PREFIX}_u.h ${CMAKE_CURRENT_BINARY_DIR}/${PREFIX}_u.c)
	add_custom_command(OUTPUT ${AUTO_FILES}
	DEPENDS ${CURRENT_ROOT_PATH}/${EDL_FILE}
	COMMAND ${CODEGEN} --${CODETYPE} --untrusted ${CURRENT_ROOT_PATH}/${EDL_FILE} --search-path ${LOCAL_ROOT_PATH}/inc/host_inc/sgx  --search-path ${SGXSDK}/include)
endif()

设置使用代码辅助生成工具根据edl文件生成辅助代码。CODEGEN和CODETYPE等变量定义在CMakeList.txt文件.--search-path用于搜索在edl文件中导入依赖的其他edl文件。 当使用SGX时,需要导入sgx提供的基础edl,因此这里指定了SGXSDK的patch "--search-path ${SGXSDK}/include)"。

set(CMAKE_C_FLAGS "-fstack-protector-all -W -Wall -Werror -Wextra -Werror=array-bounds -D_FORTIFY_SOURCE=2 -O2 -ftrapv -fPIE")
set(CMAKE_EXE_LINKER_FLAGS    "-Wl,-z,relro -Wl,-z,now -Wl,-z,noexecstack")

设置编译选项和链接选项

if(CC_GP)
	if(${CMAKE_VERSION} VERSION_LESS "3.13.0")
		link_directories(${SECGEAR_INSTALL_PATH})
	endif()
	add_executable(${OUTPUT} ${SOURCE_FILE} ${AUTO_FILES})
	target_include_directories(${OUTPUT} PRIVATE
					${LOCAL_ROOT_PATH}/inc/host_inc
					${LOCAL_ROOT_PATH}/inc/host_inc/gp
					${CMAKE_CURRENT_BINARY_DIR})
	if(${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.13.0")
		target_link_directories(${OUTPUT} PRIVATE ${SECGEAR_INSTALL_PATH})
	endif()
endif()

在iTrustee硬件环境上,设置头文件的搜索路径及编译生成非安全侧二进制文件。

if(CC_SGX)
	if(${CMAKE_VERSION} VERSION_LESS "3.13.0")
		link_directories(${SECGEAR_INSTALL_PATH})
	endif()
	add_executable(${OUTPUT} ${SOURCE_FILE} ${AUTO_FILES})
	target_include_directories(${OUTPUT} PRIVATE
						${LOCAL_ROOT_PATH}/inc/host_inc
						${LOCAL_ROOT_PATH}/inc/host_inc/sgx
						${CMAKE_CURRENT_BINARY_DIR})
	if(${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.13.0")
		target_link_directories(${OUTPUT} PRIVATE ${SECGEAR_INSTALL_PATH})
	endif()
endif()

在SGX硬件环境上,设置头文件的搜索路径及编译生成非安全侧二进制文件。

if(CC_SIM)
        target_link_libraries(${OUTPUT} secgearsim)
    else()
        target_link_libraries(${OUTPUT} secgear)
    endif()
    set_target_properties(${OUTPUT} PROPERTIES SKIP_BUILD_RPATH TRUE)
if(CC_GP)
	install(TARGETS  ${OUTPUT}
			RUNTIME
			DESTINATION /vendor/bin/
			PERMISSIONS OWNER_EXECUTE OWNER_WRITE OWNER_READ)
endif()
if(CC_SGX)
	install(TARGETS  ${OUTPUT}
			RUNTIME
			DESTINATION ${CMAKE_BINARY_DIR}/bin/
			PERMISSIONS OWNER_EXECUTE OWNER_WRITE OWNER_READ)
endif()

设置secGear链接库,当指定模拟模式CC_SIM时链接libsecgearsim.so,否则链接libsecgear.so。 在iTrustee硬件环境上需指定安装固定的安全白名单。

4 编写安全侧代码、CMakeList.txt及基础配置文件

4.1 创建enclave目录 编写hello.c

#include <stdio.h>
#include <string.h>
#include "test_t.h"

#define TA_HELLO_WORLD        "secGear hello world!"
#define BUF_MAX 32
int get_string(char *buf)
{
	strncpy(buf, TA_HELLO_WORLD, strlen(TA_HELLO_WORLD) + 1);
	return 0;
}

test_t.h:该头文件为自动生成代码工具codegen通过edl文件生成的头文件。该头文件命名为edl文件名加"_t"。

4.2 编写CMakeList.txt文件

#set auto code prefix
set(PREFIX test)
#set sign key
set(PEM Enclave_private.pem)

设置enclave签名私钥

#set sign tool
set(SIGN_TOOL ${LOCAL_ROOT_PATH}/tools/sign_tool/sign_tool.sh)
#set enclave src code
set(SOURCE_FILES ${CMAKE_CURRENT_SOURCE_DIR}/hello.c)
#set log level
set(PRINT_LEVEL 3)
add_definitions(-DPRINT_LEVEL=${PRINT_LEVEL})

设置签名工具已经安全侧打印日志level

if(CC_GP)
        #set signed output
        set(OUTPUT ${UUID}.sec)

        set(WHITE_LIST_0 /vendor/bin/helloworld)
        set(WHITE_LIST_1 /vendor/bin/secgear_test)
        set(WHITE_LIST_OWNER root)
        set(WHITELIST WHITE_LIST_0 WHITE_LIST_1)

        set(AUTO_FILES  ${CMAKE_CURRENT_BINARY_DIR}/${PREFIX}_t.h ${CMAKE_CURRENT_BINARY_DIR}/${PREFIX}_t.c ${CMAKE_CURRENT_BINARY_DIR}/${PREFIX}_args.h)
        add_custom_command(OUTPUT ${AUTO_FILES}
        DEPENDS ${CURRENT_ROOT_PATH}/${EDL_FILE}
        COMMAND ${CODEGEN} --${CODETYPE} --trusted ${CURRENT_ROOT_PATH}/${EDL_FILE} --search-path ${LOCAL_ROOT_PATH}/inc/host_inc/gp)
endif()

WHITE_LIST_x:为设置iTrustee的二进制白名单,只有这里定义的白名单,在非安全侧的二进制才可以调用安全侧的动态库。上限为8个。 WHITE_LIST_OWNER:为设置运行二进制的用户,只有该用户才可以调用安全侧动态库。 AUTO_FILES:由edl文件生成的安全侧二进制文件

    if(CC_SGX)
        set(OUTPUT enclave.signed.so)
        set(AUTO_FILES  ${CMAKE_CURRENT_BINARY_DIR}/${PREFIX}_t.h ${CMAKE_CURRENT_BINARY_DIR}/${PREFIX}_t.c)
        add_custom_command(OUTPUT ${AUTO_FILES}
        DEPENDS ${CURRENT_ROOT_PATH}/${EDL_FILE}
        COMMAND ${CODEGEN} --${CODETYPE} --trusted ${CURRENT_ROOT_PATH}/${EDL_FILE} --search-path ${LOCAL_ROOT_PATH}/inc/host_inc/sgx --search-path ${SGXSDK}/include)
endif()

设置自动生成代码及签名动态库。

set(COMMON_C_FLAGS "-W -Wall -Werror  -fno-short-enums  -fno-omit-frame-pointer -fstack-protector \
		-Wstack-protector --param ssp-buffer-size=4 -frecord-gcc-switches -Wextra -nostdinc -nodefaultlibs \
		-fno-peephole -fno-peephole2 -Wno-main -Wno-error=unused-parameter \
		-Wno-error=unused-but-set-variable -Wno-error=format-truncation=")

set(COMMON_C_LINK_FLAGS "-Wl,-z,now -Wl,-z,relro -Wl,-z,noexecstack -Wl,-nostdlib -nodefaultlibs -nostartfiles")

设置安全侧便编译选项和链接选项。由于安全侧和非安全侧不同,非安全侧的标准动态库不能被安全侧链接。例如:"-nostdlib -nodefaultlibs -nostartfiles"

if(CC_GP)
	configure_file("${CMAKE_CURRENT_SOURCE_DIR}/manifest.txt.in" "${CMAKE_CURRENT_SOURCE_DIR}/manifest.txt")

	set(CMAKE_C_FLAGS "${COMMON_C_FLAGS}  -march=armv8-a ")
	set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS}  -s -fPIC")
	set(CMAKE_SHARED_LINKER_FLAGS  "${COMMON_C_LINK_FLAGS} -Wl,-s")

	set(ITRUSTEE_TEEDIR ${iTrusteeSDK}/)
	set(ITRUSTEE_LIBC ${iTrusteeSDK}/thirdparty/open_source/musl/libc)

	if(${CMAKE_VERSION} VERSION_LESS "3.13.0")
		link_directories(${SECGEAR_INSTALL_PATH})
	endif()

	add_library(${PREFIX} SHARED ${SOURCE_FILES} ${AUTO_FILES})

	target_include_directories( ${PREFIX} PRIVATE
		${CMAKE_CURRENT_BINARY_DIR}
		${LOCAL_ROOT_PATH}/inc/host_inc
		${LOCAL_ROOT_PATH}/inc/host_inc/gp
		${LOCAL_ROOT_PATH}/inc/enclave_inc
		${LOCAL_ROOT_PATH}/inc/enclave_inc/gp
		${ITRUSTEE_TEEDIR}/include/TA
		${ITRUSTEE_TEEDIR}/include/TA/huawei_ext
		${ITRUSTEE_LIBC}/arch/aarch64
		${ITRUSTEE_LIBC}/
		${ITRUSTEE_LIBC}/arch/arm/bits
		${ITRUSTEE_LIBC}/arch/generic
		${ITRUSTEE_LIBC}/arch/arm
		${LOCAL_ROOT_PATH}/inc/enclave_inc/gp/itrustee)

	if(${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.13.0")
		target_link_directories(${PREFIX} PRIVATE ${SECGEAR_INSTALL_PATH})
	endif()

	foreach(WHITE_LIST ${WHITELIST})
		add_definitions(-D${WHITE_LIST}="${${WHITE_LIST}}")
	endforeach(WHITE_LIST)
	add_definitions(-DWHITE_LIST_OWNER="${WHITE_LIST_OWNER}")

	target_link_libraries(${PREFIX} -lsecgear_tee)

	add_custom_command(TARGET ${PREFIX}
		POST_BUILD
		COMMAND bash ${SIGN_TOOL} -d sign -x trustzone -i lib${PREFIX}.so -c ${CMAKE_CURRENT_SOURCE_DIR}/manifest.txt -m ${CMAKE_CURRENT_SOURCE_DIR}/config_cloud.ini
		-o ${CMAKE_CURRENT_BINARY_DIR}/${OUTPUT})

	install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${OUTPUT}
		DESTINATION /data
		PERMISSIONS OWNER_EXECUTE OWNER_WRITE OWNER_READ GROUP_READ GROUP_EXECUTE  WORLD_READ  WORLD_EXECUTE)

endif()

manifest.txt:itrustee安全侧配置文件,后面对该文件进行详解 指定itrustee特性编译选项,设置引用头文件和动态库的路径。 前面声明的白名单在这里定义。 itrustee需要链接secgear_tee动态库,提供seal接口等。

if(CC_SGX)
	set(SGX_DIR ${SGXSDK})
	set(CMAKE_C_FLAGS "${COMMON_C_FLAGS} -m64 -fvisibility=hidden")
	set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS}  -s")
	set(LINK_LIBRARY_PATH ${SGX_DIR}/lib64)

	if(CC_SIM)
		set(Trts_Library_Name sgx_trts_sim)
		set(Service_Library_Name sgx_tservice_sim)
	else()
		set(Trts_Library_Name sgx_trts)
		set(Service_Library_Name sgx_tservice)
	endif()

	set(Crypto_Library_Name sgx_tcrypto)

	set(CMAKE_SHARED_LINKER_FLAGS  "${COMMON_C_LINK_FLAGS} -Wl,-z,defs -Wl,-pie -Bstatic -Bsymbolic -eenclave_entry \
		-Wl,--export-dynamic -Wl,--defsym,__ImageBase=0 -Wl,--gc-sections -Wl,--version-script=${CMAKE_CURRENT_SOURCE_DIR}/Enclave.lds")

	if(${CMAKE_VERSION} VERSION_LESS "3.13.0")
		link_directories(${LINK_LIBRARY_PATH})
	endif()

	add_library(${PREFIX}  SHARED ${SOURCE_FILES} ${AUTO_FILES})

	target_include_directories(${PREFIX} PRIVATE
			${CMAKE_CURRENT_BINARY_DIR}
			${SGX_DIR}/include/tlibc
			${SGX_DIR}/include/libcxx
			${SGX_DIR}/include
			${LOCAL_ROOT_PATH}/inc/host_inc
			${LOCAL_ROOT_PATH}/inc/host_inc/sgx)

	if(${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.13.0")
		target_link_directories(${PREFIX} PRIVATE
				${LINK_LIBRARY_PATH})
	endif()

	target_link_libraries(${PREFIX}  -Wl,--whole-archive ${Trts_Library_Name} -Wl,--no-whole-archive
				-Wl,--start-group -lsgx_tstdc -lsgx_tcxx -l${Crypto_Library_Name} -l${Service_Library_Name}   -Wl,--end-group)
	add_custom_command(TARGET ${PREFIX}
	POST_BUILD
	COMMAND openssl genrsa -3 -out ${PEM} 3072
	COMMAND bash ${SIGN_TOOL} -d sign -x sgx -i lib${PREFIX}.so -k ${PEM} -o ${OUTPUT} -c ${CMAKE_CURRENT_SOURCE_DIR}/Enclave.config.xml)
endif()

在SGX硬件环境上,指定一些与sgx相关的编译选项、链接选项。链接动态库时有所不同,因为itrustee是一个具有更多功能的安全操作系统。提供如muslibc和openssl。在编译和链接itrustee时不用链接一些基本库,但是sgx没有OS概念。所以要在安全侧调用这些基本库的接口都要以静态的形式在sgxsdk中给出。例如"sgx_trts"

有关更多详细信息,请参阅sgx示例的Makefile。最后用enclave配置文件完成签名,稍后将进行介绍。secGear尚不支持远程身份验证。

4.3 编写安全侧配置文件

编写与sgx enclave相关的配置文件中Enclave.config.xml文件及enclave.lds文件与官方sgx配置相同。详情参阅官方开发文档。

编写itrustee enclave相关配置文件 mainfest.txt.in:其中gpd.ta.appID 为动态生成uuid。其他配置参见itrustee开发文档。

5 构建 安装

进入开发目录:cd .../secGear/example/test/ 创建debug目录:mkdir debug && cd debug cmake构建:cmake -DCMAKE_BUILD_TYPE=Debug -DCC_SGX=ON -DSGXSDK=sgx_sdk path .. && make && sudo make install (sgx硬件环境) cmake -DCMAKE_BUILD_TYPE=Debug -DCC_GP=ON -DiTrusteeSDK=gp_sdk path .. && make && sudo make install (itrustee硬件环境)

Log

非安全侧日志记录:

非安全侧是开发与普通开发环境一样,可使用通用打印日志接口。

安全侧日志记录:

由于各架构安全能力不同的限制,为了像非安全侧一样开发使用日志打印功能,因为我们提供了PrintInfo接口将安全端日志记录到syslog系统中。 相关配置文件为 conf/logrotate.d/secgear和conf/rsyslog.d/secgear.conf文件,安装时将安装在系统目录/etc/中。

注意:在itrustee上,需要include secgear_log.h头文件,但是sgx不需要,sgx通过ocall功能实现的,所以相关代码生成在辅助代码中。 当文件安装成功后需要运行"systemctl restart rsyslog"使日志功能生效。

日志等级:

PRINT_ERROR    0
PRINT_WARNING  1
PRINT_STRACE   2
PRINT_DEBUG    3

使用ocall

目前ocall仅在sgx平台支持,itrustee尚不支持。

seal, generate_random接口

接口定义在secgear_dataseal.h、secgear_random.h中。 注意:由于itrustee派生密钥的功能仍然不完善,因此目前还没有与密封相关的接口在itrustee平台上支持。

远程证明(尚不支持)

了解更多关于codegener

secGear引入EDL(Enclave Description Language)和中间代码辅助生成工具codegener。edl与intel sgx定义兼容。

了解更多关于sign_tool

里程碑

secGear

空文件

简介

Confidential computing framework for developing enclave apps on top of hardware TEE 展开 收起
MulanPSL-2.0
取消

发行版

暂无发行版

贡献者

全部

近期动态

加载更多
不能加载更多了
1
https://gitee.com/blue0613/secGear.git
git@gitee.com:blue0613/secGear.git
blue0613
secGear
secGear
master

搜索帮助

14c37bed 8189591 565d56ea 8189591