02-TEE SGX 内部组件

SGX从入门到放弃: https://github.com/dingelish/SGXfail

SGX 介绍

SGX 是 Intel 开发的新的处理器技术,可以在计算平台上提供一个可信的空间,保障用户关键代码和数据的机密性和完整性。SGX 全称 Intel Software Guard Extensions,顾名思义,其是对因特尔体系(IA)的一个扩展,用于增强软件的安全性。

SGX 是在 2015 年推出的第六代英特尔酷睿处理器,基于 Skylake 微架构。可以通过执行带有结构化扩展功能叶(Structured Extended Feature Leaf)标志的 CPUID 指令来检查 SGX 支持,并检查 EBX 寄存器的第二位是否已设置。为了能够使用 SGX,它必须由 BIOS 启动,并且目前,只有少数 BIOS 支持该技术,这是它没有被广泛使用的原因之一。

SGX 的保护方式并不是识别和隔离平台上的所有恶意软件,而是将合法软件的安全操作封装在一个 enclave 中,保护其不受恶意软件的攻击。而且执行 SGX 的权限非常高,特权或者非特权的软件都无法访问 enclave,也就是说,一旦软件和数据位于 enclave 中,即便操作系统管理员和 VMM(Hypervisor)也无法影响 enclave 里面的代码和数据。

Enclave 的安全边界只包含 CPU 和它自身。SGX 创建的 enclave 也可以理解为一个可信执行环境 TEE(Trusted Execution Environment)。不过其与 ARM TrustZone(TZ)还是有一点小区别的,TZ 中通过 CPU 划分为两个隔离环境(安全的环境和正常的环境),两者之间通过 SMC 指令通信;而 SGX 中一个 CPU 可以运行多个安全 enclaves,并发执行亦可。当然,在 TZ 的安全的环境内部实现多个相互隔离的安全服务亦可达到同样的效果。另外,SGX 是针对桌面和服务器平台的。

总结来说,Intel SGX 的安全性能有以下 3 点:

  1. 把应用程序分为两部分:安全应用程序和非安全应用程序;

  2. 将合法软件的安全操作封装在一个 enclave 中;

  3. 当调用 enclave 函数时,只有 enclave 内部的代码才能查看其数据,并始终拒绝外部访问;当调用结束时,enclave 的数据会留在受保护的内存中。

安全执行环境是主机进程的一部分,这意味着:

  1. 应用程序包含自己的代码,数据和 enclave;
  2. enclave 也包含自己的代码和自己的数据;
  3. SGX 保护 enclave 代码和数据的机密性和完整性;
  4. Enclave 接入点是在编译期间预先定义的;
  5. 支持多线程(但不能轻易实现);
  6. enclave 可以访问其应用程序的内存,但应用程序的内存则无法访问 enclave。

指令介绍

Intel SGX 定义了 18 条新指令,其中 13 条由管理者使用,5 条由用户使用。所有这些指令都以微代码实现,以便可以修改指令的具体行为。以下是 18 条新指令的完整说明:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
EADD:添加页面;
EENTER:进入 enclave;
EBLOCK:阻止 EPC 页面;
EEXIT:退出 enclave;
ECREATE:创建安全区;
EGETKEY:创建加密密钥;
EDBGRD:通过调试器读取数据;
EREPORT:创建加密报告;
EBDGWR:通过调试器写入数据;
ERESUME:重新进入安全区;
EINIT:初始化 enclave;
ELDB:加载 EPC 页面为已阻止;
ELDU:加载 EPC 页面为未阻止;
EPA:添加版本数组(version array);
EREMOVE:从 EPC 中删除页面;
ETRACE:激活 EBLOCK 检查;
EWB:回写或是让 EPC 页面无效;

数据结构

另外,Intel SGX 还定义了 13 种新的数据结构,其中 8 种用于 enclave 管理,3 种用于内存页面管理,2 种用于资源管理。以下是 13 种新的数据结构的完整说明:

1
2
3
4
5
6
7
8
9
10
11
12
13
SGX Enclave控制结构(SECS);
线程控制结构(TCS);
存储状态区(SSA);
页面信息(PAGEINFO);
安全信息(SECINFO);
分页加密元数据(PCMD);
版本数组(VA);
Enclave页面缓存映射(EPCM);
Enclave签名结构(SIGSTRUCT);
EINIT令牌结构(EINITTOKEN);
报告(REPORT);
报告目标信息(TARGETINFO);
密钥请求(KEYREQUEST);

我会在以下详细介绍相关的这写指令和数据结构,然后对它们如何实现哪种安全功能进行详细解释。

