在这之前,一直想学习关于SGX实操性的、应用相关的内容,我浏览了相关资料,总觉得跟不上那些作者的脚步,学到的都是些零零碎碎的知识,收获都不是很大,一边阅读还在一边质疑资料的可读性,所以我决定返朴归真,静下心来好好看一看官网的手册,并作一些笔记方便自己的日后学习。
手册下载地址: Intel® Software Guard Extensions (Intel® SGX) SDK for Linux* OS
Using Intel® Software Guard Extensions SDK Tools
这篇笔记介绍了Intel®Software Guard Extensions SDK提供的以下几个工具,并且如何使用它们:
Intel®Software Guard Extensions SDK提供以下工具:
- Edger8r Tool
生成不可信组件与enclave们之间的接口。- Enclave Signing Tool
生成enclave元数据(包括enclave签名),并将此元数据添加到enclave映像。- Enclave Debugger
帮助调试一个enclave。- Enclave Memory Measurement Tool
帮助测量运行时enclave对受保护内存的使用情况。- CPUSVN Configuration Tool
在不修改硬件的情况下,模拟cpu模拟器的升级和降级场景。
Edger8r Tool
它通过读取EDL文件生成 edge routines? 这些边缘历程定义了不可信应用程序和enclave之间的接口。通常,该工具作为enclave构建过程的一部分而自动运行,但高级enclave玩家可以手动调用Edger8r。
当给定一个EDL文件时;举个例子,Enclave.edl,Edger8r默认生成4个文件:
- Enclave_t.h —— 包含可信代理和桥的原型声明。
- Enclave_t.c —— 包含可信代理和桥的函数定义。
- Enclave_u.h —— 包含不可信代理和桥的原型声明。
- Enclave_u.c —— 包含不可信代理和桥的函数定义。
Enclave Signing Tool
Intel SGX SDK提供一个叫sgx_sign的工具为你签名enclave。通常,对enclave进行签名是一个涉及生成包含比如enclave measurement的enclave属性的签名结构的过程。一旦以下面的结构对enclave进行签名,就可以检验到enclave文件(代码、数据、签名等等)的修改。签名工具还会评估enclave映像的潜在错误并告知你潜在的安全风险。
sgx_sign通常由Intel®SGX SDK中包含的配置工具之一进行设置,并在enclave构建过程结束时自动运行。在装载过程中,检查签名以确认enclave没有被篡改并且已正确装载。此外,签名工具还可以用于报告已签名的enclave的元数据信息,并生成能将enclave签名者添加到允许列表所需的SIGStruct文件。
Table 1 Enclave Signature Structure (enclave measurement)
Enclave签名结构
Section | Name |
---|---|
Header | headerType; headerLen; headerVersion; type; modVendor; date; size; keySize; modulusSize; enponentSize; swDefined; reserved; |
Signature | modulus; exponent; signature; |
Body | miscSelect; miscMask; reserved; ISVFamilyId; attributes; attributeMask; enclaveHash; reserved; ISVextprodId; ISVProdId; ISVSVN |
Buffer | reserved; Q1; Q2; |
命令行语法:
为了运行 sgx_sign,使用以下的命令行语法:
sgx_sign <command> [args]
Table 2 Signing Tool Commands
command | Description | Arguments(args) |
---|---|---|
sign | 在一步签名中使用私钥对enclave进行签名 | 必须的:-enclave,-key,-out; 可选的:-config, -dumpfile,-cssfile |
gendata | 二步签名的第一步。生成由外部工具签名的enclave签名材料,该材料由enclave签名结构的头部和主体部分组成 | 必须的:-enclave,-key.-out; 可选的:-config |
catsig | 二步签名的第二步。使用输入签名和公钥生成签过名的enclave。输入签名是由外部工具根据gendata命令生成的数据而生成的。在这步,生成签名部分和缓冲区部分。签名部分和缓冲区部分以及标题部分和主体部分完成了enclave的签名结构。 | 必须的:-enclave,-key.-out,-sig,-unsigned; 可选的:-config, -dumpfile,-cssfile |
dump | 获取签过名的enclave文件的元数据,并将元数据转出到由-dumpfile选项指定的文件中,并将SIGSTRUCT转储到由-cssfile选项指定的文件中 | 必须的:-enclave,-dumpfile; 可选的:-cssfile |
Table 3 Signing Tool Arguments
与命令对应的相关参数列表详见手册-17-,-18-。
tips:
Sgx_sign生成输出文件并返回0表示成功。否则,它将生成一个错误消息并返回-1。
Enclave Signing Key Management
在enclave开发生命周期中,enclave项目支持ISV需要的不同签名方法:
- 使用ISV的测试私钥的单步方法:
在这个场景中,ISV管理签名密钥对,它可以由ISV使用自己的方式生成。单步方法是非生产enclave应用程序的默认签名方法,这些应用程序是使用Intel SGX项目调试和预发布概要文件创建的。 - 使用外部签名工具的二步方法:
1.第一步:在enclave构建过程的最后,签名工具生成enclave签名材料。ISV将enclave签名材料文件带到存储私钥的外部签名平台,对签名材料文件进行签名,然后将生成的结果签名文件返回到构建平台。
2.第二步:ISV使用catsig命令运行签名工具,在命令行中提供必要的信息,以便将公钥的哈希值和签名添加到enclave的元数据部分。
两步签名过程在一个单独的工具中保护签名密钥。因此,它是Intel SGX项目发布概要文件的默认签名方法。这意味着它是签署生产enclave应用程序的唯一方法。
tips:
enclave签名工具只接受PEM格式且未加密的密钥文件。
Enclave Signer Usage Examples
当私有签名密钥在构建平台上可用时,您可以按照一步签名过程来签名您的enclave。但是,当私钥只能在隔离的签名工具中访问时,您必须遵循下面描述的两步签名过程。
- One-step signing process:
使用构建系统上可用的私钥对enclave签名:
sgx_sign sign -enclave enclave.so -config config.xml
-out enclave_signed.so -key private.pem
- Two-step signing process:
使用存储在HSM(硬件安全模块)中的私钥对enclave进行签名,例如:
//1.生成enclave签名材料//
sgx_sign gendata -enclave enclave.so -config config.xml -out enclave_sig.dat
//2. 在签名平台中,对包含enclave签名材料的文件(enclave_sig.dat)进行签名,并将结果签名文件(signature.dat)返回到构建平台。//
//3. 使用签名文件和公钥对enclave进行签名//
sgx_sign catsig -enclave enclave.so -config config.xml -out enclave_signed.so -key public.pem -sig signature.dat -unsigned enclave_sig.dat
为已签名的enclave生成元数据信息报告:
sgx_sign dump -enclave enclave_signed.so -dumpfile metadata_info.txt
OpenSSL* Examples
下面的命令行是使用OpenSSL的典型示例:
- 生成RSA的3072位私钥,使用3作为公共指数值。
openssl genrsa -out private_key.pem -3 3072
- 生成RSA私钥的公共部分。
openssl rsa -in private_key.pem -pubout -out publickey.pem
- 为包含enclave签名材料的文件签名。
openssl dgst -sha256 -out signature.dat -sign privatekey.pem -keyform PEM enclave_sig.dat
Enclave Debugger(Enclave调试器)
你可以使用helper脚本sgx_gdb去调试你的enclave应用。为了在硬件平台上调试enclave,在enclave配置文件config.xml中将配置参数设置为0,在创建enclave的sgx_create_enclave(…)中将参数设置为1。调试enclave类似于调试共享库。然而,不是所有的标准特性都可以用于调试enclave。下表列出了一些不支持的GDB命令。
Table 5 GDB Unsupported Commands
GDB Command | Description |
---|---|
info sharedlibrary | 不显示加载的enclave的状态 |
next/step | 不允许在enclave内部执行下一步到enclave外,要离开enclave,使用结束命令 |
call/print | 不支持从enclave内部调用enclave外部函数,或从不可信区域中调用enclave内部函数 |
charset | 只支持GDB默认字符集 |
gcore | 不支持以应用程序转储文件调试enclave |
sgx-gdb还支持使用enclave内存测量工具测量enclave堆/栈的使用情况。sgx-gdb不支持调试通过sgx_create_enclave_form_buffer_ex API从内存中创建的enclave。
Performance Measurement using Intel® VTune™ Amplifier(使用Intel®VTune™放大器进行性能测量)
仅当enclave作为调试enclave启动时,您可以使用Intel®VTune™放大器来测量enclave代码的性能。
详见手册-24-
Enclave Memory Measurement Tool
Intel®Software Guard Extensions SDK提供了一个名为sgx_emmt的工具,用于测量运行时enclave保护内存的实际使用情况。
目前,enclave内存测量工具提供如下功能。
- 获取enclave的栈峰值使用值。
- 获取enclave的堆峰值使用值。
- 获取enclave的预留内存峰值使用值。
在Linux*操作系统上,enclave内存测量功能是由助手脚本sgx-gdb提供的。sgx-gdb是一个用于调试enclave应用程序的GDB扩展。
要测量一块enclave使用了多少受保护的内存,应该利用sgx-gdb启动sgx_emmt的GDB并且加载正在使用enclave的测试应用。
sgx-gdb提供了与sgx_emmt工具相关的三个命令:
Table 6 Enclave Memory Measurement Tool Commands
Command | Description |
---|---|
enable sgx_emmt | 开启enclave内存测试工具 |
disable sgx_emmt | 关闭enclave内存测试工具 |
show sgx_emmt | 显示enclave内存测试工具是否可用 |
下面是获取一个enclave的内存使用信息的典型步骤:
- 利用sgx_gdb启动一个GDB会话。
- 使用 enable sgx_emmt 开启enclave内存测试功能 。
- 加载并运行使用enclave的测试应用程序。
NOTE:
为了在硬件平台上正确收集enclave的各个峰值,需要确保enclave满足以下条件:
- enclave是可调式的。在enclave配置文件的配置参数应该被置为0。
- enclave以debug调试模式下启用。当调用 sgx_create_enclave去加载enclave时将debug flag置为1。
- 在enclave的版本脚本中导出 g_peak_heap_used 和 g_peak_rsrv_mem_committed。
- 通过使用 sgx_destroy_enclave API销毁enclave。