验证启动(Verified Boot)是Android一个重要的安全功能,主要是为了访问启动镜像被篡改,提高系统的抗攻击能力,简单描述做法就是在启动过程中增加一条校验链,即 ROM code 校验 BootLoader,确保 BootLoader 的合法性和完整性,BootLoader 则需要校验 boot image,确保 Kernel 启动所需 image 的合法性和完整性,而 Kernel 则负责校验 System 分区和 vendor 分区。

由于 ROM code 和 BootLoader 通常都是由设备厂商 OEM 提供,而各家实际做法和研发能力不尽相同,为了让设备厂商更方便的引入 Verified boot 功能,Google 在 Android O上推出了一个统一的验证启动框架 Android verified boot 2.0,好处是既保证了基于该框架开发的verified boot 功能能够满足 CDD 要求,也保留了各家 OEM 定制启动校验流程的弹性。

由于 ROM code 校验 BootLoader 的功能通常与 IC的设计相关,所以 AVB 2.0 关注的重点在 BootLoader 之后的校验流程。BootLoader 之后系统启动所涉及的关键镜像通常包括 boot.img,system.img,Android O 的 treble Project 还引入了 dtbo 和 vendor.img。这些 image 挨个校验可以说费时费力,而 AVB 2.0 的做法事实上十分简单,引入一个新的分区:vbmeta.img(verified boot metadata),然后把所有需要校验的内容在编译时就计算好打包到这个分区,那么启动过程中 BootLoader 只需要校验 vbmeta.img,就能确认 vbmeta 内的数据是否可信。再用 vbmeta 中的数据去比对 bootimg,dtbo,system,img,vendor.img 即可。至于 OEM 是还需要放什么其他东西到 vbmeta 中,则可以由 OEM 自由定制,可以说保留了很好的客制化空间。

除了最基本的验证启动之外,AVB 2.0 还提供防止回滚的功能和对AB分区备份的支持,AVB 2.0 的详细文档可以参考:Android Verified Boot 2.0

无论是验证启动还是防止回滚,vbmeta 都是很重要的数据结构,下面对最简单的 vbmeta struct 做一个分析说明。
下面是 vbmeta struct 的结构图示:

以上 vbmeta 所包含的数据可以分成两个大的Block:紫色色块部分为 Authentication data block 和 其他为 Auxiliary data block。当 BOARD_AVB_ALGORITHM 定义为 SHA256_RSA2048 时,默认编译出的 vbmeta.img 通常为 4KB。vbmeta.img 组成如下:

------------------------------------------------------------------------------
|   Header   |   Authentication Data   |    Auxiliary Data    |
------------------------------------------------------------------------------

其中 Header 的固定长度为 0x100 个字节,Authentication data 和 Auxiliary data 的长度存储在 Header 中。

下面分别对这三个部分进行分析、

Header 解析

Header 的数据结构为:typedef struct AvbVBMetaImageHeader
用 UE 打开 vbmeta.img,前 0x100 个字节信息如下:


根据 struct AvbVBMetaImageHeader,上图中的 Header 信息解析如下:

Authentication data block 解析

Authentication data block 用于校验 vbmeta.img 的合法性和完整性,包含两部分内容:Hash data 和 signature data。
通过分析avbtool 的 Python 脚本,即可了解 hash data 和 signature data 的生成过程。

Hash data 的生成
     hash data 是对 vbmeta 的 header 和 auxiliary data block 的 hash 计算,所以是先生成了 auxiliary data block,然后生成的 authentication data block,使用的算法由 header 中的 algorithm_type 指定,本文使用 SHA256,计算出的 hash data 长度为 0x20。截取 avbtool 的脚本代码如下:

# Calculate the hash.

ha = hashlib.new(alg.hash_name)

ha.update(header_data_blob)

ha.update(aux_data_blob)

binary_hash.extend(ha.digest())

signature data 的生成
     signature data 是对 上文计算出的 hash data 做 padding 之后的签名,使用的算法同样由 header 中的 algorithm_type 指定,本文使用 RSA2048,计算出的 signature data 长度为 0x100。截取 avbtool 的脚本代码如下:

# Calculate the signature.

padding_and_hash = str(bytearray(alg.padding)) + binary_hash

binary_signature.extend(raw_sign(signing_helper, signing_helper_with_files, algorithm_name, alg.signature_num_bytes, key_path, padding_and_hash))

有一个需要注意的地方是,hash data 和 signature data 的总长加在一起为0x120,但header 中的 authentication data block size 却为 0x140,这是因为 image 对齐需要,0x120 不能被 64 整除,所以用 0x0 填充到长度为 0x140。

Auxiliary data block 解析

Auxiliary data block 的内容则十分丰富,总得来说分为两个大类:AvbDescriptor 和 RSA public key。

AvbDescriptor 的生成
根据 avbtool make_vbmeta_image 命令支持的参数,OEM 可以自由的定制一些需要打包到 vbmeta.img 的数据,这样一段一段的二进制数据都按照AvbDescriptor 的数据结构打包进 auxiliary data block。AvbDescriptor 按照不同的 tag 分为以下几种:

typedef enum {
        AVB_DESCRIPTOR_TAG_PROPERTY,
        AVB_DESCRIPTOR_TAG_HASHTREE,
        AVB_DESCRIPTOR_TAG_HASH,
        AVB_DESCRIPTOR_TAG_KERNEL_CMDLINE,
        AVB_DESCRIPTOR_TAG_CHAIN_PARTITION,
} AvbDescriptorTag;

最常用的参数 ---include_descriptor_from_image 可以将 boot.img,dtbo,recovery.img,system.img,vendor.img 的 descriptor 打包到 Auxiliary data block 中。这些 descriptors 在 BootLoader 确认 vbmeta.img 的合法性和完整性后,可以直接被用来校验 boot.img,dtbo,recovery.img,system.img,vendor.img。

RSA public key的生成
除了这些 descriptor 之外,auxiliary data block 中还有一个重要的信息,就是 RSA public key。这个 public key 将被用来校验 authentication data block 中的 signature data。
在 avbtool make_vbmeta_image 时,必须用--key参数来指定生成 signature data 的 RSA private key,AOSP external/avb/test/data 目录下有各种供测试使用 RSA private key,格式为 PEM。avbtool 会根据 RSA private key 提取 public key 并加上 RSA key 的 header 打包进 auxiliary data block。
可以通过avbtool extract_public_key --key [priv_key_path] --output [outpubk_path] 来查看生成的 public key 信息。
其中 RSA key header 格式如下:

typedef struct AvbRSAPublicKeyHeader {
         uint32_t key_num_bits;
         uint32_t n0inv;
} AVB_ATTR_PACKED AvbRSAPublicKeyHeader;

前文中所描述 header 中的 public key size 为 0x208,即 0x8 个字节的 AvbRSAPublicKeyHeader 长度,加上 0x200个字节即 2048位 的 public key 长度。

以上就是 vbmeta 除 padding 填充 0x0 之外,主要的数据信息。

作者:SmartEmily
链接:https://www.jianshu.com/p/a2542426bdde
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

作者:SmartEmily
链接:https://www.jianshu.com/p/a2542426bdde
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

