@Intel SGX 读书笔记…
Intel SGX SDK示例代码
安装Intel SGX SDK后,你可以在[Intel SGX SDK Install Path]src下找到示例代码。
你可以在VS2017中打开示例项目:
- SampleEnclave项目展示了如何创建Enclave
- PowerTransition项目展示了如何处理Intel SGX项目的power transition
- Cxx11SGXDemo项目展示了如何在Enclave中使用c++ 11库
- LocalAttestation项目演示了如何使用Intel Wlliptical Curve Diffie-Hellman密钥交换库在运行在同一平台上的两个Enclave之间建立可信通道
- RemoteAttestation项目演示了如何在远程认证过程中使用Intel远程认证和密钥交换库
- SealedData项目展示了如何使用api来加密和完整性保护Enclave机密,并将它们存储在磁盘上
- Sgx2Enclave项目展示了如何创建一个Intel SGX2 Enclave并使用sgx_tedmm库。
Sample Enclave
SampleEnclave项目向您展示了如何从头开始编写enclave。本主题演示了enclave特性的以下基本方面:
- 初始化和销毁一个Enclave
- 创建ECALLs和OCALLs
- 在Enclave内调用可信库
注意:如果示例项目位于系统目录中,则需要管理员特权才能打开它。如果无法授予管理员权限,可以将项目文件夹复制到你的其他目录中。
配置并启用Intel SGX
一些OEM系统通过SW控制接口支持在BIOS中配置和启用Intel SGX。Intel SGX PSW公开了所有应用程序在创建应用程序之前都应该调用的API。API sgx_enable_device配置并启用Intel SGX设备(如果平台之前没有启用)。如果BIOS配置了Intel SGX作为调用的结果,那么BIOS配置需要重新启动才能生效(Intel SGX要在重新启动之后才能使用)。请参考示例应用程序中query_sgx_status函数以使用此API。有关其他详细信息,请参见sgx_enable_device。
初始化一个Enclave
在应用程序和Enclave之间建立任何可信的事务之前,需要通过uRTS提供的sgx_create_enclave来正确地创建和初始化Enclave本身。
保存和检索启动令牌
启动令牌需要传递给sgx_create_enclave进行Enclave初试化。如果启动令牌是在前一个事务中保存地,则可以直接检索和使用它。否则,你可以提供一个全0缓冲区。如果输入无效,则sgx_create_enclave将尝试创建有效地启动令牌。正确创建并初始化Enclave之后,如果令牌已被更新,你可能需要保存令牌。sgx_create_enclave地第四个参数表示是否执行了更新。
sgx_create_enclave(ENCLAVE_FILENAME, SGX_DEBUG_FLAG, &token, &updated, &global_eid, NULL);
启动令牌应该保存在每个用户的目录或注册表项中,以防在多用户环境中使用。
例如,令牌可以保存在以下任何一个位置:
- CSIDL_LOCAL_APPDATA——存储应用程序特定数据得到文件系统目录
- HKEY_CURRENT_USER——包含当前登录到计算机的用户地配置文件的注册表项
有关CSIDL_LOCAL_APPDATA的详细信息,请参见https://docs.microsoft.com/en-us/windows/win32/shell/csidl?redirectedfrom=MSDN
ECALL/OCALL函数
这个示例演示了ECALL/OCALL函数使用的基本EDL语法,以及在Enclave中使用受信任的库。
销毁一个Enclave
要释放Enclave内存,需要调用sgx_destroy_enclave,它是由sgx_urts库提供的。它将回收EPC内存和Enclave示例使用的不可信资源。
Power Transition
如果发生了power transition,Enclave内存将被删除,并且所有Enclave数据都将不可访问。因此,当系统恢复时,进程内的每个ECALLs和后续的ECALL都将失败,错误代码SGX_ERROR_ENCLAVE_LOST表示Enclave由于power transition而丢失。
Intel SGX项目应具有处理可能影响其行为的power transition的能力。该项目名为PowerTrasition ,描述了一种开发Intel SGX项目的方法,该项目可以处理电源转换。有关更多信息,请参见ECALL-ERROR_Code Based Retry。
PowerTransition 演示了以下场景:一个Enclave示例由一个主线程创建并初始化,然后与其他三个子线程共享;三个子线程重复调用Enclave,在Enclave内操作秘密数据,并在Enclave外备份相应的加密数据;在所有子线程完成之后,主线程销毁Enclave并释放相关的系统资源。如果发生电源转换,一个且仅有一个线程将重新加载Enclave,并使用保存在外部的加密数据恢复Enclave中的秘密数据,然后继续执行。
基于ECALL-Error-Code重试
在Power Transition之后,将为当前ECALL返回一个Intel SGX错误代码SGX_ERROR_ENCLAVE_LOST。为了处理power transition并在不影响的情况下继续项目,你需要首先销毁无效的Enclave以释放资源,然后使用新创建和初始化的Enclave示例重试,如下图所示。
示例中的ECALLs
PowerTransition演示了两种类型的ECALLs中处理power transition:
- 创建Enclave后初始化ECALL
- 在Enclave内操作秘密
Enclave创建后初始化ECALL
PowerTransition演示了Enclave创建后的一个初始化ECALL,如下图所示:
sgx_create_enclave是uRTS库为Enclave创建提供的一个关键API。对于sgx_create_enclave,uRTS库中已经实现了一种Power Transition处理机制。因此,不需要手动处理此API的power transition。
注意:为了集中精力处理power transition,PowerTransition假定Enclave文件和启动令牌与应用程序位于相同的目录中。有关如何正确存储启动令牌,请参见Sample Enclave。(在前面)
Enclave中正常ECALL处理机密
这是Enclave中最常见的ECALL类型。PowerTransiton演示了在主线程创建并初始化Enclave之后,在子线程中对此类ECALL的power transition处理,如下图所示。因此Enclave实例是由子线程共享的,所以需要确保一个且仅有一个子线程在power transition之后重新创建和初始化Enclave实例,而其他线程则直接使用重新创建的Enclave实例。PowerTransition通过检查Enclave ID是否更新来确认这一点。
注意:在ECALL过程中,建议经常将机密数据作为密码文本被分到Enclave之外。然后我们可以使用备份数据来恢复Enclave,以减少power transition带来的影响。
C++11 Demo
Cxx11SGXDemo项目旨在演示由Intel SGX SDK提供的Enclave内支持的C++11库特性,以及VS2017编译器支持的编译特性。这个示例为当前支持的C++11特性中的每个特性提供了实际的用例。
该示例涵盖了下表中列出的Enclave中的C++11特性的一个子集。
Headers | #include <typeinfo> #include <functional> #include <algorithm> #include <unordered_set> #include <unordered_map> #include <initializer_list> #include <tuple> #include <memory> #include <atomic> #include <mutex> #include <condition_variable> #include < |
Classes | std::function, std::all_of, std::any_of, std::none_of, std::initializer_list, std::unordered_set, std::unordered_map, std::unordered_multiset, std::unordered_multimap, std::tuple, std::shared_ptr, std::unique_ptr, std::auto std::mutex, std::condition_variable |
Compiler features(编译器特性) | lambda表达式,auto, decltype, 强类型枚举类, 基于范围的语句, static_assert,新的虚函数控件, 委托构造函数,可变参数模板, 替换失败不是一个错误(SFINAE), rvalue引用和移动语义,nullptr类型 |
如有误,请指正!感激!