Android安全启动学习(五):Android Verified Boot 2.0

这篇具有很好参考价值的文章主要介绍了Android安全启动学习(五):Android Verified Boot 2.0。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

1、AVB概要

AVB2.0被用于启动引导,此用法添加一个“vbmeta.img”镜像。

public key被编译到bootloader中用于校验vbmeta数据,vbmeta.img包含应由此public key验证的签名。

vbmeta.img包含用于验证的public key,但只有bootloader验证过vbmeta.img才会可信,就好比认证一样,包含可信public key和签名。

因此,我们在AVB中有两个重要key,一个验证vbmeta.img的OEM key,一个验证其他分区(boot/system/vendor)的verity key。当然可以使用OEM key作为verity key。

我们知道OEM key用于在bootloader阶段验证vbmeta.img。这还不够,我们必须验证其他分区,vbmeta.img包含的public key用于此目的。就像avb1.0中verity key一样,此public key用于验证system、vendor分区和boot分区。

这里有些不同之处,avb1.0使用OEM key验证boot分区,使用verity key验证system/vendor分区,但avb2.0使用OEM key验证vbmeta.img,并使用其中包含的public key验证其他分区(system/vendor/boot等)。

2、AVB流程图

非A/B系统

AVB1.0

Android安全启动学习(五):Android Verified Boot 2.0

A/B系统

AVB1.0

Android安全启动学习(五):Android Verified Boot 2.0
boot.img=kernel + ramdisk + signature,使用OEM key验证boot.img的signature合法性。

AVB2.0

正如我们上面所说,avb2.0使用OEM key来验证vbmeta.img,并使用其中所包含的public key验证其他分区。

启动时bootloader将验证两个分区一个是使用OEM key验证vbmeta.img一个是使用vbmeta.img所包含的public key验证boot分区,而system/vendor分区由init/fs_mgr来验证(使用vbmeta.img所包含的public key)。(注意从1.0到2.0的顺序变化)

Android安全启动学习(五):Android Verified Boot 2.0

3、VBMeta结构

AVB2.0增加了一个vbmeta分区,对应的vbmeta.img由make_vbmeta_image工具编译生成的,其主要包含如下三大部分:

vbmeta image header(256 Bytes)
authentication data
	hash
	signature
auxiliary data
	public key
	public key metadata
	descriptors
		hash descriptors
		hashtree descriptors
		chain partition descriptors

vbmeta分区保存了受保护分区的所有信息,每个被avb2.0保护的分区后面都有一个vbmeta结构。vbmeta结构中包含多个描述符(和其他元数据),并且所有这些数据都被加密签名。受保护的分区可以配置为hash分区或者chain(链式)分区:

  • hash分区:hash校验,用hash描述符中hash(保存在vbmeta分区的vbmeta结构里)验证目标分区(看目标生成的保存我这里的一样不)

  • chain分区:key校验,用chain分区描述符中的public key(保存在vbmeta分区的vbmeta结构里)验证目标分区vbmeta结构的完整性(vbmeta被private key签名)

chain分区:key校验

AVB中使用的中心数据结构是VBMeta结构,此数据结构包含多个描述符(和其他元数据),并且所有这些数据都被加密签名。描述符用于image哈希、image哈希表元数据和所谓的链式分区。
Android安全启动学习(五):Android Verified Boot 2.0
key0来自bootloader的oem_pubk。

其中主vbmeta分区在哈希描述符中保存boot分区的哈希,对于system和vendor分区,哈希表在文件系统之后,主vbmeta分区在哈希表描述符中保存哈希表的root hash、salt和offset。(这里想起前面的哈希树没–roothash)

因为vbmeta分区中的vbmeta结构是以密码方式签名的,所以bootloader可以检测签名,并验证它是有key0的所有者(例如,通过嵌入key0的公共部分)创建的,从而信任于boot、system和vendor。

链式分区描述符用于委托权限——它包含委托权限的分区名称以及该特定分区上的签名所信任的public key。

hash分区:hash校验

