已驗證執行作業

背景

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 會遞迴驗證執行作業,確保

  1. 所有執行的程式碼都必須根據「錨點」(例如 ROM 中的程式碼) 可信賴,且
  2. 所有用於程式碼輸入的資料,都會根據相同的錨點判定是否可信。

這項保證可讓系統完全移除不受信任的狀態,即使存在任意不良的安全漏洞也不例外。

防復原

驗證開機程序模型會假設攻擊者可將大量儲存空間內容替換成所選內容。在這個模型中,如果有任何安全漏洞可在重新啟動後遭到利用,在沒有硬體防回溯機制的情況下,這些漏洞永遠無法修補。如果沒有這類機制,攻擊者可以閃過舊版作業系統的驗證開機檢查,並重播需要重新取得 FAC 的漏洞。硬體防回溯機制會在漏洞修補後拒絕啟動過時的 Fuchsia 版本,完全避免這種情況發生。

執行中軟體模型

在此模型中,軟體執行作業和攻擊者會嘗試利用軟體中的安全漏洞,藉此控管執行中的軟體,通常是透過精心打造對軟體的惡意輸入內容。在這個安全性模型中,防禦者的目標是透過強化程式碼,以防範惡意輸入內容,解決或減輕潛在的安全漏洞。

Fuchsia 對執行中的軟體模型的回應,是將執行作業限制在可信任的程式碼上。(稍後會進一步說明「可信任」的定義)。

原則

以下列出指導 Fuchsia 驗證執行作業的一般原則 (不含全部):

  • 您應根據明確的政策驗證程式碼和相關的唯讀資料。每種程式碼、產品或建構類型可能都有不同的政策,但所有程式碼都應繫結至某個政策。政策就是一個簡單的例子:「程式碼必須經由信任的方數位簽署,才能執行。」

    • 沒有預設或備用政策。
    • 政策不允許一次性側載程式碼 (不允許「雪花」)。
    • 政策很少允許及時編譯 (JIT)。
  • 政策驗證和密碼編譯方案的輸入內容應盡可能簡單。

    • 政策驗證不應需要剖析不受信任的複雜資料。
  • 經過驗證的執行作業可在各種硬體上實作,但強烈建議使用硬體不可變信任錨點和防竄改儲存空間 (例如,儲存只能由韌體 (而非核心) 修改的回溯索引)。

驗證階段

使用雜湊和簽名模式驗證後,程式碼和資料就會視為可信任:資料會以訊息和簽名組合形式載入,並使用可信任的公開金鑰進行驗證。訊息包含較大程式碼或資料 blob 的加密雜湊,這些雜湊會先經過雜湊處理和驗證,再視為可信。

第零階段:硬體到第一個引導程式

零階段包括硬體到軟體的轉換作業。經過驗證的執行作業無法抵禦硬體攻擊,因此為了方便說明,本文假設硬體是可信任的。在此階段,不可變更的程式碼會根據不可變更的信任錨點驗證第一個系統啟動載入程式,例如一次性程式化 (OTP) 記憶體中的公開金鑰。詳細資料會因硬體而異。

階段一:從 系統啟動載入程式到主要系統啟動載入程式

第一個引導程式已完成驗證後,系統會信任該引導程式,並驗證及執行啟動系統所需的其他軟體。這可能是一連串的軟體映像檔,其中每個映像檔都會驗證並執行下一個映像檔,也可能是樹狀流程。這個階段也因硬體而異。

第二階段:從主要系統啟動載入程式到預先授權程式碼

主要引導程序負責驗證預授權程式碼,也就是指產品主管機關明確核准的所有程式碼,可做為該產品的核心部分執行。預授權程式碼可直接在硬體上執行 (也就是沒有沙箱),並包含 Fuchsia 系統的所有必要元素 (例如 Zircon 核心、套件管理系統、驅動程式)。系統啟動載入程式驗證可能會依產品而異,但通常會使用 Android 驗證開機程序 (AVB) 版本來驗證 Zircon 開機映像檔。