内存保护过程

enclave 页面缓存(Enclave Page Cache, EPC)

Enclave 代码和数据放置在被称为 Enclave Page Cache(EPC)的特殊内存区域中,该内存区域使用内存加密引擎(MEE)进行加密,(该内存区域只存在于一种专用的芯片上?这句话有疑问)。内存总线上的外部读取只能观察到加密数据。而页面只会在处理器内核中才能被解密,这个密钥只会在 enclave 页面缓存启动时生成并存储在 CPU 中。

此时传统页面检查已被扩展,以防止外部访问 EPC 页面。

Enclave页面缓存映射(EPCM)

Enclave 页面缓存映射(EPCM)结构用于存储页面状态,它位于受保护的内存中,其大小限制了 EPC 的大小(由BIOS设置,最大128MB)。EPCM 包含了每个页面的配置、权限和类型。

内存管理

数据结构

  • 页面信息(PAGEINFO):EPC 管理指令会用以 PAGEINFO 结构的参数来引用页面。这些参数包含页面的线性和虚拟地址,以及指向 SECINFO 和 SECS 结构的指针。

  • 安全信息(SECINFO):SECINFO 结构用于存储页面元数据,包括访问权限(读/写/执行)和类型(SECS,TCS,REG或VA)。

  • 分页加密元数据(PCMD):PCMD 结构用于跟踪那些从 EPC 中被清除的页面的相关联的元数据,它包含页面所属的 enclave 标识,指向 SECINFO 结构和 MAC 的指针。

  • 版本数组(VA):VA 结构用于存储从EPC中被清除的页面的版本号,它是一种特殊的页面类型,包含 512 个 8 字节的插槽来存储版本号。

相关指令

1
2
3
4
EPA:该指令分配一个4KB的内存页面,其中包含页面版本号数组(VA)以防止重播。每个元素长64位。
EBLOCK:该指令会阻止被那些正准备从EPC中清除的页面的所有访问,将来对这些页面的所有访问都将导致页面错误。
ETRACK:该指令负责从EPC中删除页面,不过前提是页面必须被阻止访问,并且不能被TLB引用。在将其写入外部内存之前,要先对页面进行加密,生成版本号和元数据,并执行最终的MAC。
ELDB/ELDU:该指令会将先前被清除的页面加载到内存中,以检测是它们否处于禁止访问状态。它会检查元数据的MAC、版本号(来自相应的VA条目)和页面加密内容。如果先前被清除的页面处于禁止访问状态,则页面内容被解密并放置在所选的EPC页面内,并且相应的VA条目被删除。

安全功能如何实现的过程

EPC 内存由 BIOS 定义,大小有限。不过 SGX 提供了一种从 EPC 中删除页面,将其放置在不受保护的内存中并在以后进行恢复的方法。由于 EPC 页面管理指令允许加密页面并生成其他元数据,因此页面保持相同的安全属性。在引用此页面的所有缓存条目都已从所有处理器逻辑内核中删除之前,不能删除该页面,且以页面的粒度大小(4KB)导出或导入内容。

内存中存储的内容

SGX Enclave 控制结构(SECS):每个 enclave 都与 SECS 结构相关联,该结构将包含其元数据(例如其哈希值和大小)。任何安全或非安全代码都无法访问它,只能由处理器本身可以访问。

线程控制结构(TCS):每个 enclave 至少与一个 TCS 结构相关联,该结构是进入 enclave 的执行点。由于 SGX 支持多线程,因此 enclave 可以使用与 TCS 一样多的活动线程。与 SECS 结构一样,它只能由处理器访问。

存储状态区(SSA):每个 TCS 至少与一个 SSA 结构相关联,该结构可以在异常和中断处理期间保存处理器的状态。它在退出时写入,在恢复时读取。

栈和堆:每个 enclave 都可以使用它的栈和堆,当进入和退出时,RBP 和 RSP 寄存器会被保存,但它们的值不会被改变。堆不在内存内部进行处理,enclave 有自己的分配器。

处理器保护过程

Enclave 的创建和检查过程

Enclave 检查(Enclave Measure):每个 enclave 都由其属性以及页面的位置、内容和保护的哈希值表示。具有相同哈希的两个 enclave 是相同的,该方法被称为 MRENCLAVE,用于检查 enclave 的完整性。

签名检查(Signer Measure):每个 enclave 也由其管理者进行签名,MRSIGNER 包含管理者公钥的哈希值,MRENCLAVE 和 MRSIGNER 使用 SHA-256 哈希函数生成。

数据结构

