官方文档总结系列:Intel_SGX_Developer_Guide

《Intel_SGX_Developer_Guide》文档下载地址在 这儿

架构

Intel SGX分为4个部分:

  • Untrusted Run-Time System(uRTS) 在英特尔 SGX 飞地环境之外执行并执行以下功能的代码:
    • 加载和管理飞地。
    • 向飞地发出ECall和从飞地内接收OCall。
  • Trusted Run-Time System (tRTS) 在 Intel SGX enclave 环境中执行并执行以下功能的代码:
    • 接收对 enclave 的调用并在 enclave 外部进行调用。
    • 管理飞地本身。
    • 标准的C/C++库和运行时环境。
  • Edge Routines 可以在 enclave 外部(不受信任的边缘例程)或 enclave 内部(受信任的边缘例程)运行的函数,用于将来自应用程序的调用与 enclave 内部的函数或来自 enclave 的调用与应用程序中的函数绑定。
  • 3rd Party Libraries 为在英特尔 SGX 飞地环境中工作而定制的任何库。

Intel SGX的几个关键技术

几个关键技术可以参考文档《SGX技术分析

  • 硬件安全密钥
    • 每个支持SGX的CPU都包含两个存储在电子保险丝内的根密钥:根供应密钥(RPK)和根密封密钥(RSK)。RPK为英特尔所知,以实现远程验证过程,而RSK只为平台所知。
    • 根供应密钥(RPK):英特尔在制造过程中创建的第一个密钥是根基配置密钥(RPK)。这个密钥是在一个名为 “英特尔密钥生成设施”(iKGF)的设施内的专用硬件安全模块(HSM)上随机生成的。英特尔公司负责维护一个包含HSM产生的所有密钥的数据库。RPK被发送到多个生产设施,以嵌入处理器的电子引信内。
    • 根密封密钥(RSK):与第一把钥匙一样,它被保证在每个生产单位之间有统计学上的差异。与RSK相反,英特尔宣布从他们的生产链中清除这些密钥的所有痕迹,以便每个平台都有一个只有自己知道的独特密钥。
  • Enclave Page Cache (EPC):Enclave代码和数据被放置在一个特殊的内存区域,该内存区域使用 内存加密引擎(MEE) 进行加密,这是一个新的专用芯片。内存总线上的外部读取只能观察到加密的数据。只有在物理处理器核心内的页面才会被解密。密钥在启动时生成并存储在CPU内。
  • EPID(Intel® Enhanced Privacy ID)
    • 解决ECDSA中当少量的密钥被用于平台的整个生命周期时,使用标准的非对称加密签名算法的认证有一个众所周知的隐私问题。由于用于签署报价的密钥需要与执行报价操作的硬件相关联,它允许第三方串通并跟踪用户访问过哪些网站。
    • 英特尔 EPID 是一种群签名方案,它允许平台对对象进行加密签名,同时保护签名者的隐私。 使用英特尔 EPID 签名方案,组中的每个签名者都有自己的签名私钥,但验证者使用相同的组公钥来验证个人签名。 因此,如果与同一方签署两笔交易,则无法唯一识别用户,因为验证者无法检测到该组的哪个成员签署了报价。 对于英特尔 SGX,该组是支持英特尔 SGX 的平台的集合。
  • QE:Quoting Enclave
    • Intel 提供的称为 Quoting Enclave (QE) 的 enclave 验证已创建到其 MRENCLAVE 测量值的报告,然后使用设备特定的非对称密钥(Intel EPID 密钥)转换和签署它们。此过程的输出称为Quoting,可在平台外进行验证。 当飞地系统运行时,只有 QE 可以访问英特尔 EPID 密钥。 因此,可以看出引述来自硬件本身,但 CPU 密钥从未暴露在平台之外。
  • 内存加密

Intel SGX的几个特征功能

  • 数据密封
  • 认证:本地认证、远程认证。
    • Intel第三代处理器上开始可以使用认证(本地、远程)功能。包括英特尔至强可扩展的处理器和至强-SP系列处理器等。
    • SGX目前支持两种远程认证:
      • 椭圆曲线数字签名算法 (ECDSA)(Intel第三代处理器上开始可以使用该功能。包括英特尔至强可扩展的处理器和至强-SP系列处理器等)
      • Intel® Enhanced Privacy ID (Intel® EPID) 认证
  • 秘密提供:基于远程认证过程。
    • SGX的秘密提供功能:秘密供应由秘密通道实现,而秘密通道需要在远程认证中同时实现。

SGX开发准则

