android dm-verity 功能

2023-11-19

Android dm-verity 实现原理深入研究

思维导图:

dm-verifydm-verity

说明:源码基于 SC20 平台 Android5.1
Android dm-verify overview

目录

Android dm-verify overview.. 1

一、原理… 1

与Verified Boot关系… 1

dm-verity. 1

作用分区… 2

二、模块结构… 2

1.签名… 2

生成OEM自己的密钥对… 4

验签… 5
用户空间,android 部分… 5

内核空间… 5

三、如何启用… 5

四、测试… 6

测试样例1. 无法 remount, 无法 push 文件… 6

测试样例2. 6

五、存在风险… 6

物理块出现坏块… 6

六、其他… 6

七、参考文档… 6

一、原理

Verified Boot关系

Verified Boot 是 Android 4.4 开始引入的一个新特性,配合可选的 dm-verify 功能,可以检测系统是否被篡改,以此保存系统的完整性。

dm-verity

dm-verity 基于kernel 的 Device mapper 框架,Device mapper 是 Linux 2.6 内核中提供的一种从逻辑设备到物理设备的映射框架机制,在该机制下,用户可以很方便的根据自己的需要制定实现存储资源的管理策略。关于 Device mapper,可以参考此文献

https://www.ibm.com/developerworks/cn/linux/l-devmapper/

dm-verity 用一个 hash 树来描述整个 system 镜像。这种机制允许 system 分区在读写的时候进行校验,而不是一次性将整个 system 镜像进行校验。当校验 hash 值不一致的时候,返回 IO 错误

框架示意图:

dm-verity-hash-treedm-verity-hash-tree

 作用分区

system

vendor

OEM

其他只读分区

二、模块结构

 1.签名

如何生成用于dm-verity 校验的镜像,可以参考一下主流程:

主流程,Android 官方文档如下:

– Generate an ext4 system image.

– Generate a hash tree for that image.

– Build a dm-verity table for that hash tree.

– Sign that dm-verity table to produce a table signature.

– Bundle the table signature and dm-verity table into verity metadata.

– Concatenate the system image, the verity metadata, and the hash tree.

  • 生成 ext4 格式的 system 镜像
  • 生成 system 镜像的 hash 树
  • 根据 hash 树生成 dm-verity table
  • 对 dm-verity 进行签名,得到签名文件
  • 将签名、dm-verity table 打包到 metadata 镜像
  • 将 verity metadata,hash 树 添加到 system 镜像末尾
  • 生成 ext4 格式的 system 镜像
    build/tools/releasetools/build_image.py  BuildImage 函数 中

通过 prop_dict 属性,判断是否启用 verity 功能,启用的话,调整 system 分区大小,以便后面添加相关文件到 system.img 末尾,然后 RunCommand(build_command) 生成初始的 system.img。

prop_dict 文件路径:

out/target/product/msm8909/obj/PACKAGING/systemimage_intermediates/system_image_info.txt

prop_dict 文件内容:

fs_type=ext4

system_size=1288491008

userdata_size=4831838208

cache_fs_type=ext4

cache_size=268435456

extfs_sparse_flag=-s

selinux_fc=out/target/product/msm8909/root/file_contexts

verity=true

verity_key=build/target/product/security/verity

verity_signer_cmd=out/host/linux-x86/bin/verity_signer

system_verity_block_device=/dev/block/bootdevice/by-name/system

skip_fsck=true

  • 生成 system 镜像的 hash 

BuildVerityTree 函数生成 hash tree (verity_image)

步骤3,4,5BuildVerityMetadata中实现,BuildVerityMetadata 调用build_verity_metadata.py 来实现

BuildVerityMetadata 生成 metadata (metadata_image),

跳转到 system/extras/verity/build_verity_metadata.py

  • 根据 hash 树生成 dm-verity table

build_verity_table 生成 dm-table

dm-table 其实就是一个字符串

  •  dm-verity 进行签名,得到签名文件

sign_verity_table 将 dm-table 签名

signer_key = build/target/product/security/verity.pk8

  • 将签名、dm-verity table 打包到 metadata 镜像

build_metadata_block 将 dm-table 和 签名信息打包,写入 datameta.img

  •  verity metadatahash  添加到 system 镜像末尾

build/tools/releasetools/build_image.py  BuildVerifiedImage 生成最终的可以用于 dm-verity 校验的镜像

