抖動式圖書館是由 Stephan Mueller 所編寫,可從以下位置取得: https://github.com/smuellerDD/jitterentropy-library,請參考以下連結: http://www.chronox.de/jent.html.在 Zircon 中,編碼器可當成簡單的熵 植入系統 CPRNG
本文件描述並分析 時基誤差:
- 是否使用變數,雜訊中的偽隨機數疊代 產生函式的方式
- 是否對使用抖動器內部人員的原始雜訊樣本進行後置處理 來處理處理常式
我考慮這些基本設定選項 這套程序我會將其與可微調的參數對比 (比如如果不選擇循環播放,就會計為一次循環播放次數) 虛擬記憶體空間,或是用戶端 O2 內部使用的暫存記憶體大小 時基誤差),因為可調整的參數並不會大幅影響 會收集熵收集到的數量與時間 這就需要耗費大量資源與成本
我得到的結論是在本文件的結尾處,但簡單來說,我覺得 因此應該避免選擇偽隨機疊代次數 抖動後處理的資料。
簡要說明抖動作用
如需作者的說明文件,請下載 HTML 表單,網址為: http://www.chronox.de/jent/doc/CPU-Jitter-NPTRNG.html 或 PDF 格式,網址為 http://www.chronox.de/jent/doc/CPU-Jitter-NPTRNG.pdf.簡單來說 會從 CPU 指示時間的變化中隨機收集位元。
Jitterentropy 會維護隨機狀態,格式為 64 位元數字 會受許多 jitterentropy 函數所影響。 輸出隨機性參數
雜訊來源有兩個,分別是執行速度相對緩慢的區塊 測量精確執行階段的程式碼 (使用系統時鐘,需要大約 奈秒解析度)。完成這些程式碼區塊的確切時間 不一定。我們測試這些時間,確保變數難以預測。「我們不能」 確保測試結果 (包括測試結果) ) 是鼓勵的。不過請注意,本文件的目的並非 正因如此 ,討論上述兩種設定選項。
第一個用做雜訊來源的程式碼區塊是耗用大量 CPU 的 LFSR
迴圈
jent_lfsr_time
函式。
LFSR 邏輯重複的次數是由
kernel.jitterentropy.ll
cmdline (「ll
」代表「LFSR 迴圈」)。如果是 ll = 0
,
使用虛擬隨機計數,否則會使用 ll
的值。
查看原始碼時,外部迴圈會根據 ll
重複執行
參數。內部迴圈每 64 步就將 LFSR 推進了 64 步,每次以 XOR 插入時
最新時間樣本中的一個位元。透過
LFSR 則會做為處理步驟,通常會對
隨機時間步。如同
熵品質測試文件
在測試 CPU 作業時間的主體內容時,請略過這個處理程序
變化版本。而啟用處理方法也會導致
有時則有可疑的金額估計值 (請參閱
「處理原始樣本的影響」一節)。
第二個雜訊來源是記憶體存取迴圈
jent_memaccess
函式。
系統會根據 kernel.jitterentropy.ml
重複記憶體存取迴圈
cmdline (「ml
」代表「記憶體迴圈」,值為 0 時則會啟用
偽隨機迴圈計數,任何非零值都會覆寫偽隨機值
數量。每次實際記憶體存取迴圈疊代時,都會讀取和寫入
記憶體區塊相當大,分為 kernel.jitterentropy.bc
個多組
每個大小為 kernel.jitterentropy.bs
個位元組的區塊。
已撰寫目前的文件為 bc = 1024
和 bs = 64
。最新的預設值
應記錄在
cmdline 文件。為了進行比較,
時基誤差原始碼為 bc = 64
和 bs = 32
請參閱這裡的定義。
根據 jent_memaccess
函式上方的註解,記憶體總大小
應大於目標機器的 L1 快取大小。令人困惑
bc = 64
和 bs = 32
會產生 2, 048 位元組的記憶體,
小於甚至大部分的 L1 快取 (我找不到任何大於 0 位元組的 CPU
但小於 4 KB 的 L1)。使用 bs = 64
和 bc = 1024
會產生 64 KB
這通常足以溢位 L1 資料快取
選項 1:Pseudorandom 迴圈計數
抖動法最初的設計是為了讓兩個雜訊產生函式
執行偽隨機次數具體而言
jent_loop_shuffle
函式
結合 (1) 從高解析度時鐘讀取時間以及 (2)
用於決定執行次數
雜訊來源
我們新增了覆寫這些偽隨機迴圈計數的功能 無論是否使用覆寫值,都會提升抖動性的效能。結果如下 「偽隨機循環機制的影響」專區, 總而言之:統計測試結果建議偽隨機循環 數量增加了遠超過預期。這讓我不信任 都會計入更高的熵數,因此建議使用較低的預估值 且偏好具有確定性迴圈計數,而非偽隨機。
Jitterentropy 的隨機資料處理
如上所述,抖動器可以處理其隨機資料 看起來會「隨機排序」的資料具體而言,處理程序會減少 (且 理想情況下移除) 隨機資料的偏差; 並減少 (最好,移除) 隨機位元組之間的任何關聯性。
產生處理樣本的主要功能是
jent_gen_entropy
、
系統就會在迴圈中呼叫
jent_read_entropy
產生任意數量的隨機位元組
基本上,jent_gen_entropy
會呼叫迴圈中的雜訊函式 64 次。
每次叫用 jent_lfsr_time
的 64 次時,都會同時混入雜訊時間測量結果
放入抖動式隨機狀態
經過 64 次疊代後,隨機狀態會選擇性顯示「stirred」英吋
jent_stir_pool
敬上
由 XOR-ing 搭配「mixer」值,本身取決於抖動式隨機
時間。如原始碼中所述,此作業不能增加或減少
泳池裡的熵 (因為 XOR 具有生物識別性) 但有可能可以
隨機狀態的統計外觀
原則上,叫用雜訊來源函式 64 次後,應會產生 64 次
乘以熵,上限為隨機狀態可容納的 64 位元上限。
這會假設 jent_lfsr_time
中的混合作業已經過加密
。我不是加密分析專家,但 LFSR 本身並不是
透過 64 個連續位元揭露完整狀態,因此加密保護 RNG
64 位元 LFSR,之後所有過去和未來的值都能輕易整合
。我不太確定時抖動機制,使用 XOR 的時刻就好
將所有結果整合到「底部」會隨著 LFSR 變更而轉移
安全。在沒有嚴謹的加密檢查的情況下 (
我知道可能存在,但眼中並沒有提到
會盡量使用未處理的樣本,並混合使用
更新為系統熵集區 (如目前採用的 SHA-2)。
也就是說,我確實針對已處理的資料樣本執行 NIST 測試套件。我的 有 個結果位於 「處理原始樣本的影響」專區)) 。
測試程序
如要瞭解執行熵來源品質測試的程序,請參閱 熵品質測試文件。
這些初步結果是在 Raspberry Pi 上的 Zircon 偵錯版本收集而來
3,從修訂版 18358de5e90a012cb1e042efae83f5ea264d1502 建立於現已過時的專案:https://fuchsia.googlesource.com/zircon/+/a1a80a6a7d
「[virtio][entropy] 基本 virtio-rng 驅動程式庫」。下列標記已在
我的 local.mk
檔案 (建構時):
ENABLE_ENTROPY_COLLECTOR_TEST=1
ENTROPY_COLLECTOR_TEST_MAXLEN=1048576
我使用
下列核心 cmdline,改變 $ML
、$LL
和 $RAW
的值:
kernel.entropy-test.src=jitterentropy
kernel.jitterentropy.bs=64
kernel.jitterentropy.bc=1024
kernel.jitterentropy.ml=$ML
kernel.jitterentropy.ll=$LL
kernel.jitterentropy.raw=$RAW
測試結果和分析
偽隨機迴圈的影響
原始資料
依循抖動原始碼中的邏輯 (搜尋
MAX_FOLD_LOOP_BIT
敬上
和
MAX_ACC_LOOP_BIT
)
虛擬迴圈計數在以下範圍內各有不同:
ml: 1 .. 128 (inclusive)
ll: 1 .. 16 (inclusive)
在此附上 NIST 套件的整體最低熵預估值 和兩個產生預估值:壓縮預估值和 馬可夫估價。NIST 最小值為 10 個不同的 包括這兩個項目壓縮估算值通常是 會以決定性迴圈計數的抖動回饋原始樣本的最小量表示,而 馬可夫估計值通常最小為,與其他動物的抖動傳染性 儲存空間設定
ml |
ll |
最小熵 (位元 / 位元組) | 壓縮估算值 | 馬可夫估價 |
---|---|---|---|---|
隨機 (1 .. 128) | 隨機 (1 .. 16) | 5.77 | 6.84 | 5.77 |
128 | 16 | 1.62 | 1.62 | 3.60 |
1 | 1 | 0.20 | 0.20 | 0.84 |
換句話說,改變迴圈計數時,會無意識地提高最低熵 原始樣本的 4.15 位元 (即 250%) 的預估結果,與確定性 一律使用偽隨機範圍中的最大值的版本。
分析
偽隨機循環計數值是由多一個額外時間決定 每個雜訊函式的範例首先,這些時間樣本與 雜訊函式時間測量,因為循環計數與間隔時間之間的落差 這些樣本與雜訊函式時間測量結果相對可預測。身為 所以很難以判斷 輸出資料的最小熵。其次,如果能想到 循環次數樣本與雜訊函式相同,約有 250% 時間測量,因為這兩者都仰賴相同的雜訊來源,但 第一個迴圈計數的時間樣本,可能會從 系統啟動系統所需的執行時間。
因此,我懷疑這起因是偽隨機迴圈計數 足以成為「笨蛋」也就是特定的統計測試套件 以預測器為基礎的 NIST 套件,但以 有關如何衍生出抖動偽迴圈計數的特定知識 甚至可以更準確地預測輸出內容我認為 偽隨機迴圈計數測試中的最小熵,對對 特別針對程式碼,在 測試,即每位元組約 0.20 到 1.62 位元。
憑藉偽隨機數的手法迫使我們做出其他決定:
保守地估計實際的熵內容,單位為每位元組 0.20 位元
偽隨機計數函式一律選擇 ml = 1
和 ll = 1
)?或是
挑選一般熵內容 (可能擁有較聰明的)
比計算 (1.62 + 0.20) / 2 = 0.91 位元 / 位元組
為本討論目的提供) 使用,並可能導致虛擬迴圈計數不足
偶爾會讓我們忽略平均熵內容如果是
過於保守,我們會花更多時間收集熵;如果
但太樂觀來看,可能出現了安全漏洞最後,這個
強制在安全性之間做出取捨 (偏好保守的熵)
估算) 和效率 (偏好以樂觀的熵估算)。
處理原始樣本的影響
原始資料
我重複了上述的三項測試,但測試者在內部使用抖動器的內部
套用設定 (使用 kernel.jitterentropy.raw = false
,而不是
預設值為 true
)。為了方便起見,下表包含 原始
最後的三列範例結果 (從上方複製),然後處理
結果 (新增) 會顯示在底部的三列。
ml |
ll |
原始 | 最小熵 (位元 / 位元組) | 壓縮估算值 | 馬可夫估價 |
---|---|---|---|---|---|
隨機 (1 .. 128) | 隨機 (1 .. 16) | true | 5.77 | 6.84 | 5.77 |
128 | 16 | true | 1.62 | 1.62 | 3.60 |
1 | 1 | true | 0.20 | 0.20 | 0.84 |
ml |
ll |
原始 | 最小熵 (位元 / 位元組) | 壓縮估算值 | 馬可夫估價 |
---|---|---|---|---|---|
隨機 (1 .. 128) | 隨機 (1 .. 16) | false | 5.79 美元 | 6.59 | 5.79 美元 |
128 | 16 | false | 5.78 | 6.97 美元 | 5.78 |
1 | 1 | false | 5.77 | 6.71 | 5.77 |
分析
後續處理的最低熵估計值幾乎等於 稍有變化,容易因隨機性而解釋 針對含虛擬迴圈計數的原始樣本進行最低熵估算。
回想一下,抖動器處理的熵由 64 個獨立隨機產生
資料樣本,混合在 64 位元內部狀態緩衝區中。每個原始
樣本與 raw = true
資料表中的一個範例相對應。尤其是
也就是說,結合 64 樣本與 ml = 1
和 ll = 1
之後,
處理時會產生 (5.77 * 8) = 每 8 個位元組的 46.2 位元熵
處理的輸出內容,意即 (46.2 / 64) = 每秒 0.72 位元的熵
而不是測量到 0.20 位元的樣本值。
此引數適用於 ml = 1
、ll = 1
、raw = false
測量、
但「不適用於」ml = 128
、ll = 16
和 raw = false
。我們要用
結合 64 個原始樣本與 ml = 128
和 ll = 16
的原則
collection (1.64 * 64 / 8) = 13.1 位元的熵,每個處理的位元組除外
當然,每位元組 8 位元有硬性限制
有趣的是,最小的熵估算器會從壓縮資料中切換 馬可夫估算器的值理論上,額外「混淆」是 後續處理就足以達到「fool」壓縮率百分比如果有 抖動處理程式中的加密編譯漏洞 然後編寫類似的 估算器,以大幅縮小 極低熵。如果我們使用一般用途測試來決定原始樣本數量 收集到 256 次最低熵,但對手使用目標性 然後 (相對於此目標性攻擊),我們的系統擁有較少的熵 擁有超乎預期的熵池這是安全漏洞。
若是基特熵處理流程中有非常糟糕的弱點,
事實上,降低「真實性」都會有「抖動現象」內部集區。
ml = 1
和 ll = 1
的算數引數顯示我們無法信任
以準確地測量
因此處理過程中
但我們的工具也無法偵測到損失。這會使得
安全漏洞。
結論
抖動實驗室的偽隨機循環計數是最大的好處 或是迫使我們犧牲安全/效益,除非我們能 顯示有說服力的證據指出偽隨機時間確實發生劇烈 提高熵預估值,而不僅是擊敗 NIST 測試套件, 採用確定性迴圈,最理想的方式是調整 或每個目標採購的費用。
據我所知,Jtterentropy 處理相關處理程序同樣問題 沒有經過足夠的加密編譯分析和測試 。此外,我們無法直接測量 透過 NIST 測試套件處理後的資料, 我們難以輕易偵測到的安全漏洞我認為我們應該改為 Zircon CPRNG 中的熵混合程式碼 (以 SHA-2 為基礎),然後退出 抖動器的處理功能已停用。
TODOs
- 針對不同的 Zircon 版本重複上述回報的測試。 確保熵估計值保持一致。
- 在不同平台和指定目標上重複測試 (注意:x86 目標不含 目前可以在早期啟動階段使用系統時鐘,所以在早期啟動階段 熵測試和早期啟動 CPRNG 種子目前不支援時抖動 x86)。
自動執行測試程序,並產生此頁面中的報表 文件。具體而言,這些測試應比較下列項目:
- 偽隨機迴圈計數與各種確定性迴圈計數值
- 原始樣本與已處理的資料