Android verified boot 2.0 vbmeta 数据结构解析相关推荐

  1. Android Verified Boot 2.0 最新安卓P AVB详解

    什么是AVB 验证启动是确保用户设备运行软件完整性的一整套流程. 它通常从设备固件的只读部分启动,使用加密方式验证代码是可靠且没有任何已知的安全缺陷之后才会执行. AVB是验证启动的一种实现. VBM ...

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

    1.AVB概要 AVB2.0被用于启动引导,此用法添加一个"vbmeta.img"镜像. public key被编译到bootloader中用于校验vbmeta数据,vbmeta. ...

  3. Magisk root 原理分析之二 :Android Verified Boot (AVB)

    1. Android Verified Boot (AVB) 或称 Verified Boot 2.0 简介 官方解释:验证用户设备上运行的软件完整性.它通常从设备固件的只读部分开始,该部分加载代码并 ...

  4. Android Glide 3.7.0 源码解析(八) , RecyclableBufferedInputStream 的 mark/reset 实现

    个人博客传送门 一.mark / reset 的作用 Android Glide 3.7.0 源码解析(七) , 细说图形变换和解码有提到过RecyclableBufferedInputStream ...

  5. AVB校验微观版本:android avb(Android Verified Boot)验证

    前辈原文:https://blog.csdn.net/weixin_43836778/article/details/90400147 其实可能有人会说,怎么整这么多重复的,其实不是的.这是为了不断地 ...

  6. Android Verified Boot dm-verity 优化和实战

    目录 一.AVB 技术背景 二.代码实现逻辑 一.AVB 技术背景 Android O/P 版本以来,谷歌加入了system-as-root的特性,此时ramdisk和system是一起放在同一个sy ...

  7. android studio无app项,Android studio 3.0:无法解析依赖:app @ dexOptions

    Android studio 3.0:无法解析依赖:app @ dexOptions 我迁移到Android studio 3.0.因此,项目无法编译名为":animator"的模 ...

  8. Android事件总线(一)EventBus3.0用法全解析

    相关文章 Android事件总线(一)EventBus3.0用法全解析 Android事件总线(二)EventBus3.0源码解析 Android事件总线(三)otto用法全解析 Android事件总 ...

  9. Spring Boot 2.0 新特性(一):配置绑定 2.0 全解析

    在Spring Boot 2.0中推出了Relaxed Binding 2.0,对原有的属性绑定功能做了非常多的改进以帮助我们更容易的在Spring应用中加载和读取配置信息.下面本文就来说说Sprin ...

  10. android启动---lk入口文件crt0.s解析

    android启动---lk入口文件crt0.s解析 // .section 伪操作, 用户可以通过.section 伪操作来自定义一个段,每一个段以段名为开始, //以下一个段名或者文件结尾为结束, ...

最新文章

  1. Android中使用File文件进行数据存储
  2. 关节点(atriculation point)算法
  3. Go 变量及基本数据类型3
  4. formal method online checking tool
  5. 配置一个Servlet可以被一个(指定的开头链接,后自定义)访问
  6. seo需要处理页面html,为什么单页面的seo不友好?如何解决这一问题?
  7. fputc会覆盖吗_蔬菜覆盖地膜有什么好处?选择什么膜好?
  8. shellcode编写
  9. python使用phantomJS循环for爬取多个页面时,解决内存持续变大而报错“ConnectionResetError: [WinError 10054]远程主机强迫关闭了一个现有的连接”的问题
  10. 社交游戏Zynga之死
  11. 47. Use traits for information about types.
  12. Python读取罗技G29数据
  13. CloudCompare 软件手册
  14. 【UWB 定位】室内定位 三边定位算法
  15. 每天一个小技巧【1】·TextMeshPro的中文设置
  16. 马哥2018linux课程目录,马哥教育2018年Linux第30期视频教程
  17. Origin 导入数据画图使用经验总结
  18. loading遮不住dialog
  19. python编程价格_Python基础练习实例46(查询价格)
  20. 在运行里输入打开WIN工具。

热门文章

  1. 你有被代理过吗?讲讲开源框架都在用的代理模式
  2. CF1296E1——String Coloring (easy version)
  3. srsRAN源码分析----enb端协议栈是如何运作
  4. axure 折线图部件_Axure教程:折线图
  5. 利用开源工具搭一套汉英翻译系统(二):词对齐
  6. 26字母 导航 android,Android自定义View实现字母导航栏的代码
  7. 如何把数字转为大写的汉字
  8. Temporal Action Proposal Generation with Transformers TAPG transformer论文阅读笔记
  9. 《孙子兵法特殊战法之火攻篇》
  10. 在浏览器输入URL,按下回车之后的流程