From: Charles R. Portwood II Date: Sat, 9 Jul 2016 18:18:45 +0000 (-0500) Subject: Adding test cases for Argon2i and Argon2d X-Git-Tag: php-7.2.0alpha1~1316^2^2~14 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=0a1274f2b12ad7e200932b9950876ea19125e210;p=php Adding test cases for Argon2i and Argon2d Added Windows config.w32 changes Updated constants in php_password.h --- diff --git a/ext/standard/config.w32 b/ext/standard/config.w32 index adff3d8c87..431dd3e484 100644 --- a/ext/standard/config.w32 +++ b/ext/standard/config.w32 @@ -20,10 +20,13 @@ EXTENSION("standard", "array.c base64.c basic_functions.c browscap.c \ url_scanner_ex.c ftp_fopen_wrapper.c http_fopen_wrapper.c \ php_fopen_wrapper.c credits.c css.c var_unserializer.c ftok.c sha1.c \ user_filters.c uuencode.c filters.c proc_open.c password.c \ - streamsfuncs.c http.c flock_compat.c random.c", false /* never shared */, + streamsfuncs.c http.c flock_compat.c random.c \ + argon2lib/argon2.c argon2lib/core.c argon2lib/blake2/blake2b.c \ + argon2lib/thread.c argon2lib/encoding.c argon2lib/ref.c", false /* never shared */, '/DZEND_ENABLE_STATIC_TSRMLS_CACHE=1'); PHP_INSTALL_HEADERS("", "ext/standard"); if (PHP_MBREGEX != "no") { CHECK_HEADER_ADD_INCLUDE("oniguruma.h", "CFLAGS_STANDARD", PHP_MBREGEX + ";ext\\mbstring\\oniguruma") } PHP_INSTALL_HEADERS("", "ext/standard"); +PHP_INSTALL_HEADERS([ext/standard/argon2lib]) diff --git a/ext/standard/password.c b/ext/standard/password.c index ca223dcc3e..f312df8030 100644 --- a/ext/standard/password.c +++ b/ext/standard/password.c @@ -71,12 +71,12 @@ static char* php_password_get_algo_name(const php_password_algo algo) static php_password_algo php_password_determine_algo(const char *hash, const size_t len) { - if (hash[0] == '$' && strstr(hash, "argon2i")) { + if (len > 3 && hash[0] == '$' && hash[1] == '2' && hash[2] == 'y' && len == 60) { + return PHP_PASSWORD_BCRYPT; + } else if (hash[0] == '$' && strstr(hash, "argon2i")) { return PHP_PASSWORD_ARGON2I; } else if (hash[0] == '$' && strstr(hash, "argon2d")) { return PHP_PASSWORD_ARGON2D; - } else if (len > 3 && hash[0] == '$' && hash[1] == '2' && hash[2] == 'y' && len == 60) { - return PHP_PASSWORD_BCRYPT; } return PHP_PASSWORD_UNKNOWN; @@ -300,7 +300,29 @@ PHP_FUNCTION(password_verify) algo = php_password_determine_algo(hash, (size_t) hash_len); switch(algo) { + case PHP_PASSWORD_ARGON2I: + case PHP_PASSWORD_ARGON2D: + { + argon2_type type = Argon2_i; + + if (strstr(hash, "argon2d")) { + type = Argon2_d; + } else if (strstr(hash, "argon2i")) { + type = Argon2_i; + } + + status = argon2_verify(hash, password, password_len, type); + + if (status == ARGON2_OK) { + RETURN_TRUE; + } + + RETURN_FALSE; + } + break; case PHP_PASSWORD_BCRYPT: + case PHP_PASSWORD_UNKNOWN: + default: { if ((ret = php_crypt(password, (int)password_len, hash, (int)hash_len, 1)) == NULL) { RETURN_FALSE; @@ -323,28 +345,6 @@ PHP_FUNCTION(password_verify) RETURN_BOOL(status == 0); } - case PHP_PASSWORD_ARGON2I: - case PHP_PASSWORD_ARGON2D: - { - argon2_type type = Argon2_i; - - if (strstr(hash, "argon2d")) { - type = Argon2_d; - } else if (strstr(hash, "argon2i")) { - type = Argon2_i; - } - - status = argon2_verify(hash, password, password_len, type); - - if (status == ARGON2_OK) { - RETURN_TRUE; - } - - RETURN_FALSE; - } - case PHP_PASSWORD_UNKNOWN: - default: - RETURN_FALSE; } RETURN_FALSE; @@ -362,7 +362,6 @@ PHP_FUNCTION(password_hash) size_t salt_len = 0, required_salt_len = 0, hash_format_len; HashTable *options = 0; zval *option_buffer; - zend_string *result; // Argon2 Options size_t t_cost = PHP_PASSWORD_ARGON2_TIME_COST; @@ -419,7 +418,7 @@ PHP_FUNCTION(password_hash) } if (threads > ARGON2_MAX_LANES || threads == 0) { - php_error_docref(NULL, E_WARNING, "Invalid numeric input for threads", threads); + php_error_docref(NULL, E_WARNING, "Invalid number of threads", threads); RETURN_NULL(); } @@ -499,6 +498,7 @@ PHP_FUNCTION(password_hash) switch (algo) { case PHP_PASSWORD_BCRYPT: { + zend_string *result; salt[salt_len] = 0; hash = safe_emalloc(salt_len + hash_format_len, 1, 1); @@ -532,7 +532,7 @@ PHP_FUNCTION(password_hash) size_t out_len = 32; size_t encoded_len; - int result = 0; + int status = 0; encoded_len = argon2_encodedlen( t_cost, @@ -545,7 +545,7 @@ PHP_FUNCTION(password_hash) encoded = emalloc(encoded_len + 1); out = emalloc(out_len + 1); - result = argon2_hash( + status = argon2_hash( t_cost, m_cost, threads, @@ -567,8 +567,8 @@ PHP_FUNCTION(password_hash) efree(salt); efree(encoded); - if (result != ARGON2_OK) { - php_error_docref(NULL, E_WARNING, argon2_error_message(result)); + if (status != ARGON2_OK) { + php_error_docref(NULL, E_WARNING, argon2_error_message(status)); RETURN_FALSE; } diff --git a/ext/standard/php_password.h b/ext/standard/php_password.h index 7c3c8821d9..c71996dbf1 100644 --- a/ext/standard/php_password.h +++ b/ext/standard/php_password.h @@ -40,8 +40,8 @@ PHP_MINIT_FUNCTION(password); typedef enum { PHP_PASSWORD_UNKNOWN, PHP_PASSWORD_BCRYPT, - PHP_PASSWORD_ARGON2I, - PHP_PASSWORD_ARGON2D + PHP_PASSWORD_ARGON2D, + PHP_PASSWORD_ARGON2I } php_password_algo; #endif diff --git a/ext/standard/tests/password/password_get_info.phpt b/ext/standard/tests/password/password_get_info.phpt index bbe207dd60..3e8b665ba2 100644 --- a/ext/standard/tests/password/password_get_info.phpt +++ b/ext/standard/tests/password/password_get_info.phpt @@ -11,9 +11,10 @@ var_dump(password_get_info('$2y$11$MTIzNDU2Nzg5MDEyMzQ1Nej0NmcAWSLR.oP7XOR9HD/vj var_dump(password_get_info('$2y$11$MTIzNDU2Nzg5MDEyMzQ1Nej0NmcAWSLR.oP7XOR9HD/vjUuOj100')); // Test Non-Bcrypt var_dump(password_get_info('$1$rasmusle$rISCgZzpwk3UhDidwXvin0')); -// Test Argon2 -//var_dump(password_get_info('$argon2i$v=19$m=65536,t=3,p=1$SWhIcG5MT21Pc01PbWdVZw$WagZELICsz7jlqOR2YzoEVTWb2oOX1tYdnhZYXxptbU')); - +// Test Argon2i +var_dump(password_get_info('$argon2i$v=19$m=65536,t=3,p=1$SWhIcG5MT21Pc01PbWdVZw$WagZELICsz7jlqOR2YzoEVTWb2oOX1tYdnhZYXxptbU')); +// Test Argon2d +var_dump(password_get_info('$argon2d$v=19$m=32768,t=2,p=1$YWpxd0VYRW9MLmp6VjFPZw$pWV5IsbBfjEK5c0bHzvAo0FsDNHUyM4p6j8vf2cxzb8')); echo "OK!"; ?> --EXPECT-- @@ -59,7 +60,7 @@ array(3) { } array(3) { ["algo"]=> - int(2) + int(3) ["algoName"]=> string(7) "argon2i" ["options"]=> @@ -72,4 +73,19 @@ array(3) { int(1) } } +array(3) { + ["algo"]=> + int(2) + ["algoName"]=> + string(7) "argon2d" + ["options"]=> + array(3) { + ["m_cost"]=> + int(32768) + ["t_cost"]=> + int(2) + ["threads"]=> + int(1) + } +} OK! diff --git a/ext/standard/tests/password/password_hash.phpt b/ext/standard/tests/password/password_hash.phpt index ebb27292ea..665ead92ca 100644 --- a/ext/standard/tests/password/password_hash.phpt +++ b/ext/standard/tests/password/password_hash.phpt @@ -10,9 +10,27 @@ $hash = password_hash("foo", PASSWORD_BCRYPT); var_dump($hash === crypt("foo", $hash)); +$hash = password_hash('foo', PASSWORD_ARGON2); +var_dump(strlen($hash)); +var_dump(password_verify('foo', $hash)); + +$hash = password_hash('foo', PASSWORD_ARGON2I); +var_dump(strlen($hash)); +var_dump(password_verify('foo', $hash)); + +$hash = password_hash('foo', PASSWORD_ARGON2D); +var_dump(strlen($hash)); +var_dump(password_verify('foo', $hash)); + echo "OK!"; ?> --EXPECT-- int(60) bool(true) -OK! \ No newline at end of file +int(99) +bool(true) +int(99) +bool(true) +int(99) +bool(true) +OK! diff --git a/ext/standard/tests/password/password_hash_error.phpt b/ext/standard/tests/password/password_hash_error.phpt index 8dc954649d..9207fb76ef 100644 --- a/ext/standard/tests/password/password_hash_error.phpt +++ b/ext/standard/tests/password/password_hash_error.phpt @@ -21,6 +21,12 @@ var_dump(password_hash("123", PASSWORD_BCRYPT, array("salt" => array()))); /* Non-string salt, checking for memory leaks */ var_dump(password_hash('123', PASSWORD_BCRYPT, array('salt' => 1234))); +var_dump(password_hash('test', PASSWORD_ARGON2, ['m_cost' => 0])); + +var_dump(password_hash('test', PASSWORD_ARGON2, ['t_cost' => 0])); + +var_dump(password_hash('test', PASSWORD_ARGON2, ['threads' => 0])); + ?> --EXPECTF-- Warning: password_hash() expects at least 2 parameters, 0 given in %s on line %d @@ -50,3 +56,13 @@ Deprecated: password_hash(): Use of the 'salt' option to password_hash is deprec Warning: password_hash(): Provided salt is too short: 4 expecting 22 in %s on line %d NULL + +Warning: password_hash(): Memory cost is outside of allowed memory range in %s on line %d +NULL + +Warning: password_hash(): Time cost is outside of allowed time range in %s on line %d +NULL + +Warning: password_hash(): Invalid number of threads in %s on line %d +NULL + diff --git a/ext/standard/tests/password/password_needs_rehash.phpt b/ext/standard/tests/password/password_needs_rehash.phpt index 8efd0add8f..b38c1dde20 100644 --- a/ext/standard/tests/password/password_needs_rehash.phpt +++ b/ext/standard/tests/password/password_needs_rehash.phpt @@ -29,8 +29,9 @@ var_dump(password_needs_rehash('$2y$'.$cost.'$MTIzNDU2Nzg5MDEyMzQ1Nej0NmcAWSLR.o // Should Issue Needs Rehash, Since Foo is cast to 0... var_dump(password_needs_rehash('$2y$10$MTIzNDU2Nzg5MDEyMzQ1Nej0NmcAWSLR.oP7XOR9HD/vjUuOj100y', PASSWORD_BCRYPT, array('cost' => 'foo'))); - - +var_dump(password_needs_rehash('$argon2i$v=19$m=65536,t=3,p=1$YkprUktYN0lHQTd2bWRFeA$79aA+6IvgclpDAJVoezProlqzIPy7do/P0sBDXS9Nn0', PASSWORD_ARGON2, ['m_cost' => 1<<17])); +var_dump(password_needs_rehash('$argon2i$v=19$m=65536,t=3,p=1$YkprUktYN0lHQTd2bWRFeA$79aA+6IvgclpDAJVoezProlqzIPy7do/P0sBDXS9Nn0', PASSWORD_ARGON2, ['t_cost' => 2])); +var_dump(password_needs_rehash('$argon2i$v=19$m=65536,t=3,p=1$YkprUktYN0lHQTd2bWRFeA$79aA+6IvgclpDAJVoezProlqzIPy7do/P0sBDXS9Nn0', PASSWORD_ARGON2, ['threads' => 2])); echo "OK!"; ?> --EXPECT-- @@ -42,4 +43,7 @@ bool(true) bool(true) bool(false) bool(true) +bool(true) +bool(true) +bool(true) OK! diff --git a/ext/standard/tests/password/password_verify.phpt b/ext/standard/tests/password/password_verify.phpt index a196763c13..0e85413a35 100644 --- a/ext/standard/tests/password/password_verify.phpt +++ b/ext/standard/tests/password/password_verify.phpt @@ -18,6 +18,13 @@ var_dump(password_verify("rasmuslerdorf", "rl.3StKT.4T8M")); var_dump(password_verify("foo", "$1")); +var_dump(password_verify('test', '$argon2d$v=19$m=32768,t=2,p=1$YWpxd0VYRW9MLmp6VjFPZw$pWV5IsbBfjEK5c0bHzvAo0FsDNHUyM4p6j8vf2cxzb8')); + +var_dump(password_verify('argon2', '$argon2d$v=19$m=32768,t=2,p=1$YWpxd0VYRW9MLmp6VjFPZw$pWV5IsbBfjEK5c0bHzvAo0FsDNHUyM4p6j8vf2cxzb8')); + +var_dump(password_verify('test', '$argon2i$v=19$m=65536,t=3,p=1$OEVjWWs2Z3YvWlNZQ0ZmNw$JKin7ahjmh8JYvMyFcXri0Ss/Uvd3uYpD7MG6C/5Cy0')); + +var_dump(password_verify('argon2', '$argon2i$v=19$m=65536,t=3,p=1$OEVjWWs2Z3YvWlNZQ0ZmNw$JKin7ahjmh8JYvMyFcXri0Ss/Uvd3uYpD7MG6C/5Cy0')); echo "OK!"; ?> --EXPECT-- @@ -28,4 +35,8 @@ bool(true) bool(false) bool(true) bool(false) -OK! +bool(true) +bool(false) +bool(true) +bool(false) +OK! \ No newline at end of file