基本准则

  • enclave是一个单片软件实体,将应用程序的TCB简化为可信运行系统、ISV代码和第三方可信库。一个组件中的错误就会危及enclave中的安全财产。
  • 任何人都可以调用enclave,所以攻击者可以开发专门的程序加载enclave,以暴露enclave中的漏洞。
  • 一旦enclave被初始化,攻击者可以调用任何ISV接口函数,以任何顺序安排调用并提供任何输入参数。
  • enclave程序越小,出问题概率越低,攻击面越小,还能减少应用程序因为缓存未命中引起的开销。
    • 每个 EEXTEND 指令测量一个 256 字节的区域(生成加密哈希),这意味着需要 16 次 EEXTEND 调用才能测量 EADD 创建的 4KB 页面。EEXTEND 的 16 次调用中的每一个都添加到加密日志信息和该部分的测量中
    • 第一代Intel SGX体系结构要求在构建时静态链接飞地内的所有功能。这造成了性能/大小的权限。开发人员必须仔细分析它对TCB大小的影响。当使用静态库功能时,ISV有两种选择:(1)提供一个填充层来调用enclave之外的功能,或者将库的实现作为enclave的一部分。第一种方法增加了性能的开销,第二种方法导致TCB大小的增加。
    • 每个 EADD 指令将 EPCM 信息记录在存储在 SECS 中的加密日志中,并将 4 KB 的数据从 EPC 外部的未受保护内存复制到分配的 EPC 页面。
    • 英特尔® SGX 提供的飞地动态内存管理 (EDMM) 允许飞地在创建后扩展。 当您的操作系统支持 EDMM 时,您的应用程序可以先创建一个较小的 enclave,然后在需要额外的 enclave 空间时扩展它。 这将一些复制页面和测量区域的时间从飞地创建时间转移到稍后的时间点。

输入、输出

  • 输入的可信不由enclave保障。
  • 当一个输入被引用传递时,只有引用(指针)在enclave内,引用的值在外部,并可在任何时候改变。所以,攻击者可以在等待enclave检查完之后改变该值。所以enclave应用开发者需要特别注意处理引用或指针,并且必须在解除指针引用之前确定内存区域(指针和大小指定)。开发者应该只通过enclave边界指针传递给enclave内已知范围的对象。指向C数据结构的指针是合理的,但指向C++对象的指针却不是。
    • 传递指针的风险:在使用 user_check 时,Edger8r 工具在将指针传递给 enclave 之前不会验证指针。
  • 所有ISV接口函数只能在enclave初始化后才能调用。
  • OCall的运行和返回是不可信的,需要处理OCall未被执行的情况,比如攻击者未执行密封数据的存储但是返回已经存储完成。
    • 风险1:非信任域有可能不会递归调用Enclave
    • 风险2:encalve不能确保ECall发生的顺序或实际调用ISV接口函数
  • 如果OCall返回引用,必须检查返回指针所引用的数据缓冲区。在某些情况下,enclave开发者可以通过重新划分应用程序并将OCall要获得的信息作为输入参数传递给ISV接口函数来避免OCall函数。
  • 与操作系统的通信需要发布数据或导入非密数据,这需要适当处理。
  • ISV注册的异常程序只能在支持的enclave异常处理线程上调用。
  • ISV必须保持开发环境不受恶意软件和其他潜在线程的影响
  • 需要确定第三方库是否包含任何暴露信息的函数,必须检查该库所有函数的输出参数。
  • 到 enclave 和从 enclave 的转换在许多方面类似于上下文切换。 当执行 EENTER 指令以将控制权转移到 enclave 时,寄存器状态和其他有关不受信任状态的信息将被保存; 然后在 enclave 中加载线程状态和其他有关受信任状态的信息,以便可以在 enclave 中开始执行。 其中大部分是由 SDK 生成的代码执行的。 由 EEXIT 指令启动的反向过程发生在从 enclave 的转换中。 保存可信线程状态信息; 然后加载不受信任的注册状态和其他信息。 在所有转换期间也会执行安全检查。 同样,其中大部分是由 SDK 生成的代码执行的。 这些动作构成了与飞地之间的转换相关联的开销的固定元素。
  • 参数从应用程序的不受信任部分编组到受信任部分,并且返回值未编组。 在可信部分中,来自不可信部分的参数被取消编组,不可信部分的返回值被编组。 由于参数的大小可能相差很大,如果应用程序在应用程序的两个部分之间传递大参数,则可能会产生明显的开销。
  • 由于 enclave 本身无法控制系统是否配置为支持 32 位程序的大地址,并且 enclave 无法控制它加载的位置或它接收的输入,所有 32 位 enclave 应该考虑到enclave可能使用2GB以上空间或者获得更大的内存地址引用。

