Intel SGX Developer Reference 学习笔记(六)

 在这之前,一直想学习关于SGX实操性的、应用相关的内容,我浏览了相关资料,总觉得跟不上那些作者的脚步,学到的都是些零零碎碎的知识,收获都不是很大,一边阅读还在一边质疑资料的可读性,所以我决定返朴归真,静下心来好好看一看官网的手册,并作一些笔记方便自己的日后学习。
手册下载地址: Intel® Software Guard Extensions (Intel® SGX) SDK for Linux* OS

Intel® Software Guard Extensions SDK Sample Code

安装Intel®Software Guard Extensions SDK后,您可以在[Intel SGX SDK安装路径]SampleCode找到示例代码。

  • SampleEnclave 项目展示如何创建一个enclave。
  • Cxx11SGXDemo 项目展示如何在enclave库里使用C++11库。
  • LocalAttestation 项目展示如何使用Intel Elliptical Curve Diffie-Hellman密钥交换库在同一平台的两个enclave中建立一个可信的通道。
  • RemoteAttestation项目展示如何在远程认证过程中使用Intel远程认证和密钥交换库。
Sample Enclave

项目SampleEnclave向您展示了如何从头开始编写enclave。本主题演示了  enclave特性的以下基本方面:

  • 建立和销毁一个enclave
  • 创建ECALLs和OCALLs
  • 在enclave内部调用可信库

 源代码随Intel SGX SDK安装包一起发布,安装路径为[Intel SGX SDK的安装路径]SampleCode/SampleEnclave。 提供了一个Makefile来在Linux上构建SampleEnclave。

Initialize an Enclave

 在应用程序和enclave间建立任何可信事务之前,enclave本身需要通过调用uRTS库(不受信任的运行时系统库)提供的sgx_create_enclave正确地创建和初始化。
保存和检索 Launch Token启动令牌
 启动Intel®SGX 2.4版本时,您不再需要传递和存储启动令牌。(Intel®SGX 2.4版本于2018年11月修订,对于2.4之前令牌是如何启动的,目前不做学习了,跳过。)
ECALL/OCALL函数
 Sample Enclave示例演示了ECALL/OCALL函数使用的基本EDL语法,以及enclave中使用的可信库。
销毁Enclave
 要释放enclave内存,需要调用sgx_urts库提供的sgx_destroy_enclave。它将回收该enclave实例使用的EPC内存和不受信任的资源。

Power Transition(电源转换)

 如果发生电源转换(断电),则enclave内存将被删除,所有enclave数据将不可访问。因此,当系统恢复时,每个进程内的ECALLS和后续的ECALLS都将失败,错误码为SGX_ERROR_ENCLAVE_LOST,它表示enclave由于电源转换而丢失。
 一个Intel SGX项目有能力处理可能影响其行为的电源转换。名为PowerTransition的项目描述了一种可以开发处理电源转换的Intel SGX项目的方法。
 PowerTransition演示了以下场景:一个enclave实例由一个主线程创建和初始化,并与其他三个子线程共享;这三个子线程重复地调用enclave,操作enclave内的秘密数据,并在enclave外备份相应的加密数据;在所有的子线程完成后,主线程销毁enclave并释放关联的系统资源。如果发生电源转换,则只有一个线程将重新加载enclave,并使用保存在外部的加密数据恢复enclave内部的秘密数据,然后继续执行。详见文档-92-。

C++11 Demo

 Cxx11SGXDemo项目旨在说明Intel SGX SDK提供的enclave中支持的一些c++11库特性,以及GCC支持的编译器特性。这个示例为当前支持c++11的每个特性提供了实际的用例。
 该示例涵盖了enclave中的c++ 11特性的一个子集,如下表所示。
在这里插入图片描述

C++14 Demo

 Cxx14SGXDemo项目旨在说明Intel SGX SDK提供的enclave中支持的一些c++ 14库特性,以及GCC支持的编译器特性。本示例为当前支持的c++ 14个特性提供了实际的用例。
 该示例涵盖了enclave中c++ 14个特性的一个子集,如下表所示。
在这里插入图片描述

