File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / php / ext / mcrypt / mcrypt.c
Revision 1.1.1.4 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Sun Jun 15 20:03:51 2014 UTC (10 years, 1 month ago) by misho
Branches: php, MAIN
CVS tags: v5_4_29, HEAD
php 5.4.29

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

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>