一、libavb库
1.1 目录结构
libavb库用于在设备端执行所有验证,在代码中的路径是external/avb。其目录结构如下:
(1)libavb:image验证的实现。具有高度可移植性。此代码会兼容C99的C编译器。其中avb_rsa.c/avb_rsa.h和avb_sha.c/avb_sha.h用于内部实现,不应在外部被使用。avb_sysdeps.h用于定义由平台提供的系统依赖项。如果平台提供了标准的C runtime,则可以使用avb_sysdeps_posix.c。
(2)libavb_atx:用于验证public key metadata的Android Things扩展。
(3)libavb_user:用于Android用户空间的AvbOps实现。在boot_control.avb和avbctl中被使用。
(4)libavb_ab:用于bootloader和适用于A/B系统的AVB实现(已于2018年6月1日弃用,必须定义AVB_AB_I_UNDERSTAND_LIBAVB_AB_IS_DEPRECATED才能使用它)。
(5)boot_control:使用libavb_ab 堆栈与bootloader一起使用的Android boot_control HAL的实现(已于2018年6月1日弃用)。
(6)contrib:包含其他项目中与AVB互操作性所需的patch。
(7)Android.bp:用于编译设备静态库libavb,单元测试的host库和单元测试的编译说明。
(8)avbtool:用于处理与verified boot相关的image。
(9)test:abvtool,libavb,libavb_ab和libavb_atx的单元测试代码。
(10)tool/ avbctl:可用于在Android runtime控制AVB的工具的源代码。
(11)example/ UEFI:使用libavb和libavb_ab的基于UEFI的bootloader的源代码。
(12)example/things:包含适用于Android Things的slot验证的源代码。
(13)README.md:说明文档。
(14)docs:包含文档文件。
1.2 版本号
avbtool有三个字段的版本号:主版本.次版本.子版本。如1.4.3中”1”代表主版本号,”4”代表次版本号,”3”代表子版本号。仅当兼容性有问题时,major version才会被改变,如结构字段已被删除或更改的情况出现。minor version只有在引入了新功能的情况下才会被更改,如已添加新算法或描述符。修正错误或进行其他不影响兼容性的更改时,sub version会增加。
在avb_vbmeta_image.h中定义AvbVBMetaImageHeader结构会带有libavb的主要版本号和次要版本号,用于验证相关结构。它存储在required_libavb_version_major和required_libavb_version_minor字段中。此外,此结构还包含一个文本字段,其中包含用于创建该结构的avbtool版本,例如”avbtool 1.4.3”或”avbtool 1.4.3 some_board Git-4589fbec”。如下图所示:
1 | required_libavb_version_major = 1 |
二、avbtool脚本
2.1 编译image
(1)boot.img
1 | out/host/linux-x86/bin/avbtool add_hash_footer \ |
(2)dtbo.img
1 | out/host/linux-x86/bin/avbtool add_hash_footer \ |
(3)system.img
1 | out/host/linux-x86/bin/avbtool add_hashtree_footer \ |
(4)vendor.img
1 | out/host/linux-x86/bin/avbtool add_hashtree_footer |
(5)product.img
1 | out/host/linux-x86/bin/avbtool add_hashtree_footer |
(6)vbmeta.img
1 | out/host/linux-x86/bin/avbtool make_vbmeta_image |
2.2 获取image信息
(1)boot.img
执行指令:avbtool info_image –image boot.img > boot.img.info,然后用文本编辑器打开boot.img.info文件:
1 | Footer version: 1.0 |
(2)dtbo.img
执行指令:avbtool info_image –image dtbo.img > dtbo.img.info,然后用文本编辑器打开dtbo.img.info文件:
1 | Footer version: 1.0 |
(3)system.img
执行指令:avbtool info_image –image system.img > system.img.info,然后用文本编辑器打开system.img.info文件:
1 | Footer version: 1.0 |
(4)vendor.img
执行指令:avbtool info_image –image vendor.img > vendor.img.info,然后用文本编辑器打开vendor.img.info文件:
1 | Footer version: 1.0 |
(5)product.img
执行指令:avbtool info_image –image product.img > product.img.info,然后用文本编辑器打开product.img.info文件:
1 | Footer version: 1.0 |
(6)vbmeta.img
执行指令:avbtool info_image –image vbmeta.img > vbmeta.img.info,然后用文本编辑器打开vbmeta.img.info文件:
1 | Minimum libavb version: 1.0 |
2.3 其它功能
(1)使用resize_image命令更改带有完整页脚的映像的大小:
1 | $ avbtool resize_image \ |
(2)可以删除映像上的完整性页脚。哈希树可以选择保留在适当的位置:
1 | $ avbtool erase_footer --image IMAGE [--keep_hashtree] |
(3)可以使用命令将映像中的哈希树和FEC数据清零:
1 | $ avbtool zero_hashtree --image IMAGE |
(4)可使用–calc_max_image_size选项计算适合给定大小分区的映像的最大大小:
1 | $ avbtool add_hash_footer --partition_size $((10*1024*1024)) \ |
(5)可使用–print_required_libavb_version选项获取放入vbmeta结构中的所需libavb版本:
1 | $ avbtool make_vbmeta_image \ |
(6)–no_hashtree可以与avbtool add_hashtree_footer命令一起使用。如果给出了–no_hashtree,则省略哈希树blob,仅将其描述符添加到vbmeta结构中。描述符表示哈希树的大小为0,这表明应用程序需要重新计算哈希树。
(7)append_vbmeta_image命令可用于将整个vbmeta blob附加到另一个映像的末尾。这在不使用任何vbmeta分区的情况下非常有用,例如:
1 | $ cp boot.img boot-with-vbmeta-appended.img |
(8)verify_image命令可用于同时验证多个映像文件的内容。在映像上调用时,将执行以下检查:
如果映像具有VBMeta结构,则根据嵌入式public key检查签名。如果映像看起来不像vbmeta.img,那么将查找页脚并使用它。如果传递了–key选项,则应使用.pem文件,并检查所述VBMeta结构中的嵌入式public key是否与给定密钥匹配。采用下列方式检查VBMeta结构中的所有描述符:
a.对于散列描述符,将加载与分区名称相对应的映像文件,并对照描述符中的摘要检查其摘要。
b. 对于哈希树描述符,将加载与分区名称相对应的映像文件,并计算哈希树,并将其根摘要与描述符中的摘要进行比较。
c. 对于链接的分区描述符,将其内容与需要通过–expected_chain_partition选项传递的内容进行比较。该选项的格式类似于–chain_partition选项的格式。如果链分区描述符没有–expected_chain_partition描述符,则检查失败。
下面是一个示例,其中boot.img和system.img的摘要存储在vbmeta.img中,该摘要已用my_key.pem签名。它还检查分区foobar的链分区是否使用回滚索引8,以及AVB格式的公钥是否与文件foobar_vendor_key.avbpubkey的公钥匹配:
1 | $ avbtool verify_image \ |
(9)compute_vbmeta_digest命令可用于同时计算多个映像文件的vbmeta摘要。结果将以十六进制字符串的形式打印在STDOUT或提供的路径上(使用–output选项):
1 | $ avbtool calculate_vbmeta_digest \ |
calculate_vbmeta_digest命令将加载vbmeta.img文件。如果此映像具有一个或多个链分区描述符,则使用与verify_image命令相同的逻辑来加载这些文件的文件(例如,假定与给定映像具有相同的目录和文件扩展名)。加载完所有vbmeta结构后,将计算摘要(使用–hash_algorithm选项提供的哈希算法)并打印出来。