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:\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/


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM