[翻译]Intel软件开发指南翻译卷3第四部分 第38章
第38章
飞地访问控制和数据结构
38.1飞地执行环境概述
当一个飞地被创建时,它有一系列的线性地址,处理器应用增强的访问控制。这个范围被称为ELRANGE(见第37.3节)。当一个飞地产生内存访问时,会应用现有的IA32分割和分页架构。此外,ELRANGE内的线性地址必须映射到EPC页面,否则当一个飞地试图访问这个线性地址时,会产生一个错误。
EPC页面不需要物理连续。系统软件将EPC页面分配到不同的区域。飞地必须遵守OS / VMM实施的分割和分页策略。OS / VMM管理的页表和扩展页表为飞地页面提供了地址转换。硬件要求将这些页面正确映射到EPC(任何失败都会产生异常)。
飞地进入必须通过特定的飞地指示:
ENCLU[EENTER], ENCLU[ERESUME].
飞地出口必须通过特定的飞地指示或事件发生:
ENCLU[EEXIT], Asynchronous Enclave Exit (AEX).
试图执行、读取或写入映射到EPC页面的线性地址内,而不是在一个飞地内,这将导致处理器改变访问权限,以保持该飞地的机密性和完整性。具体的表现可能在实现的时候是不同的。例如,一个飞地页面的读取可能会导致所有缓存线的cyphertext返回。在一个飞地的页面上写文章可能会在之后的时间里引起一个书写遗漏或者是机器检查。处理器将提供如第38.4节和第38.5节中描述的保护。
38.2术语
对ELRANGE的内存访问,由一块飞地执行的指令发起,称为直接飞地访问(Direct EA)。
内存访问某些Intel?SGX发起的指令叶如:ECREATE, EADD, EDBGRD,EDBGWR, ELDU/ELDB, EWB, EREMOVE, EENTER, 和 ERESUME EPC 页。这些被称为间接飞地访问。表38 - 1列出了SGX1和SGX2扩展的间接EA的附加细节。
直接和间接EAs被称为飞地访问(EAs)。
任何不属于飞地的内存访问都称为非飞地访问。
38.3访问控制要求
飞地访问有以下访问控制权限:
1. 所有内存访问必须符合分割和分页保护机制。
2. 代码从一个飞地中获取一个线性地址,但是在它之外的一个# GP(0)例外。
3. 非飞地访问EPC内存导致未定义的行为。EPC内存受到保护,如第38.4节和第38.5节所述。
4. EPC页面的页面类型PT_REG,PT_TCS和PT_TRIM必须映射到ELRANGE,当EPC页面被分配给这个飞地的时候,使用的就是飞地(EADD)或者是[e8]叶函数。
5. 通过其他线性地址的飞地访问会引起一个#PF和PFEC.SGX设置。
6. 任何EPC页面的直接EAs必须符合EPCM中EPC页面当前定义的安全属性。这些属性可以在飞地创建时间(EADD)中定义,也可以在使用SGX2指令的地方设置它们。这些检查的失败会导致一个#PF和PFEC.SGC设置。
——目标页必须属于当前执行的飞地。
——如果EPCM允许写访问,则可以将数据写入EPC页面。
——如果EPCM允许读访问,则可以从EPC页面读取数据。
——如果EPCM允许执行访问,则允许从EPC页面获取指令。
——目标页不能有受限制的页面类型(PT_SECS,PT_TCS,PT_VA,或PT_TRIM)。
——不能阻塞EPC页面。
——EPC页面不能挂起。
——不能修改EPC页面。
38.4基于航段的访问控制
Intel SGX架构不修改逻辑处理器执行的部分检查。在受保护模式(包括飞地访问)的逻辑处理器中所产生的所有内存访问,都要与适用的段寄存器进行分割检查。
为了确保外部实体不以一种意想不到的方式修改飞地的逻辑到线性的地址转换,ENCLU[EENTER] 和 ENCLU[ERESUME]检查CS, DS, ES, 和 SS, 如果可用(i.e., not null)的段基值为零。这些寄存器的非零段基值导致一个# GP(0)。
在通过EENTER或ERESUME的飞地条目上,处理器保存外部FS和GS寄存器的内容,并将这些寄存器的值加载到在TCS中存储的值,以便在构建时使用这些寄存器来访问该区域内的线程本地存储。在EEXIT和AEX中,进入时的内容被恢复。在AEX中,FS和GS的值保存在SSA框架中。在ERESUME上,FS和GS从SSA框架中恢复。这些操作的细节可以在EENTER、ERESUME、EEXIT和AEX流程的描述中找到。
38.5基于页的访问控制
38.5.1来自非sgx指令访问的访问控制
Intel SGX构建在处理器的分页机制上,为飞地页面提供页面粒度的访问控制。此外,飞地访问必须符合第38.3节所述的访问控制要求或者通过某些英特尔SGX指令。试图执行、读取或写入映射到EPC页面的线性地址,而不是在一个飞地内,将导致处理器改变访问权限,这样会保持该飞地的机密性和完整性。具体的表现可能在实现的时候有所不同。
38.5.2内存访问在ELRANGE中分离
当处理器在一个飞地内时(进入的一部分是在ELRANGE内,一部分是在ELRANGE外),内存数据访问被允许对ELRANGE进行分裂。如果在ELRANGE中有一个访问分割,处理器将访问分成两个子访问(一个在ELRANGE内,另一个在ELRANGE之外),并对每个访问进行评估。由于位于ELRANGE之外的部分,在ELRANGE中分割的代码获取访问时将导致一个# GP。
38.5.3隐式访问VS显式访问
来自Intel SGX指令叶函数的内存访问被归类为显式访问或隐式访问。表38 - 1列出了Intel SGX叶函数所使用的隐式和显式的内存访问。
38.5.3.1显式访问
访问内存位置,为Intel SGX指令叶函数提供显式操作数或者是它的链接数据结构,这被称为显式访问。
显式访问总是使用逻辑地址。这些访问受到分割、分页、扩展分页和apic -虚拟化检查的影响,当访问完成时,触发与这些检查相关的任何故障/退出。
显式内存访问与数据断点的交互作用是特定于叶函数的,这些在43.3.4节中有记录。
38.5.3.2隐式访问
访问物理地址被处理器缓存的数据结构称为隐式访问。这些地址不是作为指令的操作数传递,而是通过使用指令来表示。
这些访问不会触发任何访问控制故障、出口或数据断点。表38 - 1列出了Intel SGX指令叶函数通过显式访问或隐式访问的内存对象。显式访问对象的地址通过寄存器操作数传递,以及通过表38 - 1匹配的第4列的隐式编码寄存器RBX、RCX、RDX传递。
不同隐式访问中使用的物理地址将通过不同的指令和不同的时间缓存。与每个EPC页面关联的SECS的物理地址在页面被添加到飞地的时候缓存ENCLS [EADD] 或ENCLS [EAUG], 或者当页面被加载到EPC的时候缓存ENCLS[ELDB] or或ENCLS[ELDU]。当相应的页面从EPC中通过ENCLS[EREMOVE]或ENCLS[EWB]删除时,这个绑定就被切断了。TCS和SSA页面的物理地址在最近的飞地进入时缓存。退出飞地(ENUNK[EEXIT]或AEX)会刷新此缓存。在第40章中描述了异步飞地出口的细节。
隐式访问缓存的物理地址是在检查后从逻辑(或线性)地址派生出来的,比如分割、分页、EPT和APIC虚拟化检查。这些检查可能触发异常或VM出口。但是,请注意,在缓存物理地址并用于隐式访问之后,这种异常或VM出口可能不会发生。


