SGX开发特点

与传统的C++程序开发不同,SGX应用程序会分为两块,一块是执行在Enclave中的代码,一块是执行在普通环境中的代码。此外,需要在.edl文件中的trusted标记中写上在Enclave中执行的函数的声明,在untrusted标记中写上在普通环境中执行的函数的声明。

SgxEdger8r(SGX Edge Routine,主要用于在编译过程中对.edl文件中的ecall和ocall重新封装编写,即将用户编写的e/ocall改写成实际执行的e/ocall)工具会在应用程序编译过程中根据edl文件将可信与不可信函数声明重新封装成给Enclave环境、普通环境下代码所调用的桥函数,实现两种环境之间的切换。如普通环境下代码调用桥函数会进而通过sgx_ecall进入Enclave环境,Enclave环境下代码调用桥函数进而通过sgx_ocall进入普通环境,其中调用sgx_e/ocall的代码由SgxEdger8r根据用户编写在edl文件中trusted/untrusted标记下的函数声明来自动生成,即具体的进出Enclave代码不需要用户来实现,只需要打上标记即可。

环境切换步骤如下:第一步,通过工具生成的桥函数会调用sgx_ecall、sgx-ocall进而调用硬件指令来切换环境;第二步,由于那些打上标记的函数本身有用户定义的执行代码,因此在切换环境后会进入真正的函数定义。举个例子,Main()->不可信环境ECALL_A()->sgx_ecall()->EENTER->可信环境ECALL_A()。

总而言之,这些打上标记的函数声明会最终由SgxEdger8r工具在编译过程中改造成桥函数,用于切换环境,然后执行函数声明对应的函数定义。

此外在普通环境中的代码需要显式地管理Enclave的生命周期,如调用“创建初始化Enclave的函数”之后才能调用Enclave中的函数,最后需要调用“销毁Enclave的函数”。

如果想要将在普通环境和Enclave环境中传递一个“指向缓冲区的指针”等参数,需要在.edl文件的函数形参前面声明如[in]、[out]等参数标记,这是因为普通环境的内存往往是不可信的,通过比如将普通环境下的缓冲区拷贝一份到Enclave环境中,然后Enclave代码在拷贝进Enclave的缓冲区上进行操作等才是放心的,不会中途被恶意篡改等,最后可能再拷贝到普通环境供普通环境下的程序使用(具体见下文“SGX参数”章节)。

桥函数总结

通过上文的引入,现在总结一下桥函数:桥函数是指在SGX平台下,唯一能够切换可信环境与不可信环境的方式,调用硬件指令ENCLU中的EENTER、EEXIT来具体实现,是由SgxEdger8r工具来生成。

代码层面的环境切换过程大概是这样,以传统Switch模式ecall为例(这种模式便于理解,另一种Switchless模式Ecall见“SGX Switch模式及Switchless模式”章节):

不可信环境->假装调用由用户定义的ecall函数->对应的桥函数(SGX Edger8r重新封装的)>sgx_ecall()->_sgx_ecall()->CEnclave::ecall()->do_ecall()->enter_enclave()->__morestack(汇编)->ENCLU(调用硬件指令)->切换到tRTS->可信环境->enclave_entry(汇编)->enter_encalve()->do_ecall()->trts_ecall()->真正调用由用户定义的ecall函数。

SGX参数及函数属性

SGX将参数从不可信环境传入可信环境的方法是将保存在不可信环境的栈上的参数拷贝到寄存器,EENTER叶功能会将不可信环境的RSP、RBP保存到SSA结构中,并完成地址的切换进入可信环境。

这里将描述.edl文件中的SGX桥函数(接口)中参数或函数的修饰符说明,用来具体说明函数传参或函数声明的具体属性。ECALL为例子,OCALL类似。

  • public void ecall_array_user_check([user_check] int arr[4]);

这里是对函数传参属性的说明,下同。

[user_check]:Enclave程序使用数组时该数组不会被验证、数组对应缓冲区不会拷贝到Enclave内存中,Enclave可以直接修改应用程序中数组对应的缓冲区。(这个例子中参数为数组,指针类似)

  • public void ecall_array_in([in] int arr[4]);

[in]:Enclave会在内部分配相同大小的缓冲区,外部缓冲区的内容被拷贝到内部缓冲区,内部缓冲区内容修改不会导致(不影响)外部缓冲区任何变化。

  • public void ecall_array_out([out] int arr[4]);

[out]:内部缓冲区的修改在函数返回时拷贝到外部缓冲区。

  • public void ecall_array_in_out([in, out] int arr[4]);