Append2Simg 添加 verity_image 和 datameta.img 到 system.img 末尾

其他

FIXED_SALT 可以修改为自己的 salt

如何生成自己的oem key

dm-verity 相关的密钥

build/target/product/security/ build/target/product/verity.mk verity.pk8 – 私钥,用于签名 boot.img 和 system.img

verity.x509.pem – 包含公钥的证书

verity_key – 公钥,dm verity 中用于验签 system 分区

   生成OEM自己的密钥对

  1. HSM(Hardware Security Module)
  1. OpenSSL tool
  • 生成新得密钥对 >openssl version OpenSSL 1.0.2d 9 Jul 2015 >development/tools/make_key mykey ‘/C=US/ST=California/L=Mountain View/O=Android/OU=Android/CN=Android/emailAddress=android@android.com’
  • 为DM-Verity 功能生成 verity key
    1. 使用下面的命令来生成 verity key 的工具 generate_verity_key: source build/envsetup.sh choosecombo make generate_verity_key (mmm system/extras/verity/)
    2. 将 *.x509.pem 转换成 verity key generate_verity_key 的代码位于:system/extra/verity/generate_verity_key.c generate_verity_key 的用法:generate_verity_key | -convert 实例: out/host/linux-x86/bin/generate_verity_key -convert mykey.x509.pem verity_key
  • 拷贝并重命名
    1. 拷贝pk8,mykey.x509.pem,verity_key.pub 至 build/target/product/security/ 目录,将其重命名: verity.pk8, verity.x509.pem,verity_key ,并替换默认的开发 key。
  • 生成 keystore
    1. 执行下面的两个命令,生成img openssl rsa -in mykey.pk8 -inform DER -pubout -outform DER -out mypub.der java -Xmx512M -jar out/host/linux-x86/framework/KeystoreSigner.jar mykey.pk8 mykey.x509.pem keystore.img mypub.der
    2. 通过下面的脚本将img生成oem_keystore.h文件,shell 输入: function generate_oem_keystore_h() { echo \#ifndef __OEM_KEYSTORE_H echo \#define __OEM_KEYSTORE_H xxd -i $1 | sed -e ‘s/unsigned char .* = {/const unsigned char OEM_KEYSTORE[] = {/g’ -e ‘s/unsigned int .* =.*;//g’ echo \#endif }
  • generate_oem_keystore_h keystore.img > oem_keystore.h
  • 将该h文件拷贝到:bootable/bootloader/lk/platform/msm_shared/include
  1. 验签

用户空间,android 部分

相关文件:

system/core/fs_mgr/fs_mgr_verity.c

用户空间对 dm-verity 进行初始化,验签 hash_table 的签名,传入 hash_table 等参数

内核空间

相关文件:

KERNEL_SRC/driver/md/dm-verity.c 相关代码

内核空间根据用户空间传入的参数,进行初始化

当有 IO 操作时,对相应 data block 进行验签。

data block 读取时,不仅当前 data block 需要 hash 校验,上一层的 hash block 也需要进行校验,直到root hash。

每一个 data block 如果已经验签过,再次读取时就不用进行层层的校验,只校验当前 data block 的 hash 是否正确即可。

三、如何启用

  1. kernel 配置文件使能 CONFIG_DM_VERITY

kernel/arch/arm/configs/msm8909-1gb_defconfig

  1. Android 相关 mk 文件配置

device/qcom/msm8909/msm8909.mk PRODUCT_SUPPORTS_VERITY := true PRODUCT_SYSTEM_VERITY_PARTITION := /dev/block/bootdevice/by-name/system

  1. 更新 fstab,system 分区添加 verify 标志

/dev/block/bootdevice/by-name/system /system ext4 ro,barrier=1 wait,verify

  1. 编译 userdebug 或者 user 版本 boot.img 以及 system.img,烧录

四、测试

测试样例1. 无法 remount, 无法 push 文件

Mount | grep system /dev/block/dm-0 /system ext4 ro, seclable, relatime, data=ordered 0 0

adb pull /fstab.qcom c:\temp\fstab, 检查 verify 标志: /dev/block/bootdevice/by-name/system /system ext4 ro,barrier=1 wait, verify

adb remount Use “adb disable-verity” to disable verity. If you do not, remount may succeed, however, you will still not be able to write to these volumes. remount of system failed: Read-only file system remount failed

 测试样例2.

(1).先烧录启用 verity 功能的 boot.img 和 system.img

(2). 然后烧录未启用 verity 功能的 boot.img,重启后 push 一个 apk 到 /system/app/ 目录

(3). 重新烧录启用了 verity 功能的 boot.img,重启后,机器无法开机,kernel log 可以看到 data block xxx is corrupted

五、存在风险

 物理块出现坏块

  1. 开机检验出错,无法开机
  2. 开机检验没问题,读取文件出错,返回 Error IO

六、其他

软件集成和 OTA 升级,必须使用 block 方式生成 OTA 升级包,需要注意适配。

 七、参考文档

Verified Boot

https://source.android.com/security/verifiedboot/index.html

Verifying Boot

https://source.android.com/security/verifiedboot/verified-boot.html

Implementing dm-verity

https://source.android.com/security/verifiedboot/dm-verity.html

Dmverity

https://gitlab.com/cryptsetup/cryptsetup/wikis/DMVerity

dm-table format

https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/Documentation/device-mapper/verity.txt

Device mapper

https://www.ibm.com/developerworks/cn/linux/l-devmapper/

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

android dm-verity 功能 的相关文章

  • BLE 外设支持 Android-L 示例 [关闭]

    Closed 这个问题需要调试细节 help minimal reproducible example 目前不接受答案 我希望有一个适用于 Android L 的 BLE 外设模式的示例 我的代码给了我奇怪的错误 即广告商太多 这没有任何意
  • startActivity overridePendingTransition 只显示进入动画

    基本上 我遇到的问题是只显示输入幻灯片动画 调用 Activity 不会产生动画 startActivity intent overridePendingTransition R anim right in partly R anim le
  • OPENGL ES 不工作:无当前上下文

    我尝试了 OpenGL ES2 for Android 一书中所示的程序 但它不起作用 我已经在Odroid E 三星s3 三星y 三星star上进行了测试 the gl version suported returns 2 but i g
  • Android ListView 自定义适配器 ImageButton

    这可能不是正确的方法 如果有更好的方法请告诉我 我创建了一个自定义适配器类 在我的 getView 方法中我膨胀了我想要使用的视图 public View getView int position View convertView View
  • 如何在 Android 应用程序中单击按钮时打开 Gmail Compose?

    当我的 Android 应用程序中单击按钮时 我尝试打开 Gmail 撰写屏幕 我需要 Google 提供的 API 密钥吗 或者我需要在按钮 onClickListener 中做什么 任何形式的见解都非常值得赞赏 正如 JeffC 指出的
  • 在后台服务中持续获取位置更新

    我正在开发需要在后台服务中持续获取位置更新的应用程序 我已经使用了它正在使用的后台粘性服务 但是 即使我添加了启动广播并在那里启动了服务 启动完成后服务也没有启动 服务启动并立即被杀死 另外 这不适用于奥利奥 服务在应用程序关闭几分钟后停止
  • 在 Android 中始终以横向模式打开相机

    在我的 Android 应用程序中 单击按钮后我希望相机以横向模式打开 即使我将手机旋转为纵向模式 相机也应始终处于横向模式或纵向模式 使用此代码在横向模式下打开相机 Intent cameraIntent new Intent Media
  • 如何使用 Swipe 视图实现 Android TabLayout 设计支持库

    我将使用 android TabLayout 设计支持库 但我不知道如何使用滑动视图 这是我的代码 XML
  • Android:BATTERY_STATUS_DISCHARGING 和 BATTERY_STATUS_NOT_CHARGING 之间的区别

    我想知道这两个标志之间的区别 BatteryManager BATTERY STATUS DISCHARGING And BatteryManager BATTERY STATUS NOT CHARGING 我开发了一个使用这两个标志的应用
  • 有没有办法在多个嵌套的 RecyclerView 之间共享同一个 LayoutManager

    我正在开发一个显示游戏列表的应用程序 在每个游戏的 itemView 内 我还有一个要显示的视频列表 预览和结构如下 我部署了一个RecyclerView作为窗口根视图 然后对于视频 我使用网格样式的RecyclerView来显示 所以这里
  • 在 android 中,第一次单击时按钮侦听器未注册

    因为我是 Android 新手 所以我遇到了按钮监听器的问题 我正在使用 OnClickListener 来处理胸像 但它第一次点击后不执行一旦我单击多个 它就会表现良好 但如何使其在第一次单击时成为可能 这是我的代码 public cla
  • 使用后退按钮启动 Activity

    我正在 Android 中开发一个应用程序 我正在寻找解决方案 有一个活动 例如 A1 通过单击按钮 用户可以转到另一个活动 例如 A2 现在 一旦用户完成 A2 活动 他就会单击后退按钮 返回到上一个活动 A1 这是众所周知的事实 A1此
  • 无法登录 Google Play 游戏服务

    我在开发者控制台上使用包名称和正确的签名证书设置了我的游戏 并为其创建了排行榜 但没有创建任何成就 然后 我从以下位置下载了示例 Type A Number Challenge 和 BaseGameUtils https developer
  • 如何在 kotlin 中检查 lambda 空值

    在 Kotlin 中如何检查 lambda 是否为空 例如 我有这样的签名 onError Throwable gt Unit 我如何区分它的默认值是应用于主体还是应用于此函数的值 您无法测试 lambda 的主体是否为空 因此它不包含源代
  • 从 sqlite 和 mysql 加载数据微调器

    我试试这个tutorial http nielpoenya blogspot com 2012 08 tutorial android spinner dari database html加载Spinner from sqlite and
  • 动态创建 JSON 对象

    我正在尝试使用以下格式创建 JSON 对象 tableID 1 price 53 payment cash quantity 3 products ID 1 quantity 1 ID 3 quantity 2 我知道如何使用 JSONOb
  • 制作弹跳动画

    我想做图层的弹跳动画 我已经完成了该图层从右到中心的操作 现在我想将其向后移动一点 然后回到中心 这会产生反弹效果 我想我可以用这样的翻译来做到这一点
  • Application.onLowMemory() 未调用

    我创建了自己的应用程序类 我尝试调试它 代码在 Application onCreate 处停止 但不会在 onLowMemory 处停止 为了测试该场景 我打开了许多其他高内存应用程序 我看到的是调试会话终止 在 Eclipse 中 并且
  • 查询联系人 - 有时返回空游标

    我正在尝试查询联系人的显示名称 Override public void onActivityResult int requestCode int resultCode Intent data switch requestCode case
  • 如何检查设备上是否安装了文本转语音 (TTS) 的特定语言数据?

    我正在创建一个使用文本转语音的应用程序 我希望用户能够离线使用它 因此我检查设备上是否安装了 TTS 数据 以下是执行此操作的代码 Check tts data is installed Intent checkTTSIntent new

随机推荐

  • pip镜像源大全及配置

    在中国使用pip时 可以配置国内镜像源来提高安装速度和稳定性 以下是一些常见的国内镜像源 阿里云 https mirrors aliyun com pypi simple 清华大学 https pypi tuna tsinghua edu
  • Cpp学习——类与对象3

    目录 一 初始化列表 1 初始化列表的使用 2 初始化列表的特点 3 必须要使用初始化列表的场景 二 单参数构造函数的隐式类型转换 1 内置类型的隐式类型转换 2 自定义类型的隐式类型转换 3 多参数构造函数的隐式类型转换 4 当你不想要发
  • 0343基于STM32单片机的茶园大棚环境土壤湿度光强WiFi监测系统proteus仿真原理图PCB

    功能介绍 0 本系统采用STM32F103RCT6作为单片机 1 采用的LCD1602液晶实时显示当前光强土壤湿度等参数信息 2 当土壤湿度超过设定的阈值 蜂鸣器报警 同时控制水泵工作状态 3 按键可更改环境参数的阈值 4 通过WiFi模块
  • 简单对比一下Cookie和Session的主要区别

    一句话总结 Cookie是检查用户身上的 通行证 来确认用户的身份 Session就是通过检查服务器上的 客户明细表 来确认用户的身份的 Session相当于在服务器中建立了一份 客户明细表 注释 300 20 4kb
  • 记录使用fiddle对夜神模拟器抓包相关设置

    在网上百度很多 试了不少 最后试到这个时 成功实现对模拟器的抓包操作 以此记录 注意 设置完后 不开启 Fiddle 的话 模拟器就不能上网了 可以通过再把网络配置 改回去 就可以恢复网络正常访问了 一 配置Fiddle参数设置 1 Too
  • find命令详解

    前言 find命令是我们日常工作中比较常用的Linux命令 全面的掌握这个命令可以使很多操作达到事半功倍的效果 如果对find命令有以下这些疑惑 本文都能帮你解决 find命令的格式是什么 参数中出现 或 号是什么意思 比如find mti
  • JAVA-WEB项目中,前后台结合AES和RSA对数据加密处理

    实际项目中为了系统安全 我们经常需要对请求数据和响应数据做加密处理 这里以spring后台 vue前台的java web为例 记录一个实现过程 一 为什么要结合AES和RSA 因为AES是对称加密 即加密解密用的秘钥是一样 这样一来AES的
  • SQLyog连接mysql

    mysql 64位客户端下载地址 https pan baidu com s 1bYd1YQ 启动mysql安装 cmd 用户名mysql80 密码 123456 安装SQLyog 官网地址 或者装客户端 名称随意 注册码 ccbfc13e
  • C# ASP.NET 如何判断DropdownList是否为空

    程序运行时 鼠标下拉 DropdownList控件 发现下拉列表为空 参见下图 如何判断 DropdownList控件为空呢 参见下述代码 if DropDownList1 Items Count 0 Response Write retu
  • 【win】引用的账户当前已经锁定,且可能无法登陆

    错误信息 错误原因 原保留的登录账号已失效 解决方法 1 打开控制面板 gt 选择 用户账户 2 选择 管理你的凭据 3 选择 windows凭据 展开10 10 0 2登入项 选择 删除 或 编辑 即编辑为现在可用的账户和密码 5 运行
  • Android Studio 中Gradle Build时报错:请求的操作无法在使用用户映射区域打开的文件上

    今天在运行Android项目 Android Studio 中Gradle Build时报错 请求的操作无法在使用用户映射区域打开的文件上执行 1 问题描述 Error java io FileNotFoundException F And
  • 大模型学习 -- CLIP

    本文是CLIP算法的学习笔记 从CLIP算法介绍到具体实现原理 再到应用方法和后续一些优化策略来学习CLIP系列算法 CLIP是什么 CLIP全称是Contrastive Language Image Pre training 一种基于对比
  • 堆叠查询注入攻击

    堆叠注入原理及介绍 Stacked injections 堆叠注入 从名词的含义就可以看到应该是一堆sql语句 多条 一起执行 而在真实的运用中也是这样的 我们知道在mysql中 主要是命令行中 每一条语句结尾加 表示语句结束 这样我们就想
  • 极速入门体验Qt5软件开发,从安装到打包,少走弯路,Qt入门指南,串口调试助手开发实战

    文章目录 前言 一 成果先行 二 下载安装 1 安装QT 三 项目开发实战 1 创建新项目 2 UI设计 3 编写widget h头文件 4 编写widget cpp源文件 四 编译运行 五 项目打包 1 编译发布版 2 绿色版打包 3 安
  • python 调用matlab的.m文件

    最近在找算法的时候扒到一篇有用matlab写的算法 但我平时用的都是python 所以在网上找了有关python调用matlab m文件的教程 但或多或少都有点问题 经过不断尝试总算成功了 先说下软件版本我用matlab是R2020a py
  • 为多用户安装conda_Conda在中文用户名下运行

    让Conda在中文用户名下运行 本实验仅测试于Windows10系统中 理论上这个方法可以适应任何系统 核心是修改 condarc文件中的参数路径 使其脱离中文 关于如何使用conda anaconda miniconda 可以参照我这个博
  • SSM + Activiti5 简单OA系统

    介绍 本项目是为简单版自动化办公流程 项目内置 出差报销流程 可以作为熟悉了解Activit流程引擎学习项目 软件涉及技术 Spring4 SpringMVC4 MyBatis3 MySQL8 Pagehelper 分页控件 Activit
  • python-pickle模块

    python3 pickle持久化的储存数据 python程序运行中得到了一些字符串 列表 字典等数据 想要长久的保存下来 方便以后使用 而不是简单的放入内存中关机断电就丢失数据 python模块大全中pickle模块就排上用场了 他可以将
  • 最先进的深度学习:Mask R-CNN简介

    介绍 Introduction From my experience as a time traveller I can confidently say that autonomous driving is was will be all
  • android dm-verity 功能

    Android dm verity 实现原理深入研究 思维导图 dm verity 说明 源码基于 SC20 平台 Android5 1 Android dm verify overview 目录 Android dm verify ove