Intel SGX开发者参考书(四)—— Enclave开发基础(三)

@Intel SGX 读书笔记…

Enclave配置文件

Enclave配置文件是一个XML文件,包含用户定义的Enclave参数,此文件是Enclave项目的一部分。sgx_sign使用这个文件作为输入来创建Enclave的签名和元数据。下面是一个配置文件的例子:

<EnclaveConfiguration>
<ProdID>100</ProdID>
<ISVSVN>1</ISVSVN>
<StackMaxSize>0x50000</StackMaxSize>
<HeapMaxSize>0x100000</HeapMaxSize>
<TCSNum>1</TCSNum>
<TCSPolicy>1</TCSPolicy>
<DisableDebug>0</DisableDebug>
<MiscSelect>0</MiscSelect>
<MiscMask>0xFFFFFFFF</MiscMask>
<EnableKSS>1</EnableKSS>
<ISVEXTPRODID_H>1</ISVEXTPRODID_H>
<ISVEXTPRODID_L>2</ISVEXTPRODID_L>
<ISVFAMILYID_H>3</ISVFAMILYID_H>
<ISVFAMILYID_L>4</ISVFAMILYID_L>
</EnclaveConfiguration>

下表列出了配置文件中定义的元素。它们都是可选的。如果没有配置文件,或者配置文件中没有元素,则使用默认值。
表3 Enclave配置默认值

标签 描述 默认值
ProdID ISV分配的Product ID 0
ISVSVN ISV分配的SVN 0
TCSNum TCS的数量。必须大于0 1
TCSPolicy TCS管理策略。0–TCS被绑定到不可信的线程。 1–没有绑定到不可信的线程。 1
StackMaxSize 每个线程的最大栈大小。必须域4KB对其。 0X40000
HeapMaxSize 进程的最大堆大小。必须与4KB对其 0X1000000
DisableDebug 不能调试Enclave 0–Enclave可以调试
MiscSelect 所需的扩展SSA框架功能 0
MiscMask 要强制执行的MiscSelect掩码位 0XFFFFFFFF
EnableKSS 启用密钥分离和共享特性 0
ISVEXTPRODID_H ISV分配扩展产品ID(高8字节) 0
ISVEXTPRODID_L ISV分配扩展产品ID(低8字节) 0
ISVFAMILYID_H ISV分配的Family ID(高8字节) 0
ISVFAMILYID_L ISV分配的Family ID(低8字节) 0

MiscSelect 和 MiscMask用于将来的功能扩展。当前MiscSelect必须为0.否则,相应的Enclave可能无法成功加载。
将EnableKSS设置为1,以启用enclave的密钥分离和共享(KSS)特性。ISVEXTPRODID_H和ISVEXTPRODID_L用于设置ISV分配的扩展产品ID,它是一个16字节的值。ISVFAMILYID_H和ISVFAMILYID_L用于ISV分配的16字节的Family ID。注意,在设置ISV分配的扩展产品ID和ISV分配的Family ID之前,需要启用KSS。
为了避免浪费宝贵的受保护内存资源,可以使用度量工具sgx_emmt适当地调整StackMaxSize和HeapMaxSize。
用Intel SGX Configuration可以可视化的调整配置文件,前面介绍VS插件的时候有提到。
如果没有足够的堆给enclave,则ECALL返回错误代码SGX_ ERROR_STACK_OVERFLOW。此错误代码向enclave写入器提供了StackMaxSize可能需要进一步调整的信息

Enclave项目配置

