大家读完觉得有帮助记得关注和点赞!!!
概要
GPU 机密计算 (GPU-CC) 是作为 NVIDIA Hopper 架构的一部分引入的,它将信任边界扩展到传统的基于 CPU 的机密计算之外。这项创新使 GPU 能够安全地处理 AI 工作负载,为处理敏感数据提供强大而高效的解决方案。对于最终用户来说,过渡到 GPU-CC 模式是无缝的,不需要修改现有的 AI 应用程序。然而,这种易于采用与底层专有系统的复杂性形成鲜明对比。缺乏透明度给寻求更深入地了解 GPU-CC 架构和作机制的安全研究人员带来了重大挑战。
分析 NVIDIA GPU-CC 系统的挑战源于缺乏详细规格、生态系统的专有性质以及产品设计的复杂性。在本文中,我们旨在通过拼凑从各种来源披露的碎片化和不完整的信息来揭开 NVIDIA GPU-CC 系统实现的神秘面纱。我们的调查从对威胁模型和安全原则的高级讨论开始,然后深入研究每个系统组件的低级细节。我们对 GPU 内核模块(系统唯一的开源组件)进行检测,并进行一系列实验以确定安全漏洞和潜在漏洞。对于某些通过实验无法触及的组件,我们提出了关于其内部工作机制的合理推测。我们已负责任地向 NVIDIA PSIRT 团队报告了本文中提供的所有安全发现。
1.介绍
机密计算支持将涉及敏感数据的计算安全地外包到公有云基础设施上的可信执行环境。其目标是确保数据在使用时的机密性和完整性。该领域的初步工作集中在 CPU 机密计算 (CPU-CC) 上,它保护 CPU 包内的计算并加密驻留在系统内存中的数据。然而,随着计算工作负载的发展,特别是随着大型语言模型的爆炸式增长,越来越多的计算和数据被卸载到图形处理单元,以利用其大规模并行性。
为了满足这一转变,NVIDIA 最近引入了对 GPU-CC 的支持 (Dhanuskodi 等人,2023)在其 Hopper 架构中(以及即将推出的 Blackwell 架构中)。对 GPU-CC 的软件支持正在逐渐集成到 CUDA 和 NVIDIA 内核驱动程序中。GPU-CC 将信任边界从 CPU 扩展到 GPU,利用 CPU-CC 和 GPU-CC 技术将人工智能 (AI) 计算管道封装在一个统一的受保护域中。GPU-CC 显著拓宽了需要 GPU 加速和安全执行环境的 AI 应用程序的领域。它在模型所有者、数据所有者和计算提供商之间建立了明确的角色和特权分离,同时在 CPU 和 GPU 的受信任域中保护计算和数据的机密性和完整性。此外,GPU-CC 还可以用于安全的协作学习,允许多个相互不信任的一方共同执行 AI 计算。
对于最终用户来说,启用 GPU-CC 是无缝的 — AI 应用程序无需修改即可运行。但是,启用 GPU-CC 需要对底层系统堆栈进行大量更改。这包括对 CUDA 运行时和用户模式驱动程序、NVIDIA UVM 和内核模式驱动程序的修改,以及 GPU 上一套专用硬件引擎的支持。对于安全研究人员和性能工程师来说,了解 GPU-CC 的内部工作原理至关重要。然而,由于缺乏公共规范、NVIDIA 生态系统的专有性质以及所涉及的架构复杂性,分析该系统带来了重大挑战。
在本文中,我们揭开了 NVIDIA Hopper GPU 在 GPU-CC 模式下的作的神秘面纱。我们首先简要概述了威胁模型和指导其设计的安全原则。然后,我们深入研究了共同支持 GPU-CC 的关键架构组件、引导过程、数据保护机制和证明流程。我们的方法综合了来自不同来源的碎片化信息,以重建对系统的连贯和全面的理解。这种理解基于实验证据和系统分析。对于每个组件,我们详细介绍了所采用的实验方法,并重点介绍了由此产生的安全见解。在无法获得直接信息的情况下,我们会提供合理的推测来填补空白。最终,这项工作旨在阐明 GPU-CC 的现状,并为安全社区内对这项新兴技术的未来研究奠定基础。总之,本文做出了以下主要贡献:
威胁模型和安全原则检查。我们对 NVIDIA GPU-CC 解决的威胁模型进行了系统检查,概述了它旨在防止的攻击类型、信任根中的组件以及可能仍然暴露的信息类别。我们还介绍了支撑 GPU-CC 系统设计的核心安全原则。
系统架构探索。我们对 NVIDIA GPU-CC 架构进行了深入探索,重点关注关键组件及其作用。我们的分析扩展了 NVIDIA 官方材料中记录较少或仅简要提及的技术细节.这种理解来自审计和检测 CUDA 堆栈、 GPU 内核模块以及组件间通信。
数据保护机制的安全分析。我们进行了专门的安全实验,以评估 NVIDIA GPU-CC 的引导和数据保护机制的稳健性。对于每种机制,我们都会评估通过不受信任的接口泄露的潜在信息,讨论漏洞利用的风险,并提出可能的缓解措施。本文中提供的所有安全结果均已负责任地披露给 NVIDIA PSIRT 团队。
2.背景和相关工作
CPU-CC 技术。NVIDIA GPU-CC 无法独立运行。它必须与基于虚拟机 (VM) 的 CPU-CC 结合使用,例如 Intel Trust Domain Extensions (TDX) .CPU-CC 通过实施与主机环境(包括虚拟机管理程序、系统管理员和 I/O 设备)的加密隔离来保护机密虚拟机中计算和数据的机密性和完整性,这些环境被视为不受信任或可能受到威胁。这种保护依赖于安全功能,例如受信任的 VM 管理和运行时内存加密。每个云服务器都分配了一个唯一的临时密钥,用于加密内存。On-die 内存控制器中的高级加密标准 (AES) 引擎处理在 CPU 和 CVM 的私有内存之间传输的数据的加密和解密。CPU-CC 还支持远程认证,以验证可信平台的真实性和完整性。
CPU-CC 中的 I/O 保护。CPU-CC 的信任边界仅限于 CPU 及其指定的私有内存区域。当数据离开此边界时(例如,在 I/O作期间),它必须通过不受信任的组件,例如虚拟机管理程序和 I/O 设备。I/O 设备通常使用直接内存访问 (DMA) 来读/写内存,而无需 CPU 参与。由于这些设备不受信任,因此不允许它们直接访问 CVM 的私有内存,该内存使用 CVM 的密钥进行加密。一般做法是采用基于软件的加密机制,例如,传输层安全性 (TLS) 用于网络流量,Linux 统一密钥设置 (LUKS) 用于磁盘加密。在此模型中,I/O 绑定数据首先使用 TLS 或 LUKS 在 CVM 的私有内存中加密,然后传输到暂存缓冲区。此缓冲区位于 CVM 的加密内存之外,I/O 设备可通过 DMA 访问。因此,加密的 I/O 数据可以安全地传输到设备。
GPU-CC 研究。但是,GPU 不仅仅是一个简单的 I/O 设备。它最初是为图形渲染而设计的,现已发展成为由众多流式多处理器组成的通用计算设备,并配备了高带宽设备内存。在执行之前,代码和数据必须以明文形式加载到 GPU 内存中。不幸的是,CPU 和 GPU 之间的 PCIe 互连通常被认为是不受信任的,并且容易受到窥探和篡改攻击。将机密计算的信任边界从 CPU 扩展到 GPU 需要建立端到端的安全通道来桥接这种不受信任的互连。
Wang 和 Oswald(Wang 和 Oswald,2024)全面调查了 CPU-GPU 系统机密计算的最新进展。支持 GPU-CC 的研究工作始于 Graviton 等系统.Graviton 提议对 GPU 的命令处理器进行修改,而 HIX 则对 I/O 互连进行了更改。然而,由于 NVIDIA GPU 的专有性质,Graviton 的方法只能通过仿真进行评估,而 HIX 缺乏对 PCIe 和 GPU 内存的基于硬件的攻击的保护。为了避免硬件修改,研究人员还探索了基于软件的 GPU-CC 方法。例如,SAGE(Ivanov 等人,2023)使用 Intel Software Guard Extensions (SGX) 作为本地验证器,在 GPU 上建立动态信任根,而 Honeycomb(Mai 等人,2023)执行静态分析以在加载时验证 GPU 应用程序。机密计算也被探索用于其他加速器,例如 IPU(Vaswani 等人,2023)和 NPU(Lee 等人,2022),其中自定义硬件通常具有更大的灵活性。除了 x86 系统之外,GPU-CC 还在 Arm 系统的背景下进行了研究(Wang 等人,2024;江 et al.,2022;邓等人,2022).
设计 GPU-CC 的最大挑战之一源于商用 GPU 的不变性。虽然修改硬件和固件是在 GPU 上实现安全执行的最直接途径,但它通常是不切实际的。但是,像 NVIDIA 这样的 GPU 供应商可以灵活地将机密计算功能直接添加到他们的硬件/固件中。NVIDIA 推出首款商用 GPU-CC 解决方案(Dhanuskodi 等人,2023)作为其 Hopper 架构的一部分。最近的研究开始专注于提高 NVIDIA GPU-CC 的性能(Mohan 等人,2024;Tan 等人,2024;Tan 和 Mi,2024).然而,使用 GPU-CC 系统和了解其内部工作原理之间仍然存在很大差距,这主要是由于 NVIDIA 生态系统的封闭性。这种缺乏透明度使得很难评估 NVIDIA GPU-CC 是否满足机密计算的安全要求,或者其实现是否可以承受各种攻击媒介。本文旨在通过首次对 NVIDIA GPU-CC 架构进行深入研究,以及对系统进行全面的安全分析来弥合这一差距。我们的研究重点是 NVIDIA H100 GPU 的 GPU-CC。在撰写本文时,当前 Hopper 版本中禁用了对 GPU-CC 的多 GPU 支持,并且计划将 Trusted I/O 包含在即将推出的 Blackwell 架构中。我们将在附录的 C 节中讨论这两个主题。
3.威胁模型
NVIDIA GPU-CC 继承并扩展了基于虚拟机的 CPU-CC 技术(如 Intel TDX 和 AMD SEV-SNP)的威胁模型。
CPU-CC 的威胁模型。CPU-CC 威胁模型与多租户云环境相关。攻击者可以是利用漏洞渗透到云管理系统中的外部攻击者,也可以是恶意云管理员等内部攻击者。假定这些攻击者对主机具有物理或远程访问权,从而可能获得对启动固件、系统管理模式 (SMM)、主机作系统 (OS)、虚拟机管理程序和外围设备的控制权。他们还可以访问主机系统内存。
攻击者的目标是破坏云租户拥有的 VM 中代码和数据的机密性和完整性。此威胁模型不考虑损害系统可用性,因为攻击者可以控制计算资源并从主机发起拒绝服务 (DoS) 攻击。
NVIDIA GPU-CC 威胁模型中的扩展。假设离散的 NVIDIA GPU 连接到主机系统。对手可以物理或远程访问 GPU,允许他们通过带内工具(例如 nvtrust )查询或修改 GPU 设置,包括 GPU-CC 配置(英伟达,2025 年一)) 或带外接口,例如基板管理控制器 (BMC)。它们还可以刷新 GPU 的 VBIOS 并更新 GPU 固件。此外,攻击者可以虚拟地将 GPU 从一个 VM 分离和/或将其重新分配给另一个 VM。也可以从 PCIe 总线中物理移除 GPU,尽管此类作通常被视为 DoS 攻击。
CPU 和 GPU 之间的互连(例如 PCIe)被认为是不受信任的,允许对手在总线上插入并捕获流量。但是,威胁模型排除了高级物理攻击,例如解封 GPU 包和探测 GPU 内核与封装上高带宽内存 (HBM) 之间的内部互连,因为此类攻击在实际场景中被认为是非常不切实际的。因此,与 CPU-CC 不同,GPU-CC 仅依靠访问控制机制(如防火墙)来保护封装上的 GPU 内存。它不使用运行时内存加密来防范这种解封装攻击。
攻击者的目标是破坏在 CVM 到 GPU 之间传输的数据的机密性和完整性。这些数据包括 CVM 和 GPU 系统处理器 (GSP) 之间的远程过程调用 (RPC)、CVM 和 GSP 之间的内存传输、统一虚拟内存 (UVM)作、内存清理作、内存故障交付、CUDA作等。
4.安全原则

