本文中,我们介绍在Enclave函数中调用不可信OCALL函数,并获得OCALL函数的返回值。

1. 复制SampleEnclave示例并建立自己的OcallRetSum项目

SampleEnclave示例实现了安全printf函数,可以被用来安全打印我们需要打印的字符串。我们使用OCALL计算两个整数之间的所有整数的累加和(包括这两个整数),并调用printf函数打印复制的目的字符串。我们把SampleEnclave示例复制到自己的文件夹中,基于该示例,我们开发一个在Enclave函数中调用OCALL函数计算两个整数之间的所有整数的累加和(包括这两个整数)。我们把复制得到的SampleEnclave文件夹名称改成OcallRetSum文件夹。

将文件中的冗余文件删除仅剩下图目录

2. 各个文件内容介绍

2.1 App文件夹

该文件夹存放应用程序中的不可信代码部分,共有2个文件和2个文件夹,App.cpp文件、App.h文件、Edger8rSyntax文件夹和TrustedLibrary文件夹

  • App.cpp文件:该文件是应用程序中的不可信部分代码,其中包括了创建Enclave及销毁Enclave的代码,也定义了一些相关的返回码供使用者查看Enclave程序的执行状态。其中的main函数是整个项目的入口函数。是我们要修改的文件。

  • App.h文件:该文件是应用程序中的不可信部分代码的头文件,定义了一些宏常量和函数声明。我们不用进行更改。

  • Edger8rSyntax文件夹:该文件夹提供了一些工具,我们不用进行更改。

  • TrustedLibrary文件夹:该文件夹提供了一些函数库,我们不用进行更改。、

2.2 Enclave文件夹

该文件夹存放应用程序中的可信代码部分和可信与不可信代码接口文件,共有6个文件和2个文件夹,Enclave.config.xml文件、Enclave.cpp文件、Enclave.h文件、Enclave.edl文件、Enclave.lds文件、Enclave_private.pem文件、Edger8rSyntax文件夹和TrustedLibrary文件夹

  • Enclave.config.xml文件:该文件是Enclave的配置文件,定义了Enclave的元数据信息,我们可以不用更改。

  • Enclave.cpp文件:该文件是应用程序中的可信部分代码,包括了可信函数的实现,是我们要修改的文件。

  • Enclave.h文件:该文件是应用程序中的可信部分代码的头文件,定义了一些宏常量和函数声明。是我们要修改的文件。

  • Enclave.edl文件:该文件是Enclave的接口定义文件,定义了不可信代码调用可信代码的ECALL函数接口和可信代码调用不可信代码的OECALL函数接口,trusted{}中定义了ECALL函数接口,untrusted{}中定义了OECALL函数接口是我们要修改的文件。

  • Enclave.lds文件:该文件定义了一些Enclave可执行文件信息,我们不用更改。

  • Enclave_private.pem文件:该文件是SGX生成的私钥,我们不用更改。

  • Edger8rSyntax文件夹:该文件夹提供了一些工具,我们不用进行更改。

  • TrustedLibrary文件夹:该文件夹提供了一些函数库,我们不用进行更改。

2.3 Include文件夹

该文件夹存放被Enclave接口定义文件Enclave.edl使用的头文件,包括一些宏定义,我们不用管它。共只有一个user_types.h文件。

  • user_types.h文件:该文件定义了用户自定义的类型。

2.4 Makefile文件

该文件是项目的编译文件,定义了项目的编译信息,详细说明还请参考http://blog.csdn.net/daichunkai123/article/details/78027895。是需要修改的部分。

3. 改写代码

需要修改的文件问为Enclave.edl文件、Enclave.cpp文件、Enclave.h文件、App.cpp文件和Makefile文件

3.1 Enclave.edl文件修改

我们要在Enclave.edl文件中定义不可信代码调用可信函数的ECALL接口,比如我们定义的可信函数是ecall_myretsum,在该函数中我们调用OCALL函数ocall_retsum计算两个整数之间的所有整数累加和,该函数没有参数也没有返回值。

但是定义的可信函数式ocall_retsum时,该函数有2个参数:起始整数start和结束整数end。该函数有一个整数返回值。

3.1.1 添加ECALL函数ecall_myretsum,将以下代码添加到Enclave.edl文件中的untrusted{}之前。

trusted{
public void ecall_myretsum();
};