根据你的开发阶段,选择下列项目配置之一来构建Enclave:

  • Simulation:模拟模式的工作方式与调试模式相同,除了不适用真正的硬件,而是在软件中模拟Intel SGX指令。单步签名是对模拟Enclave签名的默认方法。
  • Debug:当VS中为Enclave项目选择Debugconfiguration选项时,Enclave将在Debug模式下编译,生成的Enclave文件将包含debug信息和符号。选择此项目配置还允许以Enclave允许以Enclave debug模式启动Enclave。这是用过启用SGX_DEBUG_FLAG来实现的,SGX_DEBUG_FLAG作为参数之一传递给sgx_create_enclave函数。单步方法是此项目默认的签名方法。在此模式下使用签名密钥不需要是白名单。
  • Prerelease:当您为enclave项目选择Prerelease配置选项时,Visual Studio将以发布模式构建enclave,并应用编译器优化。在此配置下,以enclave Debug模式启动enclave。在Microsoft Visual Studio enclave项目的预处理器设置中为这种模式定义了一个预处理器标记EDEBUG。在定义EDEBUG预处理器标志时,它将启用SGX_DEBUG_FLAG,而SGX_DEBUG_FLAG将以enclave Debug模式启动enclave。单步方法也是预发布项目配置的默认签名方法。与Debug配置一样,签名密钥也不需要是白名单。
  • Release:VS Enclave项目的Release配置选项在release模式下编译Enclave。这是通过禁用SGX_DEBUG_FLAG来实现的。SGX_DEBUG_FLAG仅在为定义NDEBUG或定义EDEBUG时启用。 在Debug配置中,NDEBUG是未定义的,因此SGX_DEBUG_FLAG是启用的。在prerelease配置中,都定义了NDEBUG和EDBUG,这将启用SGX_DEBUG_FLAG。在release模式中,定义了配置NDEBUG,因此它禁用SGX_DEBUG_FLAG,从而启动处于Enclave release模式。两步方法是release配置的默认签名方法。Enclave需要使用白名单密钥进行签名。

(有关不同的Enclave签名方法的更多信息,请参见Enclave Signing Tool和Enclave Signer Usage Example)

加载和卸载Enclave

Enclave源代码是作为动态链接库构建的。要使用Enclave应该通过调用API sgx_create_enclave()或sgx_create_enclave_ex()将enclave.dll加载到受保护的内存中。enclave.dll必须由sgx_sign.exe签名。当第一次加载Enclave时,加载程序获取启动令牌并将其保存回in/out参数token中。你可以将启动令牌保存到文件中,以便第二次加载Enclave时,应用程序可以从文件中获取启动令牌。提供有效的启动令牌可以增强加载性能。要卸载一个Enclave,使用参数sgx_enclave_id_t调用sgx_destroy_enclave()接口。
加载和卸载Enclave的示例代码如下所示。

#include 
#include 
#include "sgx_urts.h"
#define ENCLAVE_FILE _T("Enclave.signed.dll")
int main(int argc, char* argv[])
{
	sgx_enclave_id_t eid;
	sgx_status_t ret = SGX_SUCCESS;
	sgx_launch_token_t token = {0};
	int updated = 0;
	// Create the Enclave with above launch token.
	ret = sgx_create_enclave(ENCLAVE_FILE, SGX_DEBUG_FLAG, &token, &updated, &eid, NULL);
	if (ret != SGX_SUCCESS) {
		printf("App: error %#x, failed to create enclave.\n", ret);
		return -1;
}
	// A bunch of Enclave calls (ECALL) will happen here.
	// Destroy the enclave when all Enclave calls finished.
	if(SGX_SUCCESS != sgx_destroy_enclave(eid))
		return -1;
	return 0;
}

处理power事件

存储在启用了Intel SGX的CPU中的受保护内存加密密钥的每次power事件(包括挂起和休眠)时都会被销毁。
因此,当发生power transition时,Enclave内存将被删除,并且在此之后将无法访问所有Enclave数据。因此,当系统恢复时,任何后续的ECALL都将无法返回错误代码SGX_ERROR_ENCLAVE_LOST。这个特定的错误代码表明,Enclave由于power transition而丢失。
Intel SGX应用程序应该能够处理在将Enclave加载到受保护内存中时可能发生的任何电源转换。为了以最小的影像处理power事件并恢复Enclave执行,应用程序必须准备在ECALL失败时接收错误代码SGX_ERROR_ENCLAVE_LOST。发生这种情况时,应用程序中的一个且仅有一个线程必须销毁Enclave,即sgx_destroy_enclave(),然后重新加载它,即sgx_create_enclave()。此外,为了从enclave被销毁时的位置恢复执行,应用程序应该定期地在平台上封存和保存Enclave状态信息, 并在重新加载Enclave后使用这些信息将Enclave恢复到原始状态。
SDK中包含地Power Transition示例代码演示了这个过程。

注意:在Windows 10上,Intel SGX应用程序必须调用sgx_destroy_enclave(),以便操作系统从由于power事件而被删除的Enclave中回收受保护的内存或EPC页面。不销毁一个Enclave将导致EPC内存泄漏,sgx_create_enclave()将返回错误代码SGX_ERROR_OUT_OF_EPC。

使用Switchless调用

