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

LTP GCOV extension - code coverage report
Current view: directory - mcrypt - mcrypt.c
Test: PHP Code Coverage
Date: 2009-11-21 Instrumented lines: 467
Code covered: 88.7 % Executed lines: 414
Legend: not executed executed

       1                 : /*
       2                 :    +----------------------------------------------------------------------+
       3                 :    | PHP Version 5                                                        |
       4                 :    +----------------------------------------------------------------------+
       5                 :    | Copyright (c) 1997-2009 The PHP Group                                |
       6                 :    +----------------------------------------------------------------------+
       7                 :    | This source file is subject to version 3.01 of the PHP license,      |
       8                 :    | that is bundled with this package in the file LICENSE, and is        |
       9                 :    | available through the world-wide-web at the following url:           |
      10                 :    | http://www.php.net/license/3_01.txt                                  |
      11                 :    | If you did not receive a copy of the PHP license and are unable to   |
      12                 :    | obtain it through the world-wide-web, please send a note to          |
      13                 :    | license@php.net so we can mail you a copy immediately.               |
      14                 :    +----------------------------------------------------------------------+
      15                 :    | Authors: Sascha Schumann <sascha@schumann.cx>                        |
      16                 :    |          Derick Rethans <derick@derickrethans.nl>                    |
      17                 :    +----------------------------------------------------------------------+
      18                 :  */
      19                 : /* $Id: mcrypt.c 289076 2009-10-02 00:13:53Z srinatar $ */
      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 <Wincrypt.h>
      31                 : # include <Ntsecapi.h>
      32                 : #endif
      33                 : 
      34                 : #include "php_mcrypt.h"
      35                 : #include "fcntl.h"
      36                 : 
      37                 : #define NON_FREE
      38                 : #define MCRYPT2
      39                 : #include "mcrypt.h"
      40                 : #include "php_ini.h"
      41                 : #include "php_globals.h"
      42                 : #include "ext/standard/info.h"
      43                 : #include "ext/standard/php_rand.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                 :         {NULL, NULL, NULL}
     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              39 : {
     409              39 :         php_mcrypt *pm = (php_mcrypt *) rsrc->ptr;
     410              39 :         if (pm) {       
     411              39 :                 mcrypt_generic_deinit(pm->td);
     412              39 :                 mcrypt_module_close(pm->td);
     413              39 :                 efree(pm);
     414              39 :                 pm = NULL;
     415                 :         }
     416              39 : }
     417                 : /* }}} */
     418                 :     
     419                 : static PHP_MINIT_FUNCTION(mcrypt) /* {{{ */
     420           17633 : {
     421           17633 :         le_mcrypt = zend_register_list_destructors_ex(php_mcrypt_module_dtor, NULL, "mcrypt", module_number);
     422                 :     
     423                 :         /* modes for mcrypt_??? routines */
     424           17633 :         REGISTER_LONG_CONSTANT("MCRYPT_ENCRYPT", 0, CONST_PERSISTENT);
     425           17633 :         REGISTER_LONG_CONSTANT("MCRYPT_DECRYPT", 1, CONST_PERSISTENT);
     426                 :         
     427                 :         /* sources for mcrypt_create_iv */
     428           17633 :         REGISTER_LONG_CONSTANT("MCRYPT_DEV_RANDOM", 0, CONST_PERSISTENT);
     429           17633 :         REGISTER_LONG_CONSTANT("MCRYPT_DEV_URANDOM", 1, CONST_PERSISTENT);
     430           17633 :         REGISTER_LONG_CONSTANT("MCRYPT_RAND", 2, CONST_PERSISTENT);
     431                 :         
     432                 :         /* ciphers */
     433           17633 :         MCRYPT_ENTRY2_2_4(3DES, "tripledes");
     434           17633 :         MCRYPT_ENTRY2_2_4(ARCFOUR_IV, "arcfour-iv");
     435           17633 :         MCRYPT_ENTRY2_2_4(ARCFOUR, "arcfour");
     436           17633 :         MCRYPT_ENTRY2_2_4(BLOWFISH, "blowfish");
     437           17633 :         MCRYPT_ENTRY2_2_4(BLOWFISH_COMPAT, "blowfish-compat");
     438           17633 :         MCRYPT_ENTRY2_2_4(CAST_128, "cast-128");
     439           17633 :         MCRYPT_ENTRY2_2_4(CAST_256, "cast-256");
     440           17633 :         MCRYPT_ENTRY2_2_4(CRYPT, "crypt");
     441           17633 :         MCRYPT_ENTRY2_2_4(DES, "des");
     442           17633 :         MCRYPT_ENTRY2_2_4(ENIGNA, "crypt");
     443           17633 :         MCRYPT_ENTRY2_2_4(GOST, "gost");
     444           17633 :         MCRYPT_ENTRY2_2_4(LOKI97, "loki97");
     445           17633 :         MCRYPT_ENTRY2_2_4(PANAMA, "panama");
     446           17633 :         MCRYPT_ENTRY2_2_4(RC2, "rc2");
     447           17633 :         MCRYPT_ENTRY2_2_4(RIJNDAEL_128, "rijndael-128");
     448           17633 :         MCRYPT_ENTRY2_2_4(RIJNDAEL_192, "rijndael-192");
     449           17633 :         MCRYPT_ENTRY2_2_4(RIJNDAEL_256, "rijndael-256");
     450           17633 :         MCRYPT_ENTRY2_2_4(SAFER64, "safer-sk64");
     451           17633 :         MCRYPT_ENTRY2_2_4(SAFER128, "safer-sk128");
     452           17633 :         MCRYPT_ENTRY2_2_4(SAFERPLUS, "saferplus");
     453           17633 :         MCRYPT_ENTRY2_2_4(SERPENT, "serpent");
     454           17633 :         MCRYPT_ENTRY2_2_4(THREEWAY, "threeway");
     455           17633 :         MCRYPT_ENTRY2_2_4(TRIPLEDES, "tripledes");
     456           17633 :         MCRYPT_ENTRY2_2_4(TWOFISH, "twofish");
     457           17633 :         MCRYPT_ENTRY2_2_4(WAKE, "wake");
     458           17633 :         MCRYPT_ENTRY2_2_4(XTEA, "xtea");
     459                 : 
     460           17633 :         MCRYPT_ENTRY2_2_4(IDEA, "idea");
     461           17633 :         MCRYPT_ENTRY2_2_4(MARS, "mars");
     462           17633 :         MCRYPT_ENTRY2_2_4(RC6, "rc6");
     463           17633 :         MCRYPT_ENTRY2_2_4(SKIPJACK, "skipjack");
     464                 : /* modes */
     465           17633 :         MCRYPT_ENTRY2_2_4(MODE_CBC, "cbc");
     466           17633 :         MCRYPT_ENTRY2_2_4(MODE_CFB, "cfb");
     467           17633 :         MCRYPT_ENTRY2_2_4(MODE_ECB, "ecb");
     468           17633 :         MCRYPT_ENTRY2_2_4(MODE_NOFB, "nofb");
     469           17633 :         MCRYPT_ENTRY2_2_4(MODE_OFB, "ofb");
     470           17633 :         MCRYPT_ENTRY2_2_4(MODE_STREAM, "stream");
     471           17633 :         REGISTER_INI_ENTRIES();
     472           17633 :         return SUCCESS;
     473                 : }
     474                 : /* }}} */
     475                 : 
     476                 : static PHP_MSHUTDOWN_FUNCTION(mcrypt) /* {{{ */
     477           17665 : {
     478           17665 :         UNREGISTER_INI_ENTRIES();
     479           17665 :         return SUCCESS;
     480                 : }
     481                 : /* }}} */
     482                 : 
     483                 : #include "ext/standard/php_smart_str.h"
     484                 : 
     485                 : PHP_MINFO_FUNCTION(mcrypt) /* {{{ */
     486              42 : {
     487                 :         char **modules;
     488                 :         char mcrypt_api_no[16];
     489                 :         int i, count;
     490              42 :         smart_str tmp1 = {0};
     491              42 :         smart_str tmp2 = {0};
     492                 : 
     493              42 :         modules = mcrypt_list_algorithms(MCG(algorithms_dir), &count);
     494              42 :         if (count == 0) {
     495               0 :                 smart_str_appends(&tmp1, "none");
     496                 :         }
     497             840 :         for (i = 0; i < count; i++) {
     498             798 :                 smart_str_appends(&tmp1, modules[i]);
     499             798 :                 smart_str_appendc(&tmp1, ' ');
     500                 :         }
     501              42 :         smart_str_0(&tmp1);
     502              42 :         mcrypt_free_p(modules, count);
     503                 : 
     504              42 :         modules = mcrypt_list_modes(MCG(modes_dir), &count);
     505              42 :         if (count == 0) {
     506               0 :                 smart_str_appends(&tmp2, "none");
     507                 :         }
     508             378 :         for (i = 0; i < count; i++) {
     509             336 :                 smart_str_appends(&tmp2, modules[i]);
     510             336 :                 smart_str_appendc(&tmp2, ' ');
     511                 :         }
     512              42 :         smart_str_0 (&tmp2);
     513              42 :         mcrypt_free_p (modules, count);
     514                 : 
     515              42 :         snprintf (mcrypt_api_no, 16, "%d", MCRYPT_API_VERSION);
     516                 : 
     517              42 :         php_info_print_table_start();
     518              42 :         php_info_print_table_header(2, "mcrypt support", "enabled");
     519              42 :         php_info_print_table_row(2, "Version", LIBMCRYPT_VERSION);
     520              42 :         php_info_print_table_row(2, "Api No", mcrypt_api_no);
     521              42 :         php_info_print_table_row(2, "Supported ciphers", tmp1.c);
     522              42 :         php_info_print_table_row(2, "Supported modes", tmp2.c);
     523              42 :         smart_str_free(&tmp1);
     524              42 :         smart_str_free(&tmp2);
     525              42 :         php_info_print_table_end();
     526                 :         
     527              42 :         DISPLAY_INI_ENTRIES();
     528              42 : }
     529                 : /* }}} */
     530                 : 
     531                 : typedef enum {
     532                 :         RANDOM = 0,
     533                 :         URANDOM,
     534                 :         RAND
     535                 : } iv_source;
     536                 : 
     537                 : /* {{{ proto resource mcrypt_module_open(string cipher, string cipher_directory, string mode, string mode_directory)
     538                 :    Opens the module of the algorithm and the mode to be used */
     539                 : PHP_FUNCTION(mcrypt_module_open)
     540              40 : {
     541                 :         char *cipher, *cipher_dir;
     542                 :         char *mode,   *mode_dir;
     543                 :         int   cipher_len, cipher_dir_len;
     544                 :         int   mode_len,   mode_dir_len;
     545                 :         MCRYPT td;
     546                 :         php_mcrypt *pm;
     547                 :    
     548              40 :         if (zend_parse_parameters (ZEND_NUM_ARGS() TSRMLS_CC, "ssss",
     549                 :                 &cipher, &cipher_len, &cipher_dir, &cipher_dir_len,
     550                 :                 &mode,   &mode_len,   &mode_dir,   &mode_dir_len)) {
     551               0 :                 return;
     552                 :         }
     553                 :         
     554              40 :         td = mcrypt_module_open (
     555                 :                 cipher,
     556                 :                 cipher_dir_len > 0 ? cipher_dir : MCG(algorithms_dir),
     557                 :                 mode, 
     558                 :                 mode_dir_len > 0 ? mode_dir : MCG(modes_dir)
     559                 :         );
     560                 : 
     561              40 :         if (td == MCRYPT_FAILED) {
     562               1 :                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not open encryption module");
     563               1 :                 RETURN_FALSE;
     564                 :         } else {
     565              39 :                 pm = emalloc(sizeof(php_mcrypt));
     566              39 :                 pm->td = td;
     567              39 :                 pm->init = 0;
     568              39 :                 ZEND_REGISTER_RESOURCE(return_value, pm, le_mcrypt);
     569                 :         }
     570                 : }
     571                 : /* }}} */
     572                 : 
     573                 : /* {{{ proto int mcrypt_generic_init(resource td, string key, string iv)
     574                 :    This function initializes all buffers for the specific module */
     575                 : PHP_FUNCTION(mcrypt_generic_init)
     576              47 : {
     577                 :         char *key, *iv;
     578                 :         int key_len, iv_len;
     579                 :         zval *mcryptind;
     580                 :         unsigned char *key_s, *iv_s;
     581                 :         int max_key_size, key_size, iv_size;
     582                 :         php_mcrypt *pm;
     583              47 :         int result = 0;
     584                 :         
     585              47 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rss", &mcryptind, &key, &key_len, &iv, &iv_len) == FAILURE) {
     586               0 :                 return;
     587                 :         }
     588                 : 
     589              47 :         ZEND_FETCH_RESOURCE(pm, php_mcrypt *, &mcryptind, -1, "MCrypt", le_mcrypt);
     590                 : 
     591              47 :         max_key_size = mcrypt_enc_get_key_size(pm->td);
     592              47 :         iv_size = mcrypt_enc_get_iv_size(pm->td);
     593                 : 
     594              47 :         if (key_len == 0) {
     595               0 :                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Key size is 0");
     596                 :         }
     597                 : 
     598              47 :         key_s = emalloc(key_len);
     599              47 :         memset(key_s, 0, key_len);
     600                 : 
     601              47 :         iv_s = emalloc(iv_size + 1);
     602              47 :         memset(iv_s, 0, iv_size + 1);
     603                 : 
     604              47 :         if (key_len > max_key_size) {
     605               0 :                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Key size too large; supplied length: %d, max: %d", key_len, max_key_size);
     606               0 :                 key_size = max_key_size;
     607                 :         } else {
     608              47 :                 key_size = key_len;
     609                 :         }
     610              47 :         memcpy(key_s, key, key_len);
     611                 : 
     612              47 :         if (iv_len != iv_size) {
     613               0 :                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Iv size incorrect; supplied length: %d, needed: %d", iv_len, iv_size);
     614                 :         }
     615              47 :         memcpy(iv_s, iv, iv_size);
     616                 : 
     617              47 :         mcrypt_generic_deinit(pm->td);
     618              47 :         result = mcrypt_generic_init(pm->td, key_s, key_size, iv_s);
     619                 : 
     620                 :         /* If this function fails, close the mcrypt module to prevent crashes
     621                 :          * when further functions want to access this resource */
     622              47 :         if (result < 0) {
     623               0 :                 zend_list_delete(Z_LVAL_P(mcryptind));
     624               0 :                 switch (result) {
     625                 :                         case -3:
     626               0 :                                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Key length incorrect");
     627               0 :                                 break;
     628                 :                         case -4:
     629               0 :                                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Memory allocation error");
     630               0 :                                 break;
     631                 :                         case -1:
     632                 :                         default:
     633               0 :                                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unknown error");
     634                 :                                 break;
     635                 :                 }
     636                 :         }
     637              47 :         pm->init = 1;
     638              47 :         RETVAL_LONG(result);
     639                 : 
     640              47 :         efree(iv_s);
     641              47 :         efree(key_s);
     642                 : }
     643                 : /* }}} */
     644                 : 
     645                 : /* {{{ proto string mcrypt_generic(resource td, string data)
     646                 :    This function encrypts the plaintext */
     647                 : PHP_FUNCTION(mcrypt_generic)
     648              43 : {
     649                 :         zval *mcryptind;
     650                 :         char *data;
     651                 :         int data_len;
     652                 :         php_mcrypt *pm;
     653                 :         unsigned char* data_s;
     654                 :         int block_size, data_size;
     655                 : 
     656              43 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs", &mcryptind, &data, &data_len) == FAILURE) {
     657               0 :                 return;
     658                 :         }
     659                 :         
     660              43 :         ZEND_FETCH_RESOURCE(pm, php_mcrypt *, &mcryptind, -1, "MCrypt", le_mcrypt);
     661              43 :         PHP_MCRYPT_INIT_CHECK
     662                 : 
     663              40 :         if (data_len == 0) {
     664               1 :                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "An empty string was passed");
     665               1 :                 RETURN_FALSE
     666                 :         }
     667                 : 
     668                 :         /* Check blocksize */
     669              39 :         if (mcrypt_enc_is_block_mode(pm->td) == 1) { /* It's a block algorithm */
     670              39 :                 block_size = mcrypt_enc_get_block_size(pm->td);
     671              39 :                 data_size = (((data_len - 1) / block_size) + 1) * block_size;
     672              39 :                 data_s = emalloc(data_size + 1);
     673              39 :                 memset(data_s, 0, data_size);
     674              39 :                 memcpy(data_s, data, data_len);
     675                 :         } else { /* It's not a block algorithm */
     676               0 :                 data_size = data_len;
     677               0 :                 data_s = emalloc(data_size + 1);
     678               0 :                 memset(data_s, 0, data_size);
     679               0 :                 memcpy(data_s, data, data_len);
     680                 :         }
     681                 :         
     682              39 :         mcrypt_generic(pm->td, data_s, data_size);
     683              39 :         data_s[data_size] = '\0';
     684                 : 
     685              39 :         RETVAL_STRINGL(data_s, data_size, 1);
     686              39 :         efree(data_s);
     687                 : }
     688                 : /* }}} */
     689                 : 
     690                 : /* {{{ proto string mdecrypt_generic(resource td, string data)
     691                 :    This function decrypts the plaintext */
     692                 : PHP_FUNCTION(mdecrypt_generic)
     693               7 : {
     694                 :         zval *mcryptind;
     695                 :         char *data;
     696                 :         int data_len;
     697                 :         php_mcrypt *pm;
     698                 :         char* data_s;
     699                 :         int block_size, data_size;
     700                 :         
     701               7 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs", &mcryptind, &data, &data_len) == FAILURE) {
     702               0 :                 return;
     703                 :         }
     704                 :         
     705               7 :         ZEND_FETCH_RESOURCE(pm, php_mcrypt * , &mcryptind, -1, "MCrypt", le_mcrypt);
     706               7 :         PHP_MCRYPT_INIT_CHECK
     707                 : 
     708               6 :         if (data_len == 0) {
     709               1 :                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "An empty string was passed");
     710               1 :                 RETURN_FALSE
     711                 :         }
     712                 : 
     713                 :         /* Check blocksize */
     714               5 :         if (mcrypt_enc_is_block_mode(pm->td) == 1) { /* It's a block algorithm */
     715               5 :                 block_size = mcrypt_enc_get_block_size(pm->td);
     716               5 :                 data_size = (((data_len - 1) / block_size) + 1) * block_size;
     717               5 :                 data_s = emalloc(data_size + 1);
     718               5 :                 memset(data_s, 0, data_size);
     719               5 :                 memcpy(data_s, data, data_len);
     720                 :         } else { /* It's not a block algorithm */
     721               0 :                 data_size = data_len;
     722               0 :                 data_s = emalloc(data_size + 1);
     723               0 :                 memset(data_s, 0, data_size);
     724               0 :                 memcpy(data_s, data, data_len);
     725                 :         }
     726                 :         
     727               5 :         mdecrypt_generic(pm->td, data_s, data_size);
     728                 : 
     729               5 :         RETVAL_STRINGL(data_s, data_size, 1);
     730               5 :         efree(data_s);
     731                 : }
     732                 : /* }}} */
     733                 : 
     734                 : /* {{{ proto array mcrypt_enc_get_supported_key_sizes(resource td)
     735                 :    This function decrypts the crypttext */
     736                 : PHP_FUNCTION(mcrypt_enc_get_supported_key_sizes)
     737               1 : {
     738               1 :         int i, count = 0;
     739                 :         int *key_sizes;
     740                 :         
     741               1 :         MCRYPT_GET_TD_ARG
     742               1 :         array_init(return_value);
     743                 : 
     744               1 :         key_sizes = mcrypt_enc_get_supported_key_sizes(pm->td, &count);
     745                 : 
     746               4 :         for (i = 0; i < count; i++) {
     747               3 :                 add_index_long(return_value, i, key_sizes[i]);
     748                 :         }
     749                 : 
     750               1 :         mcrypt_free(key_sizes);
     751                 : }
     752                 : /* }}} */
     753                 : 
     754                 : /* {{{ proto int mcrypt_enc_self_test(resource td)
     755                 :    This function runs the self test on the algorithm specified by the descriptor td */
     756                 : PHP_FUNCTION(mcrypt_enc_self_test)
     757               1 : {
     758               1 :         MCRYPT_GET_TD_ARG
     759               1 :         RETURN_LONG(mcrypt_enc_self_test(pm->td));
     760                 : }
     761                 : /* }}} */
     762                 : 
     763                 : /* {{{ proto bool mcrypt_module_close(resource td)
     764                 :    Free the descriptor td */
     765                 : PHP_FUNCTION(mcrypt_module_close)
     766               1 : {
     767               1 :         MCRYPT_GET_TD_ARG
     768               1 :         zend_list_delete(Z_LVAL_P(mcryptind));
     769               1 :         RETURN_TRUE;
     770                 : }
     771                 : /* }}} */
     772                 : 
     773                 : /* {{{ proto bool mcrypt_generic_deinit(resource td)
     774                 :    This function terminates encrypt specified by the descriptor td */
     775                 : PHP_FUNCTION(mcrypt_generic_deinit)
     776               7 : {
     777               7 :         MCRYPT_GET_TD_ARG
     778                 : 
     779               7 :         if (mcrypt_generic_deinit(pm->td) < 0) {
     780               0 :                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not terminate encryption specifier");
     781               0 :                 RETURN_FALSE
     782                 :         }
     783               7 :         pm->init = 0;
     784               7 :         RETURN_TRUE
     785                 : }
     786                 : /* }}} */
     787                 : 
     788                 : /* {{{ proto bool mcrypt_enc_is_block_algorithm_mode(resource td)
     789                 :    Returns TRUE if the mode is for use with block algorithms */
     790                 : PHP_FUNCTION(mcrypt_enc_is_block_algorithm_mode)
     791               3 : {
     792               3 :         MCRYPT_GET_TD_ARG
     793                 : 
     794               3 :         if (mcrypt_enc_is_block_algorithm_mode(pm->td) == 1) {
     795               2 :                 RETURN_TRUE
     796                 :         } else {
     797               1 :                 RETURN_FALSE
     798                 :         }
     799                 : }
     800                 : /* }}} */
     801                 : 
     802                 : /* {{{ proto bool mcrypt_enc_is_block_algorithm(resource td)
     803                 :    Returns TRUE if the alrogithm is a block algorithms */
     804                 : PHP_FUNCTION(mcrypt_enc_is_block_algorithm)
     805               3 : {
     806               3 :         MCRYPT_GET_TD_ARG
     807                 : 
     808               3 :         if (mcrypt_enc_is_block_algorithm(pm->td) == 1) {
     809               2 :                 RETURN_TRUE 
     810                 :         } else {
     811               1 :                 RETURN_FALSE
     812                 :         }
     813                 : }
     814                 : /* }}} */
     815                 : 
     816                 : /* {{{ proto bool mcrypt_enc_is_block_mode(resource td)
     817                 :    Returns TRUE if the mode outputs blocks */
     818                 : PHP_FUNCTION(mcrypt_enc_is_block_mode)
     819               4 : {
     820               4 :         MCRYPT_GET_TD_ARG
     821                 : 
     822               4 :         if (mcrypt_enc_is_block_mode(pm->td) == 1) {
     823               2 :                 RETURN_TRUE
     824                 :         } else {
     825               2 :                 RETURN_FALSE
     826                 :         }
     827                 : }
     828                 : /* }}} */
     829                 : 
     830                 : /* {{{ proto int mcrypt_enc_get_block_size(resource td)
     831                 :    Returns the block size of the cipher specified by the descriptor td */
     832                 : PHP_FUNCTION(mcrypt_enc_get_block_size)
     833               3 : {
     834               3 :         MCRYPT_GET_TD_ARG
     835               3 :         RETURN_LONG(mcrypt_enc_get_block_size(pm->td));
     836                 : }
     837                 : /* }}} */
     838                 : 
     839                 : /* {{{ proto int mcrypt_enc_get_key_size(resource td)
     840                 :    Returns the maximum supported key size in bytes of the algorithm specified by the descriptor td */
     841                 : PHP_FUNCTION(mcrypt_enc_get_key_size)
     842               3 : {
     843               3 :         MCRYPT_GET_TD_ARG
     844               3 :         RETURN_LONG(mcrypt_enc_get_key_size(pm->td));
     845                 : }
     846                 : /* }}} */
     847                 : 
     848                 : /* {{{ proto int mcrypt_enc_get_iv_size(resource td)
     849                 :    Returns the size of the IV in bytes of the algorithm specified by the descriptor td */
     850                 : PHP_FUNCTION(mcrypt_enc_get_iv_size)
     851               3 : {
     852               3 :         MCRYPT_GET_TD_ARG
     853               3 :         RETURN_LONG(mcrypt_enc_get_iv_size(pm->td));
     854                 : }
     855                 : /* }}} */
     856                 : 
     857                 : /* {{{ proto string mcrypt_enc_get_algorithms_name(resource td)
     858                 :    Returns the name of the algorithm specified by the descriptor td */
     859                 : PHP_FUNCTION(mcrypt_enc_get_algorithms_name)
     860               5 : {
     861                 :         char *name;
     862               5 :         MCRYPT_GET_TD_ARG
     863                 : 
     864               5 :         name = mcrypt_enc_get_algorithms_name(pm->td);
     865               5 :         RETVAL_STRING(name, 1);
     866               5 :         mcrypt_free(name);
     867                 : }
     868                 : /* }}} */
     869                 : 
     870                 : /* {{{ proto string mcrypt_enc_get_modes_name(resource td)
     871                 :    Returns the name of the mode specified by the descriptor td */
     872                 : PHP_FUNCTION(mcrypt_enc_get_modes_name)
     873               6 : {
     874                 :         char *name;
     875               6 :         MCRYPT_GET_TD_ARG
     876                 : 
     877               6 :         name = mcrypt_enc_get_modes_name(pm->td);
     878               6 :         RETVAL_STRING(name, 1);
     879               6 :         mcrypt_free(name);
     880                 : }
     881                 : /* }}} */
     882                 : 
     883                 : /* {{{ proto bool mcrypt_module_self_test(string algorithm [, string lib_dir])
     884                 :    Does a self test of the module "module" */
     885                 : PHP_FUNCTION(mcrypt_module_self_test)
     886               3 : {
     887               3 :         MCRYPT_GET_MODE_DIR_ARGS(algorithms_dir);
     888                 :         
     889               3 :         if (mcrypt_module_self_test(module, dir) == 0) {
     890               2 :                 RETURN_TRUE;
     891                 :         } else {
     892               1 :                 RETURN_FALSE;
     893                 :         }
     894                 : }
     895                 : /* }}} */
     896                 : 
     897                 : /* {{{ proto bool mcrypt_module_is_block_algorithm_mode(string mode [, string lib_dir])
     898                 :    Returns TRUE if the mode is for use with block algorithms */
     899                 : PHP_FUNCTION(mcrypt_module_is_block_algorithm_mode)
     900               4 : {
     901               4 :         MCRYPT_GET_MODE_DIR_ARGS(modes_dir)
     902                 :         
     903               4 :         if (mcrypt_module_is_block_algorithm_mode(module, dir) == 1) {
     904               3 :                 RETURN_TRUE;
     905                 :         } else {
     906               1 :                 RETURN_FALSE;
     907                 :         }
     908                 : }
     909                 : /* }}} */
     910                 : 
     911                 : /* {{{ proto bool mcrypt_module_is_block_algorithm(string algorithm [, string lib_dir])
     912                 :    Returns TRUE if the algorithm is a block algorithm */
     913                 : PHP_FUNCTION(mcrypt_module_is_block_algorithm)
     914               4 : {
     915               4 :         MCRYPT_GET_MODE_DIR_ARGS(algorithms_dir)
     916                 :         
     917               4 :         if (mcrypt_module_is_block_algorithm(module, dir) == 1) {
     918               3 :                 RETURN_TRUE;
     919                 :         } else {
     920               1 :                 RETURN_FALSE;
     921                 :         }
     922                 : }
     923                 : /* }}} */
     924                 : 
     925                 : /* {{{ proto bool mcrypt_module_is_block_mode(string mode [, string lib_dir])
     926                 :    Returns TRUE if the mode outputs blocks of bytes */
     927                 : PHP_FUNCTION(mcrypt_module_is_block_mode)
     928               5 : {
     929               5 :         MCRYPT_GET_MODE_DIR_ARGS(modes_dir)
     930                 :         
     931               5 :         if (mcrypt_module_is_block_mode(module, dir) == 1) {
     932               2 :                 RETURN_TRUE;
     933                 :         } else {
     934               3 :                 RETURN_FALSE;
     935                 :         }
     936                 : }
     937                 : /* }}} */
     938                 : 
     939                 : /* {{{ proto int mcrypt_module_get_algo_block_size(string algorithm [, string lib_dir])
     940                 :    Returns the block size of the algorithm */
     941                 : PHP_FUNCTION(mcrypt_module_get_algo_block_size)
     942               6 : {
     943               6 :         MCRYPT_GET_MODE_DIR_ARGS(algorithms_dir)
     944                 :         
     945               6 :         RETURN_LONG(mcrypt_module_get_algo_block_size(module, dir));
     946                 : }
     947                 : /* }}} */
     948                 : 
     949                 : /* {{{ proto int mcrypt_module_get_algo_key_size(string algorithm [, string lib_dir])
     950                 :    Returns the maximum supported key size of the algorithm */
     951                 : PHP_FUNCTION(mcrypt_module_get_algo_key_size)
     952               6 : {
     953               6 :         MCRYPT_GET_MODE_DIR_ARGS(algorithms_dir);
     954                 :         
     955               6 :         RETURN_LONG(mcrypt_module_get_algo_key_size(module, dir));
     956                 : }
     957                 : /* }}} */
     958                 : 
     959                 : /* {{{ proto array mcrypt_module_get_supported_key_sizes(string algorithm [, string lib_dir])
     960                 :    This function decrypts the crypttext */
     961                 : PHP_FUNCTION(mcrypt_module_get_supported_key_sizes)
     962               2 : {
     963               2 :         int i, count = 0;
     964                 :         int *key_sizes;
     965                 :         
     966               2 :         MCRYPT_GET_MODE_DIR_ARGS(algorithms_dir)
     967               2 :         array_init(return_value);
     968                 : 
     969               2 :         key_sizes = mcrypt_module_get_algo_supported_key_sizes(module, dir, &count);
     970                 : 
     971               5 :         for (i = 0; i < count; i++) {
     972               3 :                 add_index_long(return_value, i, key_sizes[i]);
     973                 :         }
     974               2 :         mcrypt_free(key_sizes);
     975                 : }
     976                 : /* }}} */
     977                 : 
     978                 : /* {{{ proto array mcrypt_list_algorithms([string lib_dir])
     979                 :    List all algorithms in "module_dir" */
     980                 : PHP_FUNCTION(mcrypt_list_algorithms)
     981               1 : {
     982                 :         char **modules;
     983               1 :         char *lib_dir = MCG(algorithms_dir);
     984                 :         int   lib_dir_len;
     985                 :         int   i, count;
     986                 : 
     987               1 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|s",
     988                 :                 &lib_dir, &lib_dir_len) == FAILURE) {
     989               0 :                 return;
     990                 :         }
     991                 :         
     992               1 :         array_init(return_value);
     993               1 :         modules = mcrypt_list_algorithms(lib_dir, &count);
     994                 : 
     995               1 :         if (count == 0) {
     996               0 :                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "No algorithms found in module dir");
     997                 :         }
     998              20 :         for (i = 0; i < count; i++) {
     999              19 :                 add_index_string(return_value, i, modules[i], 1);
    1000                 :         }
    1001               1 :         mcrypt_free_p(modules, count);
    1002                 : }
    1003                 : /* }}} */
    1004                 : 
    1005                 : /* {{{ proto array mcrypt_list_modes([string lib_dir])
    1006                 :    List all modes "module_dir" */
    1007                 : PHP_FUNCTION(mcrypt_list_modes)
    1008               1 : {
    1009                 :         char **modules;
    1010               1 :         char *lib_dir = MCG(modes_dir);
    1011                 :         int   lib_dir_len;
    1012                 :         int   i, count;
    1013                 : 
    1014               1 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|s",
    1015                 :                 &lib_dir, &lib_dir_len) == FAILURE) {
    1016               0 :                 return;
    1017                 :         }
    1018                 : 
    1019               1 :         array_init(return_value);
    1020               1 :         modules = mcrypt_list_modes(lib_dir, &count);
    1021                 : 
    1022               1 :         if (count == 0) {
    1023               0 :                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "No modes found in module dir");
    1024                 :         }
    1025               9 :         for (i = 0; i < count; i++) {
    1026               8 :                 add_index_string(return_value, i, modules[i], 1);
    1027                 :         }
    1028               1 :         mcrypt_free_p(modules, count);
    1029                 : }
    1030                 : /* }}} */
    1031                 : 
    1032                 : /* {{{ proto int mcrypt_get_key_size(string cipher, string module)
    1033                 :    Get the key size of cipher */
    1034                 : PHP_FUNCTION(mcrypt_get_key_size)
    1035               3 : {
    1036                 :         char *cipher;
    1037                 :         char *module;
    1038                 :         int   cipher_len, module_len; 
    1039                 :         char *cipher_dir_string;
    1040                 :         char *module_dir_string;
    1041                 :         MCRYPT td;
    1042                 : 
    1043               3 :         MCRYPT_GET_INI
    1044                 : 
    1045               3 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss",
    1046                 :                 &cipher, &cipher_len, &module, &module_len) == FAILURE) {
    1047               0 :                 return;
    1048                 :         }
    1049                 :         
    1050               3 :         td = mcrypt_module_open(cipher, cipher_dir_string, module, module_dir_string);
    1051               3 :         if (td != MCRYPT_FAILED) {
    1052               3 :                 RETVAL_LONG(mcrypt_enc_get_key_size(td));
    1053               3 :                 mcrypt_module_close(td);
    1054                 :         } else {
    1055               0 :                 php_error_docref(NULL TSRMLS_CC, E_WARNING, MCRYPT_OPEN_MODULE_FAILED);
    1056               0 :                 RETURN_FALSE;
    1057                 :         }
    1058                 : }
    1059                 : /* }}} */
    1060                 : 
    1061                 : /* {{{ proto int mcrypt_get_block_size(string cipher, string module)
    1062                 :    Get the key size of cipher */
    1063                 : PHP_FUNCTION(mcrypt_get_block_size)
    1064               3 : {
    1065                 :         char *cipher;
    1066                 :         char *module;
    1067                 :         int   cipher_len, module_len; 
    1068                 :         char *cipher_dir_string;
    1069                 :         char *module_dir_string;
    1070                 :         MCRYPT td;
    1071                 : 
    1072               3 :         MCRYPT_GET_INI
    1073                 : 
    1074               3 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss",
    1075                 :                 &cipher, &cipher_len, &module, &module_len) == FAILURE) {
    1076               0 :                 return;
    1077                 :         }
    1078                 :         
    1079               3 :         td = mcrypt_module_open(cipher, cipher_dir_string, module, module_dir_string);
    1080               3 :         if (td != MCRYPT_FAILED) {
    1081               3 :                 RETVAL_LONG(mcrypt_enc_get_block_size(td));
    1082               3 :                 mcrypt_module_close(td);
    1083                 :         } else {
    1084               0 :                 php_error_docref(NULL TSRMLS_CC, E_WARNING, MCRYPT_OPEN_MODULE_FAILED);
    1085               0 :                 RETURN_FALSE;
    1086                 :         }
    1087                 : }
    1088                 : /* }}} */
    1089                 : 
    1090                 : /* {{{ proto int mcrypt_get_iv_size(string cipher, string module)
    1091                 :    Get the IV size of cipher (Usually the same as the blocksize) */
    1092                 : PHP_FUNCTION(mcrypt_get_iv_size)
    1093              12 : {
    1094                 :         char *cipher;
    1095                 :         char *module;
    1096                 :         int   cipher_len, module_len; 
    1097                 :         char *cipher_dir_string;
    1098                 :         char *module_dir_string;
    1099                 :         MCRYPT td;
    1100                 : 
    1101              12 :         MCRYPT_GET_INI
    1102                 : 
    1103              12 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss",
    1104                 :                 &cipher, &cipher_len, &module, &module_len) == FAILURE) {
    1105               0 :                 return;
    1106                 :         }
    1107                 :         
    1108              12 :         td = mcrypt_module_open(cipher, cipher_dir_string, module, module_dir_string);
    1109              12 :         if (td != MCRYPT_FAILED) {
    1110              11 :                 RETVAL_LONG(mcrypt_enc_get_iv_size(td));
    1111              11 :                 mcrypt_module_close(td);
    1112                 :         } else {
    1113               1 :                 php_error_docref(NULL TSRMLS_CC, E_WARNING, MCRYPT_OPEN_MODULE_FAILED);
    1114               1 :                 RETURN_FALSE;
    1115                 :         }
    1116                 : }
    1117                 : /* }}} */
    1118                 : 
    1119                 : /* {{{ proto string mcrypt_get_cipher_name(string cipher)
    1120                 :    Get the key size of cipher */
    1121                 : PHP_FUNCTION(mcrypt_get_cipher_name)
    1122               4 : {
    1123                 :         char *cipher_dir_string;
    1124                 :         char *module_dir_string;
    1125                 :         char *cipher_name;
    1126                 :         char *cipher;
    1127                 :         int   cipher_len;
    1128                 :         MCRYPT td;
    1129                 : 
    1130               4 :         MCRYPT_GET_INI
    1131                 : 
    1132               4 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s",
    1133                 :                 &cipher, &cipher_len) == FAILURE) {
    1134               0 :                 return;
    1135                 :         }
    1136                 : 
    1137                 :         /* The code below is actually not very nice, but I didn't see a better
    1138                 :          * method */
    1139               4 :         td = mcrypt_module_open(cipher, cipher_dir_string, "ecb", module_dir_string);
    1140               4 :         if (td != MCRYPT_FAILED) {
    1141               2 :                 cipher_name = mcrypt_enc_get_algorithms_name(td);
    1142               2 :                 mcrypt_module_close(td);
    1143               2 :                 RETVAL_STRING(cipher_name,1);
    1144               2 :                 mcrypt_free(cipher_name);
    1145                 :         } else {
    1146               2 :                 td = mcrypt_module_open(cipher, cipher_dir_string, "stream", module_dir_string);
    1147               2 :                 if (td != MCRYPT_FAILED) {
    1148               2 :                         cipher_name = mcrypt_enc_get_algorithms_name(td);
    1149               2 :                         mcrypt_module_close(td);
    1150               2 :                         RETVAL_STRING(cipher_name,1);
    1151               2 :                         mcrypt_free(cipher_name);
    1152                 :                 } else {
    1153               0 :                         php_error_docref(NULL TSRMLS_CC, E_WARNING, MCRYPT_OPEN_MODULE_FAILED);
    1154               0 :                         RETURN_FALSE;
    1155                 :                 }
    1156                 :         }
    1157                 : }
    1158                 : /* }}} */
    1159                 : 
    1160                 : 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) /* {{{ */
    1161             529 : {
    1162                 :         char *cipher_dir_string;
    1163                 :         char *module_dir_string;
    1164                 :         int block_size, max_key_length, use_key_length, i, count, iv_size;
    1165                 :         unsigned long int data_size;
    1166                 :         int *key_length_sizes;
    1167             529 :         char *key_s = NULL, *iv_s;
    1168                 :         char *data_s;
    1169                 :         MCRYPT td;
    1170                 : 
    1171             529 :         MCRYPT_GET_INI
    1172                 : 
    1173             529 :         td = mcrypt_module_open(cipher, cipher_dir_string, mode, module_dir_string);
    1174             529 :         if (td == MCRYPT_FAILED) {
    1175             132 :                 php_error_docref(NULL TSRMLS_CC, E_WARNING, MCRYPT_OPEN_MODULE_FAILED);
    1176             132 :                 RETURN_FALSE;
    1177                 :         }
    1178                 :         /* Checking for key-length */
    1179             397 :         max_key_length = mcrypt_enc_get_key_size(td);
    1180             397 :         if (key_len > max_key_length) {
    1181              10 :                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Size of key is too large for this algorithm");
    1182                 :         }
    1183             397 :         key_length_sizes = mcrypt_enc_get_supported_key_sizes(td, &count);
    1184             398 :         if (count == 0 && key_length_sizes == NULL) { /* all lengths 1 - k_l_s = OK */
    1185               1 :                 use_key_length = key_len;
    1186               1 :                 key_s = emalloc(use_key_length);
    1187               1 :                 memset(key_s, 0, use_key_length);
    1188               1 :                 memcpy(key_s, key, use_key_length);
    1189             396 :         } else if (count == 1) {  /* only m_k_l = OK */
    1190             351 :                 key_s = emalloc(key_length_sizes[0]);
    1191             351 :                 memset(key_s, 0, key_length_sizes[0]);
    1192             351 :                 memcpy(key_s, key, MIN(key_len, key_length_sizes[0]));
    1193             351 :                 use_key_length = key_length_sizes[0];
    1194                 :         } else { /* dertermine smallest supported key > length of requested key */
    1195              45 :                 use_key_length = max_key_length; /* start with max key length */
    1196             180 :                 for (i = 0; i < count; i++) {
    1197             135 :                         if (key_length_sizes[i] >= key_len && 
    1198                 :                                 key_length_sizes[i] < use_key_length)
    1199                 :                         {
    1200              37 :                                 use_key_length = key_length_sizes[i];
    1201                 :                         }
    1202                 :                 }
    1203              45 :                 key_s = emalloc(use_key_length);
    1204              45 :                 memset(key_s, 0, use_key_length);
    1205              45 :                 memcpy(key_s, key, MIN(key_len, use_key_length));
    1206                 :         }
    1207             397 :         mcrypt_free (key_length_sizes);
    1208                 :         
    1209                 :         /* Check IV */
    1210             397 :         iv_s = NULL;
    1211             397 :         iv_size = mcrypt_enc_get_iv_size (td);
    1212                 :         
    1213                 :         /* IV is required */
    1214             397 :         if (mcrypt_enc_mode_has_iv(td) == 1) {
    1215             196 :                 if (argc == 5) {
    1216             192 :                         if (iv_size != iv_len) {
    1217              77 :                                 php_error_docref(NULL TSRMLS_CC, E_WARNING, MCRYPT_IV_WRONG_SIZE);
    1218                 :                         } else {
    1219             115 :                                 iv_s = emalloc(iv_size + 1);
    1220             115 :                                 memcpy(iv_s, iv, iv_size);
    1221                 :                         }
    1222               4 :                 } else if (argc == 4) {
    1223               4 :                         php_error_docref(NULL TSRMLS_CC, E_WARNING, "Attempt to use an empty IV, which is NOT recommend");
    1224               4 :                         iv_s = emalloc(iv_size + 1);
    1225               4 :                         memset(iv_s, 0, iv_size + 1);
    1226                 :                 }
    1227                 :         }
    1228                 : 
    1229                 :         /* Check blocksize */
    1230             397 :         if (mcrypt_enc_is_block_mode(td) == 1) { /* It's a block algorithm */
    1231             390 :                 block_size = mcrypt_enc_get_block_size(td);
    1232             390 :                 data_size = (((data_len - 1) / block_size) + 1) * block_size;
    1233             390 :                 data_s = emalloc(data_size);
    1234             390 :                 memset(data_s, 0, data_size);
    1235             390 :                 memcpy(data_s, data, data_len);
    1236                 :         } else { /* It's not a block algorithm */
    1237               7 :                 data_size = data_len;
    1238               7 :                 data_s = emalloc(data_size);
    1239               7 :                 memset(data_s, 0, data_size);
    1240               7 :                 memcpy(data_s, data, data_len);
    1241                 :         }
    1242                 : 
    1243             397 :         if (mcrypt_generic_init(td, key_s, use_key_length, iv_s) < 0) {
    1244               0 :                 php_error_docref(NULL TSRMLS_CC, E_RECOVERABLE_ERROR, "Mcrypt initialisation failed");
    1245               0 :                 RETURN_FALSE;
    1246                 :         }
    1247             397 :         if (dencrypt == MCRYPT_ENCRYPT) {
    1248             260 :                 mcrypt_generic(td, data_s, data_size);
    1249                 :         } else {
    1250             137 :                 mdecrypt_generic(td, data_s, data_size);
    1251                 :         }
    1252                 :         
    1253             397 :         RETVAL_STRINGL(data_s, data_size, 1);
    1254                 : 
    1255                 :         /* freeing vars */
    1256             397 :         mcrypt_generic_end(td);
    1257             397 :         if (key_s != NULL) {
    1258             397 :                 efree (key_s);
    1259                 :         }
    1260             397 :         if (iv_s != NULL) {
    1261             119 :                 efree (iv_s);
    1262                 :         }
    1263             397 :         efree (data_s);
    1264                 : }
    1265                 : /* }}} */
    1266                 : 
    1267                 : /* {{{ proto string mcrypt_encrypt(string cipher, string key, string data, string mode, string iv)
    1268                 :    OFB crypt/decrypt data using key key with cipher cipher starting with iv */
    1269                 : PHP_FUNCTION(mcrypt_encrypt)
    1270             161 : {
    1271                 :         zval **mode;
    1272             161 :         char *cipher, *key, *data, *iv = NULL;
    1273             161 :         int cipher_len, key_len, data_len, iv_len = 0;
    1274                 :         
    1275             161 :         MCRYPT_GET_CRYPT_ARGS
    1276                 :         
    1277             135 :         convert_to_string_ex(mode);
    1278                 : 
    1279             135 :         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);
    1280                 : }
    1281                 : /* }}} */
    1282                 : 
    1283                 : /* {{{ proto string mcrypt_decrypt(string cipher, string key, string data, string mode, string iv)
    1284                 :    OFB crypt/decrypt data using key key with cipher cipher starting with iv */
    1285                 : PHP_FUNCTION(mcrypt_decrypt)
    1286             159 : {
    1287                 :         zval **mode;
    1288             159 :         char *cipher, *key, *data, *iv = NULL;
    1289             159 :         int cipher_len, key_len, data_len, iv_len = 0;
    1290                 : 
    1291             159 :         MCRYPT_GET_CRYPT_ARGS
    1292                 :         
    1293             133 :         convert_to_string_ex(mode);
    1294                 : 
    1295             133 :         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);
    1296                 : }
    1297                 : /* }}} */
    1298                 : 
    1299                 : /* {{{ proto string mcrypt_ecb(int cipher, string key, string data, int mode, string iv)
    1300                 :    ECB crypt/decrypt data using key key with cipher cipher starting with iv */
    1301                 : PHP_FUNCTION(mcrypt_ecb)
    1302             149 : {
    1303                 :         zval **mode;
    1304             149 :         char *cipher, *key, *data, *iv = NULL;
    1305             149 :         int cipher_len, key_len, data_len, iv_len = 0;
    1306                 :         
    1307             149 :         MCRYPT_GET_CRYPT_ARGS
    1308                 : 
    1309             123 :         convert_to_long_ex(mode);
    1310                 : 
    1311             123 :         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);
    1312                 : }
    1313                 : /* }}} */
    1314                 : 
    1315                 : /* {{{ proto string mcrypt_cbc(int cipher, string key, string data, int mode, string iv)
    1316                 :    CBC crypt/decrypt data using key key with cipher cipher starting with iv */
    1317                 : PHP_FUNCTION(mcrypt_cbc)
    1318             158 : {
    1319                 :         zval **mode;
    1320             158 :         char *cipher, *key, *data, *iv = NULL;
    1321             158 :         int cipher_len, key_len, data_len, iv_len = 0;
    1322                 : 
    1323             158 :         MCRYPT_GET_CRYPT_ARGS
    1324                 : 
    1325             132 :         convert_to_long_ex(mode);
    1326                 : 
    1327             132 :         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);
    1328                 : }
    1329                 : /* }}} */
    1330                 : 
    1331                 : /* {{{ proto string mcrypt_cfb(int cipher, string key, string data, int mode, string iv)
    1332                 :    CFB crypt/decrypt data using key key with cipher cipher starting with iv */
    1333                 : PHP_FUNCTION(mcrypt_cfb)
    1334               3 : {
    1335                 :         zval **mode;
    1336               3 :         char *cipher, *key, *data, *iv = NULL;
    1337               3 :         int cipher_len, key_len, data_len, iv_len = 0;
    1338                 :         
    1339               3 :         MCRYPT_GET_CRYPT_ARGS
    1340                 : 
    1341               3 :         convert_to_long_ex(mode);
    1342                 : 
    1343               3 :         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);
    1344                 : }
    1345                 : /* }}} */
    1346                 : 
    1347                 : /* {{{ proto string mcrypt_ofb(int cipher, string key, string data, int mode, string iv)
    1348                 :    OFB crypt/decrypt data using key key with cipher cipher starting with iv */
    1349                 : PHP_FUNCTION(mcrypt_ofb)
    1350               3 : {
    1351                 :         zval **mode;
    1352               3 :         char *cipher, *key, *data, *iv = NULL;
    1353               3 :         int cipher_len, key_len, data_len, iv_len = 0;
    1354                 :         
    1355               3 :         MCRYPT_GET_CRYPT_ARGS
    1356                 : 
    1357               3 :         convert_to_long_ex(mode);
    1358                 : 
    1359               3 :         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);
    1360                 : }
    1361                 : /* }}} */
    1362                 : 
    1363                 : /* {{{ proto string mcrypt_create_iv(int size, int source)
    1364                 :    Create an initialization vector (IV) */
    1365                 : PHP_FUNCTION(mcrypt_create_iv)
    1366               8 : {
    1367                 :         char *iv;
    1368               8 :         long source = RANDOM;
    1369                 :         long size;
    1370               8 :         int n = 0;
    1371                 : 
    1372               8 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l|l", &size, &source) == FAILURE) {
    1373               0 :                 return;
    1374                 :         }
    1375                 : 
    1376               8 :         if (size <= 0 || size >= INT_MAX) {
    1377               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);
    1378               0 :                 RETURN_FALSE;
    1379                 :         }
    1380                 :         
    1381               8 :         iv = ecalloc(size + 1, 1);
    1382                 :         
    1383              10 :         if (source == RANDOM || source == URANDOM) {
    1384                 : #if PHP_WIN32
    1385                 :                         /* random/urandom equivalent on Windows */
    1386                 :                         HCRYPTPROV     hCryptProv;
    1387                 :                         BYTE *iv_b = (BYTE *) iv;
    1388                 : 
    1389                 :                         /* It could be done using LoadLibrary but as we rely on 2k+ for 5.3, cleaner to use a clear dependency (Advapi32) and a 
    1390                 :                                 standard API call (no f=getAddr..; f();) */
    1391                 :                         if(!CryptAcquireContext(&hCryptProv, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT)) {
    1392                 :                                 php_error_docref(NULL TSRMLS_CC, E_ERROR, "Cannot open random device");
    1393                 :                                 RETURN_FALSE;
    1394                 :                         }
    1395                 :                         if(!CryptGenRandom(hCryptProv, size,  iv_b)) {
    1396                 :                                 php_error_docref(NULL TSRMLS_CC, E_ERROR, "Could not gather sufficient random data");
    1397                 :                                 RETURN_FALSE;
    1398                 :                         }
    1399                 :                         n = size;
    1400                 : #else
    1401                 :                 int    fd;
    1402               2 :                 size_t read_bytes = 0;
    1403                 : 
    1404               2 :                 fd = open(source == RANDOM ? "/dev/random" : "/dev/urandom", O_RDONLY);
    1405               2 :                 if (fd < 0) {
    1406               0 :                         efree(iv);
    1407               0 :                         php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot open source device");
    1408               0 :                         RETURN_FALSE;
    1409                 :                 }
    1410               8 :                 while (read_bytes < size) {
    1411               4 :                         n = read(fd, iv + read_bytes, size - read_bytes);
    1412               4 :                         if (n < 0) {
    1413               0 :                                 break;
    1414                 :                         }
    1415               4 :                         read_bytes += n;
    1416                 :                 }
    1417               2 :                 n = read_bytes;
    1418               2 :                 close(fd);
    1419               2 :                 if (n < size) {
    1420               0 :                         efree(iv);
    1421               0 :                         php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not gather sufficient random data");
    1422               0 :                         RETURN_FALSE;
    1423                 :                 }
    1424                 : #endif
    1425                 :         } else {
    1426               6 :                 n = size;
    1427             108 :                 while (size) {
    1428              96 :                         iv[--size] = (char) (255.0 * php_rand(TSRMLS_C) / RAND_MAX);
    1429                 :                 }
    1430                 :         }
    1431               8 :         RETURN_STRINGL(iv, n, 0);
    1432                 : }
    1433                 : /* }}} */
    1434                 : 
    1435                 : #endif
    1436                 : 
    1437                 : /*
    1438                 :  * Local variables:
    1439                 :  * tab-width: 4
    1440                 :  * c-basic-offset: 4
    1441                 :  * End:
    1442                 :  * vim600: sw=4 ts=4 fdm=marker
    1443                 :  * vim<600: sw=4 ts=4
    1444                 :  */

Generated by: LTP GCOV extension version 1.5

Generated at Sat, 21 Nov 2009 12:27:02 +0000 (3 days ago)

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