zoukankan      html  css  js  c++  java
  • android dm-verity 功能【转】

    转自:https://blog.csdn.net/ee230/article/details/73348344

    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,5在BuildVerityMetadata中实现,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 metadata,hash 树 添加到 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: empfstab, 检查 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/

  • 相关阅读:
    远程下载文件并设置进度显示
    python调用函数超时设置
    Ubuntu安装PostgreSQL
    sessionStatMap is full
    LdapTemplate忽略ssl证书
    MySQL5.6 Online DDL
    Mysql5.7编译调试(windows环境)
    Disruptor
    mybatis generator自定义文件后缀名
    maven占位符$变量无法替换
  • 原文地址:https://www.cnblogs.com/sky-heaven/p/9990503.html
Copyright © 2011-2022 走看看