每当CPU执行跳进(EENTER)或跳出(EEXIT)一个Enclave时,都会发生Enclave切换;例如,当使用ECALLs/OCALLs时。Enclave切换有一个性能开销。对于具有短时间和频繁调用地工作负载,可以使用无切换调用减少Enclave切换开销。无切换调用引入了一种新的操作模式来执行从/到Intel SGX Enclave的调用,使用Enclave内部和外部的工作线程。

性能提示:无切换调用是一个高级特性。它需要额外的工作线程和配置、性能测试和调优。它应该用于需要进行良好性能调优的工作负载。错误的配置可能会导致未充分利用的工作线程,这将消耗CPU时间,同时不为任何任务提供服务。

使用
要使用无切换调用,应该将EDL属性transition_using_threads附加到需要无切换调用的ECALLs和OCALLs中。一个EDL文件可以包含带有或不带有此属性的ECALLs/OCALLs。
应用程序代码必须使用sgx_create_enclave_ex创建一个Enclave,在扩展的选项向量中设置无切换标志,并提供无切换配置结构。
在创建Enclave时,uRTS根据通过初始化提供的无切换配置创建几个可信的和不可信的工作线程,并为无切换调用分配所需的数据结构。可信的工作线程使用常规的Enclave TCSed。当使用无切换的可信工作线程构建Enclave时,应该相应地更新Enclave XML配置中定义的TCSNum。

注意:不应该使用带有TCS绑定策略的无切换调用,即TCSPolicy 0.使用此策略将禁用E/OCALLs的并发执行。
当开发人员使用TCS绑定策略构建Enclave时,他们希望在调用用一个可信函数时保留可信线程的TLS数据。但是,如果Enclave使用无切换调用有两个主要原因,则无法提供这种行为:

  • 工作线程处理不同的无切换ECALLs,尽管由TCS绑定策略。因此,分配给任何工作线程的TLS区域将被工作线程服务的所有ECALL函数重用
  • 当无切换调用请求超时时,它将作为常规ECAALL使用为常规ECALL保留的TCS进行服务。因此,无切换的ECALL将重复使用常规的ECALL的TLS区域。

sgx_create_enclave_ex的使用示例:

sgx_launch_token_t token = {0};
sgx_status_t ret = SGX_ERROR_UNEXPECTED;
int updated = 0;
sgx_uswitchless_config_t us_config = { 0, 1, 1, 100000, 100000, { 0 } };
void* enclave_ex_p[32] = { 0 };
enclave_ex_p[SGX_CREATE_ENCLAVE_EX_SWITCHLESS_
BIT_IDX] = &us_config;
sgx_enclave_id_t eid;
const char* fname = "enclave.signed.so";
ret = sgx_create_enclave_ex ( fname, SGX_DEBUG_FLAG, &token, &updated, &eid, NULL, SGX_CREATE_ENCLAVE_EX_SWITCHLESS, enclave_ex_p );

High level概述
Intel SGX开发者参考书(四)—— Enclave开发基础(三)_第1张图片
主要特点:

  • 两个任务池,分别用于ECALL和OCALL任务。
  • 几个工作线程为ECALLs(在Enclave内运行)和OCALLs(在Enclave外运行)请求提供服务。
  • 描述ECALL/OCALL请求的任务对象,包括所有必须的参数。
    任务池:
    任务池包含待执行的任务请求。它使用任务对象在可信和不可信端之间传输数据,而不调用EENTER/EEXIT。
    应用程序在运行时定义任务池大小,即并发任务请求的数量。
    工作线程
    工作线程在相关的任务池中等待一个或多个挂起的任务,并开始执行这些任务,直到任务池变为空。
    工作线程的数量由应用程序在运行时定义,并且应该至少有两个来支持嵌套的无切换调用。
    嵌套无切换调用(无切换OCALL–>无切换ECALL–>…–>无切换OCALL)的深度不能大于工作线程的数量。
    退回到常规的ECALLs/OCALLs
    当任务池已满,或所有工作线程都处于繁忙状态时,无切换调用将返回到常规的ECALL/OCALL。
    嵌套的无切换调用
    无切换调用不支持私有嵌套的ECALLs。使用transition_using_threads关键字的嵌套ECALLs也必须是public的。仅允许嵌套的无切换ECALL是不够的。非公共嵌套的ECALL将SGX_ERROR_NOT_ALLOWED返回给应用程序。
    无切换调用使用配置提示
    无切换调用操作模式可以提高某些工作负载的性能。但是这种模式很复杂,可能会导致运行速度减慢或/和资源被繁忙等待的工作线程超载。
    在使用无切换调用时,强烈建议在开发周期中引入性能度量和调优。Switchless示例代码中显示了一个简单的示例。
    无切换调用操作模式回调
    应用程序可以为工作线程事件注册回调。工作线程可以发送四种类型的事件:
  • 工作线程启动
  • 工作线程退出
  • 工作线程进入空闲状态(休眠)
  • 工作线程未执行无切换调用(回退)
    工作线程事件包含已处理的和未执行的(回退)无切换调用的统计信息。统计信息对于相同类型的所有工作线程都是通用的(可信/不可信)。
    应用程序可以使用无切换模式回调(sgx_uswitchless_worker_callback_t)来收集额外的性能数据。注意,工作线程丢失事件(SGX_USWITCHLESS_WORKER_EVENT_MISS)可能会发生并导致额外的开销。
    使用无切换调用的应用程序可能会发现,检测CPU的HW功能非常有用:用于配置无切换配置结构的内核和线程的数量。
    工作线程启动事件(SGX_USWITCHLESS_WORKER_EVENT_START)可用于设置线程关联
    请参阅下面的工作线程退出回调的示例。对于回调原型,请参考sgx_uswitchless_worker_callback_t。(其实我不知道在说什么)
// global processed/missed calls counters
// 0,1 - untrusted; 2,3 - trusted
uint32_t g_stats[4] = { 0 };
/**
* callback to log switchless calls stats
*/
void exit_callback (
	sgx_uswitchless_worker_type_t type,
	sgx_uswitchless_worker_event_t event,
	const sgx_uswitchless_worker_stats_t* stats )
{
	// last thread exiting will update the latest results
	g_stats[type*2] = stats->processed;
	g_stats[type*2+1] = stats->missed;
}

启用Enclave代码机密性

Intel SGX Protected Code Loader(Intel SGX受保护代码加载器)(Intel SGX PCL)旨在保护Windows OS上运行的Intel SGX Enclave应用程序代码中的知识产权(IP)。
问题Intel SGX在运行时提供代码的完整性、机密性和数据的完整性。但是,它不提供将离线代码作为磁盘上的二进制文件的机密性。攻击者可以反向工程二进制Enclave DLL。
解决办法: 在构建时加密Enclave DLL,并在Enclave加载时解密它。
Intel SGX PCL结构概述:
运行时:
下图显示了Intel SGX PCL构建流程。
Intel SGX开发者参考书(四)—— Enclave开发基础(三)_第2张图片

  1. Intel SGX PCL库连接到ISV Intel SGX IPEclave
  2. 在ISV IP Enclave签名之前,要修改连接的DLL,以便对包含IP的PE部分进行加密。绿色密钥表示对称加密/解密密钥。

注意:

  • Intel SGX PCL加密工具将所有部分视为IP,除了签名工具、Intel SGX PSW Enclave加载程序或Intel SGX PCL解密流所需的部分。
  • 加解密密钥管理是ISV的职责,超出了本文档的范围。

运行时
ISV封装Enclave
要加载一个IP Enclave,ISV必须先将一个解密AES密钥传输到用户本地机器,将其封装在用户本地机器上,并将其用作Intel SGX PCL的输入。为此,ISV必须设计第二个Enclave,即“Sealing Enclave”。下图显示了这个流程。
Intel SGX开发者参考书(四)—— Enclave开发基础(三)_第3张图片

ISV密封Enclave执行以下操作:

  1. 使用现有的标准Intel SGX SDK远程认证来生成与ISV服务器的安全会话。(淡蓝色的密钥表示会话密钥)
  2. 以安全的方式从ISV服务器接收解密密钥
  3. 使用现有的标准Intel SGX SDK密封机制生成密封密钥并将其存储在本地。

注意:

  • 为了密封Enclave和IP Enclave能够封装和解封装解密密钥,两个Enclave必须使用相同的Intel SGX ISV签名密钥进行签名,并且具有相同的ProdID。
  • 一旦生成了蜜蜂密钥,就可以将其存储在平台上的非易失性内存中。这减少了运行所需的远程认证的数量。

ISV IP Enclave
下图为Enclave加载流程:
Intel SGX开发者参考书(四)—— Enclave开发基础(三)_第4张图片

