Intel SGX: 基本概念

SGX是Intel实现的可信执行环境,主要面向服务器和桌面端,提供了内存加密(Memory Encryption)、访问控制(Access Control)、远程认证(Remote Attestation)、本地密封(Sealing)等功能。

0x00 Overview

关于应用程序代码与可信执行环境的基本关系:

  1. 每个application分为两部分:安全(可信)部分和不安全(不可信)的部分
  2. application启动后,会在受保护的可信内存中加载一块飞地(enclave)
  3. application通过把机密数据、代码放到enclave里来保证安全性
  4. enclave为application提供调用接口,当application调用enclave内的函数时,其内部的任何内存仅enclave自身可见
  5. enclave内存即使ring 0的攻击者也看不到,因为是CPU层面的保护。实际上在SGX的安全模型里OS、BIOS等等都可以被认为是不可信的

关于可信执行环境与用户进程的关系:

  1. application 本身包括了自身的代码、数据和enclave
  2. enclave里面也有其自身的代码、数据
  3. SGX保证enclave里面的代码和数据的integrity和confidentiality
  4. enclave的entry points在编译期就确定了
  5. enclave可以访问它所在的application里的内存,但是反过来不行
  6. 支持多线程



相关的指令,User模式下和Supervisor 模式下各自有相关的指令支持SGX的使用

Super. Description User Description
EADD Add a page EENTER Enter an enclave
EBLOCK Block an EPC page EEXIT Exit an enclave
ECREATE Create an enclave EGETKEY Create a cryptographic key
EDBGRD Read data by debugger EREPORT Create a cryptographic report
EBDGWR Write data by debugger ERESUME Re-enter an enclave
EINIT Initialize en enclave
ELDB Load an EPC page as blocked
ELDU Load an EPC page as unblocked
EPA Add a version array
EREMOVE Remove a page from EPC
ETRACE Activate EBLOCK checks
EWB Write back/invalidate an EPC page

0x01 Memory

访问控制

首先介绍一下Enclave Page Cache (EPC)。EPC是用来存储enclave的代码和数据的内存区域,这部分内存是被CPU内部集成的专用协芯片Memory Encryption Engine (MEE)加密的,其密钥在CPU上电时生成,且仅储存在CPU内部。EPC里面的内存页只有在CPU物理核内部的时候才被解密,所有的外部访问都只能在总线上读取到加密后的数据。

用来存储EPC中内存页状态的结构体叫做Enclave Page Cache Map (EPCM),是一个安全内存管控的内置微架构结构体(internal micro-architecture structure),里面存储了EPC中每个内存页的配置、权限等信息。
。EPCM的大小限制了EPC的大小最多不超过128MB(新版SGX好像是256MB,由BIOS设定)。

具体的访问控制流程可以用下图表示

内存管理

由上述EPCM的解释可知EPC的大小比较有限,所以在很多个程序都要使用自己的enclave时,EPC的内存就不够用了。此时就需要有一个类似于Linux中的Swap Device这样的备用解决方案。在SGX中实现了与Linux的内存管理很相似的一套memory management策略,如下图所示。

当EPC中的内存被用完了的时候,SGX会将其中的一些不活跃的Enclave Page换出到系统存储里面,而在有程序访问到时再换入进来,类似Linux里的Page in/out。这里存储的除了加密的Enclave Page之外,还有一些用来保证完整性和存储信息的结构体SECINFO、PCMD等等。

内存分布

每个enclave的内存分布如下图所示。对于每个enclave,都有一个SGX Enclave Control Structure (SECS) 结构体与之绑定,其中存储了这个enclave的meta-data(例如hash和大小)。另外对于每个线程都有一个Thread Control Structure (TCS) 结构体,存储了线程相关的信息。这两个结构体都是仅能被CPU访问到的,其他的代码(无论普通代码还是enclave自己的代码)都不可以访问,同时一旦Enclave初始化完成之后这些结构体也是不可变的(immutable)。

0x02 Processor

创建Enclave

SGX的初始化,简单地说就是首先申请安全内存页,然后把Enclave代码复制进去,最后度量一下建立过程是否可靠:

image.png

  1. Application请求将自己的enclave加载到内存里
    • 首先向OS请求一块EPC的内存
    • OS返回EPC列表中的一块内存,表示把该部分的Enclave Page分配给Application
  2. Application执行ECREATE指令,参数为SECS的初始值。CPU执行该指令初始化该Enclave对应的SECS结构体
  3. Application使用EADD指令,参数为Enclave代码的源地址和目标地址,CPU执行指令将Enclave的代码复制到第1步中申请到的EPC内的一块内存空间
  4. Application调用EEXTEND指令,将Enclave的代码所在的每个Page都加入到度量中。这个度量(measure)是一个类似于HMAC的操作(个人感觉其实主要就是用对这堆Pages进行Hash来保证完整性?)
  5. Application调用EINIT指令,将上一步中的Hash值写到SECS结构体里,完成Enclave的初始化

对于步骤1,我们前面讲过应该认为OS也是不可信的,所以通过OS启动Enclave会需要一些额外的措施:Architectural Enclave这个特殊的Enclave(由Intel签名并启动起来的Enclave)会对Enclave的完整性进行签名保证,Enclave被OS启动过程中,相应的启动过程的度量会放在EPC的SECS中,最后会对AE签名的那个度量值比对,为了防止OS对Enclave启动过程中做小动作。 –引自 小谈Intel SGX

Enclave的调用流程

Application调用Enclave中提供的安全函数的流程如下图所示:

  1. Application执行EENTRY指令,调用需要的函数
  2. CPU首先将App的上下文存起来,放到EPC里
  3. 然后进入Enclave中执行代码
  4. 函数执行完毕之后,需要使用EEXIT指令退出Enclave
  5. CPU回到Application中继续执行

中断处理

如下图所示,当Enclave中发生中断的时候:

  1. 会产生Asynchronous Enclave Exits (AEX),传递给CPU
  2. CPU从TCS结构体中取出application的上下文,再将enclave的上下文保存在其中
  3. 然后将转到OS中的Interrupt Service Routine (ISR) 处理该异常
  4. 处理完之后然后交给Asynchronous Exit Pointer (AEP) 指向的一个application中的handler
  5. 这个handler负责用RESUME指令回到原来的Enclave发生中断的位置
  6. CPU从TCS结构体中取出enclave的上下文,再将application的上下文保存在其中
  7. 继续在enclave中发生中断之后的位置执行

0x03 Sealing and Attestation

认证这部分有两把密钥,一把在Intel需要通过网络连接认证,另一把在厂商手里。过程略有一点复杂,回头研究清楚再补充。

References

所有的图片均来自References
小谈Intel SGX
Overview of Intel SGX – Part 1, SGX Internals

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

此站点使用 Akismet 来减少垃圾评论。了解我们如何处理您的评论数据