SGX 应用支持技术研究进展*

2021-05-18 11:28董春涛沈晴霓吴鹏飞吴中海1
软件学报 2021年1期
关键词:调用应用程序内存

董春涛,沈晴霓,罗 武,吴鹏飞,吴中海1,

1(北京大学 软件与微电子学院,北京 102600)

2(北京大学 信息科学技术学院,北京 100871)

3(北京大学 软件工程国家工程研究中心,北京 100871)

4(高可信软件技术教育部重点实验室(北京大学),北京 100871)

随着云计算与大数据技术的快速发展,越来越多的应用程序被部署到第三方数据中心和云平台中,如Amazon AWS[1]和Microsoft Azure[2].但是,这也带来了一系列安全问题,例如:应用程序在云平台以明文方式处理敏感数据,容易被云服务提供商或其他攻击者攻击.因此,应用程序必须能够抵御云服务提供商和其他攻击者的攻击.传统手段中,基于加密的保护技术[3-5]只能支持有限的运算操作,全同态加密[6]可以支持任意操作,但增加了大量的开销.当前,基于CPU 提供的可信执行机制是不可信环境中保护应用程序的重要手段,例如Intel 推出的SGX(software guard extensions)指令集扩展[7].

SGX 是一种基于内存加密和证明的硬件机制,可以为应用程序提供用户空间的可信执行环境enclave[8],并将程序执行和状态与底层操作系统(operating system,简称OS)、虚拟机管理程序、固件、I/O 设备等隔离开来,保障用户关键代码和数据的机密性与完整性不受恶意软件的破坏.SGX 的可信计算基(trusted computing base,简称TCB)仅包括CPU,避免了基于软件的TCB 自身存在安全漏洞的风险,提升了系统的安全性.同时,SGX 可以保障运行时的可信执行环境,抵御恶意代码对程序被保护内容的访问与篡改,进一步增强了系统的安全性.SGX强大的安全保障能力与性能保证,使其得到了广泛的应用与发展.但是SGX 在应用中也暴漏出诸多的瓶颈问题,如何解决这些瓶颈问题也成为了学术界和工业界的重要研究方向.本文通过整理和归纳相关研究工作,总结了目前SGX 应用面临的瓶颈问题,主要包括应用安全问题、应用性能瓶颈、应用开发的困难性和应用功能的局限性,并对这4 类问题的解决方案分别进行了分析和总结.

安全性是SGX 最基本和最重要的目标.SGX 可以为代码和数据提供机密性和完整性保证,但其在实际应用中依然会面临诸多的安全风险和威胁,例如过大的TCB、暴露过多的对外接口和敏感代码的安全划分与验证以及侧信道攻击[9-11]等.针对上述安全风险与安全威胁,学术界已经提出了多种方案,本文将其归纳为TCB 最小化、对外接口最少化、敏感代码的自动化生成与安全检测以及潜在的安全威胁分析与防护这4 种类型.

性能开销是目前制约SGX 应用推广的重要因素.SGX 为代码和数据提供机密性和完整性保证,同时也带来了较高的性能开销.SGX 性能开销主要包括进入和退出enclave 导致的enclave 切换开销、内存加解密开销和页替换(paging)开销这3 个方面.针对上述性能开销的原因,本文总结和梳理了目前研究工作中的性能优化方案,将SGX 性能优化归纳为模式(enclave)切换性能优化、内存加密优化和内存页替换这3 种技术.

应用开发困难也是制约 SGX 发展和推广的重要原因.Intel 公司为用户提供了软件开发包(software development kit,简称SDK),但是使用该SDK 开发SGX 应用程序却并不容易,甚至错误的使用方式会导致安全风险.目前,SGX 应用开发的困难问题主要包括敏感代码划分工作量大且无法直接支持旧有的应用程序、缺少安全检测与性能测试等辅助开发工具、支持的语言类型有限和缺少操作系统库(library OS)支持.本文总结了相关研究工作提出的SGX 应用辅助开发技术,主要包括安全开发语言、辅助开发工具和通用系统库等.

云环境是SGX 技术应用的主要场景,但是目前SGX 技术自身缺乏对虚拟机(vitual machine,简称VM)迁移和容器(container)等云平台常用功能的支持.很多研究工作针对SGX 缺乏的功能支持,对其功能进行了扩展,主要包括虚拟机迁移支持技术和容器支持技术.

本文第1 节对SGX 的相关概念进行概述,并介绍SGX 的关键机制和SDK.第2 节对SGX 的应用现状以及瓶颈问题进行总结.第3 节对SGX 应用的安全风险以及已有的安全防护技术进行总结.第4 节分析SGX 性能开销的原因,并对相关性能优化技术进行归纳.第5 节总结SGX 应用开发的困难性问题以及已有的SGX 应用辅助开发技术.第6 节总结目前已有的SGX 应用功能扩展技术.最后对全文进行总结,阐述SGX 应用支持技术仍然需要解决的问题并展望未来的研究方向.

1 SGX 概述

SGX 是在原有Intel 架构上扩展了一组新的指令集和内存访问机制[11],这些扩展能够在计算平台上提供一个可信的隔离空间,允许应用程序使用enclave[7]保障用户关键代码和数据的机密性和完整性,不受特殊权限恶意软件的破坏[12].SGX 整体架构如图1 所示.SGX 扩展指令集包括17 条新指令,其中5 条指令是用户指令,包括进入enclave(EENTER)、退出enclave(EEXIT)、恢复enclave(ERESUME)、获取密钥(EGETKEY)和证明时获取enclave 度量报告(EREPORT).其他12 条指令是系统指令,用户通过操作系统的SGX 驱动(driver)调用执行,主要包括 enclave 创建(ECREATE,EADD,EEXTEND,EINIT)、enclave 异步退出(AEX)、enclave 销毁(EREMOVE)、资源管理(EPA,ELDB/U,EWB,EBLOCK,ETRACK).因为enclave 的创建必须在内核空间中进行,而enclave 的交互仅限于用户空间应用程序,特权代码无法进入enclave,非特权代码无法创建enclave.

所有的enclave 代码和数据都存储在EPC(enclave page cache)中,EPC 是一块用来存放enclave 和SGX 数据结构[7]的被保护的物理内存区域,EPC 内存以页为单位进行管理,对EPC 页进行访问控制的元数据信息保存在硬件结构EPCM(enclave page cache metadata)里.SXG 应用开发需要将应用程序分为可信和不可信两个部分,两部分之间通过用户定义的Ecall 和Ocall 代码进行调用.

Fig.1 Architecture description of SGX图1 SGX 整体架构

1.1 SGX安全机制

SGX 旨在保护enclave 内计算的机密性和完整性,抵御恶意软件攻击和物理攻击.SGX 技术主要包括隔离执行、认证(attestation)和密封(sealing)这3 个核心机制.本小节对SGX 的相关核心安全机制进行介绍.

1.1.1 隔离执行

SGX 的核心概念就是enclave,它是一个被保护的安全容器,用于存储应用程序的敏感数据和代码[13,14].Enclave 内除代码和数据以外,还包括元数据和TCS(thread control structure),TCS 用于保存进入或退出enclave时恢复enclave 线程的特殊信息(如图2 所示).EPC 是PRM(processor reserved memory)的一部分,PRM 则是内存的一部分,BIOS 通过配置一组范围寄存器分配PRM,系统软件或外围设备无法访问.

Fig.2 SGX sample layout of PRM and EPC图2 PRM 和EPC 布局示意图

图2 是一个PRM 和EPC 布局示意图.EPC 内存以页为单位进行管理,对EPC 页进行访问控制的元数据信息保存在硬件结构EPCM 里,一个enclave 页面对应一个EPCM 表项.通过处理器的访问控制,可以保证每个EPC页面只能映射到特定的虚拟地址,确保每一个EPC 页只允许与其相关联的enclave 访问.

Enclave 中的代码、数据和TCS 等在运行过程中始终被加密存储在内存中.处理器缓存(cache)中的数据在写到内存之前,处理器中的内存加密单元(memory encryption engine,简称MEE)会对其进行加密,因此操作系统无法直接获取EPC 中的内容,保证了应用程序代码和数据在运行过程中不受特权系统软件的攻击.SGX 的内存保护机制可以保证enclave 外部的应用程序不能访问enclave 内存,enclave 内部的代码在EPC 范围内只能访问属于自己的内存,不能访问其他enclave 的内存.这样的内存保护机制防止了enclave 内部运行的程序被其他恶意软件盗取和篡改隐私信息;同时,保证了在物理上锁住EPC 内存区域,将外部的访问请求视为访问了不存在的内存,使得外部的实体(直接存储器访问等)无法访问.

应用程序在申请创建一个enclave 时,需要进行页面分配(ECREATE)、复制程序代码与数据(EADD)和度量操作(EEXTEND).Enclave 被加载以后,需要进行完整性验证,以判断特权软件在创建enclave 过程中是否篡改了程序和数据.在enclave 初始化之后(EINIT),不可信任的代码(在enclave 外)执行可信代码(在enclave 内)的唯一方法是调用EENTER 指令.EENTER 执行上下文切换到enclave,保存不可信代码的状态,并恢复可信代码的最后已知状态.该上下文切换在概念上类似于用于英特尔 VTX 技术中的虚拟机上下文切换的VMENTER 和VMEXIT[15].

SGX SDK 提供了封装代码,称为ecall[16],用于准备执行环境并调用EENTER 指令.由于enclave 以用户级权限运行可信代码,因此enclave 无法访问硬件或其他系统资源.为了访问外部资源,例如文件系统、网络或时钟,enclave 必须退出到不可信代码,它可以通过EEXIT 指令完成.EEXIT 执行反向上下文切换并切换回不可信的代码.执行此操作的SDK 封装代码称为ocall[16].为了避免泄漏隐私数据,正在执行enclave 代码的CPU 不直接处理中断、故障(例如页面错误)或虚拟机退出.相反,CPU 首先执行AEX(asynchronous enclave exit)从enclave 代码切换到非enclave 代码,然后才处理中断故障或VM 退出.

1.1.2 认 证

在enclave 初始化之前,代码和数据是公开的,敌手可窃取和篡改.SGX 提供一个证明指令EREPORT 来抵御敌手窃取和篡改初始化之前的代码和数据.具体地,enclave 通过调用EREPORT 产生一个硬件签名的enclave 度量值报告,并发送给验证方进行证明.SGX 支持本地认证和远程认证两种类型的身份认证方式[7,17]:本地认证用于平台内部enclave 之间,用来认证报告的enclave 和自己是否运行在同一个平台上;远程认证则是用于平台之间,用于远程认证者认证enclave 的身份信息.

