SGX Architectural Encalve(AE)及SGX密钥

前言

Architectural Encalve(AE)包括了LauchEnclave、QuotingEnclave、ProvisioningEnclave

所有的AE都是特殊的Enclave,预先由Intel进行编译、签名。他们会在PSW安装的时候启动起来,叫做aemd,AE的一个守护进程。这里有介绍。

AE的源码我还没看过,资料来自于SGX手册、论文、博客,加上根据自己已有的源码阅读基础进行的推理。

LaunchEnclave

LaunchEnclave(LE)是专门用来管理普通Enclave启动的Enclave。

但是如何启动LE呢?Intel的MRSIGNER被硬编码在处理器中,可用于判断LE文件镜像的Intel公钥是否与之匹配,对LE这个特殊Enclave的启动会跳过EINITTOKEN检查。第一点,每个LE文件都由Intel签名,需要验证Intel公钥是否能解开LE文件的签名;第二点,LE启动过程的SECS中保存的MRENCLAVE也需要匹配LE文件中的MRENCLAVE,则LE启动合法。这样也就保证只有Intel签名的LE能够使用EGETKEY指令来导出启动密钥给别人的EINITTOKEN计算MAC。

使用上述Enclave启动控制模式实现严格的软件定义的Enclave属性控制策略。现在的LE要求普通Enclave要么开启了Enclave调试模式,要么它的MRSIGNER处于Intel的白名单中,才能跑起来。普通Enclave不具有Intel AE独有的特权属性,比如访问长期平台配置密钥。

可以说Enclave本地认证的安全性保证在于通过LE和EINIT访问CPU级别的机密——启动密钥。EINIT会产生启动密钥让处理器验证uRTS之前申请EINITTOKEN(里面包含了基于Enclave内容的MRENCLAVE和基于开发者的MRSIGNER标识、请求特征和属性、KEYID、MAC消息鉴别码用于保护完整性。)的正确性(事实上,启动密钥也正是依赖MRENCLAVE、MRSIGNER标识从根密钥导出的)。并要求Enclave的标识属性需要和EINITTOKEN中的一致(申请的属性要和实际采用的属性一致,属性Attribute可以参考《SGX中的X特性、SGX获取元数据》、《SGX结构体》)。EINIT指令过程可以参考《SGX初始化》。

这里的说法也很不错。LE负责向希望在当前平台上执行任务的其他Enclave分配EINITTOKEN结构,分配该结构前以及EINIT指令时会检查Enclave的签名和标识是否有效。LE是唯一能够检索、分配EINITTOKEN结构的Enclave,并从根密钥导出一个启动密钥与EINITTOKEN绑定。

