导语:此前,我曾讲过SGX的内部组件,从今天开始,我将继续讲解SGX的外部组件。
此前,我曾讲过SGX的内部组件,从今天开始,我将继续讲解SGX的外部组件。
在这篇文章中,我首先会快速解释一下应用程序如何与其enclave的相互作用过程,然后详细介绍SDK和PSW中包含的软件,最后,总结SGX技术可能遭受的攻击方式。
相互作用方式
从理论上讲,SGX enclave可以看作是一个能够执行任意算法的黑匣子。这个黑匣子可以使用下面介绍的三种不同方式与外界进行通信。
Enclave调用(ECALL)
应用程序可以在enclave内部调用预定义的函数,将进入参数和指针传递给应用程序内的共享内存,应用程序对enclave的调用便称为ECALL。
外部调用(OCALL)
当enclave执行时,它可以对应用程序中的预定义函数执行OCALL,不过与ECALL相反,OCALL无法与应用程序共享enclave内存,因此必须在OCALL之前将参数复制到应用程序内存中。
异步退出事件(AEX)
由于中断或异常,执行也可以退出enclave,这些enclave退出事件被称为异步退出事件(AEX),它们可以从enclave内的任意位置将控制从enclave转移到应用程序。
相互作用过程
可信代码库(TCB)
开发使用SGX enclave的应用程序需要提前标识好那些要保护的资源,以及包含这些资源的数据结构和管理它们的代码。然后,所有已标识的内容必须放在enclave内。enclave文件是一个与传统操作系统加载器兼容的库,它包含enclave的代码和数据,在磁盘上以明文形式显示。
接口函数
应用程序与其enclave之间的接口必须仔细设计,由于enclave会提前声明应用程序可以调用哪些函数,以及它可以调用的应用程序的函数。由于Enclave进入参数可以被非安全代码观察和修改,因此必须对它们进行仔细的检查。另外,enclave无法直接访问操作系统的服务,必须调用其应用程序。所以这些调用既不会保证隐私信息不被泄露,也不会保证按照enclave的预期执行。
软件开发工具包
软件开发工具包(SDK)为开发人员提供了开发支持SGX的应用程序所需的一切,它由一个生成应用程序和enclave之间的接口函数的工具,一个在使用它之前对enclave进行签名的工具,一个调试它的工具以及一个性能检查的工具组成。另外,它还包含模板和样本参数,用于在Windows下使用Visual Studio开发enclave,或在Linux下使用Makefile。
平台软件
平台软件(PSW)是允许支持SGX的应用程序在目标平台上执行的软件栈,它适用于Windows和Linux操作系统,由4个主要部分组成:
1.提供对硬件功能进行访问的驱动程序;
2.为执行和认证提供多个支持库;
3.运行所必需的架构型enclave;
4.加载并与enclave进行通信的服务;
架构型enclave
为了让执行环境变得更为安全,需要几个架构型enclave(Architectural Enclave,AE)。架构型enclave由英特尔提供并签名,负责执行启动策略,执行provisioning和认证过程……
启动Enclave
启动Enclave(Launch Enclave ,LE)是负责向希望在平台上执行任务的其他enclave分配EINITTOKEN结构,该结构会检查enclave的签名和标识,看它们是否有效。为了生成令牌,EINITTOKEN结构会负责启动密钥,因此启动Enclave是唯一能够检索EINITTOKEN结构的enclave。
Provisioning enclave
Provisioning Enclave(PvE)是负责通过与Intel Provisioning Service服务器通信来检索认证密钥的enclave。为了做到这一点,它使用PcE提供的证书认证平台的真实性。
Provisioning Certificate Enclave
Provisioning Certificate Enclave(PcE)是负责签名发送给PvE的处理器证书的enclave。为了做到这一点,PcE使用Provisioning Key,它是唯一能够检索到它的enclave。 PvE和PcE目前还是作为独立的enclave来实现的。
Quoting Enclave
Quoting Enclave(QE)负责检测对enclave标识的信任程度以及它在远程认证过程中执行的环境。它会解密从PvE接收的认证密钥,并使用该密钥将REPORT结构(本地验证)转换为QUOTE结构(远程验证)。
平台服务enclave
Platform Service Enclaves (PSE)是一个架构型enclave,为其他enclave提供多种服务,如单调计数器,可信时间等。这些enclave利用管理引擎(ME),形成一个个孤立的,安全的管理平台。
密钥目录
每个支持SGX的CPU都包含两个存储在e-fuses存储电路中的root密钥——Root Provisioning Key(RPK)和根Seal Key( Root Seal Key,RSK)。英特尔会支持RPK启用远程认证过程,而RSK仅被平台所支持。尽管SGX的攻击模型已经排除了物理攻击的可能性,但这反过来会使得处理器架构难以被使用,或者至少使得提取密钥成为非常复杂的事情。有了足够的硬件支持,就可以以破坏性的方式读取e-fuses存储电路。这就是为什么只有加密版本的密钥存储在e-fuses存储电路上的原因,Physical Unclonable Function(PUF)用于存储在处理器执行期间解密其他密钥的对称密钥。
root密钥
Root Provisioning Key(RPK)
英特尔在安全处理过程中创建的第一个密钥就是Root Provisioning Key(RPK)。此密钥是在位于名为Intel Key Generation Facility(iKGF)的设施内的专用硬件安全模块(HSM)上随机生成的。英特尔负责维护包含HSM生成的所有密钥的数据库,RPK也被发送到多个运行设施,并嵌入到处理器e-fuses内。
Root Seal Key
位于e-fuses内的第二个密钥被称为Root Seal Key(RSK),与第RSK的相同之处在于,RSK会保证每个单独运行之间的统计差异。与RSK相反的是,英特尔宣布从其运行环节中中删除所有这些密钥的痕迹,以便每个平台都拥有一个只有自己知道的唯一密钥。
访问导出密钥
根据安全设计原则,enclave是无法访问root密钥的。然而,它可以访问从root密钥导出的密钥。导出函数允许enclave开发者指定自己的密钥导出策略。这些策略允许使用可信值,如MRENCLAVE,MRSIGNER或enclave的属性。不过,enclave无法获得属于另一个enclave的MRENCLAVE或MRSIGNER的钥匙。此外,当密钥导出策略不使用字段时,它会自动设置为零。因此,即使非专用密钥可用,也无法从中导出专用密钥。
为了添加来自用户的熵,在导出期间使用名为Owner Epoch的值作为参数。该值在启动时通过导出密码进行配置,并在每个power循环期间保存在非易失性内存中。对于enclave而言,这个值必须保持不变,才能检索相同的密钥。相反,当平台的管理者更改时,必须更改此值,因为它会阻止新所有者访问旧所有者的个人信息,直到恢复原始密码。
SGX基础设施支持TCB对其硬件和软件组件的更新,每个组件都有一个SVN,它会在每次安全更新后都递增SVN。一个新的SVN会导致一个新的Seal Key。这意味着,新的TCB可以访问旧的TCB的密钥,以进行数据迁移,但旧的TCB不能访问新TCB的密钥。
各种密钥的导出
Provisioning Key
此密钥是从RPK导出的,并用作Intel Provisioning Service与处理器之间的信任root(与TCB版本相关联)。当非SGX处理器使用一组合法的SGX处理器时,会危及所有处理器的远程认证过程,因此必须采取极端的预防措施,以禁止对Provisioning Key的访问。目前,只有当enclave由英特尔签名(英特尔的MRSIGNER在Launch Enclave代码中被硬编码)时,Launch Enclave才能访问此密钥。
Provisioning Seal Key
该密钥是从RPK和RSK导出的,在组中的处理器注册期间,使用此密钥对每个平台的私钥进行加密,并将其发送到英特尔的认证服务系统。必须注意的是,私钥不可以使用RPK加密,因为这会破坏使用的匿名注册协议。类似地,私钥也不能使用RSK加密,因为它允许非特权enclave访问平台的私钥。但问题是,已知RSK的生成过程存在不确定性,人们可能会认为英特尔知道每个平台的私钥。
启动密钥(Launch Key)
此密钥是由RSK导出的,并由Launch Enclave用于生成EINITTOKEN。未经英特尔签名的每个enclave必须获得此令牌,否则处理器无法实例化该令牌。而且只有特定的MRSIGNER(其对应的私钥只有英特尔知道)才能访问启动密钥。在SGXv2中,可以通过编程方式更改Launch Enclave的MRSIGNER,但尚不知道英特尔打算如何将访问控制应用于Provisioning Key。
Seal Key
此密钥是从RSK导出的,用于加密与当前平台相关的数据。重要的是无论是加密还是标识验证,都不要使用非专用的Seal Key ,因为这会损害enclave的安全性。
报告密钥(Report Key)
此密钥是从RSK导出的,用于本地认证过程。