图 1.CVM 和 GPU 之间的安全数据交换
本节讨论 NVIDIA GPU-CC 的安全原则,以解决威胁模型中提到的攻击。
安全启动。根据威胁模型,假定攻击者可以访问 GPU,并可能尝试使用恶意代码刷写 VBIOS 或更新 GSP 固件。为了减轻此类威胁,NVIDIA GPU-CC 实施了一种安全启动机制,可确保所有固件组件都是真实的、未被篡改的,并由受信任的机构(例如 NVIDIA)加密签名。第 5 节详细介绍了 GPU-CC 中涉及的硬件引擎,第 6.1 节介绍了它们的安全启动过程。
设备证明。虽然安全启动可确保加载的固件是真实的并已签名,但它无法保证固件没有漏洞或未被撤销。此外,有权访问主机的对手可以自由修改 GPU-CC 设置。为了解决这些限制,采用设备认证来验证 GPU-CC 系统是否在安全状态下运行,例如,使用最新的固件和驱动程序,以及正确配置的安全设置。GPU-CC 支持生成签名认证报告,其中包括设备身份、VBIOS 和固件测量以及当前安全设置。CVM 中的认证代理可以验证此报告,以确保 GPU 在启用 GPU-CC 功能之前符合预期的安全策略。我们在第 8 节中详细介绍了 NVIDIA GPU-CC 认证。
存取控制。OS 和 PCIe 设备通过基址寄存器进行通信,允许 OS 访问设备的控制寄存器和内存。在 NVIDIA GPU 中, BAR0 映射到控制寄存器,而 BAR2 (或 BAR1,取决于模型)映射到 GPU 内存。当 GPU 传递到 VM 时,主机上的 VFIO-PCIe 驱动程序也可以访问这些 BAR 区域,该驱动程序在机密计算的威胁模型下不再受信任。为了防止不受信任的主机恶意访问或纵 GPU,GPU-CC 实现了两个关键的访问控制机制:
BAR0 解耦器。只有最小的控制寄存器子集通过 BAR0 公开,而大多数寄存器被阻止。我们在 6.2 节中分析了这种机制的有效性。
限制对 GPU 内存的访问。GPU 内存的很大一部分(例如 90%)可以指定为计算保护区域 (CPR)。阻止 CPR 的直接入口和出口。云服务器和 GPU 之间的所有数据交换都必须通过受控接口。此机制依赖于基于安全协议和数据模型 (SPDM) 的密钥协商,并使用暂存缓冲区作为数据传输的中介。如图 1 所示,CVM 和 GPU 使用 SPDM 协议协商加密密钥。暂存缓冲区是一个共享的、未加密的内存区域,可供 CVM 和 GPU 访问。在受保护的内存区域(即 CVM 的私有内存或 GPU 的 CPR)之间传输的任何数据都必须首先使用协商的密钥进行加密,然后才能放入暂存缓冲区。检索时,将使用相同的密钥解密数据。尽管可以从主机访问暂存缓冲区,但攻击者观察到的任何数据都应保持加密且无法理解。我们在第 6.3 节中讨论了 SPDM 密钥协商过程,并在第 7 节中分析了所有数据保护机制及其限制。
数据清理。由于解封装攻击被认为非常不切实际,因此超出了范围,因此 GPU-CC 不实施运行时内存加密。但是,假定攻击者能够将 GPU 从一个 VM 分离并将其重新分配给另一个 VM。在这种情况下,GPU 中的残留数据可能会泄露先前执行的信息。此外,敏感材料(例如用于保护传输中的数据的加密密钥)可能仍驻留在 GPU 内存中。为了降低这种风险,必须在重新使用之前清理所有内存并重置设备。此内存清理过程由安全处理器 (SEC2) 引擎管理,我们将在 Section 7.4 中详细描述其机制。
5.GPU-CC 架构引擎

