PHP  
 PHP: Test and Code Coverage Analysis
downloads | QA | documentation | faq | getting help | mailing lists | reporting bugs | php.net sites | links | my php.net 
 

LCOV - code coverage report
Current view: top level - ext/mcrypt - mcrypt.c (source / functions) Hit Total Coverage
Test: PHP Code Coverage Lines: 426 482 88.4 %
Date: 2014-12-13 Functions: 45 45 100.0 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.10

Generated at Sat, 13 Dec 2014 06:16:15 +0000 (4 days ago)

Copyright © 2005-2014 The PHP Group
All rights reserved.