]> granicus.if.org Git - php/commitdiff
@ Added support for libmcrypt 2.4.4
authorDerick Rethans <derick@php.net>
Fri, 11 Aug 2000 18:45:17 +0000 (18:45 +0000)
committerDerick Rethans <derick@php.net>
Fri, 11 Aug 2000 18:45:17 +0000 (18:45 +0000)
ext/mcrypt/config.m4
ext/mcrypt/mcrypt.c
ext/mcrypt/php_mcrypt.h

index 8fbee13736ccb6651a8fd289eb0fba529403f8d8..67ed516c39e28a72874be7f34b93f482131a6734 100644 (file)
@@ -19,8 +19,19 @@ if test "$PHP_MCRYPT" != "no"; then
 
   AC_ADD_INCLUDE($MCRYPT_DIR/include)
   PHP_SUBST(MCRYPT_SHARED_LIBADD)
+  AC_CHECK_LIB(mcrypt, init_mcrypt, [ AC_DEFINE(HAVE_LIBMCRYPT22,1,[ ]) ])
+  old_LIBS=$LIBS
+  LIBS="$LIBS -lltdl"
+  AC_CHECK_LIB(mcrypt, mcrypt_module_open, [LIBS="$LIBS -lltdl"],[ ],)
+  LIBS=$old_LIBS
   AC_ADD_LIBRARY_WITH_PATH(mcrypt, $MCRYPT_DIR/lib, MCRYPT_SHARED_LIBADD)
-
+  if test "$ac_cv_lib_mcrypt_init_mcrypt" = "yes"; then
+       AC_DEFINE(HAVE_LIBMCRYPT22,1,[ ])
+  fi
+  if test "$ac_cv_lib_mcrypt_mcrypt_module_open" = "yes"; then
+    AC_ADD_LIBRARY(ltdl)
+       AC_DEFINE(HAVE_LIBMCRYPT24,1,[ ])
+  fi
   AC_DEFINE(HAVE_LIBMCRYPT,1,[ ])
 
   PHP_EXTENSION(mcrypt, $ext_shared)
index c52a4291f64a66960d4bec1b7fe3b76bc1d414b0..d31e41ddd6bb1aa6e181f5c833c995b9475fe4e7 100644 (file)
@@ -13,6 +13,7 @@
    | license@php.net so we can mail you a copy immediately.               |
    +----------------------------------------------------------------------+
    | Authors: Sascha Schumann <sascha@schumann.cx>                        |
+   |          Derick Rethans <d.rethans@jdimedia.nl>                      |
    +----------------------------------------------------------------------+
  */
 
 #define NON_FREE
 #define MCRYPT2
 #include "mcrypt.h"
+#include "php_ini.h"
+#include "ext/standard/info.h"
+
+
+#if !defined(HAVE_LIBMCRYPT22) && !defined(HAVE_LIBMCRYPT24)
+#error Upgrade you version of mcrypt to at least 2.2.7, preferrable 2.4.4
+#endif
 
 function_entry mcrypt_functions[] = {
        PHP_FE(mcrypt_ecb, NULL)
        PHP_FE(mcrypt_cbc, NULL)
        PHP_FE(mcrypt_cfb, NULL)
        PHP_FE(mcrypt_ofb, NULL)
-       PHP_FE(mcrypt_get_cipher_name, NULL)
-       PHP_FE(mcrypt_get_block_size, NULL)
        PHP_FE(mcrypt_get_key_size, NULL)
+       PHP_FE(mcrypt_get_block_size, NULL)
+       PHP_FE(mcrypt_get_cipher_name, NULL)
        PHP_FE(mcrypt_create_iv, NULL)
+#if HAVE_LIBMCRYPT24
+       PHP_FE(mcrypt_list_algorithms, NULL)
+       PHP_FE(mcrypt_list_modes, NULL)
+       PHP_FE(mcrypt_get_iv_size, NULL)
+       PHP_FE(mcrypt_encrypt, NULL)
+       PHP_FE(mcrypt_decrypt, NULL)
+
+       PHP_FE(mcrypt_module_open, NULL)
+       PHP_FE(mcrypt_generic_init, NULL)
+       PHP_FE(mcrypt_generic, NULL)
+       PHP_FE(mdecrypt_generic, NULL)
+       PHP_FE(mcrypt_generic_end, NULL)
+       PHP_FE(mcrypt_enc_self_test, NULL)
+       PHP_FE(mcrypt_enc_is_block_algorithm_mode, NULL)
+       PHP_FE(mcrypt_enc_is_block_algorithm, NULL)
+       PHP_FE(mcrypt_enc_is_block_mode, NULL)
+       PHP_FE(mcrypt_enc_get_block_size, NULL)
+       PHP_FE(mcrypt_enc_get_key_size, NULL)
+       PHP_FE(mcrypt_enc_get_supported_key_sizes, NULL)
+       PHP_FE(mcrypt_enc_get_iv_size, NULL)
+       PHP_FE(mcrypt_enc_get_algorithms_name, NULL)
+       PHP_FE(mcrypt_enc_get_modes_name, NULL)
+       PHP_FE(mcrypt_module_self_test, NULL)
+
+       PHP_FE(mcrypt_module_is_block_algorithm_mode, NULL)
+       PHP_FE(mcrypt_module_is_block_algorithm, NULL)
+       PHP_FE(mcrypt_module_is_block_mode, NULL)
+       PHP_FE(mcrypt_module_get_algo_block_size, NULL)
+       PHP_FE(mcrypt_module_get_algo_key_size, NULL)
+       PHP_FE(mcrypt_module_get_supported_key_sizes, NULL)
+
+       PHP_FE(mcrypt_module_close, NULL)
+#endif
        {0},
 };
 
+static PHP_MINFO_FUNCTION(mcrypt);
 static PHP_MINIT_FUNCTION(mcrypt);
+static PHP_MSHUTDOWN_FUNCTION(mcrypt);
 
 zend_module_entry mcrypt_module_entry = {
        "mcrypt", 
        mcrypt_functions,
-       PHP_MINIT(mcrypt), NULL,
+       PHP_MINIT(mcrypt), PHP_MSHUTDOWN(mcrypt),
        NULL, NULL,
-       NULL,
+       PHP_MINFO(mcrypt),
        STANDARD_MODULE_PROPERTIES,
 };
 
-#ifdef COMPILE_DL_MCRYPT
-ZEND_GET_MODULE(mcrypt)
+#if HAVE_LIBMCRYPT24
+#ifdef ZTS
+ZEND_DECLARE_MODULE_GLOBALS(mcrypt)
+#else
+static mcrypt_global_struct mcrypt_globals;
+#endif
 #endif
 
-#if 0
-
-typedef struct mcrypt_global_struct {
-       int le_h;
-} mcrypt_global_struct;
-
-static mcrypt_global_struct mcryptg;
-
-#define MCRYPTG(x) mcryptg.x
-
+#ifdef COMPILE_DL_MCRYPT
+ZEND_GET_MODULE(mcrypt)
 #endif
 
 #define MCRYPT_ARGS2                                                                                   \
-       pval **cipher, **data, **key, **mode;                                           \
+       zval **cipher, **data, **key, **mode;                                           \
        int td;                                                                                                         \
        char *ndata;                                                                                            \
        size_t bsize;                                                                                           \
@@ -76,13 +115,25 @@ static mcrypt_global_struct mcryptg;
 
 #define MCRYPT_ARGS                                                                                    \
        MCRYPT_ARGS2;                                                                                           \
-       pval **iv
+       zval **iv
 
