SGX性能实验

时间:2023-01-11 16:24:09

SGX实验报告​

一.实验目标​

了解采用SGX可信任环境后对应用和目标主机产生的性能影响有多少。

二.实验准备​

Microsoft Window10 21H2版本主机一台,

处理器:Intel Core(TM)i5-9500F ​​CPU@3.00GHZ​​

64位操作系统,内存16GB

SGX性能实验


代码编译环境:vs2015专业版或者Clion2021

SGX性能实验


SGX插件相关版本

Intel ME版本:ME_SW_1909.12.0.1237

SDK版本:Intel SGX SDK for Windows v2.12.100.4

PSW版本:Intel SGX PSW for Windows v2.12.100.4

三.实验过程​

3.1 不使用SGX插件运行相关计算程序​

小程序:计算一万以内的素数,(循环10000次)

程序源码:

  1. //
  2. // Created by hudengfeng on 2023/1/9.
  3. //
  4. #include <iostream>
  5. #include <time.h>
  6. using namespace std;

  7. // 计算10000以内的素数
  8. void calculate_prime(){
  9. int i,j,k=0;//i是2-10000待确认是否为素数的数,j表示i的因子,k表示素数的个数
  10. for(i=2;i<10000;i++){
  11. for(j=2;j*j<=i;j++){
  12. if(i%j==0)//判断i是否能被1和本身以外的数整除,%表示求余
  13. break;//break跳出第二个for循环
  14. }
  15. if(j*j>i){
  16. cout<<i<<" ";
  17. k++;//每增加一个素数k就加1
  18. if(k%10==0) //一行打印10个数之后换行
  19. {
  20. cout<<endl;
  21. }
  22. }
  23. }
  24. }
  25. void exe(){
  26. clock_t start, finish;
  27. double duration;
  28. start = clock();
  29. for (int j = 0; j < 10000; ++j) {
  30. calculate_prime();
  31. }
  32. finish = clock();
  33. duration = (double)(finish - start) / CLOCKS_PER_SEC;
  34. cout<<endl;
  35. cout<<"计算累计用时:"<<duration<<"秒"<<endl;
  36. }

  37. int main(){
  38. // cout << "hello world!"<<endl;
  39. exe();
  40. return 0;
  41. }

正常情况cpu使用率:20%(均值)

SGX性能实验


运行程序cpu使用率:70%(均值)

SGX性能实验


代码运行结果(10次)

SGX性能实验


11.732s、13.635s、16.017s、12.544s、14.327s

11.515s、14.301s、12.988s、15.251s、12.677s

均值:13.499s


3.2 使用SGX插件运行相关计算程序​

基本原理:

SGX性能实验


SGX程序分为两部分,一部分是app应用,也就是不可信区,一部分是enclave应用,也就是可信区,非可信区只能通过 ECALL 函数调用可信区内的函数,可信区只能通过 OCALL 函数调用非可信区的函数,ECALL 函数和 OCALL 函数通过 EDL 文件声明。

程序目录结构:

SGX性能实验


App 目录内为不可信区域代码,包括 main 入口、OCALL 函数内具体逻辑代码等等。

Enclave 目录为可信区域代码,包括 ECALL 函数内具体逻辑代码实现。

Enclave.lds:EDL(Enclave Description Language) 文件。

Enclave_private.pem:enclave.so 的签名私钥。

Enclave.config.xml:Enclave 配置文件,如堆栈大小、是否等。

Enclave.h & Enclave.cpp:应用安全区代码实现。

Include目录是不可信代码和可信代码共享的头文件。

在app程序中通过ecall函数调用enclave程序的calculate函数来计算结果,然后把计算的结果通过ocall函数返回给app程序,然后app程序把结果打印出来。

编译运行:

1.通过 sgx_edger8r 工具在 App/ 目录下生成不可信代码(Enclave_u.c 和 Enclave_u.h),这部分生成代码主要会调用 ECALL (sgx_ecall);

2.编译不可信部分 Binary: app;

3.通过sgx_edger8r 工具在 Enclave/ 目录下生成可信代码(Enclave_t.c 和 Enclave_t.h);

4.编译可信动态链接库(enclave.so);

5.通过sgx_sing工具签名可信动态链接库(enclave.signed.so);

6.结束。

编译后的代码目录结构:

SGX性能实验


实验结果:

正常情况cpu使用率:20%(均值)

SGX性能实验


运行程序cpu使用率:80%(均值)

SGX性能实验


代码运行结果(10次)

SGX性能实验


17.496s、12.854s、14.327s、15.635s、14.324s

12.432s、11.543s、15.398s、18.534s、13.264s

均值:14.580s

3.3 enclave安全区多次切换​

核心程序源码:

App.cpp

  1. #include <stdio.h>
  2. #include <string.h>
  3. #include <assert.h>
  4. #include <time.h>
  5. # include <unistd.h>
  6. # include <pwd.h>
  7. # define MAX_PATH FILENAME_MAX

  8. #include "sgx_urts.h"
  9. #include "App.h"
  10. #include "Enclave_u.h"
  11. using namespace std;
  12. /* Global EID shared by multiple threads */
  13. sgx_enclave_id_t global_eid = 0;

  14. int initialize_enclave(void)
  15. {
  16. sgx_status_t ret = SGX_ERROR_UNEXPECTED;

  17. /* 调用 sgx_create_enclave 创建一个 Enclave 实例 */
  18. /* Debug Support: set 2nd parameter to 1 */
  19. ret = sgx_create_enclave(ENCLAVE_FILENAME, SGX_DEBUG_FLAG, NULL, NULL, &global_eid, NULL);
  20. if (ret != SGX_SUCCESS) {
  21. printf("Failed to create enclave, ret code: %d\n", ret);
  22. return -1;
  23. }

  24. return 0;
  25. }

  26. /* 应用程序入口 */
  27. int SGX_CDECL main(int argc, char *argv[])
  28. {
  29. (void)(argc);
  30. (void)(argv);

  31. clock_t start, finish;
  32. double duration;
  33. start = clock();


  34. /* 创建并初始化 Enclave */
  35. if(initialize_enclave() < 0){
  36. printf("Enter a character before exit ...\n");
  37. getchar();
  38. return -1;
  39. }

  40. /* ECALL 调用 */
  41. /*计算10000以内的素数*/
  42. for (int i = 0; i < 10; ++i) {
  43. ecall_calculate_from_enclave(global_eid);
  44. }
  45. finish = clock();
  46. duration = (double)(finish - start) / CLOCKS_PER_SEC;
  47. cout<<"计算累计用时:"<<duration<<"秒"<<endl;
  48. /* 销毁 Enclave */
  49. sgx_destroy_enclave(global_eid);

  50. printf("Info: SampleEnclave successfully returned.\n");

  51. printf("Enter a character before exit ...\n");
  52. getchar();
  53. return 0;
  54. }

Enclave.cpp

  1. void ecall_calculate_from_enclave(){
  2. for (int j = 0; j < 1000; ++j) {
  3. calculate_prime();
  4. }
  5. }

由以上App.cpp(51-53行)程序可以看出,还是计算10000以内的素数(10000次),但是Enclave.cpp当中只计算了1000次。app.cpp当中有10次循环调用ecall函数

实验结果:

正常情况cpu使用率:20%(均值)

SGX性能实验


运行程序cpu使用率:84%(均值)

SGX性能实验


代码运行结果(10次)

SGX性能实验


22.065s、24.905s、25.687s、21.522s、18.417s

21.592s、20.666s、21.845s、21.499s、18.457s

均值:21.666s


3.4 enclave的epc内存测试​


首先修改编译器设置,默认堆栈区大小是1M,如果不想使用堆栈,可在全局区使用大数组,前面加上static即可。需要在图形化界面修改堆栈保留大小这个字段。单位是bit,这里改成256MB,也就是256*1024*1024*8。也可在CMakeLists.txt添加下面2行,就可以达到修改堆栈内存大小的效果。

MATH(EXPR stack_size "256*1024*1024")单位是字节

set(CMAKE_EXE_LINKER_FLAGS "-Wl,--stack,${stack_size}")

也可通过图形化界面修改,在vs2015在项目的属性,找到链接器的系统这一栏,

SGX性能实验


3.4.1 不使用enclave单独跑带有大数组的程序​

在3.4.1执行函数中新增代码(5-10行)

  1. void exe(){
  2. clock_t start, finish;
  3. double duration;
  4. start = clock();
  5. int a[4096][4096] = {0};
  6. int b[4096][4096] = {1};
  7. a[0][0] = 1;
  8. size_t num = sizeof(a);
  9. a[0][1] = num;
  10. b[0][0] = a[0][1];
  11. for (int j = 0; j < 10000; ++j) {
  12. calculate_prime();
  13. }
  14. finish = clock();
  15. duration = (double)(finish - start) / CLOCKS_PER_SEC;
  16. cout<<endl;
  17. cout<<"计算累计用时:"<<duration<<"秒"<<endl;
  18. }

申请了一个两个4096*4096的int类型大数组,初始化值为0,一个大数组内存应该是4*4*4=96MB,两个是192MB,超过了128MB,然后开始跑程序。






实验结果:

正常情况cpu使用率:20%(均值)

SGX性能实验




运行代码程序后cpu使用率:84%(均值)

SGX性能实验



代码运行结果(10次)

SGX性能实验


17.744s、16.946s、20.974s、17.409s、17.022s

20.746s、16.785s、21.114s、18.742s、18.965s

均值:18.645s

3.4.2 使用enclave跑带有大数组的程序​

将上述带有大数组的代码复制到Enclave.cpp当中(写在循环外面),

核心代码:

  1. void ecall_calculate_from_enclave(){
  2. int a[4096][4096] = {0};
  3. int b[4096][4096] = {1};
  4. a[0][0] = 1;
  5. size_t num = sizeof(a);
  6. a[0][1] = num;
  7. b[0][0] = a[0][1];
  8. for (int j = 0; j < 10000; ++j) {
  9. calculate_prime();
  10. }
  11. }




实验结果:

正常情况cpu使用率:20%(均值)

SGX性能实验



运行代码程序后cpu使用率:90%(均值)

SGX性能实验


代码运行结果(10次)

SGX性能实验


26.264s、26.043s、24.434s、28.206s、23.204s

22.236s、26.238s、25.232s、23.364s、24.652s

均值:24.987s


四.实验结论​

通过上述实验可以发现使用SGX安全插件的app应用来计算10000以内的素数(10000次)用的时间比不使用插件要多,cpu使用率也要高一些,但是性能损耗在5%到10%之间,性能损耗可以接受。如果频繁使用ecall函数或者ocall函数,在可信区和非可信区之间进行切换,会有比较明显的性能消耗,性能损耗在20%以上。当epc内存过大也会明显影响主机的性能。性能损耗20%以上。