当enclave 向平台上其他enclave 报告身份时,首先要获取自身的身份信息和属性以及平台硬件TCB 信息,附加上用户希望交互的数据,生成报告结构(report structure).然后获取目标enclave 的报告密钥,对报告结构生成一个消息认证码(message authentication code,简称MAC)标签,形成最终的报告结构,传递给目标enclave,由目标enclave 验证请求报告身份的enclave 与自己是否运行于同一平台.远程认证则需要引入一个引用(quoting)enclave,由引用enclave 创建用于平台认证的签名密钥EPID(enhanced privacy identification).被认证enclave 首先执行EREPORT 指令,将身份和附加信息生成报告结构,并利用引用enclave 的报告密钥生成一个MAC 标签,一起发给引用enclave.引用enclave 通过该结构验证被认证enclave 是否运行于同一平台,然后将它封装为一个引用结构体QUOTE,并使用EPID 进行签名,将QUOTE 和签名一同发送给远程认证者.远程认证者验证enclave报告是否由可靠的Intel 处理器生成.

1.1.3 密封

密封是指enclave 使用EGETKEY 指令获取一个硬件产生的封装密钥对enclave 数据进行加密,并将加密数据存储在enclave 之外不可信存储中的过程[17].Enclave 数据根据enclave 的标识(MRENCLAVE)或签名标识(MRSIGNER)进行密封,对MRENCLAVE 加密的数据只能由相同的enclave 解密,而对MRSIGNER 加密的数据可以由同一开发人员签名的任何enclave 解密.在这两种情况下,密封密钥都来自特定于CPU 的密钥,因此数据只能在它被密封的同一台物理机器上打开.SGX 密封保证了密封数据的机密性和完整性,但不会自动提供回放(roll-back)保护.如果需要,enclave 开发人员必须检查已提供的密封数据的版本是否正确,通常通过使用安全单调计数器(monotonic counter)来实现.

1.2 SGX管理机制

1.2.1 SGX 内存管理机制

Enclave 与主机程序共用一片虚拟地址空间,部分enclave 中映射到EPC 页的虚拟内存称为enclave 线性地址空间(enclave linear address range,简称ELRANGE).这段地址空间在EPC 分配终止后,对于主机进程来说是不能访问的.任何试图读写ELRANGE 地址空间的enclave 外部代码都会产生一个未定义行为的错误.

Enclave 执行总是在受保护模式下,并由OS 内核或hypervisor 进行地址转换.SGX 为了不影响传统OS 对平台资源的管理和分配,实现enclave 中的页到EPC 中帧转换的页表(page table)仍由OS 管理[7].OS 和hypervisor完全控制页表和扩展页表(extended page table,简称EPT),enclave 代码使用与其主机应用程序相同的地址转换过程和页表.由于操作系统或hypervisor 是不可信的,因此CPU 必须要防止对enclave 的地址转换攻击[10].当从EPC 页地址转换到物理地址时,CPU 使用在SGX enclave 控制结构(SGX enclave control structure,简称SECS)中存储的初始分配信息来保证传递给地址转换过程的EPC 页虚拟地址与EPCM 中保留的EPC 入口地址相匹配.以此来防止操作系统将ELRANGE 地址映射到不受保护的内存,使得ELRANGE 内存对enclave 之外的软件不可见.

1.2.2 EPC 页驱逐(eviction)

操作系统可以将EPC 页面驱逐到不可信的DRAM 中,并将其加载回来,如图3 所示.系统软件使用EWB 指令驱逐EPC 页面,该指令产生ELDU 指令恢复被驱逐页面所需的所有数据[7].SGX 通过加密(EGETKEY)来保证被驱逐的EPC 页面存储在不可信内存中时的机密性和完整性.EWB 和ELDU/ELDB 指令使用一个ID 来识别拥有被换出页面的enclave.EWB 驱逐EPC 的内容时,会创建一个8 字节的随机数,称为页面版本(page version).SGX 的新鲜度(freshness)保证则建立在安全存储页面版本的假设之上,因此,EWB 将其存储在一个版本数组(version array,简称VA)中,VA 页面也可以驱逐.被驱逐的页面依赖于存储其页面版本的VA 页面,在VA 页面被重新加载之前无法被重加载到EPC 中.基于这种依赖关系创建的关系图称为驱逐树(eviction tree).驱逐树将EPC 页面作为叶子,将VA 页面作为内部节点.页面的父节点是存储其页面版本的VA 页面[7].

Fig.3 EPC pages evicted into non-PRM DRAM图3 EPC 页驱逐到非PRM 内存

1.3 SGX SDK

为了简化SGX 应用程序的开发,Intel 发布了SDK[14].它向开发人员隐藏了SGX 硬件细节信息,并引入了ecall 和ocall 的概念,分别用于进入和退出enclave,如同普通的函数调用那样.通过使用SGX SDK,开发人员可以创建加载到enclave 的代码,并定义enclave 代码与其他不可信的应用程序代码之间的ecall 和ocall 接口.

Intel 提供了一个名为edger8r 的边缘函数创建工具,用于自动生成ecall 和ocall 的安全封装代码.要自动生成ecall 和ocall 代码,开发人员必须使用SGX 规定的语法,在enclave 描述语言(enclave description language,简称EDL)扩展文件中声明ecall 和ocall 函数.然后,edger8r 解析EDL 文件生成封装代码,如图4 所示.Ecall 和ocall被认为是边缘函数(edge function),因为对它们的执行会跨越安全边界.函数的参数需要编组(marshall),并从加密内存复制到明文内存,反之亦然.为了边界交互的安全,需要对调用的参数执行多项安全检查,特别是在参数是指针的情况下.Enclave 代码必须验证所访问数据的完整性,如ecall 的参数、ocall 的返回值和从不可信内存读取的数据.

Fig.4 Process of edger8r generates wrapper code from EDL file图4 Edger8r 解析EDL 文件生成封装代码的过程

Enclave 支持多线程,因此需要同步原语.由于在enclave 内部无法进行睡眠等待,因此,SGX SDK 提供的enclave 内部同步原语实现了通过ocall 以在enclave 外部进行睡眠等待.SDK 提供的互斥锁的工作方式如下:如果线程尝试锁定未锁定的互斥锁,则此操作成功完成而无需离开enclave.每当线程尝试锁定已锁定的互斥锁时,它将进入队列并通过ocall 退出enclave 进入睡眠状态;然后,持有互斥锁的线程需要通过进入队列并通过ocall离开enclave 来唤醒睡眠线程.因此,SGX SDK 提供的互斥锁会导致两次ocall,开销比较大.

2 SGX 应用现状及瓶颈问题

SGX 技术推出以来,受到了学术界和工业界的极大关注,目前在很多领域已经得到了广泛的应用,如文献[18]重点讨论了SGX 在保障应用与网络安全方面的应用研究进展.但是,SGX 在应用的同时也暴露出很多安全缺陷,如Wang 等人重点讨论了针对SGX 的侧信道攻击和防御方面的研究进展[19].事实上,除了侧信道问题,SGX应用还暴露出了许多其他安全性问题、性能瓶颈、开发困难、功能局限等诸多应用方面的问题.本节首先介绍SGX 目前的应用现状,然后总结SGX 在应用中暴露出的诸多问题,最后对SGX 应用支持技术的研究方向进行总结.

从应用的场景来看,SGX 可以用于构建安全的云应用[20-22],用于保护网络通信[23-27]以及增强本地应用的安全性[28-31].SGX 首先被应用在云计算安全领域,如构建云平台应用安全隔离执行环境[32]、构建云平台大数据安全可信计算环境[33,34]和对虚拟化技术的支持[35].例如,Hunt 等人提出的Ryoan 系统[32],利用enclave 实现了一个分布式沙箱来保护沙箱实例不受潜在恶意平台的攻击.Schuster 等人提出的VC3 框架[33],基于SGX 实现了保护代码和数据的机密性和完整性mapreduce[36]框架.Brenner 等人提出的Securekeeper 框架[21],通过设计存储数据的加解密方案和在enclave 中对数据处理的方式,实现了对管理数据隐私性和完整性的保护.Arnautov 等人设计了一个用于Docker[37]的安全容器环境SCONE[35],利用SGX 来保护Docker 容器内进程免受外部攻击.微软与英特尔协作利用SGX 以增强云中的安全性,帮助数据和代码在使用过程中得到更强的保护[38].IBM 利用英特尔SGX 配合IBM Cloud Data Shield 以帮助保护使用中的数据[39].

SGX 也被用于保护网络通信安全和本地应用安全.如在文献[23]中,作者提出一种保护方案(S-NFV),利用SGX 对网络功能虚拟化(network function virtualization,简称NFV)产生的状态进行安全隔离保护.Andrew 等人提出的Haven 系统[30],通过修改Drawbridge 沙箱[40]实现了Windows 应用直接在沙箱中的enclave 内安全运行,为Windows 应用提供了安全保障.

除了应用于云计算、网络通信和本地应用以外,许多解决方案都受益于SGX 提供的安全保护,包括多方计算[41]、机器学习[42,43]、区块链[44-46]、人工智能和生物识别技术保护等.例如,文献[44]介绍了一种基于SGX 区块链资源挖掘框架REM(resource-efficient mining),REM 利用SGX 的安全保证实现了有效工作量证明(proof-ofuseful-work,简称PoUW),以提供可信的工作负载报告.UCloud 引入了SGX 技术,为智能合约提供了区块链所不能提供的机密性,可拓展的计算节点也解决了区块链本身无法应对复杂应用场景的问题.在保留区块链去中心化、用户互信的基础之上,通过可信硬件执行机密性高、需要相对复杂计算能力的程序,并通过区块链对执行结果进行记录和验证,实现可追溯的特性[96].Ekiden 同样使用SGX 保证智能合约的机密性,并利用SGX 可信性提高区块链的共识效率[47].蚂蚁金服金融科技推出的可信计算云服务则是将蚂蚁区块链自主研发的虚拟机内嵌在SGX 可信执行环境中,在数据保密的通用链下能够实现智能合约[48].

SGX 技术目前被广泛地应用到各个领域,同时,SGX 技术在应用中也暴露了诸多瓶颈问题.如何解决SGX在应用中的瓶颈问题,也成为学术界的研究热点.本文首先对目前SGX 技术相关应用和研究工作进行了梳理和总结,将SGX 技术应用的瓶颈总结为以下3 个方面.

• 应用安全问题.SGX 在TCB 大小、enclave 接口等SGX 应用程序设计方面存在诸多安全隐患,同时也面临侧信道攻击、内存攻击和硬件攻击等传统的安全威胁;

• 应用性能瓶颈.SGX 在内存加密、执行模式切换(包括ecall、ocall 和AEX)和内存页替换等方面存在高昂的性能开销,这严重制约了SGX 的应用和推广;