Android安全启动学习(五):Android Verified Boot 2.0
在这个设置中,xyz分区有一个完整性检查的哈希表,在哈希表后面是一个vbmeta结构,它包含带有哈希表元数据(root has、salt和offset等),这个结构用key1签名的。最后,在此分区的末尾是一个页脚,它具有vbmeta结构的offset。

此设置允许bootloader使用链分区描述符来查找分区末尾的页脚(使用链分区描述符中的名称),有助于帮助找到xyz分区的vbmeta结构并验证是否由key1签名的(保存在链式分区描述符中的key1 public key)。至关重要的是,因为有一个带offset的页脚,所以可以更新zyz分区,而不需要vbmeta分区进行任何更改。

白话一刻:这里的就是在vbmeta结构中,针对不同的镜像有不同的校验方式。

4、vbmeta.img中vbmeta结构

Android安全启动学习(五):Android Verified Boot 2.0

  • chain分区描述符
    • 保存了用于验证目标分区vbmeta结构的public key
    • 如果目标分区vbmeta结构验证失败,将无法启动
  • hash表描述符
    • 目标分区vbmeta结构没有被使用,忽略
  • hash描述符
    • 除非它在“requested_partitions”中,被输入到avb2.0的入口函数:avb_slot_verify(),否则忽略目标分支vbmeta结构

vbmeta与boot/recovery/system/vendor绑定

  • 配置为hash分区:必须与主vbmeta一起更新

  • 配置为chain分区:假如目标分区vbmeta结构发生异常,就算此分区在当前启动模式不被使用,设备也将无法启动。

比如,假如recovery分区配置为chain分区,一旦recovery发生异常,normal boot也将无法启动
一旦recovery分区配置为hash分区,不能通过OTA改为chain分区配置

5、打开使用AVB功能

使能AVB2.0功能

android的kernel版本大于4.9,avb2.0是必须打开的。

lk:vendor/mediatek/proprietary/bootable/bootloader/lk/project/<project.mk>

MTK_AVB20_SUPPORT = yes

kernel:_debug_defconfig & _defconfig


1
CONFIG_MTK_AVB20_SUPPORT = y

配置avb分区

kernel-4.9\arch\arm64\boot\dts\mediatek\xxxx.dts

Android安全启动学习(五):Android Verified Boot 2.0

配置vbmeta.img的公钥与私钥

vbmeta.img被oem_prvk.pem进行私钥签名,在启动阶段lk使用avbkey.h中的公钥对vbmeta.img进行验证,所以avbkey.h配置的公钥与oem_prvk.pem的私钥必须是一对,且此key与secure boot校验其他分区的key不是同一个,配置文件也不是同一个,但是可以配置成同一组key。

配置受保护分区

默认不配置情况下,受保护分区采用hash分区方式,如需配置成chain分区方式,采用如下方式:

#settings for main vbmeta
 
BOARD_AVB_ALGORITHM := SHA256_RSA2048
 
BOARD_AVB_KEY_PATH := device/mediatek/common/oem_prvk.pem
 
 
 
ifeq ($(strip $(MAIN_VBMETA_IN_BOOT)),no)
 
#settings for recovery, which is configured as chain partition
 
BOARD_AVB_RECOVERY_KEY_PATH := device/mediatek/common/recovery_prvk.pem
 
BOARD_AVB_RECOVERY_ALGORITHM := SHA256_RSA2048
 
BOARD_AVB_RECOVERY_ROLLBACK_INDEX := 0
 
# Always assign "1" to BOARD_AVB_RECOVERY_ROLLBACK_INDEX_LOCATION
 
# if MTK_OTP_FRAMEWORK_V2 is turned on in LK. In other words,
 
# rollback_index_location "1" can only be assigned to
 
# recovery partition.
 
BOARD_AVB_RECOVERY_ROLLBACK_INDEX_LOCATION := 1
 
endif
 
 
 
#settings for system, which is configured as chain partition
 
BOARD_AVB_SYSTEM_KEY_PATH := device/mediatek/common/system_prvk.pem
 
BOARD_AVB_SYSTEM_ALGORITHM := SHA256_RSA2048
 
