SGX
Intel的SGX是实现在第六代CPU之后的一组扩展指令集。SGX着眼于提供一个为用户应用程序提供可信的执行环境,为了达到这一目标,SGX使得应用程序在一段位于Enclave地址空间中能够开辟一段受保护的内存空间。这段受保护空间实行严格的访问控制和加密操作来提供对程序数据机密性和代码完整性的保护,使得即使是Hypervisor、BIOS,操作系统等特权应用都不能随意访问这段地址空间。在enclave中运行的受保护程序还拥有一个密码学测度,这可被发送给客户端来验证程序的可信执行和为远程终端或不可信平台提供secrets。
SGX的安全模型与TPM、TXT一样依赖于软件认证。Intel更进一步的将信任域从信任CPU&TPM提供商缩小到只需要信任CPU提供商,因此SGX通过不信任enclave之外的代码从而减小了TCB的大小。SGX提供的功能大多数是在微指令中实现,但是保护内存不受物理攻击主要是由CPU中的MEE(memory encryption engine)硬件单元提供,这个硬件通过对保护内存读写的解密加密,保证了数据只有在CPU中的enclave内存中才是明文。
SGX中内存管理
SGX提供的软件隔离执行环境主要是通过一套特殊的内存管理机制来实现的。如图 1:
上图为SGX的内存抽象模型,包括了内存的管理、布局与组织。PRM(Preserved Random Memory)是动态内存DRAM中一段用于SGX的保留区域,这段连续的内存空间处于最低的BIOS层而不能被任何软件访问。EPC(Enclave Page Cache)是PRM中操作系统分配的装载应用程序数据和代码的4KB大小内存的集合。EPCM(EPC Metadata)是维护EPC的入口地址,并且包含CPU跟踪EPC内存页元数据的状态表。它来保证每个EPC由一个Enclave独享。
SGX中内存布局
为了防止Enclave的内存不被特权软件染指,Intel专门保留一片物理内存来支持SGX相关功能(PRM)。如现代操作系统一样,PRM中也使用分页内存管理,SGX保留PRM的一部分内存用于EPC分页。EPC内存页只能在处理器运行于Enclave模式下才能够被访问,enclave之外的软件无法访问EPC,这一关键特性为Intel 实现强大隔离执行提供了严格的安全保证。
由于EPC分页机制是由不可信的操作系统来管理的,因此SGX会在每个EPCM中记录每个EPC页的分配信息,SGX通过此来检测分配地址的合法性与有效性。
为了跟踪运行Enclave实体的身份,SGX在每个Enclave中使用一个EPC页来维护结构体SECS(SGX enclave control structure)。SECS记录了Enclave的元数据,包括如enclave密码学测度等敏感信息,因此这段结构体只能被CPU的SGX管理机制访问修改。如果Enclave中的代码能够修改SECS结构中的数据,如密码学测度、身份信息等,那么整个系统的软件认证功能便形同虚设。EPCM结构体构造如图2:
这和一个人的简介很想,姓名(enclave SECS),性别(PT),合法公民(VALID),家庭住址(address),会做什么(RWX)。
EPCM中还保存有页表属性,这些属性需要在一开始就被enclave程序开发者(Independent Software Vendor ISV)定义好。
Enclave 内存布局
Enclave与原宿主进程共享一片虚拟地址空间,Enclave从某种程度上来说是源程序的动态加载库(DLL Windows,SO Linux)。部分Enclave中映射到EPC页的虚拟内存称为(enclave linear address range)ELRANGE。这段地址空间包含了Enclave中加载的数据与代码,并且一旦EPC分配在PRM终止后这段地址对于原始进程来说是不能访问的。任何试图读写ELRANGE地址空间的enclave外部代码都会产生一个未定义的行为的错误。
由于是操作系统或者Hypervisor将线性地址(虚拟地址)转化到物理地址,因此CPU必须要防止对enclave的地址映射攻击。当从EPC页地址转换到物理地址时,CPU使用在SECS中存储的初始分配信息来保证传递给地址转换过程的EPC页虚拟地址与EPCM中保留的EPC入口地址相匹配。这样来防止操作系统将ELRANGE地址映射到不受保护的内存,使得ELRANGE内存对enclave之外的软件不可见。
地址转化过后需要进入Enclave的话,硬件线程必须要做上下文转换使得CPU进入Enclave模式才能够访问Enclave中的内容,并且还必须设置初始enclave上下文,以便将控制权转移到enclave内的一些预定义入口点。SGX使用Thread Control Structure(TCS)来保存这类入口点信息。TCS结构必须被剥去起来,不然系统通过修改入口信息就能够在任意位置进入Enclave。与SECS一样,TCS保留在专门的EPC页中并且只能被SGX管理机制修改。TCS的另一个功能就是支持多个硬件线程并行执行Enclave中的代码,每个这样的线程必须保证线程安全且与一个TCS相关联。代码开发者必须为在enclave中的每个多线程分配相应的TCS。
如果执行过程中发生中断或者使用OCALL来调用enclave外的代码是,需要执行程序上下文切换,此时程序的上下文被保存在一系列连续的被称作State Save Area(SSA)的EPC中。
Enclave生命周期
操作系统调用ECREATE指令来创建一个Enclave,指令返回一个新Enclave的SECS结构,ECREATE会检查SECS结构的正确性,并确保在SECS中将Enclave标记为未初始化。
当Enclave未被初始化时,系统使用EADD指令来在EnclaveEPC页中加载数据和代码。EADD指令会检查操作系统分配的虚拟地址是否时位于ELRANGE中。EADD指令在试图往初始化的Enclave加载数据和代码或者EPC页已经加载数据或者代码之后会失败。在EADD之后,系统必须调用EEXTEND来对新加入的EPC页进行测度,,并且更新Enclave的测度(MRENCLAVE)。
初始化。在将初始化代码和数据加载进Enclave中后,操作系统调用EINIT指令来初始化Enclave。EINIT需要一个INIT Token来初始化。INIT Token是由Lauch Enclave提供的用来表征Enclave程序作者是否存在与Intel的白名单之上。Enclave作者还必须向Intel提交他们的身份信息和他们用于签名的公钥来使得Intel将他们添加到白名单之中。当EINIT收到INIT Token之后,它将在SECS中将Enclave标记为已初始化,并且禁止向Enclave中添加更多的内存页。因此在开发者必须在设计之初就估算好程序的空间复杂度。这样的做法一方面由Intel集中化管理身份信息使得信息透明度进一步将强并且使得恶意的enclave作者能够被迅速辨识出来使得系统的安全性大大的上升,但另一方面,由于所有的控制权都在于Intel手中,这限制了SGX技术的商业大规模使用。
Enclave的线程机制
任何能够将EPC页映射到其虚拟地址空间的进程都能够执行enclave代码。当CPU执行enclave代码时称为enclave模式,此时CPU可以访问驻留在PRM中的EPC页面。TCS的数目即线程数是由enclave作者决定,然后再决定有多少线程可以并发地执行enclave代码。
初始化后的Enclave使用EENTER指令来跳转进入Enclave执行受保护的程序。只有在RING 3的程序才能够使用EENTER指令,EENTER并不不执行特权切换,CPU依旧在ring 3的enclave 模式下执行。EENTER和Linux系统中的Syscall很相似,用在不受信任的程序想要在受保护的环境中执行代码,并且和Syscall一样,EENTER也需要保存调用者的执行上下文以便在Enclave代码返回时恢复跳转前的状态。
EENTER需要TCS的虚拟地址作为输入,接着这条指令将RIP(EIP)寄存器修改为TCS中保存的入口偏移地址。这个入口点是由enclave应用开发者定义的,任何对此地址的修改都会导致在初始化enclave是不一致的密码学测度。这样保证了enclave中的代码只会被定义好的地址上通过ECALL来调用。实际上,入口点只是enclave内存范围内的函数,enclave作者已显式地将该内存范围定义为enclave代码的入口点。
密码学测度
为了测度一个Enclave,在ECREATE,EADD,EEXTEND指令中都是用安全哈希SHA-256来对输入做计算。EINIT将完成所有中间测度,并将最终测度结果存储在enclave s SECS中的MRENCLAVE字段中。实际上,这意味着重新启动的客户端必须使用相同的enclave代码、SGX构建工具和相同版本的驱动程序,并使用相同的enclave配置以计算相同的测度来重新创建enclave。
ECREATE使用给定给ECREATE的大小参数扩展enclave测度,以保证enclave大小和SSA具有与作者期望相同的值。需要注意的时Enclave创建时的属性不是Enclave测度的一部分,而是包含在认证过程的信息当中。
EADD将会对给定EPC页ENCLAVEOFFSET进行测度,该字段是期望映射到的Enclave虚拟地址空间与ELRANGE基本地址的相对偏移量。EPC的page type和权限字段也会在EADD指令中被测度。对这些字段进行密码学测度保证了enclave的内存布局和enclave应用作者的期望一致。SGX所提供的所有安全保证都是依赖于在创建阶段对于代码和TCS页的测度。如果没有这些测度,enclave代码或者入口点地址就会被被任意修改。EADD指令不会对内存页中的内容进行测度。
为了将Enclave的测度扩展到包含内存内容,必须为指定页面EEXTEND指令。EEXTEND会以每256字节度量EPC页面的内容,以及enclave内的预期偏移量。这样的设计考虑(将内存页的加载和测度分离)可能来自SGX的一些延迟约束。
最后,EINIT最终将测度保存在SECS中的MRENCLAVE字段,接着将INIT字段设置为True来完成整个Enclave的初始化。
Enclave身份标志
软件认证依赖于受信软件的密码学测度来确定其身份。使用度量来识别受信任软件的一个大缺点是,软件的两个不同版本的测度是不一样的。SGX支持Enclave的两种不同类型的身份系统,第一个是基于Enclave的测度,第二个是基于分发给enclave应用作者的公钥证书。SECS结构体从某种角度来说就相当于Enclave的身份,它同时拥有两种enclave的身份:MRENCLAVE即为enclave的测度,MRSIGNER即为作者的测度(或者签名者的公钥)。
enclave能够基于自己的测度派生对称加密密钥,该密钥可以用于加密敏感信息,这些敏感信息可以安全地存储在enclave之外。这个秘密据说被Enclave封存起来。由于密钥来自对enclave的代码和初始数据测度,因此只有具有相同测度的同一个enclave才能派生相应的解密密钥。使用从enclave测度中获得的密钥来封存敏感信息是Seal策略中最严格的,它不允许作者在不向enclave提供敏感信息的情况下更新enclave软件。为了能够在同一飞地的不同版本之间迁移敏感信息,SGX依赖于一个CA为Enclave开发者的一级证书层次结构。当初始化Enclave的时候,EINIT指令会使用Enclave中证书的信息来填充SECS中描述基于证书的enclave身份信息字段,称为MRSIGNER。敏感信息的迁移过程使用EGETKEY指令来基于enclave的证书身份获取一个对称密钥。敏感信息使用AES-GCM分组加密后接着就可以传给不受信任的宿主程序。宿主程序将敏感信息转发给能够生成相同密钥的目标enclave,接着enclave解密消息获得敏感信息完成敏感信息迁移。
Enclave密钥生成过程
SGX的秘密由两种fuse密钥组成:Root Provisioning Key(RPK)。与Intel共享此密钥以此来支持未来的硬件认证;RootSealKey(RSK)—Intel承诺不知晓密钥,这使得SGX能够创建用于认证和封存的为一直。两者在SGX中用同样的方式存储(一次性烧入),但在英特尔提供的不同保证下由不同的进程产生和维护。
RootProvisionKey:Intel在制造设备时烧入的第一个密钥就是RPK,该密钥是在一个称为Intel Key Generation Facility (iKGF)的特殊用途设施中由专用硬件安全模块(HSM)[8]随机生成的,Intel保证该设施是一个保卫良好的离线生产设施。RPKs被交付到不同的,被英特尔的正式出版物命名为“大容量制造系统”的生产设施中,被集成烧入到处理器内。Intel存储所有RPK,因为它们是SGX处理器通过在线供应协议验证其身份的基础。出于这原因,iKGF还将每个RPK的不同派生密钥转发到Intel的在线服务器。
RootSealKey:SGX中第二个烧入的密钥称为RSK。和第一个密钥一样RSK也被保证在统计上不同部分的RSK是不同的。而与RPK不同的是,Intel宣称它试图清除这个密钥所有生产过程的残留信息,这样每个SGX都假设它的RSK值是唯一的,并且只有它自己知道。除了下面讨论的一个特殊密钥,enclave可信接口提供的所有密钥都是基于RSK派生的。
使用Root密钥派生
为SGX的不同用途,Enclave使用EGETKEY指令基于不同的请求参数和请求生成的密钥类型结合烧入的Root密钥来生成不同用途的密钥。
EGETKEY的一个重要参数是SVN(Security Version Number),SVN使用发出请求Enclave设置的用来代表请求生成密钥性质的参数。主要由两种SVN类型,CPU SVN被enclave开发者用来表示处理器的微指令更新版本,ISV SVN则用来表征enclave代码版本。如下图3:
SGX检查调用者enclave中的SIGSTRUCT中设置的SVN值,并且只允许获取小于等于调用enclave SVN值中的密钥(向下兼容,但是不允许向上请求)。这个密钥派生特性使得同一软件的升级版本获取以前版本创建的密钥成为可能。[9]
为了在密钥中包含作者的个人信息,SGX保留一个Owner Epoch参数作为在密钥生成过程中加入的个人熵,这个值由用户在启动期间通过设置密码来配置,并且会永久保存在内存中非易失性区域。SGX EGETKEY指令设置KEYREQUEST中的KEYNAME值来比表示请求生成不同类型的密钥。 EGETKEY生成的各种不同密钥总结如下表:
认证
认证是一个特称于enlave中的程序向其他enclave证明其完整性和真实性的过程。SGX认证即是一个在SGX平台上运行的ISV enclave(证明者)希望来向远程enclave(验证者)证明其身份(MRENCLAVE)、和确实是在真实的SGX处理器上正确的隔离执行。
SGX支持两种类型的认证,本地认证和远程认证。本地认证是指一个enclave可以被运行在一个SGX之上的另一个Enclave验证其向证明的上述两点。远程认证顾名思义即不要求两个enclave存在于同一个SGX之上。
本地认证
通过使用ERREPORT指令,enclave可以获取用来描述其软件和硬件TCB的硬件断言。返回的Report包含enclave的属性、测度值和ISV附加数据。对于验证方来说,这些值使得他们足以断言enclave中运行代码的完整性、执行环境(包括CPU的安全级别)以及认证enclave所使用的Seal标识。认证方指定验证方的MRENCLAVE值,然后自己填充需要参与认证的相关数据并且使用REPORT对称密钥来签名整个REPORT结构,这样EREPORT指令的输出结果并不会暴露用来签名的密钥。认证方接着将生成好的REPORT发送给验证方,验证方调用EGETKEY指令获得相同的REPORT密钥后对REPORT结构进行验证。这个REPORY密钥用来签署一个SGX中所有enclave的REPORT,因此本地认证只能在同一平台下的enclave之间进行。
本地认证过程如下图4:
在本地认证中第一次成功过后,因为可以确保是使用真正调用者属性填充的REPORT,因此后续对于认证过的enclave见证只需要根据预期认证要求验证报告字段就行了。
远程认证
在讨论远程认证之前,我们先讨论SGX平台下的一些用来获取远程认证密钥的预备过程。
预备过程即一个SGX设备向Intel证明其真实性、CPU SVN合法性以及其他一些系统属性,为得到一个反应其真实性和TCB版本的远程认证密钥。认证密钥是SGX上的敏感信息,使用密钥认证签名的有效性是由Intel签名的见证平台合法性证书来保证的。Intel使用在线的特定设施来提供SGX的预备服务。SGX的预备服务和远程认证过程是使用Intel设计的称为EPID的组签名方法[14]。为了实现EPID预备过程Intel提供了一个特殊的Enclave Povision Enclave(PvE)。
PvE。PvE负责在平台上使用Intel的在线供应服务器执行预备过程。为了证明其真实性,PvE使用一些只能由特殊enclave生成的SGX特权密钥。这两种密钥分别是Provision Key和Provision Seal Key。基于特殊enclave他们直接被intel签名的SIGSTRUCT证书,因此使用特权属性启动的特殊enclave能够使用EGETKEY来获取这两种特权密钥。PrK密钥生成过程分为两个阶段,首先是将RPK和现在硬件的TCB级别绑定,接着加上enclave的软件属性使用AES-CMAC算法得出PrK。PrK当中并没有包含RSK是因为这个密钥Intel需要预计算离线的iKGF中RPK库来生成相同密钥来认证平台的合法性。Owner Opoch属性没有在PrK中包含与上述原因一致,只不过是通过忽略平台所有者信息来生成PrK。Intel之所以这么设计的原因可能是防止太多直接使用RPK而泄露密钥。从iKGF中仅使用RPK的One Way Fuction(OWF)派生密钥和CPU的可信边界,可以防止派生密钥泄漏任何原始烧入密钥。
PvE除了生成PrK之外,还可以调用EGETKEY指令生成Provision Seal Key。和上一过程相似,PSK中也没由包含Owner Opoch属性。于PrK不同的是,这个密钥使用同时使用RSK来作为根密钥。这样生成的密钥不会被平台所有者的变化所影响,并且可以认为这个特定平台太所独有的密钥不会被Intel所知晓。
预备协议:
1:Enclave Hello。在得到硬件TCB的特定PrK后,PvE使用两个值来初始化预备协议。第一个是PrK的OWF输出,称为Platform Provision ID(PPID)。第二个反映了现有SVN下平台宣称的TCB级别。这两个值都使用Intel的provisioning server公钥加密后发送给provision 服务器。
2.服务器挑战。Intel使用PPID来判断平台以前是否已经预备化过。如果是这样的话,服
务器将加密过后的以往生成的认证密钥添加到挑战中去。其他情况则是服务器验证是否给此EPID组提供服务,接着将EPID组参数、随机参数(nouce)和预计算的TCB挑战返回给平台。
3:enclave回复。在PvE使用PrK解密收到的TCB挑战之后,它通过使用TCB挑战作为密钥计算CMAC(nonce)来生成TCB证明。接着,PvE自己产生一个随机的EPID成员密钥使用数学方法[14]隐藏这个密钥,以免Intel的Provision 服务器获取到平台生成的成员密钥信息从而获得一定的匿名性。为了支持未来取回认证密钥的服务,未被隐藏的成员密钥将使用PvE派生的Provision Seal Key来加密。在平台已经被认证过后,平台必须使用PSK来解密从服务器得到的备份认证密钥副本获得认证密钥,并且使用此认证密钥来合法地签名一条由Intel选择的消息,一次来证明自身存在于组中并未被撤销,如果是这样的话那么这个阶段可以认为此时的协议就是取回认证密钥或者TCB更新。两种EPID成员密钥、TCB和未撤销的证明作为平台响应的一部分一起被发送。
4:完成。服务器收到回复过后,首先验证TCB证明中使用的值是否和iKGF中收到的值一致,一致时继续EPID参与协议。接着处理隐藏的成员密钥,以创建使用EPID组发布者密钥签名的惟一证书,并与加密的成员密钥一起存储,以备将来重新预备事件。平台成员密钥与相配的签名证书一起来形成一个独一无二的EPID私钥。最后服务器发送带签名证书的消息来结束整个协议。需要注意的时由于认证密钥是由两方共同构建的,因此密钥发布者对此并不知晓。
5:最后。PvE使用PSK解密认证密钥,然后将其密封在enclave外来以备后用。由于EPID组按照TCB级别进行分类,因此平台的EPID签名可以在以后使用,这既代表SGX平台的真伪,也代表平台的TCB级别。
远程认证:
在远程认证过程中,enclave利用本地认证机制获取远程可验证的Quote。这靠一个称作Quoting Enclave(QE)的特殊enclave来完成。QE使用平台独一无二地非对称密钥将本地的Report转化未远程地Quote,远程主机就可以通过相应地公钥验证Quote。
与上述EPID认证协议不同,SGX版本地EPID认证协议不允许依赖方来扮演EPID验证者地角色,Intel转而提供一个全球的在线验证设施,称为Intel Attestation Server(IAS)。SGX版本的EPID认证协议涉及两个英特尔控制的服务和两个独立参与者。每对都被分为证明者和验证者:在第一对中,QE和IAS分别扮演验证者和验证者的角色。在独立地对中,ISV认证enclave和服务提供者分别扮演证明者和验证者的角色。
QE:QE提供用于远程认证的由认证密钥签名地Quotes。QE首先使用本地认证来获得请求enclave的EREPORT接着沿着REPORT的合法性,如果合法QE使用认证密钥签名这个REPORT将它转化成Quote。由于认证密钥时使用PSK封存的,只有PvE和QE可以得到它,这个特权是在由Intel签名SIGSTRUCT中的预备属性指定的。
SGX服务提供者。依赖方是指服务器提供者且并没有启用硬件的SGX技术。服务供应商应向IAS注册,满足一系列英特尔规定的要求以便提交认证证据,以便进行ISA认证。主要的IAS服务包括:验证ISV enclave Quote、请求更新的认证撤销列表和检索与获取Quote的断言历史信息记录。
远程认证模式。QE支持两种具有不同关联属性的Quote签名模式,即完全匿名Quote和假名Quote。Quote的关联属性是由平台唯一的认证密钥签名的basename参数决定。使用相同的认证密钥多次签名相同的basename参数会生成容易关联的假名Quote。当使用假名Quote时,IAS首先会验证basename是否适合特定的服务提供者相关[6]。服务提供者使用这种模式在保护用户隐私的同时来跟踪再次访问的用户并防止女巫攻击。相比之下,通过在不同的basename上签署多个签名,使得服务器提供者无法在计算上确定Quote是否使用相同的认证密钥生成,从而保护了平台的匿名性。因此,QE使用随机的basename来签署完全匿名Quote。
远程认证协议:
- 首先ISV enclave向服务提供者发送初始化请求,请求中包含EPID组。
- 如果服务提供者希望为此EPID组提供服务,则它通过向IAS请求更新的sig- RL(对应于平台的特定组)来继续服务。
- 然后服务提供者生成包含SPID、一个随机数、更新的Sig-RL、可选(使用假名签名时)basename的挑战信息。
- 如果enclave支持所请求的签名模式,那么它将调用EREPORT指令,以创建针对平台QE的可本地验证的报告。为了在enclave和服务提供者之间建立经过身份验证的安全通道,将新生成的临时公钥添加到本地报告的附加数据存储区。EREPORT连同服务提供者的挑战一起发送到QE。
- QE使用EGETKEY获取report密钥来验证EREPORT。如果成功的话QE再次调用EGETKEY获取PSK来解密远程认证密钥。根据所请求的认证模式,认证密钥首先用于通过对所挑战的basename或随机值进行签名来生成身份签名。如果使用非随机的basename,则签名反映平台的假名身份;否则,身份签名是完全匿名的。然后使用认证密钥计算平台身份签名上的两个知识签名。第一个证明身份的签名是用英特尔认证的密钥签名的。第二个是一个未撤销证明,它证明用于身份签名的密钥不会创建所挑战的Sig-RL中的任何身份签名。然后使用QE代码中硬编码中IAS的公钥对最后的Quote进行加密,结果被发送回验证飞地。
- Enclave将Quote转发给服务提供者以验证。
- 由于Quote时被加密它只能被Intel验证,因此服务提供者将Quote转发给IAS。
- IAS首先根据Quote的身份签名验证它的EPID证明。然后,它通过为列表中的每个私钥计算Quote basename上的身份签名验证它们都不等于Quote的身份签名,同时来验证平台是否在Priv-RL列表中。这将完成平台的有效性检查,然后IAS将创建一个新的认证验证报告作为对服务提供者的回复。认证验证报告包括平台为认证enclave生成的Quote结构。[10]
- 一份合法的认证验证报告证实enclave的确是在真正的Intel SGX处理器上运行一段特定代码。然后,服务提供者有责任验证ISV enclave身份,并向平台提供适当的回复。 整个过程如下图所示:
Reference
Alon Jackson.Trust is in the Keys of the Beholder:Extending SGX Autonomy and Anonymity.
Victor Costan, Srinivas Devadas.Intel SGX Explained.
David Grawrock. Dynamics of a Trusted Platform: A Building Block Approach. Intel Press, 2009.
S. Johnson, V. Scarlata, C. Rozas, E. Brickell, and F. Mckeen. Intel software guard extensions: EPID provisioning and attestation services, April 2016.
C.R.E.B.F.M.Simon Johnson, Vinnie Scarlata. Intel software guard extensions: Epid provisioning and attestation services,2016.