TrueCrypt 7.1a + Plus を作ってみた。

TrueCrypt の開発が終わった? とかよくわかんないので、
最後のまともバージョン ver 7.1a のソースードをベースに、不満な点を修正してみた。

修正点

不満点1.
パスワードに ASCII 文字列しか利用できない。

不満点2.
パスワードは64文字しか利用できない


とりあえず、LinuxのテキストUIからはこれらが動くようにしてみた。
もちろん、互換性もあるので、今まで作ったボリュームも使える。
(ただし結果は保証しないので、遊び場の砂場で遊んでね。)

なぜ不満なのか?
キーファイルを使えばいいんだろうけど、キーファイルを手元においておかないといけない。
キーファイルをDVDやUSBメディアに入れれば手元ではないかもしれないけど、それでも手持ちのファイルのいづれかと一致すればあたるかもしれない。
それならば、長いパスワードの方がまだ安心できる。

長いパスワードなんて覚えられないのでは?というかもしれないけど、別にすべて覚える必要はない。
例えば、日本国憲法前文の2ブロック目の2文字目以降から、みたいな指定ができる。
ようするに、ポインターみたいなもので、どこにそのパスワードがあったかだけを覚えればいい。

ソースコード的に、64バイトという縛りを変更すると、下位互換とか、いろいろとやばそうだったので、64バイトを超えた部分は、0バイト目からに足し合わせるようにした。

ただ、システム的に、完全な可変長にするのは面倒なので、 4096文字までいけることにした。
TrueCryptは、wchar_t なので、本当の 4096文字までいける。

例
ABURAKATABURA .... 345

64バイトを超えた 345 の部分は、先頭に足しあわされる。 
passwordBuf[i%VolumePassword::MaxSize] += conv.b[lsbPos];

A B U R A K A T A B U R A ....
+ + +
3 4 5

メイン部分のビフォーアフター

void VolumePassword::Set (const wchar_t *password, size_t charCount)
{
	if (charCount > MaxSize)
		throw PasswordTooLong (SRC_POS);

	union Conv
	{
		byte b[sizeof (wchar_t)];
		wchar_t c;
	};

	Conv conv;
	conv.c = L'A';
	
	int lsbPos = -1;
	for (size_t i = 0; i < sizeof (conv.b); ++i)
	{
		if (conv.b[i] == L'A')
		{
			lsbPos = i;
			break;
		}
	}

	if (lsbPos == -1)
		throw ParameterIncorrect (SRC_POS);

	bool unportable = false;
	byte passwordBuf[MaxSize];
	for (size_t i = 0; i < charCount; ++i)
	{
		conv.c = password[i];
		passwordBuf[i] = conv.b[lsbPos];
		for (int j = 0; j < (int) sizeof (wchar_t); ++j)
		{
			if (j != lsbPos && conv.b[j] != 0)
				unportable = true;
		}
	}
	
	Set (passwordBuf, charCount);
	
	if (unportable)
		Unportable = true;
}

↓変更↓

void VolumePassword::Set (const wchar_t *password, size_t charCount)
{
	if (charCount > VolumePassword::TrueMaxSize)
		throw PasswordTooLongByPasswordSize (SRC_POS);

	union Conv
	{
		byte b[sizeof (wchar_t)];
		wchar_t c;
	};

	Conv conv;
	conv.c = L'A';
	
	int lsbPos = -1;
	for (size_t i = 0; i < sizeof (conv.b); ++i)
	{
		if (conv.b[i] == L'A')
		{
			lsbPos = i;
			break;
		}
	}

	if (lsbPos == -1)
		throw ParameterIncorrect (SRC_POS);

	bool unportable = false;
	byte passwordBuf[MaxSize] = {0};
	for (size_t i = 0; i < charCount; ++i)
	{
		conv.c = password[i];
		passwordBuf[i%VolumePassword::MaxSize] += conv.b[lsbPos];
		byte unspoortsum = 0;
		for (int j = 0; j < (int) sizeof (wchar_t); ++j)
		{
			if (j != lsbPos && conv.b[j] != 0)
			{
				unportable = true;
				unspoortsum += conv.b[j];
			}
		}
		passwordBuf[i%VolumePassword::MaxSize] += unspoortsum;
	}

	if (charCount > VolumePassword::MaxSize)
	{
		Set (passwordBuf, VolumePassword::MaxSize);
	}
	else
	{
		Set (passwordBuf, charCount);
	}

	if (unportable)
		Unportable = true;
}

あとは、これに付属する、UI部分とかエラーメッセージとかを修正した。
tar.gz をダウンロードして見てみてね。

ビルド方法

ubuntuで、以下のようにしたらビルドできたよ。

apt-get install gcc g++ libpkcs11-helper1-dev libpkcs11-helper1 nasm fuse-utils libfuse-dev libfuse2 libwxbase2.8-dev libwxbase2.6-dev eekboek-gui

make


enjoy!