PHP RFC: Provide argon2i(d) implementations for password_hash() from ext/sodium


If PHP core was built without libargon, then password_hash() and family will not support the argon2i and argon2id hashing mechanisms. Since Password Hash Registry (implemented in 7.4) allows dynamically loaded extensions to register additional algorithms at load time, and since libsodium implements the argon2i and argon2id algorithms, it makes sense to provide backfill implementations of these algorithms if core lacks them.

For anyone who builds PHP themselves, this is mostly a non-issue as they can install libargon before compiling PHP. For distributions, however, this allows the core PHP package to be leaner with fewer external dependencies, while still providing improved algorithm support for those who need it.


Wrap crypto_pwhash_str_alg() and crypto_pwhash_str_verify() from libsodium to provide argon2i and argonid implementations to the password_hash() family of functions if core has not already registered these algorithms.

New Constants

Just in case an application wants to know where their argon2 support is coming from, I'd propose a new constant to be declared by whichever module is providing the support.

PASSWORD_ARGON2_PROVIDER == 'standard' || 'sodium'

Backward Incompatible Changes

  • Incompatibilities between libargon and libsodium: Sodium's argon2 implementation enforces a minimum time_cost value of 3. Prior to PHP 7.4, the default value for time_cost was 2. This means that argon2 password hashes produced using password_hash() on earlier versions of PHP (and using the default cost value) will not be verifiable by the ext/sodium implementation of these algorithms. Indeed, any argon2 password hash produced using an explicit time_cost of 2 or less will fail to verify with the libsodium implementation.
  • libsodium support for explicitly choosing algorithm: libsodium >= 1.0.15 provides an API for explicitly choosing which argon2 algorithm to use. Older versions of libsodium make this decision for you. For example, my build using libsodium 1.0.13 always produces argon2i hashes, not argon2id. Options:
    • Make libsodium >= 1.0.15 a requirement for building
    • Make libsodium >= 1.0.15 a requirement for including password_hash() support, but still building other features (preferred option)
    • Simply accept not having all algorithms available. (Worst option IMO)

Proposed PHP Version(s)


Open Issues

  • libsodium < 1.0.15 handling; See “Backward Incompatable Changes”

Proposed Voting Choices

“Should ext/sodium export argon2i and argon2id password_hash algorithms?”

Proposed Patch

* https://github.com/php/php-src/pull/4012 This implementation only registers the algos for password_hash() *IF* the libsodium library is recent enough. (preferred option umder BC Implications)

rfc/sodium.argon.hash.txt · Last modified: 2019/04/05 23:03 by pollita