SGX|SGX开发基础

SGX开发基础

    • 设计原则
    • 安全区定义语言(enclave definition language,DEL)
    • DEL关键词
    • 调试SGX
    • 数据密封

设计原则

设计通用原则:应用程序划分区域。

  • 可信部分(enclaves):

    • 一个应用程序可以有一个或多个安全区。安全区存储在加密的内存中,并受SGX保护。

    • 一旦建立不能被篡改:一旦被篡改会被CPU检测到,安全区就不会加载

  • 非可信部分:不被SGX保护的应用程序或内存。

综上,编程之前就需要对代码进行划分,划分为可信代码和非可信代码,并要考虑二者之间的交互。

  1. 确定机密信息:不希望被外界获取的数据。
  2. 确定机密数据的提供者和使用者:画出机密数据在应用程序各组件中的流程图。
  3. 确认安全边界:目标是包含尽可能多的机密数据,并最大限度减少与非可信代码的交互(不应该把不必加密的数据划为机密数据:安全区调试难度和安全区体积呈正比)。
  4. 精简安全区代码,原因:
    1. 单一系统用于所有安全区的内存容量固定,所以安全区应尽量小,并且在不需要机密数据后安全区立即销毁。
    2. 进出安全区的调用会产生性能损失,就和cpu上下文切换一样(一次调用完成大量工作比多次调用完成等量工作更有效率)

安全区定义语言(enclave definition language,DEL)

SGX保护措施(CPU保证):安全区的机密数据仅能被安全区内的代码访问,执行安全区内的代码的唯一方式就是通过开发人员创建的接口函数。

接口函数:

  • E-CALL:非可信应用程序进入安全区的入口
  • O-CALL: 使安全区函数可以调用外部非可信应用程序,再返回安全区

EDGER8R工具(自动化):

  • 自动为E-CALL和O-CALL生成代理函数
  • 应用程序可以想调用其他C语言函数一样调用代理函数

DEL介绍:

  • DEL文件和声明函数原型的C语言风格的头文件非常相似
  • 由可信区和非可信区组成:
    • 可信区:E-CALL定义在可信区
    • 非可信区:O-CALL定义在非可信区

DEL关键词

  • public
    • 所有能被非可信程序调用的E-CALL都必须声明为public(root E-CALL)

SGX|SGX开发基础_第1张图片

  • 每个安全区至少应有一个声明为public的E-CALL

  • 不包含public的E-CALL只能被另一个O-CALL调用(注意区分非可信程序和O-CALL)

  • 当O-CALL调用E-CALL时,必须通过Allow关键词声明该O-CALL可调用哪些E-CALL。本例中,O-CALL中的get_msg_block()只能调用E-CALL中的update_hash()。(allow缺省状态下,O-CALL不可以调用E-CALL的任何函数,即使它声明为public)
    SGX|SGX开发基础_第2张图片

  • 函数值传递

    • 每个指针或者参数之前必须有方括号来描述封送处理的方向以及封送处理的元素数量(某些情况可忽略)
      SGX|SGX开发基础_第3张图片
    • in关键词意味着数据需要封送到E-CALL或O-CALL之内
    • out关键词意味着数据需要从E-CALL或O-CALL封送回调用的函数
      • out需要在调用E-CALL或O-CALL之前分配好数据缓冲区,缺省状态下,EDGER8R假定的数据缓冲区大小等于参数的大小(sizeof)
    • 同时指定in和out关键词意味着要进行两个方向的封送处理
    • 实例中10个32位整数将会被封送处理:
      SGX|SGX开发基础_第4张图片
    • 如果这个数目运行时才可以确定,我们也可以使用另一个函数参数来表示它:
      SGX|SGX开发基础_第5张图片
    • 如果使用in关键词分送一个以“\0“作为终止符的字符串,可以根据字符集使用string(ANSI,用于str打头的函数)或者是wstring(Unicode,用于wcs打头的函数)来替代count关键词(这两个关键词不适用于out)
      SGX|SGX开发基础_第6张图片
    • 当E-CALL或O-CALL声明函数指针类型为void时,需要通知边界例程void类型对应的大小,edl语法提供了size关键词,用于指定单个元素大小,本例中,32个8字节数据将会被封送到E-CALL
      SGX|SGX开发基础_第7张图片
    • 仅把指针指向的地址传给E-CALL或O-CALL,可通过user_check关键词完成
      SGX|SGX开发基础_第8张图片

调试SGX

SGX安全区可以以Debug模式Release模式构建。

  • Debug模式:CPU允许任何以Debug模式构建的安全区,即被篡改也可运行,所以并不安全。一般调试器会跳过安全区,只有SGX调试器才可以对安全区代码进行调试。
    • 安全区可调式
    • 可附加SGX调试器
    • 查看当前状态
    • 逐句调试
  • Release模式:不允许任何形式的调试,由CPU严格保证。

数据密封

安全区状态:

  • 当系统进入睡眠、关机或者应用程序退出时,安全区立即被销毁。
  • 安全区被销毁后,其中所有的内容都会丢失

为了更好地保存机密数据,必须显式地将其发送到安全区以外的非可信内存中,于是引入了数据密封功能:

  • 当数据被密封时,数据在安全区内用密钥加密(密钥由CPU直接生成)
  • 密文数据只能在创建它的那台电脑上进行解密
  • 加密过程本身可以保证数据的机密性,完整性和真实性

密封数据策略:

  • 安全区标识(mrenclave):生成一个该安全区独有的密钥,同一台电脑的同一个安全区才可以解密数据(密钥输入:主机指纹+安全区指纹)。
  • 签名者标识(mrsigner):基于安全区签名者密钥(主机指纹)生成一个密钥,同一台电脑上的不同安全区都可以解密,且安全区之间可以互相解密,方便迭代新版本且使不同的安全区之间共享数据。

安全区指纹:Debug安全区无法解封Release模式的安全区密封数据,反之亦然

你可能感兴趣的:(SGX|SGX开发基础)