背景
Fuchsia 從一開始就設計用於支援及擴充強式驗證啟動模式。在大多數採用驗證開機功能的系統中,驗證作業只會涵蓋特定權限層級的程式碼,且在某個時間點,未經驗證的程式碼必須執行。Fuchsia 已將驗證納入系統的執行階段,因此得名為「驗證執行」(簡稱 VX 或 FVX)。FVX 的目標很簡單,就是確保所有可執行的程式碼皆可信。
除非另有指定,否則本文件會使用「可執行程式碼」一詞,指的是直接在硬體上執行的機器碼。可執行的程式碼「不會」參照已置入沙箱、解譯或受限於其他限制機制的程式碼。
範圍
本文說明一般原則和驗證執行階段,適用於使用者建構類型 (除非另有說明)。實作細節和硬體或產品專屬的政策決策不在討論範圍內。本文件著重於核心驗證邏輯,並省略了多層防衛深度。
安全性模型
VX 會考量兩種安全性模型:執行中的軟體模型和已驗證的啟動模型。
+------------------------------------------------------------------------------+
| |
| +---------------------------------------------+--------------------------+ |
| | | | |
| | +------------------+ +--------------------+ | +----------------------+ | |
| | | Recovery from | | Recovery from full | | | Mitigation against | | |
| | | physical attacks | | attacker control | | | vulnerabilities | | |
| | +------------------+ +--------------------+ | +----------------------+ | |
| | Verified boot model | Running software model | | |
| +---------------------------------------------+--------------------------+ |
| |
| Verified execution |
+------------------------------------------------------------------------------+
驗證開機安全性模型
經過驗證的啟動安全性模型有兩個層面:從實體攻擊中復原,以及從攻擊者完全控制的情況中復原。物理攻擊基本上不屬於這份總覽的範疇,但只要說,物理攻擊者比起擁有完整控制權的攻擊者,能做的事會少得多。
完整攻擊者控制 (FAC) 是指攻擊者可在「監控」或「核心」模式下執行所選程式碼的能力 (這裡不考慮更強大的執行模式)。在這個安全性模型中,防禦者的目標是透過消除攻擊者可在重新啟動時持續控制的不可信任狀態 (程式碼和資料) 來復原。
Fuchsia 對已驗證的啟動安全性模型的回應,是讓電腦只要重新啟動,就能從任何遭到入侵的情況中復原。在開機時,Fuchsia 會遞迴驗證執行作業,確保
- 所有執行的程式碼皆可根據「錨點」(例如 ROM 中的程式碼) 判定為可信任的程式碼。
- 所有用於程式碼輸入的資料,都會根據相同的錨點判定是否可信。
有了這個保證,系統就能完全移除不受信任的狀態,即使存在任意不良的安全漏洞也一樣。
防復原
經過驗證的啟動模式假設攻擊者可以將大量儲存裝置內容替換為他們選擇的內容。在這個模型中,如果有任何安全漏洞可在重新啟動後遭到利用,在沒有硬體防回溯機制的情況下,這些漏洞永遠無法修補。如果沒有這類機制,攻擊者可以閃過舊版作業系統的驗證開機檢查,並重播需要重新取得 FAC 的漏洞。硬體防回溯機制會在漏洞修補後拒絕啟動過時的 Fuchsia 版本,完全避免這種情況發生。
執行中軟體模型
在這個模型中,軟體會執行,而攻擊者會嘗試利用軟體中的安全漏洞,取得對執行中軟體的控制權,通常是透過製作惡意輸入內容來攻擊軟體。在這個安全性模型中,防禦者的目標是透過強化程式碼,解決或減輕惡意輸入內容可能造成的安全漏洞。
Fuchsia 對執行中軟體模型的回應,是將執行作業限制在可信任的程式碼上。(稍後會進一步說明「可信任」的定義)。
原則
以下列出指導 Fuchsia 驗證執行作業的一般原則 (不含全部):
您應根據明確的政策驗證程式碼和相關的唯讀資料。每種程式碼、產品或建構類型可能都有不同的政策,但所有程式碼都應繫結至某個政策。政策的簡單範例為「除非程式碼經過信任方數位簽署,否則無法執行」。
- 沒有預設或備用政策。
- 政策不允許一次性側載程式碼 (不允許「雪花」)。
- 政策很少允許及時編譯 (JIT)。
政策驗證和密碼編譯方案的輸入內容應盡可能簡單。
- 政策驗證不應需要剖析不受信任的複雜資料。
經過驗證的執行作業可在各種硬體上實作,但強烈建議使用硬體不可變的憑證錨點和防竄改儲存空間 (例如,儲存只有韌體 (而非核心) 可修改的回溯索引)。
驗證階段
使用雜湊和簽名模式驗證後,程式碼和資料就會視為可信任:資料會以訊息和簽名組合方式載入,並使用可信任的公開金鑰進行驗證。訊息包含較大程式碼或資料 blob 的加密雜湊,這些雜湊會先經過雜湊處理和驗證,再視為可信。
第零階段:硬體到第一個 Bootloader
零階段包括硬體到軟體的轉換作業。經過驗證的執行作業無法抵禦硬體攻擊,因此為了方便說明,本文假設硬體是可信任的。在此階段,不變的程式碼會驗證第一個 Bootloader 是否與不變的信任錨點相符 (例如,一次性可編程 (OTP) 記憶體中的公開金鑰)。詳細資料視硬體而定。
第一階段:將第一個系統啟動載入程式轉換為主要系統啟動載入程式
第一個引導程式已完成驗證後,系統會信任該引導程式,並驗證及執行啟動系統所需的其他軟體。這可能是一連串的軟體映像檔,其中每個映像檔都會驗證並執行下一個映像檔,也可能是樹狀流程。這個階段也與硬體相關。
第二階段:從主要啟動載入程式到預授權程式碼
主要引導程式負責驗證預授權程式碼,也就是指產品主管機關明確核准的所有程式碼,可做為該產品的核心部分執行。預授權程式碼可直接在硬體上執行 (也就是沒有沙箱),並包含 Fuchsia 系統的所有必要元素 (例如 Zircon 核心、套件管理系統、驅動程式)。ZBI
從主要啟動載入程式委派
在啟動載入程式驗證 ZBI 後,有兩個關鍵點會將驗證責任委派出去。
- 經過驗證的 ZBI 會驗證套件管理系統。具體來說,ZBI 會從系統啟動載入程式接收套件管理系統的詳細說明,並強制執行套件管理系統適用的所有政策。
- 驗證完成後,套件管理系統就會負責驗證所有非 ZBI 或套件管理系統的預授權程式碼。
直接驗證與間接驗證
直接驗證會精確描述可執行的軟體 (例如使用套件的加密編譯雜湊),藉此明確指定要信任的項目。間接驗證會指定信任對象,並將內容交由委派的授權單位處理。套件管理系統接手擔任 VX 政策執行工具後,可能會使用間接驗證功能,讓軟體可在執行期間提交,而無須進行完整的系統更新和重新啟動。為了維持信任鏈結,您必須一律直接驗證間接驗證程序 (ZBI、套件管理系統) 中涉及的元件和設定。
請注意,直接驗證的說明可能會非常複雜。如果將簽章附加至包含更多雜湊值的檔案雜湊值,則所有雜湊內容仍會直接驗證。
第三階段:非預授權代碼
如果產品擁有者未授權使用該程式碼或其簽署權限,則該程式碼並未經過驗證,而是受靜態政策規範。部分專用裝置可能完全無法執行未經預授權的程式碼。套用靜態政策是套件管理系統和元件架構的角色。
強烈意圖與弱意圖
具有明確意圖的非預授權程式碼是指,使用者在管理員角色下,明確授權在特定環境中執行的套件程式碼。這類非預授權程式碼可以在與預授權程式碼隔離的環境中,直接在機器上執行。非預先授權的程式碼意圖不明,是指意外載入的程式碼,或是由非管理員角色的使用者授權的程式碼 (例如網頁載入的 JavaScript)。意圖較弱的非預授權程式碼必須經過沙箱處理、解譯,或以其他方式受到嚴格限制機制的約束。
實作
下列 Fuchsia 系統對於強制執行已驗證的政策至關重要。
主系統啟動載入程式
主要的系統啟動載入程式實作功能會依賴 Android 驗證開機程序進行驗證和核心回溯保護。
BlobFS
BlobFS 是一種加密的內容位址指定檔案系統,專門用於支援經過驗證的執行作業。BlobFS 是可執行程式碼和相關唯讀資料的唯一儲存系統 (除了前置核心程式碼、核心和其 bootfs 的 RAM 磁碟,這些都儲存在 ZBI 中)。BlobFS 中的每個 Blob 都會由雜湊 (Merkle 根) 獨特表示及存取,而 Merkle 樹結構則可用於隨機存取 Blob。攻擊者無法在不變更雜湊值的情況下,變更 blob。
在第二階段載入 BlobFS 後,驗證預授權程式碼的方法很簡單,只要檢查每個載入的 Blob 雜湊值的簽章,並確保 Blob 內容與雜湊值相符即可。BlobFS 會執行內容驗證,而簽章檢查則會委派給套件管理系統。
套件管理系統
套件管理系統 (又稱為軟體提交 (SWD) 堆疊) 會在 BlobFS 上方新增一層,讓程式設計師更容易處理 Blob。SWD 堆疊會將描述套件的 Merkle 根 (具體來說,是套件 meta.far 的 Merkle 根) 轉譯為人類可讀的套件名稱。如果任何套件內容有所變更,meta.far 的 Merkle 根目錄也會隨之變更。為求簡潔,本文件會使用「套件雜湊」來指稱套件的 meta.far Merkle 根目錄。
SWD 堆疊會管理名為系統映像檔的特殊套件,其中包含所有基礎套件的雜湊清單。在第二階段載入套件管理系統時,ZBI 會驗證系統映像檔套件,因此所有基礎套件都會直接驗證;也就是說,開機後不需要進行簽章檢查。對於某些專用裝置,可以設定 SWD 堆疊,讓只有具備執行權的基礎套件才能載入記憶體,也就是說,裝置只會執行直接驗證的程式碼。
對於間接驗證的程式碼 (稱為「universe packages」),可信任的公開金鑰和其他中繼資料,會納入經過驗證的啟動簽章涵蓋的位置 (例如 ZBI 或基本套件)。從這類權威機構下載的任何套件,每次載入時都必須透過簽章和內容雜湊值進行驗證 (而非在下載時檢查簽章一次)。直接驗證資料中可能會包含「備用版本」中繼資料,以確保直接和間接驗證的套件都受到硬體防回溯保護機制的保護。
SWD 堆疊也會負責下載系統更新。它具有多項控制項,可防止裝置重新啟動並驗證更新前,任何正在進行更新的 Blob 可供執行中的系統使用。
元件架構
套件是軟體發行的單位,而元件是 Fuchsia 的軟體執行標準單位。這項區別的一個後果是,大多數 Fuchsia 元件不會直接與 SWD 堆疊互動。相反地,SWD 套件解析器的主要客戶是元件架構,其中包含多個元件解析器,可將權限委派給 SWD 堆疊,以便載入程式碼和資料。部分元件解析工具僅限於基本套件,其他工具則可能允許存取 Universe 套件。與其他 Fuchsia 功能一樣,這些解析器會在元件資訊清單中進行路由,可進一步控制其使用方式,並提供可稽核的功能。舉例來說,間接驗證的程式碼可以只限於特定環境。