mcryptで不正な長さのIVや鍵を渡した場合について
yandodさんのトコから。
理由については既にshimookaさんが調べているようなので、別の観点から。
「-3」が返却される条件を見てみます(libmcrypt本体を確認)。
% grep -rn mcrypt_generic_init /usr/local/src/libmcrypt-2.5.8 /usr/local/src/libmcrypt-2.5.8/ChangeLog:1221: mcrypt_generic_init() no longer fails if smaller key sizes are used. /usr/local/src/libmcrypt-2.5.8/NEWS:111:- mcrypt_generic_init() no longer fails if smaller key is used. It uses /usr/local/src/libmcrypt-2.5.8/src/aes_test.c:81: if (mcrypt_generic_init( td, key, 16, IV) < 0) { /usr/local/src/libmcrypt-2.5.8/src/aes_test.c:114: if (mcrypt_generic_init( td, key, 16, IV) < 0) { /usr/local/src/libmcrypt-2.5.8/src/aes_test.c:161: if (mcrypt_generic_init( td, key, 16, IV) < 0) { /usr/local/src/libmcrypt-2.5.8/src/aes_test.c:203: if (mcrypt_generic_init( td, key, 16, IV) < 0) { /usr/local/src/libmcrypt-2.5.8/src/cipher_test.c:82: if (mcrypt_generic_init( td, key, keysize, IV) < 0) { /usr/local/src/libmcrypt-2.5.8/src/cipher_test.c:98: if (mcrypt_generic_init( td2, key, keysize, IV) < 0) { /usr/local/src/libmcrypt-2.5.8/include/mutils/mcrypt.h.in:50: int mcrypt_generic_init(const MCRYPT td, void *key, int lenofkey, /usr/local/src/libmcrypt-2.5.8/include/mutils/mcrypt.h:50: int mcrypt_generic_init(const MCRYPT td, void *key, int lenofkey, /usr/local/src/libmcrypt-2.5.8/lib/mcrypt.c:155:int mcrypt_generic_init(const MCRYPT td, const void *key, int lenofkey, const void *IV) /usr/local/src/libmcrypt-2.5.8/lib/libmcrypt.sym:4:mcrypt_generic_init /usr/local/src/libmcrypt-2.5.8/doc/mcrypt.3:281:.B int mcrypt_generic_init( MCRYPT td, void *key, /usr/local/src/libmcrypt-2.5.8/doc/mcrypt.3:303:returned by mcrypt_generic_init(). Plaintext is the plaintext you /usr/local/src/libmcrypt-2.5.8/doc/mcrypt.3:490:The err should be a value returned by mcrypt_generic_init(). /usr/local/src/libmcrypt-2.5.8/doc/mcrypt.3:495:The err should be a value returned by mcrypt_generic_init(). /usr/local/src/libmcrypt-2.5.8/doc/mcrypt.3:550: i=mcrypt_generic_init( td, key, keysize, IV); /usr/local/src/libmcrypt-2.5.8/doc/mcrypt.3:613: mcrypt_generic_init( td, key, keysize, IV); /usr/local/src/libmcrypt-2.5.8/doc/example.c:41: i=mcrypt_generic_init( td, key, keysize, IV); /usr/local/src/libmcrypt-2.5.8/doc/example.c:104: mcrypt_generic_init ( td key, keysize, IV); % less -N /usr/local/src/libmcrypt-2.5.8/lib/mcrypt.c 〜 省略 〜 55 static int internal_init_mcrypt(MCRYPT td, const void *key, int lenofkey, const void *IV) 56 { 57 int *sizes = NULL; 58 int num_of_sizes, i, ok = 0; 59 int key_size = mcrypt_enc_get_key_size(td); 60 61 if (lenofkey > key_size || lenofkey==0) { 62 return MCRYPT_KEY_LEN_ERROR; /* error */ 63 } 〜 省略 〜 155 int mcrypt_generic_init(const MCRYPT td, const void *key, int lenofkey, const void *IV) 156 { 157 return internal_init_mcrypt(td, key, lenofkey, IV); 158 } 〜 省略 〜 % grep -rn MCRYPT_KEY_LEN_ERROR /usr/local/src/libmcrypt-2.5.8 /usr/local/src/libmcrypt-2.5.8/lib/mcrypt.c:62: return MCRYPT_KEY_LEN_ERROR; /* error */ /usr/local/src/libmcrypt-2.5.8/lib/mcrypt.c:209: case MCRYPT_KEY_LEN_ERROR: /usr/local/src/libmcrypt-2.5.8/lib/mcrypt.c:237: case MCRYPT_KEY_LEN_ERROR: /usr/local/src/libmcrypt-2.5.8/lib/mcrypt_internal.h:81:#define MCRYPT_KEY_LEN_ERROR -3
なる程。
指定したキー長がゼロの場合かモジュールが想定する最大キー長よりも大きい場合に「-3」が返却されます。最大キー長よりも小さい場合は有効とみなされる、と。
じゃあ、こういう事ね。
% less -N /usr/local/src/mcrypt.php 1 <?php 2 3 $td = mcrypt_module_open( 'rijndael-256', '', 'ofb', '' ); 4 $iv = mcrypt_create_iv( mcrypt_enc_get_iv_size( $td ), MCRYPT_DEV_RANDOM ); 5 $ks = mcrypt_enc_get_key_size( $td ); 6 7 $key = ""; // キー長をゼロに 8 $iv = "111"; 9 10 var_dump( mcrypt_generic_init( $td, $key, $iv ) ); 11 12 ?> % php /usr/local/src/mcrypt.php Warning: mcrypt_generic_init(): Key size is 0 in /usr/local/src/php-5.2.3/ext/mcrypt/m.php on line 10 Warning: mcrypt_generic_init(): Iv size incorrect; supplied length: 3, needed: 32 in /usr/local/src/php-5.2.3/ext/mcrypt/m.php on line 10 Warning: mcrypt_generic_init(): Key length incorrect in /usr/local/src/php-5.2.3/ext/mcrypt/m.php on line 10 int(-3)
どうでもいい事、失礼しました。
libmcrypt本体ではキー長を超えるサイズを渡した場合はエラーとしているのに対して、PHP側では切り詰めて処理しているので、おなじみ?の「余計なお節介」の範疇なのかな、と(そもそもキー長を超えるサイズを渡している時点で負け確定だと思っているので)。
マニュアルには追加しておいた方が良さそうな内容ですね。