• 应用开发的困难性和功能的局限性.Intel 公司提供的SDK 虽然简化了SGX 的使用,但仍需程序员手动地将应用程序划分为可信和不可信两部分,不能直接无缝对接原有的应用程序,导致SGX 应用程序的开发工作量很大.SGX 提供了强大的安全功能,但对虚拟机迁移和容器等云平台常用技术支持不足,难以满足当前云平台应用对SGX 的需求.

针对SGX 技术的上述应用瓶颈问题,工业界和学术界进行了具体的分析,并提出了相应的解决方案.本文总结了相关文章,主要包括CCS、S&P、NDSS 等顶级会议,对这些工作进行了总结和分类,见表1,主要可以分为三大类.

Table 1 Related researchs of SGX application supporting techniques表1 SGX 应用支持技术相关研究工作

• 安全增强:分析SGX 应用存在的安全风险和面临的安全威胁,并提出增强SGX 应用安全性的相关方案.目前,SGX 应用安全增强方案主要有TCB 最小化、对外接口最少化、敏感代码安全生成与检测和潜在安全威胁的分析与防护等;

• 性能优化:分析SGX 性能开销的原因,并提出相应的性能优化方案.目前,改进SGX 应用性能的解决方案主要包括减少模式切换(enclave 切换)开销、减少页替换开销以及减少对enclave 内存页的使用和访问等;

• 易用性改进:主要包括SGX 应用辅助开发技术和功能扩展技术.应用程序辅助开发技术主要包括安全开发语言、辅助开发工具以及通用系统库和函数库等;功能扩展则主要包括对虚拟机迁移和容器等云平台常用技术的支持方案等.

通过上述对SGX 应用支持技术研究现状的总结和分类,可以将SGX 应用程序支持技术的目标归纳为安全、性能和易用性这3 个方面.这3 个目标不是相互独立的,而是互相关联和影响的,如TCB 大小就会关系到应用的安全和性能.

本节首先介绍了SGX 技术的应用研究现状,分析了SGX 应用中暴露出的安全性问题、性能瓶颈、开发困难、功能局限等诸多方面的问题,然后将SGX 应用支持技术的研究方向概括为SGX 应用安全增强技术、SGX应用性能优化技术、SGX 应用程序辅助开发支持技术和SGX 应用功能扩展技术这4 个方向.本文第3 节~第6节将分别从这4 个方面进行详细的分析和总结.

3 SGX 应用安全防护技术

SGX 通过一系列技术来保护程序的安全,并且将系统的可信计算基缩小到CPU,相比以往将整个操作系统或特权软件(如hypervisor)视为可信计算基,可以避免更多的系统攻击带来的危害.但是SGX 在实际应用中依然会面临诸多的安全风险,如过大的TCB 和暴露过多的外部接口等.本文将SGX 应用程序设计和开发时需要考虑的安全风险归纳为以下4 个方面.

• TCB 的大小.有研究[70,71]表明,软件漏洞的数量以及潜在的安全漏洞会与代码大小成比例地增加.尽可能地减小TCB,可以有效地减少enclave 内部代码漏洞潜在的安全风险;

• 外部接口的多少.由于enclave 需要与不可信区域进行交互,外部接口就成为不可信操作系统的攻击面,控制主机操作系统的攻击者可以使用此接口来破坏在enclave 内运行的进程或者推测出敏感信息.因此,设计enclave 程序时需要考虑到该隐患;

• 开发的工作量和可靠性.SGX 程序开发最重要的是需要将代码划分为敏感和非敏感两部分,SGX SDK目前不支持现有的应用程序直接运行在SGX 环境中,SGX 程序开发需要经验和时间,并且不合理的敏感代码划分可能会破坏enclave 代码的安全性.因此,开发时需要充分考虑敏感代码划分的工作量和可靠性;

• 面临的安全威胁.有研究表明,SGX 面临着侧信道攻击[9-11]、内存攻击[55,72]等多种攻击的威胁.开发SGX 应用程序时也需要考虑到这些安全威胁.比如,enclave 中的数据处理过程如果依赖于外部数据,攻击者可以通过一些不合法输入,发起对enclave 的缓冲区溢出攻击,这些攻击可能会改变可信区中程序的执行流程以及获取可信区中的敏感信息.

针对SGX 目前在应用中存在的上述安全问题,工业界和学术界提出了很多解决方案,本文对相关解决方案进行了梳理和总结,具体分类如下.

• TCB 最小化.SGX 应用程序的TCB 由enclave 代码和可信硬件组成.根据最小特权原则[73],只有应用程序中需要访问敏感数据的代码才应在enclave 内执行.最小化TCB,可以保证enclave 内部代码面临尽可能少的威胁;

• 对外接口最少化.除了TCB 大小外,enclave 对外接口的复杂性同样会影响enclave 内部代码和数据的安全性.减小enclave 和不可信操作系统之间的接口,可以减小暴露的攻击面,从而减小攻击者成功攻击的可能性[70];

• 敏感代码的安全生成与检测.利用自动化的开发工具对SGX 应用程序的代码进行自动划分,可以极大地减少开发人员的工作量;通过对enclave 代码进行安全检测,可以有效地增强敏感代码的安全性;

• 潜在的安全威胁防护.本文针对常见的潜在安全威胁进行了分析和总结,并给出了目前研究中已有的防护方案和相关的开发建议.

本节下面将对这4 类方案进行详细的介绍和分析.

3.1 TCB最小化

3.1.1 TCB 安全风险分析

本小节首先来分析TCB 大小对SGX 应用程序安全性的影响.目前使用SGX 的应用在TCB 中enclave 代码部分的大小设计方面有3 种选择.

• 预定义的少量专用敏感代码:将尽可能少的代码放入enclave 中,一般只将需要直接处理敏感数据的代码放入enclave 中,如VC3[33],只将处理数据的map/reduce 函数放入enclave,而将其他不完全可信的平台代码排除在enclave 外,这样可以避免平台可能存在的安全漏洞威胁enclave 内代码和数据安全;

• 完整的应用程序及其依赖的库:将应用程序和enclave 内程序运行时所依赖的系统库和函数库等部署在enclave 内,如Haven[30]、SCONE[35]和Graphene[51]等系统,采用的方案是,在enclave 内部署函数库或系统库来支持执行完整的应用程序.安全敏感和不敏感的应用程序代码和数据都位于enclave 内,提高了性能,但从TCB 的角度来看,却增加了enclave 内部代码和数据面临的安全风险;

• 从特定应用中划分出敏感代码:将应用程序中的敏感代码划分出来作为TCB,这里的敏感代码除直接处理敏感数据的代码外,还可能包括其他间接处理敏感数据的代码以及与enclave 内部代码交互频繁的代码等.这类方案需要程序开发人员手动划分应用程序,开发工作量大,并且划分敏感代码缺乏参考标准,如果敏感代码划分得不够合理,可能会破坏enclave 内代码和数据的安全性.

另外,目前SGX v1 版本支持的enclave 最大为128M(应用程序实际能使用约93M),一旦TCB 大小超过93M,就会触发频繁的页替换,增加了安全风险和性能开销.SGX v2 有可能进一步扩展SGX 的可用物理内存,但目前Intel 官方还未发布相关资料.

3.1.2 最小化TCB 的安全方案

最小特权原则下,应该最小化TCB,从而减少enclave 内部漏洞造成的威胁.最小化TCB 的相关安全方案一般仅把支持功能,或者敏感部分放入enclave.应用程序必须遵守预定义的受限制的enclave 接口[21,33,49].这些工作的核心是使用SGX 提供的enclave 保证运算的机密性,同时保证enclave 尽可能地小.

Schuster 等人提出的VC3 系统[33]就是采用了最小化TCB 的设计方案.VC3 使用分布式系统Hadoop[36]中计算节点提供的enclave 来保护map/reduce 任务的代码和数据,并严格限制map/reduc 任务仅通过特定的接口与不可信的环境进行交互.VC3 将未经修改的Hadoop 和操作系统均排除在TCB 之外,最小化了TCB,从而减少了enclave 内部代码和数据面临的安全风险.因此,即使Hadoop 和操作系统受到损害,也可以保证map/reduce 任务代码和数据的机密性和完整性.并且,VC3 通过部署协议以保护分布式MapReduce 计算结果的安全性和可验证性.VC3 在TCB 最小的情况下,保证了数据和代码的完整性和机密性,并保证了计算结果的可验证性,但是由于map/ reduce 任务只能通过特定的接口与不可信环境交互,因此其支持的功能非常有限.

Brenner 等人提出的保证所管理数据的隐私性和完整性的ZooKeeper[74]框架Securekeeper[21]同样采用最小化TCB 的设计方案.SecureKeeper 系统通过设计所存储数据的加解密方案和在enclave 中对所管理数据进行处理的方式,将轻量修改的ZooKeeper 和操作系统排除在TCB 之外,将系统的TCB 保持在很小的水平,从而使在不可信环境下数据的隐私性和完整性得到了有效的保证.

Shinde 等人提出的PANOPLY 系统[49]旨在最小化SGX enclave 应用程序TCB,同时又能为enclace 代码提供丰富的操作系统抽象.PANOPLY 提出了一种称为微容器(micro-container or micron)的新概念,微容器是运行在enclave 中应用程序的逻辑单元,微容器将标准的Linux 抽象提供给应用程序.例如,除支持标准Linux 系统调用外,启用微容器的应用程序还可以使用多进程、多线程、事件注册/回调(例如信号).PANOPLY 可以将应用程序分成一个或多个微容器,或者通过导入微容器库来增强安全性,如图5 所示.同时,PANOPLY 保证enclave 间交互的完整性,确保即使操作系统出现异常,应用程序的执行也仍然遵循合法的控制和数据流.

PANOPLY 将最小化TCB 优先于性能作为目标.与以前的系统(例如操作系统库解决方案SGXKernel[50]、Graphene[51])不同,PANOPLY 使用了一种简单的委托而不是模拟的设计理念,将操作系统抽象的实现委托给底层操作系统,而不是在enclave 内进行仿真.PANOPLY 微容器只需要通过执行少量检查来抵御操作系统的恶意响应.这种设计消除了在enclave 内模拟基础操作系统的大量工作.通过这种设计,PANOPLY 提供的应用程序TCB 比以前的操作系统库系统的数量级小2 个数量级.

Fig.5 Panoply system overview图5 Panoply 系统概况

3.2 对外接口最少化

3.2.1 Enclave 接口的安全风险分析

由于enclave 处于用户态,自身无法执行系统调用,需要与不可信区域进行交互,enclave 必须向主机操作系统公开外部接口.外部接口则会成为不可信操作系统的攻击面,控制主机操作系统的攻击者可以使用此接口来破坏在enclave 内运行的进程并推测敏感信息,增大了安全风险和性能开销.如Iago 攻击[75],这是来自不受信任的操作系统对应用程序的语义攻击,其中未经检查的系统调用返回值或许会影响应用程序.Iago 攻击难以进行全面检测,至少对于当前的可移植操作系统接口(portable operating system interface,简称POSIX)[76]或Linux 系统调用表接口而言是这样.因此,任何SGX 框架都必须提供隔离支持,以验证或拒绝来自不受信任的操作系统的输入.接口复杂性直接影响隔离的复杂性,如操作系统库或填充(shim)库可以减小enclave 接口的数量和复杂性,从而降低Iago 攻击成功的风险.

