📄 mcrypt.c
字号:
/* +----------------------------------------------------------------------+ | PHP Version 4 | +----------------------------------------------------------------------+ | Copyright (c) 1997-2007 The PHP Group | +----------------------------------------------------------------------+ | This source file is subject to version 3.01 of the PHP license, | | that is bundled with this package in the file LICENSE, and is | | available through the world-wide-web at the following url: | | http://www.php.net/license/3_01.txt | | If you did not receive a copy of the PHP license and are unable to | | obtain it through the world-wide-web, please send a note to | | license@php.net so we can mail you a copy immediately. | +----------------------------------------------------------------------+ | Authors: Sascha Schumann <sascha@schumann.cx> | | Derick Rethans <derick@derickrethans.nl> | +----------------------------------------------------------------------+ *//* $Id: mcrypt.c,v 1.77.4.7.4.4 2007/05/03 03:15:01 edink Exp $ */#ifdef HAVE_CONFIG_H#include "config.h"#endif#include "php.h"#if HAVE_LIBMCRYPT#include "php_mcrypt.h"#include "fcntl.h"#define NON_FREE#define MCRYPT2#include "mcrypt.h"#include "php_ini.h"#include "php_globals.h"#include "ext/standard/info.h"static int le_mcrypt;typedef struct _php_mcrypt { MCRYPT td; zend_bool init;} php_mcrypt;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_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)#if HAVE_MCRYPT_GENERIC_DEINIT PHP_FE(mcrypt_generic_deinit, NULL)#endif 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 {NULL, NULL, NULL}};static PHP_MINFO_FUNCTION(mcrypt);static PHP_MINIT_FUNCTION(mcrypt);static PHP_MSHUTDOWN_FUNCTION(mcrypt);zend_module_entry mcrypt_module_entry = { STANDARD_MODULE_HEADER, "mcrypt", mcrypt_functions, PHP_MINIT(mcrypt), PHP_MSHUTDOWN(mcrypt), NULL, NULL, PHP_MINFO(mcrypt), NO_VERSION_YET, STANDARD_MODULE_PROPERTIES,};#if HAVE_LIBMCRYPT24ZEND_DECLARE_MODULE_GLOBALS(mcrypt)#endif#ifdef COMPILE_DL_MCRYPTZEND_GET_MODULE(mcrypt)#endif#define MCRYPT_ARGS2 \ zval **cipher, **data, **key, **mode; \ int td; \ char *ndata; \ size_t bsize; \ size_t nr; \ size_t nsize#define MCRYPT_ARGS \ MCRYPT_ARGS2; \ 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(Z_LVAL_PP(cipher)); \ nr = (Z_STRLEN_PP(data) + bsize - 1) / bsize; \ nsize = nr * bsize#define MCRYPT_CHECK_TD_CPY \ if(td < 0) { \ php_error(E_WARNING, "%s(): %s", get_active_function_name(TSRMLS_C), MCRYPT_FAILED); \ RETURN_FALSE; \ } \ ndata = ecalloc(nr, bsize); \ memcpy(ndata, Z_STRVAL_PP(data), Z_STRLEN_PP(data))#define MCRYPT_CHECK_IV \ convert_to_string_ex(iv); \ if(Z_STRLEN_PP(iv) != bsize) { \ php_error(E_WARNING, "%s(): %s", get_active_function_name(TSRMLS_C), MCRYPT_IV_WRONG_SIZE); \ RETURN_FALSE; \ }#define MCRYPT_ACTION(x) \ if(Z_LVAL_PP(mode) == 0) \ mcrypt_##x(td, ndata, nsize); \ else \ mdecrypt_##x(td, ndata, nsize); \ end_mcrypt_##x(td)#define MCRYPT_IV_WRONG_SIZE "%s(): 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 = MCG(algorithms_dir); \ module_dir_string = MCG(modes_dir);#define MCRYPT_CHECK_PARAM_COUNT(a,b) \ if (argc < (a) || argc > (b)) { \ WRONG_PARAM_COUNT; \ }#define MCRYPT_CHECK_PARAM_COUNT_EX(a,b) \ if (argc < (a) || argc > (b)) { \ zend_get_parameters_ex(1, &mcryptind); \ zend_list_delete (Z_LVAL_PP(mcryptind)); \ 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 \ zval **mcryptind; \ php_mcrypt *pm; \ if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &mcryptind) == FAILURE) { \ WRONG_PARAM_COUNT \ } \ ZEND_FETCH_RESOURCE (pm, php_mcrypt *, mcryptind, -1, "MCrypt", le_mcrypt); #define MCRYPT_GET_MODE_DIR_ARGS(DIRECTORY) \ char *dir = NULL; \ int dir_len; \ char *module; \ int module_len; \ if (zend_parse_parameters (ZEND_NUM_ARGS() TSRMLS_CC, \ "s|s", &module, &module_len, &dir, &dir_len) == FAILURE) { \ return; \ } #endif#if HAVE_LIBMCRYPT22#define MCRYPT_FAILED "%s(): Initialization failed"#else#define MCRYPT_OPEN_MODULE_FAILED "%s(): 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#define PHP_MCRYPT_INIT_CHECK \ if (!pm->init) { \ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Operation disallowed prior to mcrypt_generic_init()."); \ RETURN_FALSE; \ } \#if HAVE_LIBMCRYPT24PHP_INI_BEGIN() STD_PHP_INI_ENTRY("mcrypt.algorithms_dir", NULL, PHP_INI_ALL, OnUpdateString, algorithms_dir, zend_mcrypt_globals, mcrypt_globals) STD_PHP_INI_ENTRY("mcrypt.modes_dir", NULL, PHP_INI_ALL, OnUpdateString, modes_dir, zend_mcrypt_globals, mcrypt_globals)PHP_INI_END()#endifstatic void php_mcrypt_module_dtor(zend_rsrc_list_entry *rsrc TSRMLS_DC){#if HAVE_LIBMCRYPT24 php_mcrypt *pm = (php_mcrypt *) rsrc->ptr; if (pm) { mcrypt_generic_deinit(pm->td); mcrypt_module_close(pm->td); efree(pm); pm = NULL; }#endif} static PHP_MINIT_FUNCTION(mcrypt){#if defined(ZTS) && defined(HAVE_LIBMCRYPT24) ZEND_INIT_MODULE_GLOBALS(mcrypt, NULL, NULL); Z_TYPE(mcrypt_module_entry) = type;#endif le_mcrypt = zend_register_list_destructors_ex(php_mcrypt_module_dtor, NULL, "mcrypt", module_number); /* modes for mcrypt_??? routines */ REGISTER_LONG_CONSTANT("MCRYPT_ENCRYPT", 0, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("MCRYPT_DECRYPT", 1, CONST_PERSISTENT); /* sources for mcrypt_create_iv */ REGISTER_LONG_CONSTANT("MCRYPT_DEV_RANDOM", 0, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("MCRYPT_DEV_URANDOM", 1, CONST_PERSISTENT); REGISTER_LONG_CONSTANT("MCRYPT_RAND", 2, CONST_PERSISTENT); /* ciphers */#if HAVE_LIBMCRYPT22 MCRYPT_ENTRY2(3DES); MCRYPT_ENTRY2(3WAY); MCRYPT_ENTRY2(BLOWFISH_128); MCRYPT_ENTRY2(BLOWFISH_192); MCRYPT_ENTRY2(BLOWFISH_256); MCRYPT_ENTRY2(BLOWFISH_448); MCRYPT_ENTRY2(CAST_128); MCRYPT_ENTRY2(CAST_256); MCRYPT_ENTRY2(DES); MCRYPT_ENTRY2(GOST); MCRYPT_ENTRY2(IDEA); MCRYPT_ENTRY2(LOKI97); MCRYPT_ENTRY2(RIJNDAEL_128); MCRYPT_ENTRY2(RIJNDAEL_192); MCRYPT_ENTRY2(RIJNDAEL_256); MCRYPT_ENTRY2(RC2_128); MCRYPT_ENTRY2(RC2_256); MCRYPT_ENTRY2(RC2_1024); MCRYPT_ENTRY2(RC4); MCRYPT_ENTRY2(RC6_128); MCRYPT_ENTRY2(RC6_192); MCRYPT_ENTRY2(RC6_256); MCRYPT_ENTRY2(SAFER_64); MCRYPT_ENTRY2(SAFER_128); MCRYPT_ENTRY2(SAFERPLUS); MCRYPT_ENTRY2(SERPENT_128); MCRYPT_ENTRY2(SERPENT_192); MCRYPT_ENTRY2(SERPENT_256); MCRYPT_ENTRY2(TWOFISH_128); MCRYPT_ENTRY2(TWOFISH_192); MCRYPT_ENTRY2(TWOFISH_256); MCRYPT_ENTRY2(XTEA);#endif#if HAVE_LIBMCRYPT24 MCRYPT_ENTRY2_2_4(3DES, "tripledes"); MCRYPT_ENTRY2_2_4(ARCFOUR_IV, "arcfour-iv"); MCRYPT_ENTRY2_2_4(ARCFOUR, "arcfour"); MCRYPT_ENTRY2_2_4(BLOWFISH, "blowfish"); MCRYPT_ENTRY2_2_4(BLOWFISH_COMPAT, "blowfish-compat"); 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"); REGISTER_INI_ENTRIES();#endif return SUCCESS;}static PHP_MSHUTDOWN_FUNCTION(mcrypt){ UNREGISTER_INI_ENTRIES(); return SUCCESS;}#include "ext/standard/php_smart_str.h"PHP_MINFO_FUNCTION(mcrypt){#if HAVE_LIBMCRYPT24 char **modules; int i, count; smart_str tmp1 = {0}; smart_str tmp2 = {0}; modules = mcrypt_list_algorithms (MCG(algorithms_dir), &count); if (count == 0) { smart_str_appends (&tmp1, "none"); } for (i = 0; i < count; i++) { smart_str_appends (&tmp1, modules[i]); smart_str_appendc (&tmp1, ' '); } smart_str_0 (&tmp1); mcrypt_free_p (modules, count); modules = mcrypt_list_modes (MCG(modes_dir), &count); if (count == 0) { smart_str_appends (&tmp2, "none"); } for (i = 0; i < count; i++) { smart_str_appends (&tmp2, modules[i]); smart_str_appendc (&tmp2, ' '); } smart_str_0 (&tmp2); mcrypt_free_p (modules, count);#endif php_info_print_table_start(); php_info_print_table_header(2, "mcrypt support", "enabled");#if HAVE_LIBMCRYPT22 php_info_print_table_row(2, "version", "2.2.x");#endif#if HAVE_LIBMCRYPT24 php_info_print_table_row(2, "version", ">= 2.4.x"); php_info_print_table_row(2, "Supported ciphers", tmp1.c); php_info_print_table_row(2, "Supported modes", tmp2.c); smart_str_free (&tmp1); smart_str_free (&tmp2);#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){ char *cipher, *cipher_dir; char *mode, *mode_dir; int cipher_len, cipher_dir_len; int mode_len, mode_dir_len; MCRYPT td; php_mcrypt *pm; if (zend_parse_parameters (ZEND_NUM_ARGS() TSRMLS_CC, "ssss", &cipher, &cipher_len, &cipher_dir, &cipher_dir_len, &mode, &mode_len, &mode_dir, &mode_dir_len)) { return; } td = mcrypt_module_open (cipher, cipher_dir_len > 0 ? cipher_dir : MCG(algorithms_dir), mode, mode_dir_len > 0 ? mode_dir : MCG(modes_dir)); if (td == MCRYPT_FAILED) { php_error (E_WARNING, "%s(): Could not open encryption module", get_active_function_name(TSRMLS_C)); RETURN_FALSE; } else { pm = emalloc(sizeof(php_mcrypt)); pm->td = td; pm->init = 0; ZEND_REGISTER_RESOURCE(return_value, pm, le_mcrypt); }}/* }}} *//* {{{ 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; unsigned char *key_s, *iv_s; char dummy[256]; int max_key_size, key_size, iv_size; php_mcrypt *pm; int argc; int result = 0; argc = ZEND_NUM_ARGS(); MCRYPT_CHECK_PARAM_COUNT_EX (3,3) zend_get_parameters_ex(3, &mcryptind, &key, &iv); ZEND_FETCH_RESOURCE(pm, php_mcrypt *, mcryptind, -1, "MCrypt", le_mcrypt); convert_to_string_ex(key); convert_to_string_ex(iv); max_key_size = mcrypt_enc_get_key_size(pm->td); iv_size = mcrypt_enc_get_iv_size(pm->td); if (Z_STRLEN_PP(key) == 0) { php_error (E_WARNING, "%s(): Key size is 0", get_active_function_name(TSRMLS_C)); } key_s = emalloc (Z_STRLEN_PP(key)); memset (key_s, 0, Z_STRLEN_PP(key)); iv_s = emalloc (iv_size + 1); memset (iv_s, 0, iv_size + 1); if (Z_STRLEN_PP(key) > max_key_size) { sprintf (dummy, "Key size too large; supplied length: %d, max: %d", Z_STRLEN_PP(key), max_key_size); php_error (E_WARNING, "%s(): %s", get_active_function_name(TSRMLS_C), dummy); key_size = max_key_size; } else { key_size = Z_STRLEN_PP(key); } memcpy (key_s, Z_STRVAL_PP(key), Z_STRLEN_PP(key)); if (Z_STRLEN_PP(iv) != iv_size) { sprintf (dummy, "Iv size incorrect; supplied length: %d, needed: %d", Z_STRLEN_PP(iv), iv_size); php_error (E_WARNING, "%s(): %s", get_active_function_name(TSRMLS_C), dummy); } memcpy (iv_s, Z_STRVAL_PP(iv), iv_size); mcrypt_generic_deinit(pm->td); result = mcrypt_generic_init(pm->td, key_s, key_size, iv_s); /* If this function fails, close the mcrypt module to prevent crashes * when further functions want to access this resource */ if (result < 0) { zend_list_delete (Z_LVAL_PP(mcryptind)); switch (result) { case -3: php_error (E_WARNING, "%s(): Key length incorrect", get_active_function_name(TSRMLS_C)); break; case -4: php_error (E_WARNING, "%s(): Memory allocation error", get_active_function_name(TSRMLS_C)); break; case -1: default: php_error (E_WARNING, "%s(): Unknown error", get_active_function_name(TSRMLS_C)); break; } } pm->init = 1; RETVAL_LONG(result); efree(iv_s); efree(key_s);}/* }}} */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -