TrueCrypt (7.1a) で Serpent の実装をブラウズしていたのですが、何かが正しくないようです! このアルゴリズムのインターフェースは次のとおりです。
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 のすべての実装で、これは 2 つの場所で呼び出されます。これが最初のものです: CipherInit では、次のように呼び出されます:
case SERPENT:
serpent_set_key (key, CipherGetKeySize(SERPENT) * 8, ks);
break;
CipherGetKeySize(SERPENT)
32 (バイト) を返すため、渡されたパラメーターの値は 256 になります! キーの長さに関しては正しいのですが、この実装ではそうではありません! for ループが 8 回ではなく 64 回実行されるため、これにより 'serpent_set_key' でバッファ オーバーフローが発生します。これが呼び出される他の場所は、次のように EAInit にあります。
serpent_set_key (キー、32 * 8、ks);
ここで、渡されたパラメーターが 256 になることは明らかです。
他の人がこれについてどう思うか興味がありますか?他の誰かがこのバグを確認できますか?