Windows10下使用Intel SGX功能(二):helloworld流程分析

news2024/11/24 8:01:46

文章目录

  • 参考文献
  • `helloworld` 代码解读
    • 代码目录结构
    • 调用流程
      • 1. 首先定义 host 和 enclave 之间相互调用的函数
      • 2. 实现 enclave 端的 `enclave_helloworld()` 逻辑
      • 3. 实现 host 端的 `host_helloworld()` 逻辑
      • 4. 编译 enclave 应用程序
        • 4.1 使用 `oeedger8r` 编译 `helloworld.edl` 的 untrusted 部分,生成 host 端的相关文件
        • 4.2 编译
        • 4.3 签名 enclave 程序
        • 总结
      • 5. 编译 host 端应用程序
        • 5.1 使用 `oeedger8r` 编译 `helloworld.edl` 的 trusted 部分,生成 enclave 端的相关文件
      • 6. `helloworld` 调用流程
  • ninja 编译过程
  • ninja run 过程

参考文献

  • helloworld README 文档
  • API reference and supported libraries
  • Build and Sign an Enclave
  • Build options for using Open Enclave SDK libraries
  • Open Enclave SDK CMake Package
  • tee-internal-core-api-specification
  • Open Enclave edger8r

helloworld 代码解读

代码运行环境: windows 10

代码目录结构

调用流程

1. 首先定义 host 和 enclave 之间相互调用的函数

定义见 helloworld.edl

enclave {
    from "openenclave/edl/syscall.edl" import *;
    from "platform.edl" import *;

    trusted {
        public void enclave_helloworld();
    };

    untrusted {
        void host_helloworld();
    };
};

其中 public void enclave_helloworld() 是 enclave 向 host 暴露的接口。 void host_helloworld(); 是 enclave 向 host 返回数据的回调函数。

2. 实现 enclave 端的 enclave_helloworld() 逻辑

helloworld/enclave/enc.c 中代码。

  • API reference and supported libraries
// 导入 enclave 库, 完整的 enclave 库见【API reference and supported libraries】
// 此示例中包含 stdio.h 头文件,因为我们调用 CRT 函数 fprintf  在屏幕上打印消息。
// 但是,此函数依赖于内核在屏幕上打印消息,因此此代码无法在安全区本身内执行。
// 相反,这个函数将调用转交给主机,以代表enclave执行调用。
#include <stdio.h>

// 导入在构建过程中生成的受信任的helloworld头文件。
// 该文件是通过针对 helloworld.edl 文件调用sdk工具oeedger8r生成的。
#include "helloworld_t.h"

// 这是主机调用的函数。它在 enclave 中打印一条信息,然后再回调到主机中打印一条信息。
void enclave_helloworld()
{
    // 打印一个来自 enclave 的信息。
    // 注意,不是直接调用fprintf,而是将调用转交到host,并从那里调用fprintf。
    // 这是因为fprintf函数不是enclave的一部分,因为它需要内核的支持。
    fprintf(stdout, "Hello world from the enclave\n");

    // Call back into the host
    oe_result_t result = host_helloworld();
    if (result != OE_OK) // 验证是否成功
    {
        fprintf(stderr, "Call to host_helloworld failed: result=%u (%s)\n", result,
         oe_result_str(result));
    }
}

3. 实现 host 端的 host_helloworld() 逻辑

代码见 helloworld/host/host.c

// 包括本文件中使用的Open Enclave函数的头,(例如oe_terminate_enclave)。
#include <openenclave/host.h>

// 包括标准的CRT库。与 enclave 实现不同的是,enclave 实现包括一个特殊的 enclave 版本的 stdio 库,该库将API传递给主机。
// 而 host 不受保护,所以使用所有正常的C库和函数。
#include <stdio.h>

// Include the untrusted helloworld header that is generated
// during the build. This file is generated by calling the
// sdk tool oeedger8r against the helloworld.edl file.
#include "helloworld_u.h"

// 这是 enclave 调用的实际的 host 函数。该函数在 helloworld.edl 文件中定义,并在这里实现。
void host_helloworld()
{
    fprintf(stdout, "Enclave called into host to print: Hello World!\n");
}

