Skip to content

Commit

Permalink
Fix version 4.0.x with newer libsodium
Browse files Browse the repository at this point in the history
  • Loading branch information
paragonie-security committed Jan 30, 2018
1 parent 4c02383 commit 93e7091
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 10 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
# Changelog

## Version 4.0.3 (2018-01-30)

* [#72](https://github.com/paragonie/halite/issues/72): Fixed forward-compatibility with
libsodium 1.0.15.

## Version 4.0.2 (2017-12-08)

This is mostly a boyscouting/documentation release. However, we now pass Psalm under the
Expand Down
33 changes: 24 additions & 9 deletions src/KeyFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ public static function deriveAuthenticationKey(
string $salt,
string $level = self::INTERACTIVE
): AuthenticationKey {
$kdfLimits = self::getSecurityLevels($level);
$kdfLimits = self::getSecurityLevels($level, true);
// VERSION 2+ (argon2)
if (Util::safeStrlen($salt) !== \SODIUM_CRYPTO_PWHASH_SALTBYTES) {
throw new InvalidSalt(
Expand All @@ -147,7 +147,8 @@ public static function deriveAuthenticationKey(
$password->getString(),
$salt,
$kdfLimits[0],
$kdfLimits[1]
$kdfLimits[1],
\SODIUM_CRYPTO_PWHASH_ALG_ARGON2I13
);
return new AuthenticationKey(
new HiddenString($secretKey)
Expand All @@ -172,7 +173,7 @@ public static function deriveEncryptionKey(
string $salt,
string $level = self::INTERACTIVE
): EncryptionKey {
$kdfLimits = self::getSecurityLevels($level);
$kdfLimits = self::getSecurityLevels($level, true);
// VERSION 2+ (argon2)
if (Util::safeStrlen($salt) !== \SODIUM_CRYPTO_PWHASH_SALTBYTES) {
throw new InvalidSalt(
Expand All @@ -184,7 +185,8 @@ public static function deriveEncryptionKey(
$password->getString(),
$salt,
$kdfLimits[0],
$kdfLimits[1]
$kdfLimits[1],
\SODIUM_CRYPTO_PWHASH_ALG_ARGON2I13
);
return new EncryptionKey(
new HiddenString($secretKey)
Expand All @@ -208,7 +210,7 @@ public static function deriveEncryptionKeyPair(
string $salt,
string $level = self::INTERACTIVE
): EncryptionKeyPair {
$kdfLimits = self::getSecurityLevels($level);
$kdfLimits = self::getSecurityLevels($level, true);
// VERSION 2+ (argon2)
if (Util::safeStrlen($salt) !== \SODIUM_CRYPTO_PWHASH_SALTBYTES) {
throw new InvalidSalt(
Expand All @@ -221,7 +223,8 @@ public static function deriveEncryptionKeyPair(
$password->getString(),
$salt,
$kdfLimits[0],
$kdfLimits[1]
$kdfLimits[1],
\SODIUM_CRYPTO_PWHASH_ALG_ARGON2I13
);
$keyPair = \sodium_crypto_box_seed_keypair($seed);
$secretKey = \sodium_crypto_box_secretkey($keyPair);
Expand Down Expand Up @@ -253,7 +256,7 @@ public static function deriveSignatureKeyPair(
string $salt,
string $level = self::INTERACTIVE
): SignatureKeyPair {
$kdfLimits = self::getSecurityLevels($level);
$kdfLimits = self::getSecurityLevels($level, true);
// VERSION 2+ (argon2)
if (Util::safeStrlen($salt) !== \SODIUM_CRYPTO_PWHASH_SALTBYTES) {
throw new InvalidSalt(
Expand All @@ -266,7 +269,8 @@ public static function deriveSignatureKeyPair(
$password->getString(),
$salt,
$kdfLimits[0],
$kdfLimits[1]
$kdfLimits[1],
\SODIUM_CRYPTO_PWHASH_ALG_ARGON2I13
);
$keyPair = \sodium_crypto_sign_seed_keypair($seed);
$secretKey = \sodium_crypto_sign_secretkey($keyPair);
Expand All @@ -280,27 +284,38 @@ public static function deriveSignatureKeyPair(
);
}


/**
* Returns a 2D array [OPSLIMIT, MEMLIMIT] for the appropriate security level.
*
* @param string $level
* @param bool $compat
* @return int[]
* @throws InvalidType
*/
public static function getSecurityLevels(string $level = self::INTERACTIVE): array
public static function getSecurityLevels(string $level = self::INTERACTIVE, bool $compat = false): array
{
switch ($level) {
case self::INTERACTIVE:
if ($compat) {
return [4, 33554432];
}
return [
\SODIUM_CRYPTO_PWHASH_OPSLIMIT_INTERACTIVE,
\SODIUM_CRYPTO_PWHASH_MEMLIMIT_INTERACTIVE
];
case self::MODERATE:
if ($compat) {
return [6, 134217728];
}
return [
\SODIUM_CRYPTO_PWHASH_OPSLIMIT_MODERATE,
\SODIUM_CRYPTO_PWHASH_MEMLIMIT_MODERATE
];
case self::SENSITIVE:
if ($compat) {
return [8, 536870912];
}
return [
\SODIUM_CRYPTO_PWHASH_OPSLIMIT_SENSITIVE,
\SODIUM_CRYPTO_PWHASH_MEMLIMIT_SENSITIVE
Expand Down
15 changes: 14 additions & 1 deletion src/Password.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
namespace ParagonIE\Halite;

use ParagonIE\ConstantTime\Base64UrlSafe;
use ParagonIE\ConstantTime\Binary;
use ParagonIE\ConstantTime\Hex;
use ParagonIE\Halite\Alerts\{
CannotPerformOperation,
Expand Down Expand Up @@ -108,7 +109,10 @@ public static function needsRehash(
// Upon successful decryption, verify that we're using Argon2i
if (!\hash_equals(
Util::safeSubstr($hash_str, 0, 9),
\SODIUM_CRYPTO_PWHASH_STRPREFIX
'$argon2i$'
) && !\hash_equals(
Util::safeSubstr($hash_str, 0, 10),
'$argon2id$'
)) {
return true;
}
Expand All @@ -119,16 +123,25 @@ public static function needsRehash(
return !\hash_equals(
'$argon2i$v=19$m=32768,t=4,p=1$',
Util::safeSubstr($hash_str, 0, 30)
) && !\hash_equals(
'$argon2id$v=19$m=65536,t=2,p=1$',
Util::safeSubstr($hash_str, 0, 31)
);
case KeyFactory::MODERATE:
return !\hash_equals(
'$argon2i$v=19$m=131072,t=6,p=1$',
Util::safeSubstr($hash_str, 0, 31)
) && !\hash_equals(
'$argon2id$v=19$m=262144,t=3,p=1$',
Util::safeSubstr($hash_str, 0, 32)
);
case KeyFactory::SENSITIVE:
return !\hash_equals(
'$argon2i$v=19$m=524288,t=8,p=1$',
Util::safeSubstr($hash_str, 0, 31)
) && !\hash_equals(
'$argon2id$v=19$m=1048576,t=4,p=1',
Util::safeSubstr($hash_str, 0, 33)
);
default:
return true;
Expand Down

0 comments on commit 93e7091

Please sign in to comment.