by shigemk2

当面は技術的なことしか書かない

PHPのmcrypt_enc_get_key_sizeの挙動

別にcontributeしたかったわけじゃなかった。PHPのmcrypt_enc_get_key_sizeの挙動を知りたかった。7.2から非推奨だけどしゃあない。 アルゴリズムの最大鍵長を返す関数だけど、最大鍵長はアルゴリズムによって決まっていて、特段演算や処理も必要がないから、どこかで決め打ちしていると当たりをつけた。でもPHPのソースにもpecl-encryption-mcryptのソースにも該当する箇所はなかった。 実体はlibmcryptを呼び出しているので、libmcryptのソースコードを読んでみることにした。

$ cvs -d :pserver:anonymous@cvs.hellug.gr:/var/cvs/mcrypt login
Password:    (enter password anonymous)
$ cvs -d :pserver:anonymous@cvs.hellug.gr:/var/cvs/mcrypt co mcrypt
$ cvs -d :pserver:anonymous@cvs.hellug.gr:/var/cvs/mcrypt co libmcrypt
$ cvs -d :pserver:anonymous@cvs.hellug.gr:/var/cvs/mcrypt co libmcrypt-nm

CVS Info for project mcrypt

いろいろ探した結果、libmcrypt-nm/lib/mcrypt_extra.cに、決め打ちされた実装があった。

#define MCRYPT_ENTRY(name, blksize, keysize, block) \
        { #name, name, blksize, keysize, block }

struct mcrypt_algorithm_entry {
    char *name;
    int id;
    size_t blocksize;
    size_t keysize;
    int block;
};

static mcrypt_algorithm_entry algorithms[] = {
    MCRYPT_ENTRY(MCRYPT_BLOWFISH, 8, 56, 1),
    MCRYPT_ENTRY(MCRYPT_DES, 8, 8, 1),
    MCRYPT_ENTRY(MCRYPT_TRIPLEDES, 8, 24, 1),
    MCRYPT_ENTRY(MCRYPT_THREEWAY, 12, 12, 1),
    MCRYPT_ENTRY(MCRYPT_GOST, 8, 32, 1),
    MCRYPT_ENTRY(MCRYPT_SAFER_SK64, 8, 8, 1),
    MCRYPT_ENTRY(MCRYPT_SAFER_SK128, 8, 16, 1),
    MCRYPT_ENTRY(MCRYPT_CAST_128, 8, 16, 1),
    MCRYPT_ENTRY(MCRYPT_XTEA, 8, 16, 1),
    MCRYPT_ENTRY(MCRYPT_RC2, 8, 128, 1),
    MCRYPT_ENTRY(MCRYPT_TWOFISH, 16, 32, 1),
    MCRYPT_ENTRY(MCRYPT_CAST_256, 16, 32, 1),
    MCRYPT_ENTRY(MCRYPT_SAFERPLUS, 16, 32, 1),
    MCRYPT_ENTRY(MCRYPT_LOKI97, 16, 32, 1),
    MCRYPT_ENTRY(MCRYPT_SERPENT, 16, 32, 1),
    MCRYPT_ENTRY(MCRYPT_RIJNDAEL_128, 16, 32, 1),
    MCRYPT_ENTRY(MCRYPT_ARCFOUR, 1, 256, 0),
    MCRYPT_ENTRY(MCRYPT_ENIGMA, 1, 13, 0),
    {0}
};

処理の流れを完全に追えてはいないけど、PHPの実装と照らし合わせて、MCRYPT_ENTRYのkeysizeを返しているんだろう、という感じの実装だった。なお、sizeの単位はbyteです。でもRijndaelの鍵長って128 192 256あるし、MCRYPT_RIJNDAEL_256も定義されているのにここの構造体には定義がないのはどうしたものだろう。