-
Notifications
You must be signed in to change notification settings - Fork 7.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[RFC]: Add Argon2 to password_* #1997
Conversation
PASSWORD_ARGON2_MEMORY_COST PASSWORD_ARGON2_TIME_COST PASSWORD_ARGON2_LANES
Added Windows config.w32 changes Updated constants in php_password.h
Indicating constants as defaults Minor coding standards change
Is libargon2 provided by distros? I don't fancy the idea of bundling another library, unless we actually need to patch something in it. |
No, not yet - this is something specifically mentioned in the RFC draft I'm working on. libargon2 is in Debian stretch, but not stable yet. https://packages.debian.org/search?keywords=libargon2-0. I haven't seen it drop in RH/CentOS yet, hence whyy the necessary C files were added directly. I'm not too fond of including it directly either. As an alternative to directly including the source (at least until a library drops in distros) to to compile the libargon2 reference library as part of PHP's The libargon2 reference library compiles with little dependencies, going down that route however would significantly complicate the PHP build process, which I was hoping to avoid. Let me know your thoughts. There's ways to make it work without including the C source, but I completely understand tabling a feature to wait for the library to become more wildly available. |
I'm 👎 to bundle yet another lib, and to have to maintain it. Also, ext/standard should not depend on libpthread, as this is not (officialy) supported under Windows. |
'/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]) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should be PHP_INSTALL_HEADERS("", "ext/standard/argon2lib")
I agree with @jpauli here, bundling yet another library and the added Windows issues it causes is a huge -1, especially in ext/standard |
On Jul 11, 2016 00:19, "Charles R. Portwood II" [email protected]
I would suggest to add libargon2 as an optional dependency for now, which From my limited understanding, there is no pressing need to replace bcrypt |
I totally agree with @nikic here. |
Great, thanks for your feedback everyone. I can definitely change this up to use a config flag and check for the library that way. Dynamic linking should resolve the issues surrounding pthread.
You're correct. Bcrypt is still a perfectly valid and secure hashing algorithm. Argon2 is just another option. |
- Configure flag now accepts --with-argon2 for dynamic linking with libargon2. Argon2 will be enabled in password_* only if this flag is passed. - --with-argon2 config flag allows user passed directory for linking - Added Argon2 specific tests to ensure existing tests do not fail when argon2 is disable
- Added "Skipped:" flag so argon2 tests would be skipped when PHP is compiled without Argon2 support
if (CHECK_LIB("Argon2Ref.lib", "argon2", PHP_ARGON2) | ||
&& CHECK_HEADER_ADD_INCLUDE("argon2.h", "CFLAGS_ARGON2")) { | ||
AC_DEFINE('HAVE_ARGON2LIB', 1); | ||
EXTENSION("argon2", null, false); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This doesn't look right, simply drop the call to EXTENSION() here and leave the AC_DEFINE().
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was getting linker errors without the call to EXTENSION
. Is there another macro I can use to get Argon2Ref.lib
to be added to the linker? I wasn't seeing any other function for handling that.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi! It's been a while since I was tinkering around with this, but from vague memory this is how it works:
CHECK_LIB':
- The second parameter is the target of where to link the Argon2Ref.lib to (as per extension), this can be set to empty ("") -- See win32\build\confutils.js
- The third parameter is fine (as it uses PHP_ARGON2, which is the one from the --with-argon2=XXX)
CHECK_HEADER_ADD_INCLUDE
- This sets the compiler flags for an extension (CFLAGS_ARGON2), and should simply be CFLAGS (we use this value for core things, like determining IPv6 support in win32\build\config.js).
TL;DR:
Line 7 should be: if (CHECK_LIB("Argon2Ref.lib", "", PHP_ARGON2)
Line 8 should be: && CHECK_HEADER_ADD_INCLUDE("argon2.h", "CFLAGS")) {
which should allow you to drop the EXTENSION() call.
(bear in mind I'm rusty, but else poke around the sources in win32\build)!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi! Thanks for pointing me in the right direction! I really appreciate it.
It looks like the trick is to set the second arguement of CHECK_LIB
(target
) to null
instead of ""
. An empty string creates LIBS_
in the Makefile
, whereas null
correctly assigns it to LIBS
.
Thanks again!
- Added Windows config script for building on Windows - Updated tests - Renamed constants from PASSWORD_ARGON* to ARGON*_PASSWORD to avoid potential conflicts with php/php-src#1997 - Bumping version for API change
@@ -61,7 +81,14 @@ static php_password_algo php_password_determine_algo(const char *hash, const siz | |||
{ | |||
if (len > 3 && hash[0] == '$' && hash[1] == '2' && hash[2] == 'y' && len == 60) { | |||
return PHP_PASSWORD_BCRYPT; | |||
} | |||
#if HAVE_ARGON2LIB | |||
if (hash[0] == '$' && strstr(hash, "argon2i")) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This will check whether argon2i is contained anywhere in the string. Maybe doing something more precise like memcmp(hash + 1, "argon2i", sizeof("argon2i") - 1)
, with appropriate length check beforehand, would be preferable?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Because of the memory, time, and parallelism factors, Argon2 hashes can be of variable length. Using the default constants listed in php_password.h
, this string will be 99 characters long, however the change of constants would result in different sized hashes.
The other alternative is to try to parse out all the available Argon2 options on the spot - there's still a chance that the string isn't an Argon2 hash though even verifying those options. At the end of the day the hash, will be password to password_verify
. If the string isn't a valid Argon2 hash it'll be detected there and the password_verify
will return false.
Thoughts?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The comment about the length check was only to avoid out of bounds memcmp, not ensure a particular value. I.e. something along the lines of:
if (hash_len >= sizeof("$argon2i$")-1 && !memcmp(hash, "$argon2i$", sizeof("$argon2i$")-1)) {
return PHP_PASSWORD_ARGON2I;
}
// ...
You're right that it probably doesn't matter anyway. The only problem I can imagine is the string "argon2i" occurring in the salt of a non-bcrypt non-argon hash (iirc password_verify also accepts crypt hashes that password_hash cannot generate). But this is probably pretty far fetched ^^
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think it matters since bcrypt and crypt hashes are checked before hand, but I went ahead and converted it to your suggestion anyways. Your solution makes this a little more portable if new algorithms are added.
The implementation looks good to me (at least the C part, no idea about autoconf), nice work! |
Using zend_string_alloc instead of char* for out and encoded variables
@nikic Thanks, and thanks for the code review! |
Argon2d is not suitable for password_hashing. To ensure best practices within password_*, Argon2d was removed. --with-argon2 implies the full feature set of Argon2, whereas this feature only implements Argon2i within password_*. Consequently the feature flag was renamed to --with-password-argon2
- Updating tests - Adjusting cost factors: - memory_cost = 1 MiB - time_cost = 2 - threads = 2
Test normal operation of password_verify() with argon2 | ||
--SKIPIF-- | ||
<?php | ||
if (!defined('PASSWORD_ARGON2I')) die('Skipped: password_get_info not built with Argon2'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
password_get_info not built with Argon2
in password_verify
test
@charlesportwoodii ext/standard/tests/password/password_needs_rehash_argon2.phpt is failing for me on Windows x64 (I haven't checked other platforms yet) with the following diff:
The other tests are running fine. |
I'm pretty sure the test file is the problem. Just let me verify that is the case and I'll have a patch up for you momentarily. I'll also provide a separate PR for the upgrading docs since this was forked from 7.1 instead of 7.2. |
Yeah, it's just the test file that needs to be updated after the constants were changed. The following diff should fix it. Git must've not picked up my last change set for this. Sorry for the trouble.
The patch is listed below.
For the |
And a patch for the
|
Thanks, that looks fine! I'm going to commit. |
So i know i'm late to the party, But couldn't Just curious and speculating ofcourse, but couldn't really find an answer to this, enlight me! :) |
Hi, what about support for the Argon2id ( |
The bundling issue was resolved by using the This was merged in nearly a year before While I agree there could be some efficiencies gained by using I believe 7.2 is feature frozen, and the implemented version of |
RFC: https://wiki.php.net/rfc/argon2_password_hash