Skip to the content.

Android Verified Boot

1. 启动时验证

启动时验证会尽力确保所有已执行代码均来自可信来源(通常是设备的原始设备制造商 [OEM]),以防受到攻击或损坏。它可建立一条从受硬件保护的信任根到引导加载程序,再到 boot 分区和其他已验证分区(包括 system、vendor 和可选的 oem 分区)的完整信任链。在设备启动过程中,无论是在哪个阶段,都会在进入下一个阶段之前先验证下一个阶段的完整性和真实性。

除了确保设备运行的是安全的 Android 版本外,启动时验证还会检查 Android 版本是否为具有回滚保护的正确版本。回滚保护可确保设备只会更新到更高的 Android 版本,从而帮助避免可能的漏洞持续存在。

除了验证操作系统外,启动时验证还允许 Android 设备将其完整性状态传达给用户。

1.1 背景

Android 4.4 增加了对启动时验证和 dm-verity 内核功能的支持。这种验证功能组合就是启动时验证 1。

以前的 Android 版本会在发现设备损坏时向用户发出警告,但仍然允许他们启动设备;从 Android 7.0 开始,系统会严格强制执行启动时验证,从而使已破解的设备无法启动。Android 7.0 还增加了对前向纠错功能的支持,有助于更可靠地防范非恶意数据损坏。

Android 8.0 及更高版本包含 Android 启动时验证 (AVB),AVB 是启动时验证的一个参考实现,可与 Project Treble 配合使用。除了与 Treble 配合使用外,AVB 还对分区脚本格式进行了标准化并增添了回滚保护功能。

2. 设备状态

设备状态指明了能够以多大的自由度将软件刷写到设备上,以及是否强制执行验证。设备状态为 LOCKED 和 UNLOCKED。状态为 LOCKED 的设备禁止您将新软件刷写到设备上,而状态为 UNLOCKED 的设备允许您进行修改。

当设备开机后,引导加载程序会先检查设备状态是 LOCKED 还是 UNLOCKED。如果设备状态为 UNLOCKED,引导加载程序会向用户显示警告,然后继续启动,即使加载的操作系统并非由信任根签名也是如此。

如果设备状态为 LOCKED,引导加载程序会完成验证启动中的步骤,以验证该设备的软件。只有加载的操作系统由信任根正确签名后,状态为 LOCKED 的设备才会启动。如需了解详情,请参阅启动流程。

2.1 更改设备状态

如需更改设备状态,请使用 fastboot flashing [unlock lock] 命令。为了保护用户数据,只要设备状态发生了变化,都会先擦除 data 分区中的数据,并会在删除数据之前要求用户确认。

用户购买二手开发设备后,应将设备状态从 UNLOCKED 改为 LOCKED。锁定设备后,只要没有警告,用户就应该确信设备所处的状态符合设备制造商的设计。如果开发者出于开发目的而希望停用设备上的验证功能,应将设备状态从 LOCKED 改为 UNLOCKED。

2.2 信任根

信任根是用来为设备上存储的 Android 副本进行签名的加密密钥。信任根的不公开部分仅为设备制造商所知,用来为将要分发的每个 Android 版本进行签名。信任根的公开部分嵌入到设备中,并存储在一个不会被篡改的位置(通常是只读存储区)。

加载 Android 时,引导加载程序会使用信任根来验证真实性。如需详细了解此流程,请参阅验证启动。设备可能具有多个引导加载程序,因此可能有多个加密密钥。

可由用户设置的信任根 设备可根据需要选择允许用户配置信任根(例如公钥)。设备可以使用可由用户设置的信任根(而非内置信任根)来进行启动时验证。这样,用户既可以安装并使用自定义的 Android 版本,又不会牺牲启动时验证这一安全改进功能。

如果实现了可由用户设置的信任根,则应满足以下要求:

要实现可由用户设置的信任根,其中一种方法是将虚拟分区设置为仅当设备处于 UNLOCKED 状态时才能刷写或清除。Google Pixel 2 设备使用的便是此方法以及名为 avb_custom_key 的虚拟分区。avbtool extract_public_key 命令会输出此分区中数据的格式。以下示例展示了如何设置可由用户设置的信任根:

$ avbtool extract_public_key --key key.pem --output pkmd.bin
$ fastboot flash avb_custom_key pkmd.bin