[in, out]:Enclave内部会分配一个缓冲区,将数组缓冲区拷贝进来,同时在函数返回时,将内部缓冲区内容拷贝到外部缓冲区,双向。也就说缓冲区的改造过程被隐藏了,外部应用程序只能知道函数的输入输出。

  • public void ecall_array_isary([user_check, isary] array_t arr);

[isary]:告诉Edger8r用户自定义结构体array_t的变量是一个数组。

  • public void ecall_pointer_string([in, out, string] char *str);

[string]:告诉Edger8r,变量str参数是一个NULL结尾的字符串。可以用于strlen等功能。

  • public void ecall_pointer_string_const([in, string] const char *str);

const:说明字符串str不可修改,所以不适用[out]属性。

  • public void ecall_pointer_size([in, out, size=len] void *ptr, size_t len);

[size]:告诉Edger8r ptr对应的缓冲区的字节数。不能对[string]属性施加[size]属性。

  • public void ecall_pointer_count([in, out, count=cnt] int *arr, size_t cnt);

[count]:告诉Edger8r需要拷贝的arr的长度。

  • public void ecall_pointer_isptr_readonly([in, isptr, readonly, size=len] buffer_t buf, size_t len);

[isptr]:告诉Edger8r自定义类型是一个指针。

[readonly]:禁止Enclave内部分配的缓冲区被拷贝到外部去,因此不能与[out]同时使用。

  • public void ecall_function_public(void);

这里是对函数声明属性的描述,下同。

[public]:外部可以直接调用该Ecall

  • int ecall_function_private(void);

[private]:默认,外部不可以直接调用该Ocall,除非有Ocall调用这个Ecall并且是[allow]属性

  • void ocall_function_allow(void) allow(ecall_function_private);

[allow]:允许OCALL在外部调用[private] ECALL。

SGX Switch模式及Switchless模式

(可以见博客——ECALL Switch模式和ECALL Switchless模式)

由上文可见,SGX是通过Ecall来进入Enclave环境,类似的,通过Ocall离开Enclave环境。关于Ecall效率方面,传统的Switch模式,应用程序对应的线程(该进程只有一个Main线程)会切换进入Enclave环境,然后拿上它在Enclave环境的“工作证”,也就是绑定上TCS这个结构体,进行具体的用户定义的Ecall函数的执行。

但是这种模式,只能使用一个线程来完成具体任务(我们将这种调用用户定义的Ecall函数称为Ecall任务,此外还有Ocall任务),效率很低,同时还有伴随开销,比如进入Enclave环境需要拿起TCS“工作证”。因为目前还不支持unix的线程库,因此在Enclave中不支持创建线程,只能支持互斥量、条件变量等的维护(用于外部应用程序创建多个线程分别进入Enclave的场景),目前不支持线程库的原因是一方面Enclave程序旨在保护敏感代码,而远不需要创建线程等功能,另一方面出于数据依赖性、安全性等考量。

为了提高效率问题,定义了Switchless模式,如图9所示。以Ecall为例,uRTS为外部应用程序提供了Ecall任务池,以及联合tRTS初始化了多个可信Worker线程来具体执行Ecall任务。举例来说,外部应用程序调用了Ecall_A、Ecall_B,Switch做法是只有一个线程,它执行Ecall_A之后后回到不可信环境继而执行Ecall_B,是一种上下文环境切换的概念;Switchless做法是构建好Ecall Table管理器保存可能执行的Ecall函数,同时构建一个任务池用于记录每个Ecall具体执行的先后顺序,uRTS线程会唤醒空闲的可信Worker线程从任务池中取任务,然后查询Call Table,进而完成具体任务,因此省去了上下文环境切换的开销。Ocall方向的类似。

图9:Switchless模式调用架构

