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

Generated by: LTP GCOV extension version 1.5

Generated at Thu, 19 Nov 2009 08:20:12 +0000 (5 days ago)

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