ISV IP Enclave执行以下操作:

  1. 接收密封的密钥Blob作为输入。
  2. 打开Blob以接收解密密钥
  3. 使用解密密钥对IP内容进行解密

与标准过程的比较
下表总结了使用和不使用Intel SGX PCL的IP Enclave负载流之间的差异。
表4 使用和不使用Intel SGX PCL的流程比较

步骤 标准过程(没有Intel SGX PCL) Intel SGX PCL Flow
构建时 链接:ISV库和objs链接到Enclave.dll
签名:签名Enclave.dll生成Enclave.signed.dll
链接:ISV库,objs和sgx_pcl.lib连接到IPEnclave.dll
加密IPEnclave.dll为IPEclave.dll
签名:签名IPEnclave.enc.dll为IPEnclave.signed.dll
Enclave加载 1.Enclave应用程序用sgx_create_enclave加载Enclave
2.sgx_create_enclave执行隐式ECALL
3.隐式ECALL启动一个Enclave运行时初始化流
1.Enclave应用程序获取已封装的的解密密钥
2.Enclave使用sgx_create_enclave加载Enclave,并提供已封装的解密密钥
3.sgx_create_enclave_ex执行一个隐式ECALL
4.隐式ECALL调用Intel SGX PCL流
5.Intel SGX PCL解封装已加密的blob以获取解密密钥
6.Intel SGX PCL加密已加密的IP sections并返回它的功能状态的Enclave
7.这个过程在Enclave运行时初始化流中持续使用

注意:Intel SGX PCL不支持Simulation模式。
安全注意事项
不加密的区域
ISV必须确保下表中描述的区域不包含ISV IP。加密工具不会加密这些区域。
表5 不加密区域

区域 描述
PE部分以外的内容 加密工具不加密section以外的内容
Section “.reloc” Intel SGX PCL使用“.reloc”部分,用于将重新定位应用于其代码和数据
Sections “niptx”, “nipdt”, “nipdt1”, “nipdt2”
and “pcltbl” 这些部分包括在Intel SGX PCL流程中使用的代码和数据
Sections “.debug”, “sgxmeta”, “sgxdata”,
“sgxvers”, “.tls” and “.edata” 这些部分是Intel SGX SDK签名工具或Intel SGX PSW Enclave加载程序所需的
导出目录,导出目录字符串符号,导出目录函数,导出目录名称,导出目录序号,TLS目录,线程数据,调试目录,调试数据 这些区域是Intel®SGX SDK签名工具或Intel®SGX PSW enclave加载程序所需要的

可写的部分
Intel SGX PCL加密攻击在加密的PE节的节标志中设置可写位。因此,属于此类PE部分的所有页面,包括Enclave代码和只读数据的部分,在Enclave运行时都是可写的。

Intel SGX PCL加密标准
在build时,加密工具使用:

  • SHA256来计算对称加密/解密密钥的hash,并将其嵌入到IP Enclave二进制文件中
  • AES-GCM-128对IP部分进行就地加密
  • RDRAND生成每个部分的随机IVs

在运行时,Intel SGX PCL使用:

  1. SHA256来计算未密封的对称加密/解密密钥的hash。Intel SGX PCL通过在build时将加密/解密密钥的散列与嵌入到IP Enclave二进制文件中的hash进行比较,来验证对称加密/解密的完整性。
  2. AES-GCM-128对IP部分进行就地解密

Intel SGX PCL加密代码片段来自OpenSSL
Intel SGX PCL库包含来自OpenSSL1.1.1的代码片段(经过稍微修改后,可以在Intel SGX PCL中运行)。这些片段现在是ISV的IP Enclave的TCB的一部分。如果在将来,OpenSSL1.1.1的一个已识别的漏洞需要修改这些代码片段的来源文件,则ISV必须相应地更新这些代码片段。

集成Intel SGX PCL与现有地Intel SGX 解决方案

将ISV Enclave与Intel SGX PCL集成需要ISV对ISV解决方案进行修改:

  • 对IP Enclave应用修改。
  • 将修改应用于加载Enclave地Enclave应用程序
  • 创建一个另外的Enclave,封装Enclave
    注意:上述步骤已经应用于SampleEnclavePCL。见README.md用于构建和运行示例代码的说明。
    免责声明:本章提供了一个伪代码,它是不安全的,不完整的,不能编译。有关完整代码,请参见SampleEnclavePCL。