图 2.GPU-CC 中的软件/硬件元素
已设计、定制或专门用于支持 GPU-CC 的多个架构引擎。其中包括基础安全处理器 (FSP)、GPU 系统处理器 (GSP)、安全处理器 (SEC2) 和复制引擎 (CE)。如图 2 所示,这些引擎直接与 NVIDIA 软件组件交互,例如 NVIDIA 内核模式驱动程序、 UVM 驱动程序和 CUDA 用户模式驱动程序。在下文中,我们概述了每个引擎的关键功能及其在启用 GPU-CC 中的作用。
5.1. Foundation 安全处理器 (FSP))
FSP 是一种 RISC-V 微控制器,在信任链的早期进行安全启动。有关 FSP 的公开信息有限。我们只知道,一旦 FSP 安全初始化,NVIDIA 内核模式驱动程序就会通过与 FSP 的通信通道将 GSP 的第一可变代码 (FMC) 和 GSP 的资源管理器 (RM) 微码/固件作为二进制 blob 传输.这些 blob 使用 NVIDIA 的可信私钥进行数字签名,以确保完整性和真实性。FSP 在 GSP 上初始化和启动 GSP-RM 之前验证签名。信任链引导过程的详细概述可以在 Section 6.1 中找到。
5.2. GPU 系统处理器 (GSP)
GSP 将 GPU 初始化和资源管理任务从内核模式驱动程序卸载到 GPU。GSP 引擎是一个 RISC-V 微控制器,配备了 AES 硬件,用于加密和解密。它仅与 NVIDIA 内核模式驱动程序通信。
启用 GPU-CC 后,将在启动 GSP-RM 之前建立 SPDM 会话。GSP 托管 SPDM 响应程序,在握手过程中,NVIDIA 内核模式驱动程序与 SPDM 响应程序协商共享主密钥。此密钥是派生所有共享密钥的基础,这些密钥用于保护 CVM 和 GPU 之间的通信。有关 SPDM 会话建立的更多详细信息,请参见 Section 6.3。
一旦 GSP-RM 启动,它就会通过 RMAPI RPC 通道与 NVIDIA 内核模式驱动程序通信,并通过 CPU-GSP DMA 通道传输内存。从主密钥派生的单独共享密钥保护通过双向 RPC 和 DMA 通道传输的数据。此外,在 GSP 中运行的安全软件可以清理所有输入和输出,以防止虚拟机管理程序或主机进行未经授权的访问或篡改。有关 CPU 和 GSP 之间的 RPC 通信和安全内存传输的更多详细信息,请参见第 7.1 节和第 7.2 节。
5.3. 安全处理器 (SEC2)
SEC2 是专为 GPU-CC 设计的 RISC-V 微控制器。SEC2 只能解密和验证数据,但不能加密数据。与 GSP 不同,SEC2 可供内核模式客户端(例如 NVIDIA 内核模式驱动程序和 UVM 驱动程序)和用户模式客户端(例如 CUDA 用户模式驱动程序)访问。基于 NVIDIA 专利中的功能描述(Rogers 等人,2023 年一,b,2025),SEC2 提供多种安全功能:
CPR 和 GPU-CC 模式的设置。根据专利(Rogers 等人,2023 年一,2025)的 SEC2 负责创建 CPR 并将 GPU 转换为 GPU-CC 模式。GPU-CC 模式设置可以存储在连接到 GPU 的 EEPROM 中,但只有在下次 GPU 重置后才会生效。但是,演示文稿中的描述(安托万·德利纳特-拉沃德,2023)关于哪个引擎设置 GPU-CC 模式略有不同。它表示此作由 FSP 控制,SEC2 未出现在图中。由于 GPU 端实现尚未开放,因此确切的细节仍不清楚。尽管如此,FSP 和 SEC2 都属于可信边界,这意味着处理作的这种差异不会带来安全隐患。
设备证明。根据 NVIDIA 的专利(Rogers 等人,2023 年一,b,2025),SEC2 负责生成鉴证报告,以证明 GPU 的真实性和可信度。设备身份密钥在硅制造过程中烧录到密钥保险丝中,是唯一且不可变的。设备身份密钥只能由 SEC2 访问,从而防止任何其他实体的访问。认证报告使用从芯片中嵌入的加密身份层次结构派生的认证密钥进行签名。然而,表现(安托万·德利纳特-拉沃德,2023)表示 FSP 负责生成认证报告。尽管确切的细节也尚不清楚,但从用户的角度来看,这种差异不会影响流程。鉴证的详细过程可在第 8 节中找到。
安全的数据交换。 SEC2 引擎与 CVM 共享密钥,以保护传输中的数据。CVM 可以在将数据放入不受保护的暂存缓冲区之前,使用这些共享密钥对数据进行签名或加密。然后,SEC2 引擎检索数据:如果数据已签名,SEC2 将验证其完整性以检测传输过程中的任何篡改;如果已加密,SEC2 会解密数据并将其存储在 GPU 的 CPR 中。
内存清理。GPU 的 CPR 中的敏感数据在不再需要时必须擦除。NVIDIA 内核模式驱动程序可以建立与 SEC2 引擎关联的 SWL 洗涤器通道。当物理内存页被释放并需要清理时,将对提交到 SWL 洗涤器通道的命令进行签名以防止篡改。SEC2 可以触发 GPU 的软重置,确保在 GPU 内存在系统总线上可见之前,所有共享密钥都将被删除,内存将被擦除。有关内存清理的更多详细信息,请参见 Section 7.4。
安全工作负载提交。 SEC2 可用于引导安全工作负载提交。CUDA 用户态驱动程序和 UVM 驱动程序可以分配绑定到 SEC2 引擎的安全通道,从而确保命令的完整性。此通道中的命令可以使用共享 HMAC 密钥进行签名。SEC2 在执行之前验证这些命令的完整性。Section 7.3 中提供了更多详细信息。
5.4. 复制引擎 (CE)
CE 管理 GPU 的内存传输,并包括用于加密和解密的 AES 硬件。它利用一个或多个逻辑复制引擎和物理复制引擎,它们在 GPU 中作为硬件块实现。PCE 处理数据移动,而 LCE 管理 PCE 的控制逻辑。
LCE 可供内核模式客户端(例如 NVIDIA 内核模式驱动程序和 UVM 驱动程序)和用户模式客户端(例如 CUDA 用户模式驱动程序)访问。客户端可以使用从 NVIDIA 内核模式驱动程序获取的加密密钥分配安全通道来安排使用 LCE 的工作。每个 LCE 与 CVM 中的内核模式驱动程序协商四个密钥:两个密钥用于用户态使用,两个密钥用于内核模式使用。对于每种模式,一个密钥保护主机到设备 (h2d) 的数据传输,而另一个密钥保护设备到主机 (d2h) 的传输。绑定到同一 LCE 的所有通道共享相同的密钥。
数据移动保护。 CE 确保从 CPR 复制到非 CPR 内存的数据被加密,同时从非 CPR 传输到 CPR 的数据被解密和完整性检查。例如,它可以从未受保护的内存中检索加密的 GPU 推送缓冲区或 CUDA 内核,在执行之前将它们解密为 CPR。相反,CE 可以在 CPR 中对数据进行加密和签名,然后再将其移动到不受保护的内存,例如当 GPU 发送加密和签名的同步信号(例如信号量)以通知命令完成时。然后,客户端可以解密并验证这些信号以继续。此外,它还可能支持 CPR 到 CPR 和非 CPR 到非 CPR 内存之间的明文传输。我们将在 Section 7.3 中讨论一些使用 CE 的特定 UVM 案例。
内存访问控制。 CE 与 GPU 的内存管理单元 (MMU) 结合使用,通过将计算引擎限制为 CPR 内存来实施访问控制。一旦计算引擎访问 CPR,它就会被阻止访问任何其他未受保护的内存区域。任何访问 CPR 之外的内存的尝试都会被阻止,从而触发故障。值得注意的是,故障传递发生在不受信任的接口上,因此需要额外的保护。有关错误传递保护的更多详细信息,请参见 Section 7.5。
重放攻击预防。AES 的初始化向量用于防止重放攻击。虽然同一 CE 上的通道共享相同的 h2d 和 d2h 密钥,但每个通道独立维护自己的 h2d 和 d2h 对 IV,并在每次加密或解密后递增它们。因此,由于身份验证标记不匹配,重播旧密文的尝试将失败。
6.GPU-CC 引导
本节介绍 GPU-CC 初始化过程,包括: (1) GPU-CC 所需的架构引擎的安全启动。 (2) 防火墙配置,用于阻止通过 BAR 对 GPU 寄存器和 CPR 的常规访问。 (3) SPDM 会话建立,用于协商加密密钥,以保护 CVM 和 GPU 之间的通信。
6.1.架构引擎的安全启动
根据 NVIDIA 开发者论坛中分享的信息(英伟达,2024),则信任链遵循以下顺序:CEC EROT(如果存在)→ 全汉 → 普惠制 → SEC2.这里,CEC EROT 指的是 Microchip 的 CEC1736 (微芯片,[n. d.]),一个实时信任根 (RoT) 控制器,其中 EROT 代表“外部信任根”。CEC1736作为硬件 RoT 发挥着关键作用,锚定安全启动过程并建立系统的信任链。CEC EROT 和 FSP 的 BootROM 都验证 FSP 固件。这种双层验证可确保在 FSP 完全启动之前进行外部和内部完整性检查。
FSP 安全启动后,NVIDIA 内核模式驱动程序会通过管理组件传输协议 (MCTP) 向 FSP 发送命令,以启动 GSP 启动过程。此命令包括 GSP-FMC 映像的系统内存地址及其身份验证字段(例如哈希、公钥和签名),使 FSP 能够在启动 GSP-RM 之前验证微码的真实性和完整性。此外,该命令还包含 GSP-FMC 的引导参数,允许其获取、验证和加载 GSP-RM 固件。值得注意的是,GSP-FMC 在 NVIDIA 内核模式驱动程序的源代码中作为预先生成的二进制存档分发,而 GSP-RM 则作为驱动程序安装在系统目录中的二进制文件提供。这种方法提供了在运行时更新 GSP 固件的灵活性。
GSP 负责验证和启动 SEC2 引擎,但具体步骤尚不清楚,因为该过程隐藏在 GPU 中。预置和更新 SEC2 固件的方法也未知。我们推测 SEC2 的推出可能遵循类似的安全启动和经过身份验证的代码加载方法。SEC2 固件映像应由 NVIDIA 进行加密签名,GSP 使用嵌入式公钥验证签名,公钥可能存储在硬件或一次性可编程 (OTP) 内存中。通过所有检查后,GSP 可以继续加载和初始化 SEC2 引擎。
6.2.防火墙

图 3.通过 GPU 的 BAR0 读取的数据分类
在非 GPU-CC 模式下,主机上的系统管理员可以通过 BAR 自由访问和修改 GPU 的控制和状态寄存器,以及其设备内存。这些寄存器配置了各种 GPU 设置,而设备内存可能包含 CVM 中预置的敏感用户数据。由于主机及其管理员和软件堆栈在机密计算的威胁模型中不再被视为可信,因此基于 BAR 的 PCIe 访问大大扩大了攻击面。
为了缓解这种情况, NVIDIA 的论文(Dhanuskodi 等人,2023)指出启用 GPU-CC 模式会激活 PCIe 防火墙机制,该机制会阻止对大多数控制寄存器和 GPU 内存的 CPR 进行未经授权的访问。但是,仍可访问有限的寄存器子集以支持基本的 GPU 管理作。
这些 registers 驻留在 BAR0 映射的地址空间中。一个关键问题是确定启用 GPU-CC 后哪些寄存器仍可访问,以及它们的暴露是否会带来任何潜在的安全风险。遗憾的是,NVIDIA GPU 控制寄存器的规范是专有的,没有公开文档详细说明每个寄存器的功能。通过 GPU 内核模块和 nvtrust 实用程序引用了有限数量的 register 字段。
尽管单个寄存器的确切语义仍不清楚,但我们试图定量评估启用 GPU-CC 模式前后寄存器可访问性的差异。为此,我们开发了一个扫描程序,模拟对手在两个 H100 GPU 上探测整个 BAR0 空间——一个在常规模式下运行,另一个在 GPU-CC 模式下运行。程序从 BAR0 读取,从偏移量 0x0 开始,并以 4 字节的步幅前进。假设 BAR0 在 H100 上跨越 16 MB,这会导致总共 0x400000 次读取作。
我们将返回的值分为三种类型:(1) 值:非零数字返回,(2) 零:返回0x0的读取,以及 (3) 错误:读取以 0xbadxxxxx 形式返回错误代码。如图 3 所示,在非 GPU-CC 模式下,7.94% 的字段返回值,80.25% 的字段返回错误。相比之下,在 GPU-CC 模式下,99.78% 的字段返回零,只有 0.02%(1042 个字段)返回非零值,0.19% 返回错误。这种显着的归零效果归因于防火墙的 BAR0 Decoupler 的激活,它隐藏了大多数 control registers。
从对抗的角度来看,解耦器通过返回零来混淆寄存器可见性,因此很难确定字段是简单的未映射还是受保护。然而,一小部分 (0.02%) 的可访问字段会引发安全问题。我们主张 NVIDIA 对这些公开寄存器的功能及其 GPU 管理的必要性保持透明。
除了寄存器访问之外,PCIe 防火墙还阻止主机访问 GPU 内存的 CPR。此限制从根本上改变了 CVM 和 GPU 之间的数据交换方式。我们将在第 7 节中详细研究这种执行的影响和机制。
6.3.SPDM 和密钥派生
NVIDIA 内核模式驱动程序中的 SPDM 请求者初始化与 GSP 中的 SPDM 响应程序的 SPDM 会话。此会话建立了一个共享主密钥,GPU-CC 中使用的所有加密密钥都是从该密钥派生的,以保护通过不受信任的接口进行的加密通信。附录的表 1 中提供了派生密钥的完整列表。
对于 GSP,将派生以下六个密钥:gsp_cpu_locked_rpc 和 cpu_gsp_locked_rpc 密钥用于保护 RPC 通信。gsp_cpu_dma 和 cpu_gsp_dma 密钥用于保护内存传输。附加两个密钥 gsp_cpu_replayable_fault 和 gsp_cpu_non_replayable_fault 保护可重放和不可重放故障数据包从 GSP 到 CPU 的传输。
对于 SEC2,派生了六个密钥来保护安全的工作负载启动通道和洗涤器通道。数据密钥用于加密从 CPU 发送到 SEC2 的数据。HMAC 密钥用于对数据进行签名以进行完整性验证。 每个密钥都在用户模式(例如,由 CUDA 用户模式驱动程序)或内核模式(例如,由 UVM 驱动程序)中使用。cpu_sec2_data_scrubber 和 cpu_sec2_hmac_scrubber 键由 SWL 洗涤器通道使用。
在 H100 GPU 上,八个 LCE 支持安全通信,每个 LCE 在用户和内核模式下都有用于 h2d 和 d2h 通信的不同密钥。这导致总共 32 个派生密钥。
7.数据保护机制
本节探讨保护通过不受信任的接口传输的数据的机制。对于每种机制,我们检查了以下几个方面:用于进行实验和发现实施细节的方法、对机制内部运行方式的观察,以及从我们的实验和分析中获得的安全见解。实验的平台配置可在附录的 A 部分找到。
7.1.CPU-GSP RPC
方法论。NVIDIA 内核模式驱动程序通过物理 RMAPI RPC 接口通过双向通道与 GSP-RM 通信。驱动程序向 GSP 发送命令以卸载特定任务,而 GSP 则使用执行状态和 GPU 事件进行响应以通知驱动程序。由于 RPC 发生在不受信任的介质上,主机上的攻击者可以检查和插入该介质,因此通过 RPC 通道传输的所有数据都必须加密。
我们拦截了来自 NVIDIA 内核模式驱动程序的所有物理 RMAPI 调用,并从 GSP 捕获了它们的相应响应。每种命令类型都遵循由 NVIDIA 的 FINN 工具自动生成的特定编码。为了更好地理解每个 RPC 调用的语义,我们从 NVIDIA 的软件开发工具包 (SDK) 中提取了 1588 个 RMAPI 命令的编码,并在我们捕获的日志中替换了它们。
观察。RPC 基础设施在 GSP 引擎构建阶段进行初始化。在未受保护的系统内存中分配了一个共享内存区域用于通信,该区域由物理地址表、命令队列和状态队列组成。物理地址表保存共享区域中所有页面的物理地址,将物理内存布局通知 GPU。命令队列存储从驱动程序发送到 GSP 的命令及其参数,而状态队列包含从 GSP 返回到驱动程序的状态信息。在初始化期间,这些结构的位置会传达给 GSP。
要发送命令,驱动程序首先使用序列号和元素计数设置命令标头。标头还包括一个额外的经过身份验证的数据 (AAD) 缓冲区、一个身份验证标签和一个校验和,但它仍为纯文本格式。然后,驱动程序使用 cpu_gsp_locked_rpc 密钥加密私有内存中的命令负载,并计算标头和加密负载的校验和,将值记录在标头中。然后,标头和加密的有效负载将复制到暂存缓冲区中的命令队列中。GSP 检索命令,验证加密负载的校验和和完整性,使用相同的密钥对其进行解密,然后执行命令。
为了发送状态更新或通知驱动程序事件,GSP 使用 gsp_cpu_locked_rpc 密钥加密其 CPR 中的状态,并将状态标头与加密的有效负载一起复制到暂存缓冲区中的状态队列中。驱动程序从状态队列中检索数据,将其复制到私有内存,并验证校验和以及加密负载的完整性。然后,它会解密 status 有效负载并相应地对其进行处理。