EINIT 令牌结构(EINITTOKEN):EINIT 指令使用EINITTOKEN结构来检查是否允许执行enclave。它包含enclave的属性,哈希和签名者身份,它使用启动密钥执行的HMAC进行身份验证。

enclave 签名结构(SIGSTRUCT):每个enclave都与一个SIGSTRUCT结构相关联,该结构由管理者签名并包含enclave方法,签名者公钥,版本号(ISV,反映安全级别)和产品标识符(ISVPRODID,以区分同一管理者的enclave) 。它负责确保enclave未被修改,然后使用其他密钥重新签名。

指令说明

1
2
3
4
5
ECREATE:该指令负责实例化一个新的 enclave,定义其地址空间和信任 root ,这些信息存储在新分配的 SECS 中。
EADD:该指令允许向 enclave 添加新页面,此时操作系统只负责选择页面及其内容。EPCM 的初始条目表示页面类型及其保护。
EEXTEND:该指令允许通过 256 字节的代码块将页面内容添加到 enclave 检查中,必须调用 16 次才能将完整页面添加到enclave检查中。
EINIT:该指令在初始化之前会检查 enclave 是否与其 EINITTOKEN(相同的检查属性)相对应,它还会检查令牌是否已使用启动密钥签名。
EREMOVE:该指令负责彻底从 enclave 中删除页面。

保护过程

  1. 应用程序会请求将其 enclave 加载到内存中;
  2. ECREATE 指令负责创建并填充 SECS 结构;
  3. 使用 EADD 指令将每个页面加载到受保护的内存中;
  4. 使用 EEXTEND 指令将每个页面添加到 enclave 检查中;
  5. EINIT 指令最终完成对 enclave 的创建;

Enclave 的进入或退出

指令介绍

1
2
EENTER:该指令将控制从应用程序转移到 Enclave 内的预定确定的位置,它会检查 TCS 是否空闲并清除 TLB 条目,然后它将处理器置于 Enclave 模式并保存 RSP/RBP 和 XCR0 寄存器。最后,它禁用基于事件的精确抽样(PEBS),使 enclave 执行看起来像一个复杂的指令。
EEXIT:该指令将进程恢复为原始模式,并清除位于 Enclave 内的地址的 TLB 条目。控件被转移到应用程序中的指定地址,该地址会在 RBX 寄存器中指定,并释放 TCS 结构。enclave 需要在退出之前清除其寄存器,以防止数据泄漏。

Enclave 的进入过程

  1. 执行 EENTRY 指令;
  2. 保存应用程序上下文;
  3. 处理器处于 enclave 模式;

Enclave的退出过程

  1. 执行 EEXIT 指令;
  2. 处理器处于正常模式;

中断处理

指令介绍

1
ERESUME:该指令从当前SSA恢复上下文并恢复执行。

指令执行说明

异步 Enclave 退出(Asynchronous Enclave Exits,AEX)会导致中断和异常,异步退出指针(Asynchronous Exit Pointer,AEP)指向位于应用程序内部的处理程序,该处理程序将在中断服务程序(Interrupt Service Routine,ISR)处理异常后恢复执行。处理程序可以通过执行 ERESUME 指令决定是否继续执行 enclave。

当 AEX 发生时,Enclave 的上下文被保存在当前SSA中并恢复应用程序上下文。执行 ERESUME 指令时,将恢复 Enclave 上下文。TCS包含一个表示当前 SSA 的计数器,组成一个上下文栈。

中断处理过程

  1. 中断或异常信息被传送到处理器;
  2. 保存enclave上下文,恢复应用程序上下文;
  3. 在操作系统的处理程序中继续执行;
  4. 处理程序返回(IRET)到AEP一个trampoline函数;
  5. 如果AEP决定恢复enclave执行,则执行ERESUM;
  6. 先前保存的enclave上下文已恢复;
  7. 在enclave内中断的地方恢复执行过程;

最大的安全特性——密封性

指令说明

1
EGETKEY:Enclave 使用此指令访问平台提供的不同密钥,每个密钥可以实现不同的操作(密封、安全认证)。

指令执行说明

当实例化 enclave 时,其代码和数据将受到保护以免被外部访问,但当 enclave 停止实例化时,它的所有数据都会丢失。所谓密封操作就是一种将数据安全地保存在 enclave 外部的方法,例如硬盘驱动器上的方法。enclave 必须使用 EGETKEY 指令检索其密封密钥。它使用此密钥加密并确保其数据完整性,而使用的算法则由 enclave 管理者选择。

使用 Enclave 标识

