本文来自 Intel SGX Explained
SGX(Intel Software Guard Extensions)实现了一种软件认证方案,遵循 密码学(三) 概述的一般原则。在本节中,最相关的原则是基于测量(measurement)对一个远程方验证一个enclave的身份,该测量旨在识别enclave内部正在执行的软件。远程方将由可信硬件报告的enclave测量与期望的测量进行比较,只有当两个值匹配时才继续进行。
The Life Cycle of an SGX Enclave 解释了SGX enclave是如何使用ECREATE、EADD和EEXTEND指令构建的。在通过EINIT对enclave进行初始化之后,不能再使用上述提到的指令。由于SGX测量方案遵循 密码学(三) 概述的原则,SGX enclave的测量是通过对用于创建enclave并将初始代码和数据加载到其内存中的ECREATE、EADD和EEXTEND指令的输入进行安全哈希计算来获得的。EINIT会完成代表enclave测量的哈希计算。
简单来说,SGX enclave的测量是通过对ECREATE、EADD和EEXTEND指令的输入进行哈希计算得到的。这些指令用于创建enclave并将初始代码和数据加载到enclave的内存中。一旦enclave通过EINIT初始化,这些指令将不能再使用。最终,EINIT会完成哈希计算,生成代表enclave测量的值。
enclave的测量值在SGX中非常重要,因为它用于验证enclave的完整性和身份。远程方可以通过比较enclave的测量值与预期值来验证enclave是否正常运行且未被篡改。
这种SGX测量方案确保了enclave的识别和完整性,并为远程方提供了一种可靠的方式来验证enclave的身份和确保其安全性。
除了enclave的内容之外,enclave的作者还应该指定创建enclave所需使用的指令序列,以便enclave的测量值与远程方在软件认证过程中使用的预期值相匹配。SGX的预期enclave交付方式是.so和.dll动态加载库文件格式,这些格式已经包含了加载算法的非正式规范。
enclave的测量是使用安全哈希算法计算的。在SGX中,使用的具体算法是256位的SHA-2安全哈希函数。SHA-2是一个块哈希函数,它对64字节的块进行操作,并生成32字节的输出。在计算过程中,它使用32字节的内部状态。
每个enclave的测量值存储在enclave的SECS(Secure Enclave Control Structure)的MRENCLAVE字段中。这个字段的大小为32字节,它包含了SHA-2安全哈希函数的内部状态和最终输出,代表了enclave的测量值。
为了确保系统软件能够构建出具有预期测量值的enclave,它必须按照enclave的作者指定的确切指令序列进行操作。通过遵循这个指令序列,系统软件可以创建出与作者预期测量值相匹配的enclave,该测量值是由SHA-2安全哈希函数计算得出的。
总之,SGX设计采用了256位的SHA-2安全哈希函数来计算enclave的测量值。这个测量值存储在MRENCLAVE字段中,其中包含了SHA-2函数的内部状态和最终输出。系统软件只能通过按照enclave作者指定的确切指令序列来创建具有期望测量值的enclave。
ECREATE指令首先使用256位SHA-2初始化算法初始化新创建的SECS中的MRENCLAVE字段,然后使用Table中所示的64字节块扩展哈希。
Offset | Size | Description |
---|---|---|
0 | 8 | ”ECREATE\0” |
8 | 8 | SECS.SSAFRAMESIZE |
16 | 8 | SECS.SIZE |
32 | 8 | 32 zero (0) bytes |
Table :由ECREATE扩展到MRENCLAVE的64字节块。
enclave的测量值不包括BASEADDR字段。这是有意为之的,因为它允许系统软件在满足ELRANGE限制的主机进程中的任何虚拟地址处加载enclave,而不会改变enclave的测量值。这个特性可以与生成位置无关的enclave代码的编译器结合使用,以获得可重定位的enclave。
enclave的测量值包括SSAFRAMESIZE字段,该字段保证了由AEX创建并由EENTER和ERESUME使用的SSA具有enclave作者预期的大小。如果将这个字段排除在enclave的测量值之外,那么一个恶意的enclave加载程序可以尝试通过指定比enclave作者预期的更大的SSAFRAMESIZE来攻击enclave的安全检查,这可能导致由AEX写入的SSA内容覆盖enclave的代码或数据。
enclave的测量值不包括enclave属性,这些属性在SECS的ATTRIBUTES字段中指定。相反,它直接包含在由证明签名覆盖的信息中。
SGX软件证明确实需要涵盖enclave的属性。例如,如果XFRM不被覆盖,恶意的enclave加载程序可能会尝试通过将XFRM设置为启用架构扩展的值来破坏enclave的安全检查,而这些架构扩展会改变enclave使用的指令的语义,但仍然会产生适合于SSAFRAMESIZE的XSAVE输出。
对ATTRIBUTES SECS字段的特殊处理在安全角度上似乎是有问题的,因为它给软件证明验证器增加了额外的复杂性,这会导致更多的可利用漏洞的机会。这个决定还给SGX软件证明设计增加了复杂性。
在面对上述的担忧时,SGX设计选择采用这种方式的最可能原因是希望能够使用单个测量值来表示一个enclave,该enclave可以利用一些架构扩展,但也可以在没有这些扩展的情况下执行其任务。
举个例子,考虑一个使用OpenCV等库执行图像处理的enclave,该库针对SSE和AVX进行了优化,但也包含了对没有这些特性的处理器的通用回退。enclave的作者可能希望允许enclave加载程序将位1(SSE)和位2(AVX)设置为true或false。如果ATTRIBUTES(以及XFRM)是enclave测量值的一部分,那么enclave作者将不得不指定该enclave有4个有效的测量值。一般来说,允许独立使用n个架构扩展将会导致2^n个有效的测量值。
EADD指令使用Table中显示的64字节块将MRENCLAVE中的SHA-2哈希值扩展。
Offset | Size | Description |
---|---|---|
0 | 8 | EADD\0\0\0\0” |
8 | 8 | ENCLAVEOFFSET |
16 | 48 | SECINFO (first 48 bytes) |
Table :由EADD扩展到MRENCLAVE的64字节块。ENCLAVEOFFSET通过将enclave的SECS中的BASEADDR从PAGEINFO结构中的LINADDR字段中减去来计算得出。
在扩展过程中,首先在MRENCLAVE中添加8个字节的字符串"EADD\0\0\0\0"。然后,添加8个字节的ENCLAVEOFFSET,其计算方法是将enclave的SECS中的BASEADDR从PAGEINFO结构中的LINADDR字段中减去。最后,将SECINFO的前48个字节添加到MRENCLAVE中。
通过使用EADD指令将这个64字节块扩展到MRENCLAVE中,可以在enclave的测量值中包含有关enclave的位置和安全信息的额外数据,从而增强了enclave的完整性和可信度。
测量中包含的地址是期望EADD页在enclave的虚拟地址空间中映射的地址。这确保系统软件根据enclave作者的规格设置enclave的虚拟内存布局。如果恶意的enclave加载程序尝试错误地设置enclave的布局,可能是为了进行主动地址转换攻击,加载的enclave的测量值将与enclave作者预期的测量值不同。
新创建的页的虚拟地址相对于enclave的ELRANGE的起始地址进行测量。换句话说,测量中包含的值是LINADDR - BASEADDR。这使得enclave的测量值对于BASEADDR的更改是不变的,这对于可重定位的enclave是理想的。测量相对地址仍然保留了ELRANGE内存布局的所有信息,因此对安全没有负面影响。
EADD还测量提供给EADD的SECINFO结构的前48个字节,其中包含用于初始化页面的EPCM条目的页面类型(PT)和访问权限(R、W、X)字段值。通过与上述相同的论证,将这些值包含在测量中可以确保由系统软件加载的内存布局与enclave作者的规格相匹配。
因此,将地址和SECINFO结构的相关信息包括在enclave的测量中,可以确保系统软件根据enclave作者的规格正确设置enclave的内存布局,并防止恶意的enclave加载程序对enclave的布局进行篡改。
在上述提到的SECINFO结构中,EPCM字段值占用少于一个字节的空间,其余的字节被保留并期望初始化为零。这为未来的SGX功能留下了足够的扩展空间。
Table中最显著的遗漏是用于初始化新创建的EPC页面的数据。因此,由EADD提供的测量数据保证了enclave的内存布局将在期望的虚拟地址上分配具有指定访问权限的页面。然而,这些测量值并不包括加载在这些页面中的代码或数据。
例如,EADD的测量数据确保了enclave的内存布局由三个可执行页面后跟五个可写数据页面组成,但它并不能保证任何一个代码页面包含enclave作者提供的代码。
因此,SGX的设计选择将enclave的内存布局和访问权限纳入测量值中,以确保系统软件按照enclave作者的规格进行正确的初始化,但它并不提供代码或数据的完整性验证。这意味着enclave的安全性和正确性还需要额外的验证和保护措施,以确保加载的代码和数据与enclave作者的意图一致。
(1)
EEXTEND指令的存在完全是为了测量加载在enclave的EPC页面内的数据。该指令读取一个虚拟地址,并使用Table中的五个64字节块扩展enclave的测量哈希值,从而有效地保证了enclave内存中256字节数据块的内容。
Offset | Size | Description |
---|---|---|
0 | 8 | ”EEXTEND\0” |
8 | 8 | ENCLAVEOFFSET |
16 | 48 | 48 zero (0) bytes |
64 | 64 | bytes 0 - 64 in the chunk |
128 | 64 | bytes 64 - 128 in the chunk |
192 | 64 | bytes 128 - 192 in the chunk |
256 | 64 | bytes 192 - 256 in the chunk |
Table :由EEXTEND扩展到MRENCLAVE的64字节块。ENCLAVEOFFSET通过将enclave的SECS中的BASEADDR从PAGEINFO结构中的LINADDR字段中减去来计算得出。
EEXTEND指令通过将虚拟地址和一系列特定数据块的内容包括在enclave的测量中,确保了这些数据的完整性。ENCLAVEOFFSET的计算方式与之前描述的相同,通过将enclave的SECS中的BASEADDR从PAGEINFO结构中的LINADDR字段中减去来获得。
通过使用EEXTEND指令测量enclave内部加载的数据,可以提供一种验证机制,确保enclave内存中的特定数据块没有被篡改。这对于保护enclave中敏感数据的完整性非常重要,并提供了一种手段来检测任何未经授权的更改或损坏。
在详细讨论EEXTEND之前,我们需要注意,只有在测量enclave的关键页面的内容时,SGX的安全保证才能生效。例如,只有在测量了所有线程控制结构(TCS)页面的内容时,EENTER才能保证在enclave的代码内执行受控跳转。否则,恶意的enclave加载程序可以在构建enclave时更改TCS中的OENTRY字段,然后恶意的操作系统可以使用TCS在enclave代码内执行任意跳转。根据同样的论证,所有enclave的代码都应该由EEXTEND进行测量。如果没有测量的任何代码片段都可以被恶意的enclave加载程序替换。
这意味着SGX的安全性要求确保测量enclave中所有关键页面的内容。这包括线程控制结构(TCS)页面,用于控制enclave中的线程执行,以及其他包含enclave代码的页面。通过测量这些页面的内容,可以确保它们没有被恶意的enclave加载程序更改或替换。
因此,SGX的设计要求使用EEXTEND测量关键页面的内容,以确保enclave的安全性和完整性,并防止恶意的enclave加载程序或操作系统对enclave的代码执行进行未经授权的更改或跳转。
(2)
SGX设计选择将EADD进行的虚拟地址空间布局测量与EEXTEND进行的内存内容测量分离。这种解耦引入了一些潜在的问题和安全风险。
初步看来,解耦的唯一好处似乎是能够在构建enclave时将未经测量的用户输入加载到enclave中。然而,这个好处只会带来一点点性能上的改进,因为enclave也可以设计成在初始化后从不受信任的DRAM中复制用户输入。与此同时,解耦也打开了依赖于提供不具备实质安全保证的enclave的可能性,因为它没有通过EEXTEND调用来测量所有重要数据。
然而,EADD/EEXTEND分离背后的真正原因可以从SDM中的EINIT伪代码中窥见一斑。该伪代码指出,该指令在执行计算密集型的RSA签名检查时会打开一个中断窗口。如果在检查过程中发生中断,EINIT将以错误代码失败,并处理中断。这种对于处理器指令来说非常不寻常的方法表明,SGX的实现在处理中断时对指令增加的延迟有一定限制。
考虑到上述问题,可以合理地推断,EEXTEND的引入是因为使用256位SHA-2来测量整个页面非常耗时,在EADD中执行这个操作会导致指令超出SGX的延迟预算。达到特定延迟目标的需求可以合理解释这个看似随意的256字节块大小。
如果enclaves使用与构建动态加载模块相同的工具进行编写,这也是SGX设计所针对的工作流程,那么EADD/EEXTEND的分离不会引起安全问题。在这种工作流程中,用于构建enclave的工具可以轻松地识别需要测量的enclave数据,从而减轻了遗漏重要测量的风险。
从安全的角度来看,确实将256字节块的地址与数据内容一起包含在EEXTEND提供给哈希函数的消息块中是正确且有意义的。如果不包含地址信息,恶意的enclave加载程序可以进行内存映射攻击。
Straightforward Active Attacks如下所示:
我们将主动地址转换攻击定义为一类攻击,其中恶意系统软件修改应用程序使用的页表,以破坏虚拟内存抽象。内存映射攻击不包括系统软件直接写入应用程序的内存页面以破坏内存抽象的情况。
我们以一个简单的主动攻击示例开始。在这个示例中,受保护容器中的应用程序执行安全检查,决定是否披露一些敏感信息。根据安全检查的结果,enclave代码要么调用errorOut过程,要么调用disclose过程。
攻击的最简单版本假设每个过程的代码从页面边界开始,并且不超过一个页面的大小。在攻击的更复杂版本中,这些假设会放宽。
在最简单的设置中,恶意系统软件直接修改容器内应用程序的页表,如图54所示,因此用于存储errorOut过程的虚拟地址实际上被映射到包含disclose过程的DRAM页面。如果没有任何安全措施,当应用程序的代码跳转到errorOut过程的虚拟地址时,CPU将执行disclose过程的代码。
Figure:主动内存映射攻击的示例。应用程序的作者意图进行安全检查,并且只有在检查通过时才调用披露敏感信息的过程。恶意系统软件将在检查失败时调用的过程的虚拟地址映射到包含披露过程的DRAM页面。
更具体地说,恶意加载程序将在为披露过程预定的虚拟地址上使用EADD加载errorOut页面的内容,在为errorOut预定的虚拟地址上使用EADD加载披露页面的内容,然后以错误的顺序使用EEXTEND测量这些页面。如果EEXTEND不包含要测量的数据块的地址,上述步骤将产生与正确构建的enclave相同的测量结果。
通过包含地址信息,SGX设计确保测量的数据与enclave内存中的特定位置相关联,防止恶意篡改。这加强了SGX提供的安全保证,并防止利用内存映射漏洞的潜在攻击。
(3)
EEXTEND对于重定位enclave的支持是一个值得考虑的重要方面。与EADD类似,EEXTEND测量的虚拟地址是相对于enclave的BASEADDR的。这意味着测量结果包括虚拟地址与enclave基地址之间的偏移量。
此外,EEXTEND主要用于测量enclave的可信计算基础(TCB),而唯一预期由EEXTEND测量的SGX结构是TCS(线程控制结构)。TCS包含了关于enclave的重要信息,如入口点和基地址。
SGX设计中特别注意了表示enclave地址的TCS字段使用相对地址。这些字段包括OENTRY(enclave入口点的偏移量)、OFSBASGX(enclave线程控制栈的第一个页面的偏移量)和OGSBASGX(enclave全局存储区的第一个页面的偏移量)。通过使用相对地址,EEXTEND捕获的测量结果在enclave被重定位到不同物理内存位置时仍然有效。
对于重定位enclave的支持对于灵活性和可移植性非常重要。它允许enclave在不同的内存位置加载和执行,而不会影响enclave的完整性和安全性。相对寻址方案确保测量的值保持一致,只要相对于基地址的偏移量正确维护,无论物理内存位置如何。
总体而言,相对地址和EEXTEND对于重定位enclave的支持有助于确保SGX enclaves的安全性和可移植性,在各种执行环境中部署enclave并保持其安全保证。
(1)
一旦成功调用了EINIT指令,enclave进入了一个被"sealed"(封存)的状态,这标志着enclave构建过程的结束。在这个封存状态下,enclave的代码和数据被认为是安全的,并且受到系统软件的修改保护。EINIT指令是enclave构建过程的最后一步,表示enclave已准备好执行,并且其内容已经最终确定。
在封存状态下,系统软件失去了使用EADD指令向enclave加载额外代码或数据的能力。这样可以防止对enclave内容的未经授权修改,确保enclave的完整性和安全性。
此外,系统软件也被禁止使用EEXTEND指令来更新enclave的测量值。enclave的测量是一个重要的安全属性,它确保了enclave的完整性,并为attestation(验证)提供了基础。通过在封存后阻止系统软件更新测量值,可以保持enclave的完整性,并且可以检测出任何篡改尝试。
总而言之,EINIT指令标志着enclave构建过程的结束,并建立了封存状态,其中enclave的内容受到系统软件的进一步修改保护,而测量值保持不变,以确保enclave的完整性和安全性。
(2)
EINIT指令使用SHA-2最终化算法对enclave的SECS(Secure Enclave Control Structure)中的MRENCLAVE字段进行操作。在EINIT之后,该字段不再存储SHA-2算法的中间状态,而是存储安全哈希函数的最终输出。这个值在EINIT完成后保持不变,并包含在SGX软件attestation过程中生成的attestation签名中。
MRENCLAVE(Enclave Measurement)字段是SECS中的一个重要字段,用于记录enclave的测量值。在enclave构建过程中,SHA-2算法会对enclave的代码和数据进行哈希计算,生成中间状态。然而,在EINIT指令被成功调用后,SHA-2算法会对MRENCLAVE字段的中间状态进行最终化处理,得到最终的哈希输出。
这个最终的哈希输出值在EINIT完成后保持不变,成为enclave的唯一标识,并被用于生成attestation签名。attestation过程是SGX软件的验证过程,用于验证enclave的身份和完整性。通过将MRENCLAVE值包含在attestation签名中,可以确保在验证过程中可以验证enclave的正确性,并防止篡改。
因此,EINIT指令通过应用SHA-2最终化算法,将enclave的MRENCLAVE字段转换为最终的哈希输出,并确保该值在EINIT完成后保持不变。这有助于提供enclave的身份验证和完整性保证,并在attestation过程中起到关键作用。