(后续支持FLC的CPU可以由用户植入公钥Hash,这个公钥用来验证用户自定义LE的签名,详见这里

那么怎么从根密封密钥(RSK)推导启动密钥、怎么产生EINITTOKEN?

LE调用EGETKEY指令从根密封密钥RSK推导启动密钥,但是EGETKEY的一个参数是随机的KEYID值,能够保证每次生成的启动密钥都是不一样的,因此攻击的时候无法通过多轮部分密钥恢复出完整密钥。

LE会根据所给的Enclave的度量值和属性生成一个EINITTOKEN。如下图所示,先是生成随机KEYID,然后调用sgx_get_key。进入后,先生成一个临时缓冲区tmp,然后调用do_egetkey去调用EGETKEY指令来生成启动密钥,然后将启动密钥从临时缓冲区tmp拷贝到调用者的缓冲区key,紧接着将之前的临时缓冲区在return前给重写并回收。sgx_get_key返回后,LE然后使用启动密钥生成所需MAC(目前认为和EINITTOKEN有关联,不过我还没有看过这块源码,这一段介绍部分来自论文《Foreshadow》),最后的最后会将启动密钥的缓冲区key内容清零销毁(销毁缓冲区为了防止内存泄露)

拓展简介一下Foreshadow攻击的一个实例——攻击启动密钥

Foreshadow攻击中的一部分,提到敌手可以攻击短暂存在的tmp缓冲区、略微长期存在的key缓冲区。Foreshadow使用最先进的Enclave执行控制框架(如SGX-Step,也是Foreshadow作者jo van bulck做的)攻击tmp,并能够体现其严重的危害。离线攻击时,单步执行LE并转储寄存器值以获得tmp地址等感兴趣的代码位置。在线攻击时,可以将Enclave程序停在3、4之间,使用SGX-Step获取密钥。

Foreshadow这个实例的优化中,依靠页面错误(page fault)序列,可以尽量避免sgx-step中的计时中断的噪音,并最小化AEX的数量。通过构造一个有限状态机并仅仅撤销sgx_get_key或do_egetkey等关键代码页的权限,这样可以仅仅通过计算页错误数量就可以确定do_egetkey返回指令的位置。当函数中获取启动密钥的时候,启动密钥会加载进L1,Foreshadow可以可靠的获取启动密钥。成功率百分百,共用了13个页错误,不需要依赖sgx-step的单步中断技术或ELDU指令(ELDU指令在将加密数据加载回EPC过程中,会多此一举地将数据放到L1,导致可以被L1缓存侧信道如Foreshadow窃取)。

验证Foreshadow这个实例可成功性:通过uRTS里面加入一个恶意的启动令牌提供者,使用提取的启动密钥来生成EINITTOKEN(会用到公开的KEYID),其中EINIT中会从平台主密钥派生出启动密钥被Foreshadow窃取。有了启动密钥就能在同一个平台恶意地启动很多恶意的Enclave

Foreshadow这个实例的攻击,可以做到恶意启动Enclave而不需要向Intel申请许可。但是由于密钥导出仍然依赖于MRENCLAVE或MRSIGNER,所以只能恶意启动满足上述两个签名结构体的Enclave,也就是说目前顶多只能悄咪咪地创建满足签名结构体的Enclave,只能用于隐藏Enclave。

隐私追踪问题。攻击者甚至可以创建Enclave来推导出不变的配置密钥,然后用MRSIGNER等配置信息来推导产出的启动密钥等敏感密钥。而在此之前,只有Intel签名的AE可以推导密钥(用于长期远程认证等)。因此一旦破解配置密钥危害很大。

ProvisioningEnclave

ProvisioningEnclave (PvE)提供密钥配置服务。下图是来自Foreshadow的图:

PvE和远端Intel配置服务器协商出一个EPID私钥(现在额外支持DCAP),这个私钥由RPK(Root Provisioning Key)推导出,作为SGX平台配置密钥(Provisioning Key)。具体来说,配置密钥的形成来,之后

有了SGX平台配置密钥,PvE还通过Root Provisioning Key(RPK,由Intel Key Generation Facility中的硬件安全模块随机生成,存于e-fuses中)和Root Seal Key(RSK,也存于e-fuses中)产生“配置密封密钥”,用于加密SGX平台配置密钥,并可以将加密结果存放到不可信存储中。 详情看这里

QuotingEnclave

QuotingEnclave (QE)用于远程认证中,对本地Enclave报告签名发送,以及对远程Enclave报告进行验证(来自对端QE的可信签名)并转发给本地Enclave。

Enclave本地报告也叫做REPORT,只能在当前Enclave中有可信价值,只能用于同一SGX平台下的认证,远程认证的可信报告QUOTE可信程度来自QE的背书。QE也是Intel签名过的Enclave。QE可以验证本地报告(因为本地报告的签名来源于RSK导出的报告密钥Report Key)并用QE私钥签名产生Quote,远端就能用QE公钥验证,从而实现远程认证。

对于远端Enclave的验证,QE会负责检测远端Enclave的可信程度以及它在远程认证过程中执行的环境。它会解密由PvE加密(利用“配置密封密钥”)存储在CPU中的(从Intel配置服务器处接收的)SGX平台配置密钥,并使用该密钥将REPORT结构(用于本地Enclave的验证)转换为QUOTE结构(用于远程验证)。

QE认证采用EPID组签名方案(有安全隐患,渐渐改为推荐DCAP)。一个EPID组包含许多同一类型的CPU和SVN。有两种使用模式,完全匿名模式下,密码系统确保远端能验证Quote的确来自一个SGX平台,但是不能追踪具体是EPID组中的哪个CPU型号及其SGX平台。在假名模式下,远程验证者可以链接来自同一SGX平台的不同Quote,因为每个Quote都被赋予了假名,彼此之间可以被区分开来。

如上图中,远程验证者发出挑战,验证该Enclave可信程度。Enclave使用EREPORT指令将挑战与自身绑定。然后不可信APP将本地认证EREPORT交给QE,QE推导报告密钥来验证报告完整性。然后用“配置密封密钥”来解密不可信系统软件返回的SGX平台长期配置密钥。QE用SGX平台长期认证密钥(本质是EPID私钥)签名本地认证报告,形成一个Quote。验证者收到认证响应Quote,将其交给Intel Quote服务,使用EPID组公钥(配置密钥使EPID私钥)来验证Quote。

Foreshadow另一个攻击实例——攻击配置密钥

QE实施远程认证,首先依赖于本地认证机制的正确。敌手如果掌握了QE推导的报告密钥,那么可以恶意签署本地报告让QE信任,这样QE就会签署本地报告为Quote(实际上是恶意的),使得QE其实也被攻陷了。

第二,QE依赖配置密封密钥去安全加密非对称的SGX平台长期配置密钥,如果SGX平台的配置密封密钥泄露,那么攻击者就能掌握长期配置密钥,并且不再需要QE去验证Enclave报告就能直接签署之。

QE的密钥提取攻击也用到了sgx_get_key这个可信运行时函数(之前提到的那个),在调用EGETKEY指令和缓冲区被重写之间通过页错误状态机攻陷QE。这里同样不需要单步指令技术和ELDU硬件指令,也能百分百地成功提取报告密钥和配置密封密钥,共用到14个页错误。

伪造远程认证后果严重。远程认证使用DH密钥交换。有了上述攻击可以构造中间人攻击,非常直接的读取并修改内容,甚至不再需要执行Enclave或了解其内部各种复杂地机制,因为上述攻击将配置密钥拿到手了。这使得基于SGX的DRM、隐私保护毫无意义,破坏了SGX地机密性。此外还能任意构造远程SGX的计算结果,破坏了透明完整的Enclave执行。进而危害云、区块链(构造假的远程结果)等各种SGX场景。

EPID的全匿名模式下,一旦获取一个EPID私钥就可以代表整个组的其他CPU进行签名,比如获取了i5-6700U平台组的一个EPID私钥(某个i5-6700U设备的私钥),就能恶意签名让对方认为当前平台是i5-6700U,也就是说还可以冒充任意i5-6700U组内平台,受害者不知道是哪个i5-6700U设备,但是受害者信了。在这个攻击实例中,窃取了平台配置密钥,那么就可以冒充组内其他远端设备进行签名(完全不再需要执行远端设备代码,因为已经有了密钥)。不过在假名模式下,不同设备会有假名,因此尽管是同一个组,仍然会被区别出来。

密钥总结

Intel KGF生成根配置密钥,根密封密钥,存储与e-fuses。根配置密钥用于和Intel配置服务生成配置密钥。两个根密钥共同导出配置密封密钥。启动密钥、密封密钥、报告密钥均由根密封密钥导出。配置密封密钥进一步把配置密钥加密存储于不可信介质中。

报告密钥用于签署REPORT报告。启动密钥用于生产EINITTOKRN。密封密钥用于将敏感数据加密存储在不可信介质中(配置密钥需要由配置密封密钥来加密,注意区别)。配置密钥在QE需要的时候提取出来对验证过的REPORT转换为QUTEO,让远端QE通过EPID公钥验证。

相关链接

Overview of Intel SGX - Part 2, SGX Externals

  • 5
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值