我會在實習結束時撰寫這封信,記下我未曾到的事情。
正確使用 RdRand
在 x86 上,RdRand
會從確定性 CPRNG 讀取 (從硬體熵來源種種)。
新的 RdSeed
指令會直接讀取基礎熵來源,並進行一些後續處理。目前我們偏好使用 RdSeed
,如果不可用,則會改回使用 RdRand
。然而,我們只是從 RdRand
直接繪製出隨機產生的位元,然後違反 Intel HWRNG 指南 (這裡;請參閱 4.2.5 節「Guaranteeing DBRG Reseeding」)。我們應該可以解決這個問題。
在執行階段期間重新宣告 CPRNG
我的 Hacky virtio 驅動程式庫會在 qemu 上重新播映 CPRNG (每 5 分鐘的週期性計時器)。我認為這是唯一在系統啟動後重新種子的熵來源。
首先,我們應該可以使用核心內建的熵來源 (RdRand 和 Jitterentropy),只要設定規律的計時器,就能改善重新詮釋的故事。請注意,每 5 分鐘查看一次,可能比我們所需的頻率高。
我們說過,如果從 CPRNG 取得大量資料 (應該是 2^48 位元,應該是 2^48 位元),就會更常重生。
監控熵來源
熵來源可能是完全或部分失敗。
「裝置未接上電源」或「裝置沒有回應 I/O」等失敗情形總數希望可由硬體層回報。
發生部分失敗情形時,裝置會傳回資料但熵少於預期的錯誤。我們應執行簡單的健康測試,嘗試偵測局部故障。如需持續健康測試的範例,請參閱 NIST SP800-90B 的第 4.4 節。健康狀態測試非常簡單,也只需要最少的資源。它需要儲存一些有關近期熵來源輸出的統計資料,因此會帶來一些安全性風險。
NIST SP 也建議執行啟動測試 (還需要,但我不知道任何立即進行認證的計畫)。NIST 啟動測試包含至少 4096 個範例 (請參閱第 4.3 節 #12) 的持續測試,之後這些範例可重複使用,以用於傳播 CPRNG。
我們啟用監控功能後,必須決定如何因應熵來源故障。如果其中一個不同的熵來源故障,我們可能會將其視為輕微硬體故障,並記錄到這個情況。如果系統只有一個熵來源,但無法順利執行,我們必須執行更嚴格的操作 (即關閉 CPRNG 或暫停系統)。
使用者空間 RNG 驅動程式
DDK 解決完畢後,我們應加入及改善 RNG 驅動程式。目前有兩個 RNG 相關驅動程式:TPM 和 virtio-rng。
一項重要規定是透過資源或類似機制限制 zx_cprng_add_entropy
系統呼叫的存取權。針對監控目的,我們也應使用此方式區分提供熵的裝置。另外,如果核心可以透過這項資源傳送開始/停止信號給驅動程式,也很好。
以下是一些目前未使用的熵來源:
現有的 TPM 驅動程式庫會在其
bind()
回呼中呼叫cprng_add_entropy
。我們應新增 TPM 2.0 的支援,以提升涵蓋率。市面上有很多硬體 RNG,通常透過 USB 連接。我們可以為這些驅動程式增加驅動程式,但改用第三方驅動程式或許是合理的。
另外,根據 Raspberry Pi 論壇中的結果,RNG 也內建在 Raspberry Pis 的 SoC 中。一般來說,我們可以檢查其他特定目標 (即非「pc-x86-64」) 是否有硬體 RNG,然後再接線。如果幸運成功,其中許多項目都能從核心存取,以便在啟動期間或啟動後立即使用。
最後,我們可以記錄硬體 IRQ 的熵,尤其是硬碟、網路卡、輸入裝置和其他傳統熵來源。這項功能不會像專屬硬體 RNG 一樣快,但很有吸引力,因為在我們的驅動程式庫堆疊的正確位置中加入幾行程式碼,應該就能從各種極為常見的裝置中進行熵收集作業。
抖動現象
組件替換雜訊產生函式,然後移除「-O0」
目前,時基誤差是在最佳化層級 -O0
進行編譯 (按照作者的說明文件)。原因是 jent_lfsr_time
和 jent_memaccess
這兩個雜訊產生函式。我們應以組合程式碼 (可能是使用旗標 -S -O0
編譯) 來取代這些 C 函式,然後編譯其餘的時基誤差並啟用最佳化功能。完成後,我們應重新測試,確保熵預估值維持準確性。
更徹底地測試時基誤差
我們一直在有多部實體裝置進行測試。我們應該另用幾台電腦、角色扮演等方式測試時基誤差。
在執行階段測試時基誤差
目前,基特線只會在啟動序列的單一核心部分中執行 (且經過測試)。我們應在 SMP 執行階段測試時基誤差,並考慮是否需要 (例如) 停用中斷情形,或將其固定到時基誤差內的 CPU。
更多調整
請參閱調整文件。目前的通用硬式編碼參數看起來很差,因此這不是非常緊急。儘管如此,由於抖動現象是每個啟動程序的關鍵路徑,因為它也會在執行階段期間執行 (也許很快就能執行),因此建議您在特定時間點進行最佳化。
我們應該根據每個架構至少調整時基誤差,最好依目標進行微調。請注意,目前 kernel/lib/crypto/entropy/jitterentropy_collector.cpp
中的 entropy_per_1000_bytes
統計資料是以硬式編碼的方式寫入,並未取決於封存/目標。這應該也能進行設定。
複製 NIST 測試套件
我們可能想將 NIST 測試套件複製到 Fuchsia third_party。這樣一來,我們就能自動對熵來源 (尤其是 Jetterentropy) 的測試和分析作業。