安全

为防止在 pVM 内部运行任意负载,Android 虚拟化框架 (AVF) 采用分层安全方法,其中每一层都增加了额外的强制措施。以下是 AVF 安全层列表:

  • Android 确保只有具有 pVM 权限的应用才被允许创建或检查 pVM。

  • 引导加载程序 – 引导加载程序确保只有由 Google 或设备供应商签名的 pVM 映像才被允许启动,并遵守 Android 验证启动程序。此架构意味着运行 pVM 的应用无法捆绑自己的内核。

  • pVM 提供纵深防御,例如使用 SELinux,用于在 pVM 中运行的负载。纵深防御不允许将数据映射为可执行文件 (neverallow execmem),并确保 W^X 适用于所有文件类型。

安全模型

机密性、完整性和可用性(CIA 三元组)构成了一个旨在指导信息安全策略的模型

  • 机密性是一组限制信息访问的规则。
  • 完整性是确保信息值得信赖和准确的保证。
  • 可用性是保证授权实体可靠访问信息的保证。

机密性和完整性

机密性源于 pKVM 虚拟机监控程序强制执行的内存隔离属性。pKVM 跟踪各个物理内存页的内存所有权以及所有者共享页面的任何请求。pKVM 确保只有有权访问的 pVM(主机和客户机)在其虚拟机监控程序控制的第 2 阶段页表中映射了给定的页面。此架构维护了 pVM 拥有的内存内容保持私有,除非所有者明确与其他 pVM 共享。

维护机密性的限制也扩展到系统中代表 pVM 执行内存访问的任何实体,即支持 DMA 的设备和在更高级别层中运行的服务。片上系统 (SoC) 供应商必须满足一组新的要求,然后才能支持 pKVM。否则,无法提供机密性。

完整性适用于内存中的数据计算。pVM 不能

  • 未经同意修改彼此的内存。
  • 互相影响对方的 CPU 状态。

这些要求由虚拟机监控程序强制执行。但是,当必须应用其他解决方案(例如 dm-verity 或 AuthFS)时,虚拟数据存储也会出现有关数据完整性的问题。

这些原则与 Linux 提供的进程隔离没有区别,在 Linux 中,对内存页的访问通过第 1 阶段页表进行控制,并且内核在进程之间进行上下文切换。但是,pKVM 的 EL2 部分(强制执行这些属性)的攻击面比整个 Linux 内核小三个数量级(大约 1 万行代码与 2 千万行代码),因此为过于敏感而无法依赖进程隔离的用例提供了更强的保证。

鉴于 pKVM 的大小,它适合进行形式验证。我们正在积极支持学术研究,旨在正式证明实际 pKVM 二进制文件上的这些属性。

本页的其余部分介绍了围绕 pKVM 的每个组件提供的机密性和完整性保证。

虚拟机监控程序

pKVM 是一个基于 KVM 的虚拟机监控程序,它将 pVM 和 Android 隔离到互不信任的执行环境中。如果任何 pVM(包括主机)内部发生泄露,这些属性仍然成立。符合 AVF 的替代虚拟机监控程序需要提供类似的属性。

  • 除非页面所有者明确共享,否则 pVM 无法访问属于另一个实体(例如 pVM 或虚拟机监控程序)的页面。此规则包括主机 pVM,并且适用于 CPU 和 DMA 访问。

  • 在 pVM 使用的页面返回到主机之前(例如,当 pVM 被销毁时),它会被擦除。

  • 在后续设备启动中运行操作系统引导加载程序之前,会擦除所有 pVM 和 pVM 固件在一个设备启动中的内存。

  • 当连接硬件调试器(例如 SJTAG)时,pVM 无法访问其先前生成的密钥。

  • 如果 pVM 固件无法验证初始映像,则不会启动。

  • 如果 instance.img 的完整性受到破坏,则 pVM 固件不会启动。

  • 提供给 pVM 实例的 DICE 证书链和复合设备标识符 (CDI) 只能由该特定实例派生。

客户机操作系统