從主要啟動載入程式委派

在啟動載入程式驗證 ZBI 後,有兩個關鍵點會將驗證責任委派出去。

  1. 經驗證的 ZBI 會驗證套件管理系統。具體來說,ZBI 會從系統啟動載入程式接收套件管理系統的詳細說明,並強制執行套用至該系統的所有政策。
  2. 驗證完畢後,套件管理系統會負責驗證所有不屬於 ZBI 或套件管理系統的剩餘預授權程式碼。

直接驗證與間接驗證

直接驗證會精確描述允許執行的軟體 (例如使用套件的加密編譯雜湊),明確指定「值得信任的」。間接驗證會指定信任對象,並將「內容」留給委派的授權。套件管理系統接手擔任 VX 政策執行工具後,可能會使用間接驗證功能,讓軟體能夠即時提交,而無須進行完整的系統更新和重新啟動。為了維護信任鏈,與間接驗證程序 (ZBI、套件管理系統) 相關的元件和設定一律必須直接驗證。

請注意,直接驗證的說明內容可能會大致上很複雜。如果將簽章附加至包含更多雜湊值的檔案雜湊值,則所有雜湊內容仍會直接驗證。

第 3 階段:未經預先授權的程式碼

如果產品擁有者未授權使用該程式碼或其簽署權限,則該程式碼並未經過驗證,而是受靜態政策規範。部分專用裝置可能完全無法執行未經預授權的程式碼。套用靜態政策是套件管理系統和元件架構的角色。

強烈意圖與弱意圖

具有明確意圖的非預授權程式碼是指套件中的程式碼,該程式碼已由以管理員身分執行的使用者明確授權,可在特定環境中執行。這類非預授權程式碼可以在與預授權程式碼隔離的環境中,直接在機器上執行。非預先授權的程式碼意圖不明,是指意外載入的程式碼,或是由非管理員角色的使用者授權的程式碼 (例如網頁載入的 JavaScript)。如果未經預先授權且意圖不足,必須對這類程式碼執行沙箱機制、解譯,或是受到嚴格的限制機制規範。

實作

下列 Fuchsia 系統對於強制執行已驗證的政策至關重要。

主系統啟動載入程式

主要的系統啟動載入程式實作項目會依賴 Android 驗證開機程序進行驗證及核心回溯保護。

BlobFS

BlobFS 是加密編譯且已處理內容的檔案系統,專為支援經過驗證的執行作業而建構。BlobFS 是可執行程式碼和相關唯讀資料的唯一儲存系統 (除了前置核心程式碼、核心和其 bootfs 的 RAM 磁碟,這些都儲存在 ZBI 中)。BlobFS 中的每個 blob 都是以雜湊 (Merkle root) 呈現和存取,而 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 或基本套件)。從這類權威機構下載的任何套件,每次載入時都必須透過簽章和內容雜湊值進行驗證 (而非在下載時檢查簽章一次)。「Backstop version」中繼資料可能會包含在直接驗證的資料中,確保直接和間接驗證的套件皆受到硬體防復原防護機制的保障。

SWD 堆疊也會負責下載系統更新。它具有多項控制項,可防止裝置重新啟動並驗證更新前,任何正在進行更新的 Blob 可供執行中的系統使用。

元件架構

套件是軟體發行的單位,而元件是 Fuchsia 的軟體執行標準單位。這項區別的一個後果是,大多數 Fuchsia 元件不會直接與 SWD 堆疊互動。相反地,SWD 套件解析器的主要客戶是元件架構,其中包含多個元件解析器,可將權限委派給 SWD 堆疊,以便載入程式碼和資料。有些元件解析器受限於基礎套件,有些可能會允許存取宇宙套件。如同其他 Fuchsia 功能,這些解析器會轉送到元件資訊清單,以便進一步控管其使用方式。舉例來說,間接驗證的程式碼可能只限於特定環境