驗證啟動需要在使用之前對屬於正在啟動的 Android 版本一部分的所有可執行程式碼和資料進行加密驗證。這包括核心(從boot
分區載入)、設備樹(從dtbo
分區載入)、 system
分區、 vendor
分區等。
只讀一次的小分區(例如boot
和dtbo
)通常透過將整個內容載入到記憶體中然後計算其哈希來進行驗證。然後將計算出的雜湊值與預期雜湊值進行比較。如果該值不匹配,Android 將不會載入。有關更多詳細信息,請參閱引導流程。
無法裝入記憶體的較大分區(例如檔案系統)可能會使用哈希樹,其中驗證是資料載入到記憶體時發生的連續過程。在這種情況下,哈希樹的根哈希是在運行時計算的,並根據預期的根哈希值進行檢查。 Android 包含dm-verity 驅動程式來驗證較大的分割區。如果在某個時刻計算出的根雜湊值與預期的根雜湊值不匹配,則不會使用該資料並且 Android 會進入錯誤狀態。有關更多詳細信息,請參閱dm-verity 損壞。
預期的雜湊值通常儲存在每個已驗證分區的末尾或開頭、專用分區或兩者中。至關重要的是,這些雜湊值由信任根簽署(直接或間接)。例如,AVB 實作支援這兩種方法,有關詳細信息,請參閱Android 驗證啟動。
復原保護
即使使用完全安全的更新過程,非持久性 Android 核心漏洞也可能手動安裝較舊、更易受攻擊的 Android 版本,重新啟動到易受攻擊的版本,然後使用該 Android 版本安裝持久性漏洞。從那裡,攻擊者永久擁有該設備並可執行任何操作,包括停用更新。
針對此類攻擊的保護稱為回滾保護。回滾保護通常透過使用防篡改儲存記錄 Android 的最新版本來實現,如果 Android 版本低於記錄的版本,則拒絕啟動 Android。通常基於每個分區來追蹤版本。
有關 AVB 如何處理回滾保護的更多詳細信息,請參閱 AVB README 。
處理驗證錯誤
驗證可能會在啟動時(例如,如果boot
分區上計算的哈希值與預期哈希值不匹配)或在運行時(例如,如果 dm-verity 在system
分區上遇到驗證錯誤)失敗。如果在啟動時驗證失敗,設備將無法啟動,最終用戶需要執行步驟來恢復設備。
如果驗證在運行時失敗,流程會稍微複雜一些。如果設備使用 dm-verity,則應配置為restart
模式。在restart
模式下,如果遇到驗證錯誤,裝置會立即重新啟動,並設定特定標誌以指示原因。引導程式應注意到此標誌並將 dm-verity 切換為使用 I/O 錯誤 ( eio
) 模式,並保持在此模式,直到安裝新的更新。
在eio
模式下啟動時,裝置會顯示錯誤螢幕,通知使用者已偵測到損壞,且裝置可能無法正常運作。該畫面會一直顯示,直到使用者將其關閉為止。在eio
模式下,如果遇到驗證錯誤,dm-verity 驅動程式不會重新啟動設備,而是傳回 EIO 錯誤,應用程式需要處理該錯誤。
其目的是要么系統更新程式將運行(因此可以安裝沒有損壞錯誤的新作業系統),要么用戶可以從設備上獲取盡可能多的資料。安裝新作業系統後,引導程式會注意到新安裝的作業系統並切換回restart
模式。