SGX软硬件栈(四)——桥函数相关推荐

  1. c语言的四个函数,C语言学习之动态内存分配的四个函数

    前面中我们了解到: int n; int arr[n]; 这样定义数组是不可取的,不能用此方法给数组分配动态内存,那怎么样才能实现这种可能呢? 接下来我将关于动态内存的知识做以下总结. 有关动态内存的 ...

  2. python-笔记(四)函数

    一.函数是什么? 函数一次来源于数学,但是编程中的[函数]的概念,与数学中的函数还是有很大的不同的,编程中的函数在英文中也有很多不同的叫法. 在Basic中叫做subroutine(子过程或子程序), ...

  3. Java内置函数的理解和加减乘除四个函数的学习

    arraycopy为System类自带的函数,可以通过Systems.arraycopy(-)这种形式直接调用. 以下为arraycopy的解释,请自行理解,填写下段代码的空行. public sta ...

  4. Java数据结构 栈中添加辅助栈实现min函数

    栈中添加辅助栈实现min函数 class MinStack {Stack<Integer> A, B;public MinStack() {A = new Stack<>(); ...

  5. 在OpenCV环境下写的灰度图像二维傅里叶换,幅值计算,频谱平移和将数值归一化到0到255区间的四个函数

    图像处理开发需求.图像处理接私活挣零花钱,请加微信/QQ 2487872782 图像处理开发资料.图像处理技术交流请加QQ群,群号 271891601 灰度图像的二维傅里叶变换(cv_gray_fft ...

  6. 表格序号_如何让表格序号自动更新,四个函数让表格实现自动化、高效操作

    工作中我们使用Excel登记数据的时候经常会碰到个问题,当我们在原始数据删除.隐藏行后,都需要重新更新一次表格序号.今天我们就来学习一下,如何解决表格自动更新序号的问题. 案例演示: 案例说明:如上图 ...

  7. 数据结构实验之栈四:括号匹配

     数据结构实验之栈四:括号匹配 Description 给你一串字符,不超过50个字符,可能包括括号.数字.字母.标点符号.空格,你的任务是检查这一串字符中的( ) ,[ ],{ }是否匹配. Inp ...

  8. sdut 数据结构实验之栈四:括号匹配

    数据结构实验之栈四:括号匹配 Time Limit: 1000MS Memory Limit: 65536KB Submit Statistic Discuss Problem Description ...

  9. matlab求解一元四次函数,excel数据函数参数是四个吗|求一个简单的一元四次函数的最大值...

    求四次函数的最值 先求导,令导数等于0,求出x的值,判断单调性,将x代入原函数 4次幂的一元函数怎么计算 解析: (1) 四次方程,有通用求根公式. A 此公式复杂,实际使用较麻烦 B 其推导过程中可 ...

  10. 家乡 二 十 四 桥的介绍

    二 十 四 桥 "青山隐隐水迢迢,秋尽江南草未凋.二十四桥明月夜,玉人何处教吹箫".这首诗已流传了一千多年,可谓妇孺皆知.诗因桥而咏出,桥因诗而闻名.单项式桥名就引动多少文人学者打 ...

最新文章

  1. linux登录ssh怎么保存采集的脚本,ssh自动登录并且su的脚本
  2. 采用流水线技术实现8位加法器
  3. echarts散点图使用
  4. 【面试题】struts2的工作流程
  5. Android TextWatcher监控EditText中的输入内容并限制其输入字符个数
  6. JAVA 客户端跳转与服务器端跳转 get与post
  7. actions相互调用并且存在顺序
  8. genymotion 极速模拟器
  9. 语义化版本控制规范(SemVer)
  10. Web服务软件工厂(WSSF)演练之三:创建服务契约和实现方法
  11. day013内置函数一
  12. You have tried to change the API from what has been previously approved
  13. [Android 4.4.2] 泛泰A870 Mokee4.4.2 20140531 RC1.0 by syhost
  14. 在word里面加水印的方法和技巧教程!
  15. iFunk超极本或出新,你最想知道什么
  16. ROSERROR : C++ filt命令
  17. 2022年高教社杯全国大学生数学建模竞赛-【赛题解析篇】B题:无人机遂行编队飞行中的纯方位无源定位(附Python代码实现)
  18. 遗传-粒子群算法遗传-禁忌搜索算法求解TSP问题
  19. 汉白玉产地在哪里_汉白玉产地是在哪里,有哪些种类?
  20. p5.js之动态魔幻画板

热门文章

  1. 吉林省专升本历年真题高频词汇
  2. 程序员接私活完整攻略
  3. HDU 6070 Dirt Ratio [二分+线段树]
  4. 八进制数转十进制计算机计算器,八进制转十进制计算器
  5. linux锐捷认证成功无法上网,主编传授win10系统锐捷认证成功但是却无法上网的方法...
  6. 抖音企业号无需开发连接第三方系统
  7. 首发|罗振宇2018“时间的朋友”跨年演讲未删减全文
  8. 在使用变量的时候,双引号和单引号 如何使用,及其区别:
  9. android实现自动触摸,Android编程开发之多点触摸(Multitouch)实现方法
  10. 谱瑞PS8625替代方案|PS8622替代方案|高性价比EDP转LVDS转接板方案CS5211设计开发