Attestation

 在Intel®Software Guard Extensions体系结构中,认证是指证明在平台上建立了特定的enclave的过程。Intel®SGX架构提供两种认证机制:

  • 一种方法是同一平台上运行的两个enclave间建立一个身份验证的断言,称为本地身份认证。
  • 第二种机制扩展了本地认证,向平台外的第三方提供断言,称为远程认证。远程认证过程利用quoting服务。

 Intel® SDK提供应用程序使用的api来实现认证过程。

Local Attestation 本地认证
 本地认证是指同一平台上的两个enclave在交换信息之前使用Intel SGX REPORT机制对彼此进行认证。在Intel SGX应用程序中,多个enclave可能合作执行某些函数。在两个enclave验证对方是可信的,他们在一个受保护通道交换信息,该通道通常提供机密性、完整性和重放保护。本地认证和受保护的通道的建立使用基于REPORT的DiffieHellman密钥交换*协议。

Local Attestation示例代码展示了本地认证的示例实现,包括使用enclave对enclave函数调用 建立受保护的通道 和 交换秘密消息 作为示例。

Diffie-Hellman密钥交换库和本地认证流程
 SDK中的本地认证示例使用DH (Diffie-Hellman)密钥交换库在两个enclave之间建立一个受保护的通道。DH密钥交换的API被定义在sgx_dh.h中。密钥交换库是Intel SGX应用程序 SDK可信库的一部分。它与enclave代码静态链接,并为enclave代码公开API,以生成和处理本地密钥交换协议消息。这个库与其他库结合在一起并内置到名为libsgx_tservice的最终库中。
在这里插入图片描述
 上图为DH密钥交换库的使用情况。本地认证流程包括以下几个步骤:
 在图中,图中,ISV Enclave1为启动器Enclave, ISV Enclave2为响应器Enclave。

  1. 启动器enclave调用Intel ECDH密钥交换库以启动者角色发起会话session。
  2. 启动器enclave向不可信代码发出一个OCALL调用,请求DH Message 1 和 session id。
  3. 不受信任代码对响应器enclave执行一个ECALL。
  4. 响应器enclave反过来调用ECDH密钥交换库,以响应者的身份发起一个session。
  5. 响应器enclave调用密钥交换库去生成DH Message1 ga || TARGETINFO
  6. DH Message1 被从响应器enclave送回到启动器enclave。通过一个ECALL返回到不受信任的代码,紧接着通过一个OCALL返回到启动器enclave。
  7. 启动器enclave通过密钥交换库API处理DH Message1,生成DH Message2 gb||[Report Enclave 1(h(ga || gb))]SMK
  8. DH Message2 通过OCALL发送到不受信任方。
  9. 不受信任代码对响应器enclave发出一个ECALL,给出DH Message2并请求DH Message3 。
  10. 响应器enclave调用密钥交换库API处理DH Message2,生成DH Message 3 [ReportEnclave2(h(gb || ga)) ||可选Payload]SMK。
  11. DH Message3 被从响应器enclave送回到启动器enclave。通过一个ECALL返回到不受信任的代码,紧接着通过一个OCALL返回到启动器enclave。
  12. 启动器enclave使用密钥交换库处理DH Message3并建立会话session。
  13. enclave间的信息交换由AEK保护。

Diffie-Hellman密钥交换库和本地认证2.0
 DH (Diffie-Hellman)密钥交换库也公开DH密钥交换2.0 api,用于enclave代码生成和处理本地密钥交换协议消息。
 本地认证2.0流程包括上一节中除7和10之外的步骤:

  1. 启动器enclave调用Intel ECDH密钥交换库以启动者角色发起会话session。
  2. 启动器enclave向不可信代码发出一个OCALL调用,请求DH Message 1 和 session id。
  3. 不受信任代码对响应器enclave执行一个ECALL。
  4. 响应器enclave反过来调用ECDH密钥交换库,以响应者的身份发起一个session。
  5. 响应器enclave调用密钥交换库去生成DH Message1 ga || TARGETINFO
  6. DH Message1 被从响应器enclave送回到启动器enclave。通过一个ECALL返回到不受信任的代码,紧接着通过一个OCALL返回到启动器enclave。
  7. 启动器enclave通过密钥交换库2.0 API处理DH Message1,生成DH Message2 gb||[Report Enclave 1(h(proto_spec || gb))]SMK 并且 report_data替换为 proto_specin , proto_spec 是 ‘SGX LA’ || Ver|| Rev || TARGET_SPEC || padding。
  8. DH Message2 通过OCALL发送到不受信任方。
  9. 不受信任代码对响应器enclave发出一个ECALL,给出DH Message2并请求DH Message3 。
  10. 响应器enclave调用密钥交换库API处理DH Message2,生成DH Message 3 [Report Enclave2(h(ga || proto_spec)) || Optional Payload ||ga]SMK.
  11. DH Message3 被从响应器enclave送回到启动器enclave。通过一个ECALL返回到不受信任的代码,紧接着通过一个OCALL返回到启动器enclave。
  12. 启动器enclave使用密钥交换库处理DH Message3并建立会话session。
  13. enclave间的信息交换由AEK保护。