总之,系统调用的返回值必须进行检查以防止Iago 攻击.创建有原则的enclave 接口可以更容易地抵御特定攻击.决定是否采用特定方案,使用enclave 保护应用程序安全的重要判定原则是开发工作量及其是否适用于任何应用程序.目前主要有3 种enclave 接口方案.如图6 所示.

Fig.6 Design alternatives for the use of enclaves图6 Enclave 设计选择方案

• 完整的enclave 接口:在enclave 为应用程序提供完整的系统库支持,减少enclave 与不可信的系统之间的交互,如在enclave 提供库支持.例如,Graphene[51]是在enclave 中使用一个操作系统库来支持快速部署未修改的Linux 应用程序;

• 预定义的enclave 接口:如图6(b)所示,遵守预定义的受限制的enclave 接口.例如,VC3[33]强制map/reduce 任务仅通过特定的接口与不可信的环境进行交互;

• 特定应用程序的enclave 接口:如图6(c)所示,针对特定的应用程序划分可信与不可信代码,并设计相关的enclave 接口.该方案开发要求高、工作量大,且无法在应用程序之间通用.

3.2.2 减少对外接口的安全解决方案

减少enclave 接口方案一般会在enclave 内设置操作系统库或者标准函数库来支持enclave 内应用程序的执行,从而减少enclave 内代码与操作系统之间的交互,例如Haven[30]、SGXKernel[50]、Graphene[51]和SCONE[35]等等.

Haven[30]使用Drawbridge[40]操作系统库直接运行未修改的Windows 应用程序.Haven 基于drawbridge 沙箱机制,为用户程序的运行提供了一个微处理(picoprocess)容器,从而保证运行在里面的用户程序无法对外界系统造成破坏;再在容器中创建一个enclave,将用户程序、系统库和防护模块(shield module)放进enclave 中,以防止这些数据和代码被外界的特权软件或恶意程序所访问和篡改.系统库通过向下调用(downcalls)和向上调用(upcalls)的方式与drawbridge 主机进行交互,用来完成用户程序需要的系统功能,防护模块配合检查函数的参数和返回结果,进而保护用户程序的安全执行.

Graphene[51]则是在enclave 中部署一个操作系统库来支持在SGX 上快速部署未修改的Linux 应用程序.Graphene 为SGX 提供了一个端口以及一些SGX 改进措施,例如动态加载库(dynamically-loaded libraries)的完整性支持和安全多进程(secure multi-process)支持.Graphene 开销与使用填充层(shim library)的应用程序相近,大多数单进程应用的性能开销小于2 倍,Graphene 目前已经开源.SGXKernel[50]也是在enclave 内实现了一个操作系统库,通过结合异步交叉enclave 通信和可抢占的enclave 多线程避免enclave 切换,其性能明显优于Haven和Graphene.SCONE[35]则是在enclave 中配置了标准C 函数库的修改版本来支持重新编译的Linux 应用程序.

文献[64]在enclave 接口的安全设计方面给出了3 个建议.

(1)SDK 允许将ecall 定义为公有或私有[16]:公有ecall 可以随时被调用,而私有ecall 只能在ocall 中被调用.将ecall 定义为私有可以限制调用ecall 的途径来增强enclave 的安全性;

(2)开发人员必须精确指定每个ocall 中允许哪些ecall 调用.如果没有指定特定的ecall,则在执行期间会触发错误.如果开发人员未考虑特定的ecall/ocall 组合,则攻击者可能会利用它来更改程序执行的控制流并获得对特定机密的访问权限;

(3)EDL 文件定义了作为ecall 和ocall 参数传递的指针的行为,其中,user_check 标明是否将指针留给开发人员.然而,user_check 可能带来安全漏洞,例如缓冲区溢出、time-of-check-to-time-of-use 攻击[77]或传递enclave 内地址[78].因此,在进行enclave 接口设计时,需要检查并限制指针如何在enclave 接口中传递和使用.

3.3 敏感代码的自动化生成与安全检测

SGX 应用程序开发的关键是将应用程序划分为敏感代码与非敏感代码两部分,到底将哪些代码作为敏感代码放入enclave 中目前还缺乏标准化的方法,并且划分的敏感代码是否安全和合理也缺乏相应的验证方法.总的来说,SGX 应用程序开发所面临的困难主要有以下3 个方面.

• 开发工作量大:针对每一个应用程序进行开发,不仅需要开发人员具备丰富的开发经验和安全背景,同时也需要进行大量的开发工作;

• 通用性:目前需要开发人员针对每一个应用程序进行手动划分,缺乏通用性的解决方案.当前,SGX SDK 没有提供相关支持;

• 敏感代码划分的合理性和安全性:划分的敏感代码需要进行安全性和合理性验证,以确认划分出的敏感代码是否存在安全漏洞.

因此,如何对enclave 的敏感代码进行自动化划分且保证划分结果的可靠性,是SGX 应用程序开发需要解决的问题.目前,相关工作分别实现了对程序敏感代码的自动化划分和对enclave 代码的安全检查等.

3.3.1 敏感代码自动划分技术

文献[52]提出了一个用于开发C 语言SGX 应用程序的源码划分框架Glamdring.通过开发人员对安全敏感应用程序数据的注释,Glamdring 可以自动地将应用程序划分为可信和不可信代码两部分,如图 7 所示,Glamdring 的操作分为4 步.

(1)代码注释:开发人员通过注释需要机密性和完整性保护的变量来提供有关安全敏感数据的输入和输出信息;

(2)代码分析:Glamdring 基于带注释的源代码,使用数据流分析来识别可能处理敏感数据的函数,并使用向后切片来识别可能会间接影响敏感数据的函数.将直接或者间接访问或者影响敏感数据的代码标记为敏感代码.因此,Glamdring 获得了处理敏感数据或影响其完整性的最小代码集;

(3)代码划分:接下来,Glamdring 创建一个划分规范(partition specification,简称PS),该规范定义了必须由enclave 保护的代码.PS 会根据程序分析枚举敏感的函数、内存分配和全局变量;

(4)代码生成:Glamdring 使用源到源编译器(source-to-source compiler)基于PS 将代码分为敏感和非敏感的代码,然后将敏感代码放置在enclave 内,并在enclave 边界自动添加运行时检查和加密操作,以保护其免受攻击.

Fig.7 Overview of the Glamdring framework图7 Glamdring 架构

Glamdring 保护了敏感输入数据的机密性和敏感输出数据的完整性,基于最小特权原则,最小化访问敏感数据的代码,自动更改应用程序代码,极大地减少了程序开发人员的开发工作量,增强了SGX 的易用性.Liu 等人则在其源码自动划分方案PtrSplit[79]中,提出了一系列支持全局指针的方法.

3.3.2 Enclave 代码安全检测技术

SGX 可以为enclave 内部代码和数据提供机密性和完整性保护,以抵御来自enclave 外部的攻击.但是enclave 代码本身的漏洞也可能会泄露机密,例如enclave 可能受到Heartbleed[80]之类的攻击,这些攻击已被证明会从内存中泄露秘密密钥.开发人员也必须采取必要的措施来抵御协议和应用程序攻击,包括正确使用SGX 指令、使用安全的加密协议、避免由于违反内存安全性而造成错误等.

文献[53]开发了一个静态enclave 代码安全性验证工具Moat,用以验证enclave 代码是否满足机密性要求,即是否存在将秘密泄露给敌手可见的非enclave 内存的代码.Moat 分析了enclave 二进制代码的指令级行为,采用信息流敏感类型检查算法自动验证enclave 程序是否提供机密性保证.对于类型错误的程序,Moat 会利用漏洞程序证明机密可能会泄露给非enclave 内存.Moat 为程序员编写安全的enclave 提供了验证方法和工具支持.

3.4 潜在安全威胁的分析与防护

SGX 原则上能够提供安全的隔离计算环境,但实际上同样面临各种各样的安全威胁,比如侧信道攻击、内存攻击和回放攻击等.当前,学术界的相关工作也已经进行了证实[9-11,77].针对每类攻击,相关研究工作提出了一系列防御措施,但目前仍缺少通用的解决方案.因此,需要SGX 应用开发人员在开发SGX 应用程序时充分考虑相关的安全威胁,并采取一定的防御措施.

3.4.1 侧信道攻击和防护方案

SGX 面临的最大威胁是侧信道攻击.侧信道攻击的主要手段是通过攻击面获取数据,推导获得控制流和数据流信息,最终获取enclave 的代码和数据的信息,比如加密密钥、隐私数据等.Wang 等人对相关的SGX 侧信道攻击进行了详细的分析和总结[19].本文只介绍典型的攻击面,包括页表、缓存(cache)以及CPU 内部结构,这几种侧信道攻击的方式如下.

• 基于页表的攻击:利用页表对enclave 页面的访问控制权,设置enclave 页面为不可访问.之后,任何访问都会触发缺页异常,从而能够区分enclave 访问了哪些页面.按照时间顺序把这些信息组合,就能够反推出enclave 的某些状态和保护的数据.该类攻击包括controlled-channel 攻击[10]和pigeonhole 攻击[11]等;

• 基于Cache 的攻击.在SGX 环境中,大部分基于Cache 的侧信道技术仍然适用,例如文献[81]证明,SGX易受Cache-timing 攻击;

• 基于CPU 内部结构的攻击.CPU 内部有大量的结构是在enclave 和非enclave 之间共用的,这就给侧信道攻击提供了大量的攻击面,例如文献[82]实现的侧信道攻击.

这些侧信道攻击有的需要从SGX 设计的角度来解决,有的则可以在应用程序内部进行解决.更加合理地设计应用程序,可以减少攻击者能够收集的有效信息,极大地降低攻击者成功攻击的几率.SGX 现有的部分侧信道防御方法可以按照不同层次进行分类,主要包括:

• 软件层:应用程序可以进行自我防御,通过合理地设计应用程序,避免泄露过多的差异信息,使得攻击者难以成功.例如:像Opaque[34]等分析平台通过内部混淆让攻击者无法获取相关的差异信息,有效地保护了enclave 内部数据的安全性;Chandra 等人提出的方案[42]在训练机器学习模型时充分考虑到了侧信道攻击,将决策树的数据结构进行重新设计,保证敌手无法观察到差异信息,以避免应用程序泄露相关模型信息;ORAM[83]技术同样通过无差别的访问等方法避免泄露差异信息,从而有效地抵御SGX 面临的侧信道攻击,但是目前在性能方面仍然需要加以提高;

