2

キーが正しいかどうかを簡単にテストするために、常にスレッドセーフであるか、スレッドセーフな方法で簡単に使用できる (または、できれば最小限の労力で変更できる) cryptsetup の暗号化バックエンドはありますか?

背景と私が試したこと:

まず、cryptsetup のソースを変更して、pthread を使用して複数のキーを簡単にテストできるかどうかをテストしました。これはクラッシュしました。最初は gcrypt を使用していたと思います。最終的に、cryptsetup の安定版ソースで利用可能なすべてのバックエンドを試したところ、openssl と nettle がクラッシュを回避しているように見えることがわかりました。

ただし、私のテストは完全ではなく、(具体的にはイラクサで) クラッシュしませんが、スレッドを使用すると正しく動作しないようです。単一のスレッドを使用する場合は常に機能しますが、スレッドの数を増やすと、暗黙のうちに正しいキーを見つけることができなくなる可能性が高くなります。

これは、LUKS デバイスに対する総当たり攻撃用です。pbkdf がクロールまで遅くなることは承知しています。また、KDF が存在しなくても、AES のキー スペースを使い果たすことはできないことも認識しています。これは、ネットワーク分散およびマルチスレッド方式で作成する楽しみのためだけです。

cryptsetup (libdevmapper.c) のソースで気付きました:

/*
 * libdevmapper is not context friendly, switch context on every DM call.
 * FIXME: this is not safe if called in parallel but neither is DM lib.
 */

ただし、単に正しく使用していない可能性があります。

    if(!LUKS_open_key_with_hdr(CRYPT_ANY_SLOT, key, strlen(key), &cd->u.luks1.hdr, &vk, cd)) {
            return 0;
    }

各ワーカー スレッドがこれを行います。ワーカー スレッドが起動する前に crypt_init() と crypt_load() を 1 回だけ呼び出し、構造体 crypt_device の独自のコピーを渡します。vk は試行ごとにローカルに作成されます。キーは、ミューテックスによるアクセス制御を使用してワードリストから簡単にフェッチされます。各スレッドがこれらの関数 (crypt_init と crypt_load) を毎回呼び出すと、クラッシュしやすくなることがわかりました。

dmcrypt を使用するコードを削除して書き直そうとするのは完全に間違っていますか? LUKS_endec_template() では、ループ デバイスを crypto デバイスに接続し、最終的に open() に与える dm デバイスを作成し、それから read_blockwise() に fd を与えます。私の考えは、キーを確認する以外にデバイスを実際に使用する必要がないため、単純にそのすべてをスキップすることでした。ただし、単純に暗号化デバイスを直接開く (そして read_blockwise() に渡す) だけでは機能しません。

4

0 に答える 0