安全性

为防止在 pVM 中运行任意载荷,Android 虚拟化框架 (AVF) 采用分层安全方法,其中每一层都增加了额外的强制执行功能。下面列出了 AVF 安全层:

  • Android 会确保仅具有 pVM 权限的应用才可以创建或检查 pVM。

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

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

安全模型

机密性、完整性和可用性(又称“信息安全三要素”)构成一个模型,旨在提供信息安全政策指南:

  • 机密性是一套用于限制信息访问权限的规则。
  • 完整性即确保信息可信又准确。
  • 可用性即保证已获授权的实体对信息的可靠访问。

机密性和完整性

机密性源自 pKVM Hypervisor 强制执行的内存隔离属性。pKVM 会跟踪各个物理内存页面的内存所有权,以及所有者为共享页面而发出的任何请求。pKVM 会确保只有获得授权的 pVM(主机和客户机)才能在由 Hypervisor 控制的第 2 阶段页表中映射指定页面。此架构会确保 pVM 拥有的内存内容保持不公开状态,除非所有者明确将其与另一个 pVM 共享。

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

完整性适用于内存计算中的数据。pVM 无法:

  • 未征得同意便修改彼此的内存。
  • 影响彼此的 CPU 状态。

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

这些原则与 Linux 提供的进程隔离没有关系,在这种进程隔离中,通过第 1 阶段页面表和进程间的内核上下文切换来控制对内存页面的访问。不过,pKVM 的 EL2 部分会强制执行这些属性,与整个 Linux 内核相比,其攻击面减小了大约一半(约为 10000 行代码,而整个 Linux 内核是 2000 万行),因此可针对因过于敏感而不能依赖进程隔离的用例提供更强的安全保证。

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

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

Hypervisor

pKVM 是基于 KVM 的 Hypervisor,用于将 pVM 和 Android 隔离到互不信任的执行环境中。如果任何 pVM(包括主机)遭到破解,这些属性就会适用。遵从 AVF 的替代 Hypervisor 需要提供类似的属性。

  • pVM 无法访问属于其他实体(如 pVM 或 Hypervisor)的网页,除非网页所有者明确共享该网页。此规则包含主机 pVM,并且同时适用于 CPU 和 DMA 访问。

  • 在将 pVM 使用的网页返回给主机之前(例如,当 pVM 被销毁时),系统会擦除该网页。

  • 系统会先擦除一次设备启动中所有 pVM 和 pVM 固件的内存,而后才在后续设备启动中运行 OS 引导加载程序。

  • 连接硬件调试程序(例如 SJTAG)后,pVM 无法访问之前创建的密钥。

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

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

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

客户机 OS

Microdroid 是在 pVM 中运行的 OS 的一个示例。Microdroid 由一个基于 U-boot 的引导加载程序、GKI、一部分 Android 用户空间和一个载荷启动器组成。如果任何 pVM(包括主机)遭到破解,这些属性就会适用。在 pVM 中运行的替代 OS 应提供类似的属性。

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

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

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

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

  • 如果在客户机 pVM 之外修改 instance.img,Microdroid 将不会启动(或启动时处于干净初始状态)。

  • Microdroid 为启动链提供认证。

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

  • 提供给 pVM 实例的 BCC 和 CDI 只能由该特定实例衍生。

  • 写入到已加密存储卷的内容属于机密内容,但在加密块粒度级别,不提供回滚保护。此外,对数据块进行的其他任意外部篡改会导致数据块对 Microdroid 显示为垃圾内容,而不会被明确检测为 I/O 错误。

Android

以下属性由 Android 作为主机进行维护,但在主机遭破解时不适用:

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

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

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

  • 在主机和 pVM 之间建立 vsock 连接时使用的标识符称为上下文标识符 (CID),而在主机 pVM 处于运行状态时,不会重复使用该标识符。例如,您无法将正在运行的 pVM 替换为另一个 pVM。

可用性

对 pVM 来说,可用性是指主机为客户机分配足够的资源,以便客户机能够执行其本该执行的任务。

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

同样,pKVM 还会将物理中断处理委托给主机内核,以降低 Hypervisor 的复杂性,并让主机负责调度。我们会努力确保客户机中断转发只会导致拒绝服务攻击(中断次数过少、过多或路由错误)。

最后,主机的虚拟机监控器 (VMM) 进程负责分配内存和提供虚拟设备,例如网卡。恶意 VMM 可以拒绝来自客户机的资源。

虽然 pKVM 不会为客户机提供可用性,但这种设计可以保护主机的可用性免受恶意客户机的影响,因为主机可以随时抢占或终止客户机并收回其资源。

安全启动

数据与 pVM 实例相关联,安全启动可确保对实例数据的访问可控制。实例首次启动时,系统会通过以下方法对其进行预配:为 pVM 随机生成秘密信息盐,并从所加载的映像中提取详细信息(例如验证公钥和哈希)。此信息用于验证 pVM 实例的后续启动,并确保仅将该实例的秘密信息发布到通过验证的映像。系统会在 pVM 中的每个加载阶段执行此过程:pVM 固件、pVM ABL、Microdroid 等等。

DICE 为每个加载阶段都提供了认证密钥对,该密钥对的公开部分已在相应阶段的 BCC 条目中进行了认证。该密钥对会在两次启动之间发生更改,因此还衍生了密封秘密信息,该信息在虚拟机实例重新启动后仍保持稳定,因此适用于保护永久性状态。密封秘密信息对虚拟机非常有价值,因此不应直接使用。应从密封秘密信息衍生密封密钥,并且密封秘密信息应尽早销毁。

每个阶段都会将明确编码的 CBOR 对象交给下一阶段。此对象包含秘密信息和 BCC,后者包含累积的状态信息,例如最后一个阶段是否已安全加载。

已解锁的设备

使用 fastboot oem unlock 解锁设备时,系统会擦除用户数据。此流程可保护用户数据免遭未经授权的访问。当设备解锁时,pVM 的专用数据也会失效。

解锁后,设备所有者可以随意重新刷写通常受启动时验证保护的分区,包括包含 pKVM 实现的分区。因此,在维护安全模型时,已解锁设备上的 pKVM 不可信。

远程方可以通过检查设备密钥认证证书中的启动时验证状态来发现这种可能不安全的状态。