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

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:  */
1.1.1.2 ! misho      19: /* $Id$ */
1.1       misho      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);
1.1.1.2 ! misho    1390: 
1.1       misho    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>