保护通道的建立
 下图说明了两个enclave(源enclave和目标enclave)之间建立会话的交互。应用程序通过对源enclave执行一个ECALL,并传入目标enclave的enclave id,从而在源enclave和目标enclave之间启动一个会话。接下来的流程如上图所示。

Remote Attestation 远程认证
 一般来说,远程认证是指硬件实体或硬件和软件的组合获得某种类型的远程提供者或生产者的信任。在Intel SGX中,远程认证软件提供包括app的enclave和intel提供的QE(Quoting Enclave)和PvE(Provisioning Enclave),认证硬件是Intel®SGX启用的CPU。
 单独的远程认证不足以让远程方安全地交付其服务(秘密和资产)。安全交付服务还需要一个安全的通信会话。在此会话建立过程中使用远程认证。 这与熟悉的SSL握手包括身份验证和会话建立的方式类似。

 Intel SGX SDK包括简单的样例代码展示:

  • 应用程序enclave如何向远程方身份证明
  • 应用程序enclave和远程方间如何建立安全会话。

 SDK包括一个远程会话建立或密钥交换库,可用于极大的简化这些步骤。
 Intel SGX使用匿名签名方案,Intel Enhanced Privacy ID(Intel EPID)用于认证。被提供的密钥交换库实现一个类似Sigma的会话建立协议。Sigma是一个包括Diffie-Hellman密钥交换的协议,但也解决了DH的弱点。Intel SGX使用的协议与IKE v1,v2使用的Sigma协议的不同之处在于,Intel SGX平台使用Intel EPID去认证,而服务提供者使用PKI,在Sigma中,两边都使用PKI。最后,密钥交换库要求服务提供者在协议的身份验证部分使用ECDSA而不是RSA密钥对,而库使用ECDH进行实际的密钥交换。(SGX使用的签名方案与Sigma类似,但不相同,以及它们的不同之处)

Remote Key Exchange (KE) Libraries 远程密钥交换库
 SDK中的RemoteAttestation sample示例使用上面描述的远程密钥交换库来创建一个enclave的远程认证,并且使用他在建立安全会话(密钥交换)中认证。
 既有不可信的密钥交换KE库,也有可信的密钥交换KE库。不受信任的密钥交换KE库作为静态库libsgx_ukey_exchange.a提供。Intel®SGX应用程序需要链接到这个库,并包含头文件sgx_ukey_exchange.h,其中包含可信密钥交换库公开的API的原型。

NOTE
 如果您不能使用两个预构建的不受信任密钥交换静态库中的任何一个,则此SDK附带的远程认证示例应用程序的isv_app子文件夹中包含一个示例的不受信任密钥交换库的源代码。

 可信密钥交换库也是最为静态库提供的。作为一个可信库,使用它的过程与使用不可信密钥交换库的过程略有不同。主要的区别在于,可信密钥交换库暴露了被不可信密钥交换库调用的ECALL。这意味着可信库中有一个EDL文件sgx_tkey_exchange.edl,必须在使用这个库的应用程序enclave的EDL文件中导入。下面的代码展示了app_enclave.edl(应用程序enclave的EDL文件)的完整内容。

