AVB数据解析:Android verified boot 2.0 vbmeta 数据结构解析

本文涉及的产品
全局流量管理 GTM,标准版 1个月
云解析 DNS,旗舰版 1个月
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
简介: AVB数据解析:Android verified boot 2.0 vbmeta 数据结构解析

前言

验证启动(Verified Boot)是Android一个重要的安全功能,主要是为了访问启动镜像被篡改,提高系统的抗攻击能力,简单描述做法就是在启动过程中增加一条校验链。或者也可以说是信任链:

ROM code-->BootLoader-->boot image--> 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 自由定制,可以说保留了很好的客制化空间。

于是整个信任链的建立可以分为两个部分:自研的(bootrom + loader)+ 开源的AVB(boot、vendor、system。。。)

之前我们对于这个AVB的方案也有些了解,对于流程之类的也写了一部分的blog,但是对于镜像的本身没有研究过,在进行一些校验失败的场景,肯定是在所难免的需要看一下镜像的自身结构,说不定有帮助。

除了最基本的验证启动之外,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 的固定长度为 0x100 个字节,Authentication data 和 Auxiliary data 的长度存储在 Header 中。

下面展开瞅瞅

一、Header 解析

可以copy一份header的数据结构体看一下:https://android.googlesource.com/platform/external/avb/+/master/libavb/avb_vbmeta_image.h

用 UE 打开 vbmeta.img,前 0x100 个字节信息如下:

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

  • 0x0 - 0x3 magic[AVB_MAGIC_LEN] magic字符串,固定为 AVB0
  • 0x4 - 0x7 required_libavb_version_major libavb 大版本号 0x1
  • 0x8 - 0xb required_libavb_version_minor libavb 小版本号 0x0
  • 0xc - 0x13 authentication_data_block_size 如果选用 SHA256_RSA2048算法,则 authentication data size 固定为 0x140
  • 0x14 - 0x1B auxiliary_data_block_size 根据 make_vbmeta_image 不同参数,长度不同,上图为 0x4C0
  • 0x1C - 0x1F algorithm_type 由AvbAlgorithmType定义, 0x1 表示AVB_ALGORITHM_TYPE_SHA256_RSA2048
  • 0x20 - 0x27 hash_offset hash data 在 authentication data 中的位置,通常为 0x0,hash data的具体说明会在 Authentication data 的解析中加以说明
  • 0x28 - 0x2F hash_size hash data 的大小,使用SHA256算法时 Hash data 固定为 0x20 个字节,即 256 bits
  • 0x30 - 0x37 signature_offset signature data 在 authentication data 中的位置,signature data紧跟在 Hash data 后面,所以 offset 在 hash 算法为 SHA256时,固定为 0x20
  • 0x38 - 0x3F signature_size signature data 的大小,在签名算法使用 RSA2048 时,固定为 0x100个字节,即 2048 bits
  • 0x40 - 0x47 public_key_offset 签名算法对应的公钥存储在 Auxiliary data block 中的位置,上图为 0x298
  • 0x48 - 0x4F public_key_size 签名算法对应的公钥长度,使用RSA2048 作为签名算法时,该长度固定为 0x208, public key 部分会在 Auxiliary data block 的解析中加以说明
  • 0x50 - 0x57 public_key_metadata_offset public key metadata 在 auxiliary data block 中的存储位置
  • 0x58 - 0x5F public_key_metadata_size public key metadata 的大小,为 0x0 表示没有 public key metadata 数据
  • 0x60 - 0x67 descriptors_offset descriptor 在 Auxiliary data block 中的位置,默认固定为 0x0,descriptor 的具体含义会在 Auxiliary data block 的解析中加以说明
  • 0x68 - 0x6F descriptors_size descriptor 的长度,取决于 make_vbmeta_image 时的参数 —include_descriptor_from_image
  • 0x70 - 0x77 rollback_index 供rollback protection 功能使用,由 make_vbmeta_image 时的参数 —rollback_index 指定,上图中为 0x0,即未对回滚保护做支持
  • 0x78 - 0x7F reserved0[4] 16字节对齐使用,固定为四个 0x0
  • 0x80 - 0xAF release_string[AVB_RELEASE_STRING_SIZE] avbtool 的 release 信息,48个字节,一般为 avbtool 1.0.0 xxxxx
  • 0xB0 - 0xFF reserved[80] padding数据,保证 Header长度为 x100,内容必须全部填 0x0

二、Authentication data block 解析

Authentication data block 用于校验 vbmeta.img 的合法性和完整性,包含两部分内容:Hash data 和 signature data。

通过分析avbtool 的 Python 脚本,即可了解 hash data 和 signature data 的生成过程。

1-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())

2-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。

1-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 之外,主要的数据信息。

以上就是全部内容,关于vbmeta镜像,如果是你想了解其校验的过程、以及镜像生成的过程,可以看一下源码,结合这个专栏其他的文章食用更佳。

感谢前辈的优秀blog,供给我们学习。

参考链接:

https://www.jianshu.com/p/a2542426bdde