可通过发出以下命令来清除可由用户设置的信任根:

$ fastboot erase avb_custom_key

3. 验证启动

对于要启动的 Android 版本中包含的所有可执行代码和数据,启动时验证均要求在使用前以加密形式对其进行验证,其中包括内核(从 boot 分区加载)、设备树(从 dtbo 分区加载)、system 分区和 vendor 分区等。

对于 boot 和 dtbo 这类仅读取一次的小分区,通常是通过将整个内容加载到内存中,然后计算其哈希值来进行验证。接下来,系统会将计算出的哈希值与预期哈希值进行比较。如果值不一致,则 Android 将无法加载。如需了解详情,请参阅启动流程。

内存装不下的较大分区(如文件系统)可能会使用哈希树;在这种情况下,验证流程会在将数据加载到内存的过程中持续进行。对于这种情况,系统会在运行时计算哈希树的根哈希值,并将其与预期根哈希值进行比较。Android 包含用于验证较大分区的 dm-verity 驱动程序。如果在某个时刻计算出的根哈希值与预期根哈希值不一致,系统便不会使用相应数据,而且 Android 会出现错误。如需了解详情,请参阅 dm-verity 损坏。

预期哈希值通常存储在每个经过验证的分区的末尾或开头、专用分区中,或同时存储在以上两个位置。最重要的是,这些哈希值已由信任根以直接或间接的方式签名。举个例子,AVB 实现就支持这两种方式;如需了解详情,请参阅 Android 启动时验证。

3.1 回滚保护

即使更新流程完全安全,攻击者仍可能会利用非永久性 Android 内核漏洞来手动安装更易受攻击的旧版 Android 系统,重新启动进入易受攻击的版本,然后通过该 Android 版本来安装永久性漏洞。在这种情况下,攻击者可通过这种漏洞永久拥有相应设备,并可以执行任何操作(包括停用更新)。

防范这类攻击的保护措施称为“回滚保护”。“回滚保护”通常通过以下方式实现:使用防篡改的存储空间来记录最新的 Android 版本,并在 Android 版本低于记录的版本时拒绝启动 Android。系统通常会针对每个分区来跟踪版本。

如需详细了解 AVB 处理回滚保护的方式,请参阅 AVB README。

3.2 处理验证错误

验证在启动时(例如,如果在 boot 分区上计算出的哈希值与预期哈希值不一致)或运行时(例如,如果 dm-verity 在 system 分区上遇到验证错误)都可能会失败。如果验证在启动时失败,设备则无法启动,而且最终用户需要执行相关步骤才能恢复设备使用。

如果验证在运行时失败,恢复流程就会更复杂一些。如果设备使用的是 dm-verity,则应在 restart 模式下进行配置。在 restart 模式下,如果遇到验证错误,设备会立即重启,并设置特定标记以表明错误原因。引导加载程序应该会注意到该标记,并将 dm-verity 切换为使用 I/O 错误 (eio) 模式并保持该模式,直到安装新的更新为止。

在 eio 模式下启动时,设备会显示错误屏幕,以通知用户系统已检测到损坏,而且设备可能无法正常使用。该屏幕会持续显示,直到用户将其关闭为止。在 eio 模式下,如果遇到验证错误,dm-verity 驱动程序不会重启设备,而是会返回 EIO 错误,并且相应的应用需要处理该错误。

这样做的目的是,让系统更新程序能够正常运行(以便安装不含损坏错误的新操作系统),或者让用户能够从设备上获取尽可能多的数据。安装新的操作系统后,引导加载程序会注意到新安装的操作系统,并切换回 restart 模式。

4. 启动流程

建议的设备启动流程如下所示:

verified boot flow

图 1. 启动时验证流程

4.1 适用于 A/B 设备的流程

如果设备使用的是 A/B 系统,则启动流程略有不同。必须先使用启动控件 HAL 将要启动的槽位标记为 SUCCESSFUL,然后再更新回滚保护 (Rollback Protection) 元数据。

如果平台更新失败(未标记为 SUCCESSFUL),A/B 堆栈便会回退至仍具有先前 Android 版本的另一槽位。不过,如果已设置回滚保护元数据,之前的版本会因回滚保护而无法启动。

4.2 将启动时验证状态传达给用户

确定设备的启动状态后,您需要将该状态传达给用户。如果设备没有任何问题,则会继续运行,而不显示任何内容。启动时验证问题分为以下几类:

具有自定义信任根的已锁定设备

黄色屏幕示例:

boot yellow

如果设备处于已锁定状态,已设置自定义的信任根,并且映像已使用该自定义信任根进行签名,则会在每次启动时显示黄色屏幕。黄色屏幕会在 10 秒钟后关闭,并且设备会继续启动。如果用户按下电源按钮,“按电源按钮即可暂停”文字便会更改为“按电源按钮即可继续”,并且该屏幕永远都不会关闭,但设备可能会调暗或关闭显示屏以防烧屏。如果再次按下按钮,该屏幕便会关闭,并且手机会继续启动。

对于hex-number,请使用用于验证的 libavb 表示形式公钥的 sha256 的前 8 位数字,例如 d14a028c。

建议采用的文本:

您的设备加载了不同的操作系统。

请在其他设备上访问此链接以了解详情:

g.co/ABH

ID:hex-number

按电源按钮即可暂停

已解锁的设备

橙色屏幕示例:

boot orange

如果设备处于已解锁状态,则会在每次启动时显示橙色屏幕。橙色屏幕会在 10 秒钟后关闭,并且设备会继续启动。如果用户按下电源按钮,“按电源按钮即可暂停”文字便会更改为“按电源按钮即可继续”,并且该屏幕永远都不会关闭(设备可能会根据需要调暗和/或关闭显示屏,以防出现烧屏或类似问题)。如果再次按下按钮,该屏幕便会关闭,并且手机会继续启动。

对于hex-number,请使用用于验证的 libavb 表示形式公钥的 sha256 的前 8 位数字,例如 d14a028c。

建议采用的文本:

引导加载程序已解锁,无法保证软件完整性。攻击者可能可以获取设备上存储的所有数据。请勿在此设备上存储任何敏感数据。

请在其他设备上访问此链接以了解详情:

g.co/ABH

ID:hex-number

按电源按钮即可暂停。

dm-verity 损坏

红色 eio 屏幕示例:

boot red

如果找到 Android 的有效版本,并且设备当前处于 eio dm-verity 模式,则会显示红色 eio 屏幕。用户需要按电源按钮才能继续。如果用户未在 30 秒内确认警告屏幕,设备将关机(以防烧屏并节省电量)。

注意:系统可能会在显示此屏幕后显示其他警告屏幕。例如,如果设备处于 UNLOCKED 状态,则之后会显示橙色屏幕。

建议采用的文本:

您的设备已损坏。该设备不可信任,并且可能无法正常工作。

请在其他设备上访问此链接以了解详情:

g.co/ABH

按电源按钮即可继续。

找不到有效的操作系统

红色屏幕示例:

boot red 2

如果找不到有效的 Android 版本,屏幕会显示红色。设备无法继续启动。如果用户未在 30 秒内确认警告屏幕,设备将关机(以防烧屏并节省电量)。

对于hex-number,请使用用于验证的 libavb 表示形式公钥的 sha256 的前 8 位数字,例如 d14a028c。

建议采用的文本:

找不到有效的操作系统。设备无法启动。

请在其他设备上访问此链接以了解详情:

g.co/ABH

ID:hex-number

按电源按钮即可关机。

解锁确认

屏幕示例:

unlock confirmation

显示一个解锁确认屏幕,以响应通过 fastboot 接口执行的 fastboot flashing unlock 命令。初始选中的是“不解锁”选项。如果用户未在 30 秒内与警告屏幕互动,屏幕会消失并且该命令会失败。

建议采用的文本:

如果您解锁引导加载程序,则可以在此手机上安装自定义操作系统软件。自定义操作系统未经过与原始操作系统相同级别的测试,可能会导致您的手机和已安装的应用停止正常工作。使用自定义操作系统无法保证软件完整性,因此在引导加载程序处于解锁状态时存储在手机上的所有数据都可能面临风险。

为防止他人未经授权访问您的个人数据,解锁引导加载程序还将删除您手机上的所有个人数据。

按音量调高按钮/音量调低按钮可选择是否解锁引导加载程序,然后按电源按钮即可继续。

解锁

解锁引导加载程序。

不解锁

不解锁引导加载程序并重启手机。

锁定确认

