SGX问答

0 前言

有些问题比较常见,在这里直接将问答内容贴出来,方便大家搜索。有空再重新组织文字。

(我会避免泄露私人信息)

1 内存地址翻译全部交给os,那中间经过cache也是全部交给os是嘛?这个cache这部分,enclave中是怎么处理的呢?

page walk依旧是os来做,但是SGX特有的EPCM会确保这个page walk的结果是正确未被篡改的。

cache属于cpu内的微架构,cpu内的数据流都是明文的。将要流向epc的数据流在离开cpu时,进入总线前,被mee加密。

当epc evict时,会由指令里的微码流进行加密。其他情况下,数据流一般可能被sdk软件形式加密,比如加密文件库函数会软件形式加密将要传出到eclave外的文件

也有一些情况,enclave内的内容被开发者明文传出,通过寄存器或者store enclave外地址,这是开发者代码开发过程中自定义的需求

2 在enclave中能访问整个app的所有内存,但是app不可信的部分不能访问enclave内部的内存。如果在enclave内存中发生了栈溢出什么的,会影响到整个app吗?我的意思是虽然enclave中发生了栈溢出堆溢出,会改变执行流吗?

enclave内能rw外面,不能x;enclave外不能rwx里面

enclave里栈溢出的溢出对象是enclave线程的线程栈,是在enclave虚拟内存空间的一部分,和外面没什么关系

enclave里的漏洞会直接影响里面的数据/控制流,可能间接影响外面

3 电脑不支持sgx,只安装sdk来模拟的话,可以实现远程认证这个功能嘛

以SampleCode/RemoteAttestation为例来说,模拟模式功能不全,并且更重要的是没有任何安全性保障,因为sgx安全性来自于硬件,模拟模式只是让你感受感受它的大概样

(续)我还有个问题,就是远程认证中传给挑战者的认证报告里,是包含后续安全通道的加密密钥的嘛,sgx自己还会有一个解密密钥,对吗,这两个密钥生成和名字都是怎样的呢?

这是两套不同的密钥,一个是intel和ae之间协商的密钥,用来验证quote report,我看你关心的是挑战者和应答者之间的协商密钥,这是另一套,前一套是在ae初始化的时候完成的,而后一套是在远程认证的过程中,有额外的信息来进行密钥协商,这次协商基于的信息是挑战者和应答者提供的(而前一套密钥协商过程中的信息是由ae和intel服务器提供的),也就是说远程认证是帮助挑战者能够确信对方应答者是某个在intel服务器上注册在案的实体,基于认证基础之上,进行的密钥协商,构建一条加密信道

(续)也就是说,挑战者可以从intel服务器验证报告的时候得到密钥,接下来就可以通过这个密钥加密自己想要传输给SGX的消息,然后sgx自己有解密密钥便可以解密看到消息,这整个过程别人是无法窥探到的,是这样吧?

关于远程认证,这https://blog.csdn.net/clh14281055/article/details/107919383(最下面的一张图)里面放了一张从foreshadow里截的图,你可以看看那个图,涉及Architectural Enclave(AE,包括后面提到的QE、PvE等)。简单来说,qoute report是quote enclave(QE)通过本地cpu里的密钥验证local report,重新签名生成的,注意QE是intel 签名过的,所以QE本身是可信的,此外,QE是使用PvE(ProvisioningEnclave,也是intel签名的)和intel公司服务器协商生成的密钥来重新签名的,因此密钥也是安全的。可信的QE和可信的密钥,证明quote是可信的(这里可信主要指,由于假设intel公司可信的,使得这一系列流程是可信的)。然后可信的quote交到挑战者的手里,挑战者可以找intel服务器验证,因为intel服务器里存了之前协商的密钥,它可以验证。

(续)哦哦,就是说远程认证是向挑战者证明他是官方认证的实际存在的sgx,后续需要SGX产生一对密钥,将公钥给挑战者,继而挑战者以此加密自己的信息发给SGX,这个信息通道,便可以看作是安全通道了

差不多是这样

