AVB源码学习(一):AVB2.0工作原理及编译配置
參考資料
感謝前輩的blog,安全相關的資料可太少了,很詳細很卓越
https://blog.csdn.net/jackone12347/article/details/116241676
前言
在這個AVB源碼系列學習之前,還是重新看一下這個AVB到底是什么?AVB是為什么誕生?
1、設備中的系統分區,可以通過fastboot和燒錄工具進行替換掉,替換成功后,可以正常開機,這種能接受么? 2、在設備運行過程中,破壞或者篡改一部分數據,系統能知道被篡改了么? 3、google發布了security patch安全補丁版本,明確告知某個版本有缺陷,OEM廠商仍然使用有缺陷的版本 或者被攻擊者使用了有缺陷的版本,系統能檢查的出來么? 4、boot鏡像的head頭和內容被篡改了,系統能檢查的出來么? 5、uboot被替換,或者system被替換,系統能檢查的出來其中有一個被替換過么?這些問題,可統歸為系統安全相關的問題,從Android O版本開始,google就設計出了AVB,用來解決這些問題。
其實AVB校驗的設計難點,主要是在uboot中的AVB校驗,因為uboot要校驗vbmeta和boot分區要校驗公鑰,以及lock上鎖邏輯、防回滾邏輯、啟動狀態的邏輯,以及這些邏輯的內容存儲在分區中還是RPMB中等等。
(這里不一定是uboot去校驗avb,這是與系統的啟動流程。)
下面開始android AVB2.0(一)工作原理及編譯配置
android AVB2.0(一)工作原理及編譯配置
android AVB2.0介紹,本篇主要介紹AVB2.0的概述和工作原理、配置和編譯。有關AVB2.0的其他子系統的介紹,請查看android AVB2.0學習總結。
AVB2.0概述
什么是AVB?
先看一段google官方的定義: “Verified boot is the process of assuring the end user of the integrity of the software running on a device. It typically starts with a read-only portion of the device firmware which loads code and executes it only after cryptographically verifying that the code is authentic and doesn’t have any known security flaws. AVB is one implementation of verified boot.”AVB是確保終端用戶運行的設備安全的一整套流程。
通常從設備固件的只讀部分啟動,使用加密的方式驗證代碼是真實的,且沒有任何已知的安全缺陷后才執行它。AVB是驗證啟動的一種實現。
AVB是android的一個非常重要的安全功能,主要是防止啟動鏡像被篡改,提高系統整體的抗攻擊的能力,在啟動的過程實現一整套的校驗鏈,確保各個啟動階段是安全啟動的。
AVB在系統啟動的哪些階段工作?
AVB一般在bootloader階段和INIT的第一階段工作。AVB在這兩個階段做了哪些事情?
AVB主要在Bootloader中校驗vbmeta/vbmeta_system/boot/vendor_boot等分區,在init的第一階段校驗vbmeta/system/vendor等分區。AVB工作原理大概是怎樣的?
- 1、在bootloader或者UEFI中對vbmeta分區做校驗,
- 2、通過vbmeta中的descriptor描述符信息,去校驗boot/vendor_boot等分區,同時獲取系統中的device_status(locked or unlocked 即上鎖或者未上鎖)、boot_status(啟動狀態)、vbmeta中的加密的digest/加密算法/vbmeta大小等信息,append到kernel cmdline中;
- 3、然后啟動kernel,kernel加載ramdisk運行init進程,進入init第一階段,進行system/vendor分區的安全校驗,會利用kernel cmdline中的值,跳過boot分區的校驗;同時,因為system/vendor分區比較大,對大分區會執行hashtree的數據處理,將root digest等信息通過ioctl存到kernel中,后面訪問數據時文件系統會執行dm-verity校驗,執行運行時動態安全校驗。
AVB對分區的處理是怎樣的?
知道了其工作原理后,那google是如何設計框架的,對系統分區做了哪些設計呢?
首先,google想到了這樣的設計:通過增加一個獨立的分區,這個分區包括了其他分區的重要校驗信息;只要保證這個vbmeta的足夠安全,那么vbmeta中包含的其他分區的信息也就足夠安全。
其次,這些安全的信息總不能用明文吧,所以得加密。用什么加密方式比較合適呢?google采用了RSA非對稱加密,對鏡像數據做RSA簽名,將來在啟動加載鏡像分區時做公鑰驗證簽名。一級級的保證各個分區的安全性。
好了,有了這些基本內容后,我們接下就介紹vbmeta的設計細節,以及它的設計用意。
AVB細節
一、vbmeta鏡像內容說明:
在整個AVB驗證的過程中,需要借助于vbmeta分區,需要增加vbmeta分區和vbmeta.img鏡像。
vbmeta.img鏡像,編譯出來的大小為4KB
可使用avbtool提供的工具查看編譯出來的vbmeta.img鏡像內容:
./android/external/avb/avbtool info_image --image android/out/target/product/xxx/vbmeta.img The vbmeta image consists of three blocks:| Header data - fixed size 256 bytes rollback index | algorithm_type | signature offset | public_key offset| Authentication data - variable size hash of vbmeta.img | signature of vbmeta.img| Auxiliary data - variable size public key | public key metadata | descriptors of other include imagevbmeta分區描述內容及vbmeta_system.img內容 :
Vbmeta的Descriptor的分類:
Chain Descriptor: 鏈式,vbmeta等分區數據少的分區。 Hash Descriptor:hash哈希,boot等小分區。 Hashtree Descriptor: dm-verity校驗的大分區,像vendor在A/B版本中的vbmeta分區描述:
vbmeta鏡像的加解密過程簡述:
● 加密過程
根據摘要信息生成private key(私鑰),利用私鑰extra生成public key(公鑰),同時利用私鑰對vbmeta鏡像進行簽名(signature),并將公鑰和計算的hash寫到vbmeta鏡像的header中。
● 解密過程
先驗證公鑰是否平臺簽發的(公鑰比對,防止vbmeta鏡像的公鑰和簽名都被篡改掉),然后利用公鑰進行解密簽名。
AVB中鏡像的加密和解密過程,以boot.img鏡像為例
編譯制作boot.img時進行簽名時,先通過SHA-256算法得到一個散列值digest(十六進制長度為64),然后用帶RSA算法的私鑰加密這個digest,并生成簽名后和公鑰一起加在鏡像的footer尾部上,編譯時也會將這個digest存一份到vbmeta.img鏡像中。
在bootloader中加載boot鏡像時,先從vbmeta.img鏡像分區中讀出boot descriptor的digest,然后利用boot鏡像中的公鑰進行解密計算得到一個digest,和自己SHA-256計算得到的digest進行比較;
digest相等則說明boot.img是平臺編譯簽名的,如果不相等,則boot.img可能是被篡改過的,boot啟動失敗。
最后再計算一次boot鏡像內容的hash是否相等,hash不相等,啟動也是失敗。
所以這里也說保護這個vbmeta是很重要的。
私鑰簽名 公鑰驗簽的python腳本舉例說明,這個看起來就更明白些了吧?
私鑰簽名 def rsa_private_sign(data):private_key = get_key('rsa_private_key.pem')signer = PKCS1_signature.new(private_key)digest = SHA.new()digest.update(data.encode("utf8"))sign = signer.sign(digest)signature = base64.b64encode(sign)signature = signature.decode('utf-8')return signature ? ?公鑰驗證簽名 def rsa_public_check_sign(text, sign):publick_key = get_key('rsa_public_key.pem')verifier = PKCS1_signature.new(publick_key)digest = SHA.new()digest.update(text.encode("utf8"))return verifier.verify(digest, base64.b64decode(sign)) ? ?調用 def test_sign():msg = ‘test content'sign = rsa_private_sign(msg)print(rsa_public_check_sign(msg, sign)) # True二、AVB2.0的配置和編譯
AVB2.0的配置,其實看完android/external/avb/README.md中的內容,估計就了解的差不多了,耐著點心看完。
我簡單點歸納一下,主要分下面三個部分來介紹。
- 1、AVB的配置總開關
- 2、AVB key配置介紹
AVB使用的key的路徑和加密算法類型。這個key可自己使用openssl命令生成即可, 唯一需要注意的是使用-f4 4096參數,算法類型保持不變。為什么要用4096而不用2048?這個長度越長,越難被破解,vbmeta的public key驗證時盡量用4096這個長度。
- 3、AVB編譯鏡像
鏡像的編譯主要有vbmeta.img、boot.img、system/vendor.img、recovery.img等。
我們一個個來看。
vbmeta.img鏡像的編譯
vbmeta.img需要配置物理分區大小為64KB,這個是google推薦的,實際上數據只有4KB左右。
因為vbmeta.img里面要保存boot/dtbo/system/vendor等分區的校驗信息,所以編譯時會依賴于這些鏡像的編譯。BOARD_AVB_KEY_PATH可自定義,如果沒有定義則使用avb默認的test測試密鑰。
下面是build/core/Makefile中編譯vbmeta.img部分的腳本,其中BOARD_AVB_ALGORITHM和BOARD_AVB_KEY_PATH就是前面章節提到的需要自定義的算法和KEY路徑了。
ifdef BUILDING_VBMETA_IMAGE INSTALLED_VBMETAIMAGE_TARGET := $(BUILT_VBMETAIMAGE_TARGET) $(INSTALLED_VBMETAIMAGE_TARGET): PRIVATE_AVB_VBMETA_SIGNING_ARGS := \--algorithm $(BOARD_AVB_ALGORITHM) --key $(**BOARD_AVB_KEY_PATH**) #key是私鑰 $(INSTALLED_VBMETAIMAGE_TARGET): \$(AVBTOOL) \$(INSTALLED_BOOTIMAGE_TARGET) \$(INSTALLED_VENDOR_BOOTIMAGE_TARGET) \$(INSTALLED_SYSTEMIMAGE_TARGET) \$(INSTALLED_VENDORIMAGE_TARGET) \$(INSTALLED_PRODUCTIMAGE_TARGET) \$(INSTALLED_SYSTEM_EXTIMAGE_TARGET) \$(INSTALLED_ODMIMAGE_TARGET) \$(INSTALLED_DTBOIMAGE_TARGET) \$(INSTALLED_CUSTOMIMAGES_TARGET) \$(INSTALLED_RECOVERYIMAGE_TARGET) \$(INSTALLED_VBMETA_SYSTEMIMAGE_TARGET) \$(INSTALLED_VBMETA_VENDORIMAGE_TARGET) \$(BOARD_AVB_VBMETA_SYSTEM_KEY_PATH) \$(BOARD_AVB_VBMETA_VENDOR_KEY_PATH) \$(BOARD_AVB_KEY_PATH)$(build-vbmetaimage-target)這個會調用external/avb/avbtool.py腳本的make_vbmeta_image函數,去完成對vbmeta.img鏡像的處理,后面會專門拿一個章節來介紹這些腳本函數。
define build-vbmetaimage-target$(call pretty,"Target vbmeta image: $(INSTALLED_VBMETAIMAGE_TARGET)")$(hide) mkdir -p $(AVB_CHAIN_KEY_DIR)$(call extract-avb-chain-public-keys, $(AVB_CHAIN_KEY_DIR)) #生成公鑰信息$(hide) $(AVBTOOL) make_vbmeta_image \$(INTERNAL_AVB_MAKE_VBMETA_IMAGE_ARGS) \ ##添加chain鏈式分區信息和avbpubkey公鑰信息$(PRIVATE_AVB_VBMETA_SIGNING_ARGS) \ ##添加—algorithm和BOARD_AVB_KEY_PATH,在板卡mk中配置過的$(BOARD_AVB_MAKE_VBMETA_IMAGE_ARGS) \ ##設置padding_size/set_hashtree_disabled_flag/rollback_index等參數--output $@編譯出來的vbmeta.img鏡像,可用info_image命令進行查看。
命令:
boot鏡像的編譯
在boot.img鏡像編譯的時候,會調用add_hash_footer函數,也是調用的avbtool.py腳本的函數,是為了在boot.img鏡像的尾部添加校驗信息,為后面bootloader校驗boot.img安全性做的功能,通過這個尾部的信息來判斷當前啟動的boot.img是否足夠安全。
編譯完成后,可以使用xxd命令查看鏡像中的內容,看一下就大致明白是怎么回事了。
# xxd boot.img | head # xxd boot.img | tailsysmte/vendor鏡像的編譯
system/vendor鏡像處理是類似的,因為這兩個鏡像一般都比較大,不能采用和boot.img鏡像的add_hash_footer,如果在開機的時候對system/vendor整個內容進行hash計算,會比較耗時,所以google設計采用了hashtree的方式,計算整體分區最后只保證root digest hash和salt,只校驗這兩個值速度就比較快了。(而且這個過程好像是在后臺動態運行的,不影響流暢性。)
下面是腳本內容
@build/core/Makefileifeq ($(BOARD_AVB_ENABLE),true)$(BUILT_SYSTEMIMAGE): $(BOARD_AVB_SYSTEM_KEY_PATH)endif$(BUILT_SYSTEMIMAGE): $(FULL_SYSTEMIMAGE_DEPS) $(INSTALLED_FILES_FILE)$(call build-systemimage-target,$@)$(INSTALLED_SYSTEMIMAGE_TARGET): $(BUILT_SYSTEMIMAGE)@echo "Install system fs image: $@"$(copy-file-to-target)$(hide) $(call assert-max-image-size,$@,$(BOARD_SYSTEMIMAGE_PARTITION_SIZE))ifeq ($(BOARD_AVB_ENABLE),true)PATH=$(INTERNAL_USERIMAGES_BINARY_PATHS):$$$$PATH \$(AVBTOOL) add_hashtree_footer \ ###主要是這個函數了--image $(3) \--key $(BOARD_AVB_$(call to-upper,$(2))_KEY_PATH) \--algorithm $(BOARD_AVB_$(call to-upper,$(2))_ALGORITHM) \--partition_size $(BOARD_AVB_$(call to-upper,$(2))_PARTITION_SIZE) \--partition_name $(2) \$(INTERNAL_AVB_CUSTOMIMAGES_SIGNING_ARGS) \$(BOARD_AVB_$(call to-upper,$(2))_ADD_HASHTREE_FOOTER_ARGS)endif至于avbtool腳本如何處理hashtree數據,本篇就不介紹了,請自行看看這個函數。
好了朋友們,關于AVB2.0的工作原理和編譯配置本篇就介紹到這里了。
三、vbmeta和vbemta_system,以及vbmeta_system和system等分區的關系。
vbmeta_system.img
android/build/make/core/board_config.mk BUILDING_SYSTEM_IMAGE := true BUILDING_VBMETA_IMAGE := trueboardxx.mk 配置vbmeta_system.img的簽名需要的內容
BOARD_AVB_VBMETA_SYSTEM := system system_ext product BOARD_AVB_VBMETA_SYSTEM_KEY_PATH := external/avb/test/data/testkey_rsa2048.pem BOARD_AVB_VBMETA_SYSTEM_ALGORITHM := SHA256_RSA2048 BOARD_AVB_VBMETA_SYSTEM_ROLLBACK_INDEX := $(PLATFORM_SECURITY_PATCH_TIMESTAMP) BOARD_AVB_VBMETA_SYSTEM_ROLLBACK_INDEX_LOCATION := 2build/core/Makefile 制作vbmeta_system.img
define build-chained-vbmeta-image$(call pretty,"Target chained vbmeta image: $@")$(hide) $(AVBTOOL) make_vbmeta_image \$(INTERNAL_AVB_$(call to-upper,$(1))_SIGNING_ARGS) \$(BOARD_AVB_MAKE_$(call to-upper,$(1))_IMAGE_ARGS) \$(foreach image,$(BOARD_AVB_$(call to-upper,$(1))), \--include_descriptors_from_image $(call images-for-partitions,$(image))) \ ##遍歷遍歷BOARD_AVB_VBMETA_SYSTEM所有的分區描述符,并保存在vbmeta_system中--output $@ endefifdef BUILDING_SYSTEM_IMAGE ifdef BOARD_AVB_VBMETA_SYSTEM INSTALLED_VBMETA_SYSTEMIMAGE_TARGET := $(PRODUCT_OUT)/vbmeta_system.img $(INSTALLED_VBMETA_SYSTEMIMAGE_TARGET): \$(AVBTOOL) \$(call images-for-partitions,$(BOARD_AVB_VBMETA_SYSTEM)) \ ##遍歷BOARD_AVB_VBMETA_SYSTEM所有的分區鏡像,并將這些鏡像的信息存在vbmeta_system中$(BOARD_AVB_VBMETA_SYSTEM_KEY_PATH)$(call build-chained-vbmeta-image,vbmeta_system) endif endif # BUILDING_SYSTEM_IMAGEvbmeta.img
制作vbmeta.img,這里能看到有添加INSTALLED_VBMETA_SYSTEMIMAGE_TARGET這個vbmeta_system.img進來
這樣vbmeta.img就包含vbmeta_system.img內容了
define build-vbmetaimage-target$(call pretty,"Target vbmeta image: $(INSTALLED_VBMETAIMAGE_TARGET)")$(hide) mkdir -p $(AVB_CHAIN_KEY_DIR)$(call extract-avb-chain-public-keys, $(AVB_CHAIN_KEY_DIR)) ##分離抽取私鑰對應的公鑰出來,公鑰保存在鏡像頭部$(hide) $(AVBTOOL) make_vbmeta_image \$(INTERNAL_AVB_MAKE_VBMETA_IMAGE_ARGS) \$(PRIVATE_AVB_VBMETA_SIGNING_ARGS) \$(BOARD_AVB_MAKE_VBMETA_IMAGE_ARGS) \--output $@$(hide) rm -rf $(AVB_CHAIN_KEY_DIR) endefifdef BUILDING_VBMETA_IMAGE INSTALLED_VBMETAIMAGE_TARGET := $(BUILT_VBMETAIMAGE_TARGET) $(INSTALLED_VBMETAIMAGE_TARGET): PRIVATE_AVB_VBMETA_SIGNING_ARGS := \ ##vbmeta的key路徑和算法類型--algorithm $(BOARD_AVB_ALGORITHM) --key $(BOARD_AVB_KEY_PATH)$(INSTALLED_VBMETAIMAGE_TARGET): \ ...$(INSTALLED_VBMETA_SYSTEMIMAGE_TARGET) \vbmeta_system.img如何將這些分區鏡像的數據進行存儲的
現在我們來分解一下vbmeta_system.img,看下是如何將這些分區鏡像的數據進行存儲的。
執行
vim vbmeta_system.img,然后輸入%!xxd,就可以看到如下內容了:
00000000: 4156 4230 0000 0001 0000 0000 0000 0000 AVB0............ 00000010: 0000 0140 0000 0000 0000 0880 0000 0001 ...@............ 00000020: 0000 0000 0000 0000 0000 0000 0000 0020 ............... 00000030: 0000 0000 0000 0020 0000 0000 0000 0100 ....... ........ 00000040: 0000 0000 0000 0670 0000 0000 0000 0208 .......p........ 00000050: 0000 0000 0000 0878 0000 0000 0000 0000 .......x........ 00000060: 0000 0000 0000 0000 0000 0000 0000 0670 ...............p 00000070: 0000 0000 6156 4f80 0000 0000 0000 0000 ....aVO......... 00000080: 6176 6274 6f6f 6c20 312e 312e 3000 0000 avbtool 1.1.0... 00000090: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 000000a0: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 000000b0: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 000000c0: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 000000d0: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 000000e0: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 000000f0: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 我把這里分割一下,前面256字節內容長度是固定的,用來存儲vbmeta_system.img本身的內容00000100: f471 409a 8786 ca2f 2d22 0f33 732c e431 .q@..../-".3s,.1 00000110: a164 95fb a21b e7dd 646e 8879 5a70 6943 .d......dn.yZpiC 00000120: af4a a9ca 55c2 7050 7201 10ca 8561 eb68 .J..U.pPr....a.h 00000130: 83b9 839b 0a80 42ac ee56 5855 720b f9be ......B..VXUr... 00000140: b37b c224 2292 9f99 a903 9c19 a423 38d0 .{.$"........#8. 00000150: d495 9f22 b7fa b7ee af00 3b46 5680 3130 ..."......;FV.10 00000160: 1d1e 84d3 241b 6366 0121 c7db 60e6 ad0b ....$.cf.!..`... 00000170: 9fa7 adbd 920e 1def 4a9b 5102 e359 2072 ........J.Q..Y r 00000180: dbac f867 42b9 5dd2 a7c5 5398 e6b9 5e3d ...gB.]...S...^= 00000190: 770f ede6 0df0 cb89 31e0 f1ac ad3c 6540 w.......1....<e@ 000001a0: f435 215d f298 d1d4 bbb4 91e9 6bc3 9174 .5!]........k..t 000001b0: 2377 dc5a 27e9 cc97 e5fb eb6f e6e6 9a13 #w.Z'......o.... 000001c0: 3428 c340 6f0a 3a71 788c 76fe 2b4d 9da4 4(.@o.:qx.v.+M.. 000001d0: ee5e 4ac4 7936 478a d9ef 10c6 2ffd 813c .^J.y6G...../..< 000001e0: 90d8 68af 31be 9ca9 0b8e b840 8fb3 877d ..h.1......@...} 000001f0: fcb1 cf2a d092 3c64 af9f 0d14 876a cdbc ...*..<d.....j.. 00000200: db84 c462 b32f cbc1 af4e 2be8 0c1b aa78 ...b./...N+....x 00000210: a359 263e f7a8 e3fe 1efb dcd7 7663 0206 .Y&>........vc.. 00000220: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 00000230: 0000 0000 0000 0000 0000 0000 0000 0000 ................ 00000240: 0000 0000 0000 0000 0000 0000 0000 0088 ................ 說明:到這里是576字節 =256 +320 ,這里存的是Authentication簽名和hash數據了,加密混淆了。 Header Block: 256 bytes Authentication Block: 320 bytes... 00000a30: 5c3b 9436 c18f fec9 d25a 6aa0 46e1 a28b \;.6.....Zj.F... 00000a40: 2f51 6151 a336 9183 b4fb cda9 4034 4698 /QaQ.6......@4F. 00000a50: 8a1a 91df d92c 3abf 573a 4646 20f2 f0bc .....,:.W:FF ... 00000a60: 315e 29fe 5890 325c 6697 999a 8e15 23eb 1^).X.2\f.....#. 00000a70: a947 d363 c618 bb8e d220 9f78 af71 b32e .G.c..... .x.q.. 00000a80: 0889 a1f1 7db1 30a0 e61b bd6e c8f6 33e1 ....}.0....n..3. 00000a90: dab0 bd16 41fe 076f 6e97 8b6a 33d2 d780 ....A..on..j3... 00000aa0: 036a 4de7 0582 281f ef6a a975 7ee1 4ee2 .jM...(..j.u~.N. 00000ab0: 955b 4fe6 dc03 b981 0000 0000 0000 0000 .[O............. 這些數據就是輔助數據了,存的是vbmeta_system包含的system等分區的descriptor信息了 Auxiliary Block: 2176 bytesvbmeta鏡像中包含了vbmeta_system鏡像的信息
分析完了vbmeta_system.img,再回過頭來看vbmeta.img,可以看到vbmeta鏡像中包含了vbmeta_system鏡像的信息。
$ ./external/avb/avbtool.py info_image --image out/xxx/vbmeta.img Minimum libavb version: 1.0 Header Block: 256 bytes Authentication Block: 576 bytes Auxiliary Block: 3136 bytes Public key (sha1): 6fc544ec428a010fa304a398f3a8fe62c1xxxxxx Algorithm: SHA256_RSA4096 Rollback Index: 0 Flags: 0 Release String: 'avbtool 1.1.0' Descriptors:Chain Partition descriptor:Partition Name: vbmeta_systemRollback Index Location: 2Public key (sha1): cdbb77177f731920bbe0a0f94f84d9038axxxxxx ###公鑰的sha1值和前面vbmeta_system Public key (sha1)值是相同的Prop: com.android.build.boot.fingerprint -> xxx:userdebug/test-keys'Prop: com.android.build.boot.os_version -> '11'Hash descriptor:Image Size: 26800128 bytesHash Algorithm: sha256Partition Name: bootSalt: a55c2fa693f09b24bf261f2cae3c0290d37aad3a63a78f7ed673a2d656xxxxxxDigest: f352ae2862e12e85c921394448fc47585a01ec29a77c6d8dea8c6f9e33xxxxxxFlags: 0 ...一般android設備在uboot階段加載校驗vbmeta本身和校驗boot/vendor_boot/dtbo等分區,在android init階段啟動的時候,不再需要校驗vbmeta本身了,但是會加載vbmeta整個分區(此接口libavb靜態庫中有實現),這樣能讀到vbmeta_system的信息。
所以,init啟動AVB校驗的第一個分區是system分區。
代碼處理在first_stage_mount.cpp中的SetUpDmVerity函數
SetUpDmVerity會讀fstab:
會先判斷fstab中是否有avb_keys=/avb/q-gsi.avbpubkey:/avb/r-gsi.avbpubkey:/avb/s-gsi.avbpubkey的flag
然后判斷fstab中是否有avb=vbmeta_system的flag
如果都沒有,則沒有開啟AVB
那么fstab中為什么要添加avb_keys=/avb/q-gsi.avbpubkey公鑰的flag呢?這種設計是要解決什么問題?
system分區的公鑰和簽名信息都在了vbmeta_system中了,為什么還需要在first_stage_ramdisk中保存一份avbpubkey呢?
我們看一下編譯產物:
再回過頭來看一下extract-avb-chain-public-keys的定義,從定義的內容來看,應該是各partition的公鑰了,形式為partition.avbpubkey
define extract-avb-chain-public-keys$(if $(BOARD_AVB_BOOT_KEY_PATH),\$(hide) $(AVBTOOL) extract_public_key --key $(BOARD_AVB_BOOT_KEY_PATH) \--output $(1)/boot.avbpubkey)$(if $(BOARD_AVB_VENDOR_BOOT_KEY_PATH),\$(AVBTOOL) extract_public_key --key $(BOARD_AVB_VENDOR_BOOT_KEY_PATH) \--output $(1)/vendor_boot.avbpubkey)$(if $(BOARD_AVB_SYSTEM_KEY_PATH),\$(hide) $(AVBTOOL) extract_public_key --key $(BOARD_AVB_SYSTEM_KEY_PATH) \--output $(1)/system.avbpubkey)而我們這里是r-gsi.avbpubkey,那r-gsi表示什么?搞過XTS的應該知道是google搞的通用系統鏡像,是需要燒錄對應的system.img的。
所以,在fstab中配置的avb_keys=/avb/xxx.avbpubkey,應該是為了過GSI測試用的,在VTS測試時,會往data分區push google簽名對應的public key。
(這個末尾這點就是說這個小尾巴的內容是為了通過谷歌測試。)
(銷往海外的Android電視,若想使用Google的應用程序和服務,如YouTube、Gmail、Google Play Store等,必須通過此認證,獲得Google授權。通過Google XTS TV認證測試。)
總結
以上是生活随笔為你收集整理的AVB源码学习(一):AVB2.0工作原理及编译配置的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: IIS如何防ASP木马
- 下一篇: storyboard搭建项目_轻松搞定一