当前位置:   article > 正文

SGX项目开始_aesm.socket

aesm.socket

从rust-sgx-sdk开始

阅读
https://github.com/dingelish/SGXfail/blob/master/01.md
摘要:
关键字:可信 + 保密

sgx运行环境的结构

intel sgx程序分成untrusted和trusted两部分, trusted 包括了用户自己写的SGX enclave。 用户自己的untrusted app需要和Intel提供的untrusted runtime等运行时库配合使用。
支持Intel SGX程序执行,需要
	- untrusted部分的守护进程aesmd,提供application enclave service manager.
	- 官方Enclave:
	
		- Launch Enclave(le)
		- Quoting Enclave(qe)
		- Platform Service Enclave(pse)
		- Provisioning Enclave (pve)
		- Provisioning Certification Enclave(pce)
		- Reference Launch Enclave
		- 和一些配套的untrusted AE接口
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

在这里插入图片描述图中可以知道:

  • SGX的内核驱动暴露一个/dev/isgx的misc device 给用户态,用户态的AESM守护进程和uae service等经过这个misc device为用户进程的untrusted部分提供create/destroy enclave等能力
  • AESM的守护进程aesmd会打开一个domain socket:aesm.socket给用户态程序的urts(untrusted runtime service)库和uae_service库提供支持。asem对于用户就是一个黑盒子。 用户只需要通过urts和uae_service提供的接口来实现业务逻辑就可以了。

运行一个SGX程序的前提

  1. 包括平台提供isgx设备
  2. 全套的aesm服务
  3. urts/uae_service的动态库
  • 提供了一套软件模拟环境,编译时指定SGX_MODE=SE打开。启用SW环境之后,编译时会链接所有库的模拟执行版本。例如libsgx_trts_sim.a, libsgx_tservice_sim.a等。对于untrusted部分也有模拟环境:libsgx_uae_service_sim.so, libsgx_urts_sim.so。所以,在没有SGX硬件的支持下,也是可以通过软件模拟的方式来操作SGX。

rust-sgx-sdk

hello-rust

  1. untrusted 和 trust 都是rust编写的

  2. app 目录下的untrusted 部分

    • sgx_types是数据结构定义
    • sgx_urts是函数接口定义;untrusted runtime service的接口
    • 对于一个untrused端app,不考虑PSE、unprotected_fs等情况下,这两个依赖项就是足够创建和关闭enclave了
  3. app/build.rs

  • 这个文件会把编译选项输出给rustc,主要的事情是:
    • 帮助rustc找到SGX SDK的位置
    • 帮助rustc找到enclave EDL所生成的Enclave_u的位置
    • 帮助rustc link 到正确的urts库(HW or SW)
  1. EDL
  • Intel给定的文件格式,接近C的header file写法,规定了Enclave 的边界 ECALL/OCALL的定义。
  • Intel提供了一个由Ocaml编写的EDL编译器edger8r
  • 将每一个输入的EDL转化为
    • Enclave_u.c+ Enclave_u.h
    • Enclave_t.c+Enclave_t.h
  • 这四个文件包含了ECALL/OCALL中所引入的必要的"额外proxy function 和marshling数据结构",用于完成ECALL/OCALL操作,
  • app调用导出的ECALL函数时,控制流会转到这个自动生成的stub中,完成必要的操作,再把控制权交给sgx_ecall函数,它负责状态转换到sgx模式,进入enclave。
  • 进入enclave之后胡县到enclave_t.c中实现bridge function的另一端,进行另一些参数包装之后最后才会执行到Enclave函数的实现
  • 上面的过程时不可见的,但是是程序员理解SGX的关键,
    细节:
    https://software.intel.com/sites/default/files/managed/e1/ec/SGX_SDK_Developer_Guidance-CVE-2017-5753.pdf;
    https://software.intel.com/sites/default/files/managed/e1/ec/180309_SGX_SDK_Developer_Guidance_Edger8r.pdf
    中文:
    https://github.com/dingelish/SGXfail/blob/master/02.md
    https://github.com/dingelish/SGXfail/blob/master/03.md
  1. hello-rust源码阅读
    hello-rust/enclave/Enclave.edl
enclave {
    from "sgx_tstd.edl" import *;
    from "sgx_stdio.edl" import *;
    from "sgx_backtrace.edl" import *;
    from "sgx_tstdc.edl" import *;
    trusted {
        /* define ECALLs here. */

        public sgx_status_t say_something([in, size=len] const uint8_t* some_string, size_t len);
    };
};
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 唯一一个用户定义的ECALL函数是say_something,其参数包括一个uint8_t *的指针和一个长度len。在EDL里利用size=len来告诉SGX要把多少个字节的参数拷贝到Enclave里。
  • 在Enclave里的say_something看来,这个指针是指向Enclave内存的,而不是指向untrusted部分的内存。所以,ECall会把这样的参数连续的按字节拷贝到Enclave的加密内存中,因此需要个长度。
    app/src/main.rs
    let result = unsafe {
        say_something(enclave.geteid(),
                      &mut retval,
                      input_string.as_ptr() as * const u8,
                      input_string.len())
    };
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • ECALL传递参数的时候是包括两个“隐参数”的,即enclave id和"返回值所存的地址&retval。并且这个ECALL会具有另外一个返回值result。这里result代表的含义是:ECALL执行是否成功。ret代表的含义是:ECALL函数的返回值。

enclave部分

- Cargo.toml:staticlib
- 会被编译成一个.a文件,和intel其他库文件连接一起成为enclave.so,
- sgx_sign工具配合Enclave.config.xml配置文件、签名私钥一起做签名和属性刻画,生成enclave.signed.so,成为Enclave
- dependency包含sgx_types,sgx_tstd,后者是标准库,
- lib.rs是Enclave源代码,
  • 1
  • 2
  • 3
  • 4
  • 5
    // Ocall to normal world for output
    println!("{}", &hello_string);
  • 1
  • 2
  • 如果做print打印需要syscall的,而SCX内不可以作syscall,这里要进行OCALL。但在该例子EDL里面没有直接出现OCALL打印函数,这是因为我们在实现pringln!的过程中加入了内置的OCALL,并定义了对应的EDL,并且在Enclave.edl中做了import.
  enclave {
      from "sgx_tstd.edl" import *;
     from "sgx_stdio.edl" import *;
     from "sgx_backtrace.edl" import *;
     from "sgx_tstdc.edl" import *;
  • 1
  • 2
  • 3
  • 4
  • 5
  • printf实现复杂,需要在超长的调用过程中的某一点进行切割,将控制流从Enclave内转到Enclave外,在untrusted部分完成write,判断在哪里进行切割需要partition.

Partition

  • 意味着划分可信/不可信的边界。
  • partition是一个“业务逻辑”层面的事情,对于一个业务,partition可以有无数种方式。
  • 让我们拿Scone-python做例子。Scone(和Graphene SGX)是一类试图将”任意程序“跑在SGX内的解决方案。他们甚至可以直接跑python解释器。看上去很美。但是在SGX的威胁模型下,只有Enclave内是可信的,这导致,在Enclave内执行的python解释器在执行到import numpy的时候,会从磁盘中读取numpy的python文件并进行解释,而读进来的文件是不可信的!这时相当于:在可信环境中执行了不可信的代码,然而——用户依然认为它是可信的!这是一个典型的错误可信计算基的实例。攻击者可以简单的替换磁盘中的numpy,下次用户再次import numpy的时候,就会使用植入了恶意逻辑(比如发送secret)的numpy在Enclave内执行,导致秘密泄露。
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/知新_RL/article/detail/65098
推荐阅读
  

闽ICP备14008679号