显示一个锁定确认屏幕,以响应通过 fastboot 接口执行的 fastboot flashing lock 命令。初始选中的是“不锁定”选项。如果用户未在 30 秒内与警告屏幕互动,屏幕会消失并且该命令会失败。

文本:

如果您锁定引导加载程序,则无法在此手机上安装自定义操作系统软件。为防止他人未经授权访问您的个人数据,锁定引导加载程序还将删除您手机上的所有个人数据。

按音量调高按钮/音量调低按钮可选择是否锁定引导加载程序,然后按电源按钮即可继续。

锁定

锁定引导加载程序。

不锁定

不锁定引导加载程序并重启手机。

将启动时验证状态传达给 Android

屏幕示例:

lock confirmation

引导加载程序通过内核命令参数或 bootconfig(从 Android 12 开始)将启动时验证状态传达给 Android。它会将 androidboot.verifiedstate 选项设置为以下其中一个值:

androidboot.veritymode 选项设置为 eio 或 restart,具体取决于启动加载程序在处理 dm-verity 错误时所处的状态。如需了解详情,请参阅处理验证错误。

5. 实现 dm-verity

Android 4.4 及更高版本支持通过可选的 device-mapper-verity (dm-verity) 内核功能进行启动时验证,以便对块存储设备进行透明的完整性检查。dm-verity 有助于阻止可以持续保有 root 权限并入侵设备的持续性 Rootkit。验证启动功能有助于 Android 用户在启动设备时确定设备状态与上次使用时是否相同。

具有 root 权限的潜在有害应用 (PHA) 可以躲开检测程序的检测,并以其他方式掩蔽自己。可以获取 root 权限的软件就能够做到这一点,因为它通常比检测程序的权限更高,从而能够“欺骗”检测程序。

通过 dm-verity 功能,您可以查看块存储设备(文件系统的底部存储层),并确定它是否与预期配置一致。该功能是利用加密哈希树做到这一点的。对于每个块(通常为 4k),都有一个 SHA256 哈希。

由于哈希值存储在页面树中,因此顶级“根”哈希必须可信,才能验证树的其余部分。能够修改任何块相当于能够破坏加密哈希。下图描绘了此结构。

dm-verity-hash-table

图 1. dm-verity 哈希表

启动分区中包含一个公钥,该公钥必须已由设备制造商在外部进行验证。该密钥用于验证相应哈希的签名,并用于确认设备的系统分区是否受到保护且未被更改。

5.1 操作

dm-verity 保护机制位于内核中。因此,如果获取 Root 权限的软件在内核启动之前入侵系统,它将会一直拥有该权限。为了降低这种风险,大多数制造商都会使用烧录到设备的密钥来验证内核。该密钥在设备出厂后即无法更改。

制造商会使用该密钥验证第一级引导加载程序中的签名,而该引导加载程序会依次验证后续级别引导加载程序、应用引导加载程序和内核中的签名。希望利用启动时验证功能的每个制造商都应该有验证内核完整性的方法。内核经过验证后,可以在块存储设备装载时由内核对其进行检查和验证。

验证块存储设备的一种方法是直接对其内容进行哈希处理,然后将其与存储的值进行比较。不过,尝试验证整个块存储设备可能会需要较长的时间,并且会消耗设备的大量电量。设备将需要很长时间来启动,从而在可供使用之前便消耗了大量电量。

而 dm-verity 只有在各个块被访问时才会对其进行单独验证。将块读入内存时,会以并行方式对其进行哈希处理。然后,会从第一级开始逐级验证整个哈希树的哈希。由于读取块是一项耗时又耗电的操作,因此这种块级验证带来的延时相对而言就有些微不足道了。

注意:作为针对 Android Go 和类似的低 RAM 设备进行的优化,dm-verity 可以配置为仅在首次(而不是每次)从数据设备读取页面时验证这些页面。首次验证之后,它会设置一个位以指示验证成功。由于此项优化提供的完整性保证级别略低,因此不应将其用于 RAM 更高的设备。如需了解详情,请参阅这些内核补丁。

如果验证失败,设备会生成 I/O 错误,指明无法读取相应块。设备看起来与文件系统损坏时一样,也与预期相同。

应用可以选择在没有结果数据的情况下继续运行,例如,当这些结果并不是应用执行主要功能所必需的数据时。不过,如果应用在没有这些数据的情况下无法继续运行,则会失败。

5.2 前向纠错