// host 是创建和调用enclave的应用程序,所以host是一个正常的C可执行文件,有一个标准的主函数。
int main(int argc, const char* argv[])
{
    oe_result_t result;
    int ret = 1;
    oe_enclave_t* enclave = NULL;

    if (argc != 2)
    {
        fprintf(stderr, "Usage: %s enclave_image_path\n", argv[0]);
        goto exit;
    }

    // 1. 通过调用oe_create_helloworld_enclave来创建一个enclave,该enclave的签名库文件的路径刚好作为第一个参数传递给启动应用程序。
    // oe_create_helloworld_enclave函数是由oeedger8r生成的,默认名字方式是oe_create_[xxxx]_enclave,其中xxx是 EDL文件的名称。该函数创建了一个enclave 镜像供主机进程使用。
    // 该函数功能包括:
    //   (1). 分配 enclave 地址空间。
    //   (2). 从enclave 库文件中加载 enclave 代码和数据到它的地址空间。
    //   (3). 设置enclave环境,包括enclave堆和每个enclave线程的数据结构。
    //   (4). 测量产生的enclave身份,并确保它与enclave签名相匹配。
    //   (5). 初始化 "enclave",使其准备好从主机上调用。
    // 2. OE_ENCLAVE_FLAG_DEBUG标志允许在没有签署enclave二进制的情况下创建enclave。
    // 它还允许开发人员调试进程并获得对enclave内存的访问。这意味着**不要发送带有OE_ENCLAVE_FLAG_DEBUG的代码**,因为它是不安全的。它所提供的是更容易开发你的enclave的能力。
    // 在你运送代码之前,你需要为enclave可执行文件准备一个适当的代码签名故事。
    // 一些较新的英特尔SGX平台允许使用自签名的证书,但一些较老的英特尔SGX平台要求英特尔对你的enclave可执行文件进行签名。
    // 3. 在成功创建后,该函数会返回一个不透明的enclave句柄,用于今后对enclae的任何操作。
    result = oe_create_helloworld_enclave(
        argv[1], OE_ENCLAVE_TYPE_AUTO, OE_ENCLAVE_FLAG_DEBUG, NULL, 0, &enclave);
    if (result != OE_OK)
    {
        fprintf(stderr, "oe_create_helloworld_enclave(): result=%u (%s)\n", result, oe_result_str(result));
        goto exit;
    }

    // 调用了从helloworld.edl文件中生成的主机marshaling函数。它处理任何参数的代码,并在enclave本身中调用该函数。
    // 在这个例子中,没有任何实际的函数参数。
    // 同时,尽管函数enclave_helloworld()是一个无效的返回类型,但marshaling代码本身可能会失败,所以需要验证与之相关的返回代码。
    // 如果enclave_helloworld()要返回一个值,这将作为一个out参数传回来。
    // Open Enclave处理host模式和enclave模式之间的所有上下文切换。
    result = enclave_helloworld(enclave);
    if (result != OE_OK)
    {
        fprintf(stderr, "calling into enclave_helloworld failed: result=%u (%s)\n", result, oe_result_str(result));
        goto exit;
    }

    ret = 0;

exit:
    // 终止enclave并释放与之相关的所有资源。
    if (enclave)
        oe_terminate_enclave(enclave);

    return ret;
}

4. 编译 enclave 应用程序

4.1 使用 oeedger8r 编译 helloworld.edl 的 untrusted 部分,生成 host 端的相关文件