+#if HAVE_LIBMCRYPT22
 #define MCRYPT_CONVERT                                                                                         \
        convert_to_long_ex(cipher);                                                             \
        convert_to_long_ex(mode);                                                                       \
        convert_to_string_ex(data);                                                             \
        convert_to_string_ex(key)
+#else
+#define MCRYPT_CONVERT                                                                                         \
+       convert_to_string_ex(cipher);                                                           \
+       convert_to_string_ex(mode);                                                             \
+       convert_to_string_ex(data);                                                             \
+       convert_to_string_ex(key)
+#define MCRYPT_CONVERT_WO_MODE                                                                 \
+       convert_to_string_ex(cipher);                                                           \
+       convert_to_string_ex(data);                                                             \
+       convert_to_string_ex(key)
+#endif
 
 #define MCRYPT_SIZE                                                                                    \
        bsize = mcrypt_get_block_size((*cipher)->value.lval);           \
@@ -111,15 +162,95 @@ static mcrypt_global_struct mcryptg;
                mdecrypt_##x(td, ndata, nsize);                                                 \
        end_mcrypt_##x(td)
 
-#define MCRYPT_IV_WRONG_SIZE "The IV paramater must be as long as the blocksize"
+#define MCRYPT_IV_WRONG_SIZE "The IV parameter must be as long as the blocksize"
+
+#if HAVE_LIBMCRYPT24
+#define MCRYPT_ENCRYPT 0
+#define MCRYPT_DECRYPT 1
+
+#define MCRYPT_GET_INI                                                                                 \
+       cipher_dir_string = INI_STR("mcrypt.algorithms_dir");           \
+       module_dir_string = INI_STR("mcrypt.modes_dir");
+
+#define MCRYPT_CHECK_PARAM_COUNT(a,b)                                                  \
+       if (argc < (a) || argc > (b)) {                                                         \
+               WRONG_PARAM_COUNT;                                                                              \
+       }
+
+#define MCRYPT_GET_CRYPT_ARGS                                                                  \
+       switch (argc) {                                                                                         \
+               case 5:                                                                                                 \
+                       if (zend_get_parameters_ex(5, &cipher, &key, &data, &mode, &iv) == FAILURE) {   \
+                               WRONG_PARAM_COUNT;                                                              \
+                       }                                                                                                       \
+                       convert_to_string_ex(iv);                                                       \
+                       break;                                                                                          \
+               case 4:                                                                                                 \
+                       if (zend_get_parameters_ex(4, &cipher, &key, &data, &mode) == FAILURE) {                \
+                               WRONG_PARAM_COUNT;                                                              \
+                       }                                                                                                       \
+                       iv = NULL;                                                                                      \
+                       break;                                                                                          \
+               default:                                                                                                \
+                       WRONG_PARAM_COUNT;                                                                      \
+       }
+
+#define MCRYPT_GET_TD_ARG                                                                              \
+       if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &mcryptind) == FAILURE) {                 \
+               WRONG_PARAM_COUNT                                                                                                                                       \
+       }                                                                                                                                                                               \
+       ZEND_FETCH_RESOURCE (td, MCRYPT, mcryptind, -1, "MCrypt", MCG(le_h));                           
+
+#define MCRYPT_GET_MODE_DIR_ARGS(DIRECTORY)                                                            \
+       switch (argc) {                                                                                                         \
+               case 2:                                                                                                                 \
+                       lib_dir_s = (*lib_dir)->value.str.val;                                          \
+                       if (zend_get_parameters_ex(2, &arg1, &lib_dir) == FAILURE)      \
+                       {                                                                                                                       \
+                               WRONG_PARAM_COUNT;                                                                              \
+                       }                                                                                                                       \
+                       convert_to_string_ex (lib_dir);                                                         \
+                       break;                                                                                                          \
+               case 1:                                                                                                                 \
+                       lib_dir_s = INI_STR(DIRECTORY);                                                         \
+                       if (zend_get_parameters_ex(1, &arg1) == FAILURE)                        \
+                       {                                                                                                                       \
+                               WRONG_PARAM_COUNT;                                                                              \
+                       }                                                                                                                       \
+                       break;                                                                                                          \
+               default:                                                                                                                \
+                       WRONG_PARAM_COUNT;                                                                                      \
+       }                                                                                                                                       \
+       convert_to_string_ex(arg1);
+       
+#endif
+
+#if HAVE_LIBMCRYPT22
 #define MCRYPT_FAILED "mcrypt initialization failed"
+#else
+#define MCRYPT_OPEN_MODULE_FAILED "mcrypt module initialization failed"
+#endif
 
+#if HAVE_LIBMCRYPT22
 #define MCRYPT_ENTRY_NAMED(a,b) REGISTER_LONG_CONSTANT("MCRYPT_" #a, b, CONST_PERSISTENT)
 #define MCRYPT_ENTRY2(a) MCRYPT_ENTRY_NAMED(a, MCRYPT_##a)
 #define MCRYPT_ENTRY(a) MCRYPT_ENTRY_NAMED(a, a)
+#else /* MCRYPT_2_4 */
+#define MCRYPT_ENTRY2_2_4(a,b) REGISTER_STRING_CONSTANT("MCRYPT_" #a, b, CONST_PERSISTENT)
+#define MCRYPT_ENTRY2_4(a) MCRYPT_ENTRY_NAMED(a, a)
+#endif
+
+PHP_INI_BEGIN()
+       PHP_INI_ENTRY("mcrypt.algorithms_dir",  NULL, PHP_INI_ALL, NULL)
+       PHP_INI_ENTRY("mcrypt.modes_dir",       NULL, PHP_INI_ALL, NULL)
+PHP_INI_END()
 
 static PHP_MINIT_FUNCTION(mcrypt)
 {
+#ifdef ZTS
+    ZEND_INIT_MODULE_GLOBALS(mcrypt, NULL, NULL);
+    mcrypt_module_entry.type = type;
+#endif
        /* modes for mcrypt_??? routines */
        REGISTER_LONG_CONSTANT("MCRYPT_ENCRYPT", 0, CONST_PERSISTENT);
        REGISTER_LONG_CONSTANT("MCRYPT_DECRYPT", 1, CONST_PERSISTENT);
@@ -130,7 +261,7 @@ static PHP_MINIT_FUNCTION(mcrypt)
        REGISTER_LONG_CONSTANT("MCRYPT_RAND", 2, CONST_PERSISTENT);
        
        /* ciphers */
-#if defined(MCRYPT_API_VERSION) && MCRYPT_API_VERSION >= 19991015
+#if HAVE_LIBMCRYPT22
        MCRYPT_ENTRY2(BLOWFISH_448);
        MCRYPT_ENTRY2(DES);
        MCRYPT_ENTRY2(3DES);
@@ -163,24 +294,1126 @@ static PHP_MINIT_FUNCTION(mcrypt)
        MCRYPT_ENTRY2(RC6_128);
        MCRYPT_ENTRY2(RC6_192);
        MCRYPT_ENTRY2(RC4);
-#else
-#error Please update your mcrypt library
 #endif
-       
+#if HAVE_LIBMCRYPT24
+       MCRYPT_ENTRY2_2_4(ARCFOUR_IV, "arcfour-iv");
+       MCRYPT_ENTRY2_2_4(ARCFOUR, "arcfour");
+       MCRYPT_ENTRY2_2_4(BLOWFISH, "blowfish");
+       MCRYPT_ENTRY2_2_4(CAST_128, "cast-128");
+       MCRYPT_ENTRY2_2_4(CAST_256, "cast-256");
+       MCRYPT_ENTRY2_2_4(CRYPT, "crypt");
+       MCRYPT_ENTRY2_2_4(DES, "des");
+       MCRYPT_ENTRY2_2_4(ENIGNA, "crypt");
+       MCRYPT_ENTRY2_2_4(GOST, "gost");
+       MCRYPT_ENTRY2_2_4(LOKI97, "loki97");
+       MCRYPT_ENTRY2_2_4(PANAMA, "panama");
+       MCRYPT_ENTRY2_2_4(RC2, "rc2");
+       MCRYPT_ENTRY2_2_4(RIJNDAEL_128, "rijndael-128");
+       MCRYPT_ENTRY2_2_4(RIJNDAEL_192, "rijndael-192");
+       MCRYPT_ENTRY2_2_4(RIJNDAEL_256, "rijndael-256");
+       MCRYPT_ENTRY2_2_4(SAFER64, "safer-sk64");
+       MCRYPT_ENTRY2_2_4(SAFER128, "safer-sk128");
+       MCRYPT_ENTRY2_2_4(SAFERPLUS, "saferplus");
+       MCRYPT_ENTRY2_2_4(SERPENT, "serpent");
+       MCRYPT_ENTRY2_2_4(THREEWAY, "threeway");
+       MCRYPT_ENTRY2_2_4(TRIPLEDES, "tripledes");
+       MCRYPT_ENTRY2_2_4(TWOFISH, "twofish");
+       MCRYPT_ENTRY2_2_4(WAKE, "wake");
+       MCRYPT_ENTRY2_2_4(XTEA, "xtea");
+
+       MCRYPT_ENTRY2_2_4(IDEA, "idea");
+       MCRYPT_ENTRY2_2_4(MARS, "mars");
+       MCRYPT_ENTRY2_2_4(RC6, "rc6");
+       MCRYPT_ENTRY2_2_4(SKIPJACK, "skipjack");
+/* modes */
+       MCRYPT_ENTRY2_2_4(MODE_CBC, "cbc");
+       MCRYPT_ENTRY2_2_4(MODE_CFB, "cfb");
+       MCRYPT_ENTRY2_2_4(MODE_ECB, "ecb");
+       MCRYPT_ENTRY2_2_4(MODE_NOFB, "nofb");
+       MCRYPT_ENTRY2_2_4(MODE_OFB, "ofb");
+       MCRYPT_ENTRY2_2_4(MODE_STREAM, "stream");
+#endif
+       REGISTER_INI_ENTRIES();
+       return SUCCESS;
+}
+
+static PHP_MSHUTDOWN_FUNCTION(mcrypt)
+{
+       UNREGISTER_INI_ENTRIES();
        return SUCCESS;
 }
 
