環境依存な発見が難しいセキュリティーホールの元なバグ

OFBエンコードデコードのアルゴリズムをついさっきまで組んでいたのだ。
OFBはエンコードおよびデコードのプログラムは同じはずである。
しかしながらデコードすると全く違う値が返ってくるのだ。
これはオカシイ。
OFBの実装の仕方が悪かったのかと考え並々ならぬ時間をかけていろいろと試行錯誤したのだが・・・
どうにもこうにも解決しない・・・。普通は30分から1時間あればテストかけて完全にリリースできる至極簡単なプログラムのはずなのだが・・・。
で、バグはOFB関数内部ではなくOFB関数外部に潜んでいたのだ。
http://d.hatena.ne.jp/studiokingyo/20060407#p3
そう、この前紹介したこの関数の引数のconst T &srcに注目してほしいのだ。
これは絶対に変更されないと保証されている変数なのだ。
しかし、デバッガで追っていくと「とある条件」になるとこの変数が変更されていたのだ。
で、外部のInitial Vector値(srcに入れた変数の元の変数)が変更されてしまいOFBのデコード時に入れるInitial Vector値がまったく見当違いの値になっていたのだ。


さて、その「とある条件」だが、これがまたまたアホなもので・・・


///uint32はWin32環境でのunsigned int型と思ってくれ
uint32 target[32]
encoder.ofb(target,ivec,sizeof(target),cipher);
はい!分かる人! 分かった人はこの記事を読む必要はありません!時間取らせてごめんなさい。
はい!続きを読むリンクをクリックした分からない人!
sizeof(target)は何バイトとですか!?
32です!
おぉ!心の友よ!
んなわけないだろ!
128だっつの!
よって訂正

#define DKUTIL_ARRAY_NUM_OF(s) ( sizeof(s) / sizeof(s[0]) )
encoder.ofb(target,ivec,DKUTIL_ARRAY_NUM_OF(target),cipher);
のようにしないとOFB関数の仕様を満たした値を第三引数に入れる事が出来ないんです。
なので、関数内部でtargetはアクセスバイオレーションをおこしスタックを破壊してInitial Vector値(上記の関数例ではivec)を上書きしてしまうバグを引き起こしてしまったのです。
まぁ、このようにしてセキュリティーホールなるものは空けられるのだなと身をもって経験したのであります。
みなさんも気を付けましょうね。\(-_-;) オイオイ、あなたが一番気をつけなきゃならないんでしょ!