对IP Enclave的修改

  • 如果启用,禁用incremental linking
  • 如果启用,禁用整个程序优化
  • 如果启用,禁用过程间优化“多文件”
  • 如果启用,禁用控制流保护
  • 添加sgx_pcl.lib到Enclave所连接的静态库列表中。
  • 更改构建流,以便在对Enclave进行签名之前运行构建时加密工具sgx_enc_ip.exe
 sgx_enc_ip.exe -k key.bin -i IPEnclave.dll -o IPEnclave.enc.dll
  • 将sign命令更改位对加密的IPenclave.enc.dll进行签名
  • 不需要修改的IP Enclave源代码

对Enclave应用程序的修改
所需的步骤:

  1. 获取已封装的blob:
    如果存在一个包含密封blob的文件(例如,它是在前几次运行期间生成的),请读取它
    如果文件不存在:
    1.创建密封Enclave
    2.使用密封Enclave将解密密钥提供给平台并密封
    3.将密封的密钥保存到平台上的一个文件中,以备将来使用。
  2. 使用sgx_create_enclave_ex加载加密的Enclave,并提供密封的blob
    伪代码:
#define SEALED_KEY_FILE_NAME "SealedKey.bin"
#define IP_ENCLAVE_FILE_NAME "IPEnclave.signed.dll"
#define SEALING_ENCLAVE_FILE_NAME "SealingEnclave.signed.dll"
uint8_t* sealed_key;
size_t sealed_key_size;
if(file_exists(SEALED_KEY_FILE_NAME))
{
	// Sealed key file exists, read it into buffer:
	ReadFromFile(SEALED_KEY_FILE_NAME, sealed_key);
}
else
{
	/*
	 * Sealed key file does not exist. Create it:
	 * 1. Create the Sealing Enclave
	 * 2. Use the Sealing Enclave to provision the decryption key onto the platform and seal it.
	 * 3. Save the sealed key to a file for future uses
	 */
	 // 1. create the sealing enclave
	sgx_create_enclave(
		SEALING_ENCLAVE_FILE_NAME,
		debug,
		&token,
		&updated,
		&seal_enclave_id,
		NULL);
	/*
	 * 2. Use the Sealing Enclave to provision the decryption key onto the platform and seal it:
	 */
	ecall_get_sealed_key_size(seal_enclave_id, &sealed_key_size);
	sealed_key = (uint8_t*)malloc(sealed_key_size);
	ecall_get_sealed_key(seal_enclave_id, sealed_key, sealed_key_size);
	// 3. Save the sealed key to a file for future uses
	WriteToFile(SEALED_KEY_FILE_NAME, sealed_key);
}
// Load the encrypted enclave, providing the sealed key:
const void* ex_features[32] = {};
ex_features[SGX_CREATE_ENCLAVE_EX_PCL_BIT_IDX] = sealed_key;
sgx_create_enclave_ex(
	IP_ENCLAVE_FILE_NAME,
	debug,
	&token,
	&updated,
	ip_enclave_id,
	NULL,
	ex_features,
	SGX_CREATE_ENCLAVE_EX_PCL);

封装Enclave
Intel SGX PCL解密密钥供应
本节描述创建和使用ISV密封Enclave的方法。ISV密封Enclave将解密密钥提供给用户本地机器并对其进行密封。(把解密密钥给我,再对这个密钥密封起来)
要安全地将解密AES密钥传输到用户本地机器,ISV密封Enclave需要向ISV服务器进行验证,生成一个安全会话,并使用它来提供解密密钥。(向ISV获取解密密钥的过程)
将Intel SGX PCL解密密钥从ISV服务器发送到本地平台
本文档中的远程认证示例详细说明和描述了如果使用ISV服务器启动远程认证会话。
远程认证允许服务器和客户端共享密钥。这些密钥可用于在ISV服务器和密封Enclave之间生成安全会话(例如,使用TLS)。然后,可以使用安全会话安全地提供解密密钥。
密封Intel SGX PCL解密密钥
**本文档中地密封样例代码说明了如何封装一个秘密。**默认情况下,IntelSGX SDK使用MRSIGNER来密封这个秘密。
与Enclave应用程序地交互
在上面的为代码中,ISV密封Enclave通过实现Enclave调用ecall_get_sealed_key_size 和ecall_get_sealed_key来为Enclave应用程序提供密封的解密密钥。这不是一个架构需求,ISV可以使用自己的设计。

启用CVE-2020-0551缓解