Android 7.0 及更高版本通过前向纠错 (FEC) 功能提高了 dm-verity 的稳健性。AOSP 实现首先使用常用的 Reed-Solomon 纠错码,并应用一种称为交错的技术来减少空间开销并增加可以恢复的损坏块的数量。有关 FEC 的更多详情,请参阅严格强制执行的启动时验证与纠错。

5.3 实现

摘要

  1. 生成 EXT4 系统映像。

  2. 为该映像生成哈希树。

  3. 为该哈希树构建 dm-verity 表。

  4. 为该 dm-verity 表签名以生成表签名。

  5. 将表签名和 dm-verity 表绑定到 Verity 元数据。

  6. 将系统映像、Verity 元数据和哈希树连接起来。

如需关于哈希树和 dm-verity 表的详细说明,请参阅 Chromium 项目 - 验证启动。

生成哈希树

如简介中所述,哈希树是 dm-verity 不可或缺的一部分。cryptsetup 工具将为您生成哈希树。或者,也可以使用下面定义的兼容方式:

<your block device name> <your block device name> <block size> <block size> <image size in blocks> <image size in blocks + 8> <root hash> <salt>

为了形成哈希,该工具会将系统映像在第 0 层拆分成 4k 大小的块,并为每个块分配一个 SHA256 哈希。然后,通过仅将这些 SHA256 哈希组合成 4k 大小的块来形成第 1 层,从而产生一个小得多的映像。接下来再使用第 1 层的 SHA256 哈希以相同的方式形成第 2 层。

直到前一层的 SHA256 哈希可以放到一个块中,该过程就完成了。获得该块的 SHA256 哈希后,就相当于获得了树的根哈希。

哈希树的大小(以及相应的磁盘空间使用量)会因已验证分区的大小而异。在实际中,哈希树一般都比较小,通常不到 30 MB。

如果某个层中的某个块无法由前一层的哈希正好填满,您应在其中填充 0 来获得所需的 4k 大小。这样一来,您就知道哈希树没有被移除,而是填入了空白数据。

为了生成哈希树,需要将第 2 层哈希组合到第 1 层哈希的上方,将第 3 层哈希组合到第 2 层哈希的上方,依次类推。然后将所有这些数据写入到磁盘中。请注意,这种方式不会引用根哈希的第 0 层。

总而言之,构建哈希树的一般算法如下:

  1. 选择一个随机盐(十六进制编码)。

  2. 将系统映像拆分成 4k 大小的块。

  3. 获取每个块的加盐 SHA256 哈希。

  4. 组合这些哈希以形成层。

  5. 在层中填充 0,直至达到 4k 块的边界。

  6. 将层组合到哈希树中。

  7. 重复第 2-6 步(使用前一层作为下一层的来源),直到最后只有一个哈希。

该过程的结果是一个哈希,也就是根哈希。在构建 dm-verity 映射表时会用到该哈希和您选择的盐。

构建 dm-verity 映射表

构建 dm-verity 映射表,该映射表会标明内核的块存储设备(或目标)以及哈希树的位置(是同一个值)。在生成 fstab 和设备启动时会用到此映射。该映射表还会标明块的大小和 hash_start,即哈希树的起始位置(具体来说,就是哈希树在映像开头处的块编号)。

如需关于 Verity 目标映射表字段的详细说明,请参阅 cryptsetup。

为 dm-verity 表签名

为 dm-verity 表签名以生成表签名。在验证分区时,会首先验证表签名。该验证是对照位于启动映像上某个固定位置的密钥来完成的。密钥通常包含在制造商的构建系统中,以便自动添加到设备上的固定位置。

如需使用这种签名和密钥的组合来验证分区,请执行以下操作:

  1. 将一个格式与 libmincrypt 兼容的 RSA-2048 密钥添加到 /verity_key 分区的 /boot 中。确定用于验证哈希树的密钥所在的位置。

  2. 在相关条目的 fstab 中,将 verify 添加到 fs_mgr 标记。

将表签名绑定到元数据

将表签名和 dm-verity 表绑定到 Verity 元数据。为整个元数据块添加版本号,以便它可以进行扩展,例如添加第二种签名或更改某些顺序。

一个魔数(作为一个健全性检查项目)会与每组表元数据相关联,以协助标识表。由于长度包含在 EXT4 系统映像标头中,因此这为您提供了一种在不知道数据本身内容的情况下搜索元数据的方式。

