加密編譯的安全虛擬隨機號碼產生器

本文件說明 Zircon 的加密編譯虛擬化虛擬設計 隨機號碼產生器 (CPRNG) 包括其演算法、(重新) 播種程序 和熵來源

簡介

Zircon 內建的 CPRNG 可在 不會造成阻斷的趨勢使用者空間程式可透過 zx_cprng_draw() Syscall。

Zircon 的 CPRNG 只信任直接從 因為驅動程式等核心以外的任何內容 屬於使用者空間程式 因此不能信任為了讓 CPRNG 正常運作 必須取得至少其中一個來源,並以安全可靠的方式運作。不過 使用者空間程式可以透過 zx_cprng_add_entropy()敬上 syscall。

演算法

Zircon 的 CPRNG 是一種偽隨機號碼產生器。其實作方式位於 通知時間:zircon/kernel/lib/crypto。支援兩項作業:Draw()AddEntropy(),對應上述兩個 Sys 呼叫。 內部狀態包含 256 位元 key 和 128 位元 noncekey 必須 因為 CPRNG 輸出內容可以可靠地預測,因為 學到的知識key 一開始會隨機使用某些位元組進行初始化調整 (請參閱下一節) 且 nonce 已初始化為 0。

呼叫 Draw() 方法時:

  1. nonce 遞增。

  2. 輸出緩衝區會使用 ChaCha20 演算法,搭配 keynonce

每個 Draw() 要求都會遞增 nonce,以確保不同 也就是預測結果呼叫端會提供可就地執行加密的緩衝區。不限 系統會使用緩衝區中的現有資料,因為這些資料不會影響安全性 資源。

如果有 AddEntropy() 要求,key 會透過混合來更新 包含舊金鑰的額外熵:

k<sub>new</sub> = H(e || k<sub>old</sub>)

其中 k<sub>old</sub>k<sub>new</sub> 分別是舊的和新的 keye 分別是輸入位元組,H 則是 SHA256 雜湊函式,|| 表示串連舊金鑰會包含在雜湊中,以確保 呼叫者,例如呼叫 zx_cprng_add_entropy() 的使用者空間程式無法 請清除舊的 key,並替換為這些程式控制的內容。

播種與轉播

呼叫 AddEntropy() 方法會執行 Zircon 的初始播種 CPRNG.虛擬記憶體 ASLR 需要初始種子,因此第一個呼叫 傳送至 AddEntropy() 方法的最早在啟動序列中 使用者空間必須要有初始種子,CPRNG 才能運作 Draw() 方法會封鎖,直到加入足夠的熵。

在初始種子之後,系統會建立執行緒,以每 30 次重新播完 CPRNG 秒內回應,方法是呼叫 AddEntropy() 方法。以確保正向密碼 (A 保證 CPRNG 自上次重新上線之後,所有先前輸出內容皆安全無虞。 即使內部狀態遭到破壞也一樣)。

熵來源

Zircon 的 CPRNG 可用來進行種子作業, 轉播:

  • 來自核心 cmdline 選項 kernel.entropy-mixin 的熵 (記錄在 kernel_cmdline.md

  • 來自硬體 RNG 的熵,例如 x86 裝置上的 RDSEED 指令 其他硬體專屬 RNG

  • Jitter 熵

核心 cmdline 是常數,只會用於初始種子 會在啟動時傳入,僅限使用一次。硬體和抖動的熵 熵適合用來進行初始播種與轉播。為了確保 CPRNG 足以 (重新) 來自選定的熵來源,您可以使用 核心 cmdline kernel.cprng-(re)seed-require.* 選項。如需更多資訊 請參閱 kernel_cmdline.md

可能還有其他可用的熵來源,例如可信平台模組 (TPM),但我們目前沒有完善的使用者空間架構 能夠安全地與核心中的 CPRNG 子系統通訊。