2017-07-30 46 views
2

因此,自從Debian維護者臭名昭着地導致RNG種子變得可預測commenting out a usage of uninitialized data以來已經過去了11年。爲什麼在OpenSSL的隨機數生成器中使用未初始化的內存安全?

這個問題在網絡圈子裏引起了很多熱烈的討論,大部分的重點似乎都在批評審查過程或攻擊有問題的開發者。

但是,我一直無法找到任何有關該部門背後的實際思維過程的信息。許多用戶認爲「最壞的情況下,它不會受到傷害」 - 但是,這對我來說似乎完全違反了直覺。

畢竟,從未初始化的內存讀取調用未定義的行爲,臭名昭着的,可能會導致鼻惡魔,運行nethack或格式化您的硬盤驅動器。因此,在我看來,將這種邏輯引入任何程序 - 更let論加密庫 - 讓您從一場徹底的災難中進行一次積極的編譯優化。

因此,我的問題(S):

  • 我誤解的東西嗎?有沒有理由爲什麼這實際上不是調用UB,而是在標準下明確定義的?
  • 如果它實際上調用UB,爲什麼最初包含在OpenSSL中?
+1

我沒有介入,所以把它當作適度充分知情的猜測。理論上的UB(鼻子惡魔是一種可能的後果)和實用的UB(你會得到某種不可預知的結果)。 UB的使用並不是很好,但使用它的實際結果是事情在修復之前比隨機更加隨機。這是一個破損的代碼被「固定」的代碼,代碼更多但破壞程度不同 - 乍看之下第二批代碼也被破壞並不明顯。 –

+0

另請參閱[nasal demons](https://stackoverflow.com/a/45395334/15168)。 –

回答

2

Debian「fix」是completely incorrectssleay_rand_add只有函數將熵添加到池中。真正的罪魁禍首是在調用的網站,它應該在那裏修復 - 因爲功能本身沒有錯。

所以基本上它的情況:

void add_entropy(void *buf, size_t length) { 
    actually_add_entropy(buf, length); 
} 

int main(void) { 
    char buf[256]; 

    // uninitialized local variable 
    add_entropy(buf, length); 

    // calculate more entropy to buf 
    // ... 
    add_entropy(buf, length); 
} 

如果你在看代碼,問題是,參數傳遞在第一次調用的是真正的罪魁禍首,第二種情況是確定的,如buf現在已初始化。正確的解決方法是如下「修理」 add_entropy

void add_entropy(void *buf, size_t length) { 
    // valgrind complains about buf being uninitialized so 
    // actually_add_entropy(buf, length); 
} 

不過,他們在試圖移除未初始化數組是 - UB和USB之外,它可能已經掩蓋了代碼中的嚴重問題 - 它可能很有可能是熵已經從未初始化的數據初始化了只有,因此可能仍然是可猜測或可控的 - 但只有這一次難以注意。

+0

因此緩衝區並不總是未初始化的,只是在一些調用中 - 並且它們停止了將它添加到_all_ invocations中?這就解釋了爲什麼「去除一個熵源」實際上意味着去除(幾乎)所有的熵源。 – Treeston

+0

@特里斯頓。在'ssh-keygen'中只有* initial *值,正在運行的進程的進程ID被用來爲隨機生成器播種。 –

+0

不幸的是,從Crypto Engineering的角度來看,有兩個高層失敗。首先,用戶沒有正確使用庫,因爲他們沒有爲發生器播種。 OpenSSL的wiki現在試圖非常清楚他們應該給發電機發電。其次,圖書館容易使用不當,更難以正確使用。我相信這是通過從OS生成器中提取種子來解決的。發電機仍然像時間和PID一樣混合,但它們不是熵的唯一來源。這些更改使發生器更易於正確使用。 – jww

1

它不是,只是發生(鼻惡魔的一種表現)工作得很好。 Debian刪除了UB是正確的。 OpenSSL是錯誤的,有這樣的破碎的代碼開始。

+0

他們*正確*刪除未初始化的東西,但錯誤地刪除*所有的熵*。 –

相關問題