这可确保您未选择验证未经验证的分区。如果是这样,缺少此魔数将会导致验证流程中断。该数字类似于: 0xb001b001

十六进制的字节值为:

下图展示了 Verity 元数据的细分:

<magic number>|<version>|<signature>|<table length>|<table>|<padding>
\-------------------------------------------------------------------/
\----------------------------------------------------------/   |
                            |                                  |
                            |                                 32K
                       block content

下表介绍了这些元数据字段。

表 1.Verity 元数据字段

字段 用途 大小
魔数 供 fs_mgr 用作一个健全性检查项目 4 个字节 0xb001b001
版本 用于为元数据块添加版本号 4 个字节 目前为 0
签名 PKCS1.5 填充形式的表签名 256 个字节  
表长度 dm-verity 表的长度(以字节数计) 4 个字节  
上文介绍的 dm-verity 表 字节数与表长度相同  
填充 此结构会通过填充 0 达到 32k 长度   0

优化 dm-verity

为了充分发挥 dm-verity 的最佳性能,您应该:

6. 验证 system_other 分区

6.1 实现

搭载 Android 9 及更低版本且具有 A/B 分区的 Android 设备可以使用不活跃的 system_other 分区(例如,当 slot_a 处于活跃状态时,system_b 闲置)存储预优化的 VDEX/ODEX 文件。使用 system_other 时,ro.cp_system_other_odex 被设置为 1,以便软件包管理器服务设置 sys.cppreopt=requested,使 cppreopts.rc 能对其执行操作。

Android 10 中引入了 libfs_avb,以便支持对 system_other 分区进行独立的 AVB 验证。此类分区的 VBMeta 结构体附加在分区末尾,将由文件系统中的预期公钥验证。Android 构建系统支持对 system_other.img 签名,并将相应的签名密钥包含在 /product/etc/security/avb/system_other.avbpubkey 下。发布工具 sign_target_files_apks.py 还支持将签名密钥替换为发布版本。

如果 A/B 设备搭载的 Android 版本低于 Android 10,即便升级到 Android 10 并将 PRODUCT_RETROFIT_DYNAMIC_PARTITIONS 设置为 true,也具有一个 system_other 物理分区。

注意:建议不要在这些设备上启用 AVB。无线下载软件包中不包含 system_other.img,这可能会在一些 A/B 更新后导致验证错误。

搭载 Android 10 的 A/B 设备必须具有一个 system_other 逻辑分区。以下示例显示了对 system_other 启用 AVB 的典型 fstab.postinstall 文件。

#<dev> <mnt_point> <type>  <mnt_flags options>  <fs_mgr_flags>
system /postinstall ext4 ro,nosuid,nodev,noexec
slotselect_other,logical,avb_keys=/product/etc/security/avb/system_other.avbpubkey

需要对 system_other 分区启用 AVB 的设备应将 fstab 文件放到产品分区中,并将属性 ro.postinstall.fstab.prefix 设置为 /product。

# Use /product/etc/fstab.postinstall to mount system_other. PRODUCT_PRODUCT_PROPERTIES += \
ro.postinstall.fstab.prefix=/product

PRODUCT_COPY_FILES += \
$(LOCAL_PATH)/fstab.postinstall:$(TARGET_COPY_OUT_PRODUCT)/etc/fstab.postinstall

7. Android 启动时验证

Android 8.0 及更高版本包含启动时验证的一个供参考的实现,名为 Android 启动时验证 (AVB) 或启动时验证 2.0。AVB 是支持 Project Treble 架构的一个启动时验证版本,可以将 Android 框架与底层供应商实现分离开来。

AVB 与 Android 构建系统相集成,并通过一行代码(负责生成所有必要的 dm-verity 元数据并为其签名)进行启用。如需了解详情,请参阅构建系统集成。

AVB 提供 libavb,后者是一个在启动时用于验证 Android 的 C 库。您可以通过以下方式将 libavb 与引导加载程序集成在一起:针对 I/O 实现特定于平台的功能,提供信任根,并获取/设置回滚保护元数据。

AVB 的主要功能包括:针对不同分区委托更新、提供用于对分区进行签名的通用页脚格式,以及防止攻击者回滚到存在漏洞的 Android 版本。

如需了解实现方面的详细信息,请参阅 /platform/external/avb/README.md。