+PHP_MINFO_FUNCTION(mcrypt)
+{
+#if HAVE_LIBMCRYPT24
+       char **modules;
+       int i, count;
+       char *tmp, *tmp2;
+
+       tmp = emalloc (2048);
+       memset (tmp, 0, sizeof(tmp));
+       modules = mcrypt_list_algorithms (INI_STR("mcrypt.algorithms_dir"), &count);
+       if (count == 0) {
+               strcpy (tmp, "none");
+       }
+       for (i = 0; i < count; i++) {
+               strcat (tmp, modules[i]);
+               strcat (tmp, " ");
+       }
+       mcrypt_free_p (modules, count);
+
+       tmp2 = emalloc (2048);
+       memset (tmp2, 0, sizeof(tmp2));
+       modules = mcrypt_list_modes (INI_STR("mcrypt.modes_dir"), &count);
+       if (count == 0) {
+               strcpy (tmp2, "none");
+       }
+       for (i = 0; i < count; i++) {
+               strcat (tmp2, modules[i]);
+               strcat (tmp2, " ");
+       }
+       mcrypt_free_p (modules, count);
+#endif
+
+       php_info_print_table_start();
+       php_info_print_table_header(2, "mcrypt support", "enabled");
+#if HAVE_LIBMCRYPT24
+       php_info_print_table_row(2, "API Version", ">= 20000320");
+       php_info_print_table_row(2, "Supported ciphers", tmp);
+       php_info_print_table_row(2, "Supported modes", tmp2);
+       efree (tmp2);
+       efree (tmp);
+#endif
+       php_info_print_table_end();
+       
+       DISPLAY_INI_ENTRIES();
+}
+
 typedef enum {
        RANDOM = 0,
        URANDOM,
        RAND
 } iv_source;
 