图 4.GSP-RM RPC 中的信息泄漏
安全洞察。请务必注意,在未受保护的暂存缓冲区中,只有命令和状态 RPC 负载会加密,而物理地址表、队列标头和队列元素标头仍以纯文本形式存在,并暴露在主机上的潜在攻击者面前。图 4 通过从虚拟机管理程序中的相应物理地址转储内存来说明这些数据结构。
物理地址表由 129 个条目组成(图 4 显示了前 4 个条目)。第一个条目存储表自己的物理地址,后跟一个 TX 队列标头条目、63 个条目用于 TX 队列元素、一个条目用于 RX 队列标头和 63 个条目用于 RX 队列元素。如果攻击者获得了对物理地址表的访问权限,他们可以轻松找到 TX/RX 队列中的所有元素。例如,第二个条目 (0x000000016921f000) 指向 TX/RX 队列的标头,其中 readPtr 和 writePtr 字段指示要读取和写入的下一个元素。然后,这些字段可以用作地址表中的索引,以查找队列中的活动元素。
例如,第三个条目 (0x0000000169297000) 指向特定的 queue 元素。每个元素都包含一个标头,其中包含 authTagBuffer、aadBuffer、checkSum、seqNum 和 elemCount 等字段,后跟加密的 RPC 有效负载。plaintext 标头还可以显示有关当前活动元素的重要信息。例如,如果 elemCount 的值大于 1,则可以使用它来推断 RPC 类型,精度很高
一个关键的挑战是在 CVM 的大物理内存空间内定位物理地址表。出现漏洞是因为 address 表中的第一个条目存储了自己的物理地址(例如,图 4 中的 0x000000016921e000)。鉴于地址表是页面对齐的,攻击者可以在整个物理内存中以 4096 字节的步幅(典型的页面大小)执行内存扫描。如果在扫描期间找到的 64 位物理地址等于存储在该位置的值,则攻击者可以唯一标识物理地址表的起始地址,从而可能暴露关键内存映射。
为了防止 RPC 执行状态泄露,我们建议不仅加密 RPC 负载,还加密上述 TX/RX 队列的元数据。

(一)从 GSP 读取数据
(二)将数据写入 GSP
图 5.CPU-GSP 内存传输中的时序通道
7.2.CPU-GSP 内存传输
方法论。GPU 通常通过 PCIe BAR 将专用窗口公开到其封装内存中。BAR2 是一个大孔径,为主机提供了一个用于访问 GPU 内存的虚拟地址空间。但是,启用 GPU-CC 模式后,将阻止 BAR2 对 CPR 的访问。在 CPR 中对数据的读取和写入应使用替代路由。对于 CVM 和 GSP 之间的内存传输,驱动程序使用 CPU-GSP DMA。由于 DMA 无法直接访问云服务器中的私有内存,因此驱动程序需要在未受保护的内存中分配和映射一个暂存缓冲区,该缓冲区不受云服务器密钥保护。
在我们的实验中,我们拦截了 CVM 和 GSP 之间的所有内存传输,并记录了它们在 CVM 整个生命周期中的执行时间。我们的目标是研究源或目标 aperture 以及 memory 传输的大小如何影响执行时间,以及是否可以利用 timing channels 的潜在存在。
观察。要从 GPU 的 CPR 读取数据,驱动程序会发送内存传输 RPC 命令,其中包含指定内存大小、GPU CPR 中的源以及位于未受保护的系统内存中的暂存缓冲区中的目标的参数。传输此 RPC 命令的保护已在 Section 7.1 中讨论。收到命令后,GSP 使用 gsp_cpu_dma 密钥加密 CPR 中的源数据,并通过 DMA 将其复制到未受保护的暂存缓冲区中。然后,驱动程序将数据传输到私有内存,并使用相同的密钥对其进行解密。
为了将数据写入 GPU 的 CPR,驱动程序首先使用 cpu_gsp_dma 密钥对 CVM 私有内存中的数据进行加密,并将其复制到未受保护的暂存缓冲区。然后,驱动程序再次通过 RPC 发送内存传输命令,指定内存大小、暂存缓冲区中的源以及 CPR 中的目标。收到命令后,GSP 通过 DMA 从未受保护的暂存缓冲区复制数据,使用相同的密钥对其进行解密,并将其写入 CPR 中的目标地址。
安全洞察。我们记录了整个 CVM 生命周期中 CPU 和 GSP 之间 4394 次内存传输的执行时间,包括 453 次读取作和 3941 次写入作。我们的目标是分析传输大小是否会影响执行时间。图 5 显示了读取和写入作的直方图,其中 x 轴表示执行时间,y 轴表示每个时间范围内的内存传输计数。不同的颜色表示不同的内存传输大小,范围从 8 字节到 4096 字节不等。
我们的观察表明,读取和写入作都表现出执行时间的双峰分布。对于较小的传输大小(8 到 256 字节),执行时间在很大程度上由 RPC 本身的固有成本决定,因此内存大小的影响相对微不足道。但是,对于较大的传输(4096 字节,由蓝色条表示),会发生明显的变化,与较小的传输相比,执行时间会显著增加。
为了缓解潜在的 timing side-channel 攻击(攻击者在不受信任的内存中监控 RPC 通道可以从执行时间变化中推断出敏感信息),我们建议为 RPC 调用实施恒定时间执行,或引入统计噪声来混淆 timing patterns。
7.3. 统一虚拟内存 (UVM)