可以使用 enclave 标识进行密封,然后,密钥推导基于 MRENCLAVE 的值。两个不同的 enclave 都有着自己的密钥,但也有相同 enclave 的两个版本,这会阻止数据的本地迁移。

使用签名者标识

也可以使用签名者标识进行密封,然后,密钥推导基于 MRSIGNER 的值。两个不同的 enclave 仍然有着不同的钥匙,但两个版本的 enclave 共享相同的钥匙,可以读取密封的数据。如果使用相同的密钥对多个 enclave 域进行签名,则它们都可以读取彼此的数据。

安全版本号(SVN)

原则上,旧版本的 enclave 是不允许读取由较新版本的 enclave 密封的数据,为防止出现意外,就需要使用安全版本号(SVN)。在每次 enclave 的安全性被更新后,安全版本号的计数器都会递增。使用 SVN 产生密钥时,Enclave 可以检索与当前版本或更旧版本的安全级别相对应的密钥,但不能找到较新版本对应的密钥。

特性-安全认证

安全认证结构

密钥请求(KEYREQUEST)

KEYREQUEST结构用作EGETKEY指令的进入,它允许选择要获取的密钥,以及生成所需的其他参数。

报告目标信息(TARGETINFO)

TARGETINFO 结构用作 EREPORT 指令的进入,它将用于识别能够验证CPU生成的报告结构的enclave(哈希和属性)。

报告(Report)

REPORT 结构是 EREPORT 指令退出的,它包含 enclave 的属性、检测标识、签名者标识以及在源和预定的 enclave 之间共享的一些用户数据,处理器使用报告密钥在此结构上执行 MAC。

指令介绍

1
EREPORT:Enclave 使用此指令生成一个 REPORT 结构,其中包含有关它的许多信息,并使用预定的 Enclave 的报告密钥进行标识验证。

指令执行说明

enclave 代码和数据在初始化之前是明文形式的,虽然其中一部分可以从技术上进行加密,但是解密密钥不能预先安装(或者它不会提供任何额外的安全性)。加密必须来自外部,可能是密钥和敏感数据。enclave 必须能够向第三方认证它可以被信任(没有被篡改过),并且是在一个合法的平台上执行的。以下是两类认证方式:

  1. 本地认证:同一平台的两个 enclave 之间的认证过程;
  2. 远程认证:enclave 和不在平台上的第三方之间的认证过程;

本地认证

必须在 enclaveA 和 enclaveB 之间建立一个通道,enclaveA 使用该通道来检索 enclaveB 的 MRENCLAVE。EnclaveA 使用 EnclaveB 的 MRENCLAVE 调用 EREPORT 来为 EnclaveB 生成签名报告。

EnclaveB 调用 EGETKEY 来检索其报告密钥并验证 EREPORT 结构的 MAC,如果有效,则 enclave 是预期的并且在合法平台上运行。

远程认证

远程认证需要一个被称为 Quoting Enclave(QE)的 enclave,此 Enclave 通过使用另一个特殊密钥 Provisioning Key 对 REPORT 进行签名验证(本地验证),并将其转换为 QUOTE(远程验证)。具体步骤如下:

  1. 最初,enclave 会通知应用程序,它需要在位于平台外部的某个位置加密。此时,应用程序与服务器建立安全通信,服务器对此请求进行回应,以认证正在执行的 enclave 没有被篡改,并且它执行的平台是合法的;
  2. 该应用程序为其 enclave 提供了 Quoting Enclave 标识和认证请求;
  3. enclave 产生一个包括认证回应和临时公钥的清单,该公钥将在稍后被用于保护服务器和 enclave 之间的通信。而生成的哈希,则包含在E REPORT 指令的用户数据部分中。该指令为 Quoting Enclave 生成一个报告,将清单与 enclave 关联起来,此时,enclave 将REPORT 发送给应用程序;
  4. 该应用程序将REPORT发送到Quoting Enclave进行验证和签名;
  5. QE使用EGETKEY指令检索其报告密钥并验证REPORT,它会创建QUOTE结构,并在将其提供给应用程序之前使用其Provisioning Key对其进行签名;
  6. 应用程序将QUOTE和关联的清单发送到服务器进行验证;
  7. 服务器使用Intel提供的认证服务来验证QUOTE签名,然后,它使用QUOTE用户数据中的哈希检查清单完整性。以确保清单包含对认证的预期响应。

Reference


02-TEE SGX 内部组件
https://flepeng.github.io/081-数据安全-TEE-02-TEE-SGX-内部组件/
作者
Lepeng
发布于
2023年4月14日
许可协议