• 硬件层:通过优化SGX 硬件设计,可以避免某些侧信道攻击.例如,在enclave 的切换过程中,CPU 清除共用的内部结构体信息,避免非enclave 得到任何残留记录.同时还要注意一些细节,比如清除的时间也必须是稳定不变的[82].硬件层为每个enclave 隔离出一个cache,也是侧信道攻击的解决方案之一,虽然文献[84]已经进行了一些尝试,但仍然还未能彻底解决该问题.

3.4.2 内存攻击和防护方案

基于SGX 的隔离执行,为应用程序在不可信平台上的运行提供了强大的安全保障.但是隔离执行不能保护程序免受内存攻击[72],这些攻击很普遍,特别是用非安全语言(如C/C++)编写的应用程序.例如,Heartbleed[80]之类的内存安全攻击可能会使隔离执行的机密性和完整性保障完全失效.远程攻击者可以通过利用现有的程序漏洞来调用越界内存访问,以破坏内存安全性.然后,攻击者可以劫持程序控制流程或泄露机密数据[85].

所有内存攻击的基础条件是能够访问禁止访问的内存区域,因此,可以通过边界检查技术[86]限制enclave 程序可访问的内存范围.具体地,为每个分配对象的边界维护数据结构用于边界检查,确认指针是否仍在边界范围内.但是该数据结构可能会变得很大,并且查找成本很高.文献[55]基于SGX设计了一种用于enclave 的高效边界检查技术,可有效抵御来自于enclave 内部漏洞的威胁,并且结合标记指针和紧凑内存布局来提高性能.

3.5 小结

本节总结的以上4 种SGX 应用安全防护技术概括了目前常见的SGX 应用安全增强方案,为了更加直观地表述每一种技术的优缺点和性能,本小节给出如下总结(见表2).通过分析这4 种常见的SGX 应用安全增强技术的方案与优劣性,可以将这4 种技术的研究总结为以下3 个方面.

• 最小化TCB 和最少化对外接口,都可以降低SGX 应用面临的安全风险.但是两者之间存在一定的冲突,例如,要最小化TCB 就难以提供enclave 内部丰富的系统调用支持,难以做到最少化对外接口.目前缺少能够自动平衡TCB 大小和对外接口的开发工具,主要还是依赖程序员的开发经验来设计TCB 和enclave 接口.同样,也缺乏能够兼顾两个方面的安全增强方案;

• 敏感代码自动划分工具能够减少程序员的工作量,但其划分结果的准确性和可靠性难以验证,而且目前也缺乏普遍认可的划分标准.如何更准确、更可靠和更细粒度地自动划分应用程序,是需要实现的目标;

• 开发人员设计SGX 应用程序时应该充分考虑到侧信道攻击等未知安全威胁,根据不同的场景进行相应调整,以抵御可能面临的安全威胁.这需要开发人员具有足够的安全知识,当前还缺乏自动化支持工具以辅助开发人员实现对潜在安全威胁的抵御.

Table 2 Security enhancement solutions of SGX application表2 SGX 应用安全增强方案

4 SGX 应用性能优化技术

SGX 性能一直是学术界和工业界关注和研究的重要方向之一,也是制约SGX 应用的重要因素.对SGX 性能进行优化是必不可少的.相关研究[21,35,56-58]分析了SGX 潜在的性能问题,并提出了多种技术来优化SGX 性能.本文总结了优化SGX 性能相关的研究工作,将SGX 性能开销的问题和相关原因概括为以下几个方面.

• 模式切换开销.模式切换即enclave 切换,原因主要包括ecall、ocall 和AEX.模式切换出于安全原因,必须执行一系列检查和更新,包括TLB(translation lookaside buffer)刷新,基于内存的enclave 参数也必须在可信和不可信的内存之间进行复制,从而导致模式切换需要付出高昂的代价;

• Enclave 页替换开销.内存要求超过EPC 大小的应用程序必须在EPC 和未受保护的内存之间替换页面.EPC 页换出的代价高昂,因为它们必须在被复制到外部内存之前被加密并得到完整性保护.为了防止地址转换攻击,替换协议中断所有enclave 线程并刷新TLB.并且,页替换同样会导致enclave 模式的切换.在enclave 执行期间的页替换,由于额外的转换和加密操作而开销巨大;

• 内存加密开销.由于MEE 必须加密和解密高速缓存线,会导致加密内存访问存在高昂的开销,enclave代码也会由于写入内存和高速缓存未命中而产生开销.

针对上述开销原因,相应地,本文将目前SGX 性能优化方案也总结为3 种技术——模式切换性能优化技术、内存页替换优化技术和内存加密优化技术.

• 模式切换开销优化技术.模式切换需要付出高昂的代价,因此应尽量避免模式切换,可以通过异步调用[56-58]来加以避免;

• 页替换开销优化技术.页替换的开销很大,应尽量避免页替换,可以通过多种技术来减少页替换.如尽量将enclave 保持得较小,通过EPC 页面预加载以避免enclave 内部发生页错误,在enclave 内部使用替换的内存管理机制,如STANlite[20]和Eleos[58];

• 内存加密开销优化技术.内存加密开销是因SGX 的内存加密保护机制所致,可以通过减少对enclave内存的不必要使用、使用节省空间的数据结构或将较小的数据块加载到enclave 来进行优化.

4.1 模式切换性能优化技术

模式切换是SGX 能够在enclave 中执行代码的基本保障机制,但是模式切换也是SGX 应用程序性能开销的主要原因,尤其是对于系统调用密集型SGX 应用程序而言,导致的开销会达到几倍、几十倍甚至上百倍.只要CPU 进入或退出enclave,就会发生模式切换.模式切换开销的主要原因是复杂的状态保存和安全检查、保存和恢复CPU 状态以及由刷新TLB 引起的TLB 缓存未命中.

SGX SDK[16]提供的用于进行跨enclave 函数调用的标准方法ecall 和ocall 都会触发enclave 上下文切换.文献[35,44,50]分别对SGX 的ecall 和ocall 的性能开销进行了评测.任何ecall 和ocall 都会导致性能开销,因为硬件必须执行某些操作来维护SGX 的安全保障.Enclave 代码还必须验证所访问数据的完整性,例如ecall 的参数、ocall 的返回值和从不可信内存读取的数据.本文对评测结果进行了总结,具体见表3.从表中总结结果来看,直接使用SGX SDK 的边缘函数性能开销高达8 000 到17 000 个时钟周期(CPU cycle).Ecall 的开销大约为8 000个时钟周期,ocall 的开销大约为10 000 个时钟周期,这相比于系统调用150 个时钟周期来说是非常高的.因此,减少模式切换导致的开销变得非常重要.目前,避免或降低模式切换的技术主要有通过共享内存和专用线程避免切换、增加库操作系统来减少切换操作以及合理地设计enclave 接口.

Table 3 SGX ecall and ocall performance evaluation表3 SGX ecall 和ocall 性能测试

文献[64]则在3 种设置中直接测量了EENTER 和EEXIT 指令的时间开销:(1)在未修改的支持SGX 的处理器上,使用一个热高速缓存(warm cache)进行了一次往返,测得的切换时间约为5 850 个时钟周期(约为2 130ns);(2)SDK 更新修复Spectre[87]漏洞补丁(patchs)后(该漏洞影响了SGX[88]),测得的切换时间约为10 170个时钟周期(约为3 850ns),是没有补丁情况下切换时间的1.74 倍;(3)更新修复Foreshadow[89]漏洞的补丁后,在同时抵御Spectre 和Foreshadow 漏洞的情况下,enclave 切换变得更加缓慢,约为13 100 个时钟周期(约4 890ns),约2.24 倍,这些测试结果进一步说明了避免模式切换的必要性.

4.1.1 无切换调用

为了最大限度地降低模式切换带来的性能损失,文献[35,56-58]分别提出了解决方案,这些方案具有相同的核心思想:调用线程将ecall/ocall 的请求发送到共享的不可信缓冲区,工作线程则从该缓冲区异步接收和处理请求.由于采用这种方式调用eall/ocall 不会触发模式切换,故称为无切换调用(switchless calls)[57].如文献[56]提出一个由请求者和响应者组成的体系结构HotCalls,通过未加密共享内存进行通信,采用同步自旋锁机制,相比于SGX 默认的接口加速13~27 倍.

Eleos[58]则采用远程过程调用(remote procedure call,简称RPC)的方式处理系统调用,RPC 机制允许在不退出enclave 的情况下,将调用阻塞到不可信代码中执行,实际调用被委托给工作线程,该工作线程在enclave 所有者进程的不可信内存区域中执行.由于enclave 可执行多个线程,因此,Eleos 维护一个具有多个工作线程的线程池,通过位于不可信内存中的共享作业队列与enclave 交互.线程池中的线程轮询队列,调用请求的函数,并通过不可信的共享缓冲区传回结果.因为enclave 的线程不能使用互斥等标准的OS 同步原语,可信和不可信上下文之间的同步是通过轮询执行的.为了降低轮询成本,Eleos 通过简单的ocall 机制调用长时间运行的系统调用.

上述通过使用共享内存作为通信信道和专门设置线程轮询消息的方案被证明是有效的,但是这种无切换调用技术在效率方面存在疑问,用额外的CPU 内核来减少模式切换未必总是合理的.无切换调用必须由工作线程执行,因此需要额外的CPU 内核.实现的加速比随着工作量的减少而减小.在几乎空闲的工作负载的极端情况下,使用的额外CPU 内核显然是浪费资源的.文献[56]建议:如果工作线程长时间没有收到任何请求,则将其置于休眠状态.但是,可能存在请求稀疏却不足以触发超时睡眠的情况;并且,是否唤醒休眠工作线程处理一个或两个请求然后再次睡眠也存在疑问,这种情况下,浪费CPU 问题变得更加严重.工作线程使用额外CPU 核心可能已用于为同台机器上其他应用程序的线程.由于上述原因,enclave 应用程序会遇到各种动态工作负载,是否采用无切换调用则需要进一步加以分析.

Intel 的研究团队将无切换调用作为一种实用技术,确保它能够有效地提高性能[57].通过数学和模拟分析建立性能模型,研究无切换调用可以有效提高性能的条件,并设计了一种基于效率的调度算法,该算法可以自动调整工作线程数量以响应不断变化的工作量.Intel 公司目前已将无切换调用及其优化算法集成到SDK,从SDK 2.2 开始,正式提供这一功能.

4.1.2 增加操作系统库/函数库减少模式切换

SGX 提供了强大的安全保证,但SGX 的一个限制是enclave 内缺乏系统调用支持,这导致SGX 在性能方面并不理想.为解决这一问题,Haven[30]、SGXKernel[50]和Graphene[51]通过提供用于enclave 执行的兼容层,为SGX内部的应用程序提供操作系统库支持,无需修改应用程序代码.