同时因为需要start和end参数的返回值,还将下列代码添加到``untrusted{}`中

size_t ocall_retsum(size_t start, size_t end);

3.1.2 修改后的Enclave.edl文件如下所示

enclave {

    include "user_types.h" /* buffer_t */

    /* Import ECALL/OCALL from sub-directory EDLs.
* [from]: specifies the location of EDL file.
* [import]: specifies the functions to import,
* [*]: implies to import all functions.
*/ from "Edger8rSyntax/Types.edl" import *;
from "Edger8rSyntax/Pointers.edl" import *;
from "Edger8rSyntax/Arrays.edl" import *;
from "Edger8rSyntax/Functions.edl" import *; from "TrustedLibrary/Libc.edl" import *;
from "TrustedLibrary/Libcxx.edl" import ecall_exception, ecall_map;
from "TrustedLibrary/Thread.edl" import *; /*
* ocall_print_string - invokes OCALL to display string buffer inside the enclave.
* [in]: copy the string buffer to App outside.
* [string]: specifies 'str' is a NULL terminated buffer.
*/ trusted{
public void ecall_myretsum();
}; untrusted {
void ocall_print_string([in, string] const char *str);
size_t ocall_retsum(size_t start, size_t end);
}; };

3.2 Enclave.cpp文件修改

在Enclave.cpp文件中实现ecall_myretsum函数,该函数比较简单,就是定义两个整数参数和一个存储返回值的整数变量,并调用OCALL函数ocall_retsum计算累加和,获得计算结果,然后调用printf函数打印计算的累加和。

这个地方需要注意的是:获得OCALL函数的返回值和获得普通的C/C++函数的返回值是不一样的,获得C/C++函数的返回值可以直接通过赋值得到,但是获得OCALL函数的返回值需要把存储返回值的变量的地址传给Enclave函数,OCALL函数执行完之后,SGX会把返回值复制到地址参数指向的内存地址处,从而将返回值返回给想返回的变量。

事实上,在SGX中,OCALL函数执行时是有返回值的,返回的是该函数执行的状态,可以通过赋值获得OCALL函数执行的状态,从而判断有没有正确执行。

3.2.1 将以下代码添加到Enclave.cpp文件中

void ecall_myretsum()
{
    size_t start = 5;
    size_t end = 10;
    size_t sum = 0;     ocall_retsum(&sum,start, end);
    printf("%d\n", sum);
}

3.2.2 修改后的Enclave.cpp文件如下所示

#include "Enclave.h"
#include "Enclave_t.h" /* print_string */
#include <stdarg.h>
#include <stdio.h> /* vsnprintf */
#include <string.h> /*
* printf:
* Invokes OCALL to display the enclave buffer to the terminal.
*/
int printf(const char* fmt, ...)
{
char buf[BUFSIZ] = { '\0' };
va_list ap;
va_start(ap, fmt);
vsnprintf(buf, BUFSIZ, fmt, ap);
va_end(ap);
ocall_print_string(buf);
return (int)strnlen(buf, BUFSIZ - 1) + 1;
} void ecall_myretsum()
{
    size_t start = 5;
    size_t end = 10;
    size_t sum = 0;     ocall_retsum(&sum,start, end);
    printf("%d\n", sum);
}

3.3 Enclave.h文件修改

我们在Enclave.h文件中添加ecall_myretsum函数声明,该文件修改比较简单。

3.3.1将以下代码添加到Enclave.h文件中

void ecall_myretsum();

3.3.2 修改后的Enclave.h文件如下所示

#ifndef _ENCLAVE_H_
#define _ENCLAVE_H_ #include <stdlib.h>
#include <assert.h> #if defined(__cplusplus)
extern "C" {
#endif void printf(const char *fmt, ...);
void ecall_myretsum(); #if defined(__cplusplus)
}
#endif #endif /* !_ENCLAVE_H_ */

3.4 App.cpp文件修改

我们在该文件中调用自定义的OCALL函数ocall_retsum并调用自定义的ECALL函数ecall_myretsum。

3.4.1 修改main函数

由于我们不需要Edger8rSyntax和TrustedLibrary相关的函数调用,所以我们把main函数中与这两部分相关的函数调用删除,也就是把下面部分删除:

/* Utilize edger8r attributes */
edger8r_array_attributes();
edger8r_pointer_attributes();
edger8r_type_attributes();
edger8r_function_attributes(); /* Utilize trusted libraries */
ecall_libc_functions();
ecall_libcxx_functions();
ecall_thread_functions();

3.4.2 main函数中插入函数调用

在main函数之前插入OCALL函数ocall_retsum的实现,该函数计算两个整数之间的所有整数的累加和(包括这两个整数),并返回计算的累加值。即将以下代码插入到main函数之前

size_t ocall_retsum(size_t start, size_t end){  
    size_t sum = 0;  
    for (; start <= end; start++)  
        sum += start;  
    return sum;  
}

在main函数中的Enclave创建和销毁之间插入我们定义的ecall_myretsum函数的调用代码,也就是把以下代码放到sgx_destroy_enclave(global_eid);之前。global_eid参数是必须的,是enclave的id。

ecall_myretsum(global_eid);

3.4.3 删除无关代码

我们也可以将main函数后面的无关代码给删了,也就是删除以下代码。

printf("Info: SampleEnclave successfully returned.\n");
printf("Enter a character before exit ...\n");
getchar();

修改后的main函数及其之前如下所示

size_t ocall_retsum(size_t start, size_t end){  
    size_t sum = 0;  
    for (; start <= end; start++)  
        sum += start;  
    return sum;  
} /* Application entry */
int SGX_CDECL main(int argc, char *argv[])
{
(void)(argc);
(void)(argv); /* Initialize the enclave */
if(initialize_enclave() < 0){
printf("Enter a character before exit ...\n");
getchar();
return -1;
} ecall_myretsum(global_eid);
/* Destroy the enclave */
sgx_destroy_enclave(global_eid); return 0;
}

3.5 Makefile文件修改

我们在Makefile文件中修改编译相关的信息。主要更改

SGX_SDK ?= /opt/intel/sgxsdk
App_Cpp_Files := App/App.cpp $(wildcard App/Edger8rSyntax/*.cpp) $(wildcard App/TrustedLibrary/*.cpp) Enclave_Cpp_Files := Enclave/Enclave.cpp $(wildcard Enclave/Edger8rSyntax/*.cpp) $(wildcard Enclave/TrustedLibrary/*.cpp)

3.5.1 修改SGX SDK路径

如果SGX SDK路径不是/opt/intel/sgxsdk,要将其改成为所在目录下/home/zjz/sgxsdk,

3.5.2 修改不可信代码编译的源文件

由于我们的不可信代码可能是多个文件,因此,我们最好在App_Cpp_Files中包括App文件夹中的所有cpp文件,更改后的结果如下。本项目中App_Cpp_Files可以不用更改。

3.5.3 修改可信代码编译的源文件

由于我们的可信代码可能是多个文件,因此,我们最好在Enclave_Cpp_Files中包括App文件夹中的所有cpp文件,更改后的结果如下。本项目中Enclave_Cpp_Files可以不用更改。

4. 编译文件

打开文件下的终端输入make

5. 运行程序

执行 ./app 运行程序

其中遇到一个lib库的问题 使用export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/zjz/sgxsdk/lib64 解决后重新运行

最终成功输出两数之和为45

Ubuntu 18.04下Intel SGX应用程序程序开发——获得OCALL调用的返回值的更多相关文章

  1. Ubuntu 18.04 下配置 HAXM 加速 Android模拟器

    Ubuntu 18.04 下配置 HAXM 加速 Android模拟器 最近在vmware环境下搭建ubuntu18.04开发环境,开始发现总是运行android模拟器在console提示加载如下错误 ...

  2. Ubuntu 18.04 下 emscripten SDK 的安装

    Ubuntu 18.04 下 emscripten SDK 的安装http://kripken.github.io/emscripten-site/docs/getting_started/downl ...

  3. Ubuntu 18.04下安装Steam顶级在线游戏平台

    Ubuntu 18.04下安装Steam顶级在线游戏平台 原创: 聆听世界的鱼 Linux公社 今天 Steam是由Valve公司开发的顶级在线游戏平台,是目前全球最大的综合性数字发行平台之一.它让你 ...

  4. 在Ubuntu 18.04 下安装mysql,没有初始密码,重设root密码

    在Ubuntu 18.04 下安装mysql 不知道是由于mysql更新为新版还是.Ubuntu18.04中的特性,安装过程中没有设置密码的环节,在网络上找了半天,总算解决了!特此记录下来,以便以后查 ...

  5. ubuntu 18.04下Chromium设置为系统代理

    前言 在ubuntu 18.04下挂上ss后firefox能直接上google了但是chromium上不去 会出现下面两种情况 # This site can't be reached xxxxxx ...

  6. Ubuntu 18.04下Couldn't connect to Docker daemon at http+docker://localunixsocket解决办法

    一台服务器系统为:Ubuntu 18.04 LTS,上面建了git裸仓库,用于开发吧代码push到这里.同时WEB测试环境通过docker也部署在这台.通过git钩子post-receive,当有新代 ...

  7. 在ubuntu 18.04下,无线网卡无驱动,连不上wifi,显示wifi没有适配器的解决方法

    近来因为做东西要用到linux环境,所以自己的笔记本在win10的系统上又安装了ubuntu 18.04版本的双系统,但是安装好以后,没有无线网卡的驱动,显示wifi没有适配器等字样,很纠结,前后研究 ...

  8. ubuntu 18.04下编译最新版本的KMS

    KMS:kurento媒体服务,即 kurento media server 很庞大的一个WEBRTC项目,GIT库主项目:https://github.com/Kurento 基础实现,修改了gst ...

  9. 在 Ubuntu 18.04 下安装 fcitx 及搜狗拼音输入法

    感觉自己傻逼透了,之前在 16.04 时折腾着要装 ibus 和 rime 输入法,现在 18.04 默认安装 ibus 了,又因为 rime 的智能联想太弱,打字不爽,又想装回搜狗一劳永逸... 环 ...

随机推荐

  1. fiddler抓包+安卓机 完成手机app抓包的配置 遇到的一些问题

    fiddler抓包+安卓模拟器完成手机app抓包的配置:fiddler抓包+雷电模拟器 完成手机app抓包的配置 其实在安卓真机上弄比在虚拟机上弄更麻烦一点,它们的步骤都差不多一样,就是在安卓真机上弄 ...

  2. 牛客编程巅峰赛S1第6场 - 黄金&钻石&王者 B.牛牛摆放花 (贪心)

    题意;将一组数重新排序,使得相邻两个数之间的最大差值最小. 题解:贪心,现将所有数sort一下,然后正向遍历,将数分配到新数组的两端,然后再遍历一次维护一个最大值即可. 代码: class Solut ...

  3. windows下进程间通信方法

    摘 要 随着人们对应用程序的要求越来越高,单进程应用在许多场合已不能满足人们的要求.编写多进程/多线程程序成为现代程序设计的一个重要特点,在多进程程序设计中,进程间的通信是不可避免的.Microsof ...

  4. python爬虫笔记Day01

    python爬虫笔记第一天 Requests库的安装 先在cmd中pip install requests 再打开Python IDM写入import requests 完成requests在.py文 ...

  5. K8S(16)集成实战-使用spinnaker进行自动化部署

    K8s集成实战-使用spinnaker进行自动化部署 1 spinnaker概述和选型 1.1 概述 1.1.1 主要功能 Spinnaker是一个开源的多云持续交付平台,提供快速.可靠.稳定的软件变 ...

  6. Leetcode(257)-二叉树的所有路径

    给定一个二叉树,返回所有从根节点到叶子节点的路径. 说明: 叶子节点是指没有子节点的节点. 示例: 输入: 1 / \ 2 3 \ 5 输出: ["1->2->5", ...

  7. 关于st表的推导

    #include <bits/stdc++.h> using namespace std; const int maxn=1e6+7; int st[maxn][32]; int a[ma ...

  8. 卧槽,sql注入竟然把我们的系统搞挂了

    前言 最近我在整理安全漏洞相关问题,准备在公司做一次分享.恰好,这段时间团队发现了一个sql注入漏洞:在一个公共的分页功能中,排序字段作为入参,前端页面可以自定义.在分页sql的mybatis map ...

  9. cheerio & jQuery for server

    cheerio & jQuery for server Fast, flexible & lean implementation of core jQuery designed spe ...

  10. .dmg & .pkg & .ipa

    .dmg & .pkg & .ipa Apple, macOS, iOS .dmg mysql-8.0.21-macos10.15-x86_64.dmg https://dev.mys ...