Intel SGX SDK利用CVE-2020-0551的缓解,即LVI(负载值注入).Intel SGX SDK支持两个缓解级别。一级处理易受LVI攻击的所有指令。这个级别为CVE-2020-0551-Load(简称Load)。第二个缓解级别只处理脆弱的控制流指令,称为CVE-2020-0551-CF(简称CF)。

支持缓解的信任库
Intel SGX SDK包含三组可信库:Unmitigated、Load和CF。
表6

缓解等级 路径
Unmitigated [Intel SGX SDK Install Path]bin\x64\Release
Load [Intel SGX SDK Install Path]bin\x64\CVE-2020-0551-Load-Release
CF [Intel SGX SDK Install Path]bin\x64\CVE-2020-0551-CF-Release

如上所述,Intel SGX SDK利用CVE-2020-0551的缓解。充分利用这一点的Intel SGX开发人员需要以下工具。
所需工具:

  • VS2017及以上版本
  • Sgx-asm-pp.py.这是一个自定义工具,是Intel SGX SDK的一部分。此工具有助于缓解手写的汇编代码。
    所需的选项:
Load缓解level CF缓解level 无LVI缓解
VS2017及以上版本 /Qspectre-load /Qspectre-load-cf 两者都不
Sgx-asm-pp.py --MITIGATION-CVE-2020-0551=LOAD --MITIGATION-CVE-2020-0551=CF --MITIGATIONCVE-2020-0551=NONE o或者直接使用 NASM/MASM
Sgx-asm-pp.py还有另一个必需的选项--assembler。此选项用于指定用于程序集源文件的汇编程序。--assembler的有效参数是‘nasm’和‘ml64’(不带引号)。

创建启用可信Enclave的CVE-2020-0551缓解项目
你可以用Intel SGX VS Wizard来创建启用CVE-2020-0551 mitigation的新项目。
参见Microsoft* Visual Studio* Intel®Software Guard Extensions向导创建一个启用CVE-2020-0551缓冲的新项目(前面已经介绍过了)
在新的可信项目创建后,将发现四个新的CVE-2020-0051缓解相关配置。

  • CVE-2020-0551-Load-Release
  • CVE-2020-0551-Load-Prerelease
  • CVE-2020-0551-CF-Release
  • CVE-2020-0551-CF-Prerelease
    详细信息在 缓解配置介绍 部分。

注意:这四个配置只在x64平台上支持。

缓解配置介绍
CVE-2020-0051缓解包括以下四个相关配置:
CVE-2020-0551-Load-Release:

  • 项目以发布模式构建,并启用了Load级别缓解功能
  • 所有C/C++文件都将使用/Qspectre-load选项构建

CVE-2020-0551-Load-Prerelease:

  • 项目以预发布模式构建,并启用了Load级别缓解功能
  • 所有C/C++文件都将使用/Qspectre-load选项构建

CVE-2020-0551-CF-Release:

  • 使用发布模式构建项目,并启用控制流(CF)级别缓解功能
  • 所有C/C++文件都将使用/Qspectre-load-cf选项构建

CVE-2020-0551-CF-Prerelease:

  • 使用预发布模式构建项目,并启用控制流(CF)级别缓解功能
  • 所有C/C++文件都将使用/Qspectre-load-cf选项构建

在每个配置中,每个.asm文件的build命令都会根据它的属性–>常规–>项目类型(没找到啊)类型改变:

  • 如果.asm文件的类型是自定义构建工具,并且是由ml64.exe构建的。文件的属性–>自定义构建工具–>命令行将切换到:
python "$(SGXSDKInstallPath)\scripts\sgx-asm-pp.py"
--assembler=ml64 --MITIGATION-CVE-2020-0551=
[LOAD|CF] <ml64 command line options>
  • 如果.asm文件的类型是自定义构建工具,并且是由nasm.exe构建的。文件的属性–>自定义构建工具–>命令行将切换到:
python "$(SGXSDKInstallPath)\scripts\sgx-asm-pp.py"
--assembler=nasm --MITIGATION-CVE-2020-0551=
[LOAD|CF] <nasm command line options>
  • 如果.asm文件的类型是 Microsoft Macro
    Assembler。可新项目的属性–>构建依赖项–>构建自定义…将切换到Intel SGX特殊的masm脚本。

存在问题:
找不到属性–>常规–>项目类型,导致后面的都没有完成,应该是没有构建这个模式吧?

如有误,请指正!感激!

你可能感兴趣的:(sgx)