Microdroid 是在 pVM 中运行的操作系统示例。Microdroid 由基于 U-boot 的引导加载程序、GKI、Android 用户空间子集和负载启动器组成。如果任何 pVM(包括主机)内部发生泄露,这些属性仍然成立。在 pVM 中运行的替代操作系统应提供类似的属性。

  • 如果无法验证 boot.imgsuper.imgvbmeta.imgvbmeta\_system.img,Microdroid 将不会启动。

  • 如果 APK 验证失败,Microdroid 将不会启动。

  • 即使 APK 已更新,同一 Microdroid 实例也不会启动。

  • 如果任何 APEX 未通过验证,Microdroid 将不会启动。

  • 如果 instance.img 在客户机 pVM 外部被修改,Microdroid 将不会启动(或以干净的初始状态启动)。

  • Microdroid 提供对启动链的证明。

  • 对与客户机 pVM 共享的磁盘映像的任何(未签名)修改都会导致 pVM 端的 I/O 错误。

  • 提供给 pVM 实例的 DICE 证书链和 CDI 只能由该特定实例派生。

  • 写入加密存储卷是机密的,但是没有加密块粒度的回滚保护。此外,对数据块的其他任意外部篡改会导致该块在 Microdroid 中显示为垃圾数据,而不是显式检测为 I/O 错误。

Android

以下是 Android 作为主机维护的属性,但在主机泄露的情况下不成立

  • 客户机 pVM 无法直接与其他客户机 pVM 交互(例如建立 vsock 连接)。

  • 只有主机 pVM 中的 VirtualizationService 才能建立与 pVM 的通信通道。

  • 只有使用平台密钥签名的应用才能请求创建、拥有或与 pVM 交互的权限。

  • 在设置主机和 pVM 之间的 vsock 连接时使用的标识符(称为上下文标识符 (CID))在主机 pVM 运行时不会重复使用。例如,您不能用另一个 pVM 替换正在运行的 pVM。

可用性

在 pVM 的上下文中,可用性是指主机为客户机分配足够的资源,以便客户机可以执行其设计要执行的任务。

主机的职责包括调度 pVM 的虚拟 CPU。与传统的 Type-1 虚拟机监控程序(例如 Xen)不同,KVM 明确设计决定将工作负载调度委托给主机内核。鉴于当今调度程序的大小和复杂性,此设计决策显著减小了可信计算基 (TCB) 的大小,并使主机能够做出更明智的调度决策以优化性能。但是,恶意主机可以选择永远不调度客户机。

同样,pKVM 也将物理中断处理委托给主机内核,以降低虚拟机监控程序的复杂性,并让主机负责调度。已采取措施确保转发客户机中断只会导致拒绝服务(中断太少、太多或错误路由)。

最后,主机的虚拟机监视器 (VMM) 进程负责分配内存和提供虚拟设备,例如网卡。恶意 VMM 可能会阻止客户机的资源。

尽管 pKVM 不向客户机提供可用性,但该设计保护主机的可用性免受恶意客户机的侵害,因为主机始终可以抢占或终止客户机并回收其资源。

安全启动

数据与 pVM 实例绑定,安全启动确保可以控制对实例数据的访问。实例的首次启动通过为 pVM 随机生成一个密钥盐并从加载的映像中提取详细信息(例如验证公钥和哈希)来对其进行配置。此信息用于验证 pVM 实例的后续启动,并确保实例的密钥仅发布给通过验证的映像。此过程在 pVM 内的每个加载阶段(pVM 固件、pVM ABL、Microdroid 等)中发生。

DICE 为每个加载阶段提供一个证明密钥对,其公钥部分在针对该阶段的 DICE 证书中获得认证。此密钥对可能会在启动之间更改,因此还会派生一个密封密钥,该密钥在 VM 实例的重新启动之间保持稳定,因此适用于保护持久状态。密封密钥对 VM 非常有价值,因此不应直接使用。相反,应从密封密钥派生密封密钥,并且应尽早销毁密封密钥。

每个阶段都将确定性编码的 CBOR 对象传递到下一个阶段。此对象包含密钥和 DICE 证书链,后者包含累积的状态信息,例如上一阶段是否安全加载。

解锁的设备

当使用 fastboot oem unlock 解锁设备时,用户数据将被擦除。此过程可保护用户数据免遭未经授权的访问。当发生设备解锁时,pVM 私有的数据也会失效。

解锁后,设备所有者可以自由地重新刷写通常受验证启动保护的分区,包括包含 pKVM 实施的分区。因此,在解锁的设备上,pKVM 不会被信任来维护安全模型。

远程方可以通过检查密钥证明证书中的设备验证启动状态来观察这种潜在的不安全状态。