检测英特尔intel CPU SGX的方法教程?什么是英特尔SGX |
什么是英特尔SGX? 英特尔SGX,也就是软件防卫扩展,是2015年推出的流行架构扩展,旨在提高应用程序代码及其数据的安全性。英特尔官方网站描述,英特尔SGX通过使用enclaves来实现保护,enclaves是CPU内置的隔离存储区域。这些区域可以保护数据免受在任何特权级别(包括操作系统)运行进程的影响。相关阅读:检测服务器或者PC是否支持Intel SGX的原理和方式 概述: 英特尔® Software Guard Extensions(英特尔® SGX)SDK提供了三个功能来检测和启用系统上的英特尔 SGX 支持。CPUID 指令还提供了一个接口,用于检测 CPU 上的 Intel SGX 支持。软件开发人员的关键问题是:检测系统上英特尔 SGX 支持的正确方法是什么,以便我的应用程序及其安装程序做出相应的行为? 这似乎是一个简单的问题。如果处理器支持英特尔 SGX,应用程序可以安全地启动飞地并使用它们来保护系统上运行的其他软件的机密。如果处理器不支持英特尔 SGX,开发人员可以选择停止应用程序的功能(并向用户显示错误),或者退回到非英特尔 SGX 代码路径。 这听起来很简单,但实际情况要复杂得多。要了解原因,有必要了解 CPU 中英特尔 SGX 支持背后的详细信息、如何管理以及如何将其报告给应用程序。 平台上的英特尔® Software Guard Extensions(英特尔® SGX)支持 虽然单个 CPU 可能支持 Intel SGX,但 Intel SGX 是否真的可用取决于两个组件: BIOS 英特尔 SGX 平台软件包 我们将在下面详细讨论这两者。 BIOS 支持 英特尔 SGX 需要 BIOS 支持才能在系统中启用和配置英特尔 SGX 功能。 系统所有者必须通过 BIOS 启用它来选择加入英特尔 SGX。这需要 OEM 提供明确支持英特尔 SGX 的 BIOS。BIOS 提供的支持可能因 OEM 不同而异,甚至可能因 OEM 的产品线而异。 共有三种可能的 BIOS 设置。 已启用的
软件控制的
已禁用
注意:您的 BIOS 可能只有 Enabled 和 Disabled 选项,或者如果它只支持 Software Controlled 选项(或者根本不支持 Intel SGX),则它可能没有这些选项。请咨询您的设备制造商,以确定您的系统是否支持英特尔 SGX。 在 BIOS 中将 Intel SGX 设置为 Enabled 时,表示 Intel SGX 已启用,并且 Intel SGX 指令和资源可供应用程序使用。 当英特尔 SGX 设置为软件控制时,英特尔 SGX 最初处于禁用状态,直到通过在 SDK 中进行以下调用之一的软件应用程序启用: sgx_enable_device() sgx_cap_enable_device() 这些功能执行软件选择加入,并在下面更详细地描述。英特尔对 OEM 和 ODM 的建议是提供软件控制模式并将其设为默认设置。 当英特尔 SGX 设置为禁用时,它被明确禁用并且无法通过软件启用。要启用英特尔 SGX,最终用户必须: 在 BIOS 中将其设置回启用状态。 或者: 在 BIOS 中将其设置为软件控制状态(此时,英特尔 SGX 仍处于禁用状态,直到通过软件应用程序启用为止)。 软件控制状态有什么意义? 英特尔 SGX 最多保留 128 MB 的系统 RAM 作为处理器保留内存 (PRM),用于保存 Enclave 页面缓存 (EPC)。虽然其确切大小由 BIOS 设置决定,但重要的是要注意启用英特尔 SGX 会消耗系统资源的一部分,从而有效地使其他应用程序无法使用这些资源。 BIOS 中的软件控制设置允许 OEM 以就绪状态运送支持英特尔 SGX 的系统,可以通过软件激活(这是软件选择加入)。这是默认情况下完全启用英特尔 SGX 与潜在消耗系统资源(即使系统上没有英特尔 SGX 软件)和完全关闭之间的折衷。允许通过软件进行激活消除了最终用户将系统启动到 BIOS 设置屏幕并通过该界面手动启用英特尔 SGX 的需要,这对于非技术用户来说可能是一项艰巨的任务。 软件启用是一种单向操作:无法通过软件禁用英特尔 SGX。启用 Intel SGX 后禁用它的唯一方法是通过 BIOS 执行此操作: 如果 BIOS 提供此选项,则将 Intel SGX 显式设置为 Disabled。 或者: 将新的 BIOS 映像刷新到设备,这会将 BIOS 中的英特尔 SGX 支持重置为默认状态(禁用或软件控制,具体取决于 BIOS 提供商)。 平台软件包 要使英特尔 SGX 发挥作用,必须在系统上安装英特尔 SGX 平台软件包或 PSW。PSW 包括: 运行时库 支持和维护最终用户系统上可信计算块的服务 执行和管理关键英特尔 SGX 操作(例如证明)的服务 与平台服务的接口,例如可信时间和单调计数器 PSW 由软件供应商安装,作为应用程序安装过程的一部分。由软件供应商的应用程序安装程序来检测平台是否支持英特尔 SGX,如果支持,则运行 PSW 安装程序。 如果系统上已安装平台软件,PSW 安装包将升级现有安装(如果现有安装较旧)或退出而不采取进一步措施。 Windows* 平台 这两个库安装在 Windows 平台的系统目录中: sgx_uae_service.dll sgx_urts.dll 应用程序需要按此顺序加载 DLL。 Linux* 平台 这两个库安装在 Linux 平台上的系统库目录中(通常为/usr/lib或/usr/lib64): libsgx_uae_service.so libsgx_urts.so 应用程序需要按此顺序加载共享对象。 使用动态加载,而不是动态链接 在单个二进制文件中同时具有英特尔 SGX 和非英特尔 SGX 代码路径的应用程序必须动态加载英特尔 SGX 运行时库。动态链接不是一种选择,因为缺乏英特尔 SGX 支持的系统将不会安装 PSW 包。尝试在没有 PSW 包的系统上运行动态链接的可执行文件将导致无法解决的符号错误,从而阻止应用程序启动。 请注意,上述对 PSW 包的检查从必需共享库的动态加载开始。应用程序可以简单地保持这些句柄打开。 使用 Microsoft Visual Studio* 的 Windows 开发人员可以通过该/DELAYLOAD选项在链接器中启用延迟加载 DLL 支持。启用后,Visual Studio 会自动生成一个辅助函数,该函数在运行时根据需要为目标 DLL 执行动态加载。这允许开发人员编写他们的软件,就像他们在实际实现动态加载的同时动态链接库一样。 Linux 开发人员需要在他们的应用程序中明确使用动态加载。 PSW 库安全 作为一般规则,应用程序应从安装 PSW 的系统目录加载 PSW 库。 Windows 系统可以调用GetSystemDirectory()以获取系统目录路径,并SetDllDirectory()在调用 .dll 之前将 DLL 搜索路径设置为该目录LoadLibrary()。 正确配置的 Linux 系统应该在 中指定系统库路径f,但最终用户可以通过LD_LIBRARY_PATH环境变量对运行时环境进行重大控制。 但是,无论应用程序在哪个平台上运行,操作系统都在可信计算库之外,恶意软件可以尝试影响动态库的首选加载顺序。这可能导致英特尔 SGX 拒绝服务。应用程序开发人员可以采取基本的预防措施来缓解动态库预加载攻击,但没有万无一失的解决方案。 CPUID呢? CPUID 指令不足以检测英特尔 SGX 在平台上的可用性。它可以报告处理器是否支持英特尔 SGX 指令,但英特尔 SGX 的可用性取决于 BIOS 设置和 PSW。仅根据 CPUID 枚举做出决策的应用程序存在在运行时生成 #GP 或 #UD 错误的风险。 此外,VMM(例如 Hyper-V*)可以屏蔽 CPUID 结果,因此即使 CPUID 的结果报告未设置 Intel SGX 功能标志,系统也可能支持 Intel SGX。 适用于 Windows 系统的英特尔® Software Guard Extensions 功能检测程序 开发应用程序时,英特尔 SGX 检测必须在应用程序运行时和应用程序安装程序中进行。每个都有自己的程序。
Windows 应用程序安装程序 所有英特尔 SGX 应用程序都必须安装 PSW。在不支持 Intel SGX 的系统上安装 PSW 没有意义。应用程序安装人员必须在尝试安装 PSW 之前检查本地系统的英特尔 SGX 功能,还必须完成软件选择以启用英特尔 SGX。推荐的程序如图 1 所示。 打电话sgx_is_capable()。如果系统支持 Intel SGX,请转到第 2 步。如果不是,请不要安装 PSW 并且不要尝试选择加入软件。下一步要做什么由应用程序供应商决定,但通常有以下选项: 如果应用程序支持英特尔 SGX 和非英特尔 SGX 代码路径,请安装该应用程序。 如果应用程序作为单独的二进制文件分发,请安装非英特尔 SGX 版本的应用程序。 如果需要英特尔 SGX 支持,则完全中止安装,并告诉用户该软件与机器配置不兼容。 运行 PSW 安装程序。如果安装成功,请转至步骤 3。否则,中止安装。 调用sgx_cap_enable_device()启用 Intel SGX,然后检查返回结果。 如果结果是启用了英特尔 SGX,则无需采取进一步措施。 如果启用英特尔 SGX 成功但需要重新启动,则提示用户需要重新启动才能运行新安装的应用程序。 如果启用 Intel SGX 不成功,则向用户显示错误。 请注意,这两个功能sgx_is_capable(),并sgx_cap_enabled_device()都需要管理员权限。应用程序安装程序通常需要此级别的权限,因此英特尔 SGX 应用程序安装程序在 Windows 中触发 UAC 提示并不罕见。 因为包含这些功能的安装程序可能会在安装 PSW 之前运行,所以它们以独立的 DLL 形式提供,这些 DLL 旨在与安装程序在一起。 视窗应用程序 在运行时检测应用程序中的英特尔 SGX 与在应用程序安装程序中检测它不同。安装应用程序后,可能会出现以下情况之一: 安装程序未检测到系统支持Intel SGX,因此没有Intel SGX PSW。 该系统被检测为英特尔SGX-能够通过安装程序,因此它有它安装英特尔SGX平台软件。英特尔 SGX 的状态是: Enabled,通过在 BIOS 中显式启用或通过安装程序的软件选择启用。 在软件选择加入之前启用,这意味着用户需要在执行英特尔 SGX 指令之前重新启动他们的系统。 Disabled,意味着用户在安装应用程序后的某个时间点明确禁用了英特尔 SGX。 无论哪种情况适用,应遵循的正确应用程序如图 2 所示。
检查是否已安装 PSW。如果是,请转到第 2 步。如果不是,则平台上没有英特尔 SGX,它应该采取的操作取决于应用程序本身的代码路径。 如果应用程序支持非英特尔 SGX 代码分支,则应执行非英特尔 SGX 代码。 如果应用程序仅适用于英特尔 SGX,则它必须退出。 调用sgx_enable_device()以确保软件选择加入,并检查返回值。 如果结果是启用了英特尔 SGX,应用程序可能会执行英特尔 SGX 代码路径。 如果无法启用英特尔 SGX,应用程序应回退到非英特尔 SGX 代码路径(如果有),或退出(如果没有)。 如果结果是需要重新启动或其他一些手动操作,例如更改 BIOS,应用程序应通知用户需要采取什么操作。如果需要,应用程序可以继续使用非英特尔 SGX 代码路径。 适用于 Linux 系统的英特尔® Software Guard Extensions 功能检测程序 Linux 系统的程序与 Windows 系统的程序类似,但由于两个平台之间的差异而变得复杂。 Windows 上的 AESM 服务是 PSW 的一部分,始终为用户级进程的软件启用操作提供支持。在撰写本文时,PSW 的 Linux 发行版不提供此功能。 SDK 的 Windows 发行版包括一个名为 的 DLLsgx_capable.dll,其中包含用于检测英特尔 SGX 功能以及在以管理员权限运行时执行软件启用的函数。此库旨在供应用程序安装程序使用。适用于 Linux 的英特尔 SDK 的 1.9 及更早版本不包含等效库。但是,它可以在源代码存储库的一个分支中作为静态和动态库(分别为libsgx_capable.a和libsgx_capable.so)使用。预计将在未来版本中合并到主要发行版中。 Linux 应用程序安装程序 Linux 上的应用程序安装程序的过程与 Windows 上的相同,必须调用libsgx_capable以执行功能检测和软件启用功能。应用程序安装程序可以选择静态或动态链接到此库。 请注意,sgx_cap_enable_device()需要 root 权限才能执行软件启用,因此应用程序安装程序需要以 root 身份运行。 Linux 应用程序 应用程序的过程假定 PSW 的 Linux 发行版最终将与 Windows 达到同等水平,特别是包括该sgx_enable_device()功能。如果未找到此函数,应用程序应从sgx_cap_get_status()libsgx_capable回退到该函数。应用程序应该静态链接到这个库。 请注意,与 Windows 不同,由于 efivarfs 文件系统,用户模式进程可以检测英特尔 SGX 的状态。 Linux 应用程序要遵循的过程如图 3 所示。
检查是否已安装 PSW。如果是,请转到第 2 步。如果不是,则平台上不可用英特尔 SGX,它应采取的操作取决于应用程序本身的代码路径。 如果应用程序支持非英特尔 SGX 代码分支,则应执行非英特尔 SGX 代码。 如果应用程序仅适用于英特尔 SGX,则它必须退出。 确定函数是否在sgx_enable_device()中定义libsgx_uae_service.so。 如果sgx_enable_device()已定义,则调用该函数以尝试启用软件并获取英特尔 SGX 的结果状态。 如果未找到此函数,则调用sgx_cap_get_status()以获取 Intel SGX 的当前状态。 检查从步骤 2 中获得的英特尔 SGX 的状态。 如果结果是启用了英特尔 SGX,应用程序可能会执行英特尔 SGX 代码路径。 如果无法启用英特尔 SGX,应用程序应回退到非英特尔 SGX 代码路径(如果有),或退出(如果没有)。 如果结果是需要重新启动或其他一些手动操作,例如更改 BIOS,应用程序应通知用户需要采取什么操作。如果需要,应用程序可以继续使用非英特尔 SGX 代码路径。 细微差别 禁用与不支持 无法区分以下三种情况: CPU 不支持 Intel SGX BIOS 不支持英特尔 SGX BIOS 和 CPU 支持英特尔 SGX,但在 BIOS 中明确禁用 但是,安装程序的过程不应改变。在所有三种情况下,sgx_is_capable()都将返回零,这表明该平台不支持英特尔 SGX。 在 Linux 上链接 libsgx_capable 面向 Linux 的英特尔 SGX SDK 构建了 libsgx_capable 的静态和动态版本。应用程序安装程序可以选择静态或动态链接,但出于以下原因,应用程序本身应尽可能静态链接此库: 使用libsgx_capable在Linux应用程序是运行时特征检测桥梁的解决方案,旨在使用才在Linux上的PSW支持软件使能能力,具体而言,该sgx_enable_device()功能。 该sgx_capable.dll库不是 Windows 上英特尔 SGX 运行时的一部分,也不作为 PSW 包的一部分分发。为了最小化在两个平台之间的不一致,Linux系统不应安装任libsgx_capable.so或libsgx_capable.a到终端用户设备。 Linux 应用程序的运行时功能检测程序的结构是自动弃用 libsgx_capable 中存在的函数。动态链接会导致最终用户系统上出现一个未使用的库。 英特尔® Software Guard Extensions SDK 特征检测功能 启用程序使用英特尔 SGX SDK 中的四个功能: sgx_is_capable() sgx_cap_enable_device() sgx_cap_get_status() sgx_enable_device() 这些功能描述如下。如需更多信息,请阅读英特尔 SGX SDK 中的函数参考。 sgx_is_capable sgx_status_t sgx_is_capable(int*sgx_capable) 该函数决定了系统在当前运行环境下是否能够执行 Intel SGX 指令。返回值是类型sgx_status_t,表示查询成功或失败。 返回值 如果它返回 SGX_SUCCESS,则系统已成功查询英特尔 SGX 支持并将结果存储在*sgx_capable 中。返回SGX_ERROR_NO_PRIVILEGE意味着安装程序没有以管理员权限运行。 任何其他返回值都意味着无法确定系统的英特尔 SGX 功能。在这种情况下,应用程序安装程序应该保守并假设系统不支持英特尔 SGX。 输出参数 返回值SGX_SUCCESS并不意味着系统能够支持英特尔 SGX,只是它能够明确回答问题。要确定系统是否支持英特尔 SGX,您必须检查*sgx_capable的值:值 1 表示是,值 0 表示否。 笔记 此函数仅报告是或否,没有其他信息。它旨在成为应用程序安装程序使用的快速过滤器。如果函数报告说,该系统是Intel SGX-能力,安装程序应该安装PSW包进行。PSW 需要与所有支持英特尔 SGX 的应用程序安装程序在一起。如果系统没有SGX能力,安装程序不应试图安装PSW包。 视窗 在 Windows 系统上,此功能需要管理权限才能访问 EFI 变量。 应用程序安装程序需要sgx_capable.dll在其安装包中包含 DLL。 Linux 在 Linux 系统上,操作系统必须已安装并以 UEFI 模式启动,并且必须挂载 efi 文件系统,以便函数可以访问 EFI 变量。如果 efi 文件系统不可用或无法访问,它将无法将处于软件控制状态的系统检测为支持英特尔 SGX。 应用程序安装程序需要在libsgx_capable.so其安装程序包中包含共享库或将安装程序静态链接到libsgx_capable.a. sgx_cap_enable_device sgx_status_t sgx_cap_enable_device (sgx_device_status_t*sgx_device_status) 该函数尝试软件选择加入英特尔 SGX,并在 *sgx_device_status 中设置 SGX 的最终状态。返回值的类型sgx_status_t,并指示系统是否可以尝试该软件申请加入。返回值并不表示英特尔 SGX 设备本身是否已成功启用。这些信息被存储在* sgx_device_status只有当软件选择在尝试。 此功能需要管理员权限,因为它必须访问通过 BIOS 提供的软件控制接口。它的目的是通过应用程序调用安装程序,并执行PSW已经被安装,以使英特尔SGX后。 返回值 如果这个函数返回SGX_SUCCESS时,软件选择在尝试,而尝试的成功或失败被保存在* sgx_device_status。 如果返回值是SGX_ERROR_NO_PRIVILEGE,安装程序并没有以管理员权限运行。 任何其他返回值意味着无法在此系统或当前环境中尝试选择加入软件。在这种情况下,应用程序安装程序应该保守,并假设无法通过该系统上的软件选择启用英特尔 SGX。 输出参数 的返回值SGX_SUCCESS并不意味着英特尔SGX已成功启用,仅仅是软件选择,在被尝试。接下来必须检查存储在*sgx_device_status 中的值。 SGX_ENABLED表示已启用 Intel SGX。 SGX_DISABLED_REBOOT_REQUIRED意味着软件选择成功,但需要重新启动才能完成英特尔 SGX 启用。尝试在运行时检测英特尔 SGX 可用性的应用程序将被告知英特尔 SGX 在重新启动之前不可用。 任何其他值表示软件选择失败,用户必须通过 BIOS 设置屏幕手动启用英特尔 SGX。 笔记 由于此功能需要管理权限,因此不应由英特尔 SGX 应用程序运行。但是,它目前是在 Linux 系统上执行软件启用的唯一方法,因此适合在旨在由 root 执行的独立二进制文件中使用。 视窗 Windows 应用程序安装程序需要sgx_capable.dll在其安装包中包含 DLL。 Linux Linux 应用程序安装程序需要在libsgx_capable.so其安装程序包中包含共享库或将安装程序静态链接到libsgx_capable.a. sgx_cap_get_status sgx_status_t sgx_cap_get_status (sgx_device_status_t*sgx_device_status) 此函数检查当前系统上英特尔 SGX 的状态,如果不可用,状态代指出原因。sgx_is_capable()当需要有关英特尔 SGX 状态的更多信息时,它是一种替代方法。 在 Windows 上,这仅供应用程序安装程序使用。在 Linux 上,应用程序和安装程序都可以使用它。 视窗 在 Windows 系统上,此功能需要管理权限才能访问 EFI 变量。 它旨在供应用程序安装程序使用,因此可以要求用户通过软件控制界面确认启用英特尔 SGX。如果函数报告*sgx_device_status代码SGX_DISABLED_SCI_AVAILABLE,安装程序将继续执行软件启用程序。 安装程序需要DLL sgx_capable.dll在他们的安装包中包含 。 Linux 在 Linux 系统上,操作系统必须已安装并以 UEFI 模式启动,并且必须挂载 efi 文件系统,以便函数可以访问 EFI 变量。如果 efi 文件系统不可用或无法访问,那么它将无法将处于软件控制状态的系统检测为支持英特尔 SGX。 当一个应用程序安装程序使用,如果函数报告说,该系统是Intel SGX-能够安装程序应继续安装PSW包。PSW 需要与所有支持英特尔 SGX 的应用程序安装程序在一起。如果系统不支持Intel SGX,则安装程序不应尝试安装 PSW 包。 Linux 安装程序需要在libsgx_capable.so其安装程序包中包含共享库或将安装程序静态链接到libsgx_capable.a. sgx_enable_device sgx_status_t sgx_enable_device (sgx_device_status_t *sgx_device_status) 此功能类似于sgx_cap_enable_device(),但它旨在由应用程序而不是安装程序运行。 它不需要管理权限;它联系在本地机器上运行的 AE 服务,并要求该服务尝试选择加入软件。请注意,这会导致对 PSW 的依赖:它必须安装在系统上。 sgx_enable_device()一旦应用程序验证 PSW 库存在于系统中,应用程序就会运行以确保英特尔 SGX 可供使用。返回值和英特尔 SGX 设备状态几乎与sgx_cap_enable_device(). 因为必须安装 PSW 才能运行此功能,所以安装人员不能调用它。 Linux PSW 的 Linux 版本未实现此功能,因此此功能未包含在英特尔 SGX SDK 的 Linux 版本中。 为 Linux 获取 libsgx_capable 英特尔 SGX SDK 1.9 及更早版本的 Linux 发行版不包含 libsgx_capable。要获取此库,您必须从 Github* 上的存储库获取英特尔 SGX SDK 源代码并从主分支构建 SDK。 SDK 安装程序会将库放置在 SDK 库目录中。 代码示例 提供的代码示例将这些过程实现为一对独立的可执行文件,用于演示目的:一个用于应用程序安装程序,另一个用于运行时的应用程序。这些代码示例在 Windows 和 Linux 中构建。 负责检查每个,is_sgx_supported(), 的函数原型如下: int is_sgx_supported(UINT*sgx_support); 如果它可以成功确定系统上英特尔 SGX 支持的状态,则返回 1,如果由于错误而无法确定,则返回 0。 英特尔 SGX 支持的状态放置在变量sgx_support 中,该变量作为指向函数的指针传递。它是以下位的组合: #define ST_SGX_UNSUPPORTED 0x0 #define ST_SGX_CAPABLE 0x1 #define ST_SGX_ENABLED 0x2 #define ST_SGX_REBOOT_REQUIRED 0x4 #define ST_SGX_BIOS_ENABLE_REQUIRED 0x8 当且仅当该ST_SGX_ENABLED位被设置时,系统才能执行英特尔 SGX 指令。其他位仅传达有关英特尔 SGX 支持状态的附加信息(如果有),以及启用它可能需要采取哪些进一步措施。 结论 在运行时回答系统是否已启用英特尔 SGX 的问题很复杂。对 BIOS、PSW 和最终用户自己的操作的依赖性意味着系统可以支持英特尔 SGX,但尚未完全启用或准备好使用。应用程序需要正确识别英特尔 SGX 支持的状态,以确保它们执行正确的代码路径,并避免误报和漏报。此处描述的过程是推荐的方法。 附件:sgx-feature-detection.zip 来源: 波卡PHA矿机、PHA挖矿、Phala矿机、波卡PHA服务器详询陆零网络客服,/span> |