38.6INTEL?SGX数据结构概述
飞地操作通过数据结构集合管理。许多顶级数据结构都包含子结构。顶层数据结构与可能用于飞地的安装维护的参数有关,由Intel SGX指令或AEX事件使用。顶层数据结构为:
1. SGX飞地控制结构(SECS)
2. 线程控制结构(TCS)
3. 状态保存区(SSA)
4. 页面信息(PAGEINFO)
5. 安全信息(SECINFO)
6. 分页加密元数据(PCMD)
7. 飞地签名结构(SIGSTRUCT)
8. EINIT牌结构(EINITTOKEN)
9. 报告结构(报告)
10. 报告目标信息(TARGETINFO)
11. 关键请求(KEYREQUEST)
12. 版本阵列(VA)
13. 飞地页Cache映射(EPCM)
第38.7节通过第38.19节列出了顶层数据结构和相关子结构的细节。
38.7 SGX飞地控制结构(SECS)
SECS数据结构需要4k字节对齐。


38.7.1属性
属性数据结构由在SECS中使用的位粒度字段、报告和关键请求结构组成。CPUID(EAX = 12H,ECX = 1)枚举属性中允许设置为1的位图。

38.7.2 SECS.MISCSELECT领域
CPUID(EAX = 12H,ECX = 0):EBX[31:0]枚举在AEX发生时,处理器可以把扩展信息保存到SSA的MISC区域。一个飞地作者可以通过SIGSTRUCT来指定如何设置SECS.MISCSELECT字段。MISCSELECT的位向量选择在生成AEX时在SSA框架的MISC区域中保存扩展的信息。扩展信息的位向量定义如表38 - 4所示。
如果CPUID.(EAX = 12H,ECX = 0):EBX[31:0]= 0,SECS。SECS.MISCSELECT必须是零。
SECS.MISCSELECT确定了SSA框架中MISC区域的大小,见第38.9.2节。