oeedger8r --search-path c:\openenclave\include --search-path c:\openenclave\include\openenclave\edl\sgx ..\helloworld.edl --untrusted
filedescription
host/helloworld_args.h所有函数的参数定义
host/helloworld_u.c包含 "enclave_helloworld() "函数,该函数具有调用 enclave 版本的 "enclave_helloworld() "函数的 marshaling 代码。
host/helloworld_u.h`enclave_helloworld()'函数的函数原型

Open Enclave edger8r 的说明文档在这儿

4.2 编译

  • Build and Sign an Enclave
  • Build options for using Open Enclave SDK libraries

与英特尔SGX SDK一样,Open Enclave SDK目前只支持构建单一的二进制 enclave 。与英特尔SGX SDK一样,这些二进制文件也必须用一组特定的包含物和构建标志来构建。
为了简化指定正确构建参数的过程,Open Enclave SDK提供了一套pkg-config设置:

  • Building enclave or host binary
  • Using GCC or Clang build tools
  • Compiling C or C++ code

具体的语法是:

oe<enclave|host>-<gcc|g++|clang|clang++>

helloworld 编译方法如下:

$(CC) -g -c $(CFLAGS) -DOE_API_VERSION=2 enc.c -o enc.o
$(CC) -g -c $(CFLAGS) -DOE_API_VERSION=2 helloworld_t.c -o helloworld_t.o
$(CC) -o helloworldenc helloworld_t.o enc.o $(LDFLAGS) $(CRYPTO_LDFLAGS)

4.3 签名 enclave 程序

在运行SGX enclave 之前,需要为 enclave 指定定义 enclave 应如何加载的属性。这些属性与签名密钥一起,定义了用于验证和密封操作的 enclave 身份。

使用 essign 的 SDK 工具对 encalve 库进行签名。

oesign sign -e helloworldenc -c helloworld.conf -k private.pem

enclave 的签名证书必须是 3072-bit RSA keys with exponent 3
密钥生成方法如下:

openssl genrsa -out myprivate.pem -3 3072

签名的配置文件在 helloworld.conf。该文件定义了enclave的配置。

必选项

  • Debug: enclave 是否可以以 debug 模式加载
  • NumTCS:要在 enclave 中分配的线程控制结构(TCS)的数量。这决定了在 enclave 中可以执行的最大并发线程数。
  • NumStackPages:为 enclave 中每个线程分配的堆栈页数。
  • NumHeapPages:为 enclave 分配的作为堆内存的页数。

上述4个属性也将反映在产生的 enclave 的UniqueID(MRENCLAVE)中。此外,以下两个属性是由开发者定义的,并直接映射到以下SGX身份属性。

  • ProductID:产品标识(ISVPRODID),供开发者区分以相同MRSIGNER值签署的不同 enclave。
  • SecurityVersion:enclave 的安全版本号(ISVSVN),它可以用来防止对密封密钥的回滚攻击。每当对 enclave 代码进行安全修复时,这个值都应该被递增。

可选项

  • Linux, PSW >= 2.14.1

    • CreateZeroBaseEnclave:是否应该用基础地址0x0创建 enclave ?默认为0。

    • StartAddress:当 enclave 基址为0x0(CreateZeroBaseEnclave=1)时, enclave 镜像将在此地址创建。该值需要与OE_PAGE_SIZE(0x1000)对齐,并大于mmap最小地址(/proc/sys/vm/mmap_min_addr)。

      基于0的 enclave 在访问0页时保证了NullPointerException行为。依赖于这种行为的应用程序现在可以在 enclave 内运行(例如,.NET运行时)。

  • 指定额外的密钥共享和分离(KSS)身份属性(for SGX enclave only)

    • FamilyID:开发者可以指定产品系列标识(SGX的ISVFAMILYID),将不同的 enclave 组合在一个共同的标识下,如包括几个 enclave 应用程序的应用套件的标识。
    • ExtendedProductID:扩展的产品标识(SGX的ISVEXTPRODID)值,当16位的产品标识被证明过于局限时,开发者可以将其作为enclave的128位全球唯一标识。更多细节,请参见《英特尔软件》的表37-19。
      比如:
      FamilyID=47183823-2574-4bfd-b411-99ed177d3e43
      ExtendedProductID=2768c720-1e28-11eb-adc1-0242ac120002
      
  • SGX2 机器

    • CapturePFGPExceptions:是否应该启用(1)或不启用(0) enclave 内异常处理程序来捕获#PF和#GP异常(SGX2特性,默认值:0)。

上述所有设置可以通过宏定义(OE_SET_ENCLAVE_SGX2 OE_SET_ENCLAVE_SGX)来进行设置。
OE_SET_ENCLAVE_SGX2 支持 KSS 设置。

OE_SET_ENCLAVE_SGX2(
    1,     /* ProductID */
    1,     /* SecurityVersion */
    ({0x47, 0x18, 0x38, 0x23, 0x25, 0x74, 0x4b, 0xfd, 0xb4, 0x11, 0x99, 0xed, 0x17, 0x7d, 0x3e, 0x43}),   /* ExtendedProductID */
    ({0x27, 0x68, 0xc7, 0x20, 0x1e, 0x28, 0x11, 0xeb, 0xad, 0xc1, 0x02, 0x42, 0xac, 0x12, 0x00, 0x02}),   /* FamilyID */
    true,  /* Debug */
    true,  /* CapturePFGPExceptions */
    true   /* RequireKSS */
    false, /* CreateZeroBaseEnclave */
    0,     /* StartAddress */
    1024,  /* NumHeapPages */
    1024,  /* NumStackPages */
    1);    /* NumTCS */

OE_SET_ENCLAVE_SGX设置下,允许在调试模式下运行enclave,而不用先签署它。在这种情况下,enclave 被视为具有标准签名者ID(MRSIGNER)的值。

OE_SET_ENCLAVE_SGX(
    1,    /* ProductID */
    1,    /* SecurityVersion */
    1,    /* Debug */
    1024, /* NumHeapPages: heap size in units of 4KB pages */
    1024, /* NumStackPages: stack size, in units of 4KB pages */
    1);   /* NumTCS */

如果是 OP-TEE (ARM TrustZone),则使用sign.py对其进行签名。具体用法参考Signing an OP-TEE Enclave。

总结

更多关于Intel TEE API的操作参考 tee-internal-core-api-specification

5. 编译 host 端应用程序

5.1 使用 oeedger8r 编译 helloworld.edl 的 trusted 部分,生成 enclave 端的相关文件

oeedger8r --search-path c:\openenclave\include --search-path c:\openenclave\include\openenclave\edl\sgx ..\helloworld.edl --trusted
filedescription
enclave/helloworld_args.h所有函数的参数定义
enclave/helloworld_t.c包含 "host_helloworld() "函数,其中包含调用 host 的 "host_helloworld() "函数的 marshaling 代码。
enclave/helloworld_t.hhost_helloworld()函数的函数原型

6. helloworld 调用流程

ninja 编译过程

ninja run 过程

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/384099.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

学生专用台灯怎么选?给孩子买台灯需要注意什么

台灯是现在很多学生孩子都使用比较多的产品&#xff0c;晚上看书学习&#xff0c;停笔沉思&#xff0c;台灯柔和舒适的光照&#xff0c;可以营造良好的氛围&#xff0c;也能有效保护眼睛&#xff0c;不受光线刺激、辐射伤害。 那么学生专用台灯该怎么选呢&#xff1f; ①一个…

捍宇医疗再冲刺科创板上市:核心产品专利来自购买,暂未商业化

2023年3月1日&#xff0c;上海捍宇医疗科技股份有限公司&#xff08;下称“捍宇医疗”&#xff09;递交招股书&#xff0c;准备在科创板上市。据贝多财经了解&#xff0c;捍宇医疗曾冲刺港交所上市&#xff0c;并于2021年9月通过聆讯&#xff0c;但最终放弃了港交所上市的打算。…

后端必备之Vue基础【黑马程序员】

黑马程序员4小时入门Vue传送门 1. 简介 Vue是一个操作JavaScript的框架&#xff0c;类似于jQuery&#xff0c;但比jQuery好用&#xff0c;是现在的主流 2. 测试例子 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8" /&…

LeetCode-746. 使用最小花费爬楼梯

题目来源 746. 使用最小花费爬楼梯 动态规划 动态规划五部曲 1.确定dp数组以及下标的含义 使用动态规划&#xff0c;就要有一个数组来记录状态&#xff0c;本题只需要一个一维数组dp[i]就可以了。 dp[i]的定义&#xff1a;到达第i台阶所花费的最少体力为dp[i]。 2.确定递推…

The simplest way to get started with Stable Diffusion on Ubuntu

link1 link2 Stable Diffusion is a machine learning model that can generate images from natural language descriptions. Because it’s open source, it’s also easy to run it locally, which makes it very convenient to experiment with in your own time. The sim…

万字长文漫谈高可用高并发技术

互联网应用通常面向海量用户&#xff0c;其后台系统必须支撑高并发请求。在后端开发面试中&#xff0c;高并发技术也是一个常见的考察点。 那么&#xff0c;高并发系统通常是怎么设计的呢&#xff1f;需要采用哪些技术呢&#xff1f;本文就简单聊一聊高并发背后的各种技术栈。…

蓝桥杯任意刷

这里写目录标题受伤的皇后全球变暖&#xff08;最大联通子集&#xff0c;一趟递归记得不要嵌套计数&#xff09;游园问题金额查错蓝肽子序列&#xff08;最长公共子序列&#xff09;受伤的皇后 #include <iostream> #include <bits/stdc.h> using namespace std; …

运动带什么蓝牙耳机好,最适合运动佩戴的蓝牙耳机分享

运动时汗如雨下&#xff01;这可如何是好&#xff0c;这时候一款运动专用的防水耳机就成为人们的最爱。现在&#xff0c;市面上的耳机种类已经多到数不胜数。价格也不一&#xff0c;到底是一分钱一分货&#xff0c;还是打着低价卖你一个小型音响。到底怎么挑才能找到一款性价比…

联邦学习(fate)从主机安装到实现联邦学习

联邦学习&#xff08;fate&#xff09;从主机安装到实现联邦学习一、单机部署1.1虚拟机配置1.2安装python1.3端口检查1.4获取安装包&#xff0c;并解压1.5安装1.6启动1.7测试1.8安装FATE-Client、FATE-Test、FATE-Flow、jupyter notebook1.8.1FATE-Client、FATE-Test1.8.2FATE-…

Newman+Jenkins实现接口自动化测试

一、是什么Newman Newman就是纽曼手机这个经典牌子&#xff0c;哈哈&#xff0c;开玩笑啦。。。别当真&#xff0c;简单地说Newman就是命令行版的Postman&#xff0c;查看官网地址。 Newman可以使用Postman导出的collection文件直接在命令行运行&#xff0c;把Postman界面化运…

【C++】stack 与 queue

stack 与 queuestackSTL 容器中 stack 的使用模拟实现 stackqueueSTL 容器中 queue 的使用模拟实现 queuestack 在数据结构中&#xff0c;我们了解到&#xff0c;stack 栈结构&#xff0c;是一种先进后出的结构&#xff0c;并且我们是使用顺序表来进行实现栈的操作的。 STL 容…

如何使用FindFunc在IDA Pro中寻找包含指定代码模式的函数代码

关于FindFunc FindFunc是一款功能强大的IDA Pro插件&#xff0c;可以帮助广大研究人员轻松查找包含了特定程序集、代码字节模式、特定命名、字符串或符合其他各种约束条件的代码函数。简而言之&#xff0c;FindFunc的主要目的就是在二进制文件中寻找已知函数。 使用规则过滤 …

C++回顾(六)—— 对象动态建立

6.1 new 和 delete 用法 6.1.1 概述 在软件开发过程中&#xff0c;常常需要动态地分配和撤销内存空间&#xff0c;例如对动态链表中结点的插入与删除。在C语言中是利用库函数malloc和free来分配和撤销内存空间的。C提供了较简便而功能较强的运算符new和delete来取代malloc和f…

smart-doc Java Restful API 文档生成工具

smart-doc简介 官方地址smart-doc smart-doc 是一款同时支持 JAVA REST API 和 Apache Dubbo RPC 接口文档生成的工具&#xff0c;smart-doc 在业内率先提出基于 JAVA 泛型定义推导的理念&#xff0c; 完全基于接口源码来分析生成接口文档&#xff0c;不采用任何注解侵入到业…

vue基础学习笔记

1.v-text 设置标签的文本值&#xff0c;将标签内的内容完全替换为v-text绑定的值。 如果想要保留标签内的值&#xff0c;可以采用差值表达式的方式&#xff08;<h2>text{{message}}</h2>&#xff09; 内部值支持拼接 <!DOCTYPE html> <html lang"en…

Unity Asset Bundle学习 - 加载网络资源

昨天调试了一下加载本地资源 Unity Asset Bundle学习 - 加载本地资源 今天试一下用Asset Bundle加载网络数据 接着按照文档走 发现 有问题 引用命名空间一直报错 按文档走不通 就直接百度查了 查了好多 这个东西有很多前辈的经验 直接拷贝代码拿过来用的 下面这段是测试没问题…

技术分享 | OceanBase 集群扩容缩容

作者&#xff1a;杨文 DBA&#xff0c;负责客户项目的需求与维护&#xff0c;会点数据库&#xff0c;不限于MySQL、Redis、Cassandra、GreenPlum、ClickHouse、Elastic、TDSQL等等。 本文来源&#xff1a;原创投稿 *爱可生开源社区出品&#xff0c;原创内容未经授权不得随意使用…

面试官:为什么说ArrayList线程不安全?

本博客知识点收录于&#xff1a;⭐️《JavaSE系列教程》⭐️ 1&#xff09;线程安全与不安全集合 我们学习集合的时候发现集合存在由线程安全集合和线程不安全集合&#xff1b;线程安全效率低&#xff0c;安全性高&#xff1b;反之&#xff0c;线程不安全效率高&#xff0c;安…

Yuga Labs发布“TwelveFold“进军BTC,新大陆的探索即将开启

Yuga Labs 正在将新的 NFT 引入比特币区块链&#xff0c;并于 2 月 28 日推出了一个名为 TwelveFold 的系列。该系列是比特币网络上“刻在 satoshis 上”的 300 个生成作品的限量版。据官方说明&#xff0c;TwelveFold将限量发行三百幅的生成式NFT 画作&#xff0c;每件NFT 作品…

AcWing3696. 构造有向无环图

先看题&#xff1a; 首先来看一下题目的要求&#xff1a;利用给定的边来构造一个有向无环图。 那么什么是有向无环图呢&#xff1f;我们来搜索一番&#xff1a;"所谓有向无环图其实就是&#xff1a;有方向的边&#xff1b;这些边在一个图中不会构成一个闭合的环路。"…