SGX(Software Guard eXtensions)_linux构建可信执行环境(一):如何开发第一个最简单的 SGX 应用 HelloWorld
一、了解SGX 1.1SGX定义
Intel 软件防护扩展SGX(Software Guard Extension)是一项针对台式机和服务器平台的旨在满足可信计算需求的技术。Intel SGX是Intel架构新的扩展,在原有架构上增加了一组新的指令集和内存访问机制。
Intel在2015年从第6代Intel酷睿处理器平台开始引入了Intel软件防护扩展新指令集,使用特殊指令和软件可将应用程序代码放入一个enclave中执行。Enclave可以提供一个隔离的可信执行环境,可以在BIOS、虚拟机监控器、主操作系统和驱动程序均被恶意代码攻陷的情况下,仍对enclave内的代码和内存数据提供保护,防止恶意软件影响enclave内的代码和数据,从而保障用户的关键代码和数据的机密性和完整性。
1.2基本原理
SGX应用由两部分组成: untrusted 不可信区:代码和数据运行在普通非加密内存区域,程序main入口必须在非可信区。 trusted 可信区:代码和数据运行在硬件加密内存区域,此区域由CPU创建的且只有CPU有权限访问。
1.3两大机制 1.3.1保护机制 针对enclave的保护机制主要包括两个部分:一是enclave内存访问语义的变化,二是应用程序地址映射关系的保护。这两项功能共同完成对enclave的机密性和完整性的保护。
1.3.2 认证机制 SGX 提出了两种类型的身份认证方式:一种是平台内部 enclave 间的认证,用来认证进行报告的 enclave 和自己是否运行在同一个平台上;另一种是平台间的远程认证,用于远程的认证者认证 enclave 的身份信息。
本地证明:同一平台的两个Enclave之间的证明过程。
远程证明:Enclave和不在平台上的第三方之间的证明过程。
二、Linux下安装SGX
简介:我们需要安装几个东西。第一是驱动Drive,有了驱动才可以调用intel芯片里面的硬件部分。第二个是PSW(平台软件),其是允许支持SGX的应用程序在目标平台上执行的软件栈,包含四部分1.提供对硬件功能进行访问的驱动程序;2.为执行和认证提供多个支持库;3.运行所必需的架构型enclave;4.加载并与enclave进行通信的服务;。第三个是软件开发工具包(SDK)为开发人员提供了开发支持SGX的应用程序所需的一切,它由一个生成应用程序和enclave之间的接口函数的工具,一个在使用它之前对enclave进行签名的工具,一个调试它的工具以及一个性能检查的工具组成。另外,它还包含模板和样本参数,用于在Windows下使用Visual Studio开发enclave,或在Linux下使用Makefile。
有了这三样东西我们才可以进行代码开发
以Ubuntu20.04 LTS为例
硬件需求仅当安装sgx驱动和PSW时需要,安装sgx sdk并不需要硬件支持。
硬件不支持的情况下,可以在模拟环境下编写测试SGX程序,其中makefile里SGX_MODE=SIM。(虽然 SGX是基于硬件的,但是依旧可以使用软件条件进行模拟)
先安装驱动、PSW、SDK所需依赖
1 2 3 sudo apt-get update sudo apt-get install libssl-dev libcurl4-openssl-dev libprotobuf-dev sudo apt-get install build-essential python
下载Intel SGX驱动并安装
1 2 3 4 wget https://download.01.org/intel-sgx/sgx-linux/2.7.1/distro/ubuntu18.04-server/sgx_linux_x64_driver_2.6.0_4f5bb63.bin chmod +x sgx_linux_x64_driver_2.6.0_4f5bb63.binsudo ./sgx_linux_x64_driver_2.6.0_4f5bb63.bin sudo reboot
下载Intel SGX PSW并安装
1 2 wget https://download.01.org/intel-sgx/sgx-linux/2.7.1/distro/ubuntu18.04-server/libsgx-enclave-common_2.7.101.3-bionic1_amd64.deb sudo dpkg -i ./libsgx-enclave-common_2.7.101.3-bionic1_amd64.deb
下载并安装Intel SGX SDK
1 2 3 wget https://download.01.org/intel-sgx/sgx-linux/2.7.1/distro/ubuntu18.04-server/sgx_linux_x64_sdk_2.7.101.3.bin chmod +x ./sgx_linux_x64_sdk_2.7.101.3.bin./sgx_linux_x64_sdk_2.7.101.3.bin
添加环境变量,执行上一步结束时输出的命令
1 source /path/to/sgxsdk/environment
接下来进入到sgxsdk/SampleCode/SampleEnclave文件夹里
1 cd /path/to/sgxsdk/SampleCode/SampleEnclave
编辑一下Makefile
1 2 3 4 5 6 7 8 SGX_SDK ?= /home/luoyhang003/SGX/sgxsdk SGX_MODE ?= SIM SGX_ARCH ?= x64 SGX_DEBUG ?= 1
退出然后运行示例
注意一定要添加环境变量source /path/to/sgxsdk/environment,这行命令是临时环境变量,即存活时间为一个终端的市场,一旦重启或开启新的终端环境变量即会失效,需要手动添加。也可以永久化环境变量。
成功运行截图
三、文件结构与代码 目录结构
编译&运行
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 $ make GEN => App/Enclave_u.h CC <= App/Enclave_u.c CXX <= App/App.cpp LINK => app GEN => Enclave/Enclave_t.h CC <= Enclave/Enclave_t.c CXX <= Enclave/Enclave.cpp LINK => enclave.so <EnclaveConfiguration> <ProdID>0</ProdID> <ISVSVN>0</ISVSVN> <StackMaxSize>0x40000</StackMaxSize> <HeapMaxSize>0x100000</HeapMaxSize> <TCSNum>10</TCSNum> <TCSPolicy>1</TCSPolicy> <!-- Recommend changing 'DisableDebug' to 1 to make the enclave undebuggable for enclave release --> <DisableDebug>0</DisableDebug> <MiscSelect>0</MiscSelect> <MiscMask>0xFFFFFFFF</MiscMask> </EnclaveConfiguration> tcs_num 10, tcs_max_num 10, tcs_min_pool 1 The required memory is 3960832B. The required memory is 0x3c7000, 3868 KB. Succeed. SIGN => enclave.signed.so The project has been built in debug hardware mode. $ ./app Hello world Info: SampleEnclave successfully returned. Enter a character before exit ...
编译流程(Makefile)
通过 sgx_edger8r
工具在 App/
目录下生成不可信代码(Enclave_u.c 和 Enclave_u.h),这部分生成代码主要会调用 ECALL (sgx_ecall);
编译不可信部分 Binary: app
;
通过sgx_edger8r
工具在 Enclave/
目录下生成可信代码(Enclave_t.c 和 Enclave_t.h);
编译可信动态链接库(enclave.so);
通过sgx_sing
工具签名可信动态链接库(enclave.signed.so);
结束。
编译后目录结构
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 HelloWorld ├── app ├── App │ ├── App.cpp │ ├── App.h │ ├── App.o #[generated] │ ├── Enclave_u.c #[generated] │ ├── Enclave_u.h #[generated] │ └── Enclave_u.o #[generated] ├── Enclave │ ├── Enclave.config.xml │ ├── Enclave.cpp │ ├── Enclave.edl │ ├── Enclave.h │ ├── Enclave.lds │ ├── Enclave.o #[generated] │ ├── Enclave_private.pem │ ├── Enclave_t.c #[generated] │ ├── Enclave_t.h #[generated] │ └── Enclave_t.o #[generated] ├── enclave.signed.so #[generated] ├── enclave.so #[generated] ├── Include └── Makefile
HelloWorld
1.添加可信函数Encalve/Enclave.edl
1 2 3 4 5 enclave { trusted { public void ecall_hello_from_enclave ([out, size=len] char * buf, size_t len) ; }; };
2.在可信区域定义可信函数Enclave/Enclave.cpp
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 #include "Enclave.h" #include "Enclave_t.h" #include <string.h> void ecall_hello_from_enclave (char *buf, size_t len) { const char *hello = "Hello world" ; size_t size = len; if (strlen (hello) < len) { size = strlen (hello) + 1 ; } memcpy (buf, hello, size - 1 ); buf[size-1 ] = '\0' ; }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 #include <stdio.h> #include <string.h> #include <assert.h> # include <unistd.h> # include <pwd.h> # define MAX_PATH FILENAME_MAX #include "sgx_urts.h" #include "App.h" #include "Enclave_u.h" sgx_enclave_id_t global_eid = 0 ;int initialize_enclave (void ) { sgx_status_t ret = SGX_ERROR_UNEXPECTED; ret = sgx_create_enclave (ENCLAVE_FILENAME, SGX_DEBUG_FLAG, NULL , NULL , &global_eid, NULL ); if (ret != SGX_SUCCESS) { printf ("Failed to create enclave, ret code: %d\n" , ret); return -1 ; } return 0 ; } int SGX_CDECL main (int argc, char *argv[]) { (void )(argc); (void )(argv); const size_t max_buf_len = 100 ; char buffer[max_buf_len] = {0 }; if (initialize_enclave () < 0 ){ printf ("Enter a character before exit ...\n" ); getchar (); return -1 ; } ecall_hello_from_enclave (global_eid, buffer, max_buf_len); printf ("%s\n" , buffer); sgx_destroy_enclave (global_eid); printf ("Info: SampleEnclave successfully returned.\n" ); printf ("Enter a character before exit ...\n" ); getchar (); return 0 ; }
总结 即便最简单的 SGX HelloWold 也比较复杂,当然“安全性”和“成本”(技术壁垒门槛、开发成本、维护成本、物料成本等)总是成正比的,和“效率”成反比的。希望这篇文章对那些想入门开发 SGX 应用的用户有所帮助。