BOARD_AVB_SYSTEM_ROLLBACK_INDEX := 0
 
BOARD_AVB_SYSTEM_ROLLBACK_INDEX_LOCATION := 2
  • 配置了system分区为chain分区方式
  • 算法为SHA256_RSA2048
  • private key为device/mediatek/common/system_prvk.pem
  • 当MAIN_VBMETA_IN_BOOT宏为no时,配置recovery分区为chain分区方式

6、小结

在vbmeta 中包含了 数个descriptor ,每个descriptor 描述关于镜像文件的信息。例如 boot 镜像的hash值,dtbo 镜像的hash值。system和vendor分区比较大,因此在这里存放了这两个分区的Hashtree的数据。在vbmeta的镜像文件中除了存放vbmeta struct,还有AVB 私钥(key0)对vbmeta image的签名数据,以及AVB 公钥的数据。

Android安全启动学习(五):Android Verified Boot 2.0
AVB key 是一对非对称密钥。私钥用来签名,公钥用来验证。如关系如图所示:

Android安全启动学习(五):Android Verified Boot 2.0
其中key在源代码中存放的位置如下:
私钥

${MY_ANDROID}/device/fsl/common/security/xxxx_private.pem

公钥

${MY_ANDROID}/device/fsl/common/security/xxxx_public.bin.

为了更直观地了解vbmeta struct deneirong,我们可以根据Android 提供的工具,分析下vbmeta文件镜像的内容。命令下下:

Vbmeta image can be parsed using avbtool in Android.
$ cd ${MY_ANDROID}/out/target/product/xxxx
$ ../../../../external/avb/avbtool info_image --image vbmeta.img > vbmeta.img.info
$ cat vbmeta.img.info

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

DM-verity 的私钥在source code的地址:

${MY_ANDROID}/build/target/product/security/verity_private_dev_key.

公钥所在地址:

${MY_ANDROID}/build/target/product/security/verity_key.

对dm-verity table 签名之后,公钥放在boot镜像文件所在的分区中。

签名得对vbmeta签名,还得对dm-verity 表签名。为啥还得对表签名?这涉及到对于dm-verity table的理解。和hashtree 相对应的dm-verity table。

前面说过每个block都在hash-tree中记录了对应的hash值,这样就能防止别人篡改block的内容了,但是如果黑客把block改了之后,重新计算hash把hash-tree中对应的hash值也改了呢,这样就能神不知鬼不觉了,所以必须要有一种机制防止hash-tree被篡改,hash-tree是这样一种结构,所有的block对应的hash值放在最底层,也就是第0层,Android中采用的方法是算root-hash的签名,verity-table中保存了root-hash,对verity-table进行签名。

verity-table的校验是在用户空间(/system/core/fs_mgr/ )中完成的,校验合法之后会将verity-table传给kernel使用。

最后整个安全启动过程:

1.在刚启动的时候芯片rom对bootloader,或者如果使能了TEE OS,还包括对TEE 镜像的验证。
2.bootloader 对boot.img(kernel) 进行验证.
3.kernel启动完成后,对/system /vendor分区进行验证

第二步和第三步就是AVB的过程

这部分的理解还是存在局部的细节问题,等待继续思考学习

参考资料:

https://ressrc.com/2018/10/07/android-p
https://android.googlesource.com/platform/external/avb/+/master/README.md#The-VBMeta-struct
https://blog.csdn.net/StevenYang2008/article/details/106747458/文章来源地址https://www.toymoban.com/news/detail-422142.html

