ます’s Blog - どうでもいい記事100選

どうでもいい記事100選

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側では切り詰めて処理しているので、おなじみ?の「余計なお節介」の範疇なのかな、と(そもそもキー長を超えるサイズを渡している時点で負け確定だと思っているので)。
マニュアルには追加しておいた方が良さそうな内容ですね。