多线程

  • enclave中受信任的上下文是由不受信任域选择的,所以多线程情况下,不能保障enclave是按照顺序执行的
  • 必须在enclave内部添加阻塞功能(比如通过存储状态),防止攻击者嵌套调用ECall
  • 硬件只在enclave加载时才对enclave进行测量验证。所以任何人都可以修改enclave并用自己的密钥签名。为了阻止这种攻击,enclave的签名结构可以验证enclave签名者。
  • 优化数据同步、锁定、线程模型和所选的内存分配算法以提高性能。
  • 当在 enclave 中使用多个线程时,与线程绑定策略相关的某些条件或线程本地存储或互斥锁的使用方式可能会使 enclave 受到攻击。
  • uRTS 在 enclave 调用期间使用相同的可信线程上下文。 换句话说,它将为嵌套飞地调用选择相同的上下文。 由于在这种模式下可信线程上下文的选择是任意的,飞地内的可信运行时将在每次根飞地调用时初始化整个线程本地存储数据集。
    这意味着所有线程本地存储变量都将在每次根飞地调用开始时重置

其他重要准则

  • 英特尔SGX并没有提供一个直接的机制(例如,通过自动生成的报告字段)来区分飞地的两个(或多个)运行实例。一个飞地的两个运行实例不能仅通过它们的报告中自动生成的数据来区分。要做到这一点,必须在用来建立对底层飞地信任的协议中添加一个nonce(建议使用KEYREQUEST.KEYID字段传递一个随机数给EGETKEY指令)。

    • 为了建立对底层飞地的信任,使用硬件的RDRAND功能,并确保它被提交(直接或间接通过加密哈希),作为飞地之间交换的报告中包含的用户数据字段的一部分。
  • enclave变量释放时必须使用 memset_s() 函数释放变量空间,否则会向外部泄露机密信息。

  • 将enclave从旧系统迁移到新的系统需要一个第三服务来验证旧系统和新enclave身份。不论使用何种方式,密封密钥都不能在enclave外共享。因为它可能会危及该enclave先前密封的所有数据。

  • 由于系统信息都是在不受信任场景中收集的,所以enclave需要针对意外和不一致场景进行设计和验证。

    扫描二维码关注公众号,回复: 15256073 查看本文章
    • 可以开发专门的OCall程序来获取主机信息,比如CPUID,系统环境变量和其他应用程序属性
  • 开发人员应考虑与标准 I/O 和系统功能相关的这些指令,这些功能依赖于这些硬件指令来实现其底层。收集主机系统属性、执行 I/O 或需要更高权限级别的功能应在安全区外部执行。在某些情况下,开发人员可能有权访问受信任的替代方案,例如受信任的时间和受信任的 I/O。但是,此功能并非由英特尔 SGX 架构直接提供,目前超出了本文档的范围。

  • 平衡应用程序在enclave中执行的时间和应用程序进入/退出enclave的频率

  • 如果需要开启SGX的纵深防御机制,需要打开编译器的纵深防御功能。

    • Microsoft* Visual Studio 编译器选项 /GS 和 GNU* 编译器选项 – 当堆栈中的缓冲区大小低于特定阈值时,fstack-protector 不提供保护以避免显着的性能损失
  • 确保所有的代码是不可写的,避免注入攻击。除了enclave处理图像需要在初始化之后重定位,所以需要代码的写权限,这就有注入攻击的风险。所以enclave不能开放基于text处理的重定位权限。

    • 地址重定位:执行时加载,根据内存大小确定物理地址。
    • 如果 enclave 图像在 .text 部分中包含任何重定位,则提供给 ISV 用于签署其 enclave 的工具应输出警告,这意味着最终 enclave 将具有可写代码页。
  • enclave不支持地址空间布局随机化。

    • 英特尔® SGX SDK 包括有限的数据地址随机化,其中所有堆栈变量的地址都是随机化的。 随机化是以增加堆栈使用为代价的。 使用支持地址随机化的英特尔® SGX SDK 构建的飞地应将其堆栈大小设置增加 4 KB。 要确认您的英特尔® SGX SDK 版本支持地址随机化,请查看发行说明。
  • 开发人员应谨慎使用 enclave 内的 C++11 属性。 特别是 noreturn 属性可能会导致潜在的安全风险。 例如,如果受信任的函数调用 noreturn 函数,则在函数调用之后放置的任何清理代码都将被忽略。

电池管理

  • 英特尔 SGX 架构不提供将断电事件直接发送到飞地的方法。 应用程序可以为此类事件注册回调函数。 当调用回调函数时,应用程序可以专门调用飞地以将秘密状态保存到磁盘以供保存。 然而,操作系统不保证 enclave 有足够的时间来密封其所有内部状态。 希望跨电源转换事件保留状态的飞地必须定期密封飞地外部(在磁盘或云上)的飞地状态数据。 在重新实例化应用程序时,飞地从头开始重建,飞地必须在飞地内检索其受保护状态(从磁盘或云)。
  • 为了最大限度地减少不断密封秘密并将加密数据存储在磁盘或云中所造成的开销,enclave writer 应该设计一个应用程序 enclave,在 enclave 内部保留尽可能少的状态信息,这样应用程序就可以顺利地在电源转换事件中幸存下来 .

猜你喜欢

转载自blog.csdn.net/shuizhongmose/article/details/130130153