Do You PHP はてブロ

Do You PHPはてなからはてブロに移動しました

mcryptで不正な長さのIVや鍵を渡した場合

ちょw オマケに名指し。


@shimooka 教えてエロイ人 http://d.hatena.ne.jp/yando...

id:yandodさんのエントリmcryptの動作がマニュアルと違うように見える件 - yandodの日記ですが、mcrypt_generic_deinitする前にmcrypt拡張側で長さチェックしているのが原因みたいですねぇ。以下、PHP5.2.5のext/mcrypt.cです。

    408 PHP_FUNCTION(mcrypt_generic_init)
    409 {
                     :
    439     if (Z_STRLEN_PP(key) > max_key_size) {
    440         php_error_docref(NULL TSRMLS_CC, E_WARNING, "Key size too large; supplied length: %d, max: %d", Z_STRLEN_PP(key), max_key_size);
    441         key_size = max_key_size;
    442     } else {
    443         key_size = Z_STRLEN_PP(key);
    444     }
    445     memcpy(key_s, Z_STRVAL_PP(key), Z_STRLEN_PP(key));
    446
    447     if (Z_STRLEN_PP(iv) != iv_size) {
    448         php_error_docref(NULL TSRMLS_CC, E_WARNING, "Iv size incorrect; supplied length: %d, needed: %d", Z_STRLEN_PP(iv), iv_size);
    449     }
    450     memcpy(iv_s, Z_STRVAL_PP(iv), iv_size);
    451
    452     mcrypt_generic_deinit(pm->td);
    453     result = mcrypt_generic_init(pm->td, key_s, key_size, iv_s);
    454
    455     /* If this function fails, close the mcrypt module to prevent crashes
    456      * when further functions want to access this resource */
    457     if (result < 0) {
    458         zend_list_delete(Z_LVAL_PP(mcryptind));
    459         switch (result) {
    460             case -3:
    461                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Key length incorrect");
    462                 break;
    463             case -4:
    464                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Memory allocation error");
    465                 break;
    466             case -1:
    467             default:
    468                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unknown error");
    469                 break;
    470         }
    471     }

これを

    438
    439 //  if (Z_STRLEN_PP(key) > max_key_size) {
    440 //      php_error_docref(NULL TSRMLS_CC, E_WARNING, "Key size too large; supplied length: %d, max: %d", Z_STRLEN_PP(key), max_key_size);
    441 //      key_size = max_key_size;
    442 //  } else {
    443         key_size = Z_STRLEN_PP(key);
    444 //  }
    445     memcpy(key_s, Z_STRVAL_PP(key), Z_STRLEN_PP(key));
    446
    447 //  if (Z_STRLEN_PP(iv) != iv_size) {
    448 //      php_error_docref(NULL TSRMLS_CC, E_WARNING, "Iv size incorrect; supplied length: %d, needed: %d", Z_STRLEN_PP(iv), iv_size);
    449 //  }
    450     memcpy(iv_s, Z_STRVAL_PP(iv), iv_size);
    451

として再buildし、

<?php
/* 暗号モジュールをオープンします */
$td = mcrypt_module_open('rijndael-256', '', 'ofb', '');

/* IV を作成し、キー長を定義します。*/
$iv = mcrypt_create_iv(mcrypt_enc_get_iv_size($td), MCRYPT_DEV_RANDOM);
$ks = mcrypt_enc_get_key_size($td);

/* キーを作成します */
$key = substr(md5('very secret key'), 0, $ks);

// add start
$key .= "aa"; //キーを不正な長さにします
$iv = "111";  //IVを不正にします
// add end/* 暗号化処理を初期化します */
$ret = mcrypt_generic_init($td, $key, $iv);

var_dump($ret);

で試したところ、出力結果は

Warning: mcrypt_generic_init() [function.mcrypt-generic-init]: Key length incorrect in /home/shimooka/public_html/mcrypt_yando.php on line 16
int(-3)

となりました。
まあ、


@yando Extensionが謎な実装になってますね (´A`)

とか

@yando とりあえずFALSEは絶対返ってきませんよね.RETURN_LONGしかないもん

のフォローもありますが、現状では「イケてない実装」になってるのは確かのようです。

誤りがあれば指摘をお願いします>もっとエロイ人w