38.8线程控制结构(TCS)
在飞地中的每一个执行线程都与线程控制结构相关联。它需要4 k字节对齐。

38.8.1TCS.FLAGS

38.8.2状态保存区偏移(OSSA)
OSSA指向一个保存区域(SSA)框架的堆栈(见第38.9节),当在这个飞地执行时发生中断或异常时,用于保存处理器状态。
38.8.3当前状态保存区域框架(CSSA)
CSSA是当前SSA框架的索引,处理器将使用该索引来决定在执行过程中,飞地发生中断或异常时保存处理器状态的位置。它是由OSSA处理的框架数组中的一个索引。CSSA以一个AEX递增,并在ERESUME上递减。
38.8.4国家保存区域帧数(NSSA)
NSSA指定此TCS可用的SSA帧数。当进入飞地或EENTER将失败时,必须至少有一个可用的SSA框架。
38.9状态保存区(SSA)框架
当AEX在飞地中运行时,架构状态保存在线程当前的SSA框架中,该框架由TCS.CSSA指向。一个SSA框架必须是页对齐的,并且包含以下区域:
1. XSAVE区域从SSA框架的底部开始,该区域包含XSAVE / fxsave兼容的非压缩格式的扩展特性寄存器状态。
2. 一个Pad区域:软件可以选择维护一个填充区域,将XSAVE区域和MISC区分开。软件根据MISC和GPRSGX区域的大小选择pad区域的大小。
3. GPRSGX地区。GPRSGX区域是SSA框架的最后一个区域(见表38 - 7)。这是用来保存处理器通用寄存器(RAX … R15), RIP,外部RSP 和 RBP, RFLAGS 和AEX 信息的.
MISC区域(If CPUIDEAX = 12H,ECX = 0):EBX[31:0]!= 0). MISC区域与GRPSGX区域相邻,并可能包含AEX发生时保存的扩展信息的零个或多个组件。如果MISC区域不存在,那么GPRSGX和XSAVE区域之间的区域是软件可以使用的pad区域。如果MISC区域存在,MISC和XSAVE区域之间的区域是软件可以使用的pad区域。参见第38.9.2节中的其他细节。

38.9.1 GPRSGX范围

38.9.1.1 EXITINFO
EXITINFO包含用来报告飞地内软件的退出原因。它是一个4字节字段,如表38 - 9所列。有效位仅仅是为了在一个飞地内设置异常条件。见表38 - 10,在飞地内报告的异常情况。如果异常情况不是在飞地内部报告的,那么VECTOR和EXIT_TYPE将被清除。

38.9.1.2 VECTOR字段定义
表38 - 10包含VECTOR字段。这个字段包含了关于在飞地内发生的一些异常信息。这些向量值与常规的异常处理程序引导时使用的值相同。所有未显示的值都没有报告在一个飞地内。

38.9.2Misc区域
MISC区域的布局如表38 - 11所示。在MISC区域中处理器支持的组件的数量对应于CPUID的设置位。(EAX = 12H,ECX = 0):EBX[31:0]设为1。每一组都在CPUID中。(EAX = 12H,ECX = 0):EBX[31:0]具有相应组件的定义大小,如表38 - 11所示。飞地作者需要做以下事情:
1. 决定该飞地将支持哪些MISC区域组件。
2. 分配一个足够大的SSA框架来容纳上面所选择的组件。
3. 指导每一个飞地建造者软件在secs . miscselect中设置适当的位。
第一个组件EXINFO在GPRSGX区域的旁边开始。MISC区域中的其他组件在MISC区域内以升序增长,向XSAVE区域增长。
MISC区域的大小按以下方式计算:
1. 如果CPUID.(EAX = 12H,ECX = 0):EBX[31:0]= 0,不支持MISC区域。
2. 如果CPUID。(EAX = 12 h,连成一片= 0):EBX[31:0]!= 0,MISC区域的大小是由SECS.MISCSELECT中最高位集和对应于该位的MISC组件的大小的总和得来的。表38 - 11列出了目前定义的MISC组件的偏移量和大小信息。例如,如果SECS.MISCSELECT中的最高位设置为位0,则MISC区域偏移量为偏移量(GPRSGX)- 16,大小为16字节。
3. 如果且仅当SECS.MISCSELECT[i]为1时,处理器在MISC区域中保存一个MISC组件i。

38.9.2.1EXINFO结构
表38 - 12包含了提供附加信息的EXINFO结构的布局。

38.9.2.2页错误的错误代码
表38 - 13包含了可以在exinfo . errcd中报告的页面错误代码。