目录
相关文章
|
1月前
|
Java 开发工具 Android开发
Android与iOS开发环境搭建全解析####
本文深入探讨了Android与iOS两大移动操作系统的开发环境搭建流程,旨在为初学者及有一定基础的开发者提供详尽指南。我们将从开发工具的选择、环境配置到第一个简单应用的创建,一步步引导读者步入移动应用开发的殿堂。无论你是Android Studio的新手还是Xcode的探索者,本文都将为你扫清开发道路上的障碍,助你快速上手并享受跨平台移动开发的乐趣。 ####
|
1月前
|
消息中间件 存储 缓存
十万订单每秒热点数据架构优化实践深度解析
【11月更文挑战第20天】随着互联网技术的飞速发展,电子商务平台在高峰时段需要处理海量订单,这对系统的性能、稳定性和扩展性提出了极高的要求。尤其是在“双十一”、“618”等大型促销活动中,每秒需要处理数万甚至数十万笔订单,这对系统的热点数据处理能力构成了严峻挑战。本文将深入探讨如何优化架构以应对每秒十万订单级别的热点数据处理,从历史背景、功能点、业务场景、底层原理以及使用Java模拟示例等多个维度进行剖析。
55 8
|
1月前
|
数据采集 自然语言处理 搜索推荐
基于qwen2.5的长文本解析、数据预测与趋势分析、代码生成能力赋能esg报告分析
Qwen2.5是一款强大的生成式预训练语言模型,擅长自然语言理解和生成,支持长文本解析、数据预测、代码生成等复杂任务。Qwen-Long作为其变体,专为长上下文场景优化,适用于大型文档处理、知识图谱构建等。Qwen2.5在ESG报告解析、多Agent协作、数学模型生成等方面表现出色,提供灵活且高效的解决方案。
158 49
|
24天前
|
存储 Linux API
深入探索Android系统架构:从内核到应用层的全面解析
本文旨在为读者提供一份详尽的Android系统架构分析,从底层的Linux内核到顶层的应用程序框架。我们将探讨Android系统的模块化设计、各层之间的交互机制以及它们如何共同协作以支持丰富多样的应用生态。通过本篇文章,开发者和爱好者可以更深入理解Android平台的工作原理,从而优化开发流程和提升应用性能。
|
24天前
|
Java 调度 Android开发
安卓与iOS开发中的线程管理差异解析
在移动应用开发的广阔天地中,安卓和iOS两大平台各自拥有独特的魅力。如同东西方文化的差异,它们在处理多线程任务时也展现出不同的哲学。本文将带你穿梭于这两个平台之间,比较它们在线程管理上的核心理念、实现方式及性能考量,助你成为跨平台的编程高手。
|
23天前
|
XML JSON JavaScript
HttpGet 请求的响应处理:获取和解析数据
HttpGet 请求的响应处理:获取和解析数据
|
2月前
|
自然语言处理 数据可视化 前端开发
从数据提取到管理:合合信息的智能文档处理全方位解析【合合信息智能文档处理百宝箱】
合合信息的智能文档处理“百宝箱”涵盖文档解析、向量化模型、测评工具等,解决了复杂文档解析、大模型问答幻觉、文档解析效果评估、知识库搭建、多语言文档翻译等问题。通过可视化解析工具 TextIn ParseX、向量化模型 acge-embedding 和文档解析测评工具 markdown_tester,百宝箱提升了文档处理的效率和精确度,适用于多种文档格式和语言环境,助力企业实现高效的信息管理和业务支持。
4081 5
从数据提取到管理:合合信息的智能文档处理全方位解析【合合信息智能文档处理百宝箱】
|
1月前
|
存储 分布式计算 Java
存算分离与计算向数据移动:深度解析与Java实现
【11月更文挑战第10天】随着大数据时代的到来,数据量的激增给传统的数据处理架构带来了巨大的挑战。传统的“存算一体”架构,即计算资源与存储资源紧密耦合,在处理海量数据时逐渐显露出其局限性。为了应对这些挑战,存算分离(Disaggregated Storage and Compute Architecture)和计算向数据移动(Compute Moves to Data)两种架构应运而生,成为大数据处理领域的热门技术。
64 2
|
1月前
|
存储 消息中间件 NoSQL
Redis数据结构:List类型全面解析
Redis数据结构——List类型全面解析:存储多个有序的字符串,列表中每个字符串成为元素 Eelement,最多可以存储 2^32-1 个元素。可对列表两端插入(push)和弹出(pop)、获取指定范围的元素列表等,常见命令。 底层数据结构:3.2版本之前,底层采用**压缩链表ZipList**和**双向链表LinkedList**;3.2版本之后,底层数据结构为**快速链表QuickList** 列表是一种比较灵活的数据结构,可以充当栈、队列、阻塞队列,在实际开发中有很多应用场景。
|
1月前
|
JavaScript API 开发工具
<大厂实战场景> ~ Flutter&鸿蒙next 解析后端返回的 HTML 数据详解
本文介绍了如何在 Flutter 中解析后端返回的 HTML 数据。首先解释了 HTML 解析的概念,然后详细介绍了使用 `http` 和 `html` 库的步骤,包括添加依赖、获取 HTML 数据、解析 HTML 内容和在 Flutter UI 中显示解析结果。通过具体的代码示例,展示了如何从 URL 获取 HTML 并提取特定信息,如链接列表。希望本文能帮助你在 Flutter 应用中更好地处理 HTML 数据。
121 1

推荐镜像

更多