enclave{
	form "sgx_tkey_exchange.edl" import *;
	include "sgx_key_exchange.h"
	include "sgx_trts.h"
	trusted{
		public sgx_status_t enclave_init_ra(int b_pse,[out] sgx_ra_context_t *p_context);
		public sgx_status_t enclave_ra_close(sgx_ra_context_t context);
	};
};

 值得注意的是,sgx_key_exchange.h包含特定于远程密钥交换的类型,必须包括在上面的示例中,以及使用enclave的应用程序的不受信任的代码中。sgx_tkey_exchange.h是一个包含可信库暴露的API原型的头文件,但这些不是ECALL,而是被应用程序enclave中的ISV代码调用的API。

Remote Attestation and Protected Session Establishment 远程认证和受保护会话建立
 这部分详细介绍远程认证样例的功能。
NOTE
 在样例代码中,服务提供者被建模为一个共享对象service_provider.so。示例服务提供者不依赖于Intel SGX头文件、类型定义、库等。这样做是为了证明在构建远程认证服务提供者时,不需要Intel SGX。
在这里插入图片描述
 Intel®Software Guard Extensions (Intel®SGX)应用程序通常从服务提供商(SP)请求服务(例如,流媒体)开始,SP将响应一个挑战。这在图中没有显示。图中始于应用程序对挑战的反应。

  1. 该流从应用程序进入密钥交换的端点enclave开始,传入b_pse,该标志指示应用程序/enclave是否使用Platform Services。
  2. 如果b_pse为true,那么isv enclave将使用sgx_create_pse_session()调用受信任的AE支持库,以使用PSE建立会话。
  3. enclave中的代码调用sgx_ra_init(),传入SP的ECDSA公钥g_sp_pub_key和b_pse。g_sp_pub_ key的完整性是一个公钥,这一点很重要,因此这个值应该构建到isv_ enclave中。
  4. 如果之前会话已经被建立,则通过sgx_close_pse_session()关闭PSE会话。要求是,如果应用程序enclave使用Platform Services,那么在应用程序enclave调用sgx_ra_init()之前必须已经建立与PSE的会话。
  5. sgx_ra_init()将密钥交换内容返回给app enclave,而app enclave将内容返回给应用。
  6. 应用程序调用sgx_get_extended_epid_group_id()并在msg0中将p_extended_epid_group_id中返回的值发送给服务器。
  7. 服务器检查是否支持扩展的Intel®EPID组ID。如果不支持该ID,服务器将终止远程认证。
    **NOTE:**目前,Intel®扩展EPID组ID唯一有效的是零。服务器应该验证这个值为零。如果Intel®EPID组ID不为零,服务器将终止远程认证。
  8. 应用程序调用sgx_ra_get_msg1(),传入这个KE的上下文中。图3显示了应用程序还传递了一个指针,指向由TKE公开的与sgx_ra_get_ga对应的不受信任的代理。这反映了一个事实,即不可信代理的名称是特定于enclave的。
  9. sgx_ra_get_msg1()构建一个S1 message= (ga || GID)并将其返回给应用程序。
  10. 应用程序通过ra_network_send_ receive()将S1发送给服务提供商(SP),它将调用sp_ra_proc_msg1_req()来处理S1并生成S2。
  11. 应用程序最终接收到S2。
  12. 应用程序调用sgx_ra_proc_msg2(),传入S2和上下文。
  13. sgx_ra_proc_msg2()中的代码构建S3 = CMACSMK(M)||M,其中M = ga ||PS_SECURITY_PROPERTY|| QUOTE并返回它。只有当app/enclave使用平台服务时,才会包含平台服务安全信息。
  14. 应用程序通过ra_network_send_ receive()将msg3发送给SP, SP验证msg3。
  15. SP将验证结果返回给应用程序。

 此时,会话已经建立并交换了密钥。服务提供者是否认为会话是安全的并使用它取决于S3消息所指示的平台的安全属性。如果平台的安全属性满足服务提供者的条件,那么服务提供者可以使用会话密钥来安全地传递一个密钥,而应用程序enclave可以在通过调用可信KE库上的sgx_ra_get_keys()获取会话密钥后的任何时间使用该密钥。这在图中没有显示,会话的关闭也没有显示。关闭会话需要进入app enclave,并在可信KE库上调用sgx_ra_close(),以及其他特定于app enclave的清理。

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值