SGXKernel[50]在enclave 内部提供了一个操作系统库,从而可以减少enclave 切换,使应用程序不再需要进行频繁的模式切换.这种减少模式切换的设计是通过结合两个设计实现的:即异步进行enclave 通信和可抢占的enclave 内部多线程.Graphene[51]除了提供一个操作系统库支持之外,还提供了一些使SGX 更加可用的改进措施,例如动态加载库的完整性支持以及安全的多进程支持,有效地减少了模式切换.

4.1.3 轻量级细粒度的并行减少enclave 之间模式转换

文献[60]提出了一个针对SGX 的框架EActors,提出新的概念actor,实现轻量级细粒度的并行,从而避免了SGX SDK 提供的同步功能的高开销问题,解决了enclave 内部和多个enclave 之间执行模式转换的高开销问题.最后,EActors 提供了基于安全和性能要求的高度选择自由来执行可信或不可信的actor.性能评估结果表明:基于EActors 实现的安全消息传递服务与基于SGX SDK 实现的版本性能提高了40 倍,EActor 可以更加无缝、灵活和高效地使用SGX,特别是对于需要多个enclave 的应用程序.

4.2 内存页替换开销优化技术

Enclave 性能开销高的另一个重要原因是enclave 内存空间比较小,尤其是应用程序本身可用工作空间比较小.Enclave 所在的EPC 大小有限,当前SGX v1 最大可设置为128M,实际约93M 可供应用程序使用,其他空间用于存储完整性保护的元数据[7].SGX 支持从EPC 到主内存的页替换,以满足不适合EPC 的enclave.当程序代码数量和规模增大时,敏感页面会在内存中的EPC 和非EPC 区域之间频繁交换.Enclave 执行期间的页替换开销巨大(约4 万时钟周期),因为它需要进行系统调用、页面复制、完整性树和元数据的更新等.文献[59]分析表明:页替换开销使系统平均减慢5 倍,内存密集型应用的速度更慢,对enclave 的性能有很大影响[21,35].

页替换会导致过高的性能开销,因此,enclave 设计应尽可能地避免遇到页替换.本文分析了页替换开销的原因以及相关的解决方案,具体如下.

• Enclave 太大可能是由于内部的数据集太大或数据处理不当所致.保持enclave 较小以始终适合EPC,可以避免发生页替换,如通过使用节省空间的数据结构或将较小的数据块加载到enclave 来实现.但是EPC 在所有运行的enclave 之间共享,很难确定enclave 大小是否合适,因为EPC 可能已被其他enclave阻塞,从而无法避免页替换,尤其是在多租户的云平台中;

• EPC 空间太小的问题也可以通过增加EPC 大小和增加并发线程来加以解决.鉴于大量的页替换开销,可以让EPC 更大以提高其命中率.如直接提供更大的EPC 空间或支持创建enclave 后再进行扩展[90],VAULT[59]提供了支持EPC 扩展的数据结构支持,但enclave 超出EPC 大小仍然会导致页替换;

• 在enclave 内使用替换的内存管理机制,取代SGX 采用的系统内存管理机制.例如,STANlite[20]和Eleos[58],这些系统在enclave 内部提供了新的内存管理机制,从而消除了EPC 硬件页面故障和enclave退出导致的性能开销;

• 通过预加载页到EPC 中来防止enclave 执行期间发生页面错误.例如,可以通过在发出ecall 之前加载所需的页面来实现.这样可以防止执行过程中enclave 内部发生页面错误和AEX.

4.2.1 高效的完整性验证结构减少分页开销技术

通过增加EPC 的大小来匹配物理内存的大小,允许EPC 容纳非敏感页面,可以有效地减少分页开销.Taassori 等人提出了解决方案VAULT[54],他们首先分析了目前EPC 最大只支持128M 的原因,具体如下.

• 用于存储EPC 元信息的完整性树深度和大小限制:完整性树的深度和大小随着受保护的内存的增大而增大.过大的树大小和深度导致可缓存性差以及带宽损失更高;

• 内存容量开销:每个EPC 块所需要的完整性树和MAC 可占据受保护内存的四分之一(约占128MB 中的32MB);

• 性能要求:由于EPC 页面访问开销巨大,因此不适合非敏感页面.在设计时将大部分内存指定为EPC,会导致敏感页面需求较少的应用程序不能充分利用EPC 和更高的性能开销.

因此,为了支持启用更大的EPC,必须解决至少两个重要问题:(1)改进完整性树的深度及其可缓存性以保持内存容量和带宽开销较低;(2)减少完整性验证的空间开销(包括完整性树和MAC).

VAULT[59]首先引入了用于完整性验证的可变元统一加密叶子树(variable arity unified encrypted-leaf tree,简称VAULT)计数器,如图8 所示.VAULT 可以有效平衡管理树深度和计数器溢出问题.SGX 完整性树的参数(arity)为8,VAULT 则将完整性树的arity 设计为16 到64 可变,从而实现一个更紧凑且深度更低的VAULT,每次读取和写入的可缓存性和带宽开销都得到了提高.并且,VAULT 提出了压缩共享 MAC(shared MAC with compression,简称SMC)技术,用以压缩数据块并将其MAC 打包到单个高速缓存行中,从而减少带宽开销,通过在多个数据块之间共享MAC 来减少存储开销,并证明了基于压缩的技术可以在大多数情况下消除或减少带宽损失.因此,SMC 可以同时减少带宽和内存容量开销.最后,VAULT 仅为敏感页面按需分配MAC,以进一步减少MAC 容量开销.通过结合VAULT 和MAC 共享和压缩,VAULT 实现了扩展EPC 到整个物理内存,并且可以解决SGX 内存访问中的大多数低效问题,相对于SGX,整体性能提高3.7 倍,而内存空间开销仅为4.7%.

Fig.8 VAULT schematic diagram图8 VAULT 示意图

4.2.2 安全用户管理虚拟内存技术

Orenbach 等人提出了用于enclave 的无退出(exit-less)运行时系统服务Eleos[58],通过透明且安全地将系统调用委派给运行在一个应用程序线程中的RPC 服务,实现了无退出系统调用,即无需退出enclave.Eleos 包含3个部分(如图9 所示):可信的运行时负责在enclave 内提供RPC 和SUVM;在单独的应用程序线程中运行的不可信运行时负责处理RPC 请求并与SGX 驱动程序进行交互;SGX 驱动程序模块公开了用于在多个协调SUVM内存分配的接口.

Eleos 还提出一种安全用户管理虚拟内存(secure user-managed virtual memory,简称SUVM)抽象,这种抽象通过引入enclave 子页面访问粒度,消除了EPC 硬件页面故障和enclave 退出导致的性能开销.用户通过特殊的分配器,在SUVM 中分配缓冲区,并获得安全指针;然后可以将其用作应用程序中的常规指针,指针访问被逐出的SUVM 页面会触发软件页面错误,并且完全在enclave 内部进行处理.这些机制提高了enclave 性能,且不会削弱SGX 安全保证.Eleos 只在TCB 中添加了几百行代码,与SGX SDK 或Graphene[51]等操作系统库(约1 000 行代码)相比,Eleos 在TCB 中添加的代码相对较少.

Fig.9 Eleos high-level design图9 Eleos 架构示意图

Sartakov 等人提出了在机架规模环境中进行安全数据处理的内存数据库引擎STANlite[20].STANlite 通过在enclave 内使用可扩展的虚拟内存引擎(virtual memory engine,简称VME),替代了操作系统提供的内存页替换机制,并使其对内存具有完全控制权,从而避免巨大的模式转换开销.STANlite 在不需要考虑机密性的情况下,提供了一种纯粹的完整性保护数据管理模式,以提高性能.STANlite 还具有基于远程直接内存访问(remote direct memory access,简称RDMA)、无切换和零拷贝的通信层,可在机架级环境中进行快速的远程数据库访问.

4.3 安全内存访问开销优化

文献[35]使用SGX SDK 微基准测试评估了enclave 内存访问开销.该基准测试了顺序读/写和随机读/写操作的时间开销,并与未部署enclave 安全内存的访问时间进行了对比.所有操作总共处理256MB 数据,但访问的内存区域大小不同.

如图10 所示:只要访问的内存大小不超过3 级(L3)缓存(8MB),enclave 内存访问开销就可以忽略不计.如果L3 缓存未命中,随机存储器访问的性能开销可高达12 倍左右.当访问的内存超出可用的EPC 大小时,触发的页错误会导致3 个数量级(1 000 倍)左右的开销.连续内存访问由于CPU 预读取实现了更好的性能,这隐藏了一些解密开销,在EPC 大小范围内几乎没有内存访问开销,而超出EPC 大小的内存访问大约有2 倍左右的性能开销.

Fig.10 Normalized overhead of memory accesses with SGX enclaves图10 SGX encalve 内存的标准化开销

文献[56,58]也对enclave 内存访问开销进行了测试,见表4.文献[56]采用SPEC[91]测试集进行测试,表明内存写操作的开销(30%~102%)要比内存读操作(6.5%~19.5%)高5 倍左右,但是没有区分连续访问和随机访问操作.文献[58]则采用生成10 万个随机数进行enclave 内存访问开销测试,内存随机访问和连续访问以及读和写操作的开销相近,大约在5.6 倍~9.5 倍开销之间.

Table 4 Performance evaluation of SGX memory read/write operation表4 SGX 内存读写操作性能测试

以上结果表明,enclave 内存加密开销由SGX 设计本身所致,难以作进一步的优化.出于性能原因,安全程序设计应尽量减少对enclave 内存的使用和访问.例如,SCONE[35]通过将加密的应用程序数据(如缓存文件和网络缓冲区)存储在enclave 之外,以减少enclave 昂贵的内存访问.如果必须使用enclave 内存,应尽量采用连续访问的数据结构,避免采用随机访问的数据结构.

4.4 小结

本节总结的以上3 种SGX 性能优化技术概括了目前常见的SGX 应用性能优化方案,为了更加直观地对比每一种技术的性能提升程度和对安全性的影响,本节作了如下总结(见表5).

Table 5 SGX performance optimization solutions表5 SGX 性能优化方案

通过分析这3 种常见的SGX 应用性能优化技术的性能提升与安全性影响,可以将这3 种技术的研究总结为以下4 个方面.

• Enclave 的开销主要归结为模式切换、页替换和内存加解密开销.目前,主要的研究工作集中在对模式切换和页替换开销优化方面;

• 模式切换开销目前的主要解决方案是将同步执行改为异步执行,最大化enclave 内部和外部的执行时间,从而减少频繁的模式切换导致的性能开销;

• 页替换开销目前的解决方案是,通过高效的数据存储结构来增大EPC 和采用更高效的内存管理机制;

