sgx 的环境配置

环境 : vs2015 dellxps13 win10

dell xps13的sgx需要在bios里面手动打开,intel提供了一个SgxPlatformCapabilityTool可以检测当前是否开启了sgx

开启状态应该是这个样子的:

首先安装intel提供的Intel SGX PSW for Windows和Intel SGX SDK for Windows。sdk安装的时候会给vs2015打上一个插件,有了这个插件,就可以创建sgx的工程了。

创建好的工程应该是这个样子的:

之后就可以在Enclave_test.cpp中写主要的代码了。

这里以一个简单的函数为例:

void hello_from_sgx(char *des)
{
    char *hello = "hello";
    memcpy(des, hello, 1 + strlen(hello));
}

写完函数之后,我们需要在Enclave_test.edl中声明这个函数:

enclave {
    from "sgx_tstdc.edl" import *;

    trusted {
        /* define ECALLs here. */
        public void hello_from_sgx([out,size=6]char *des);
    };

    untrusted {
        /* define OCALLs here. */

    };
};

对于每个指针,sgx都要求开发者给与声明。想这个例子中的out,就是标识这个指针所指的区域是会在函数体里面改变的,而size标识了改变的长度。

之后点击生成,可以看到sgx自动生成的关于这个函数的代码。

static sgx_status_t SGX_CDECL sgx_hello_from_sgx(void* pms)
{
    ms_hello_from_sgx_t* ms = SGX_CAST(ms_hello_from_sgx_t*, pms);
    sgx_status_t status = SGX_SUCCESS;
    char* _tmp_des = ms->ms_des;
    size_t _len_des = 6;
    char* _in_des = NULL;

    CHECK_REF_POINTER(pms, sizeof(ms_hello_from_sgx_t));
    CHECK_UNIQUE_POINTER(_tmp_des, _len_des);

    if (_tmp_des != NULL) {
        if ((_in_des = (char*)malloc(_len_des)) == NULL) {
            status = SGX_ERROR_OUT_OF_MEMORY;
            goto err;
        }

        memset((void*)_in_des, 0, _len_des);
    }
    hello_from_sgx(_in_des);
err:
    if (_in_des) {
        memcpy(_tmp_des, _in_des, _len_des);
        free(_in_des);
    }

    return status;
}

可以看到这里会创建一个临时的_tmp_des,函数运行结束之后会拷贝对应的长度出来。

需要注意的是,如果不填写size属性的话,默认的拷贝长度是sizeof(type)。

我们的sgx工程现在已经编译成功了,那么要怎么才能运行呢?

于是我们需要在当前解决方案中另外创建一个生成可执行文件的工程:

创建工程的过程就和普通的工程一样,创建成功后,我们需要引入刚才编写的sgx:

然后引入我们刚才编写的sgx文件:

引入之后,我们需要先生成一遍刚创建的工程,这样sgx才会在当前工程中自动生成代码。

这样,我们就可以编写我们的代码了:

// APP.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include "Enclave_test_u.h"
#include "sgx_capable.h"
#include "sgx_uae_service.h"
#include "sgx_tcrypto.h"
#include "sgx_urts.h"
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#define ENCLAVE_FILE _T("Enclave_test.signed.dll")
sgx_enclave_id_t enclaveId = NULL;
sgx_launch_token_t token = { 0 };
int updated;
bool initializeEnclave()
{

    if (sgx_create_enclave(ENCLAVE_FILE, SGX_DEBUG_FLAG, &token, &updated,
        &enclaveId, NULL) != SGX_SUCCESS)
        return false;
    return true;
}
bool destroyEnclave()
{
    if (sgx_destroy_enclave(enclaveId) != SGX_SUCCESS)
        return false;
    return true;
}
int main()
{
    sgx_status_t ret = SGX_SUCCESS;
    if (!initializeEnclave())
    {
        printf("init failed!\n");
        return -1;
    }
    char des[20] = { 0 };
    hello_from_sgx(enclaveId, des);
    printf("%s", des);
    if (!destroyEnclave())
    {
        printf("failed to destory sgx\n");
        return -1;
    }
    system("pause");
    return 0;
}

编写完成之后,将这个项目设为启动项目,点击生成,之后再把调试器改为:

当然这时候还是不能允许,因为生成dll的目录不是工程目录,所以需要在调试选项里将改变一下工作目录:

这时候应该就可以愉快的运行了~

发表评论

电子邮件地址不会被公开。 必填项已用*标注