+#if HAVE_LIBMCRYPT24
+
+/* {{{ proto resource mcrypt_module_open(string cipher, string cipher_directory, string mode, string mode_directory)
+   Opens the module of the algorithm and the mode to be used */
+PHP_FUNCTION(mcrypt_module_open)
+{
+       zval **cipher, **cipher_directory, **mode, **mode_directory;
+       MCRYPT td;
+       int argc;
+    MCLS_FETCH();
+    
+       argc = ZEND_NUM_ARGS();
+       MCRYPT_CHECK_PARAM_COUNT (4,4)
+       
+       zend_get_parameters_ex(4, &cipher, &cipher_directory, &mode, &mode_directory);
+       convert_to_string_ex(cipher);
+       convert_to_string_ex(cipher_directory);
+       convert_to_string_ex(mode);
+       convert_to_string_ex(mode_directory);
+       
+       td = mcrypt_module_open ((*cipher)->value.str.val,
+               (*cipher_directory)->value.str.len > 0 ? (*cipher_directory)->value.str.val : INI_STR("mcrypt.algorithms_dir"),
+               (*mode)->value.str.val, 
+               (*mode_directory)->value.str.len > 0 ? (*mode_directory)->value.str.val : INI_STR("mcrypt.modes_dir"));
+
+       if (td == MCRYPT_FAILED) {
+               php_error (E_WARNING, "could not open encryption module");
+               RETURN_FALSE;
+       } else {
+               ZEND_REGISTER_RESOURCE (return_value, td, MCG(le_h));
+       }
+}
+/* }}} */
+
+
+/* {{{ proto int mcrypt_generic_init(resource td, string key, string iv)
+   This function initializes all buffers for the specific module */
+PHP_FUNCTION(mcrypt_generic_init)
+{
+       zval **key, **iv;
+       zval **mcryptind;
+       char *key_s, *iv_s;
+       int key_size, iv_size;
+       MCRYPT td;
+       int argc;
+    MCLS_FETCH();
+       
+       argc = ZEND_NUM_ARGS();
+       MCRYPT_CHECK_PARAM_COUNT (3,3)
+       
+       zend_get_parameters_ex(3, &mcryptind, &key, &iv);
+       ZEND_FETCH_RESOURCE (td, MCRYPT, mcryptind, -1, "MCrypt", MCG(le_h));                           
+       convert_to_string_ex (key);
+       convert_to_string_ex (iv);
+
+       key_size = mcrypt_enc_get_key_size (td);
+       key_s = emalloc (key_size + 1);
+       memset (key_s, 0, key_size + 1);
+
+       iv_size = mcrypt_enc_get_iv_size (td);
+       iv_s = emalloc (iv_size + 1);
+       memset (iv_s, 0, iv_size + 1);
+
+       if ((*key)->value.str.len != key_size) {
+               php_error (E_WARNING, "key size is incorrect");
+       }
+       strncpy (key_s, (*key)->value.str.val, key_size);
+
+       if ((*iv)->value.str.len != iv_size) {
+               php_error (E_WARNING, "iv size is incorrect");
+       }
+       strncpy (iv_s, (*iv)->value.str.val, iv_size);
+
+       RETVAL_LONG (mcrypt_generic_init (td, key_s, key_size, iv_s));
+       efree (iv_s);
+       efree (key_s);
+}
+/* }}} */
+
+
+/* {{{ proto string mcrypt_generic(resource td, string data)
+   This function encrypts the plaintext */
+PHP_FUNCTION(mcrypt_generic)
+{
+       zval **data, **mcryptind;
+       MCRYPT td;
+       int argc;
+       char* data_s;
+       int block_size, data_size;
+    MCLS_FETCH();
+       
+       argc = ZEND_NUM_ARGS();
+       MCRYPT_CHECK_PARAM_COUNT (2,2)
+       
+       zend_get_parameters_ex(2, &mcryptind, &data);
+       ZEND_FETCH_RESOURCE (td, MCRYPT, mcryptind, -1, "MCrypt", MCG(le_h));                           
+       convert_to_string_ex (data);
+
+       /* Check blocksize */
+       if (mcrypt_enc_is_block_algorithm (td) == 1) { /* It's a block algorithm */
+               block_size = mcrypt_enc_get_block_size (td);
+               data_size = ((((*data)->value.str.len - 1) / block_size) + 1) * block_size;
+               data_s = emalloc (data_size);
+               memset (data_s, 0, data_size);
+               memcpy (data_s, (*data)->value.str.val, (*data)->value.str.len);
+       }
+       else { /* It's not a block algorithm */
+               data_size = (*data)->value.str.len;
+               data_s = emalloc (data_size);
+               memset (data_s, 0, data_size);
+               memcpy (data_s, (*data)->value.str.val, (*data)->value.str.len);
+       }
+       
+       mcrypt_generic (td, data_s, data_size);
+
+       RETVAL_STRINGL (data_s, data_size, 1);
+       efree (data_s);
+}
+/* }}} */
+
+
+/* {{{ proto string mdecrypt_generic(resource td, string data)
+   This function decrypts the plaintext */
+PHP_FUNCTION(mdecrypt_generic)
+{
+       zval **data, **mcryptind;
+       MCRYPT td;
+       int argc;
+       char* data_s;
+       int block_size, data_size;
+    MCLS_FETCH();
+       
+       argc = ZEND_NUM_ARGS();
+       MCRYPT_CHECK_PARAM_COUNT (2,2)
+       
+       zend_get_parameters_ex(2, &mcryptind, &data);
+       ZEND_FETCH_RESOURCE (td, MCRYPT, mcryptind, -1, "MCrypt", MCG(le_h));                           
+       convert_to_string_ex (data);
+
+       /* Check blocksize */
+       if (mcrypt_enc_is_block_algorithm (td) == 1) { /* It's a block algorithm */
+               block_size = mcrypt_enc_get_block_size (td);
+               data_size = ((((*data)->value.str.len - 1) / block_size) + 1) * block_size;
+               data_s = emalloc (data_size);
+               memset (data_s, 0, data_size);
+               memcpy (data_s, (*data)->value.str.val, (*data)->value.str.len);
+       }
+       else { /* It's not a block algorithm */
+               data_size = (*data)->value.str.len;
+               data_s = emalloc (data_size);
+               memset (data_s, 0, data_size);
+               memcpy (data_s, (*data)->value.str.val, (*data)->value.str.len);
+       }
+       
+       mdecrypt_generic (td, data_s, data_size);
+
+       RETVAL_STRINGL (data_s, data_size, 1);
+       efree (data_s);
+}
+/* }}} */
+
+
+/* {{{ proto int mcrypt_enc_get_supported_key_sizes(resource td)
+   This function decrypts the crypttext */
+PHP_FUNCTION(mcrypt_enc_get_supported_key_sizes)
+{
+       zval **mcryptind;
+       MCRYPT td;
+       int argc, i, count;
+       int *key_sizes;
+    MCLS_FETCH();
+       
+       argc = ZEND_NUM_ARGS();
+       MCRYPT_GET_TD_ARG
+
+       key_sizes = mcrypt_enc_get_supported_key_sizes (td, &count);
+
+       if (array_init(return_value) == FAILURE) {
+               php_error(E_ERROR, "Unable to initialize array");
+               return;
+       }
+       if (count != 0) {
+               for (i = 0; i < count; i++) {
+                       add_index_long(return_value, i, key_sizes[i]);
+               }
+       }
+       mcrypt_free (key_sizes);
+}
+/* }}} */
+
+
+/* {{{ proto int mcrypt_enc_self_test(resource td)
+   This function runs the self test on the algorithm specified by the descriptor td */
+PHP_FUNCTION(mcrypt_enc_self_test)
+{
+       zval **mcryptind;
+       MCRYPT td;
+    MCLS_FETCH();
+       
+       MCRYPT_GET_TD_ARG
+
+       RETURN_LONG (mcrypt_enc_self_test (td));
+}
+/* }}} */
+
+
+PHP_FUNCTION(mcrypt_module_close)
+{
+       zval **mcryptind;
+    int id;
+       MCRYPT td;
+    MCLS_FETCH();
+       
+       MCRYPT_GET_TD_ARG
+
+       if (mcrypt_module_close (td) == -1) {
+               php_error (E_WARNING, "could not close module");
+               RETURN_FALSE
+       } else {
+               zend_list_delete ((*mcryptind)->value.lval);
+               RETURN_TRUE
+       }
+}
+
+
+/* {{{ proto bool mcrypt_generic_end(resource td)
+   This function terminates encrypt specified by the descriptor td */
+PHP_FUNCTION(mcrypt_generic_end)
+{
+       zval **mcryptind;
+       MCRYPT td;
+    MCLS_FETCH();
+       
+       MCRYPT_GET_TD_ARG
+
+       if (mcrypt_generic_end (td) == -1) {
+               php_error (E_WARNING, "could not terminate encryption specifier");
+               RETURN_FALSE
+       }
+       RETURN_TRUE
+}
+/* }}} */
+
+
+/* {{{ proto bool mcrypt_enc_is_block_algorithm_mode(resource td)
+   Returns TRUE if the mode is for use with block algorithms */
+PHP_FUNCTION(mcrypt_enc_is_block_algorithm_mode)
+{
+       zval **mcryptind;
+       MCRYPT td;
+    MCLS_FETCH();
+       
+       MCRYPT_GET_TD_ARG
+
+       if (mcrypt_enc_is_block_algorithm_mode (td) == 1)
+               RETURN_TRUE
+       else
+               RETURN_FALSE
+}
+/* }}} */
+
+
+/* {{{ proto bool mcrypt_enc_is_block_algorithm(resource td)
+   Returns TRUE if the alrogithm is a block algorithms */
+PHP_FUNCTION(mcrypt_enc_is_block_algorithm)
+{
+       zval **mcryptind;
+       MCRYPT td;
+    MCLS_FETCH();
+       
+       MCRYPT_GET_TD_ARG
+
+       if (mcrypt_enc_is_block_algorithm (td) == 1)
+               RETURN_TRUE
+       else
+               RETURN_FALSE
+}
+/* }}} */
+
+
+/* {{{ proto bool mcrypt_enc_is_block_mode(resource td)
+   Returns TRUE if the mode outputs blocks */
+PHP_FUNCTION(mcrypt_enc_is_block_mode)
+{
+       zval **mcryptind;
+       MCRYPT td;
+    MCLS_FETCH();
+       
+       MCRYPT_GET_TD_ARG
+
+       if (mcrypt_enc_is_block_mode (td) == 1)
+               RETURN_TRUE
+       else
+               RETURN_FALSE
+}
+/* }}} */
+
+
+/* {{{ proto int mcrypt_enc_get_block_size(resource td)
+   Returns the block size of the cipher specified by the descriptor td */
+PHP_FUNCTION(mcrypt_enc_get_block_size)
+{
+       zval **mcryptind;
+       MCRYPT td;
+    MCLS_FETCH();
+       
+       MCRYPT_GET_TD_ARG
+
+       RETURN_LONG (mcrypt_enc_get_block_size (td));
+}
+/* }}} */
+
+
+/* {{{ proto int mcrypt_enc_get_key_size(resource td)
+   Returns the maximum supported key size in bytes of the algorithm specified by the descriptor td */
+PHP_FUNCTION(mcrypt_enc_get_key_size)
+{
+       zval **mcryptind;
+       MCRYPT td;
+    MCLS_FETCH();
+       
+       MCRYPT_GET_TD_ARG
+
+       RETURN_LONG (mcrypt_enc_get_key_size (td));
+}
+/* }}} */
+
+
+/* {{{ proto int mcrypt_enc_get_iv_size(resource td)
+   Returns the size of the IV in bytes of the algorithm specified by the descriptor td */
+PHP_FUNCTION(mcrypt_enc_get_iv_size)
+{
+       zval **mcryptind;
+       MCRYPT td;
+    MCLS_FETCH();
+       
+       MCRYPT_GET_TD_ARG
+
+       RETURN_LONG (mcrypt_enc_get_iv_size (td));
+}
+/* }}} */
+
+
+/* {{{ proto string mcrypt_enc_get_algorithms_name(resource td)
+   Returns the name of the algorithm specified by the descriptor td */
+PHP_FUNCTION(mcrypt_enc_get_algorithms_name)
+{
+       zval **mcryptind;
+       MCRYPT td;
+       char *name;
+    MCLS_FETCH();
+       
+       MCRYPT_GET_TD_ARG
+
+       name = mcrypt_enc_get_algorithms_name (td);
+       RETVAL_STRING (name, 1);
+       mcrypt_free (name);
+}
+/* }}} */
+
+
+/* {{{ proto string mcrypt_enc_get_modes_name(resource td)
+   Returns the name of the mode specified by the descriptor td */
+PHP_FUNCTION(mcrypt_enc_get_modes_name)
+{
+       zval **mcryptind;
+       MCRYPT td;
+       char *name;
+    MCLS_FETCH();
+       
+       MCRYPT_GET_TD_ARG
+
+       name = mcrypt_enc_get_modes_name (td);
+       RETVAL_STRING (name, 1);
+       mcrypt_free (name);
+}
+/* }}} */
+
+
+/* {{{ proto bool mcrypt_module_self_test(string algorithm [, string lib_dir])
+   Does a self test of the module "module" */
+PHP_FUNCTION(mcrypt_module_self_test)
+{
+       zval **arg1, **lib_dir;
+       char *lib_dir_s;
+       int argc;
+       
+       argc = ZEND_NUM_ARGS();
+
+       MCRYPT_GET_MODE_DIR_ARGS("mcrypt.algorithms_dir");
+       
+       if (mcrypt_module_self_test ((*arg1)->value.str.val, lib_dir_s) == 0) {
+               RETURN_TRUE;
+       }
+       else {
+               RETURN_FALSE;
+       }
+}
+/* }}} */
+
+
+/* {{{ proto bool mcrypt_module_is_block_algorithm_mode(string mode [, string lib_dir])
+   Returns TRUE if the mode is for use with block algorithms */
+PHP_FUNCTION(mcrypt_module_is_block_algorithm_mode)
+{
+       zval **arg1, **lib_dir;
+       char *lib_dir_s;
+       int argc;
+       
+       argc = ZEND_NUM_ARGS();
+
+       MCRYPT_GET_MODE_DIR_ARGS("mcrypt.modes_dir")
+       
+       if (mcrypt_module_is_block_algorithm_mode ((*arg1)->value.str.val, lib_dir_s) == 0) {
+               RETURN_TRUE;
+       }
+       else {
+               RETURN_FALSE;
+       }
+}
+/* }}} */
+
+
+/* {{{ proto bool mcrypt_module_is_block_algorithm(string algorithm [, string lib_dir])
+   Returns TRUE if the algorithm is a block algorithm */
+PHP_FUNCTION(mcrypt_module_is_block_algorithm)
+{
+       zval **arg1, **lib_dir;
+       char *lib_dir_s;
+       int argc;
+       
+       argc = ZEND_NUM_ARGS();
+
+       MCRYPT_GET_MODE_DIR_ARGS("mcrypt.algorithms_dir")
+       
+       if (mcrypt_module_is_block_algorithm ((*arg1)->value.str.val, lib_dir_s) == 0) {
+               RETURN_TRUE;
+       }
+       else {
+               RETURN_FALSE;
+       }
+}
+/* }}} */
+
+
+/* {{{ proto bool mcrypt_module_is_block_mode(string mode [, string lib_dir])
+   Returns TRUE if the mode outputs blocks of bytes */
+PHP_FUNCTION(mcrypt_module_is_block_mode)
+{
+       zval **arg1, **lib_dir;
+       char *lib_dir_s;
+       int argc;
+       
+       argc = ZEND_NUM_ARGS();
+
+       MCRYPT_GET_MODE_DIR_ARGS("mcrypt.modes_dir")
+       
+       if (mcrypt_module_is_block_mode ((*arg1)->value.str.val, lib_dir_s) == 0) {
+               RETURN_TRUE;
+       }
+       else {
+               RETURN_FALSE;
+       }
+}
+/* }}} */
+
+
+/* {{{ proto int mcrypt_module_get_algo_block_size(string algorithm [, string lib_dir])
+   Returns the block size of the algorithm */
+PHP_FUNCTION(mcrypt_module_get_algo_block_size)
+{
+       zval **arg1, **lib_dir;
+       char *lib_dir_s;
+       int argc;
+       
+       argc = ZEND_NUM_ARGS();
+
+       MCRYPT_GET_MODE_DIR_ARGS("mcrypt.algorithms_dir")
+       
+       RETURN_LONG(mcrypt_module_get_algo_block_size ((*arg1)->value.str.val, lib_dir_s))
+}
+/* }}} */
+
+
+/* {{{ proto int mcrypt_module_get_algo_key_size(string algorithm [, string lib_dir])
+   Returns the maximum supported key size of the algorithm */
+PHP_FUNCTION(mcrypt_module_get_algo_key_size)
+{
+       zval **arg1, **lib_dir;
+       char *lib_dir_s;
+       int argc;
+       
+       argc = ZEND_NUM_ARGS();
+
+       MCRYPT_GET_MODE_DIR_ARGS("mcrypt.algorithms_dir");
+       
+       RETURN_LONG(mcrypt_module_get_algo_key_size ((*arg1)->value.str.val, lib_dir_s))
+}
+/* }}} */
+
+
+/* {{{ proto int mcrypt_module_get_supported_key_sizes(string algorithm [, string lib_dir])
+   This function decrypts the crypttext */
+PHP_FUNCTION(mcrypt_module_get_supported_key_sizes)
+{
+       zval **arg1, **lib_dir;
+       char *lib_dir_s;
+       int argc, i, count;
+       int *key_sizes;
+       
+       argc = ZEND_NUM_ARGS();
+
+       MCRYPT_GET_MODE_DIR_ARGS("mcrypt.algorithms_dir")
+
+       key_sizes = mcrypt_module_get_algo_supported_key_sizes ((*arg1)->value.str.val, lib_dir_s, &count);
+
+       if (array_init(return_value) == FAILURE) {
+               php_error(E_ERROR, "Unable to initialize array");
+               return;
+       }
+       if (count != 0) {
+               for (i = 0; i < count; i++) {
+                       add_index_long(return_value, i, key_sizes[i]);
+               }
+       }
+       mcrypt_free (key_sizes);
+}
+/* }}} */
+
+
+/* {{{ proto array mcrypt_list_algorithms([string lib_dir])
+   List all algorithms in "module_dir" */
+PHP_FUNCTION(mcrypt_list_algorithms)
+{
+       zval **lib_dir;
+       char **modules;
+       char *lib_dir_s;
+       int i, count, argc;
+
+       argc = ZEND_NUM_ARGS();
+       MCRYPT_CHECK_PARAM_COUNT (0,1)
+       
+       switch (argc) {
+               case 1:
+                       if (zend_get_parameters_ex (1, &lib_dir) == FAILURE) {
+                               WRONG_PARAM_COUNT
+                       }
+                       convert_to_string_ex (lib_dir);
+                       lib_dir_s = (*lib_dir)->value.str.val;
+                       break;
+               case 0:
+                       lib_dir_s = INI_STR("mcrypt.algorithms_dir");
+                       break;
+               default:
+                       WRONG_PARAM_COUNT
+       }       
+
+       modules = mcrypt_list_algorithms (lib_dir_s, &count);
+
+       if (array_init(return_value) == FAILURE) {
+               php_error(E_ERROR, "Unable to initialize array");
+               return;
+       }
+       if (count == 0) {
+               php_error (E_WARNING, "No algorithms found in module dir");
+       }
+       for (i = 0; i < count; i++) {
+               add_index_string(return_value, i, modules[i], 1);
+       }
+       mcrypt_free_p (modules, count);
+}
+/* }}} */
+
+
+/* {{{ proto array mcrypt_list_modes([string lib_dir])
+   List all modes "module_dir" */
+PHP_FUNCTION(mcrypt_list_modes)
+{
+       zval **lib_dir;
+       char **modules;
+       char *lib_dir_s;
+       int i, count, argc;
+
+       argc = ZEND_NUM_ARGS();
+       MCRYPT_CHECK_PARAM_COUNT (0,1)
+       
+       switch (argc) {
+               case 1:
+                       if (zend_get_parameters_ex (1, &lib_dir) == FAILURE) {
+                               WRONG_PARAM_COUNT
+                       }
+                       convert_to_string_ex (lib_dir);
+                       lib_dir_s = (*lib_dir)->value.str.val;
+                       break;
+               case 0:
+                       lib_dir_s = INI_STR("mcrypt.modes_dir");
+                       break;
+               default:
+                       WRONG_PARAM_COUNT
+       }       
+
+       modules = mcrypt_list_modes (lib_dir_s, &count);
+
+       if (array_init(return_value) == FAILURE) {
+               php_error(E_ERROR, "Unable to initialize array");
+               return;
+       }
+       if (count == 0) {
+               php_error (E_WARNING, "No modes found in module dir");
+       }
+       for (i = 0; i < count; i++) {
+               add_index_string(return_value, i, modules[i], 1);
+       }
+       mcrypt_free_p (modules, count);
+}
+/* }}} */
+
+
+/* {{{ proto int mcrypt_get_key_size(string cipher, string module)
+   Get the key size of cipher */
+PHP_FUNCTION(mcrypt_get_key_size)
+{
+       zval **cipher;
+       zval **module;
+       char *cipher_dir_string;
+       char *module_dir_string;
+       long key_size;
+       MCRYPT td;
+
+       MCRYPT_GET_INI
+
+       if (ZEND_NUM_ARGS() != 2 || zend_get_parameters_ex(2, &cipher, &module) == FAILURE) {
+               WRONG_PARAM_COUNT;
+       }
+
+       convert_to_string_ex(cipher);
+       convert_to_string_ex(module);
+       
+       td = mcrypt_module_open(
+               (*cipher)->value.str.val, 
+               cipher_dir_string,
+               (*module)->value.str.val,
+               module_dir_string);
+       if (td != MCRYPT_FAILED)
+       {
+               key_size = mcrypt_enc_get_key_size(td);
+               mcrypt_module_close(td);
+               RETVAL_LONG(key_size);
+       }
+       else
+       {
+               php_error (E_WARNING, MCRYPT_OPEN_MODULE_FAILED);
+               RETVAL_LONG(0);
+       }
+}
+/* }}} */
+
+
+/* {{{ proto int mcrypt_get_block_size(string cipher, string module)
+   Get the key size of cipher */
+PHP_FUNCTION(mcrypt_get_block_size)
+{
+       zval **cipher;
+       zval **module;
+       char *cipher_dir_string;
+       char *module_dir_string;
+       long key_size;
+       MCRYPT td;
+
+       MCRYPT_GET_INI
+
+       if (ZEND_NUM_ARGS() != 2 || zend_get_parameters_ex(2, &cipher, &module) == FAILURE) {
+               WRONG_PARAM_COUNT;
+       }
+
+       convert_to_string_ex(cipher);
+       convert_to_string_ex(module);
+       
+       td = mcrypt_module_open(
+               (*cipher)->value.str.val, 
+               cipher_dir_string,
+               (*module)->value.str.val,
+               module_dir_string);
+       if (td != MCRYPT_FAILED)
+       {
+               key_size = mcrypt_enc_get_block_size(td);
+               mcrypt_module_close(td);
+               RETVAL_LONG(key_size);
+       }
+       else
+       {
+               php_error (E_WARNING, MCRYPT_OPEN_MODULE_FAILED);
+               RETVAL_LONG(0);
+       }
+}
+/* }}} */
+
+
+/* {{{ proto int mcrypt_get_iv_size(string cipher, string module)
+   Get the IV size of cipher (Usually the same as the blocksize) */
+PHP_FUNCTION(mcrypt_get_iv_size)
+{
+       zval **cipher;
+       zval **module;
+       char *cipher_dir_string;
+       char *module_dir_string;
+       long key_size;
+       MCRYPT td;
+
+       MCRYPT_GET_INI
+
+       if (ZEND_NUM_ARGS() != 2 || zend_get_parameters_ex(2, &cipher, &module) == FAILURE) {
+               WRONG_PARAM_COUNT;
+       }
+
+       convert_to_string_ex(cipher);
+       convert_to_string_ex(module);
+       
+       td = mcrypt_module_open(
+               (*cipher)->value.str.val, 
+               cipher_dir_string,
+               (*module)->value.str.val,
+               module_dir_string);
+       if (td != MCRYPT_FAILED)
+       {
+               key_size = mcrypt_enc_get_iv_size(td);
+               mcrypt_module_close(td);
+               RETURN_LONG(key_size);
+       }
+       else
+       {
+               php_error (E_WARNING, MCRYPT_OPEN_MODULE_FAILED);
+               RETURN_FALSE;
+       }
+}
+/* }}} */
+
+
+/* {{{ proto string mcrypt_get_cipher_name(string cipher)
+   Get the key size of cipher */
+PHP_FUNCTION(mcrypt_get_cipher_name)
+{
+       zval **cipher;
+       char *cipher_dir_string;
+       char *module_dir_string;
+       char *cipher_name;
+       MCRYPT td;
+
+       MCRYPT_GET_INI
+
+       if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &cipher) == FAILURE) {
+               WRONG_PARAM_COUNT;
+       }
+
+       convert_to_string_ex(cipher);
+
+       /* The code below is actually not very nice, but I didn see a better method */
+       td = mcrypt_module_open(
+               (*cipher)->value.str.val, 
+               cipher_dir_string,
+               "ecb",
+               module_dir_string);
+       if (td != MCRYPT_FAILED)
+       {
+               cipher_name = mcrypt_enc_get_algorithms_name(td);
+               mcrypt_module_close(td);
+               RETVAL_STRING(cipher_name,1);
+               mcrypt_free (cipher_name);
+       }
+       else
+       {
+               td = mcrypt_module_open(
+                       (*cipher)->value.str.val, 
+                       cipher_dir_string,
+                       "stream",
+                       module_dir_string);
+               if (td != MCRYPT_FAILED)
+               {
+                       cipher_name = mcrypt_enc_get_algorithms_name(td);
+                       mcrypt_module_close(td);
+                       RETVAL_STRING(cipher_name,1);
+                       mcrypt_free (cipher_name);
+               }
+               else
+               {
+                       php_error (E_WARNING, MCRYPT_OPEN_MODULE_FAILED);
+                       RETURN_FALSE;
+               }
+       }
+}
+/* }}} */
+
+
+static void php_mcrypt_do_crypt (char* cipher, zval **key, zval **data, char *mode, zval **iv, int argc, int dencrypt, zval* return_value)
+{
+       char *cipher_dir_string;
+       char *module_dir_string;
+       int block_size, max_key_length, use_key_length, i, count, iv_size;
+       unsigned long int data_size;
+       int *key_length_sizes;
+       char *key_s, *iv_s;
+       char *data_s;
+       MCRYPT td;
+
+       MCRYPT_GET_INI
+
+       td = mcrypt_module_open (
+               cipher, 
+               cipher_dir_string, 
+               mode, 
+               module_dir_string);
+       if (td == MCRYPT_FAILED) {
+               php_error (E_WARNING, MCRYPT_OPEN_MODULE_FAILED);
+               RETURN_FALSE;
+       }
+       /* Checking for key-length */
+       max_key_length = mcrypt_enc_get_key_size (td);
+       if ((*key)->value.str.len > max_key_length) {
+               php_error (E_WARNING, "size of key is too large for this algorithm");
+       }
+       key_length_sizes = mcrypt_enc_get_supported_key_sizes (td, &count);
+       if (count == 0 && key_length_sizes == NULL) { /* all lengths 1 - k_l_s = OK */
+               key_s = estrdup ((*key)->value.str.val);
+               use_key_length = (*key)->value.str.len;
+       }
+       else if (count == 1) {  /* only m_k_l = OK */
+               key_s = emalloc (key_length_sizes[0]);
+               memset (key_s, 0, key_length_sizes[0]);
+               strcpy (key_s, (*key)->value.str.val);
+               use_key_length = key_length_sizes[0];
+       }
+       else { /* derterminating smallest supported key > length of requested key */
+               use_key_length = max_key_length; /* start with max key length */
+               for (i = 0; i < count; i++) {
+                       if (key_length_sizes[i] >= (*key)->value.str.len && 
+                               key_length_sizes[i] < use_key_length)
+                       {
+                               use_key_length = key_length_sizes[i];
+                       }
+               }
+               key_s = emalloc (use_key_length);
+               memset (key_s, 0, use_key_length);
+               strcpy (key_s, (*key)->value.str.val);
+       }
+       mcrypt_free (key_length_sizes);
+       
+       /* Check IV */
+       iv_s = NULL;
+       iv_size = mcrypt_enc_get_iv_size (td);
+       if (argc == 5) {
+               if (iv_size != (*iv)->value.str.len) {
+                       php_error (E_WARNING, MCRYPT_IV_WRONG_SIZE);
+                       
+               }
+               else {
+                       iv_s = emalloc (iv_size + 1);
+                       memcpy (iv_s, (*iv)->value.str.val, iv_size);
+               }
+       }
+       else if (argc == 4)
+       {
+               if (iv_size != 0) {
+                       php_error (E_WARNING, "attempt to use an empty IV, which is NOT recommend");
+                       iv_s = emalloc (iv_size + 1);
+                       memset (iv_s, 0, iv_size + 1);
+               }
+       }
+
+       /* Check blocksize */
+       if (mcrypt_enc_is_block_algorithm (td) == 1) { /* It's a block algorithm */
+               block_size = mcrypt_enc_get_block_size (td);
+               data_size = ((((*data)->value.str.len - 1) / block_size) + 1) * block_size;
+               data_s = emalloc (data_size);
+               memset (data_s, 0, data_size);
+               memcpy (data_s, (*data)->value.str.val, (*data)->value.str.len);
+       }
+       else { /* It's not a block algorithm */
+               data_size = (*data)->value.str.len;
+               data_s = emalloc (data_size);
+               memset (data_s, 0, data_size);
+               memcpy (data_s, (*data)->value.str.val, (*data)->value.str.len);
+       }
+       
+       if (mcrypt_generic_init (td, key_s, use_key_length, iv_s) == -1) {
+               php_error (E_ERROR, "generic_init failed");
+       }
+       if (dencrypt == MCRYPT_ENCRYPT)
+               mcrypt_generic (td, data_s, data_size);
+       else
+               mdecrypt_generic (td, data_s, data_size);
+       
+       RETVAL_STRINGL (data_s, data_size, 1);
+
+/* freeing vars */
+       mcrypt_generic_end (td);
+       if (iv_s != NULL)
+               efree (iv_s);
+       efree (data_s);
+       mcrypt_module_close (td);
+}
+
+/* {{{ proto string mcrypt_encrypt(string cipher, string key, string data, string mode, string iv)
+   OFB crypt/decrypt data using key key with cipher cipher starting with iv */
+PHP_FUNCTION(mcrypt_encrypt)
+{
+       zval **cipher, **key, **data, **mode, **iv;
+       int argc;
+       
+       argc = ZEND_NUM_ARGS();
+       
+       MCRYPT_CHECK_PARAM_COUNT (4, 5)
+       MCRYPT_GET_CRYPT_ARGS
+
+       MCRYPT_CONVERT;
+
+       php_mcrypt_do_crypt ((*cipher)->value.str.val, key, data, (*mode)->value.str.val, iv, argc, MCRYPT_ENCRYPT, return_value);
+}
+
+
+/* {{{ proto string mcrypt_decrypt(string cipher, string key, string data, string mode, string iv)
+   OFB crypt/decrypt data using key key with cipher cipher starting with iv */
+PHP_FUNCTION(mcrypt_decrypt)
+{
+       zval **cipher, **key, **data, **mode, **iv;
+       int argc;
+       
+       argc = ZEND_NUM_ARGS();
+
+       MCRYPT_CHECK_PARAM_COUNT (4, 5)
+       MCRYPT_GET_CRYPT_ARGS
+
+       MCRYPT_CONVERT;
+
+       php_mcrypt_do_crypt ((*cipher)->value.str.val, key, data, (*mode)->value.str.val, iv, argc, MCRYPT_DECRYPT, return_value);
+}
+
+
+/* {{{ proto string mcrypt_ecb(int cipher, string key, string data, int mode, string iv)
+   ECB crypt/decrypt data using key key with cipher cipher starting with iv */
+PHP_FUNCTION(mcrypt_ecb)
+{
+       zval **cipher, **key, **data, **mode, **iv;
+       int argc;
+       
+       argc = ZEND_NUM_ARGS();
+
+       MCRYPT_CHECK_PARAM_COUNT (4, 5)
+       MCRYPT_GET_CRYPT_ARGS
+
+       MCRYPT_CONVERT_WO_MODE;
+       convert_to_long_ex(mode);
+
+       php_mcrypt_do_crypt ((*cipher)->value.str.val, key, data, "ecb", iv, argc, (*mode)->value.lval, return_value);
+}
+
+
+/* {{{ proto string mcrypt_cbc(int cipher, string key, string data, int mode, string iv)
+   CBC crypt/decrypt data using key key with cipher cipher starting with iv */
+PHP_FUNCTION(mcrypt_cbc)
+{
+       zval **cipher, **key, **data, **mode, **iv;
+       int argc;
+       
+       argc = ZEND_NUM_ARGS();
+
+       MCRYPT_CHECK_PARAM_COUNT (4, 5)
+       MCRYPT_GET_CRYPT_ARGS
+
+       MCRYPT_CONVERT_WO_MODE;
+       convert_to_long_ex(mode);
+
+       php_mcrypt_do_crypt ((*cipher)->value.str.val, key, data, "cbc", iv, argc, (*mode)->value.lval, return_value);
+}
+
+
+/* {{{ proto string mcrypt_cfb(int cipher, string key, string data, int mode, string iv)
+   CFB crypt/decrypt data using key key with cipher cipher starting with iv */
+PHP_FUNCTION(mcrypt_cfb)
+{
+       zval **cipher, **key, **data, **mode, **iv;
+       int argc;
+       
+       argc = ZEND_NUM_ARGS();
+
+       MCRYPT_CHECK_PARAM_COUNT (4, 5)
+       MCRYPT_GET_CRYPT_ARGS
+
+       MCRYPT_CONVERT_WO_MODE;
+       convert_to_long_ex(mode);
+
+       php_mcrypt_do_crypt ((*cipher)->value.str.val, key, data, "cfb", iv, argc, (*mode)->value.lval, return_value);
+}
+
+
+/* {{{ proto string mcrypt_ofb(int cipher, string key, string data, int mode, string iv)
+   OFB crypt/decrypt data using key key with cipher cipher starting with iv */
+PHP_FUNCTION(mcrypt_ofb)
+{
+       zval **cipher, **key, **data, **mode, **iv;
+       int argc;
+       
+       argc = ZEND_NUM_ARGS();
+
+       MCRYPT_CHECK_PARAM_COUNT (4, 5)
+       MCRYPT_GET_CRYPT_ARGS
+
+       MCRYPT_CONVERT_WO_MODE;
+       convert_to_long_ex(mode);
+
+       php_mcrypt_do_crypt ((*cipher)->value.str.val, key, data, "ofb", iv, argc, (*mode)->value.lval, return_value);
+}
+
+#endif
+
 /* {{{ proto string mcrypt_create_iv(int size, int source)
    Create an initializing vector (IV) */
 PHP_FUNCTION(mcrypt_create_iv)
 {
-       pval **size, **psource;
+       zval **size, **psource;
        char *iv;
        iv_source source;
        int i;
@@ -232,11 +1465,14 @@ PHP_FUNCTION(mcrypt_create_iv)
 }
 /* }}} */
 