• Enclave 内存加解密开销是由于SGX 本身的设计,目前主要通过合理使用加密内存来有效避免这些开销.要从根本上降低加密内存访问开销,需要从SGX 设计层面来优化,如重新设计加解密算法等.

5 SGX 应用辅助开发技术

SGX 技术目前应用的场景越来越广泛,但是安全且简便地使用SGX 并不容易,错误或者不合适的使用方式甚至会导致安全风险.因此,辅助用户更好地使用SGX 技术,也是一个非常重要的需求.目前,SGX 应用辅助开发技术主要包括安全开发语言、辅助开发工具和通用的操作系统库和函数库等.

5.1 安全开发语言

通过使用SGX SDK[16],开发人员可以创建加载到enclave 的代码.虽然SDK 简化了SGX 的使用,但SGX 所提供的编程支持有限,如不提供enclave 内部交互的编程支持、要求将可信代码硬编码到enclave 中,这限制了灵活性.开发SGX 应用需要对程序进行改造,当程序规模比较大时,带来的编程成本非常高.为了方便用户进行SGX 应用的开发并增强SGX 的安全性,目前学术界和工业界提出了支持SGX 应用开发的安全开发语言.

Rust SGX SDK[61]是百度安全实验室开发的一个SGX Rust 语言开发工具包.通过将Rust 语言和SGX 技术相结合,开发人员可通过用Rust 语言编写SGX 应用程序.开发人员基于Rust 语言可以快速开发出没有内存安全漏洞的SGX 应用程序,即使在操作系统被恶意控制时也能提供强大的安全防护能力,避免敏感数据被窃取.

MesaPy[62]也是百度安全实验室开发的一个安全开源项目,是一个内存安全的Python 实现.Python 包含超过30 万行C 代码,含有很多安全漏洞和隐患.MesaPy 基于Python 编译器PyPy,通过使用内存安全语言重写外部库和形式化验证保障代码的内存安全等方法,全面提升Python 解释器的安全性,避免内存问题引发的高危安全漏洞.基于这些安全特性,MesaPy 也支持运行在SGX 中,开发者可以使用Python 轻松地开发SGX 应用运行于可信运行环境中.

Ghosn 等人为增强SGX 的可用性,提出了一种将可信执行环境(trusted execution environment,简称TEE)集成到语言中的方案Secured Routines[63].该工作扩展了Go 语言,允许开发人员依靠编译器自动提取安全代码和数据.其原型GOTEE 是基于Go 编译器进行的扩展.GOTEE 为TEE 提供了一种简单的编程模型,开发人员可以直接通过关键字定义敏感代码.

5.2 辅助开发工具

5.2.1 安全划分与检测工具

自动化安全开发和检测工具也是SGX 应用辅助开发工具的重要类型,该类工具的主要目标是实现对应用敏感代码的自动化分析和划分,以及对enclave 代码的安全性检测.本文第3.3 节介绍了用于SGX 应用程序的源码划分框架Glamdring,可以基于开发人员对敏感数据的注释,自动地将应用程序划分为不可信和可信两部分.

SGX 为enclave 内的代码和数据提供硬件保护,以抵御来自底层操作系统的攻击,但是应用程序本身中的漏洞(例如SGX 指令使用不正确或内存安全错误)也存在泄露机密的风险.文献[53]基于自动定理证明和信息流分析,提出了一套SGX 的使用规范,设计了Moat 这一检测工具,通过在汇编语言层面对程序进行分析,从而检测应用程序是否存在泄露SGX 区域中秘密信息的可能.

5.2.2 性能测试与优化工具

SGX 目前所提供的开发支持工具非常有限,这会导致耗时的反复实验开发和调试,并存在性能下降的风险.SDK 自带了一个调试器插件,可用于检查enclave、设置断点等,但是该插件仅适用于使用SDK 开发的应用程序.Intel 提供的性能分析器VTune Amplifier[92]也可用于测试SGX 应用程序(包括enclave)性能.VTune Amplifier支持一种称为热点(hotspots)的新分析类型,可用于分析enclave 应用程序.热点是一段频繁执行的代码,例如循环主体,由类似于每条指令的总周期数或高速缓存未命中等指标来定义.开发人员可以使用热点的默认设置来深入了解SGX 应用程序与热点有关的enclave 函数,确定要进一步优化的代码.VTune 专注于代码片段的底层分析,未充分考虑SGX 特性,不足以帮助开发人员编写高效的enclave 域代码.

文献[64]介绍了一组用于SGX 应用程序的动态性能分析的工具sgx-perf,它可以对enclave 中的性能关键事件进行细粒度分析,允许开发人员跟踪enclave 执行并记录影响性能的关键事件,例如enclave 切换和页替换.它通过隐藏SGX SDK 的特定功能并重定向控制流来实现,分析记录的数据可以发现潜在的性能瓶颈.此外,sgx-perf 提供了改进enclave 代码和接口提高性能的建议.测试表明:使用sgx-perf 提供的建议最多可以将应用程序的性能提高2.66 倍,这有助于开发出性能良好的SGX 应用程序.

5.3 系统库支持

相关工作中提供操作系统库和函数库来支持enclave 内通用应用程序的执行,如Haven[30]、SGXKernel[50]、Graphene[51]和SCONE[35]等.本文已在上文中有所介绍,这里再进行一些简单梳理.Haven 将drawbridge 系统库部署到enclave 内部,支持在enclave 内直接运行未修改的Windows 应用程序.Graphene 则是在enclave 中部署了一个支持Linux 应用程序运行的操作系统库,可以实现在SGX 上快速部署未修改的Linux 应用程序.SGXKernel同样也是在enclave 内部署了一个支持Linux 应用程序操作系统库,且其性能明显优于Haven 和Graphene.SCONE 则是在enclave 中配置了标准C 函数库[79]的修改版本,以支持重新编译的Linux 应用程序.

5.4 小结

本文将SGX 应用辅助开发技术总结为安全开发语言、辅助开发工具以及系统库和函数库这3 类(见表6).通过分析总结上述研究工作,并结合目前SGX 应用需求,本文分析了SGX 应用辅助开发技术的发展方向.

• 开发语言目前已经支持C/C++、Python、GO 语言,并且GOTEE 已将可信的开发环境集成到了GO 语言中,可以通过关键字直接定义敏感函数.相关工作都考虑到将内存安全功能集成到开发语言中,简便使用和更多的功能集成,是安全开发语言的发展方向;

• 辅助开发工具目前主要有SGX 应用程序自动划分工具、enclave 机密性验证工具和程序性能测试工具,但是这些工具仍存在一些问题需要解决,如自动划分工具代码划分粒度不够细、缺乏划分标准等;

• 操作系统库和函数库目前主要有通用Linux 系统库、Windows 系统库和标准C 函数库,并且基本能够支持90%以上的常用系统库和函数库API.

Table 6 SGX application-assisted development techniques表6 SGX 应用辅助开发技术

6 SGX 应用功能扩展技术

SGX 的主要功能是创建可信执行空间,抵御特权软件的威胁,应用的主要场景是云平台.然而,目前SGX 自身缺乏对虚拟机迁移和容器等云平台常用技术的支持.目前很多研究工作对SGX 进行了功能扩展,使其支持常用的云平台技术.

6.1 支持虚拟机迁移

SGX 可以解决云计算中的信息泄露问题,但是现有的虚拟机管理器(virtual machine manager,简称VMM)不提供启用SGX 虚拟机(vitual machine,简称VM)的高效管理操作,如实时迁移.随着SGX 越来越多地部署到云平台中,内部运行enclave 的VM 失去了实时迁移的能力,而VM 实时迁移在云计算中被广泛使用,例如用于负载平衡、容错.这是由于SGX 硬件防止不可信的虚拟机管理程序或操作系统访问enclave 的运行状态所致,而这是传统VM 实时迁移所必需的.启用SGX 的VM 能够实时迁移不是一个简单的问题,也面临着如下困难.

• 加密内存页在目的主机解密问题:Enclave 绑定到单个物理CPU,使用特定于CPU 的唯一密钥加密,如果VMM 以现有方式迁移enclave,则由于密钥不匹配,另一主机无法从源主机解密enclave 内存页;

• 抵御回放攻击(roll-back attack):Enclave 存储空间有限,有时需要将enclave 内部的数据加密并换出enclave,然后在需要处理时再换入enclave 并解密.但这样会面临回放攻击,恶意系统使用旧版本的数据欺骗enclave,enclave 需要使用硬件计数器来抵御;

• 持久状态的迁移:包括密封数据和单调计数器,前者存在数据丢失风险,后者破坏了SGX 的安全保障.

Park 等人提出了一种支持SGX VM 迁移的方法及其实现模型[65],基于KVM(kernel-based virtual machine)实现了相关设计,为应用程序和支持SGX 的KVM 客户操作系统提供了SGX 库,并为开发人员提供了SDK,以便他们编写enclave 代码时无需了解相关的迁移机制,例如控制线程.其系统性能开销可以忽略不计,迁移内部运行64 个enclave 的虚拟机,迁移的总时间增长了4.7%,而停机时间仅增加了3ms.

Chen 等人设计了一个基于软件的VM 安全迁移机制,允许enclave 迁移其运行状态[66].迁移过程需要enclave 和不可信特权软件之间的合作.该机制在每个enclave 中引入一个控制线程来帮助VM 迁移,从内部安全地转存所有enclave 的状态.对于enclave 中的数据和CPU 上下文等状态,控制线程将对它们进行加密,并在转存之前进行完整性保护;对于不能由软件直接访问的状态,例如由CPU 维护的当前状态保存区域(CSSA),设计记账机制来推断 enclave 内的值,并通过两阶段检查点方案强化设计,利用远程证明和自我销毁来保证每个enclave 实例在迁移后不会回放或生成多个实例,以此来防御回放攻击.该工作采用纯软件方法实现密封数据和单调计数器迁移,并且维持SGX 的安全保证,最大限度地减少了开发人员的工作量,性能开销可以忽略不计.

Alder 等人则将SGX 计数器作为持久状态,实现了相应的迁移方案[67],并设计和实现一个框架,实现具有持久状态enclave 的迁移,同时保持SGX 相同的安全性保证.该迁移方案解决了一些实际挑战,例如从VM 访问enclave,并将enclave 迁移到目标计算机的性能开销限制在12.3%以下,大大减少了enclave 开发人员的工作量.

6.2 支持容器

基于容器的虚拟化技术变得越来越流行[93].许多多租户环境使用容器来实现应用程序的性能隔离,比如使用Docker[37]来封装容器、使用Docker Swarm[94]或Kubernetes[95]进行部署.尽管硬件虚拟化得到了改进,但容器在虚拟机管理程序上仍然比虚拟机(VM)具有性能优势:启动时间更短、I/O 吞吐量更高且延迟也更低[96].但提供的安全属性比VM 要弱,因为主机OS 通常只使用软件机制进行隔离[97].现有的容器隔离机制主要保护环境免受不可信容器的访问,但是租户希望保护其应用程序数据的机密性和完整性,防止未授权方的访问,不仅来自其他容器,还来自更高权限的系统软件.攻击者会攻击虚拟化系统软件中的漏洞,或损害特权系统管理员的安全凭证[98].

