1999-05-16 12:01:25 +00:00
/*
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
1999-07-16 13:13:16 +00:00
| PHP version 4.0 |
1999-05-16 12:01:25 +00:00
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
2001-02-26 06:11:02 +00:00
| Copyright ( c ) 1997 - 2001 The PHP Group |
1999-05-16 12:01:25 +00:00
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
2000-05-18 15:34:45 +00:00
| This source file is subject to version 2.02 of the PHP license , |
1999-07-16 13:13:16 +00:00
| that is bundled with this package in the file LICENSE , and is |
| available at through the world - wide - web at |
2000-05-18 15:34:45 +00:00
| http : //www.php.net/license/2_02.txt. |
1999-07-16 13:13:16 +00:00
| 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 . |
1999-05-16 12:01:25 +00:00
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
1999-11-26 17:12:01 +00:00
| Authors : Sascha Schumann < sascha @ schumann . cx > |
2000-10-18 07:25:26 +00:00
| |
2000-10-25 18:09:23 +00:00
| HMAC and KEYGEN functionality added by |
| Nikos Mavroyanopoulos < nmav @ hellug . gr > |
1999-05-16 12:01:25 +00:00
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
*/
# include "php.h"
# if HAVE_LIBMHASH
2000-10-17 19:43:49 +00:00
# include "fcntl.h"
1999-05-16 12:01:25 +00:00
# include "php_mhash.h"
# include "mhash.h"
2000-10-17 19:43:49 +00:00
# include "php_ini.h"
# include "php_globals.h"
# include "ext/standard/info.h"
1999-05-16 12:01:25 +00:00
function_entry mhash_functions [ ] = {
PHP_FE ( mhash_get_block_size , NULL )
2000-10-17 19:43:49 +00:00
PHP_FE ( mhash_get_hash_name , NULL )
2000-10-25 18:09:23 +00:00
PHP_FE ( mhash_keygen_s2k , NULL )
2000-10-17 19:43:49 +00:00
PHP_FE ( mhash_count , NULL )
PHP_FE ( mhash , NULL ) { 0 }
,
1999-05-16 12:01:25 +00:00
} ;
1999-08-02 16:06:13 +00:00
static PHP_MINIT_FUNCTION ( mhash ) ;
1999-05-16 12:01:25 +00:00
zend_module_entry mhash_module_entry = {
2000-10-17 19:43:49 +00:00
" mhash " ,
1999-05-16 12:01:25 +00:00
mhash_functions ,
1999-08-02 16:06:13 +00:00
PHP_MINIT ( mhash ) , NULL ,
1999-05-16 12:01:25 +00:00
NULL , NULL ,
NULL ,
STANDARD_MODULE_PROPERTIES ,
} ;
2000-05-02 03:29:45 +00:00
# ifdef COMPILE_DL_MHASH
ZEND_GET_MODULE ( mhash )
# endif
1999-05-21 20:09:23 +00:00
# define MHASH_FAILED_MSG "mhash initialization failed"
2000-10-25 18:09:23 +00:00
# define MHASH_KEYGEN_FAILED_MSG "mhash key generation failed"
1999-08-02 16:06:13 +00:00
static PHP_MINIT_FUNCTION ( mhash )
1999-05-16 12:01:25 +00:00
{
1999-05-21 20:09:23 +00:00
int i ;
char * name ;
char buf [ 128 ] ;
2000-10-17 19:43:49 +00:00
for ( i = 0 ; i < = mhash_count ( ) ; i + + ) {
1999-05-21 20:09:23 +00:00
name = mhash_get_hash_name ( i ) ;
2000-10-17 19:43:49 +00:00
if ( name ) {
1999-05-21 20:09:23 +00:00
snprintf ( buf , 127 , " MHASH_%s " , name ) ;
2000-10-17 19:43:49 +00:00
zend_register_long_constant ( buf , strlen ( buf ) + 1 ,
i , CONST_PERSISTENT ,
module_number ELS_CC ) ;
1999-05-21 20:09:23 +00:00
free ( name ) ;
}
}
2000-10-17 19:43:49 +00:00
1999-05-16 12:01:25 +00:00
return SUCCESS ;
}
2001-01-15 12:01:34 +00:00
/* {{{ proto int mhash_count(void)
Gets the number of available hashes */
1999-05-21 20:09:23 +00:00
PHP_FUNCTION ( mhash_count )
{
RETURN_LONG ( mhash_count ( ) ) ;
}
2000-10-17 19:43:49 +00:00
2000-05-26 17:20:36 +00:00
/* }}} */
1999-05-21 20:09:23 +00:00
2000-05-26 17:20:36 +00:00
/* {{{ proto int mhash_get_block_size(int hash)
2001-01-15 12:01:34 +00:00
Gets the block size of hash */
1999-05-16 12:01:25 +00:00
PHP_FUNCTION ( mhash_get_block_size )
{
1999-09-17 09:40:51 +00:00
pval * * hash ;
1999-05-16 12:01:25 +00:00
2000-10-17 19:43:49 +00:00
if ( ZEND_NUM_ARGS ( ) ! = 1
| | zend_get_parameters_ex ( 1 , & hash ) = = FAILURE ) {
1999-05-16 12:01:25 +00:00
WRONG_PARAM_COUNT ;
}
1999-09-17 09:40:51 +00:00
convert_to_long_ex ( hash ) ;
1999-05-16 12:01:25 +00:00
2000-11-22 21:47:15 +00:00
RETURN_LONG ( mhash_get_block_size ( Z_LVAL_PP ( hash ) ) ) ;
1999-05-16 12:01:25 +00:00
}
2000-10-17 19:43:49 +00:00
2000-05-26 17:20:36 +00:00
/* }}} */
1999-05-16 12:01:25 +00:00
2000-05-26 17:20:36 +00:00
/* {{{ proto string mhash_get_hash_name(int hash)
2001-01-15 12:01:34 +00:00
Gets the name of hash */
1999-05-21 20:09:23 +00:00
PHP_FUNCTION ( mhash_get_hash_name )
{
1999-09-17 09:40:51 +00:00
pval * * hash ;
1999-05-21 20:09:23 +00:00
char * name ;
2000-10-17 19:43:49 +00:00
if ( ZEND_NUM_ARGS ( ) ! = 1
| | zend_get_parameters_ex ( 1 , & hash ) = = FAILURE ) {
1999-05-21 20:09:23 +00:00
WRONG_PARAM_COUNT ;
}
1999-09-17 09:40:51 +00:00
convert_to_long_ex ( hash ) ;
1999-05-21 20:09:23 +00:00
2000-11-22 21:47:15 +00:00
name = mhash_get_hash_name ( Z_LVAL_PP ( hash ) ) ;
2000-10-17 19:43:49 +00:00
if ( name ) {
1999-05-21 20:09:23 +00:00
RETVAL_STRING ( name , 1 ) ;
free ( name ) ;
} else {
RETVAL_FALSE ;
}
}
2000-10-17 19:43:49 +00:00
2000-05-26 17:20:36 +00:00
/* }}} */
1999-05-21 20:09:23 +00:00
2001-01-15 12:01:34 +00:00
/* {{{ proto string mhash(int hash, string data [, string key])
Hash data with hash */
1999-05-16 12:01:25 +00:00
PHP_FUNCTION ( mhash )
{
2000-10-17 19:43:49 +00:00
pval * * hash , * * data , * * key ;
1999-05-21 20:09:23 +00:00
MHASH td ;
1999-05-16 12:01:25 +00:00
int bsize ;
unsigned char * hash_data ;
2000-10-17 19:43:49 +00:00
int num_args ;
num_args = ZEND_NUM_ARGS ( ) ;
1999-05-16 12:01:25 +00:00
2000-10-17 19:43:49 +00:00
if ( num_args < 2 | | num_args > 3 ) {
1999-05-16 12:01:25 +00:00
WRONG_PARAM_COUNT ;
}
2000-10-17 19:43:49 +00:00
if ( num_args = = 2 ) { /* 2 arguments, just hash */
if ( zend_get_parameters_ex ( 2 , & hash , & data ) = = FAILURE ) {
WRONG_PARAM_COUNT ;
}
} else { /* 3 arguments, do HMAC hash (keyed hash) */
if ( zend_get_parameters_ex ( 3 , & hash , & data , & key ) = =
FAILURE ) {
WRONG_PARAM_COUNT ;
}
convert_to_string_ex ( key ) ;
}
1999-05-16 12:01:25 +00:00
1999-09-17 09:40:51 +00:00
convert_to_long_ex ( hash ) ;
convert_to_string_ex ( data ) ;
1999-05-16 12:01:25 +00:00
2000-11-22 21:47:15 +00:00
bsize = mhash_get_block_size ( Z_LVAL_PP ( hash ) ) ;
2000-10-17 19:43:49 +00:00
if ( num_args = = 3 ) {
2000-11-22 21:47:15 +00:00
if ( mhash_get_hash_pblock ( Z_LVAL_PP ( hash ) ) = = 0 ) {
2000-10-17 19:43:49 +00:00
php_error ( E_WARNING , MHASH_FAILED_MSG ) ;
RETURN_FALSE ;
}
2000-11-22 21:52:53 +00:00
td = mhash_hmac_init ( Z_LVAL_PP ( hash ) ,
2000-11-22 21:47:15 +00:00
Z_STRVAL_PP ( key ) ,
Z_STRLEN_PP ( key ) ,
2000-11-22 21:52:53 +00:00
mhash_get_hash_pblock ( Z_LVAL_PP ( hash ) ) ) ;
2000-10-17 19:43:49 +00:00
} else {
2000-11-22 21:47:15 +00:00
td = mhash_init ( Z_LVAL_PP ( hash ) ) ;
2000-10-17 19:43:49 +00:00
}
if ( td = = MHASH_FAILED ) {
1999-08-02 19:17:14 +00:00
php_error ( E_WARNING , MHASH_FAILED_MSG ) ;
1999-05-16 12:01:25 +00:00
RETURN_FALSE ;
}
2000-11-22 21:47:15 +00:00
mhash ( td , Z_STRVAL_PP ( data ) , Z_STRLEN_PP ( data ) ) ;
1999-05-16 12:01:25 +00:00
2000-10-17 19:43:49 +00:00
if ( num_args = = 3 ) {
hash_data = ( unsigned char * ) mhash_hmac_end ( td ) ;
} else {
hash_data = ( unsigned char * ) mhash_end ( td ) ;
}
1999-11-14 23:11:31 +00:00
if ( hash_data ) {
RETVAL_STRINGL ( hash_data , bsize , 1 ) ;
2000-10-17 19:43:49 +00:00
mhash_free ( hash_data ) ;
1999-11-14 23:11:31 +00:00
} else {
RETURN_FALSE ;
}
1999-05-16 12:01:25 +00:00
}
2000-10-17 19:43:49 +00:00
2000-05-26 17:20:36 +00:00
/* }}} */
1999-05-16 12:01:25 +00:00
2000-10-25 18:09:23 +00:00
/* {{{ proto string mhash_keygen_s2k(int hash, string input_password, string salt, int bytes)
2001-01-15 12:01:34 +00:00
Generates a key using hash functions */
2000-10-25 18:09:23 +00:00
/* SALTED S2K uses a fixed salt */
# define SALT_SIZE 8
PHP_FUNCTION ( mhash_keygen_s2k )
{
pval * * hash , * * input_password , * * bytes , * * input_salt ;
unsigned char * key ;
int password_len , salt_len ;
int hashid , size = 0 , val ;
KEYGEN keystruct ;
char salt [ SALT_SIZE ] , * ret ;
char * password , error [ 128 ] ;
if ( ZEND_NUM_ARGS ( ) ! = 4 ) {
WRONG_PARAM_COUNT ;
}
if ( zend_get_parameters_ex ( 4 , & hash , & input_password , & input_salt , & bytes ) = = FAILURE ) {
WRONG_PARAM_COUNT ;
}
convert_to_long_ex ( hash ) ;
convert_to_string_ex ( input_password ) ;
convert_to_string_ex ( input_salt ) ;
convert_to_long_ex ( bytes ) ;
2000-11-22 21:47:15 +00:00
password = Z_STRVAL_PP ( input_password ) ;
password_len = Z_STRLEN_PP ( input_password ) ;
2000-10-25 18:09:23 +00:00
2000-11-22 21:47:15 +00:00
salt_len = Z_STRLEN_PP ( input_salt ) ;
2000-10-25 18:09:23 +00:00
if ( salt_len > mhash_get_keygen_salt_size ( KEYGEN_S2K_SALTED ) ) {
sprintf ( error , " The specified salt [%d] is more bytes than the required by the algorithm [%d] \n " , salt_len , mhash_get_keygen_salt_size ( KEYGEN_S2K_SALTED ) ) ;
php_error ( E_WARNING , error ) ;
}
memset ( salt , 0 , SALT_SIZE ) ;
2000-11-22 21:47:15 +00:00
memcpy ( salt , Z_STRVAL_PP ( input_salt ) , salt_len ) ;
2000-10-25 18:09:23 +00:00
salt_len = SALT_SIZE ;
/* if (salt_len==0) {
* php_error ( E_WARNING , " Not using salt is really not recommended) ;
* }
*/
2000-11-22 21:47:15 +00:00
hashid = Z_LVAL_PP ( hash ) ;
size = Z_LVAL_PP ( bytes ) ;
2000-10-25 18:09:23 +00:00
keystruct . hash_algorithm [ 0 ] = hashid ;
keystruct . hash_algorithm [ 1 ] = hashid ;
keystruct . count = 0 ;
keystruct . salt = salt ;
keystruct . salt_size = salt_len ;
2000-11-22 21:52:53 +00:00
ret = emalloc ( size ) ;
2000-10-25 18:09:23 +00:00
if ( ret = = NULL ) {
php_error ( E_WARNING , MHASH_KEYGEN_FAILED_MSG ) ;
RETURN_FALSE ;
}
val = mhash_keygen_ext ( KEYGEN_S2K_SALTED , keystruct , ret , size , password , password_len ) ;
2000-11-22 21:52:53 +00:00
if ( val > = 0 ) {
RETVAL_STRINGL ( ret , size , 0 ) ;
2000-10-25 18:09:23 +00:00
} else {
php_error ( E_WARNING , MHASH_KEYGEN_FAILED_MSG ) ;
2000-11-22 21:52:53 +00:00
efree ( ret ) ;
2000-10-25 18:09:23 +00:00
RETURN_FALSE ;
}
}
/* }}} */
2000-10-17 19:43:49 +00:00
1999-05-16 12:01:25 +00:00
# endif