文章目录
- SGX新增
- 第二章 Intel体系架构背景知识
- Overview
- 计算模型
- 软件权限级别
- 地址空间
- 地址转换
- 第五章 SGX Programming Medol
- 5.1 SGX物理内存组织
- 5.1.1 The Enclave Page Cache(EPC)
- 5.1.2 The Enclave Page Cache Map(EPCM)
- 5.1.3 The SGX Enclave Control Structure(SECS)
- 5.2 An SGX Enclave的内存布局
- 5.2.1 The Enclave Linear Address Range(ELRANGE)
- 5.2.2 SGX enclave Attributes
- 5.2.3 Address Translation for SGX enclaves
- 5.2.4 The Thread Control Structure(TCS)
- The State Save Area(SSA)
- 5.3 The life Cycle of an SGX enclave
- 5.3.1 Creation
- 5.7 SGX Enclave Versioning Support
- 5.7.1 Enclave Certificates
- 5.7.2 Certificate-Based Enclave Identity
- 5.7.3 CPU Security Version Numbers
- 5.7.4 Establishing an Enclave’s Identity
- 5.8 SGX Software Attestation
- 5.8.1 Local Attestation
这篇文章翻译自Intel SGX Explained。
SGX新增
新增CPU指令
指令 | 解释 |
---|---|
EREPORT | 发起签名进程?身份认证,签名 |
EGETKEY | 产生认证秘钥 |
特殊的enclave
特定enclave | 解释 |
---|---|
Quoting Enclave | 执行签名进程,能够访问SGX认证秘钥,签名函数等在该enclave里 |
Provisioning enclave | 产生认证秘钥 |
新增硬件结构
硬件结构 | 解释 |
---|---|
EPCM | enclave page cache map,用于页面分配的安全检查 |
SCES | |
EPC |
第二章 Intel体系架构背景知识
了解Intel体系架构的背景来去了解SGX的设计师的想法。
Overview
一个计算机的主要资源是内存和处理器。在Intel计算机中,动态随机存取存储器(DRAM)芯片提供了内存,一个或多个CPU芯片公开逻辑处理器。这些资源由系统软件管理,在Intel中运行两种典型的系统软件,即操作系统和hypervisors(管理程序)。
hypervisor又称虚拟机监视器(英语:virtual machine monitor,缩写为 VMM),是用来建立与执行虚拟机器的软件、固件或硬件。
被Hypervisor用来执行一个或多个虚拟机器的电脑称为主体机器(host machine),这些虚拟机器则称为客体机器(guest machine)。hypervisor提供虚拟的作业平台来执行客体操作系统(guest operating systems),负责管理其他客体操作系统的执行阶段;这些客体操作系统,共同分享虚拟化后的硬件资源。
hypervisor是所有虚拟技术的核心。
x86的管理程序主要分为下边三种架构:1.裸机型,直接安装在硬件资源上,管理硬件资源,操作系统运行并安装在hypervisor之上,2.宿主型,经过操作系统管理硬件资源。最常见的是这两种。
Intel机构被设计来支持运行多个应用程序软件实例,称为进程。操作系统分配计算机的资源来运行进程。服务器计算机,尤其是在云环境中,可能会同时运行多个操作系统实例。这是通过让一个系统管理程序hypervisor将计算机的资源分区在计算机上运行的操作系统实例之间来实现的。
系统软件使用虚拟化技术将其管理的每一个软件(进程或操作系统)与计算机上运行的其他软件隔离开来。这种隔离是将软件复杂性保持在可管理级别的关键工具,因为它允许应用程序和操作系统开发人员专注于他们的软件,而忽略与可能在计算机上运行的其他软件的交互。
虚拟化的一个关键组件是地址转换,它被用来给软件一种它拥有计算机上所有内存的印象。地址转换提供了隔离,防止一个错误或恶意软件通过修改其内存内容直接损坏其他软件。
虚拟化的另一个关键组件是由CPU强制执行的软件特权级别。硬件特权分离确保了一个漏洞或恶意软件不会通过干扰管理它的系统软件而间接损害其他软件。
进程通过创建执行线程来表达它们的计算能力需求,这些执行线程由操作系统分配给计算机的逻辑处理器。线程包含一个执行上下文,这是执行计算所需的信息。例如,一个执行上下文存储了将由处理器执行的下一条指令的地址。
操作系统给每个进程一种错觉,即它有无限数量的逻辑处理器可供处理,并在每个进程创建的线程之间重用可用的逻辑处理器。现代操作系统实现了抢占式的多线程,其中逻辑处理器每隔几毫秒就会在系统上的所有线程之间旋转一次。更改分配给逻辑处理器的线程是通过一个执行上下文切换来完成的。
虚拟机管理程序向每个操作系统公开固定数量的虚拟处理器(vcpu),并使用上下文切换,在呈现给客户操作系统的vcpu之间对逻辑cpu进行多路复用。
逻辑处理器中的执行核心可以以比DRAM提供快得多的速度执行指令和消耗数据。现代计算机架构中的许多复杂性都源于对弥补这种速度差距的需要。最近的Intelcpu依赖于超线程(2.9.4)、无序执行(2.10)和缓存(2.11),所有这些都有安全影响。
英特尔处理器包含许多级别的中间内存,比DRAM快得多,但也要小几个数量级,最快的中间内存是逻辑处理器的寄存器文件(2.2、2.4、2.6)。其他的中间内存被称为缓存(2.11)。
英特尔计算机有多个逻辑处理器。因此,它们在CPU芯片上也有多个缓存。在多套接字系统上,缓存分布在多个CPU芯片上。因此,Intel系统使用缓存一致性机制(2.11.3),以确保所有缓存具有相同的DRAM视图。由于缓存的一致性,程序员可以构建不知道缓存的软件,并且在分布式缓存的存在下仍然能正常运行。但是,缓存的一致性并不包括地址转换(2.11.5)所使用的专用缓存,系统软件必须采取特殊措施来保持这些缓存的一致性。
cpu通过I/O设备(也称为外设)与外部世界进行通信,如网络接口卡和显示适配器(2.9)。从概念上讲,CPU通过一个连接所有这些组件的系统总线与DRAM芯片和I/O设备进行通信。
为Intel架构编写的软件通过I/O地址空间(2.4)和内存地址空间与I/O设备进行通信,内存地址空间主要用于访问DRAM。系统软件必须配置CPU的缓存(2.11.4),以识别I/O设备使用的内存地址范围。设备可以通过调度中断(2.12)通知CPU事件的发生,导致逻辑处理器停止执行其当前线程,并在系统软件(2.8.2)中调用特殊处理程序。
英特尔系统有一个高度复杂的计算机初始化序列(2.13),因为需要支持大量的外设,以及针对不同版本的体系结构的许多操作系统。初始化序列对任何试图保护英特尔计算机的尝试都是一个挑战,并促进了许多安全妥协(2.3)。
英特尔的工程师使用处理器的微码设施(2.14)来实现英特尔架构中更复杂的方面,这大大有助于管理硬件的复杂性。这个微代码对软件开发人员来说是完全看不见的,而且它的设计大多是没有文档记录的。然而,为了评估任何架构更改建议的可行性,必须能够区分可以在微码中实现的更改和只能通过修改硬件实现的更改。
总结: 计算机中最主要的资源是CPU和内存,由操作系统和虚拟管理系统等系统软件来管理这些资源。其中支持多个应用程序软件同时运行,称为进程,进程又有许多线程组成,由虚拟技术来隔离这些软件(虚拟技术通过地址转换和软件特权级别实现),使得软件出现一种计算机资源独享的感觉。
为了降低CPU与内存之间的速度差,有速度最快的是寄存器,其次是缓存cache,要保持缓存一致性,使得所有缓存具有相同的DRAM视图。
CPU通过外部设备(I/O)与外部世界进行通信。
计算模型
本节为实现Intel架构的计算机提供了一个高度简化的模型,如图4所示。这个简化的模型旨在帮助读者的直觉处理论文其余部分使用的基本概念。下面的部分逐步将简化的模型细化为对Intel体系结构的详细描述。
一个计算机的核心的处理器和内存,他们通过一个系统总线连接,计算机也有I/O设备,比如键盘,外设也是通过系统总线与处理器连接。
内存是一个存储单元的数组,从0开始使用自然数进行寻址,并实现了图5中所示的抽象。它的显著特征是,在一个地址上读取一个内存单元的结果必须等于写入到该内存单元的最新值。
该处理器具有一个内部内存,称为寄存器文件。寄存器文件是由静态随机存取存储器单元组成,通常称为寄存器,他们比DRAM单元快很多,但是也贵挺多。
指令对其输入执行简单的计算,并将结果存储在输出位置。处理器的寄存器组成了一个执行上下文,它提供输入并存储大多数指令的输出。例如,ADD RDX、RAX、RBX执行一个整数加法,其中输入是寄存器RAX和RBX,结果存储在输出寄存器RDX中。
图6中提到的寄存器是指令指针(RIP),它存储了处理器要执行的下一条指令的内存地址,以及堆栈指针(RSP),它存储了处理器的过程性编程支持所使用的调用堆栈中的最顶层元素的内存地址。
当一条指令导致故障时,处理器将停止其正常的执行流程,并执行2.8.2中记录的故障处理程序进程。简而言之,处理器首先根据故障的性质查找将处理故障的代码的地址,并设置执行环境,以准备执行故障处理程序。
处理器通过系统总线相互连接并连接到内存上,系统总线是一个实现图7中抽象的广播网络。
在每个时钟周期中,连接到系统总线的设备最多可以发送一条消息,由连接到系统总线的所有其他设备接收。连接到总线上的每个设备将解码总线上发送的所有消息的操作代码和地址,并忽略不需要其参与的消息。
例如,当处理器希望读取存储位置时,它发送具有操作代码read请求和与期望存储位置对应的总线地址的消息。内存会在总线上看到消息并执行READ操作。在稍后的时间里,内存通过发送具有操作代码READ-响应、与请求相同的地址和数据值设置为READ操作的结果的消息来响应。
计算机通过I/O设备与外界进行通信,如键盘、显示器和网卡,这些设备都连接到系统总线上。设备大多响应处理器发出的请求。然而,设备也能够发出中断请求,通知处理器的外部事件,例如用户按下键盘上的一个键。
中断触发将在2.12中进行讨论。在现代系统中,设备通过对特殊的总线地址发出写操作来发送中断请求。中断被认为是硬件异常,就像故障一样,并以类似的方式处理。
总结: 这一小节介绍了计算机的各个结构,通过系统总线连接和通信,各个寄存器的作用,故障处理,中断等。
软件权限级别
在基础设施即服务(IaaS)云环境中,如Amazon EC2,商品cpu在四个不同的特权级别上运行软件,如下图所示:
每个特权级别都比下面的特权级别更强大,因此一个软件可以自由读取和修改运行在较低特权级别的代码和数据。因此,一个软件模块可以被任何运行在更高特权级别的软件所破坏。因此,一个软件模块隐式地信任运行在更多特权级别上的所有软件,并且系统的安全分析必须考虑到所有特权级别上的软件。
系统管理模式(SMM)是为主板制造商实现风扇控制和深度睡眠等功能,和/或模拟缺失的硬件。
因此,计算机固件中的引导软件(§2.13)负责将DRAM的连续子集设置为系统管理RAM(SMRAM),并将需要在SMM模式下运行的所有代码加载到SMRAM中。SMRAM享有特殊的硬件保护,以防止享有较低特权的软件访问SMM代码。
IaaS云提供商允许其客户在虚拟化环境中运行其选择的操作系统。硬件虚拟化[181],被Intel称为虚拟机扩展(VMX),增加了对系统管理程序的支持,在Intel文档中也称为虚拟机监视器(VMM)。虚拟机监控程序以比操作系统更高的特权级别(VMX根模式)运行, 并负责在共享同一物理机器的多个操作系统之间分配硬件资源。该管理程序使用CPU的硬件虚拟化特性,使每个操作系统都相信它是在自己的计算机上运行的,这被称为虚拟机(VM)。管理程序代码通常在VMX根模式下以环0运行。
系统研究文献建议将操作系统分解成一个小内核,这个小内核运行在高特权级别,称为内核模式或监督模式,在Intel体系结构中,称为环0。内核将计算机的资源分配给其他系统组件,如以较低的特权级别运行的设备驱动程序和服务。然而,由于性能原因,主流操作系统有大量的代码在环0处运行。它们的单片内核包括设备驱动程序、文件系统代码、网络堆栈和视频渲染功能。
应用程序代码,如Web服务器或游戏客户端,运行在最低的特权级别,称为用户模式(在Intel架构中的环3)。在IaaS云环境中,客户提供的虚拟机映像在VMX非根模式下运行,因此内核在VMX非根环0中运行,而应用程序代码在VMX非根环3中运行。
总结: 介绍了计算机的软件特权级别,高一级别的软件可以访问低级别的资源。
地址空间
为英特尔体系结构编写的软件使用四个不同的物理地址空间访问计算机的资源,如图9所示。地址空间在目的和内容上部分重叠,这可能导致混淆。本节提供了由Intel架构定义的物理地址空间的高级概述,重点介绍了它们的目的和用于管理它们的方法。
四个物理地址空间:寄存器和MSR是CPU内部的,内存地址空间和I/O地址空间被用来在DRAM和其他设备之间的通信通过系统总线。
寄存器空间由用于访问CPU的寄存器文件的名称组成,这是唯一在CPU的时钟频率下运行的内存,可以使用而没有任何延迟惩罚。寄存器空间由CPU的体系结构定义,并记录在SDM中。(寄存器空间是由寄存器文件组成)
一些寄存器,如控制寄存器(CRs),在配置CPU的操作中发挥着特定的作用。例如,CR3在地址翻译中起着核心作用(2.5)。这些寄存器只能通过系统软件进行访问。其余的寄存器组成了一个应用程序的执行上下文(2.6),这本质上是一个高速的抓取空间。这些寄存器可以在所有特权级别上访问,它们的分配由软件的编译器管理。许多CPU指令只对寄存器中的数据进行操作,并且只将其结果放在寄存器中。
内存空间,通常称为地址空间,或物理地址空间,由2^36个(64 GB)- 2 ^40个(1 TB)地址组成。内存空间主要用于访问DRAM,但它也用于与内存映射设备通信,这些设备从系统总线上读取内存请求并为CPU写响应。一些CPU指令可以从内存空间读取它们的输入,或者使用内存空间存储结果。
输入/输出(I/O)空间由2 ^16个I/O地址组成,通常称为端口。I/O端口专门用于与设备进行通信。CPU提供了从读取和写入I/O空间的特定指令。I/O端口按照正式的或事实上的标准分配给设备。例如,端口0xCF8和0xCFC总是用于访问PCIexpress(2.9.1)配置空间。
特定模型的寄存器(MSR)空间由2 ^32个MSR组成,用于配置CPU的操作。MSR空间最初打算用于使用特定于CPU模型的固件,但一些MSR已经被提升到架构中的MSR状态,使它们的语义成为Intel架构的一部分。例如,体系结构MSR 0x10拥有一个高分辨率、单调递增的时间戳计数器。
总结:这一小节介绍了CPU和系统总线里的地址空间,计算机通过使用这四种地址空间来访问计算机上的资源。
地址转换
系统软件依赖于CPU的地址转换机制来实现在较低特权的软件部分(应用程序或操作系统)之间的隔离。几乎所有安全体系结构设计都为地址转换带来变化。
从系统的角度来看,地址转换是由程序的内存加载和存储指令使用的虚拟地址和引用物理地址空间(2.4)的物理地址之间的一个间接层(如图10所示)。虚拟地址和物理地址之间的映射由由系统软件管理的页表来定义。
操作系统使用地址转换来实现虚拟内存抽象,如图11所示。虚拟内存抽象公开了与2.2中的内存抽象相同的接口,但是每个进程都使用一个单独的虚拟地址空间,该空间只引用分配给该进程的内存。从应用程序开发人员的角度来看,虚拟内存可以通过假装每个进程都运行在单独的计算机上,并有自己的DRAM来进行建模。
操作系统使用地址转换在多个应用程序进程之间多路复用DRAM,将进程彼此隔离,并防止应用程序代码直接访问被内存映射的设备。后两种保护措施可以防止应用程序的bug影响其他应用程序或操作系统内核本身。管理程序还使用地址转换,在并发运行的操作系统之间划分DRAM,并虚拟化与内存映射的设备。
64位操作系统所使用的地址转换模式,被Intel的文档称为IA-32e,它将48位虚拟地址映射到最多52位的物理地址。转换过程,如图12所示,是由CPU中的专用硬件执行的,这被称为地址转换单元或内存管理单元(MMU)。
除了隔离应用程序进程外,操作系统还使用地址转换特性来运行其集体内存需求超过计算机中安装的DRAM数量的应用程序。该操作系统会将很少使用的内存页面从DRAM转移到较大(但较慢)的存储器中,如硬盘驱动器(HDD)或固态驱动器(SSD)。由于历史原因,这个较慢的内存被称为磁盘。
第五章 SGX Programming Medol
SGX的核心概念就是enclave,是一个受保护的环境,其包含对安全敏感计算有关的代码和数据。
支持SGX的处理器提供可信计算,通过将不可信的软件隔离在enclave外来隔离每个enclave的环境,并且通过实现一个软件验证方案(software attestation)允许一个远程party来认证其软件运行在enclave中。SGX的隔离机制旨在保护在enclave里执行的计算的机密性和完整性,免受来自在同一计算机上执行的恶意软件的攻击,以及有限的物理攻击。
这一章总结了SGX的概念。本章的信息来源于Intel’s Software Developer Manual。
总结: SGX的enclave,提供隔离环境和认证功能,隔离包括enclave之间的隔离和enclave和不可信软件的隔离,认证包括本地enclave之间的认证和远程认证。为在enclave运行的数据和代码提供机密性和完整性。
5.1 SGX物理内存组织
enclave的代码和数据存储在Processor Reserved Memory(PRM,处理器预留内存)中,该内存是DRAM的子集,并且该内存不能由其他软件(包括系统软件和SMM code)直接访问。CPU的集成内存控制器(MMU?)也拒绝针对PRM的MDA传输,从而保护该内存不被其他外设访问。
总结:enclave的代码和数据放在内存DRAM里的一块专有内存PRM中,其中该内存不被其他特权软件访问,也不被DMA访问。(DMA是不经过CPU就直接能从内存存取数据的数据交换模式)
PRM是一个连续的内存范围,其bounds由base和一个掩码寄存器进行设置,其语义和 a variable memory type range(2.11.4中有讲)相同。因此,PRM的大小必须是2的整数次幂,并且它的起始地址必须与2的相同次幂对齐。由于这些限制,检查一个地址是否属于PRM是很简单就由硬件完成,使用2.11.4概述的电路。
这里讲的是PRM这块内存地址的限制,使得该内存地址更容易的与其他普通内存区分,更好的实现隔离。
Intel的软件开发手册里没有描述PRM和PRM范围寄存器(PRMRR)。这些概念是在SGX的手册和SGX的论文中描述的。因此,PRM是一个微架构细节。我们对SGX的安全分析依赖于围绕PRM的实现细节。
5.1.1 The Enclave Page Cache(EPC)
enclaves的内容和其有关的数据结构都存储在EPC中,EPC是PRM的子集。
SGX的设计支持在一个系统上同时有多个enclaves,这在多进程环境中时必要的。这是通过将EPC分成4KB的页面,可以分配给不同的Enclaves。EPC使用与体系结构的地址转换特性相同的页面大小。这并不是是一个巧合,因为未来的部分将揭示SGX实现与地址转换实现是紧密结合的。
EPC由管理计算机其余物理内存的同一系统软件管理。该系统软件可以是hypervisor(系统管理程序),或者是OS kernel,它使用SGX指令将未使用的页面分配给enclaves,并释放以前分配的EPC页面。该系统软件预计将enclaves的创建和管理服务暴露给应用程序软件。
Non-enclave软件不能直接访问EPC,因为它包含在PRM中,这种限制在SGX的enclave隔离保证中起着关键作用,但当系统软件需要将初始化代码和数据加载到一个新创建的enclave时,就会造成障碍。SGX设计通过将EPC页面分配给enclave的指令的同时也初始化这个页面来解决这个问题。大多数EPC页面都是通过从Non-PRM内存页面中复制数据来初始化的。
总结:EPC是PRM处理器预留内存的一部分,而PRM又是DRAM的一部分,所以EPC也可以说是DRAM的一部分。PRM是一块受保护的内存,除了EPC还有其他数据。
EPC由4KB大小的页面组成,这些页面可以分配给不同的enclaves。一个系统上可以有多个enclaves并存,支持多进程操作。
EPC由不可信的操作系统管理,使用SGX特定指令来分配和销毁
分配页面的同时也进行了数据初始化,将数据复制到EPC页中。
5.1.2 The Enclave Page Cache Map(EPCM)
SGX的设计希望系统软件将EPC页面分配给enclaves,但是,由于系统软件是不可信的,SGX处理器将会检查系统软件的分配决策的正确性,并拒绝执行任何会危及SGX的安全保证的操作。例如,如果系统软件试图将相同的EPC页面分配给两个Enclaves,则用于执行该分配的SGX指令将会失败。
为了执行其安全检查,SGX会在EPCM中记录关于每个EPC页面的系统软件分配决策的一些信息。EPCM是一个数组,每个EPC页面有一个条目,所以计算一个页面的EPCM条目的地址只需要逐位移位操作和加操作。
EPCM的内容只用于SGX的安全检查。在正常的运行下,EPCM不会产生任何软件可见的行为,Enclave所有者和系统软件开发人员大多可以忽略它。因此,开发手册上只在非常高的级别上描述EPCM,列出其中包含的信息,并指出EPCM是“可信的内存”,开发手册没有公开EPCM所使用的存储介质或内存布局。
EPCM使用下表中的信息来跟踪每个EPC页面的所有权。我们将EPCM的完整讨论推迟到后面的部分,因为他的内容与SGX的所有特性紧密相关,这将在接下来的几个部分中进行描述。
分配一个EPC页面的SGX指令将相应的EPCM条目的VALID位设置为1,并拒绝对已经设置了VALID位的EPC页面进行操作。
用于分配EPC页面的指令还确定了页面的预期用途,该用途记录在相应EPCM条目的页面类型(PT)字段中。存储一个enclave的代码和数据的页面被认为具有一个常规类型(regular type,在手册中的PT_REG)。专门用于存储SGX的支持数据结构的页面被标记为特殊类型,例如,PT_SECS类型标识了包含SGX enclave控制结构的页面。
最后,一个页面的EPCM条目还标识了拥有EPC页面的enclave。这些信息被强制执行SGX的隔离保证的机制所使用,以防止一个enclave访问另一个enclave的隐私信息。由于EPCM为每个EPC页面标识一个拥有的enclave,因此enclaves不可能使用EPC页面通过共享内存进行通信。幸运的是,enclaves可以共享不可信的Non-EPC内存,这将在5.2.3中讨论。
因为EPC页面是由不可信的系统软件分配的,所以SGX设计了一种安全检查机制EPCM来检查系统软件的分配是否正确,EPCM可以理解成一个多维数组,每个数组元组对应一个EPC页面,记录该EPC页面是否被分配、页面类型、该页面分配给了哪个enclave。
5.1.3 The SGX Enclave Control Structure(SECS)
SGX将每个enclave的元数据存储在与每个enclave关联的SGX enclave control structure(SECS)中。每个SECS都存储在一个专用的EPC页面中,页面类型为PT_SECS。这些页面不被映射到任何enclaves的地址空间,而是由CPU的SGX实现专门使用的。
一个enclave的身份几乎是它的SECS的同义词。激活一个enclave的第一步就是分配一个EPC页面作为该enclave的SECS,而销毁一个enclave的最后一步是释放所持有的SECS的页面。EPCM的条目字段标识了这个enclave拥有这个EPC页面,该字段指向这个enclave的SECS。系统软件调用SGX指令时,使用一个enclave的SECS虚拟地址来识别该enclave。
所有的SGX指令都以虚拟地址作为其输入。鉴于SGX指令使用SECS地址来识别enclaves,系统软件必须在其页表中创建指向其管理的enclave的ESCS的条目。但是,系统软件无法访问任何的SECS页面,因为这些页面存储在PRM中。SECS页面不被映射到其enclave的虚拟地址空间中,并且启用了SGX的处理器显示地阻止enclave代码访问SECS页面。
SGX实现可以在SECS中存储敏感信息,并且能够假设没有潜在的恶意软件会访问这些信息。例如,开发文档中声明每个enclave的度量都存储在SECS中。如果软件能够修改一个enclave的度量值,那么SGX软件认证方案将不会提供任何的安全保证。
SECS与SGX的许多特性紧密结合,因此,随着SGX的介绍,将逐步介绍组成SECS的信息。
标识enclave的身份信息等元数据存放在SECS中,该SECS是一个专有EPC页面,与enclave的数据和代码的页面类型不同。不映射到enclave的虚拟地址空间,并且不允许enclave代码访问。
软件系统要分配EPC页面时,无法访问任何的SECS的页面,需要在页表上创建指向SECS的条目。(系统软件维护的这个页表需要了解)
明晰ECPM和ESCS的关系:EPCM中的条目中有一个字段,指向该enclave的ESCS。
EPCM对于系统软件是否可见?
5.2 An SGX Enclave的内存布局
SGX的设计目的是最小化影响,即需要转换应用代码来利用enclaves。历史证明,这是一个明智的决定,因为Intel架构持续占据主导地位的一个重要因素是他保持向后兼容的能力。为此,SGX enclaves被设计成在概念上类似于软件模块化构造,动态加载库,它们被打包为Unix上的.so文件,Windows上的.dll文件。
为了简单起见,我们描述了enclaves和non-enclaves软件之间的交互,假设每个enclave只由一个应用程序进程使用,我们称之为enclave的主进程。然而,注意到,SGX设计并没有明确禁止多个应用程序进程共享一个enclave。
5.2.1 The Enclave Linear Address Range(ELRANGE)
每个enclave在其虚拟地址空间中指定一个区域,称为enclave线性地址范围(ELRANGE),用于映射存储在该enclave的EPC页面中的代码和敏感数据。ELRANGE之外的虚拟地址空间被映射到通过与enclave的主进程相同虚拟地址来访问non-EPC内存,如下图所示。
这个图片:enclave的EPC页面使用enclave的虚拟地址空间中专有区域来访问。虚拟地址空间剩余的部分用来访问主程序的内存(non-EPC部分)。这个内存映射是使用系统软件管理的页表来建立的。
SGX设计保证enclave在ELRANGE里的内存访问服从虚拟内存抽象,但是ELRANGE之外的没有任何保证。因此,enclaves必须将所有的代码和隐私数据存储在ELRANGE内,并且必须将ELRANGE之外的内存看做是外部世界不可信的接口。
这里为了方便理解,放入2.5.1节内容:
从系统角度来看,地址转换是一个虚拟地址和物理地址之间的中间层。如下图所示。其中,虚拟地址用来加载一个程序的内存和存储指令的,物理地址指的是物理地址空间。
操作系统使用地址转换来实现虚拟内存抽象,如下图所示。虚拟内存抽象揭示了与2.2节中的内存抽象相同的接口,但是每个进程都使用一个单独的虚拟地址空间,该空间只引用分配给该进程的内存。从应用程序开发人员的角度来看,虚拟内存可以假装每个进程都运行在单独的计算机上,并有自己的DRAM来进行建模。
ELRANGE中的“线性”一次指的是64位Intel架构中的vestigial segmentation(详细看2.7节解释)特性所产生的的线性地址。在大多数情况下,“线性”可以被视为“虚拟” 的同义词。
ELRANGE可使用enclave的SESC中的base(BASEADDR字段)和size(SIZE)来指定。ELRANGE必须满足与variable内存类型范围(2.11.4)和PRM范围相同的约束条件,即大小必须为2的幂,并且base必须与大小对齐(这里不是很理解)。这些限制是这样的,以便SGX实现可以在硬件或者软件中容易地检查一个地址是否属于一个enclave的ELRANGE。
当一个enclave代表一个动态库时,自然会将ELRANGE设置为由loader为库保留的内存范围。从enclave代码访问non-enclave内存的能力使重用现有的库代码变得很容易,这些库代码希望与指向主进程中有代码管理的内存缓冲区的指针一起工作。
Non-enclave软件无法访问PRM内存,在PRM内部解析的内存访问会导致事务中止,该事务在架构级别上未定义,在当前的处理器上,中止写操作是被忽略的,中止读返回一个值,他们的位都被置为1。这在上面的应用场景中发挥作用,将enclave作为动态加载库加载到主程序进程中。该系统软件将这个enclave的代码和数据映射到EPC页面中。如果应用程序软件试图访问ELRANGE内的内存,他将会经历abort 事务语义。当前的语义不会导致应用程序崩溃(例如,页面故障),但也保证主应用程序不能篡改enclave或读取其隐私信息。
总结:这里主要讲的是enclave也是用到了内存抽象的概念,让程序运行者以为程序独占了内存空间。系统软件将虚拟内存和物理内存通过页表来映射,其中enclave映射的EPC内存由ELRANGE专有虚拟内存空间。ELRANGE的基地址和大小由ESCS结构确定。
思考:这里怎么联系系统软件与ESCS的关系?因为ESCS是在PRM里的,系统软件是访问不了的,那么系统软件管理的页表是如何映射到EPC的呢?
5.2.2 SGX enclave Attributes
Enclave的执行环境严重受到SECS中ATTRIBUTES字段的影响。本工作的其余部分将指出字段的子字段,如下表所示:
SECS结构中有一个字段是ATTRIBUTES,同时ATTRIBUTES字段中又有一些子字段。
从安全的角度看,最重要的属性是DEBUG标志。当设置此标志时,它允许为此enclave使用SGX的调试特性。这些调试特性包括能够读取和修改enclave的大部分内存。因此,DEBUG应该只在开发环境中设置,因为它会导致enclave失去所有的SGX安全保证。
SGX保证enclave的代码始终在将XCR0寄存器设置为extended features request mask(XFRM)所指示的值时运行。enclave的作者应该使用XFRM来指定用于生成enclave代码的编译器所启用的架构扩展集。明确指定XFRM允许Intel设计新的架构扩展,以改变现有的指令语义,如内存保护扩展(MPX),而不必担心在没有意识新特征的情况下开发的enclave代码的安全影响。
对于使用64位Intel架构的enclave,MODE64BIT标志被设置为真。从安全的角度来看,这个标志位甚至不应该存在,因为支持二级体系结构为SGX实现增加了不必要的复杂性。32位架构支持很可能是由于Intel提供广泛的向后兼容性的策略,这到目前为止已经获得了相当好的回报。
这个工作没有分析那些MODE64BIT标记被清除的enclave的SGX行为,然而,一个希望发现SGX漏洞的安全研究人员可能会研究这一领域。
最后,在创建enclave的SECS时,INIT标志总为FALSE。这个标志在enclave生命周期的某个点设置为TRUE,这将在5.3中总结。
总结:这些SECS的属性对enclave的调试,运行时的环境进行了设置。
5.2.3 Address Translation for SGX enclaves
在SGX下,系统软件和hypervisor仍然完全控制页表和EPTs(Extended Page Tables,扩展页表),并且每个enclave的代码使用与其主应用程序相同的地址转换进程和页表。这将最小化减少向现有的系统软件添加SGX支持所需的更改量。同时,通过不受信任的系统软件管理页表,将在3.7节中描述对SGX的地址转换攻击。正如未来章节将揭示的那样,SGX设计的大量复杂性可以归因于防止这些攻击的需要。
SGX的主动内存映射攻击防御机制围绕着确保每个EPC页面只能被映射到一个特定的虚拟地址。当分配EPC页面时,其预期的虚拟地址将记录在页面的EPCM条目ADDRESS字段中。
当地址转换结果是EPC页面的物理地址时,CPU确保提供给地址转换进程的虚拟地址与记录在页面的EPCM条目中的预期虚拟地址相匹配。
SGX还通过确保每个EPC页面的访问权限始终与enclave的所有者的意图匹配来防止一些被动内存映射攻击和错误注册攻击。对于每个EPC页面的访问权限,在分配页面时指定,并记录在页面的EPCM条目中的可读(R)、可写(W)和可执行(X)字段中,如下表所示:
当地址转换解析为EPC页面时,相应的EPCM条目字段将覆盖页表中指定的访问权限属性。例如,EPCM条目中的W字段覆盖可写(W)属性,而X字段覆盖禁止执行(XD)属性。
地址转换2.5节:CPU的地址转换机制。转换进程,是由CPU中的专有硬件执行的,被称为地址转换单元或内存管理单元(MMU)
因此,允许enclave的所有者必须知道enclave的同时知道内存布局信息,这样,加载enclave的系统软件将知道每个enclave页面的预期虚拟内存地址和访问权限。作为回报,SGX设计向enclave所有者保证,管理页表和EPT的系统软件将无法与所有者期望不一致的方式设置enclave的虚拟地址空间。
.so和.dll文件格式是SGX预期的enclave交付工具,他们已经规定了指定软件模块设计要使用的虚拟地址,以及每个模块内存区域的所需访问权限。
最后,启用SGX的CPU将确保ELRANGE内的虚拟内存映射到EPC页面。这可以防止系统软件执行地址转换攻击,即它将enclave的整个虚拟地址空间映射到PRM之外的DRAM页面,这些页面不会出发上述任何检查,并且可以被系统软件直接访问。
这节讲的是虚拟地址到物理地址的地址转换,enclave预期的虚拟地址放在EPCM中的ADDRESS字段中,以及enclave的访问权限都在EPCM中。系统软件分配页面时必须按照enclave所用者设置的访问权限设置页面。
地址转换需要依赖CPU的地址转换机制MMU。它来实现从虚拟地址到物理地址的映射,那么是不是能解决系统软件不接触EPC物理地址的问题?去了解一下地址转换,页表和地址转换机制的关系?
5.2.4 The Thread Control Structure(TCS)
SGX的设计完全采用了多核处理器。多个逻辑处理器可以通过不同的线程同时执行同一enclave的代码。
SGX实现对执行enclave代码的每个逻辑处理器使用线程控制结构(TCS)。因此,一个enclave的所有者必须提供至少与该enclave打算支持的最大并发线程数量相同的做多的TCS实例。
每个TCS都存储在一个专用的EPC页面中,其中EPCM条目类型为PT_TCS。手册中描述了TCS中的前几个字段。这些字段被认为属于结构的体系结构部分,因此保证在所有支持SGX的处理器上具有相同的语义。其余文档没有TCS的记录。
包含TCS的EPC页面的内容不能直接访问,即使是通过拥有TCS的enclave代码也不能直接访问。此限制类似于对包含SECS实例的EPC页面的访问限制。但是,TCS中的体系结构字段可以通过enclave的调试指令来读取。
TCS的体系结构字段展示了逻辑处理器在执行non-enclave代码和enclave代码之间转换时执行的上下文切换。
例如,OENTRY字段指定当TCS用于开始执行enclave代码时,在指令指针(RIP)中加载的值,因此enclave所有者对enclave的主应用程序可用的入口点有严格的控制。此外,OFSBASGX和OGSBASGX字段指定了加载在FS和GS段寄存器中的基本地址,这通常指向线程本地存储(TLS)。
总结:这节主要讲SGX允许并发执行,通过线程控制结构TCS满足。TCS是一个专有EPC页面,不被enclave的代码访问,和SECS结构类似。
The State Save Area(SSA)
当在enclave中执行代码时,当处理器遇到硬件异常,例如中断,它执行一个特权级别的转换并调用系统软件提供的硬件异常处理程序。但是,在执行异常处理程序之前,处理器需要一个安全区域来存储enclave代码的执行上下文,这样执行上下文中的信息就不会显示给不受信任的系统软件。
在SGX的设计中,在处理硬件异常时,用于存储enclave线程的执行上下文的区域称为State Save Area(SSA),如下图所示。每个TCS引用一个连续的SSA序列。The offset of the SSA array(OSSA)字段指定了该enclave的虚拟地址空间中的第一个SSA位置。The number of SSAs(NSSA)字段指定了可用的SSA的数量。
每个SSA从EPC页面的开头开始,并占用在enclave SECS的SSAFRAMESIZE字段中指定的EPC页面数。这些对齐和大小限制很可能通过减少需要处理的特殊情况的数量来简化SGX的实现。
一个飞地线程的执行上下文由通用寄存器(GPRs)和XSAVE指令(2.6)的结果组成。因此,执行上下文的大小取决于XSAVE所使用的requested-feature bitmap(RFBM)。一个飞地中的所有代码都使用相同的RFBM,该RFBM在XFRM飞地属性(5.2.2)中声明。为SSA指定的每个SSA保留的EPC页数必须足够大,以适合XFRM指定的feature bitmap的XSAVE输出。
SSAs存储在常规的EPC页面中,其EPCM页面类型为PT_REG。因此,SSA的内容可以被enclave软件访问,SSA的布局结构被完全的记录在开发手册中。这打开了主应用程序调用的飞地异常处理程序发生硬件异常的可能性,并对SSA中的信息进行操作。
总结:这节主要讲的是当执行enclave代码时,发生异常,则需调用系统软件执行异常处理程序。这里需要将enclave代码上下文安全的保存起来,SSA就是这个作用。
5.3 The life Cycle of an SGX enclave
enclave的生命周期与资源管理深深地交织在一起,特别是EPC页面的分配。因此,在不同生命周期状态之间转换的指令只能由系统软件来执行。系统软件预计将把下面描述的SGX指令作为enclave加载和销毁服务。下面的小节描述了一个enclave的生命周期中的主要步骤,如下图所示:
5.3.1 Creation
当系统软件发出ECREATE指令时,一个enclave就创建了,该指令将一个空闲的EPC页面转换为新enclave的SECS。
ECREATE使用系统软件拥有的non-EPC页面中的信息初始化这个新创建的SECS。此页面指定开发手册中定义的所有SECS字段的值,如BASEADDR和SIZE,使用保证在未来实现中保留的架构布局。
5.7 SGX Enclave Versioning Support
由可信平台模块(4.4)引入的软件认证模型(3.3)依赖于一个度量(5.6),它本质上是一个内容散列,用于识别容器内的软件。使用内容哈希作为标识的缺点是,保存同一软件的不同版本的容器的身份之间没有关系。
在实践中,基于安全容器的系统非常希望能够处理软件更新,而不需要在最初的软件证明过程中访问远程方。这需要能够在具有旧版本软件的容器和有软件更新的容器之间迁移秘密。这一要求意味着需要一个单独的识别系统,可以识别同一软件的两个版本之间的关系。
SGX支持在代表同一软件的不同版本的飞地之间的秘密迁移,如下图所示。
秘密迁移特性依赖于一个one-level证书层次结构,其中每个enclave author都是一个Certificate Authority,每个enclave都收到一个来自其author的证书。这些证书必须被格式化为Signature Structure(SIGSTRUCT),这在5。7.1中有描述。这些证书中的信息是5.7.2中提出的enclave身份方案的基础,该方案可以识别同一软件的不同版本之间的关系。
EINIT指令检查目标enclave的证书,并使用其中的信息来填充描述该enclave的基于证书的身份的SECS字段,此过程在5.7.4中总结了。
最后,实际的秘密迁移过程是基于由EGETKEY指令实现的密钥派生服务,详见5.7.5。发送enclave使用EGETKEY指令根据其身份获得一个对称密钥,用密钥加密他的秘密,并将加密的秘密交给不受信任的系统软件。接收enclave将发送enclave的身份传给EGETKEY,获得与上面相同的对称密钥,并使用该密钥对从系统软件接收到的秘密进行解密。
从EGETKEY获得的对称密钥可以与加密原语一起使用,以保护被不可信的系统软件迁移到另一个飞地时的一个飞地机密的机密性和完整性。但是,对称密钥不能单独用来提供新鲜度保证,因此秘密迁移会受到重放攻击。当正在迁移的秘密是不可变的时,例如当这些秘密是通过软件认证获得的加密密钥时,这是可以接受的。
每个enclave都有一个证书,该证书由其作者颁布,证书结构为SIGSTRUCT。EINIT指令检查每个enclave的证书是否合法。
证书中的信息是为了可以识别同一软件的不同版本之间的关系,更方便的实现同一软件不同版本之间的秘密迁移。
5.7.1 Enclave Certificates
SGX的设计要求每个enclave都有一个由其author颁发的证书,该要求由EINIT指令强制执行,并拒绝在没有有效证书的enclave上操作。
SGX实现使用格式化为Signature Structures(SIGSTRUCT)的证书,这些证书打算由一个enclave构建toolchain生成,如下图所示。
一个SIGSTRUCT证书由元数据字段组成,其中最有趣的在表19,以及一个保证元数据真实性的RSA签名,其格式如表20所示,这些字段的语义将在下面的章节出现。
ISVPRODID:区分同一私钥签名的模块;ISVSVN:区分同一模块的版本;VENDOR:区分Intel enclaves
enclave证书必须由RSA签名算法签名,它遵循RFC 3447,使用256位SHA-2作为减少输入大小的哈希函数,以及PKCS #1 v1.5中描述的填充方法,如图45所示。
SGX实现只支持3072位RSA密钥,其公共指数位3.密钥大小的选择可能是为了满足FIPS的建议,该建议使SGX有资格在美国政府的应用程序中使用。公共指数3提供了一个简化的签名验证算法,并在6.5中进行了讨论。简化的算法还需要RSA签名中的字段Q1和Q2,这也在6.5中描述。
5.7.2 Certificate-Based Enclave Identity
一个enclave身份由其证书中的三个字段决定:用来签名证书所使用的RSA密钥的模数(MODULUS),enclave的产品ID(ISVPRODID)和安全版本号(ISVSVN)。
用于颁发证书的RSA公钥标识了该enclave的作者。所有用于颁发飞地证书的RSA密钥必须将公共指数设置为3,因此它们只通过它们的模数来区分。SGX不使用一个key的整个模量,而是使用一个模量的256位SHA-2哈希。 这被称为签名者度量(signer measurement,MRSIGNER),与enclave度量(MRENCLAVE)的名称相似,enclave度量是用于识别飞地内容的SHA-2 哈希值。
SGX的实现依赖于一个硬编码的MRSIGNER值来识别英特尔颁发的证书。拥有由intel颁发的证书的飞地可以获得额外的特权,这将在5.8中进行讨论。
enclave作者可以使用相同的RSA密钥为代表不同软件模块的enclave颁发证书。每个模块通过唯一的Product ID(ISVPRODID)值标识。相反地,所有enclaves假设代表同一软件模块的不同版本,这些enclave的证书具有相同的ISVPRODID并被相同的RSA密钥颁发(因此具有相同的MRENCLAVE)。
表示一个模块的不同版本的飞地可以有不同的安全版本号(SVN)。SGX的设计不允许将秘密从SVN较高的飞地迁移到SVN较低的飞地。此限制旨在帮助分发安全补丁,如下所示。
如果在飞地中发现了安全漏洞,作者可以发布具有更高SVN的修补版本。随着用户的升级,SGX将促进秘密从飞地的脆弱版本迁移到修补版本。一旦用户的秘密被迁移,SGX中的SVN限制将抵御任何基于构建脆弱的飞地版本并使用它来读取迁移的秘密的攻击。
添加功能的软件升级不应该伴随着SVN的增加,因为SGX允许秘密在具有匹配的SVN值的飞地之间自由地迁移。如上所述,只有在发现安全漏洞时,软件模块的SVN才会增加。SIGSTRUCT只为ISVSVN字段分配2个字节,即65,536个可能的SVN值。如果一个大团队(错误地)设置了一个连续的构建系统,为它产生的每个软件构建分配一个新的SVN,并且每个代码更改都会触发一个构建,那么这个空间可能会耗尽。
基于证书的enclave识别是通过RSA密钥的模数(MODULUS),enclave的产品ID(ISVPRODID),安全版本号(ISVSVN)决定。其中同一软件的不同版本的MODULUS和ISVPRODID相同,ISVSVN不同。SVN高的秘密不允许迁移至SVN低的enclave。当软件有漏洞时,才新创建一个安全版本号。同一软件相同产品ID和相同的安全版本号之间,enclave的秘密可以自由的迁移。
5.7.3 CPU Security Version Numbers
SGX实现本身有一个安全版本号(CPUSVN),除了飞地的身份信息外,它还在由EGETKEY实现的密钥派生过程中使用。CPUSVN是一个128位的值,根据开发文档的说法,它反映了处理器的微码更新版本。
开发文档没有描述CPUSVN的结构,但它指出,使用整数比较来比较CPUSVN值是没有意义的,而且只有一些CPUSVN值是有效的。此外,cpusvn承认它的排序关系与飞地svn之间的排序关系具有相同的语义。具体来说,SGX实现将考虑所有具有svn较低的SGX实现由于安全漏洞而受到损害,并且不信任它们。
一项SGX专利[138]公开了,CPUSVN是一个表示组成SGX实现的各种组件的svn的小整数的连接。这个结构与开发文档中所做的所有语句都相一致。
5.7.4 Establishing an Enclave’s Identity
当EINIT指令为代码执行准备了一个飞地时,它还设置了构成该飞地的基于证书身份的SECS字段,如图77所示。
EINIT要求颁发给飞地的SIGSTRUCT证书的虚拟地址,并使用证书中的信息来初始化飞地的SECS中的基于证书的身份信息。在使用证书中的信息之前,EINIT首先验证其RSA签名。SUGSTRUCT字段Q1和Q2,以及RSA的指数3,促进了一个简化的验证算法,这将在6.5中进行讨论。
如果发现SIGSTRUCT证书签名正确,EINIT将遵循以下几段中讨论的步骤,以确保证书被颁发给正在初始化的飞地。一旦检查完成,EINIT计算MRSIGNER,即SIGSTRUCT中模量域的256位SHA-2散列,并将其写入飞地的SECS。EINIT还将ISVPRODID和ISVSVN字段从SIGSTRUCT复制到飞地的SECS中。如5.7.2中所述,这些字段构成了该飞地的基于证书的身份。
在SIGSTRUCT中验证RSA签名后,EINIT将签名的填充复制到飞地的SECS中的PADDING字段中。图45中概述的PKCS #1 v1.5填充方案不涉及随机性,因此填充对于所有飞地应该具有相同的值。
EINIT执行一些检查,以确保正在初始化的飞地确实得到了所提供的SIGSTRUCT的授权。最明显的检查是确保SIGSTRUCT中的ENCLAVEHASH值等于飞地的度量,它存储在飞地的SECS中的MRENCLAVE字段中。
然而,MRENCLAVE并不包括飞地的属性,它们存储在SECS的ATTRIBUTES字段中。如5.6.2中讨论的,从MRENCLAVE中省略ATTRIBUTES有助于编写具有优化实现时可以使用架构扩展,并且具有在没有扩展的cpu上工作的回退实现。当使用XFRM(5.2.2,5.2.5)属性中的各种值进行构建时,这样的飞地可以正确地执行。同时,允许系统软件在ATTRIBUTES字段中使用任意值将会危及SGX的安全保证。
当一个飞地使用软件认证(3.3)来获取对秘密的访问时,用于构建它的属性值将包含在SGX认证签名(5.8)中。这使认证过程中的远程当事方有机会拒绝使用不希望的属性值构建的飞地。但是,当使用基于证书的身份所促进的迁移过程获得秘密时,没有一个远程当事方可以检查飞地的属性。
5.8 SGX Software Attestation
SGX实施的软件认证方案遵循3.3节中概述的原则。启用SGX的处理器计算在每个enclave中加载的代码和数据的度量,这与TPM计算的度量类似。enclave内的软件可以启动一个生成SGX证明签名的过程,该签名包括enclave的度量和飞地消息。
SGX的认证签名中使用的密码原语太复杂, 无法在硬件中实现,因此签名过程由Intel发布的特权Quoting Enclave执行,它可以访问SGX认证密钥。该enclave将在5.8.2中进行讨论。
将签名功能推到Quoting Enclave,需要在接受软件认证的enclave和Quoting enclave之间建立一个安全的通信通道。SGX设计通过一个本地认证机制解决了这个问题,一个enclave可以使用该机制向由同一启用SGX的CPU托管的任何其他enclave证明其身份。该方案是由EREPORT指令实现,在5.8.1中描述。
在启用了SGX的处理器离开工厂时,Quoting enclave所使用的SGX认证密钥并不存在。认证密钥稍后将提供,使用一个进程,该进程包含一个由Intel发布的Provisioning enclave和两种特殊EGETKEY密钥类型。这个过程的公开细节总结见5.8.2。
SGX启动enclave和EINITTOKEN结构将在5.9中讨论。
总结:对加载到enclave里的数据和代码进行度量,并对计算的enclave度量和enclave消息进行签名,想要认证一个enclave是否是真是CPU创建的,或者检测加载到enclave里的代码和数据是否被篡改,验证方可以对签名进行验证。
5.8.1 Local Attestation
一个enclave向另一个目标enclave证明它的身份,通过下图中的EREPORT指令。SGX指令生成一个认证报告(REPORT),该报告加密地将enclave提供的信息和与enclave基于度量和基于证书的身份绑定。加密绑定是通过一个MAC标签完成的,该标签使用的对称秘钥只在目标enclave和SGX实现之间共享。
SGX指令EREPORT生成一个证明报告,该指令利用对称加密AES-CMAC算法,将enclave的消息与其基于度量的身份和基于证书的身份进行加密形成MAC标签。对称秘钥在目标enclave与SGX之间共享。
EREPORT指令从enclave的SECS中读取当前enclave的身份信息,并且使用它来填充REPORT结构。特别是,EREPORT复制SECS字段,这些字段指示enclave的度量(MRENCLAVE),基于证书的身份(MRSIGNER,ISVPRODID,ISVSVN),和属性(ATTRIBUTES)。这个认证报告也包含SGX实现的SVN(CPUSVN)和由enclave提供的一个64字节的消息。
接收到认证报告的目标enclave可以说服自己相信该报告的真实性,如下图所示,真个报告的真实性证明是其MAC标签。验证MAC所需的密钥只能通过目标enclave获得,通过询问EGETKEY来派生出一个Report key。开发手册MAC标签是使用基于分组加密的MAC(CMAC),但是没有指定底层加密,SGX的一篇论文指出,CMAC是基于128位的AES的。
由EGETKEY返回的Report key是来自CPU中嵌入的一个秘钥,并且这个key的原材料包括目标enclave的度量。目标enclave可以确定报告中的MAC标签是由SGX实现产生,原因如下。底层秘钥派生的密码属性和MAC算法确保只有SGX实现可以产生MAC标签,因为只有这一个SGX实体可以访问处理器的密钥,一个攻击者不可能在没有处理器秘钥的情况下来派生Report key。SGX的设计保证了由EGETKEY生成的密钥依赖于enclave的度量值,所以只有目标enclave才能获得用于在报告中生成的MAC标签的key。
假设enclave A和enclave B之间要进行身份认证,首先enclaveB作为目标enclave,A向B证明身份的真实性,流程可简单概括如下:1)A调用EREPORT指令生成一个包含A信息MAC标签的Report。具体的,使用对称加密算法将A的度量、证书身份、SVN等加密形成一个MAC标签,并将MAC标签和以上信息一同形成一个Report发送给B。注意:这个加密密钥生成原料包括目标enclave B的度量等信息。这里是确保只有目标enclave可以获得Report key,来验证报告中MAC标签的真实性。2)B收到Report后,调用EGETKEY指令,来获得验证MAC标签的Report key。其中Report key的原料也是包含B的度量值等信息,确保只有B能获得Report key。通过对称秘钥Report key来解密MAC标签,验证解密后的信息和Report内的信息是否一致。
对称秘钥生成是由CPU内嵌的密钥派生的,只有SGX的特定实体可以访问该CPU密钥,所以,攻击者不能在没有CPU密钥的情况下产生Report key。所以B可以确定该Report是由SGX实体产生的,因此可以确保A的真实身份,是运行在同一个CPU上。在这节刚开始介绍对称秘钥仅有目标enclave B和SGX知晓,那么A不知晓对称秘钥,怎么加密MAC的呢?我理解的是对称秘钥由A和B知晓,相当于通过SGX EGETKEY来协商秘钥。如有理解有误,回头再看看5.7节再修改该部分。
当调用KEYNAME设置为与Report key关联的值时,EREPORT和EGETKEY使用相同的密钥派生进程。因此,EREPORT需要一个Report Target Info(TARGETINFO)结构的虚拟地址,该结构包含目标enclave的基于度量的身份和属性。
当得到一个Report key时,EGETKEY的行为与seal key的行为略有不同,如下图所示,秘钥生成材料从不包含与enclave的基于证书身份(MRSIGNER、ISVPRODID、ISVSVN)对应的字段,并且忽略在KEYREQUEST结构中的KEYPOLICY字段。因此,该报告只能由目标enclave进行验证核实。
此外,用于密钥生成的SGX实现的SVN(CPUSVN)值由当前CPUSVN决定,而不是从Key Request结构中读取,因此,SGX实现升级,增加了CPUSVN使所有未完成的报告无效。鉴于CPUSVN的增加与安全修复相关联,5.7.2中的参数表明,此限制可能会降低SGX实现中漏洞的影响。
最后,EREPORT将密钥生成材料中的KEYID字段设置为SGX配置寄存器(CR_REPORT_KEYID)的内容,该寄存器在SGX初始化时以随机值初始化。KEYID值也保存在认证报告中,但是MAC标签不包括它。