SGX 可以保护应用程序代码和数据免受其他软件的访问,包括更高权限的软件.使用enclave 可以保护容器不受更高权限软件的威胁.容器的应用程序可以在enclave 内执行,以确保数据的机密性和完整性.但是,使用SGX 设计安全容器机制面临着两个挑战:(1)最小化enclave 内TCB 的大小,同时支持安全容器中的现有应用程序;(2)保证安全容器的低性能开销.

文献[35]设计了一个用于Docker 的安全容器环境SCONE,基于SGX 实现在安全容器中运行Linux 应用程序,SCONE 内部架构如图11 所示.

SCONE 的内部组件如下.

• 对主机OS 系统调用的外部接口.SCONE 在将参数传递给应用程序之前执行完整性检查,并将所有基于内存的返回值复制到安全区内部来抵御攻击.为保护通过文件描述符处理的数据的完整性和机密性,SCONE 通过屏蔽(shield)来支持数据的透明加密和身份验证;

•M:N线程模型.M个enclave 绑定的应用程序线程在N个OS 线程之间进行多路复用.当应用程序线程发出系统调用时,SCONE 检查是否存在另一个可以唤醒并执行的应用程序线程,直到系统调用的结果是可用为止,从而避免了不必要的模式切换开销;

• 异步系统调用接口.异步系统调用通过使用共享内存来传递系统调用参数和返回值,并发出信号请求执行系统调用实现.系统调用由 SCONE 内核模块中单独运行的线程执行.因此,执行系统调用时,enclave 内的线程不必退出;

• 与现有的Docker 容器环境集成,并确保与标准Linux 容器兼容.但是Linux SGX 驱动程序和SCONE内核模块必须运行在主机OS 上,因此,除了Linux SGX 驱动程序以外,SCONE 不使用SDK[16]中的任何功能.

SCONE 在保证安全容器的TCB 较小的情况下,通过线程异步执行等操作实现了很低的性能开销,且对Docker 是透明的,与普通容器类似.由于容器镜像通常由专家生成,因此,缺乏经验的用户可以从SCONE 中受益,只要信任安全容器镜像的创建者即可.

Fig.11 SCONE architecture图11 SCONE 架构图

在异构集群上部署和调度容器,混合使用具有和不具有SGX 功能的计算机存在挑战.需要使用SGX 的容器将会存在争夺enclave 内存的可能性,因此,必须使用具有度量资源使用功能的调度管理器跟踪SGX 内存请求并相应地调度容器.但是现有的容器协调器都没有提供有关的SGX 资源使用运行时监控,只能依赖用户在部署时提供的静态信息.这些信息可能是错误的或不符合容器的实际使用,导致分配过多或分配不足.文献[68]提出了一种用于调度容器的SGX 感知架构,并提供了该框架的开源实现,包括修改SGX 的Linux 驱动程序作为Kubernetes 设备插件.

6.3 构建可信的外部路径

在本地应用环境中,用户可以使用SGX 保护应用程序不被受到破坏的操作系统的影响.但是SGX 缺乏对通用可信I/O 路径的支持,以保护用户在enclave 和I/O 设备之间的输入和输出.文献[69]介绍了一种SGX 通用可信路径架构SGXIO,允许用户应用程序在不可信的操作系统上安全运行.SGXIO 将SGX 编程模型的优势与传统的基于hypervisor 的可信路径架构相结合,实现了支持通用I/O 设备的可信路径.SGXIO 超越了云计算中的传统用例,使SGX 技术可用于保护以用户为中心的本地应用程序,以防止内核级别的键盘记录程序等攻击手段的使用.

6.4 小结

本节对SGX 的相关功能扩展技术进行了总结和分析.当前,SGX 的功能扩展技术主要包括虚拟机迁移支持技术、容器支持技术和通用I/O 可信路径支持技术.具体扩展的功能和优势见表7.

通过总结和分析上述研究工作,并结合云平台等典型的计算场景,本文总结和分析了SGX 应用功能扩展技术未来的研究方向.

• 目前,SGX VM 迁移主要基于软件模拟的方式实现,并不能完美地解决SGX VM 迁移问题,VM 迁移等操作需要SGX 设计和实现的进一步支持;

• 容器技术与SGX 基本的结合问题得到了有效的解决,但在性能方面仍然有进一步优化的空间;

• SGX 技术在很多方面仍然缺乏一定的功能支持,尤其是在某些具体的应用场景,如多方计算场景下,需要多个enclave 之间进行交互,而多个enclave 之间的切换开销高昂,目前,SGX 缺乏有效的支持技术.

Table 7 Feature extension techiques for SGX application表7 SGX 应用功扩展技术

7 SGX 应用支持技术研究展望

SGX 技术的推出,为远程可信计算问题提供了解决方案.本文对SGX 技术的研究现状及瓶颈问题进行了总结和归纳,如何完美地解决SGX 技术应用的瓶颈问题,需要进一步的研究.本文从安全防护、性能优化和易用性这3 个方面进行了分析.

(1)安全防护:应用安全是SGX 应用所面临的最基本的问题.如何有效地解决SGX 应用所面临的侧信道攻击、内存攻击等安全威胁,增强SGX 应用的安全性,依然是该技术应用研究的重要研究方向,具体的研究方向包括:SGX 代码运行时的安全性分析与检测、SGX 应用代码合理划分、抵御侧信道攻击等问题;

(2)性能优化:性能开销高是制约SGX 应用的重要瓶颈.如何减小SGX 技术的内在开销,实现其性能优化的一般性解决方案,是后续的研究方向.具体的研究方向包括:通过硬件加速或可选加解密算法等方式降低enclave 内存加解密开销、具备性能调优功能的自动化代码划分和更加高效的加密内存页管理方式等;

(3)易用性:SGX 应用开发的困难性和功能的局限性也是制约其应用的重要原因.如何增强SGX 技术的易用性和扩展SGX 功能,是该技术研究的热点问题.具体的研究方向包括:对遗留应用中敏感代码自动化识别划分和安全性分析、避免重构代码支持原有程序直接运行的方案、更简洁易用的开发语言和动态可调整的库支持、对虚拟化等云平台常用技术的有效支持以及辅助用户开发安全和性能良好的SGX 应用的开发工具等.

SGX 应用支持技术在学术界和工业界都引起广泛关注,我们认为,SGX 应用支持技术在未来的研究工作可能会偏重以下几个方面.

(1)对硬件能力的扩展

SGX 目前的功能主要是基于17 条指令来实现的,SGX 本身不支持虚拟机迁移,虽然基于软件模拟的方案实现了相关功能,但是更好的解决方案是对SGX 的硬件能力进行扩展,提供支持相应操作的SGX 指令及安全机制.目前,SGX v1 可以支持的最大EPC 为128M,但仍然无法满足应用对SGX 的需求,EPC 需要进一步地加以扩展.这其中,有一些挑战性问题需要解决,如高效的完整性验证结构以及无安全需求的代码对EPC 的浪费和高开销问题.

(2)对各种应用场景的有效支持

SGX 目前的主要应用场景是云计算,但是目前可信计算的需求越来越广泛,IoT、边缘计算等都需要可信支持.SGX 由于性能等限制难以直接应用到相关场景中,需要对SGX 技术进行扩展和改进.目前,SGX 已经应用到的场景中,如多方计算,SGX 主要起到基本的安全隔离作用.但在多方计算场景下,应用本身交互频繁,SGX 的设计无法直接对这些场景提供有效的支持,性能开销很高.SGX 的密钥管理同样面临性能问题,在复杂场景和应用中,性能开销过高、实用性差,SGX 需要更加高效的密钥管理方案.

(3)与区块链等技术结合扩展SGX 能力

SGX 与区块链等新兴技术的结合,目前是SGX 技术的研究热点之一.SGX 提供的可信环境可以为智能合约等提供区块链所不具备的机密性保证[99],可信的计算节点也可以支持区块链应用于更加复杂的应用场景[47].目前,利用SGX 提高区块链安全性和性能的研究工作还有很多瓶颈问题需要解决,如不支持enclave 内部智能合约之间的调用问题[47]、利用SGX 的可信性替代区块链共识机制可信性的合理性问题等[47].SGX 可以为区块链提供机密性和可信性保证,同样,区块链技术也可以为SGX 提供持久化存储和可信性验证方法,对计算结果进行记录和验证,从而实现可追溯等.这些都是对SGX 非常重要的能力扩展,可以使其应用到更加广泛的场景.如何结合区块链等技术对SGX 能力进行扩展,也是后续研究的重要研究方向.

(4)如何解决SGX 固有的信任问题

SGX 自公布以来在很多方面受到质疑,例如固件的不可审计、对Intel 管理引擎(management engine)代码模块的依赖导致会受到安全漏洞的威胁以及必须信任Intel 作为远程证明的前提.尤其是SGX 必须使用Intel认证服务(Intel attestation service,简称IAS)使其可信性受到广泛质疑,Intel 公司作为SGX 技术远程证明服务提供方,用户也无法对其进行审计,因此很难完全信任SGX.目前,Intel 公司在固件中实现的新特性FLC(flexible launch control)可以实现开放第三方验证服务,一定程度上增强了SGX 的可信性.但是,固件的不可审计和对Intel 管理引擎代码模块的依赖,仍然没有得到有效解决.

8 结束语

本文对SGX 应用支持技术的研究进展进行了深入分析和总结.首先介绍了SGX 技术的相关机制和SDK,分析了SGX 技术应用现状及瓶颈问题的研究进展;接着,分别介绍了SGX 应用安全防护技术、性能优化技术、辅助开发技术和功能扩展技术;最后,展望了SGX 应用支持技术的未来研究方向.从我们的总结来看,SGX 应用支持技术仍然有一系列的挑战问题,未来有很多工作值得继续加以研究.期望通过我们的工作,能够给以后的研究者提供有益的借鉴与参考,为SGX 技术的进一步应用和发展做出贡献.

致谢在此,我们向对本文工作给予支持并给出宝贵建议的评审老师和同行表示衷心的感谢.

猜你喜欢
调用应用程序内存
核电项目物项调用管理的应用研究
笔记本内存已经在涨价了,但幅度不大,升级扩容无须等待
删除Win10中自带的应用程序
“春夏秋冬”的内存
谷歌禁止加密货币应用程序
基于系统调用的恶意软件检测技术研究
内存搭配DDR4、DDR3L还是DDR3?
利用RFC技术实现SAP系统接口通信
三星电子将开设应用程序下载商店
微软软件商店开始接受应用程序