到了这里,关于Android安全启动学习(五):Android Verified Boot 2.0的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • android安全启动验证链

    前言android 系统安全内容总结 启动验证链核心技术就是签名验签,这里复习下,流程如上图: android基础算法使用的是RSA 红色部分是编译时对需要验签的镜像与文件进行签名操作;需要用到私钥,这个私钥一般放在编译代码或者签名服务器。 黄色部分是开机启动时对启动镜像

    2024年02月05日
    浏览(49)
  • 【0-1】从0.1开始学Android逆向-APK基本结构概要分析

    最近在进行Android的逆向,在这里整理知识点和分享Android逆向知识。如果文章中有任何勘误,诚挚的邀请师傅们批评改正! 逆向工程(Reverse Engineering)是一种分析和解剖已有产品、系统或软件的过程,以了解其内部工作原理、设计、功能或源代码。逆向工程可以应用于多个领

    2024年02月08日
    浏览(37)
  • Spring Boot学习随笔-第一个SpringBoot项目快速启动(org.springframework.boot、@SpringBootApplication、application.yml)

    学习视频:【编程不良人】2021年SpringBoot最新最全教程 创建第一个Module 环境要求 jdk1.8+ maven3.2+ Spring Framework 5.x+ Tomcat 9.0+ IDEA 2021 自动保存刷新pom 在resources下添加application.yml文件后,即可启动springboot应用 由于tomcat内嵌在springboot里面了,所以我们在修改端口号等设置也在配置

    2024年02月05日
    浏览(56)
  • Spring Boot 2.0 @ModelAttribute

    Spring Boot 2.0 中的注解 @ModelAttribute 有什么作用呢? 通常情况下,我们会将 @ModelAttribute 注解放置在 Controller 中的某个方法上,那么,如果您在请求这个 Controller 中定义的 URI 时,会首先调用这个被注解的方法,并将该方法的结果作为 Model 的属性,然后才会调用对应 URI 的处理

    2024年02月08日
    浏览(33)
  • linuxer眼中ml.net机器学习概要

    https://github.com/markjprice/cs12dotnet8 https://github.com/markjprice/cs12dotnet8/blob/main/docs/ch01-dotnet-history.md 这里讲的很清楚   现代.net和以前的.net框架的关系,如下图  其中.net5是一个关键的跨越版本,在这后.net完全的跨平台统一了 2020 年 11 月合并为 .NET 5 这样的单一线程。(注意, .NE

    2024年02月05日
    浏览(31)
  • android源码学习- APP启动流程(android12源码)

    百度一搜能找到很多讲APP启动流程的,但是往往要么就是太老旧(还是基于android6去分析的),要么就是不全(往往只讲了整个流程的一小部分)。所以我结合网上现有的文章,以及源码的阅读和调试,耗费了3整天的时间,力求写出一篇最完整,最详细,最通俗易懂的文章,

    2024年02月11日
    浏览(44)
  • 【Android】APP启动优化学习笔记

    用户体验: 应用的启动速度直接影响用户体验。用户希望应用能够快速启动并迅速响应他们的操作。如果应用启动较慢,用户可能会感到不满,并且有可能选择卸载或切换到竞争对手的应用。通过启动优化,可以提高应用的启动速度,让用户获得更好的使用体验。 竞争优势

    2024年02月14日
    浏览(40)
  • 小诺2.0开源版工程启动

    小诺是一款开源的前后端开发框架,同若依、SpringBladex一样可作为私活、外包脚手架。 开源地址:Snowy: 最新:💖国内首个国密前后分离快速开发平台💖,采用Vue3+AntDesignVue3 + Vite+SpringBoot+Mp+HuTool+SaToken。集成国密加解密插件,在前后分离框架中,实现前后分离“密”不可分;

    2024年02月05日
    浏览(76)
  • YOLO技术概要学习笔记2——YOLOV2到YOLOV3

    实时物体检测已经成为众多邻域应用的关键组成部分,这些领域包括:自动驾驶车辆、机器人、视频监控和增强现实等。在众多物体检测算法中,近年来,YOLO(You Only Look Once)框架以其卓越的速度和准确性脱颖而出,实际证明能够快速可靠地识别图像中的物体。自诞生以来,

    2024年02月08日
    浏览(34)
  • Android framework学习指南之Launcher启动过程原理分析

    Launcher是一个用来显示系统中已经安装的应用程序的应用程序,Launcher 在启动过程中会请求PackageManagerService 返回系统中已经安装的应用程序的信息,并将这些信息封装成一个快捷图标列表显示在系统屏幕上,这样用户可以通过点击这些快捷图标来启动相应的应用程序,它的作

    2024年02月03日
    浏览(47)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包