图 6.SEC2、WLC 和 LCIC 之间的相互作用
方法论。NVIDIA 的 UVM 系统在系统内存和 GPU 内存之间提供统一的地址空间,通过自动管理内存迁移、页面错误和一致性来实现无缝内存访问。UVM 依靠 pushbuffers 发送 GPU 方法以在各种内存作上执行。
在传统的非 CC 模式下,UVM 利用 CE 来促进内存作。在系统内存中分配一个 pushbuffer,并映射用于 CPU 和 GPU 访问。CPU 使用 GPU 方法流填充 pushbuffer,并写入包含 pushbuffer 地址和长度的 GPFIFO 条目。然后,它会更新 GPPUT 指针并按门铃通知 CE。CE 随后从 GPFIFO 获取方法并执行它们。完成后,它会向 CPU 发出信号以清理已使用的 GPFIFO 条目。
在 GPU-CC 模式下,GPU 无法访问私有内存 的 CVM 和 BAR2 对 GPU 的 CPR 的访问也被禁用。因此,由于共享内存不可信,因此 CPU 或 GPU 无法再直接访问或修改 UVM作所必需的关键组件(例如推送缓冲区、GPFIFO 条目、GPPUT 指针和同步信号量)。为了降低泄露或泄漏的风险,这些组件在驻留在未受保护的暂存缓冲区中时需要额外的安全措施。
UVM 在 GPU-CC 中的实现要复杂得多,涉及多个阶段和递归交互。为了更好地了解其执行情况,我们对 NVIDIA 内核模式驱动程序和 UVM 驱动程序进行了检测,将控制流重组为清晰的时间序列。我们的主要重点是分析不同引擎(例如 SEC2 和 CE)之间的交互,并研究它们的派生密钥如何保护这个新内存管理模型中的特定目标组件。
观察。UVM for GPU-CC 中引入了三个专用通道:SEC2 通道、工作启动通道 (WLC) 和启动确认指示器通道 (LCIC)。
SEC2 通道:SEC2 通道是第一个创建的通道,用作引导安全工作负载提交的基础。其主要作用是验证和设置 WLC 和 LCIC 信道。只有一个 SEC2 通道,它与 SEC2 引擎相关联,并使用两个加密密钥:cpu_sec2_hmac_kernel 和 cpu_sec2_data_kernel,分别用于签名方法和加密有效负载。
WLC 通道:WLC 通道负责间接启动 UVM 工作负载。它们处理 UVM 驱动程序提交的加密 UVM CE 推送,验证其完整性,并将其分派给选定的 CE 执行。SEC2 通道初始化 16 个 WLC 通道,对应于最大并发推送数。每个 WLC 通道都与一个具有两个密钥的 LCE 相关联:lce{x}_h2d_kernel 用于主机到设备加密,lce{x}_d2h_kernel 用于设备到主机加密,其中 {x} 表示关联 LCE 的索引。
LCIC 通道:与 WLC 通道类似,LCIC 通道也由 SEC2 通道初始化。每个 LCIC 通道与相应的 WLC 通道配对,共享相同的 LCE 关联,从而产生总共 16 个 LCIC 通道。LCIC 通道旨在跟踪其配对的 WLC 通道的执行进度。
该工作流可分为两个阶段:
第一阶段通过 SEC2 设置 WLC/LCIC。SEC2 通道充当引导 WLC 和 LCIC 通道的信任锚点。SEC2 的 GPPUT、GPFIFO 条目和推送缓冲区分配在未受保护的暂存缓冲区中,并保持未加密状态。但是,SEC2 pushbuffers 中的方法使用 cpu_sec2_hmac_kernel 密钥进行签名。因此,SEC2 引擎可以验证方法的完整性以检测任何篡改。
启用 GPU-CC 后,WLC/LCIC 通道的 GPPUT、GPFIFO 和推送缓冲区必须放置在 GPU 的 CPR 中,以保护它们免受未经授权的访问。UVM 驱动程序填充 SEC2 推送,以便为 WLC/LCIC 通道设置这些数据结构。此过程对所有 16 个 WLC 和 LCIC 通道重复。在此阶段,WLC/LCIC信道已启动,但尚未运行。下一步是设置他们的时间表。
WLC 计划由两个交替推送组成:(1) decrypt_push — 负责解密下一个run_push并将其放入 CPR。decrypt_push 是静态的,保持不变。(2) run_push — 执行 GPU 方法以启动 UVM CE 推送,其中包含 UVM作的有效负载,并将 LCIC 通道的 GPPUT 前进一步以进行同步。run_push 是可变的,因为其参数必须动态更新以适应不同的 UVM CE 推送。
LCIC计划是完全静态的,只是将WLC GPPUT提前两步,确保WLC信道在下一个周期中始终从decrypt_push开始。
最后,上传WLC/LCIC计划的静态部分(在图6中标记为蓝色),并通过SEC2推送更新其GPFIFO条目。完成此作后,WLC/LCIC 通道将完全运行并准备好接受 UVM CE 推送。
第二阶段通过 WLC 间接启动 UVM CE 推送。WLC/LCIC通道完全初始化后,可以在运行时选择它们以间接启动UVM CE推送。UVM CE 推送的 pushbuffer 包含用于执行特定 UVM 任务的方法,例如,为地址范围编写页表条目。
要执行 UVM CE 推送,UVM 驱动程序会选择一个 WLC 通道,并使用该 WLC 通道的 lce{x}_h2d_kernel 密钥加密计划的 UVM CE 推送的推送缓冲区。加密的 pushbuffer 放置在不受保护的暂存缓冲区中。WLC 信道的相应run_push是根据 UVM CE 推送的参数生成的,经过加密并存储在暂存缓冲区中。在第一阶段预加载的 decrypt_push 首先执行以将run_push解密为 CPR。解密后,run_push通过解密 UVM CE 推送的推送缓冲区、在 CPR 中设置 GPFIFO 和 GPPUT 并触发其在另一个 CE 上运行来开始执行。UVM CE 推送使用绑定到新附加的 CE 的密钥 lce{y}_h2d_kernel 和 lce{y}_d2h_kernel。最后,run_push向 LCIC 通道发出信号,以推进 WLC 的 GPPUT,为下一个执行周期做好准备。
在整个过程中,WLC、LCIC 和 UVM CE 会更新各自的跟踪信号量,然后将其加密并存储在未受保护的暂存缓冲区中。UVM 驱动程序持续监控这些加密的信号量以跟踪执行进度。跟踪信号量的解密由不同的密钥处理:lce{x}_d2h_kernel 用于 WLC/LCIC 推送,lce{y}_d2h_kernel 用于 UVM CE 推送。
安全洞察。在 UVM 中,系统依靠 SEC2 通道的签名推送来引导 WLC/LCIC 通道。SEC2 推送未加密,因为它仅包含预定义的方法,没有嵌入的密钥。但是,SEC2 通道的 GPFIFO、GPPUT 和信号量驻留在未受保护的暂存缓冲区中,既未签名也未加密。攻击者可能会通过纵 GPFIFO 和 GPPUT 来利用这一点,将执行重定向到构建的推送缓冲区。但是,由于方法本身已签名,因此 SEC2 引擎仍然可以检测并防止执行被篡改的方法。因此,此类攻击将属于 DoS 的范围,而 DoS 通常被认为超出了范围。
WLC、LCIC 和 CE 命令队列的关键数据结构(如 GPFIFO 和 GPPUT)被安全地放置在 CPR 中。推送缓冲区(包括 WLC 的 run_push 和 UVM CE 推送)在传输到 CPR 之前,会在未受保护的暂存缓冲区中进行加密。与 SEC2 推送不同,这些缓冲区是可变的,并且包含敏感信息,包括内存地址和 UVM作。因此,它们在通过不受信任的接口传输时需要加密。此外,用于向 UVM 驱动程序发送信号的信号量在传递到 CVM 的私有内存之前,也会在未受保护的内存中进行加密,从而确保检索命令队列执行状态的机密性和完整性。
7.4.内存清理
方法论。内存清理用于故意覆盖内存内容以清除敏感信息。这可以防止机密数据的恢复,这在安全环境中尤为重要,否则旧数据可能会被未经授权的用户利用。通常,NVIDIA 内核模式驱动程序与 CE 建立洗涤器通道,在该通道中提交用于内存清理的 GPU 方法,从而允许 CE 执行任务。但是,当启用 GPU-CC 时,需要一个专用且安全的通道来提交内存清理方法,以防止通过不受信任的接口进行篡改。启用 GPU-CC 时,SEC2 用于内存清理,而不是使用 CE,因为它支持签名推送。
在我们的实验中,我们在 SEC2 实用程序中拦截了负责 SWL 洗涤器通道中签名方法的签名函数调用。然后,我们回溯调用跟踪,以确定 GPU 内存管理器中内存清理请求的来源。这种方法让我们更深入地了解了 GPU 内存清理的基础机制。
观察。NVIDIA 内核模式驱动程序建立了一个链接到 SEC2 引擎的 SWL 洗涤器通道,以安全地处理内存清理任务。当 GPU 的内存管理器需要释放某些内存页时,它会使用一系列方法填充 pushbuffer,以使用 SEC2 进行安全内存集作。然后,这些方法流将提交到 SWL 洗涤器通道。
为了确保完整性,pushbuffer 中的方法流使用 cpu_sec2_hmac_scrubber 密钥进行签名,并且它们的 HMAC 摘要存储在身份验证标记缓冲区中。生成两种类型的身份验证标签 — 一种用于 scrub 方法,另一种用于信号量方法。这些身份验证标记缓冲区的 GPU 虚拟地址作为方法中的参数传递。信号量在跟踪身份验证标签使用情况和指示方法执行状态方面起着至关重要的作用。它们还在命令中进行配置,以触发驱动程序的特定通知。
一旦所有方法都添加到推送缓冲区中,它就会链接到 SWL 洗涤器通道的 GPFIFO 队列,并发送一个门铃信号来启动在 SEC2 引擎上的执行。在 GPU 端,SEC2 引擎从 SWL 洗涤器通道检索方法流,并通过根据 cpu_sec2_hmac_scrubber 键验证 HMAC 摘要来验证其完整性。这可确保方法流在遍历不受信任的接口时保持不被篡改。
安全洞察。在早期版本的 NVIDIA 内核模式驱动程序中,SEC2 内存清理重复使用 cpu_sec2_hmac_kernel 密钥对方法流进行签名。但是,在最新的驱动程序版本中,专门为清理任务引入了专用的洗涤器键(cpu_sec2_hmac_scrubber 和 cpu_sec2_data_scrubber)。cpu_sec2_hmac_scrubber密钥现在用于对方法进行签名,而 cpu_sec2_data_scrubber 密钥存在但仍未使用。鉴于 SWL 洗涤器通道中的 pushbuffer 和 authentication tag 缓冲区当前分配在未受保护的暂存缓冲区中并且缺乏加密,我们推测 cpu_sec2_data_scrubber 最终可能会用于保护这些结构。
此外,SEC2 引擎仅支持解密,不提供加密功能。值得注意的是,虽然有 cpu_sec2_* 密钥用于保护发送到 SEC2 的数据,但没有相应的 sec2_cpu_* 密钥用于保护从 SEC2 返回到驱动程序的数据。这意味着用于通知驱动程序的信号量仍不受保护。SEC2 缺乏加密支持背后的基本原理尚不清楚,需要 NVIDIA 进一步澄清。这可能会带来安全风险,因为主机上的攻击者可以观察到未加密的 pushbuffers 和身份验证标签缓冲区(尽管由于完整性验证,他们无法篡改命令)并纵未受保护的信号量。
7.5.GPU 内存故障
方法论。在 GPU-CC 模式下,由于内存访问控制更严格,处理 GPU 内存故障会带来独特的挑战。通常,当程序尝试访问越界内存、取消引用 null 指针或写入已释放的内存时,会发生内存故障。在非 CC 环境中,GPU 和 NVIDIA 驱动程序都可以访问共享的硬件缓冲区,从而允许 GPU 将故障数据包直接记录到缓冲区中,然后驱动程序可以检索和处理该缓冲区。但是,在 GPU-CC 模式下,此硬件缓冲区放置在 GPU 的 CPR 中,因此 CPU 无法访问它。因此,需要一种新的机制来通过不受信任的接口安全地传输故障数据包。
为了在 GPU-CC 模式下分析此内存故障工作流,我们开发了一个 CUDA 程序,旨在故意触发内存故障。通过检测 NVIDIA 内核模式驱动程序和 UVM 驱动程序,我们拦截了用于设置暂存缓冲区以传递故障数据包的 RPC 调用,并监控了与内存故障相关的加密密钥的使用情况。
观察。为了满足 GPU-CC 中的内存访问控制要求,UVM 驱动程序请求 NVIDIA 内核模式驱动程序分配两个阴影缓冲区 — 一个用于可重放内存故障,另一个用于不可重放内存故障。这些影子缓冲区驻留在未受保护的暂存缓冲区中,使 GSP 能够直接写入它们。NVIDIA 内核模式驱动程序通过 GSP-RM RPC 向 GSP 注册这些影子缓冲区,并通知 GSP 其结构。然后,GSP 使用 gsp_cpu_replayable_fault 或 gsp_cpu_non_replayable_fault 密钥对故障数据包进行加密,然后再将其复制到影子缓冲区中。存储故障数据包后,GSP 会通过 RPC 返回路径发送 MMU_FAULT_QUEUED 事件,通知驱动程序。UVM 驱动程序监视此事件并计划中断服务例程 (ISR) 以从影子缓冲区中检索加密的故障数据包。每个故障数据包都包含一个身份验证标签和一个有效字段(用作 AAD)。UVM 驱动程序使用相应的密钥来验证和解密传入的数据包,然后解析它们以有效地处理内存故障,同时保持数据的机密性和完整性。
安全洞察。根据评论(英伟达,2025年)在 UVM 驱动程序的源代码中,可重放的错误源自图形引擎 (GE),而不可重放的故障来自其他引擎。在非 CC 模式下,这两种类型的故障遵循不同的处理路径。UVM 驱动程序专门管理可重放的故障,并拥有存储这些故障的硬件缓冲区。相比之下,处理不可重放的故障需要通过特定的影子缓冲区与 NVIDIA 内核模式驱动程序交互,因为只有内核模式驱动程序才能访问硬件缓冲区以查找不可重放的故障。
但是,在 GPU-CC 模式下,GSP-RM 拥有硬件缓冲区,而 CPU 缺乏直接访问,可重放和不可重放的故障都依赖于影子缓冲区来存储加密的故障数据包。因此,在 GPU-CC 模式下,它们的处理路径变得相似。此外,每当放置新的故障数据包时,GSP-RM 都需要更新影子缓冲区的 PUT 指针。NVIDIA 重新调整 BAR0 中映射的访问计数器寄存器的用途,以将此指针公开给 CPU。这意味着攻击者也可以在主机上观察到此值。但是,由于内存故障发生频率较低,因此 PUT 指针暴露的风险仍然很低。
7.6.CUDA 的
方法论。由于 CUDA 用户态驱动程序不是开源的,因此它在 GPU-CC 下的执行流程仍然不透明。为了分析它的行为,我们拦截了它与我们可以检测的外部组件的交互。我们的方法涉及开发一个示例 CUDA 应用程序,该应用程序执行关键作,例如 GPU 内存分配、主机到设备的数据传输和 CUDA 内核启动。但是,我们没有使用 CUDA 运行时 API,而是直接调用了低级 CUDA 驱动程序 API 来更好地控制执行。例如,我们将 CUDA 内核编译为并行线程执行( PTX )代码,并通过 cuLaunchKernel 启动它。
为了进一步剖析通信流,我们对 NVIDIA 内核模式驱动程序和 UVM 驱动程序进行了检测,捕获了它们与 CUDA 用户模式驱动程序的交互。此外,从 PipeLLM 中汲取见解(Tan 等人,2024)确定 OpenSSL API 用于 CUDA 的加密、解密和 MAC 验证,我们还检测了相关的 OpenSSL 函数。通过预加载 OpenSSL 库的自定义版本,我们拦截了 CUDA 用户模式驱动程序调用的所有加密作,从而使我们能够观察在 GPU-CC 下如何执行安全机制。
观察。通过拦截 OpenSSL 函数,我们能够监控 CUDA 用户模式驱动程序使用的密钥,并将它们映射到从 SPDM 会话期间协商的主密钥派生的密钥。我们的分析显示,CUDA 用户模式驱动程序通过 GetKMB API 从 NVIDIA 内核模式驱动程序中检索两类密钥:(1) cpu_sec2_data_user / cpu_sec2_hmac_user 密钥 — 这些密钥与 SEC2 引擎相关联,可能用于 SEC2 的加密数据传输和完整性验证。(2) lce{x}_h2d_user / lce{x}_d2h_user 密钥 — 这些密钥与特定的 LCE 相关联,有助于在 CPU 和 GPU 的 CE 之间进行加密数据传输。值得注意的是,由于 CUDA 在用户空间运行,因此所有这些密钥都用 _user 后固定,表明它们的权限级别。
安全洞察。CUDA 用户模式驱动程序与 NVIDIA 内核模式驱动程序的交互有限,主要发生在以下期间:CUDA API/上下文初始化、内核通道创建和密钥检索以及内存清理。但是,与启动 CUDA 内核相关的最安全关键作在用户模式驱动程序中仍然是自包含的,这使得它们的可观察性较差。鉴于可用的信息有限,我们可以对 GPU-CC 下的 CUDA 内核执行提出以下合理的推测:
(1) 保护命令队列的数据结构至关重要。GPFIFO、GPPUT、pushbuffers 和信号量应驻留在 GPU 的 CPR 中,或者在存储在未受保护的暂存缓冲区中时进行加密。可以采用一种类似于使用 SEC2 的引导安全作品提交的机制,如 UVM 中所示。cpu_sec2_hmac_user 密钥可用于对 SEC2 推送进行签名,而 cpu_sec2_data_user 密钥可以加密传递到 SEC2 引擎的数据。工作提交可以通过 SEC2 或其他安全渠道(例如 WLC)间接执行,WLC 本身由 SEC2 安全地引导。
(2) 保护 CUDA 应用程序和 GPU 之间的代码/数据传输是必要的。这包括编译后的 CUDA 内核和内核在执行过程中引用的数据。我们推测 CE 应该在维护机密性方面发挥关键作用,lce{x}_h2d_user 密钥加密从云服务器复制到 GPU 的数据,而 lce{x}_d2h_user 密钥保护传输回云服务器的数据。
(3) 保护与 CUDA 内核相关的元数据结构也至关重要。队列元数据 (QMD) 包含内核函数地址、内核参数和执行配置等信息,必须受到保护。由于 QMD 地址在命令队列内的 GPU 方法中作为参数传递,因此应在未受保护的暂存缓冲区中对其进行加密,并在 CUDA 内核执行之前将其传输到 CPR 中。
8.设备认证