+
+#if HAVE_LIBMCRYPT22
+
 /* {{{ proto string mcrypt_get_cipher_name(int cipher)
    Get the name of cipher */
 PHP_FUNCTION(mcrypt_get_cipher_name)
 {
-       pval **cipher;
+       zval **cipher;
        char *str, *nstr;
 
        if(ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &cipher) == FAILURE) {
@@ -260,7 +1496,7 @@ PHP_FUNCTION(mcrypt_get_cipher_name)
    Get the key size of cipher */
 PHP_FUNCTION(mcrypt_get_key_size)
 {
-       pval **cipher;
+       zval **cipher;
 
        if(ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &cipher) == FAILURE) {
                WRONG_PARAM_COUNT;
@@ -276,7 +1512,7 @@ PHP_FUNCTION(mcrypt_get_key_size)
    Get the block size of cipher */
 PHP_FUNCTION(mcrypt_get_block_size)
 {
-       pval **cipher;
+       zval **cipher;
 
        if(ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &cipher) == FAILURE) {
                WRONG_PARAM_COUNT;
@@ -384,4 +1620,6 @@ PHP_FUNCTION(mcrypt_ecb)
 }
 /* }}} */
 
+#endif /* MCRYPT_2_2 */
+
 #endif
index 87585ae2cc8fa35508f397a625d58b62db31f3be..be1196636b3abdc2ca3cabdb5e1d91f18e81532b 100644 (file)
@@ -3,6 +3,10 @@
 
 #if HAVE_LIBMCRYPT
 
+#ifdef ZTS
+#include "TSRM.h"
+#endif
+
 #if PHP_API_VERSION < 19990421
 #define  zend_module_entry zend_module_entry
 #include "modules.h"
 #endif
 
 extern zend_module_entry mcrypt_module_entry;
+
 #define mcrypt_module_ptr &mcrypt_module_entry
 
+/* Functions for both old and new API */
 PHP_FUNCTION(mcrypt_ecb);
 PHP_FUNCTION(mcrypt_cbc);
 PHP_FUNCTION(mcrypt_cfb);
@@ -21,6 +27,67 @@ PHP_FUNCTION(mcrypt_get_block_size);
 PHP_FUNCTION(mcrypt_get_key_size);
 PHP_FUNCTION(mcrypt_create_iv);
 
+#if HAVE_LIBMCRYPT24
+/* Support functions for old API */
+PHP_FUNCTION(mcrypt_list_algorithms);
+PHP_FUNCTION(mcrypt_list_modes);
+PHP_FUNCTION(mcrypt_get_iv_size);
+PHP_FUNCTION(mcrypt_encrypt);
+PHP_FUNCTION(mcrypt_decrypt);
+
+/* Functions for new API */
+PHP_FUNCTION(mcrypt_module_open);
+PHP_FUNCTION(mcrypt_generic_init);
+PHP_FUNCTION(mcrypt_generic);
+PHP_FUNCTION(mdecrypt_generic);
+PHP_FUNCTION(mcrypt_generic_end);
+PHP_FUNCTION(mcrypt_enc_self_test);
+PHP_FUNCTION(mcrypt_enc_is_block_algorithm_mode);
+PHP_FUNCTION(mcrypt_enc_is_block_algorithm);
+PHP_FUNCTION(mcrypt_enc_is_block_mode);
+PHP_FUNCTION(mcrypt_enc_get_block_size);
+PHP_FUNCTION(mcrypt_enc_get_key_size);
+PHP_FUNCTION(mcrypt_enc_get_supported_key_sizes);
+PHP_FUNCTION(mcrypt_enc_get_iv_size);
+PHP_FUNCTION(mcrypt_enc_get_algorithms_name);
+PHP_FUNCTION(mcrypt_enc_get_modes_name);
+PHP_FUNCTION(mcrypt_module_self_test);
+PHP_FUNCTION(mcrypt_module_is_block_algorithm_mode);
+PHP_FUNCTION(mcrypt_module_is_block_algorithm);
+PHP_FUNCTION(mcrypt_module_is_block_mode);
+PHP_FUNCTION(mcrypt_module_get_algo_block_size);
+PHP_FUNCTION(mcrypt_module_get_algo_key_size);
+PHP_FUNCTION(mcrypt_module_get_supported_key_sizes);
+PHP_FUNCTION(mcrypt_module_close);
+
+#ifdef ZTS
+ZEND_BEGIN_MODULE_GLOBALS(mcrypt)
+       int le_h;
+ZEND_END_MODULE_GLOBALS(mcrypt)
+#else
+typedef struct mcrypt_global_struct {
+       int le_h;
+} mcrypt_global_struct;
+#endif
+
+#ifdef ZTS
+# define MCLS_D        zend_mcrypt_globals *mcrypt_globals
+# define MCLS_DC       , MCLS_D
+# define MCLS_C        mcrypt_globals
+# define MCLS_CC       , MCLS_C
+# define MCG(v)        (mcrypt_globals->v)
+# define MCLS_FETCH()  zend_mcrypt_globals *mcrypt_globals = ts_resource(mcrypt_globals_id)
+#else
+# define MCLS_D
+# define MCLS_DC
+# define MCLS_C
+# define MCLS_CC
+# define MCG(v)        (mcrypt_globals.v)
+# define MCLS_FETCH()
+#endif
+
+#endif
+
 #else
 #define mcrypt_module_ptr NULL
 #endif