在EXINFO中没有报告显示U / S = 0的飞地模式的页面错误
38.10页面信息(PAGEINFO)
PAGEINFO是一种架构数据结构,它被用作EPC管理指令的参数。它需要32字节对齐。

38.11安全信息(SECINFO)
SECINFO数据结构保存一个关于飞地页面的元数据。

38.11.1 SECINFO.FLAGS
SECINFO.FLAGS是描述一个飞地页面属性的一组字段。

38.11.2 PAGE_TYPE字段定义
SECINFO标志和EPC标志包含指示页面类型的位。

38.12分页加密元数据(PCMD)
PCMD结构用于跟踪与分页页面相关联的加密元数据。结合PAGEINFO,它为处理器提供了足够的信息来验证、解密和重新加载分页的EPC页面。PCMD结构的大小(128个字节)是架构性的。
EWB计算消息身份验证码(MAC)值并写出PCMD。ELDB / U读取字段并检查MAC。
PCMD的格式如下:

38.13飞地签署结构(SIGSTRUCT)
SIGSTRUCT是一个由飞地开发人员创建并签署的结构,包含有关飞地的信息。通过EINIT叶函数处理SIGSTRUCT,可以验证该飞地是否正确构建。
SIGSTRUCT包括ENCLAVEHASH as SHA256摘要,定义为FIPS PUB 180 - 4。摘要是长度为32的字节字符串。8个哈希dwords中的每一个都存储在little - endian命令中。
SIGSTRUCT包括四个3072位整数(MODULUS, SIGNATURE, Q1, Q2)。每个这样的整数都表示为长度为384的字节字符串,其中最重要的字节为“偏移量+ 383”,以及“偏移”位置上最不重要的字节。
(3072位整数)签名应该为RSA签名,其中:a)RSA模数(模数)是一个3072位整数;b)公共指数为3;c)签名过程使用emsa - pkcs1 - v1.5格式,在PKCS # 1 v2.1 / RFC 3447中指定的“DigestInfo”值的DER编码。
3072位整数Q1和Q2是由:
q1 = floor(Signature^2 / Modulus);
q2 = floor((Signature^3 - q1 * Signature * Modulus) / Modulus);
SIGSTRUCT必须是页面对齐的
在表38 - 19的第5列中,“Y”表示该字段应该包含在开发人员生成的签名中。


38.14 EINIT TOKEN 结构 (EINITTOKEN)
EINIT使用EINIT标记来验证该飞地是否被允许启动。EINIT标记是由一个飞地拥有的EINITTOKEN密钥(发射飞地)产生的。
EINIT令牌必须为512字节对齐。

38.15报告
报告结构是EREPORT指令的输出,必须是512字节对齐。

38.15.1 REPORTDATA
REPORTDATA是一个64字节的数据结构,由这块飞地提供,并包含在报告中。它可以用来安全地将信息从飞地传递到目标飞地。
38.16报告目标信息(TARGETINFO)
该结构是关于脑叶功能的输入参数。在RBX中,TARGETINFO的地址被指定为一个有效的地址。它被用来识别目标飞地,它将能够通过密码验证埃瑞波特返回的报告结构。TARGETINFO必须是512字节对齐的。

38.17关键请求(KEYREQUEST)
该结构是EGETKEY叶函数的输入参数。它作为RBX中有效的地址传递,必须是512字节对齐。它用于选择适当的键,以及在该键派生过程中附加需要的任何其他参数。

38.17.1关键请求KeyNames

38.17.2密钥请求策略结构

38.18版本阵列(VA)
为了安全地存储被驱逐的EPC页面的版本,Intel SGX定义了一个名为Version Array(VA)的特殊EPC页面类型。每个VA页面包含512个槽,每一个都可以包含一个从EPC中被逐出的页面的8字节版本号。当EPC页面被驱逐时,软件在VA页面中选择一个空槽;这个槽接收被驱逐的页面的唯一版本号。当EPC页面被重新加载时,必须有一个VA槽,它必须持有该页面的版本。如果页面成功地重新加载,将清除VA槽中的版本。
VA页面可以被驱逐,就像其他EPC页面一样。当将一个VA页面逐出时,其他VA页面中的一个版本槽必须被用来保存将被逐出的VA的版本。一个版本的数组页面必须是4k字节对齐的。

38.19飞地隐藏地图页
EPCM是处理器用来跟踪EPC内容的安全结构。EPCM为当前加载到EPC中的每一个页面都保留一个条目。EPCM不是由软件访问的,EPCM字段的布局是特定于实现的。

译注:文章为Intel软件开发指南第38章,翻译的自我感觉有些生硬,希望各位大佬可以指点一下,谢谢。
文章由 敲代码的猫 翻译