图 7.GPU 的设备和 RIM 文件证书链
设备认证是一个过程,用于通过验证硬件组件的真实性和完整性来确定硬件组件的可信度。在 GPU-CC 的上下文中,证明使用户能够确认 GPU 是由受信任的供应商制造的,并且其机密计算功能已正确启用。成功的证明为用户和第三方提供了 GPU 可以安全地执行代码和处理敏感数据的保证。NVIDIA 的 GPU-CC 认证遵循R表情在遗嘱程序S (大鼠)规范(Birkholz 等人,2023;奥弗比,2023;内特尼,2025).下面,我们描述了证明机密 GPU 所涉及的具体步骤。
设备证书链检索/验证。该过程从为每个 NVIDIA GPU 配置唯一的加密身份开始:硬件融合的设备身份密钥和相应的设备身份证书。此证书锚定到 NVIDIA 的根证书颁发机构 (CA),构成了用于建立信任的证书链的基础。当在 CVM 中运行的验证程序启动鉴证时,它会检索设备证书链。如图 7 的左侧部分所示,该链包含五个证书:证明证书和设备身份证书从 GPU 检索,而其余的 Provisioner 证书、模型证书和根证书从 NVIDIA 内核模式驱动程序获取。
设备身份证书对应于不可变的 GSP 引导 ROM (BROM),并由 NVIDIA Provisioner CA 签名。设备身份证书将设备唯一标识为真实的 NVIDIA GPU。不可变的 GSP-BROM 开始执行,并确保系统以安全状态启动。 GSP-FMC 已加载并进行身份验证。 测量特定的硬件安全保险丝(在制造时配置)。这些度量值用于派生认证密钥对。私有认证密钥用于对认证报告进行签名。认证证书由设备身份的私钥签名,从而建立信任链。它包含验证认证报告所需的公有认证密钥。证书链的根是根证书,这是一种用作信任锚点的自签名证书。
验证程序首先将根证书替换为本地证书,以防止遭到入侵的驱动程序破坏证书链。然后,它以相反的顺序验证链,从 Device Identity Certificate 开始,一直到 Root Certificate。在此过程中,验证程序会向 NVIDIA 在线证书状态协议 (OCSP) 服务发送多个请求(英伟达,2025b)以检查每个证书的吊销状态。如果链同时通过签名和吊销检查,则验证员将继续请求认证报告。
认证报告检索/验证。然后,验证程序检索已签名的证明报告,其中包含测量数据和标识 GPU 固件和驱动程序的不透明元数据块。测量数据由 64 个结构化记录组成,每个记录都包含测量规范、大小字段和被测组件(例如固件、配置)的加密哈希值。不透明数据块提供用于识别 GPU 驱动程序和固件版本的信息。验证程序使用证明证书验证证明报告的签名。
测量检索/验证。验证程序从不透明块中派生驱动程序和 VBIOS ID,并从 NVIDIA RIM 服务检索相应的参考完整性清单 (RIM) 文件(英伟达,2025 年).验证程序通过验证 RIM 文件的架构和背书来检查 RIM 文件的状态。每个 RIM 文件都包含一个证书链。验证器附加一个本地 Root RIM Certificate 以完成链(图 7 的左侧部分)并对其进行验证。验证链后,叶证书(即 RIM 文件证书)将用于验证 RIM 文件上的签名。为了验证度量值,验证程序会从 RIM 文件编译黄金度量值列表。它将认证报告中的每个测量值与黄金列表中的允许值进行比较。如果发现不匹配,验证程序会得出结论,即 GPU 未处于预期状态。
如果所有检查都成功,包括证书验证、签名验证和测量比较,验证程序会报告证明结果,用户可以选择将 GPU 转换为 READY 状态。
9.结论
NVIDIA GPU-CC 系统旨在为处理敏感数据的新兴 AI 应用程序提供隔离且安全的执行管道。然而,缺乏公共规范、其硬件和软件生态系统的专有性质以及其设计的复杂性,在评估其实现是否满足机密计算的安全要求方面带来了重大挑战。本文迈出了揭开 GPU-CC 内部工作原理的神秘面纱并为未来的安全研究奠定基础的第一步。我们描述了 GPU-CC 的安全原则和架构组件,并提出了一系列深入的安全实验,以评估潜在的信息泄露并探索可能的利用途径。所有安全检测结果均已负责任地披露给 NVIDIA,以帮助加强 GPU-CC 的安全性。

3597

被折叠的 条评论
为什么被折叠?



