Annotation of embedaddon/php/ext/mcrypt/mcrypt.c, revision 1.1

1.1     ! misho       1: /*
        !             2:    +----------------------------------------------------------------------+
        !             3:    | PHP Version 5                                                        |
        !             4:    +----------------------------------------------------------------------+
        !             5:    | Copyright (c) 1997-2012 The PHP Group                                |
        !             6:    +----------------------------------------------------------------------+
        !             7:    | This source file is subject to version 3.01 of the PHP license,      |
        !             8:    | that is bundled with this package in the file LICENSE, and is        |
        !             9:    | available through the world-wide-web at the following url:           |
        !            10:    | http://www.php.net/license/3_01.txt                                  |
        !            11:    | If you did not receive a copy of the PHP license and are unable to   |
        !            12:    | obtain it through the world-wide-web, please send a note to          |
        !            13:    | license@php.net so we can mail you a copy immediately.               |
        !            14:    +----------------------------------------------------------------------+
        !            15:    | Authors: Sascha Schumann <sascha@schumann.cx>                        |
        !            16:    |          Derick Rethans <derick@derickrethans.nl>                    |
        !            17:    +----------------------------------------------------------------------+
        !            18:  */
        !            19: /* $Id: mcrypt.c 321634 2012-01-01 13:15:04Z felipe $ */
        !            20: 
        !            21: #ifdef HAVE_CONFIG_H
        !            22: #include "config.h"
        !            23: #endif
        !            24: 
        !            25: #include "php.h"
        !            26: 
        !            27: #if HAVE_LIBMCRYPT
        !            28: 
        !            29: #if PHP_WIN32
        !            30: # include "win32/winutil.h"
        !            31: #endif
        !            32: 
        !            33: #include "php_mcrypt.h"
        !            34: #include "fcntl.h"
        !            35: 
        !            36: #define NON_FREE
        !            37: #define MCRYPT2
        !            38: #include "mcrypt.h"
        !            39: #include "php_ini.h"
        !            40: #include "php_globals.h"
        !            41: #include "ext/standard/info.h"
        !            42: #include "ext/standard/php_rand.h"
        !            43: #include "php_mcrypt_filter.h"
        !            44: 
        !            45: static int le_mcrypt;
        !            46: 
        !            47: typedef struct _php_mcrypt { 
        !            48:        MCRYPT td;
        !            49:        zend_bool init;
        !            50: } php_mcrypt;
        !            51: 
        !            52: /* {{{ arginfo */
        !            53: ZEND_BEGIN_ARG_INFO_EX(arginfo_mcrypt_module_open, 0, 0, 4)
        !            54:        ZEND_ARG_INFO(0, cipher)
        !            55:        ZEND_ARG_INFO(0, cipher_directory)
        !            56:        ZEND_ARG_INFO(0, mode)
        !            57:        ZEND_ARG_INFO(0, mode_directory)
        !            58: ZEND_END_ARG_INFO()
        !            59: 
        !            60: ZEND_BEGIN_ARG_INFO_EX(arginfo_mcrypt_generic_init, 0, 0, 3)
        !            61:        ZEND_ARG_INFO(0, td)
        !            62:        ZEND_ARG_INFO(0, key)
        !            63:        ZEND_ARG_INFO(0, iv)
        !            64: ZEND_END_ARG_INFO()
        !            65: 
        !            66: ZEND_BEGIN_ARG_INFO_EX(arginfo_mcrypt_generic, 0, 0, 2)
        !            67:        ZEND_ARG_INFO(0, td)
        !            68:        ZEND_ARG_INFO(0, data)
        !            69: ZEND_END_ARG_INFO()
        !            70: 
        !            71: ZEND_BEGIN_ARG_INFO_EX(arginfo_mdecrypt_generic, 0, 0, 2)
        !            72:        ZEND_ARG_INFO(0, td)
        !            73:        ZEND_ARG_INFO(0, data)
        !            74: ZEND_END_ARG_INFO()
        !            75: 
        !            76: ZEND_BEGIN_ARG_INFO_EX(arginfo_mcrypt_enc_get_supported_key_sizes, 0, 0, 1)
        !            77:        ZEND_ARG_INFO(0, td)
        !            78: ZEND_END_ARG_INFO()
        !            79: 
        !            80: ZEND_BEGIN_ARG_INFO_EX(arginfo_mcrypt_enc_self_test, 0, 0, 1)
        !            81:        ZEND_ARG_INFO(0, td)
        !            82: ZEND_END_ARG_INFO()
        !            83: 
        !            84: ZEND_BEGIN_ARG_INFO_EX(arginfo_mcrypt_module_close, 0, 0, 1)
        !            85:        ZEND_ARG_INFO(0, td)
        !            86: ZEND_END_ARG_INFO()
        !            87: 
        !            88: ZEND_BEGIN_ARG_INFO_EX(arginfo_mcrypt_generic_deinit, 0, 0, 1)
        !            89:        ZEND_ARG_INFO(0, td)
        !            90: ZEND_END_ARG_INFO()
        !            91: 
        !            92: ZEND_BEGIN_ARG_INFO_EX(arginfo_mcrypt_enc_is_block_algorithm_mode, 0, 0, 1)
        !            93:        ZEND_ARG_INFO(0, td)
        !            94: ZEND_END_ARG_INFO()
        !            95: 
        !            96: ZEND_BEGIN_ARG_INFO_EX(arginfo_mcrypt_enc_is_block_algorithm, 0, 0, 1)
        !            97:        ZEND_ARG_INFO(0, td)
        !            98: ZEND_END_ARG_INFO()
        !            99: 
        !           100: ZEND_BEGIN_ARG_INFO_EX(arginfo_mcrypt_enc_is_block_mode, 0, 0, 1)
        !           101:        ZEND_ARG_INFO(0, td)
        !           102: ZEND_END_ARG_INFO()
        !           103: 
        !           104: ZEND_BEGIN_ARG_INFO_EX(arginfo_mcrypt_enc_get_block_size, 0, 0, 1)
        !           105:        ZEND_ARG_INFO(0, td)
        !           106: ZEND_END_ARG_INFO()
        !           107: 
        !           108: ZEND_BEGIN_ARG_INFO_EX(arginfo_mcrypt_enc_get_key_size, 0, 0, 1)
        !           109:        ZEND_ARG_INFO(0, td)
        !           110: ZEND_END_ARG_INFO()
        !           111: 
        !           112: ZEND_BEGIN_ARG_INFO_EX(arginfo_mcrypt_enc_get_iv_size, 0, 0, 1)
        !           113:        ZEND_ARG_INFO(0, td)
        !           114: ZEND_END_ARG_INFO()
        !           115: 
        !           116: ZEND_BEGIN_ARG_INFO_EX(arginfo_mcrypt_enc_get_algorithms_name, 0, 0, 1)
        !           117:        ZEND_ARG_INFO(0, td)
        !           118: ZEND_END_ARG_INFO()
        !           119: 
        !           120: ZEND_BEGIN_ARG_INFO_EX(arginfo_mcrypt_enc_get_modes_name, 0, 0, 1)
        !           121:        ZEND_ARG_INFO(0, td)
        !           122: ZEND_END_ARG_INFO()
        !           123: 
        !           124: ZEND_BEGIN_ARG_INFO_EX(arginfo_mcrypt_module_self_test, 0, 0, 1)
        !           125:        ZEND_ARG_INFO(0, algorithm)
        !           126:        ZEND_ARG_INFO(0, lib_dir)
        !           127: ZEND_END_ARG_INFO()
        !           128: 
        !           129: ZEND_BEGIN_ARG_INFO_EX(arginfo_mcrypt_module_is_block_algorithm_mode, 0, 0, 1)
        !           130:        ZEND_ARG_INFO(0, mode)
        !           131:        ZEND_ARG_INFO(0, lib_dir)
        !           132: ZEND_END_ARG_INFO()
        !           133: 
        !           134: ZEND_BEGIN_ARG_INFO_EX(arginfo_mcrypt_module_is_block_algorithm, 0, 0, 1)
        !           135:        ZEND_ARG_INFO(0, algorithm)
        !           136:        ZEND_ARG_INFO(0, lib_dir)
        !           137: ZEND_END_ARG_INFO()
        !           138: 
        !           139: ZEND_BEGIN_ARG_INFO_EX(arginfo_mcrypt_module_is_block_mode, 0, 0, 1)
        !           140:        ZEND_ARG_INFO(0, mode)
        !           141:        ZEND_ARG_INFO(0, lib_dir)
        !           142: ZEND_END_ARG_INFO()
        !           143: 
        !           144: ZEND_BEGIN_ARG_INFO_EX(arginfo_mcrypt_module_get_algo_block_size, 0, 0, 1)
        !           145:        ZEND_ARG_INFO(0, algorithm)
        !           146:        ZEND_ARG_INFO(0, lib_dir)
        !           147: ZEND_END_ARG_INFO()
        !           148: 
        !           149: ZEND_BEGIN_ARG_INFO_EX(arginfo_mcrypt_module_get_algo_key_size, 0, 0, 1)
        !           150:        ZEND_ARG_INFO(0, algorithm)
        !           151:        ZEND_ARG_INFO(0, lib_dir)
        !           152: ZEND_END_ARG_INFO()
        !           153: 
        !           154: ZEND_BEGIN_ARG_INFO_EX(arginfo_mcrypt_module_get_supported_key_sizes, 0, 0, 1)
        !           155:        ZEND_ARG_INFO(0, algorithm)
        !           156:        ZEND_ARG_INFO(0, lib_dir)
        !           157: ZEND_END_ARG_INFO()
        !           158: 
        !           159: ZEND_BEGIN_ARG_INFO_EX(arginfo_mcrypt_list_algorithms, 0, 0, 0)
        !           160:        ZEND_ARG_INFO(0, lib_dir)
        !           161: ZEND_END_ARG_INFO()
        !           162: 
        !           163: ZEND_BEGIN_ARG_INFO_EX(arginfo_mcrypt_list_modes, 0, 0, 0)
        !           164:        ZEND_ARG_INFO(0, lib_dir)
        !           165: ZEND_END_ARG_INFO()
        !           166: 
        !           167: ZEND_BEGIN_ARG_INFO_EX(arginfo_mcrypt_get_key_size, 0, 0, 2)
        !           168:        ZEND_ARG_INFO(0, cipher)
        !           169:        ZEND_ARG_INFO(0, module)
        !           170: ZEND_END_ARG_INFO()
        !           171: 
        !           172: ZEND_BEGIN_ARG_INFO_EX(arginfo_mcrypt_get_block_size, 0, 0, 2)
        !           173:        ZEND_ARG_INFO(0, cipher)
        !           174:        ZEND_ARG_INFO(0, module)
        !           175: ZEND_END_ARG_INFO()
        !           176: 
        !           177: ZEND_BEGIN_ARG_INFO_EX(arginfo_mcrypt_get_iv_size, 0, 0, 2)
        !           178:        ZEND_ARG_INFO(0, cipher)
        !           179:        ZEND_ARG_INFO(0, module)
        !           180: ZEND_END_ARG_INFO()
        !           181: 
        !           182: ZEND_BEGIN_ARG_INFO_EX(arginfo_mcrypt_get_cipher_name, 0, 0, 1)
        !           183:        ZEND_ARG_INFO(0, cipher)
        !           184: ZEND_END_ARG_INFO()
        !           185: 
        !           186: ZEND_BEGIN_ARG_INFO_EX(arginfo_mcrypt_encrypt, 0, 0, 5)
        !           187:        ZEND_ARG_INFO(0, cipher)
        !           188:        ZEND_ARG_INFO(0, key)
        !           189:        ZEND_ARG_INFO(0, data)
        !           190:        ZEND_ARG_INFO(0, mode)
        !           191:        ZEND_ARG_INFO(0, iv)
        !           192: ZEND_END_ARG_INFO()
        !           193: 
        !           194: ZEND_BEGIN_ARG_INFO_EX(arginfo_mcrypt_decrypt, 0, 0, 5)
        !           195:        ZEND_ARG_INFO(0, cipher)
        !           196:        ZEND_ARG_INFO(0, key)
        !           197:        ZEND_ARG_INFO(0, data)
        !           198:        ZEND_ARG_INFO(0, mode)
        !           199:        ZEND_ARG_INFO(0, iv)
        !           200: ZEND_END_ARG_INFO()
        !           201: 
        !           202: ZEND_BEGIN_ARG_INFO_EX(arginfo_mcrypt_ecb, 0, 0, 5)
        !           203:        ZEND_ARG_INFO(0, cipher)
        !           204:        ZEND_ARG_INFO(0, key)
        !           205:        ZEND_ARG_INFO(0, data)
        !           206:        ZEND_ARG_INFO(0, mode)
        !           207:        ZEND_ARG_INFO(0, iv)
        !           208: ZEND_END_ARG_INFO()
        !           209: 
        !           210: ZEND_BEGIN_ARG_INFO_EX(arginfo_mcrypt_cbc, 0, 0, 5)
        !           211:        ZEND_ARG_INFO(0, cipher)
        !           212:        ZEND_ARG_INFO(0, key)
        !           213:        ZEND_ARG_INFO(0, data)
        !           214:        ZEND_ARG_INFO(0, mode)
        !           215:        ZEND_ARG_INFO(0, iv)
        !           216: ZEND_END_ARG_INFO()
        !           217: 
        !           218: ZEND_BEGIN_ARG_INFO_EX(arginfo_mcrypt_cfb, 0, 0, 5)
        !           219:        ZEND_ARG_INFO(0, cipher)
        !           220:        ZEND_ARG_INFO(0, key)
        !           221:        ZEND_ARG_INFO(0, data)
        !           222:        ZEND_ARG_INFO(0, mode)
        !           223:        ZEND_ARG_INFO(0, iv)
        !           224: ZEND_END_ARG_INFO()
        !           225: 
        !           226: ZEND_BEGIN_ARG_INFO_EX(arginfo_mcrypt_ofb, 0, 0, 5)
        !           227:        ZEND_ARG_INFO(0, cipher)
        !           228:        ZEND_ARG_INFO(0, key)
        !           229:        ZEND_ARG_INFO(0, data)
        !           230:        ZEND_ARG_INFO(0, mode)
        !           231:        ZEND_ARG_INFO(0, iv)
        !           232: ZEND_END_ARG_INFO()
        !           233: 
        !           234: ZEND_BEGIN_ARG_INFO_EX(arginfo_mcrypt_create_iv, 0, 0, 2)
        !           235:        ZEND_ARG_INFO(0, size)
        !           236:        ZEND_ARG_INFO(0, source)
        !           237: ZEND_END_ARG_INFO()
        !           238: /* }}} */
        !           239: 
        !           240: const zend_function_entry mcrypt_functions[] = { /* {{{ */
        !           241:        PHP_FE(mcrypt_ecb,                              arginfo_mcrypt_ecb)
        !           242:        PHP_FE(mcrypt_cbc,                              arginfo_mcrypt_cbc)
        !           243:        PHP_FE(mcrypt_cfb,                              arginfo_mcrypt_cfb)
        !           244:        PHP_FE(mcrypt_ofb,                              arginfo_mcrypt_ofb)
        !           245:        PHP_FE(mcrypt_get_key_size,     arginfo_mcrypt_get_key_size)
        !           246:        PHP_FE(mcrypt_get_block_size,   arginfo_mcrypt_get_block_size)
        !           247:        PHP_FE(mcrypt_get_cipher_name,  arginfo_mcrypt_get_cipher_name)
        !           248:        PHP_FE(mcrypt_create_iv,                arginfo_mcrypt_create_iv)
        !           249: 
        !           250:        PHP_FE(mcrypt_list_algorithms,  arginfo_mcrypt_list_algorithms)
        !           251:        PHP_FE(mcrypt_list_modes,               arginfo_mcrypt_list_modes)
        !           252:        PHP_FE(mcrypt_get_iv_size,              arginfo_mcrypt_get_iv_size)
        !           253:        PHP_FE(mcrypt_encrypt,                  arginfo_mcrypt_encrypt)
        !           254:        PHP_FE(mcrypt_decrypt,                  arginfo_mcrypt_decrypt)
        !           255: 
        !           256:        PHP_FE(mcrypt_module_open,              arginfo_mcrypt_module_open)
        !           257:        PHP_FE(mcrypt_generic_init,     arginfo_mcrypt_generic_init)
        !           258:        PHP_FE(mcrypt_generic,                  arginfo_mcrypt_generic)
        !           259:        PHP_FE(mdecrypt_generic,                arginfo_mdecrypt_generic)
        !           260:        PHP_DEP_FALIAS(mcrypt_generic_end, mcrypt_generic_deinit, arginfo_mcrypt_generic_deinit)
        !           261:        PHP_FE(mcrypt_generic_deinit,   arginfo_mcrypt_generic_deinit)
        !           262: 
        !           263:        PHP_FE(mcrypt_enc_self_test,    arginfo_mcrypt_enc_self_test)
        !           264:        PHP_FE(mcrypt_enc_is_block_algorithm_mode, arginfo_mcrypt_enc_is_block_algorithm_mode)
        !           265:        PHP_FE(mcrypt_enc_is_block_algorithm,   arginfo_mcrypt_enc_is_block_algorithm)
        !           266:        PHP_FE(mcrypt_enc_is_block_mode,                arginfo_mcrypt_enc_is_block_mode)
        !           267:        PHP_FE(mcrypt_enc_get_block_size,               arginfo_mcrypt_enc_get_block_size)
        !           268:        PHP_FE(mcrypt_enc_get_key_size,                 arginfo_mcrypt_enc_get_key_size)
        !           269:        PHP_FE(mcrypt_enc_get_supported_key_sizes, arginfo_mcrypt_enc_get_supported_key_sizes)
        !           270:        PHP_FE(mcrypt_enc_get_iv_size,                  arginfo_mcrypt_enc_get_iv_size)
        !           271:        PHP_FE(mcrypt_enc_get_algorithms_name,  arginfo_mcrypt_enc_get_algorithms_name)
        !           272:        PHP_FE(mcrypt_enc_get_modes_name,               arginfo_mcrypt_enc_get_modes_name)
        !           273:        PHP_FE(mcrypt_module_self_test,                 arginfo_mcrypt_module_self_test)
        !           274: 
        !           275:        PHP_FE(mcrypt_module_is_block_algorithm_mode,   arginfo_mcrypt_module_is_block_algorithm_mode)
        !           276:        PHP_FE(mcrypt_module_is_block_algorithm,                arginfo_mcrypt_module_is_block_algorithm)
        !           277:        PHP_FE(mcrypt_module_is_block_mode,                     arginfo_mcrypt_module_is_block_mode)
        !           278:        PHP_FE(mcrypt_module_get_algo_block_size,               arginfo_mcrypt_module_get_algo_block_size)
        !           279:        PHP_FE(mcrypt_module_get_algo_key_size,                 arginfo_mcrypt_module_get_algo_key_size)
        !           280:        PHP_FE(mcrypt_module_get_supported_key_sizes,   arginfo_mcrypt_module_get_supported_key_sizes)
        !           281: 
        !           282:        PHP_FE(mcrypt_module_close,                                     arginfo_mcrypt_module_close)
        !           283:        PHP_FE_END
        !           284: };
        !           285: /* }}} */
        !           286: 
        !           287: static PHP_MINFO_FUNCTION(mcrypt);
        !           288: static PHP_MINIT_FUNCTION(mcrypt);
        !           289: static PHP_MSHUTDOWN_FUNCTION(mcrypt);
        !           290: 
        !           291: ZEND_DECLARE_MODULE_GLOBALS(mcrypt)
        !           292: 
        !           293: zend_module_entry mcrypt_module_entry = {
        !           294:        STANDARD_MODULE_HEADER,
        !           295:        "mcrypt", 
        !           296:        mcrypt_functions,
        !           297:        PHP_MINIT(mcrypt), PHP_MSHUTDOWN(mcrypt),
        !           298:        NULL, NULL,
        !           299:        PHP_MINFO(mcrypt),
        !           300:        NO_VERSION_YET,
        !           301:        PHP_MODULE_GLOBALS(mcrypt),
        !           302:        NULL,
        !           303:        NULL,
        !           304:        NULL,
        !           305:        STANDARD_MODULE_PROPERTIES_EX
        !           306: };
        !           307: 
        !           308: #ifdef COMPILE_DL_MCRYPT
        !           309: ZEND_GET_MODULE(mcrypt)
        !           310: #endif
        !           311: 
        !           312: #define MCRYPT_ARGS2                                                                                   \
        !           313:        zval **cipher, **data, **key, **mode;                                           \
        !           314:        int td;                                                                                                         \
        !           315:        char *ndata;                                                                                            \
        !           316:        size_t bsize;                                                                                           \
        !           317:        size_t nr;                                                                                                      \
        !           318:        size_t nsize
        !           319: 
        !           320: #define MCRYPT_ARGS                                                                                    \
        !           321:        MCRYPT_ARGS2;                                                                                           \
        !           322:        zval **iv
        !           323: 
        !           324: #define MCRYPT_SIZE                                                                            \
        !           325:        bsize = mcrypt_get_block_size(Z_LVAL_PP(cipher));               \
        !           326:        nr = (Z_STRLEN_PP(data) + bsize - 1) / bsize;                   \
        !           327:        nsize = nr * bsize
        !           328: 
        !           329: #define MCRYPT_CHECK_TD_CPY                                                                    \
        !           330:        if (td < 0) {                                                                                           \
        !           331:                php_error_docref(NULL TSRMLS_CC, E_WARNING, MCRYPT_FAILED);                                     \
        !           332:                RETURN_FALSE;                                                                                   \
        !           333:        }                                                                                                                       \
        !           334:        ndata = ecalloc(nr, bsize);                                                             \
        !           335:        memcpy(ndata, Z_STRVAL_PP(data), Z_STRLEN_PP(data))
        !           336: 
        !           337: #define MCRYPT_CHECK_IV                                                                                \
        !           338:        convert_to_string_ex(iv);                                                                       \
        !           339:        if (Z_STRLEN_PP(iv) != bsize) {                                                         \
        !           340:                php_error_docref(NULL TSRMLS_CC, E_WARNING, MCRYPT_IV_WRONG_SIZE);                      \
        !           341:                RETURN_FALSE;                                                                                   \
        !           342:        }
        !           343: 
        !           344: #define MCRYPT_ACTION(x)                                                                               \
        !           345:        if (Z_LVAL_PP(mode) == 0) {                                                             \
        !           346:                mcrypt_##x(td, ndata, nsize);                                                   \
        !           347:        } else {                                                                                                        \
        !           348:                mdecrypt_##x(td, ndata, nsize);                                                 \
        !           349:        }                                                                                                                       \
        !           350:        end_mcrypt_##x(td)
        !           351: 
        !           352: #define MCRYPT_IV_WRONG_SIZE "The IV parameter must be as long as the blocksize"
        !           353: 
        !           354: #define MCRYPT_ENCRYPT 0
        !           355: #define MCRYPT_DECRYPT 1
        !           356: 
        !           357: #define MCRYPT_GET_INI                                                                                 \
        !           358:        cipher_dir_string = MCG(algorithms_dir);                                        \
        !           359:        module_dir_string = MCG(modes_dir);
        !           360: 
        !           361: /*
        !           362:  * #warning is not ANSI C
        !           363:  * #warning Invalidate resource if the param count is wrong, or other problems
        !           364:  * #warning occurred during functions.
        !           365:  */
        !           366: 
        !           367: #define MCRYPT_GET_CRYPT_ARGS                                                                          \
        !           368:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sssZ|s",  \
        !           369:                &cipher, &cipher_len, &key, &key_len, &data, &data_len, &mode, &iv, &iv_len) == FAILURE) {      \
        !           370:                return;         \
        !           371:        }
        !           372: 
        !           373: #define MCRYPT_GET_TD_ARG                                                                              \
        !           374:        zval *mcryptind;                                                                                        \
        !           375:        php_mcrypt *pm;                                                                                                 \
        !           376:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &mcryptind) == FAILURE) {                     \
        !           377:                return;                                                                                                                         \
        !           378:        }                                                                                                                                                                               \
        !           379:        ZEND_FETCH_RESOURCE (pm, php_mcrypt *, &mcryptind, -1, "MCrypt", le_mcrypt);                            
        !           380: 
        !           381: #define MCRYPT_GET_MODE_DIR_ARGS(DIRECTORY)                                                            \
        !           382:        char *dir = NULL;                                                   \
        !           383:        int   dir_len;                                                      \
        !           384:        char *module;                                                       \
        !           385:        int   module_len;                                                   \
        !           386:        if (zend_parse_parameters (ZEND_NUM_ARGS() TSRMLS_CC,               \
        !           387:                "s|s", &module, &module_len, &dir, &dir_len) == FAILURE) {      \
        !           388:                return;                                                         \
        !           389:        }
        !           390: 
        !           391: #define MCRYPT_OPEN_MODULE_FAILED "Module initialization failed"
        !           392: 
        !           393: #define MCRYPT_ENTRY2_2_4(a,b) REGISTER_STRING_CONSTANT("MCRYPT_" #a, b, CONST_PERSISTENT)
        !           394: #define MCRYPT_ENTRY2_4(a) MCRYPT_ENTRY_NAMED(a, a)
        !           395: 
        !           396: #define PHP_MCRYPT_INIT_CHECK  \
        !           397:        if (!pm->init) {        \
        !           398:                php_error_docref(NULL TSRMLS_CC, E_WARNING, "Operation disallowed prior to mcrypt_generic_init().");    \
        !           399:                RETURN_FALSE;   \
        !           400:        }       \
        !           401: 
        !           402: PHP_INI_BEGIN()
        !           403:        STD_PHP_INI_ENTRY("mcrypt.algorithms_dir", NULL, PHP_INI_ALL, OnUpdateString, algorithms_dir, zend_mcrypt_globals, mcrypt_globals)
        !           404:        STD_PHP_INI_ENTRY("mcrypt.modes_dir",      NULL, PHP_INI_ALL, OnUpdateString, modes_dir, zend_mcrypt_globals, mcrypt_globals)
        !           405: PHP_INI_END()
        !           406: 
        !           407: static void php_mcrypt_module_dtor(zend_rsrc_list_entry *rsrc TSRMLS_DC) /* {{{ */
        !           408: {
        !           409:        php_mcrypt *pm = (php_mcrypt *) rsrc->ptr;
        !           410:        if (pm) {       
        !           411:                mcrypt_generic_deinit(pm->td);
        !           412:                mcrypt_module_close(pm->td);
        !           413:                efree(pm);
        !           414:                pm = NULL;
        !           415:        }
        !           416: }
        !           417: /* }}} */
        !           418:     
        !           419: static PHP_MINIT_FUNCTION(mcrypt) /* {{{ */
        !           420: {
        !           421:        le_mcrypt = zend_register_list_destructors_ex(php_mcrypt_module_dtor, NULL, "mcrypt", module_number);
        !           422: 
        !           423:        /* modes for mcrypt_??? routines */
        !           424:        REGISTER_LONG_CONSTANT("MCRYPT_ENCRYPT", 0, CONST_PERSISTENT);
        !           425:        REGISTER_LONG_CONSTANT("MCRYPT_DECRYPT", 1, CONST_PERSISTENT);
        !           426: 
        !           427:        /* sources for mcrypt_create_iv */
        !           428:        REGISTER_LONG_CONSTANT("MCRYPT_DEV_RANDOM", 0, CONST_PERSISTENT);
        !           429:        REGISTER_LONG_CONSTANT("MCRYPT_DEV_URANDOM", 1, CONST_PERSISTENT);
        !           430:        REGISTER_LONG_CONSTANT("MCRYPT_RAND", 2, CONST_PERSISTENT);
        !           431: 
        !           432:        /* ciphers */
        !           433:        MCRYPT_ENTRY2_2_4(3DES, "tripledes");
        !           434:        MCRYPT_ENTRY2_2_4(ARCFOUR_IV, "arcfour-iv");
        !           435:        MCRYPT_ENTRY2_2_4(ARCFOUR, "arcfour");
        !           436:        MCRYPT_ENTRY2_2_4(BLOWFISH, "blowfish");
        !           437:        MCRYPT_ENTRY2_2_4(BLOWFISH_COMPAT, "blowfish-compat");
        !           438:        MCRYPT_ENTRY2_2_4(CAST_128, "cast-128");
        !           439:        MCRYPT_ENTRY2_2_4(CAST_256, "cast-256");
        !           440:        MCRYPT_ENTRY2_2_4(CRYPT, "crypt");
        !           441:        MCRYPT_ENTRY2_2_4(DES, "des");
        !           442:        MCRYPT_ENTRY2_2_4(ENIGNA, "crypt");
        !           443:        MCRYPT_ENTRY2_2_4(GOST, "gost");
        !           444:        MCRYPT_ENTRY2_2_4(LOKI97, "loki97");
        !           445:        MCRYPT_ENTRY2_2_4(PANAMA, "panama");
        !           446:        MCRYPT_ENTRY2_2_4(RC2, "rc2");
        !           447:        MCRYPT_ENTRY2_2_4(RIJNDAEL_128, "rijndael-128");
        !           448:        MCRYPT_ENTRY2_2_4(RIJNDAEL_192, "rijndael-192");
        !           449:        MCRYPT_ENTRY2_2_4(RIJNDAEL_256, "rijndael-256");
        !           450:        MCRYPT_ENTRY2_2_4(SAFER64, "safer-sk64");
        !           451:        MCRYPT_ENTRY2_2_4(SAFER128, "safer-sk128");
        !           452:        MCRYPT_ENTRY2_2_4(SAFERPLUS, "saferplus");
        !           453:        MCRYPT_ENTRY2_2_4(SERPENT, "serpent");
        !           454:        MCRYPT_ENTRY2_2_4(THREEWAY, "threeway");
        !           455:        MCRYPT_ENTRY2_2_4(TRIPLEDES, "tripledes");
        !           456:        MCRYPT_ENTRY2_2_4(TWOFISH, "twofish");
        !           457:        MCRYPT_ENTRY2_2_4(WAKE, "wake");
        !           458:        MCRYPT_ENTRY2_2_4(XTEA, "xtea");
        !           459: 
        !           460:        MCRYPT_ENTRY2_2_4(IDEA, "idea");
        !           461:        MCRYPT_ENTRY2_2_4(MARS, "mars");
        !           462:        MCRYPT_ENTRY2_2_4(RC6, "rc6");
        !           463:        MCRYPT_ENTRY2_2_4(SKIPJACK, "skipjack");
        !           464: /* modes */
        !           465:        MCRYPT_ENTRY2_2_4(MODE_CBC, "cbc");
        !           466:        MCRYPT_ENTRY2_2_4(MODE_CFB, "cfb");
        !           467:        MCRYPT_ENTRY2_2_4(MODE_ECB, "ecb");
        !           468:        MCRYPT_ENTRY2_2_4(MODE_NOFB, "nofb");
        !           469:        MCRYPT_ENTRY2_2_4(MODE_OFB, "ofb");
        !           470:        MCRYPT_ENTRY2_2_4(MODE_STREAM, "stream");
        !           471:        REGISTER_INI_ENTRIES();
        !           472: 
        !           473:        php_stream_filter_register_factory("mcrypt.*", &php_mcrypt_filter_factory TSRMLS_CC);
        !           474:        php_stream_filter_register_factory("mdecrypt.*", &php_mcrypt_filter_factory TSRMLS_CC);
        !           475: 
        !           476:        return SUCCESS;
        !           477: }
        !           478: /* }}} */
        !           479: 
        !           480: static PHP_MSHUTDOWN_FUNCTION(mcrypt) /* {{{ */
        !           481: {
        !           482:        php_stream_filter_unregister_factory("mcrypt.*" TSRMLS_CC);
        !           483:        php_stream_filter_unregister_factory("mdecrypt.*" TSRMLS_CC);
        !           484: 
        !           485:        UNREGISTER_INI_ENTRIES();
        !           486:        return SUCCESS;
        !           487: }
        !           488: /* }}} */
        !           489: 
        !           490: #include "ext/standard/php_smart_str.h"
        !           491: 
        !           492: PHP_MINFO_FUNCTION(mcrypt) /* {{{ */
        !           493: {
        !           494:        char **modules;
        !           495:        char mcrypt_api_no[16];
        !           496:        int i, count;
        !           497:        smart_str tmp1 = {0};
        !           498:        smart_str tmp2 = {0};
        !           499: 
        !           500:        modules = mcrypt_list_algorithms(MCG(algorithms_dir), &count);
        !           501:        if (count == 0) {
        !           502:                smart_str_appends(&tmp1, "none");
        !           503:        }
        !           504:        for (i = 0; i < count; i++) {
        !           505:                smart_str_appends(&tmp1, modules[i]);
        !           506:                smart_str_appendc(&tmp1, ' ');
        !           507:        }
        !           508:        smart_str_0(&tmp1);
        !           509:        mcrypt_free_p(modules, count);
        !           510: 
        !           511:        modules = mcrypt_list_modes(MCG(modes_dir), &count);
        !           512:        if (count == 0) {
        !           513:                smart_str_appends(&tmp2, "none");
        !           514:        }
        !           515:        for (i = 0; i < count; i++) {
        !           516:                smart_str_appends(&tmp2, modules[i]);
        !           517:                smart_str_appendc(&tmp2, ' ');
        !           518:        }
        !           519:        smart_str_0 (&tmp2);
        !           520:        mcrypt_free_p (modules, count);
        !           521: 
        !           522:        snprintf (mcrypt_api_no, 16, "%d", MCRYPT_API_VERSION);
        !           523: 
        !           524:        php_info_print_table_start();
        !           525:        php_info_print_table_header(2, "mcrypt support", "enabled");
        !           526:        php_info_print_table_header(2, "mcrypt_filter support", "enabled");
        !           527:        php_info_print_table_row(2, "Version", LIBMCRYPT_VERSION);
        !           528:        php_info_print_table_row(2, "Api No", mcrypt_api_no);
        !           529:        php_info_print_table_row(2, "Supported ciphers", tmp1.c);
        !           530:        php_info_print_table_row(2, "Supported modes", tmp2.c);
        !           531:        smart_str_free(&tmp1);
        !           532:        smart_str_free(&tmp2);
        !           533:        php_info_print_table_end();
        !           534:        
        !           535:        DISPLAY_INI_ENTRIES();
        !           536: }
        !           537: /* }}} */
        !           538: 
        !           539: typedef enum {
        !           540:        RANDOM = 0,
        !           541:        URANDOM,
        !           542:        RAND
        !           543: } iv_source;
        !           544: 
        !           545: /* {{{ proto resource mcrypt_module_open(string cipher, string cipher_directory, string mode, string mode_directory)
        !           546:    Opens the module of the algorithm and the mode to be used */
        !           547: PHP_FUNCTION(mcrypt_module_open)
        !           548: {
        !           549:        char *cipher, *cipher_dir;
        !           550:        char *mode,   *mode_dir;
        !           551:        int   cipher_len, cipher_dir_len;
        !           552:        int   mode_len,   mode_dir_len;
        !           553:        MCRYPT td;
        !           554:        php_mcrypt *pm;
        !           555:    
        !           556:        if (zend_parse_parameters (ZEND_NUM_ARGS() TSRMLS_CC, "ssss",
        !           557:                &cipher, &cipher_len, &cipher_dir, &cipher_dir_len,
        !           558:                &mode,   &mode_len,   &mode_dir,   &mode_dir_len)) {
        !           559:                return;
        !           560:        }
        !           561:        
        !           562:        td = mcrypt_module_open (
        !           563:                cipher,
        !           564:                cipher_dir_len > 0 ? cipher_dir : MCG(algorithms_dir),
        !           565:                mode, 
        !           566:                mode_dir_len > 0 ? mode_dir : MCG(modes_dir)
        !           567:        );
        !           568: 
        !           569:        if (td == MCRYPT_FAILED) {
        !           570:                php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not open encryption module");
        !           571:                RETURN_FALSE;
        !           572:        } else {
        !           573:                pm = emalloc(sizeof(php_mcrypt));
        !           574:                pm->td = td;
        !           575:                pm->init = 0;
        !           576:                ZEND_REGISTER_RESOURCE(return_value, pm, le_mcrypt);
        !           577:        }
        !           578: }
        !           579: /* }}} */
        !           580: 
        !           581: /* {{{ proto int mcrypt_generic_init(resource td, string key, string iv)
        !           582:    This function initializes all buffers for the specific module */
        !           583: PHP_FUNCTION(mcrypt_generic_init)
        !           584: {
        !           585:        char *key, *iv;
        !           586:        int key_len, iv_len;
        !           587:        zval *mcryptind;
        !           588:        unsigned char *key_s, *iv_s;
        !           589:        int max_key_size, key_size, iv_size;
        !           590:        php_mcrypt *pm;
        !           591:        int result = 0;
        !           592:        
        !           593:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rss", &mcryptind, &key, &key_len, &iv, &iv_len) == FAILURE) {
        !           594:                return;
        !           595:        }
        !           596: 
        !           597:        ZEND_FETCH_RESOURCE(pm, php_mcrypt *, &mcryptind, -1, "MCrypt", le_mcrypt);
        !           598: 
        !           599:        max_key_size = mcrypt_enc_get_key_size(pm->td);
        !           600:        iv_size = mcrypt_enc_get_iv_size(pm->td);
        !           601: 
        !           602:        if (key_len == 0) {
        !           603:                php_error_docref(NULL TSRMLS_CC, E_WARNING, "Key size is 0");
        !           604:        }
        !           605: 
        !           606:        key_s = emalloc(key_len);
        !           607:        memset(key_s, 0, key_len);
        !           608: 
        !           609:        iv_s = emalloc(iv_size + 1);
        !           610:        memset(iv_s, 0, iv_size + 1);
        !           611: 
        !           612:        if (key_len > max_key_size) {
        !           613:                php_error_docref(NULL TSRMLS_CC, E_WARNING, "Key size too large; supplied length: %d, max: %d", key_len, max_key_size);
        !           614:                key_size = max_key_size;
        !           615:        } else {
        !           616:                key_size = key_len;
        !           617:        }
        !           618:        memcpy(key_s, key, key_len);
        !           619: 
        !           620:        if (iv_len != iv_size) {
        !           621:                php_error_docref(NULL TSRMLS_CC, E_WARNING, "Iv size incorrect; supplied length: %d, needed: %d", iv_len, iv_size);
        !           622:        }
        !           623:        memcpy(iv_s, iv, iv_size);
        !           624: 
        !           625:        mcrypt_generic_deinit(pm->td);
        !           626:        result = mcrypt_generic_init(pm->td, key_s, key_size, iv_s);
        !           627: 
        !           628:        /* If this function fails, close the mcrypt module to prevent crashes
        !           629:         * when further functions want to access this resource */
        !           630:        if (result < 0) {
        !           631:                zend_list_delete(Z_LVAL_P(mcryptind));
        !           632:                switch (result) {
        !           633:                        case -3:
        !           634:                                php_error_docref(NULL TSRMLS_CC, E_WARNING, "Key length incorrect");
        !           635:                                break;
        !           636:                        case -4:
        !           637:                                php_error_docref(NULL TSRMLS_CC, E_WARNING, "Memory allocation error");
        !           638:                                break;
        !           639:                        case -1:
        !           640:                        default:
        !           641:                                php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unknown error");
        !           642:                                break;
        !           643:                }
        !           644:        }
        !           645:        pm->init = 1;
        !           646:        RETVAL_LONG(result);
        !           647: 
        !           648:        efree(iv_s);
        !           649:        efree(key_s);
        !           650: }
        !           651: /* }}} */
        !           652: 
        !           653: /* {{{ proto string mcrypt_generic(resource td, string data)
        !           654:    This function encrypts the plaintext */
        !           655: PHP_FUNCTION(mcrypt_generic)
        !           656: {
        !           657:        zval *mcryptind;
        !           658:        char *data;
        !           659:        int data_len;
        !           660:        php_mcrypt *pm;
        !           661:        unsigned char* data_s;
        !           662:        int block_size, data_size;
        !           663: 
        !           664:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs", &mcryptind, &data, &data_len) == FAILURE) {
        !           665:                return;
        !           666:        }
        !           667:        
        !           668:        ZEND_FETCH_RESOURCE(pm, php_mcrypt *, &mcryptind, -1, "MCrypt", le_mcrypt);
        !           669:        PHP_MCRYPT_INIT_CHECK
        !           670: 
        !           671:        if (data_len == 0) {
        !           672:                php_error_docref(NULL TSRMLS_CC, E_WARNING, "An empty string was passed");
        !           673:                RETURN_FALSE
        !           674:        }
        !           675: 
        !           676:        /* Check blocksize */
        !           677:        if (mcrypt_enc_is_block_mode(pm->td) == 1) { /* It's a block algorithm */
        !           678:                block_size = mcrypt_enc_get_block_size(pm->td);
        !           679:                data_size = (((data_len - 1) / block_size) + 1) * block_size;
        !           680:                data_s = emalloc(data_size + 1);
        !           681:                memset(data_s, 0, data_size);
        !           682:                memcpy(data_s, data, data_len);
        !           683:        } else { /* It's not a block algorithm */
        !           684:                data_size = data_len;
        !           685:                data_s = emalloc(data_size + 1);
        !           686:                memset(data_s, 0, data_size);
        !           687:                memcpy(data_s, data, data_len);
        !           688:        }
        !           689:        
        !           690:        mcrypt_generic(pm->td, data_s, data_size);
        !           691:        data_s[data_size] = '\0';
        !           692: 
        !           693:        RETVAL_STRINGL(data_s, data_size, 1);
        !           694:        efree(data_s);
        !           695: }
        !           696: /* }}} */
        !           697: 
        !           698: /* {{{ proto string mdecrypt_generic(resource td, string data)
        !           699:    This function decrypts the plaintext */
        !           700: PHP_FUNCTION(mdecrypt_generic)
        !           701: {
        !           702:        zval *mcryptind;
        !           703:        char *data;
        !           704:        int data_len;
        !           705:        php_mcrypt *pm;
        !           706:        char* data_s;
        !           707:        int block_size, data_size;
        !           708:        
        !           709:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs", &mcryptind, &data, &data_len) == FAILURE) {
        !           710:                return;
        !           711:        }
        !           712:        
        !           713:        ZEND_FETCH_RESOURCE(pm, php_mcrypt * , &mcryptind, -1, "MCrypt", le_mcrypt);
        !           714:        PHP_MCRYPT_INIT_CHECK
        !           715: 
        !           716:        if (data_len == 0) {
        !           717:                php_error_docref(NULL TSRMLS_CC, E_WARNING, "An empty string was passed");
        !           718:                RETURN_FALSE
        !           719:        }
        !           720: 
        !           721:        /* Check blocksize */
        !           722:        if (mcrypt_enc_is_block_mode(pm->td) == 1) { /* It's a block algorithm */
        !           723:                block_size = mcrypt_enc_get_block_size(pm->td);
        !           724:                data_size = (((data_len - 1) / block_size) + 1) * block_size;
        !           725:                data_s = emalloc(data_size + 1);
        !           726:                memset(data_s, 0, data_size);
        !           727:                memcpy(data_s, data, data_len);
        !           728:        } else { /* It's not a block algorithm */
        !           729:                data_size = data_len;
        !           730:                data_s = emalloc(data_size + 1);
        !           731:                memset(data_s, 0, data_size);
        !           732:                memcpy(data_s, data, data_len);
        !           733:        }
        !           734:        
        !           735:        mdecrypt_generic(pm->td, data_s, data_size);
        !           736: 
        !           737:        RETVAL_STRINGL(data_s, data_size, 1);
        !           738:        efree(data_s);
        !           739: }
        !           740: /* }}} */
        !           741: 
        !           742: /* {{{ proto array mcrypt_enc_get_supported_key_sizes(resource td)
        !           743:    This function decrypts the crypttext */
        !           744: PHP_FUNCTION(mcrypt_enc_get_supported_key_sizes)
        !           745: {
        !           746:        int i, count = 0;
        !           747:        int *key_sizes;
        !           748:        
        !           749:        MCRYPT_GET_TD_ARG
        !           750:        array_init(return_value);
        !           751: 
        !           752:        key_sizes = mcrypt_enc_get_supported_key_sizes(pm->td, &count);
        !           753: 
        !           754:        for (i = 0; i < count; i++) {
        !           755:                add_index_long(return_value, i, key_sizes[i]);
        !           756:        }
        !           757: 
        !           758:        mcrypt_free(key_sizes);
        !           759: }
        !           760: /* }}} */
        !           761: 
        !           762: /* {{{ proto int mcrypt_enc_self_test(resource td)
        !           763:    This function runs the self test on the algorithm specified by the descriptor td */
        !           764: PHP_FUNCTION(mcrypt_enc_self_test)
        !           765: {
        !           766:        MCRYPT_GET_TD_ARG
        !           767:        RETURN_LONG(mcrypt_enc_self_test(pm->td));
        !           768: }
        !           769: /* }}} */
        !           770: 
        !           771: /* {{{ proto bool mcrypt_module_close(resource td)
        !           772:    Free the descriptor td */
        !           773: PHP_FUNCTION(mcrypt_module_close)
        !           774: {
        !           775:        MCRYPT_GET_TD_ARG
        !           776:        zend_list_delete(Z_LVAL_P(mcryptind));
        !           777:        RETURN_TRUE;
        !           778: }
        !           779: /* }}} */
        !           780: 
        !           781: /* {{{ proto bool mcrypt_generic_deinit(resource td)
        !           782:    This function terminates encrypt specified by the descriptor td */
        !           783: PHP_FUNCTION(mcrypt_generic_deinit)
        !           784: {
        !           785:        MCRYPT_GET_TD_ARG
        !           786: 
        !           787:        if (mcrypt_generic_deinit(pm->td) < 0) {
        !           788:                php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not terminate encryption specifier");
        !           789:                RETURN_FALSE
        !           790:        }
        !           791:        pm->init = 0;
        !           792:        RETURN_TRUE
        !           793: }
        !           794: /* }}} */
        !           795: 
        !           796: /* {{{ proto bool mcrypt_enc_is_block_algorithm_mode(resource td)
        !           797:    Returns TRUE if the mode is for use with block algorithms */
        !           798: PHP_FUNCTION(mcrypt_enc_is_block_algorithm_mode)
        !           799: {
        !           800:        MCRYPT_GET_TD_ARG
        !           801: 
        !           802:        if (mcrypt_enc_is_block_algorithm_mode(pm->td) == 1) {
        !           803:                RETURN_TRUE
        !           804:        } else {
        !           805:                RETURN_FALSE
        !           806:        }
        !           807: }
        !           808: /* }}} */
        !           809: 
        !           810: /* {{{ proto bool mcrypt_enc_is_block_algorithm(resource td)
        !           811:    Returns TRUE if the alrogithm is a block algorithms */
        !           812: PHP_FUNCTION(mcrypt_enc_is_block_algorithm)
        !           813: {
        !           814:        MCRYPT_GET_TD_ARG
        !           815: 
        !           816:        if (mcrypt_enc_is_block_algorithm(pm->td) == 1) {
        !           817:                RETURN_TRUE 
        !           818:        } else {
        !           819:                RETURN_FALSE
        !           820:        }
        !           821: }
        !           822: /* }}} */
        !           823: 
        !           824: /* {{{ proto bool mcrypt_enc_is_block_mode(resource td)
        !           825:    Returns TRUE if the mode outputs blocks */
        !           826: PHP_FUNCTION(mcrypt_enc_is_block_mode)
        !           827: {
        !           828:        MCRYPT_GET_TD_ARG
        !           829: 
        !           830:        if (mcrypt_enc_is_block_mode(pm->td) == 1) {
        !           831:                RETURN_TRUE
        !           832:        } else {
        !           833:                RETURN_FALSE
        !           834:        }
        !           835: }
        !           836: /* }}} */
        !           837: 
        !           838: /* {{{ proto int mcrypt_enc_get_block_size(resource td)
        !           839:    Returns the block size of the cipher specified by the descriptor td */
        !           840: PHP_FUNCTION(mcrypt_enc_get_block_size)
        !           841: {
        !           842:        MCRYPT_GET_TD_ARG
        !           843:        RETURN_LONG(mcrypt_enc_get_block_size(pm->td));
        !           844: }
        !           845: /* }}} */
        !           846: 
        !           847: /* {{{ proto int mcrypt_enc_get_key_size(resource td)
        !           848:    Returns the maximum supported key size in bytes of the algorithm specified by the descriptor td */
        !           849: PHP_FUNCTION(mcrypt_enc_get_key_size)
        !           850: {
        !           851:        MCRYPT_GET_TD_ARG
        !           852:        RETURN_LONG(mcrypt_enc_get_key_size(pm->td));
        !           853: }
        !           854: /* }}} */
        !           855: 
        !           856: /* {{{ proto int mcrypt_enc_get_iv_size(resource td)
        !           857:    Returns the size of the IV in bytes of the algorithm specified by the descriptor td */
        !           858: PHP_FUNCTION(mcrypt_enc_get_iv_size)
        !           859: {
        !           860:        MCRYPT_GET_TD_ARG
        !           861:        RETURN_LONG(mcrypt_enc_get_iv_size(pm->td));
        !           862: }
        !           863: /* }}} */
        !           864: 
        !           865: /* {{{ proto string mcrypt_enc_get_algorithms_name(resource td)
        !           866:    Returns the name of the algorithm specified by the descriptor td */
        !           867: PHP_FUNCTION(mcrypt_enc_get_algorithms_name)
        !           868: {
        !           869:        char *name;
        !           870:        MCRYPT_GET_TD_ARG
        !           871: 
        !           872:        name = mcrypt_enc_get_algorithms_name(pm->td);
        !           873:        RETVAL_STRING(name, 1);
        !           874:        mcrypt_free(name);
        !           875: }
        !           876: /* }}} */
        !           877: 
        !           878: /* {{{ proto string mcrypt_enc_get_modes_name(resource td)
        !           879:    Returns the name of the mode specified by the descriptor td */
        !           880: PHP_FUNCTION(mcrypt_enc_get_modes_name)
        !           881: {
        !           882:        char *name;
        !           883:        MCRYPT_GET_TD_ARG
        !           884: 
        !           885:        name = mcrypt_enc_get_modes_name(pm->td);
        !           886:        RETVAL_STRING(name, 1);
        !           887:        mcrypt_free(name);
        !           888: }
        !           889: /* }}} */
        !           890: 
        !           891: /* {{{ proto bool mcrypt_module_self_test(string algorithm [, string lib_dir])
        !           892:    Does a self test of the module "module" */
        !           893: PHP_FUNCTION(mcrypt_module_self_test)
        !           894: {
        !           895:        MCRYPT_GET_MODE_DIR_ARGS(algorithms_dir);
        !           896:        
        !           897:        if (mcrypt_module_self_test(module, dir) == 0) {
        !           898:                RETURN_TRUE;
        !           899:        } else {
        !           900:                RETURN_FALSE;
        !           901:        }
        !           902: }
        !           903: /* }}} */
        !           904: 
        !           905: /* {{{ proto bool mcrypt_module_is_block_algorithm_mode(string mode [, string lib_dir])
        !           906:    Returns TRUE if the mode is for use with block algorithms */
        !           907: PHP_FUNCTION(mcrypt_module_is_block_algorithm_mode)
        !           908: {
        !           909:        MCRYPT_GET_MODE_DIR_ARGS(modes_dir)
        !           910:        
        !           911:        if (mcrypt_module_is_block_algorithm_mode(module, dir) == 1) {
        !           912:                RETURN_TRUE;
        !           913:        } else {
        !           914:                RETURN_FALSE;
        !           915:        }
        !           916: }
        !           917: /* }}} */
        !           918: 
        !           919: /* {{{ proto bool mcrypt_module_is_block_algorithm(string algorithm [, string lib_dir])
        !           920:    Returns TRUE if the algorithm is a block algorithm */
        !           921: PHP_FUNCTION(mcrypt_module_is_block_algorithm)
        !           922: {
        !           923:        MCRYPT_GET_MODE_DIR_ARGS(algorithms_dir)
        !           924:        
        !           925:        if (mcrypt_module_is_block_algorithm(module, dir) == 1) {
        !           926:                RETURN_TRUE;
        !           927:        } else {
        !           928:                RETURN_FALSE;
        !           929:        }
        !           930: }
        !           931: /* }}} */
        !           932: 
        !           933: /* {{{ proto bool mcrypt_module_is_block_mode(string mode [, string lib_dir])
        !           934:    Returns TRUE if the mode outputs blocks of bytes */
        !           935: PHP_FUNCTION(mcrypt_module_is_block_mode)
        !           936: {
        !           937:        MCRYPT_GET_MODE_DIR_ARGS(modes_dir)
        !           938:        
        !           939:        if (mcrypt_module_is_block_mode(module, dir) == 1) {
        !           940:                RETURN_TRUE;
        !           941:        } else {
        !           942:                RETURN_FALSE;
        !           943:        }
        !           944: }
        !           945: /* }}} */
        !           946: 
        !           947: /* {{{ proto int mcrypt_module_get_algo_block_size(string algorithm [, string lib_dir])
        !           948:    Returns the block size of the algorithm */
        !           949: PHP_FUNCTION(mcrypt_module_get_algo_block_size)
        !           950: {
        !           951:        MCRYPT_GET_MODE_DIR_ARGS(algorithms_dir)
        !           952:        
        !           953:        RETURN_LONG(mcrypt_module_get_algo_block_size(module, dir));
        !           954: }
        !           955: /* }}} */
        !           956: 
        !           957: /* {{{ proto int mcrypt_module_get_algo_key_size(string algorithm [, string lib_dir])
        !           958:    Returns the maximum supported key size of the algorithm */
        !           959: PHP_FUNCTION(mcrypt_module_get_algo_key_size)
        !           960: {
        !           961:        MCRYPT_GET_MODE_DIR_ARGS(algorithms_dir);
        !           962:        
        !           963:        RETURN_LONG(mcrypt_module_get_algo_key_size(module, dir));
        !           964: }
        !           965: /* }}} */
        !           966: 
        !           967: /* {{{ proto array mcrypt_module_get_supported_key_sizes(string algorithm [, string lib_dir])
        !           968:    This function decrypts the crypttext */
        !           969: PHP_FUNCTION(mcrypt_module_get_supported_key_sizes)
        !           970: {
        !           971:        int i, count = 0;
        !           972:        int *key_sizes;
        !           973:        
        !           974:        MCRYPT_GET_MODE_DIR_ARGS(algorithms_dir)
        !           975:        array_init(return_value);
        !           976: 
        !           977:        key_sizes = mcrypt_module_get_algo_supported_key_sizes(module, dir, &count);
        !           978: 
        !           979:        for (i = 0; i < count; i++) {
        !           980:                add_index_long(return_value, i, key_sizes[i]);
        !           981:        }
        !           982:        mcrypt_free(key_sizes);
        !           983: }
        !           984: /* }}} */
        !           985: 
        !           986: /* {{{ proto array mcrypt_list_algorithms([string lib_dir])
        !           987:    List all algorithms in "module_dir" */
        !           988: PHP_FUNCTION(mcrypt_list_algorithms)
        !           989: {
        !           990:        char **modules;
        !           991:        char *lib_dir = MCG(algorithms_dir);
        !           992:        int   lib_dir_len;
        !           993:        int   i, count;
        !           994: 
        !           995:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|s",
        !           996:                &lib_dir, &lib_dir_len) == FAILURE) {
        !           997:                return;
        !           998:        }
        !           999:        
        !          1000:        array_init(return_value);
        !          1001:        modules = mcrypt_list_algorithms(lib_dir, &count);
        !          1002: 
        !          1003:        if (count == 0) {
        !          1004:                php_error_docref(NULL TSRMLS_CC, E_WARNING, "No algorithms found in module dir");
        !          1005:        }
        !          1006:        for (i = 0; i < count; i++) {
        !          1007:                add_index_string(return_value, i, modules[i], 1);
        !          1008:        }
        !          1009:        mcrypt_free_p(modules, count);
        !          1010: }
        !          1011: /* }}} */
        !          1012: 
        !          1013: /* {{{ proto array mcrypt_list_modes([string lib_dir])
        !          1014:    List all modes "module_dir" */
        !          1015: PHP_FUNCTION(mcrypt_list_modes)
        !          1016: {
        !          1017:        char **modules;
        !          1018:        char *lib_dir = MCG(modes_dir);
        !          1019:        int   lib_dir_len;
        !          1020:        int   i, count;
        !          1021: 
        !          1022:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|s",
        !          1023:                &lib_dir, &lib_dir_len) == FAILURE) {
        !          1024:                return;
        !          1025:        }
        !          1026: 
        !          1027:        array_init(return_value);
        !          1028:        modules = mcrypt_list_modes(lib_dir, &count);
        !          1029: 
        !          1030:        if (count == 0) {
        !          1031:                php_error_docref(NULL TSRMLS_CC, E_WARNING, "No modes found in module dir");
        !          1032:        }
        !          1033:        for (i = 0; i < count; i++) {
        !          1034:                add_index_string(return_value, i, modules[i], 1);
        !          1035:        }
        !          1036:        mcrypt_free_p(modules, count);
        !          1037: }
        !          1038: /* }}} */
        !          1039: 
        !          1040: /* {{{ proto int mcrypt_get_key_size(string cipher, string module)
        !          1041:    Get the key size of cipher */
        !          1042: PHP_FUNCTION(mcrypt_get_key_size)
        !          1043: {
        !          1044:        char *cipher;
        !          1045:        char *module;
        !          1046:        int   cipher_len, module_len; 
        !          1047:        char *cipher_dir_string;
        !          1048:        char *module_dir_string;
        !          1049:        MCRYPT td;
        !          1050: 
        !          1051:        MCRYPT_GET_INI
        !          1052: 
        !          1053:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss",
        !          1054:                &cipher, &cipher_len, &module, &module_len) == FAILURE) {
        !          1055:                return;
        !          1056:        }
        !          1057:        
        !          1058:        td = mcrypt_module_open(cipher, cipher_dir_string, module, module_dir_string);
        !          1059:        if (td != MCRYPT_FAILED) {
        !          1060:                RETVAL_LONG(mcrypt_enc_get_key_size(td));
        !          1061:                mcrypt_module_close(td);
        !          1062:        } else {
        !          1063:                php_error_docref(NULL TSRMLS_CC, E_WARNING, MCRYPT_OPEN_MODULE_FAILED);
        !          1064:                RETURN_FALSE;
        !          1065:        }
        !          1066: }
        !          1067: /* }}} */
        !          1068: 
        !          1069: /* {{{ proto int mcrypt_get_block_size(string cipher, string module)
        !          1070:    Get the key size of cipher */
        !          1071: PHP_FUNCTION(mcrypt_get_block_size)
        !          1072: {
        !          1073:        char *cipher;
        !          1074:        char *module;
        !          1075:        int   cipher_len, module_len; 
        !          1076:        char *cipher_dir_string;
        !          1077:        char *module_dir_string;
        !          1078:        MCRYPT td;
        !          1079: 
        !          1080:        MCRYPT_GET_INI
        !          1081: 
        !          1082:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss",
        !          1083:                &cipher, &cipher_len, &module, &module_len) == FAILURE) {
        !          1084:                return;
        !          1085:        }
        !          1086:        
        !          1087:        td = mcrypt_module_open(cipher, cipher_dir_string, module, module_dir_string);
        !          1088:        if (td != MCRYPT_FAILED) {
        !          1089:                RETVAL_LONG(mcrypt_enc_get_block_size(td));
        !          1090:                mcrypt_module_close(td);
        !          1091:        } else {
        !          1092:                php_error_docref(NULL TSRMLS_CC, E_WARNING, MCRYPT_OPEN_MODULE_FAILED);
        !          1093:                RETURN_FALSE;
        !          1094:        }
        !          1095: }
        !          1096: /* }}} */
        !          1097: 
        !          1098: /* {{{ proto int mcrypt_get_iv_size(string cipher, string module)
        !          1099:    Get the IV size of cipher (Usually the same as the blocksize) */
        !          1100: PHP_FUNCTION(mcrypt_get_iv_size)
        !          1101: {
        !          1102:        char *cipher;
        !          1103:        char *module;
        !          1104:        int   cipher_len, module_len; 
        !          1105:        char *cipher_dir_string;
        !          1106:        char *module_dir_string;
        !          1107:        MCRYPT td;
        !          1108: 
        !          1109:        MCRYPT_GET_INI
        !          1110: 
        !          1111:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss",
        !          1112:                &cipher, &cipher_len, &module, &module_len) == FAILURE) {
        !          1113:                return;
        !          1114:        }
        !          1115:        
        !          1116:        td = mcrypt_module_open(cipher, cipher_dir_string, module, module_dir_string);
        !          1117:        if (td != MCRYPT_FAILED) {
        !          1118:                RETVAL_LONG(mcrypt_enc_get_iv_size(td));
        !          1119:                mcrypt_module_close(td);
        !          1120:        } else {
        !          1121:                php_error_docref(NULL TSRMLS_CC, E_WARNING, MCRYPT_OPEN_MODULE_FAILED);
        !          1122:                RETURN_FALSE;
        !          1123:        }
        !          1124: }
        !          1125: /* }}} */
        !          1126: 
        !          1127: /* {{{ proto string mcrypt_get_cipher_name(string cipher)
        !          1128:    Get the key size of cipher */
        !          1129: PHP_FUNCTION(mcrypt_get_cipher_name)
        !          1130: {
        !          1131:        char *cipher_dir_string;
        !          1132:        char *module_dir_string;
        !          1133:        char *cipher_name;
        !          1134:        char *cipher;
        !          1135:        int   cipher_len;
        !          1136:        MCRYPT td;
        !          1137: 
        !          1138:        MCRYPT_GET_INI
        !          1139: 
        !          1140:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s",
        !          1141:                &cipher, &cipher_len) == FAILURE) {
        !          1142:                return;
        !          1143:        }
        !          1144: 
        !          1145:        /* The code below is actually not very nice, but I didn't see a better
        !          1146:         * method */
        !          1147:        td = mcrypt_module_open(cipher, cipher_dir_string, "ecb", module_dir_string);
        !          1148:        if (td != MCRYPT_FAILED) {
        !          1149:                cipher_name = mcrypt_enc_get_algorithms_name(td);
        !          1150:                mcrypt_module_close(td);
        !          1151:                RETVAL_STRING(cipher_name,1);
        !          1152:                mcrypt_free(cipher_name);
        !          1153:        } else {
        !          1154:                td = mcrypt_module_open(cipher, cipher_dir_string, "stream", module_dir_string);
        !          1155:                if (td != MCRYPT_FAILED) {
        !          1156:                        cipher_name = mcrypt_enc_get_algorithms_name(td);
        !          1157:                        mcrypt_module_close(td);
        !          1158:                        RETVAL_STRING(cipher_name,1);
        !          1159:                        mcrypt_free(cipher_name);
        !          1160:                } else {
        !          1161:                        php_error_docref(NULL TSRMLS_CC, E_WARNING, MCRYPT_OPEN_MODULE_FAILED);
        !          1162:                        RETURN_FALSE;
        !          1163:                }
        !          1164:        }
        !          1165: }
        !          1166: /* }}} */
        !          1167: 
        !          1168: static void php_mcrypt_do_crypt(char* cipher, const char *key, int key_len, const char *data, int data_len, char *mode, const char *iv, int iv_len, int argc, int dencrypt, zval* return_value TSRMLS_DC) /* {{{ */
        !          1169: {
        !          1170:        char *cipher_dir_string;
        !          1171:        char *module_dir_string;
        !          1172:        int block_size, max_key_length, use_key_length, i, count, iv_size;
        !          1173:        unsigned long int data_size;
        !          1174:        int *key_length_sizes;
        !          1175:        char *key_s = NULL, *iv_s;
        !          1176:        char *data_s;
        !          1177:        MCRYPT td;
        !          1178: 
        !          1179:        MCRYPT_GET_INI
        !          1180: 
        !          1181:        td = mcrypt_module_open(cipher, cipher_dir_string, mode, module_dir_string);
        !          1182:        if (td == MCRYPT_FAILED) {
        !          1183:                php_error_docref(NULL TSRMLS_CC, E_WARNING, MCRYPT_OPEN_MODULE_FAILED);
        !          1184:                RETURN_FALSE;
        !          1185:        }
        !          1186:        /* Checking for key-length */
        !          1187:        max_key_length = mcrypt_enc_get_key_size(td);
        !          1188:        if (key_len > max_key_length) {
        !          1189:                php_error_docref(NULL TSRMLS_CC, E_WARNING, "Size of key is too large for this algorithm");
        !          1190:        }
        !          1191:        key_length_sizes = mcrypt_enc_get_supported_key_sizes(td, &count);
        !          1192:        if (count == 0 && key_length_sizes == NULL) { /* all lengths 1 - k_l_s = OK */
        !          1193:                use_key_length = key_len;
        !          1194:                key_s = emalloc(use_key_length);
        !          1195:                memset(key_s, 0, use_key_length);
        !          1196:                memcpy(key_s, key, use_key_length);
        !          1197:        } else if (count == 1) {  /* only m_k_l = OK */
        !          1198:                key_s = emalloc(key_length_sizes[0]);
        !          1199:                memset(key_s, 0, key_length_sizes[0]);
        !          1200:                memcpy(key_s, key, MIN(key_len, key_length_sizes[0]));
        !          1201:                use_key_length = key_length_sizes[0];
        !          1202:        } else { /* dertermine smallest supported key > length of requested key */
        !          1203:                use_key_length = max_key_length; /* start with max key length */
        !          1204:                for (i = 0; i < count; i++) {
        !          1205:                        if (key_length_sizes[i] >= key_len && 
        !          1206:                                key_length_sizes[i] < use_key_length)
        !          1207:                        {
        !          1208:                                use_key_length = key_length_sizes[i];
        !          1209:                        }
        !          1210:                }
        !          1211:                key_s = emalloc(use_key_length);
        !          1212:                memset(key_s, 0, use_key_length);
        !          1213:                memcpy(key_s, key, MIN(key_len, use_key_length));
        !          1214:        }
        !          1215:        mcrypt_free (key_length_sizes);
        !          1216:        
        !          1217:        /* Check IV */
        !          1218:        iv_s = NULL;
        !          1219:        iv_size = mcrypt_enc_get_iv_size (td);
        !          1220:        
        !          1221:        /* IV is required */
        !          1222:        if (mcrypt_enc_mode_has_iv(td) == 1) {
        !          1223:                if (argc == 5) {
        !          1224:                        if (iv_size != iv_len) {
        !          1225:                                php_error_docref(NULL TSRMLS_CC, E_WARNING, MCRYPT_IV_WRONG_SIZE);
        !          1226:                        } else {
        !          1227:                                iv_s = emalloc(iv_size + 1);
        !          1228:                                memcpy(iv_s, iv, iv_size);
        !          1229:                        }
        !          1230:                } else if (argc == 4) {
        !          1231:                        php_error_docref(NULL TSRMLS_CC, E_WARNING, "Attempt to use an empty IV, which is NOT recommend");
        !          1232:                        iv_s = emalloc(iv_size + 1);
        !          1233:                        memset(iv_s, 0, iv_size + 1);
        !          1234:                }
        !          1235:        }
        !          1236: 
        !          1237:        /* Check blocksize */
        !          1238:        if (mcrypt_enc_is_block_mode(td) == 1) { /* It's a block algorithm */
        !          1239:                block_size = mcrypt_enc_get_block_size(td);
        !          1240:                data_size = (((data_len - 1) / block_size) + 1) * block_size;
        !          1241:                data_s = emalloc(data_size);
        !          1242:                memset(data_s, 0, data_size);
        !          1243:                memcpy(data_s, data, data_len);
        !          1244:        } else { /* It's not a block algorithm */
        !          1245:                data_size = data_len;
        !          1246:                data_s = emalloc(data_size);
        !          1247:                memset(data_s, 0, data_size);
        !          1248:                memcpy(data_s, data, data_len);
        !          1249:        }
        !          1250: 
        !          1251:        if (mcrypt_generic_init(td, key_s, use_key_length, iv_s) < 0) {
        !          1252:                php_error_docref(NULL TSRMLS_CC, E_RECOVERABLE_ERROR, "Mcrypt initialisation failed");
        !          1253:                RETURN_FALSE;
        !          1254:        }
        !          1255:        if (dencrypt == MCRYPT_ENCRYPT) {
        !          1256:                mcrypt_generic(td, data_s, data_size);
        !          1257:        } else {
        !          1258:                mdecrypt_generic(td, data_s, data_size);
        !          1259:        }
        !          1260:        
        !          1261:        RETVAL_STRINGL(data_s, data_size, 1);
        !          1262: 
        !          1263:        /* freeing vars */
        !          1264:        mcrypt_generic_end(td);
        !          1265:        if (key_s != NULL) {
        !          1266:                efree (key_s);
        !          1267:        }
        !          1268:        if (iv_s != NULL) {
        !          1269:                efree (iv_s);
        !          1270:        }
        !          1271:        efree (data_s);
        !          1272: }
        !          1273: /* }}} */
        !          1274: 
        !          1275: /* {{{ proto string mcrypt_encrypt(string cipher, string key, string data, string mode, string iv)
        !          1276:    OFB crypt/decrypt data using key key with cipher cipher starting with iv */
        !          1277: PHP_FUNCTION(mcrypt_encrypt)
        !          1278: {
        !          1279:        zval **mode;
        !          1280:        char *cipher, *key, *data, *iv = NULL;
        !          1281:        int cipher_len, key_len, data_len, iv_len = 0;
        !          1282:        
        !          1283:        MCRYPT_GET_CRYPT_ARGS
        !          1284:        
        !          1285:        convert_to_string_ex(mode);
        !          1286: 
        !          1287:        php_mcrypt_do_crypt(cipher, key, key_len, data, data_len, Z_STRVAL_PP(mode), iv, iv_len, ZEND_NUM_ARGS(), MCRYPT_ENCRYPT, return_value TSRMLS_CC);
        !          1288: }
        !          1289: /* }}} */
        !          1290: 
        !          1291: /* {{{ proto string mcrypt_decrypt(string cipher, string key, string data, string mode, string iv)
        !          1292:    OFB crypt/decrypt data using key key with cipher cipher starting with iv */
        !          1293: PHP_FUNCTION(mcrypt_decrypt)
        !          1294: {
        !          1295:        zval **mode;
        !          1296:        char *cipher, *key, *data, *iv = NULL;
        !          1297:        int cipher_len, key_len, data_len, iv_len = 0;
        !          1298: 
        !          1299:        MCRYPT_GET_CRYPT_ARGS
        !          1300:        
        !          1301:        convert_to_string_ex(mode);
        !          1302: 
        !          1303:        php_mcrypt_do_crypt(cipher, key, key_len, data, data_len, Z_STRVAL_PP(mode), iv, iv_len, ZEND_NUM_ARGS(), MCRYPT_DECRYPT, return_value TSRMLS_CC);
        !          1304: }
        !          1305: /* }}} */
        !          1306: 
        !          1307: /* {{{ proto string mcrypt_ecb(int cipher, string key, string data, int mode, string iv)
        !          1308:    ECB crypt/decrypt data using key key with cipher cipher starting with iv */
        !          1309: PHP_FUNCTION(mcrypt_ecb)
        !          1310: {
        !          1311:        zval **mode;
        !          1312:        char *cipher, *key, *data, *iv = NULL;
        !          1313:        int cipher_len, key_len, data_len, iv_len = 0;
        !          1314:        
        !          1315:        MCRYPT_GET_CRYPT_ARGS
        !          1316: 
        !          1317:        convert_to_long_ex(mode);
        !          1318: 
        !          1319:        php_mcrypt_do_crypt(cipher, key, key_len, data, data_len, "ecb", iv, iv_len, ZEND_NUM_ARGS(), Z_LVAL_PP(mode), return_value TSRMLS_CC);
        !          1320: }
        !          1321: /* }}} */
        !          1322: 
        !          1323: /* {{{ proto string mcrypt_cbc(int cipher, string key, string data, int mode, string iv)
        !          1324:    CBC crypt/decrypt data using key key with cipher cipher starting with iv */
        !          1325: PHP_FUNCTION(mcrypt_cbc)
        !          1326: {
        !          1327:        zval **mode;
        !          1328:        char *cipher, *key, *data, *iv = NULL;
        !          1329:        int cipher_len, key_len, data_len, iv_len = 0;
        !          1330: 
        !          1331:        MCRYPT_GET_CRYPT_ARGS
        !          1332: 
        !          1333:        convert_to_long_ex(mode);
        !          1334: 
        !          1335:        php_mcrypt_do_crypt(cipher, key, key_len, data, data_len, "cbc", iv, iv_len, ZEND_NUM_ARGS(), Z_LVAL_PP(mode), return_value TSRMLS_CC);
        !          1336: }
        !          1337: /* }}} */
        !          1338: 
        !          1339: /* {{{ proto string mcrypt_cfb(int cipher, string key, string data, int mode, string iv)
        !          1340:    CFB crypt/decrypt data using key key with cipher cipher starting with iv */
        !          1341: PHP_FUNCTION(mcrypt_cfb)
        !          1342: {
        !          1343:        zval **mode;
        !          1344:        char *cipher, *key, *data, *iv = NULL;
        !          1345:        int cipher_len, key_len, data_len, iv_len = 0;
        !          1346:        
        !          1347:        MCRYPT_GET_CRYPT_ARGS
        !          1348: 
        !          1349:        convert_to_long_ex(mode);
        !          1350: 
        !          1351:        php_mcrypt_do_crypt(cipher, key, key_len, data, data_len, "cfb", iv, iv_len, ZEND_NUM_ARGS(), Z_LVAL_PP(mode), return_value TSRMLS_CC);
        !          1352: }
        !          1353: /* }}} */
        !          1354: 
        !          1355: /* {{{ proto string mcrypt_ofb(int cipher, string key, string data, int mode, string iv)
        !          1356:    OFB crypt/decrypt data using key key with cipher cipher starting with iv */
        !          1357: PHP_FUNCTION(mcrypt_ofb)
        !          1358: {
        !          1359:        zval **mode;
        !          1360:        char *cipher, *key, *data, *iv = NULL;
        !          1361:        int cipher_len, key_len, data_len, iv_len = 0;
        !          1362:        
        !          1363:        MCRYPT_GET_CRYPT_ARGS
        !          1364: 
        !          1365:        convert_to_long_ex(mode);
        !          1366: 
        !          1367:        php_mcrypt_do_crypt(cipher, key, key_len, data, data_len, "ofb", iv, iv_len, ZEND_NUM_ARGS(), Z_LVAL_PP(mode), return_value TSRMLS_CC);
        !          1368: }
        !          1369: /* }}} */
        !          1370: 
        !          1371: /* {{{ proto string mcrypt_create_iv(int size, int source)
        !          1372:    Create an initialization vector (IV) */
        !          1373: PHP_FUNCTION(mcrypt_create_iv)
        !          1374: {
        !          1375:        char *iv;
        !          1376:        long source = RANDOM;
        !          1377:        long size;
        !          1378:        int n = 0;
        !          1379: 
        !          1380:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l|l", &size, &source) == FAILURE) {
        !          1381:                return;
        !          1382:        }
        !          1383: 
        !          1384:        if (size <= 0 || size >= INT_MAX) {
        !          1385:                php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot create an IV with a size of less than 1 or greater than %d", INT_MAX);
        !          1386:                RETURN_FALSE;
        !          1387:        }
        !          1388:        
        !          1389:        iv = ecalloc(size + 1, 1);
        !          1390:        
        !          1391:        if (source == RANDOM || source == URANDOM) {
        !          1392: #if PHP_WIN32
        !          1393:                /* random/urandom equivalent on Windows */
        !          1394:                BYTE *iv_b = (BYTE *) iv;
        !          1395:                if (php_win32_get_random_bytes(iv_b, (size_t) size) == FAILURE){
        !          1396:                        efree(iv);
        !          1397:                        php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not gather sufficient random data");
        !          1398:                        RETURN_FALSE;
        !          1399:                }
        !          1400:                n = size;
        !          1401: #else
        !          1402:                int    fd;
        !          1403:                size_t read_bytes = 0;
        !          1404: 
        !          1405:                fd = open(source == RANDOM ? "/dev/random" : "/dev/urandom", O_RDONLY);
        !          1406:                if (fd < 0) {
        !          1407:                        efree(iv);
        !          1408:                        php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot open source device");
        !          1409:                        RETURN_FALSE;
        !          1410:                }
        !          1411:                while (read_bytes < size) {
        !          1412:                        n = read(fd, iv + read_bytes, size - read_bytes);
        !          1413:                        if (n < 0) {
        !          1414:                                break;
        !          1415:                        }
        !          1416:                        read_bytes += n;
        !          1417:                }
        !          1418:                n = read_bytes;
        !          1419:                close(fd);
        !          1420:                if (n < size) {
        !          1421:                        efree(iv);
        !          1422:                        php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not gather sufficient random data");
        !          1423:                        RETURN_FALSE;
        !          1424:                }
        !          1425: #endif
        !          1426:        } else {
        !          1427:                n = size;
        !          1428:                while (size) {
        !          1429:                        iv[--size] = (char) (255.0 * php_rand(TSRMLS_C) / RAND_MAX);
        !          1430:                }
        !          1431:        }
        !          1432:        RETURN_STRINGL(iv, n, 0);
        !          1433: }
        !          1434: /* }}} */
        !          1435: 
        !          1436: #endif
        !          1437: 
        !          1438: /*
        !          1439:  * Local variables:
        !          1440:  * tab-width: 4
        !          1441:  * c-basic-offset: 4
        !          1442:  * End:
        !          1443:  * vim600: sw=4 ts=4 fdm=marker
        !          1444:  * vim<600: sw=4 ts=4
        !          1445:  */

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>