4 我看到seal这里,有一个问题。enclave关闭时,seal是为了未来某时间使用。1)使用mrenclave来seal数据,这种方法,属于seal到当前enclave。如果enclave关闭了,如果程序重新运行,enclave还是原来那个enclave吗?2)使用mrsignerseal到当前作者,这里提到更新了enclave版本之后能解封数据,这个enclave不同版本是什么意思呢。这里的作者又是什么意思呢

  1. MRENCLAVE这个信息来自于SGX签名工具根据Enclave文件信息签名时产生的,会在Enclave启动时,由EINIT指令(结合Launch Enclave给的token)进行验证。因此具体运行的Enclave实例若来自于同一个Enclave镜像文件,那么它们的MRENCLAVE是一样的。进一步,seal数据的密钥需要根据MRENCLAVE以及MRSIGNER派生,因此,MRENCLAVE和MRSIGNER相同的Enclave那就是是同一个Enclave,派生的密钥也是同一个密钥,因此能够对对应的密封数据进行操作。
    【扩展】与此类似的MRSIGNER是来自于签名者产商的信息,就算是同一份Enclave代码,由不同的人签名,那么MRSIGNER是不一样的。更进一步,SGX2还支持Key Separation&Sharing(https://fortanix.com/blog/2018/02/upcoming-intel-sgx-features-explained/ 有解释)还能帮助不同厂商共享密封密钥。

  2. 这里的版本指security version,随着enclave的迭代开发,enclave的sv会不断增加,需要确保高sv的enclave能够读取以前的旧的低sv的Enclave密封的数据。你说的MRSIGNER也是用来验证Enclave启动及派生密封密钥的。

5 ELRANGE和EPC是一一对应的吗?就是说在epcm中,寻址的时候会记录下符合的虚拟地址,如果虚拟地址空间(ELRANGE)大于物理地址空间EPC,就会产生swap到磁盘上面,这个时候,epcm的虚拟地址怎么对应呢

elrange其中有些是有映射,有些是尚未映射。其中有映射的部分,一部分是映射到EPC物理内存,那么就会有EPCM记录对应关系,因为它不信任OS页表。但由于EPC大小有限,有的映射就被从EPC移除了,这个过程叫做epc evict,涉及ELD、EWB Ring0指令,也就是说让OS负责把这块内存去普通内存中存储起来(使用另外的加密密钥),同时将对应的记录从epcm移除。你说的swap是已经被evict到普通内存的那些page才会被swap到硬盘

你可以看一下手册或者这里(https://blog.csdn.net/clh14281055/article/details/108229461)的EWB指令的伪代码。EPC Evict的流程可以参考intel sgx explained里的图
在这里插入图片描述

6 远程认证中PvE和intel provisioning servers协商epid的目的

epid首先是某个SGX平台(记为A)和Intel配置服务器协商的,平台A保留EPID私钥,Intel服务器保留EPID公钥。然后EPID的用处在于,当有个挑战者在挑战平台A的enclave(记为1)时,会获得这个平台A上的quote enclave对enclave1认证并用epid私钥签发的quote报告,挑战者将获得的quote报告交给intel quote服务器,intel quote服务器会从intel 配置服务器知道epid公钥并验证quote报告是否正确并告知挑战者,如此挑战者就知道平台a上的enclave1是否确实实在平台A上的。关于它是否是enclave1,那么已经又平台a的qe在本地认证环节就确认(确认MRENCLAVE/MRSIGNER信息)了

(续)这里为什么说epid认证是组签名方案呢

我记得是有一套数学的东西在背后,能够确保平台a和b各自的私钥能够和同一个epid公钥对应上。

因为平台a和b都能对应到同一个公钥,因此它们就是同一组的了,因为光靠公钥,区分不开a和b。

举个例子就是平台a的cpu是i5-6700u,平台a有一个自己的私钥,平台b的cpu也是i5-6700u,平台b也有一个自己的私钥,然后intel服务器有一个公钥,能够专门验证quote签名所用到的epid私钥是不是标识着i5-6700u,但是服务器不知道它具体是平台a还是b

目前说的是全匿名模式,还有一种叫别名模式,就是每个设备都会被服务器起一个别名,然后记录在服务器端,应该是每个设备特殊的设备信息会和别名绑定起来

7 Enclave.lds文件一般在什么情况下修改

lds文件是在编程生成动态库时候用到的,因为动态库一般来说希望暴露有限的导出表,lds文件就是用来确定动态库里的哪些函数导出或哪些函数不导出,导出的意思就是在linker进行链接的工程中能够发现这个符号。linker链接多个对象的时候需要对对象的符号进行解析,开发人员开发程序可能用到动态库的某个函数,那么就需要linker去动态库找到对应的符号,由于lds限制了动态库的导出函数,如果能够在导出表找到对应的符号,那么链接就能成功,如果找不到,就会报错 undefined reference

8 有没有办法把egetkey的各种key给打印出来?

有个密封文件的例子,其中会调用do_egetkey函数派生一个密钥出来,你可以在sgx_get_key(sdk/selib/sgx_get_key.cpp)看到egetkey的调用,以及获取派生密钥的过程

9 远程认证必须要求intel的参与吗?如果是局域网,我是指A机器上的飞地向B机器上的飞地进行remote attestation,但 A机器和B机器都不连外网仅仅在本地局域网中,那还能完成远程认证不

必须要有一个第三方(如intel服务器)和sgx平台预先协商(同时也相当于将sgx平台注册到intel服务器),然后相当于埋一个密钥到平台供后续使用,不然后面没法证明

(续)dcap认证方式也是吗?我知道epid是这样

应该也是,dcap我记得用到了椭圆曲线,有点忘了,但是这个基本前提肯定也是会满足的,不然没法做验证。不然就可以伪造了

(续)也就是说局域网没法做远程认证了吗。。。

理论上可以自己搭建一套服务器,充当intel服务器,但是估计实现上会有很大改动。

关于这个你可以深入研究研究,之前有听说有人打算改远程认证机制,想办法避免对intel服务器的依赖

10 现在SGX2.0是没有ASLR的吧,为啥我重复运行一个sgx app,打印enclave.cpp里面变量的地址,每次都不一样?

Enclave虚寸是mmap出来的,由于起址没指定,所以每次mmap结果可能不相同,所以和aslr没啥关系。mmap的过程可以在psw/enclave_common/sgx_enclave_common.cpp:enclave_create_ex里面看到,默认不指定ELRANGE起址。比如EnclaveCreatorHW::create_enclave里面调用enclave_create_ex函数

(续) 是这里吗?

在这里插入图片描述
这个是map文件时候调用,和加载enclave无关。也就是说首先将文件读到内存,然后将文件内容一点点加载到ELRANGE(涉及我刚才提到的mmap),之后mmap文件的虚存可以unmap掉了。

11 在构造 SGX enclave 的过程中的第三步 EEXTEND 中生成的 measurement,具体来说是一个 256 位的哈希值吗?它是通过对 enclave 的每个页的地址和 secinfo 进行 hash 运算后得到的吗?

你可以参考SGX手册或这里(https://blog.csdn.net/clh14281055/article/details/108229461)40.3节里面的EEXTEND的伪代码

(续)这边我有个不太理解的地方是DS:TMP_SECS.MRENCLAVE <- SHA256UPDATE(DS:TMP_SECS.MRENCLAVE, TMPUPDATEFIELD) SHA256UPDATE 是对TMP_SECS.MRENCLAVETMPUPDATEFIELD的值做与操作后再进行 sha256 哈希计算吗?还有一个问题 是这边的 TMP_ENCLAVEOFFSET是比如我 ADD 的 enclave page 的偏移值吗?

第一个问题中,一般来说是拼接以后做sha256,因为hash输入可以是任意长度的,然后输出是固定的,具体需要看intel硬件具体咋实现了,但是它没开源。第二个问题,TMP_ENCLAVEOFFSET我的理解应该是虚存的概念,然后TMP_ENCLAVEOFFSET代表了当前page距离Enclave虚拟地址空间(Elrange)的起始地址的偏移(如果没记错,应该就是虚存的偏移)

12 如何查看EPC大小

$ sudo cat /proc/iomem | grep INT0E0C
  80200000-85ffffff : INT0E0C:00

如上,大小约为90M

13 如何查看Enclave虚存(ELRANGE)最大支持的大小

$ cpuid -1|| grep Enclave
      MaxEnclaveSize_Not64 (log2)            = 0x1f (31)
      MaxEnclaveSize_64 (log2)               = 0x24 (36)

SGX1代普遍为236

$ cpuid -1 | grep Enclave
      MaxEnclaveSize_Not64 (log2)            = 0x1f (31)
      MaxEnclaveSize_64 (log2)               = 0x38 (56)

我手上的SGX2代服务器为256

14 还有点不太懂,当建立堆栈的时候,没进入epc的阶段,在elrange是怎么建立堆栈的?加载动态链接库的时候,elrange的范围就确定好了吗?那其中的堆栈呢?

elrange是mmap出来的,然后再往elrange填数据和布局每一块数据都对应到具体的epc物理内存来存储,对应关系记录到epcm。你可以看下这个函数psw/enclave_common/sgx_enclave_common.cpp:enclave_create_ex,里面会mmap enclave文件里声明的大小的内存,默认不指定elrange起始地址,那么由mmap自行分配。mmap占据一块虚存,对应的物理内存由EADD来添加。

(续)那sgx2是如何扩展到1t?这个扩展的是虚存把?

扩展的物理内存。理论上epc可以无限大,但是sgx1使用了mee里的哈希树保护epc完整性,因此epc一旦大了开销非常大,而sgx2不再提供完整性保护了,因此理论上epc没有任何限制。

epc其实是一个抽象的概念,由module specifical registers来从比如常见的买来的ddr4内存上指定一块区域为epc,这个epc的概念能够被mmu及其prmrr模块知悉。

破坏EPC完整性的一个常见例子:我把旧的EPC内存(经过合法加密的)记录下来,覆盖到别人使用的epc上去,虽然机密性没破坏,但是完整性破坏了。完整性检查就是要防止诸如此类的事情,由一个专门的哈希树来保障。epc一旦大了,这个哈希树的维护开销就会增大。所以sgx2为了支持大epc,就把哈希树去了。

(续)不维护这个hash树,降低了开销。物理上PRM还是原来的大小吗

prm是可以cpu自己定的,用两个范围寻址寄存器指定一下就行,cpu用2个reg声明哪里到哪里是prm,哪里到哪里是epc。然后mmu会根据reg对epc之外的内存进行常规的地址翻译,对epc里的交给mmu内部的prmrr来进一步翻译epc地址

(续)那怎么扩大到1T呢,加更多内存条嘛?然后可以通过两个寄存器指定

需要,前提就是你给机子配了1T以上的内存,然后2个reg指定其中1T为epc。现在的情况是价格越贵的cpu,2个reg给你指更大的范围。

(续)cpu是透明的,出厂就定好了

cpu虽然定好了,寄存器是可以调整的,都不用拉线,通过bios设置。sgx1的时候epc也是能调整大小的,就是通过bios,只能调小,不能调大。

评论 13
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值