2014-03-02 40 views
3

我在瀏覽蛇實施TrueCrypt加密(7.1A)和一些看起來不正確的!這裏是這個算法的接口:TrueCrypt的錯誤在蛇實施

void serpent_set_key(const unsigned __int8 userKey[], int keylen, unsigned __int8 *ks); 
void serpent_encrypt(const unsigned __int8 *inBlock, unsigned __int8 *outBlock, unsigned __int8 *ks); 
void serpent_decrypt(const unsigned __int8 *inBlock, unsigned __int8 *outBlock, unsigned __int8 *ks); 

這裏感興趣的功能是serpent_set_key。用戶密鑰是在長度爲32個字節,則keylen應該是它的大小和ks是用於加密/解密的輸出密鑰。問題在於實施。這是一開始的有關片段:

unsigned __int32 a,b,c,d,e; 
unsigned __int32 *k = (unsigned __int32 *)ks; 
unsigned __int32 t; 
int i; 

for (i = 0; i < keylen/(int)sizeof(__int32); i++) 
    k[i] = LE32(((unsigned __int32*)userKey)[i]); 

for循環,實際上是從用戶按鍵來執行關鍵複製數據。它是通過將數據視爲4字節整數來完成的。現在,如果關鍵LEN發送作爲字節(32是正確的),但...

在TrueCrypt的全部實現這就是所謂的在兩個地方一切正常。這是第一個: 在CipherInit被稱爲像這樣:

case SERPENT: 
    serpent_set_key (key, CipherGetKeySize(SERPENT) * 8, ks); 
    break; 

CipherGetKeySize(SERPENT)將返回32(字節),所以在參數傳遞將有256的價值!這是正確的,因爲關鍵的長度,但不是這個實現!這將導致'serpent_set_key'中的緩衝區溢出,因爲for循環將運行64次,而不僅僅是8次! 這是所謂的其他地方是在這樣的EAInit:

serpent_set_key(key,32 * 8,ks);

這是很明顯的是,在參數傳遞將是256

我很好奇別人怎麼想這件事?任何人都可以證實這個錯誤嗎?

+0

TL; DR - http://www.truecrypt.org/bugs/ – CBroe

回答

3

由於VeraCrypt主要開發者,因爲VeraCrypt基於TrueCrypt加密源的用戶重定向我到這個職位。

研究你提出這個問題後,我可以證實,這確實是在代碼中的錯誤和調用serpent_set_key要經過32而不是256作爲參數。

幸運的是,這個錯誤對程序執行過程中的正確性或安全性沒有影響,這就是爲什麼沒有人在你面前發現它。因此,我們不能將其視爲錯誤。

讓我在三點解釋:

  1. 讓我們來看看Serpent算法實現的serpent_set_key:參數keylen僅用於複製用戶鑰匙插入ks緩衝區是保證有最小尺寸爲(看crypt.h中定義的SERPENT_KS)。因此,即使keylen是256而不是32,我們也不會超出ks的分配內存。
  2. 這個循環後到來將建立使用膨脹蛇鍵的前32個字節的用戶鑰僅如蛇算法規範內部密鑰擴展。因此,在前32個之後的所有字節將被丟棄,並且它們將不會被使用。這就解釋了爲什麼計算結果是正確的,即使傳遞了256字節而不是預期的32字節。
  3. 如果我們列出所有運行時調用導致serpent_set_key我們會發現,除了自動測試的情況下,所有的呼叫使用,即使它的第32個字節填充USERKEY參數256個字節的緩衝區(看在crypto.h中的MASTER_KEYDATA_SIZE)。因此,在運行時,我們永遠不會讀取分配緩衝區空間之外的內容。它仍然是自動測試(在Tests.c中的ei或在Dlgcode.c中的CipherTestDialogProc),其中32字節的緩衝區用於userKey:這裏我們將讀取超出分配的空間,但實際上它不會造成任何傷害,因爲該緩衝區周圍的內存是可讀的。

我希望這闡明爲什麼這個錯誤是無害的。這就是說,它必須得到糾正,這就是我們在VeraCrypt中要做的。

爲了記錄在案,看來這個錯誤是由twofish_set_keyserpent_set_key之間的混淆造成的:兩個函數的聲明具有相同類型的參數,但twofish_set_key預計用戶密鑰長度位,而serpent_set_key指望它在字節!顯然,我們應該對密鑰的大小有相同的約定。

+0

好的我同意這個問題不會影響程序的正常運行,但它至少是乾淨的算法實現中的一個錯誤! – user3369634

+0

我犯了一個修復的這VeraCrypt(https://sourceforge.net/p/veracrypt/code/ci/86abdb1b12e855d1b92c103446b2cadf9c4e57a3/)。實際上,由於我們只使用固定大小的鍵(256位),所以我除去了解決問題的密鑰長度參數,而且還最小化了對引導加載程序非常重要的代碼大小(我們正在努力使其儘可能小爲了能夠添加新的功能)。 –