本文件說明 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 位元 nonce
。key
必須
因為 CPRNG 輸出內容可以可靠地預測,因為
學到的知識key
一開始會隨機使用某些位元組進行初始化調整
(請參閱下一節) 且 nonce
已初始化為 0。
呼叫 Draw()
方法時:
nonce
遞增。輸出緩衝區會使用 ChaCha20 演算法,搭配
key
並nonce
。
每個 Draw()
要求都會遞增 nonce
,以確保不同
也就是預測結果呼叫端會提供可就地執行加密的緩衝區。不限
系統會使用緩衝區中的現有資料,因為這些資料不會影響安全性
資源。
如果有 AddEntropy()
要求,key
會透過混合來更新
包含舊金鑰的額外熵:
k<sub>new</sub> = H(e || k<sub>old</sub>)
其中 k<sub>old</sub>
和 k<sub>new</sub>
分別是舊的和新的 key
。
e
分別是輸入位元組,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
核心 cmdline 是常數,只會用於初始種子
會在啟動時傳入,僅限使用一次。硬體和抖動的熵
熵適合用來進行初始播種與轉播。為了確保 CPRNG
足以 (重新) 來自選定的熵來源,您可以使用
核心 cmdline kernel.cprng-(re)seed-require.*
選項。如需更多資訊
請參閱 kernel_cmdline.md。
可能還有其他可用的熵來源,例如可信平台模組 (TPM),但我們目前沒有完善的使用者空間架構 能夠安全地與核心中的 CPRNG 子系統通訊。