📄 mcrypt.c
字号:
php_error (E_WARNING, MCRYPT_OPEN_MODULE_FAILED, get_active_function_name(TSRMLS_C)); 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( Z_STRVAL_PP(cipher), cipher_dir_string, Z_STRVAL_PP(module), 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, get_active_function_name(TSRMLS_C)); 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( Z_STRVAL_PP(cipher), 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( Z_STRVAL_PP(cipher), 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, get_active_function_name(TSRMLS_C)); 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 TSRMLS_DC){ 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 = NULL, *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, get_active_function_name(TSRMLS_C)); RETURN_FALSE; } /* Checking for key-length */ max_key_length = mcrypt_enc_get_key_size (td); if (Z_STRLEN_PP(key) > max_key_length) { php_error (E_WARNING, "%s(): Size of key is too large for this algorithm", get_active_function_name(TSRMLS_C)); } 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 */ use_key_length = Z_STRLEN_PP(key); key_s = emalloc (use_key_length); memset (key_s, 0, use_key_length); memcpy (key_s, Z_STRVAL_PP(key), use_key_length); } else if (count == 1) { /* only m_k_l = OK */ key_s = emalloc (key_length_sizes[0]); memset (key_s, 0, key_length_sizes[0]); memcpy (key_s, Z_STRVAL_PP(key), MIN(Z_STRLEN_PP(key), key_length_sizes[0])); 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] >= Z_STRLEN_PP(key) && 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); memcpy (key_s, Z_STRVAL_PP(key), MIN(Z_STRLEN_PP(key), use_key_length)); } mcrypt_free (key_length_sizes); /* Check IV */ iv_s = NULL; iv_size = mcrypt_enc_get_iv_size (td); if (argc == 5) { if (iv_size != Z_STRLEN_PP(iv)) { php_error (E_WARNING, MCRYPT_IV_WRONG_SIZE, get_active_function_name(TSRMLS_C)); } else { iv_s = emalloc (iv_size + 1); memcpy (iv_s, Z_STRVAL_PP(iv), iv_size); } } else if (argc == 4) { if (iv_size != 0) { php_error (E_WARNING, "%s(): Attempt to use an empty IV, which is NOT recommend", get_active_function_name(TSRMLS_C)); iv_s = emalloc (iv_size + 1); memset (iv_s, 0, iv_size + 1); } } /* Check blocksize */ if (mcrypt_enc_is_block_mode (td) == 1) { /* It's a block algorithm */ block_size = mcrypt_enc_get_block_size (td); data_size = (((Z_STRLEN_PP(data) - 1) / block_size) + 1) * block_size; data_s = emalloc (data_size); memset (data_s, 0, data_size); memcpy (data_s, Z_STRVAL_PP(data), Z_STRLEN_PP(data)); } else { /* It's not a block algorithm */ data_size = Z_STRLEN_PP(data); data_s = emalloc (data_size); memset (data_s, 0, data_size); memcpy (data_s, Z_STRVAL_PP(data), Z_STRLEN_PP(data)); } if (mcrypt_generic_init (td, key_s, use_key_length, iv_s) < 0) { php_error (E_ERROR, "%s(): Mcrypt initialisation failed", get_active_function_name(TSRMLS_C)); } 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 (key_s != NULL) efree (key_s); if (iv_s != NULL) efree (iv_s); efree (data_s);}/* {{{ 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 (Z_STRVAL_PP(cipher), key, data, Z_STRVAL_PP(mode), iv, argc, MCRYPT_ENCRYPT, return_value TSRMLS_CC);}/* }}} *//* {{{ 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 (Z_STRVAL_PP(cipher), key, data, Z_STRVAL_PP(mode), iv, argc, MCRYPT_DECRYPT, return_value TSRMLS_CC);}/* }}} *//* {{{ 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 (Z_STRVAL_PP(cipher), key, data, "ecb", iv, argc, Z_LVAL_PP(mode), return_value TSRMLS_CC);}/* }}} *//* {{{ 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 (Z_STRVAL_PP(cipher), key, data, "cbc", iv, argc, Z_LVAL_PP(mode), return_value TSRMLS_CC);}/* }}} *//* {{{ 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 (Z_STRVAL_PP(cipher), key, data, "cfb", iv, argc, Z_LVAL_PP(mode), return_value TSRMLS_CC);}/* }}} *//* {{{ 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 (Z_STRVAL_PP(cipher), key, data, "ofb", iv, argc, Z_LVAL_PP(mode), return_value TSRMLS_CC);}/* }}} */#endif/* {{{ proto string mcrypt_create_iv(int size, int source) Create an initialization vector (IV) */PHP_FUNCTION(mcrypt_create_iv){ char *iv; long source = RANDOM; long size; int n = 0; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l|l", &size, &source) == FAILURE) { return; } if (size <= 0 || size >= INT_MAX) { 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); RETURN_FALSE; } iv = ecalloc(size + 1, 1); if (source == RANDOM || source == URANDOM) { int fd; size_t read_bytes = 0; fd = open(source == RANDOM ? "/dev/random" : "/dev/urandom", O_RDONLY); if (fd < 0) { efree(iv); php_error(E_WARNING, "%s(): Cannot open source device", get_active_function_name(TSRMLS_C)); RETURN_FALSE; } while (read_bytes < size) { n = read(fd, iv + read_bytes, size - read_bytes); if (n < 0) break; read_bytes += n; } n = read_bytes; close(fd); if (n < size) { efree(iv); php_error(E_WARNING, "%s(): Could not gather sufficient random data", get_active_function_name(TSRMLS_C)); RETURN_FALSE; } } else { n = size; while (size) { iv[--size] = 255.0 * rand() / RAND_MAX; } } RETURN_STRINGL(iv, n, 0);}/* }}} */#if HAVE_LIBMCRYPT22/* {{{ proto string mcrypt_get_cipher_name(int cipher) Get the name of cipher */PHP_FUNCTION(mcrypt_get_cipher_name){ zval **cipher; char *str, *nstr; if(ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &cipher) == FAILURE) { WRONG_PARAM_COUNT; } convert_to_long_ex(cipher); str = mcrypt_get_algorithms_name(Z_LVAL_PP(cipher)); if (str) { nstr = estrdup(str); free(str); RETURN_STRING(nstr, 0); } RETURN_FALSE;}/* }}} *//* {{{ proto int mcrypt_get_key_size(int cipher) Get the key size of cipher */PHP_FUNCTION(mcrypt_get_key_size){ zval **cipher; if(ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &cipher) == FAILURE) { WRONG_PARAM_COUNT; } convert_to_long_ex(cipher); RETURN_LONG(mcrypt_get_key_size(Z_LVAL_PP(cipher)));}/* }}} *//* {{{ proto int mcrypt_get_block_size(int cipher) Get the block size of cipher */PHP_FUNCTION(mcrypt_get_block_size){ zval **cipher; if(ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &cipher) == FAILURE) { WRONG_PARAM_COUNT; } convert_to_long_ex(cipher); RETURN_LONG(mcrypt_get_block_size(Z_LVAL_PP(cipher)));}/* }}} *//* {{{ 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){ MCRYPT_ARGS; if(ZEND_NUM_ARGS() != 5 || zend_get_parameters_ex(5, &cipher, &key, &data, &mode, &iv) == FAILURE) { WRONG_PARAM_COUNT; } MCRYPT_CONVERT; MCRYPT_SIZE; MCRYPT_CHECK_IV; td = init_mcrypt_ofb(Z_LVAL_PP(cipher), Z_STRVAL_PP(key), Z_STRLEN_PP(key), Z_STRVAL_PP(iv)); MCRYPT_CHECK_TD_CPY; MCRYPT_ACTION(ofb); RETURN_STRINGL(ndata, nsize, 0);}/* }}} *//* {{{ 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){ MCRYPT_ARGS; if(ZEND_NUM_ARGS() != 5 || zend_get_parameters_ex(5, &cipher, &key, &data, &mode, &iv) == FAILURE) { WRONG_PARAM_COUNT; } MCRYPT_CONVERT; MCRYPT_SIZE; MCRYPT_CHECK_IV; td = init_mcrypt_cfb(Z_LVAL_PP(cipher), Z_STRVAL_PP(key), Z_STRLEN_PP(key), Z_STRVAL_PP(iv)); MCRYPT_CHECK_TD_CPY; MCRYPT_ACTION(cfb); RETURN_STRINGL(ndata, nsize, 0);}/* }}} *//* {{{ proto string mcrypt_cbc(int cipher, string key, string data, int mode [, string iv]) CBC crypt/decrypt data using key key with cipher cipher using optional iv */PHP_FUNCTION(mcrypt_cbc){ MCRYPT_ARGS; int ac = ZEND_NUM_ARGS(); if(ac < 4 || ac > 5 || zend_get_parameters_ex(ac, &cipher, &key, &data, &mode, &iv) == FAILURE) { WRONG_PARAM_COUNT; } MCRYPT_CONVERT; MCRYPT_SIZE; if(ac > 4) { MCRYPT_CHECK_IV; } td = init_mcrypt_cbc(Z_LVAL_PP(cipher), Z_STRVAL_PP(key), Z_STRLEN_PP(key)); MCRYPT_CHECK_TD_CPY; if(ac > 4) { mcrypt(td, Z_STRVAL_PP(iv)); } MCRYPT_ACTION(cbc); RETURN_STRINGL(ndata, nsize, 0);}/* }}} *//* {{{ proto string mcrypt_ecb(int cipher, string key, string data, int mode) ECB crypt/decrypt data using key key with cipher cipher */PHP_FUNCTION(mcrypt_ecb){ MCRYPT_ARGS2; if(ZEND_NUM_ARGS() != 4 || zend_get_parameters_ex(4, &cipher, &key, &data, &mode) == FAILURE) { WRONG_PARAM_COUNT; } MCRYPT_CONVERT; MCRYPT_SIZE; td = init_mcrypt_ecb(Z_LVAL_PP(cipher), Z_STRVAL_PP(key), Z_STRLEN_PP(key)); MCRYPT_CHECK_TD_CPY; MCRYPT_ACTION(ecb); RETURN_STRINGL(ndata, nsize, 0);}/* }}} */#endif /* MCRYPT_2_2 */#endif/* * Local variables: * tab-width: 4 * c-basic-offset: 4 * End: * vim600: sw=4 ts=4 fdm=marker * vim<600: sw=4 ts=4 */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -