aboutsummaryrefslogtreecommitdiffstats
path: root/src/lib
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib')
-rw-r--r--src/lib/pbkdf/pbkdf2/pbkdf2.cpp5
-rw-r--r--src/lib/pbkdf/pbkdf2/pbkdf2.h2
-rw-r--r--src/lib/pbkdf/pgp_s2k/pgp_s2k.cpp5
-rw-r--r--src/lib/pbkdf/pgp_s2k/pgp_s2k.h2
-rw-r--r--src/lib/pbkdf/pwdhash.h19
-rw-r--r--src/lib/pbkdf/scrypt/scrypt.cpp22
-rw-r--r--src/lib/pbkdf/scrypt/scrypt.h2
-rw-r--r--src/lib/pubkey/pbes2/pbes2.cpp13
8 files changed, 57 insertions, 13 deletions
diff --git a/src/lib/pbkdf/pbkdf2/pbkdf2.cpp b/src/lib/pbkdf/pbkdf2/pbkdf2.cpp
index 47a5a0bb4..65e8a9503 100644
--- a/src/lib/pbkdf/pbkdf2/pbkdf2.cpp
+++ b/src/lib/pbkdf/pbkdf2/pbkdf2.cpp
@@ -214,4 +214,9 @@ std::unique_ptr<PasswordHash> PBKDF2_Family::from_params(size_t iter, size_t, si
return std::unique_ptr<PasswordHash>(new PBKDF2(*m_prf, iter));
}
+std::unique_ptr<PasswordHash> PBKDF2_Family::from_iterations(size_t iter) const
+ {
+ return std::unique_ptr<PasswordHash>(new PBKDF2(*m_prf, iter));
+ }
+
}
diff --git a/src/lib/pbkdf/pbkdf2/pbkdf2.h b/src/lib/pbkdf/pbkdf2/pbkdf2.h
index e70f56d99..72637bc30 100644
--- a/src/lib/pbkdf/pbkdf2/pbkdf2.h
+++ b/src/lib/pbkdf/pbkdf2/pbkdf2.h
@@ -77,6 +77,8 @@ class BOTAN_PUBLIC_API(2,8) PBKDF2_Family final : public PasswordHashFamily
*/
std::unique_ptr<PasswordHash> default_params() const override;
+ std::unique_ptr<PasswordHash> from_iterations(size_t iter) const override;
+
std::unique_ptr<PasswordHash> from_params(
size_t iter, size_t, size_t) const override;
private:
diff --git a/src/lib/pbkdf/pgp_s2k/pgp_s2k.cpp b/src/lib/pbkdf/pgp_s2k/pgp_s2k.cpp
index 65e4e72c0..355e2cf44 100644
--- a/src/lib/pbkdf/pgp_s2k/pgp_s2k.cpp
+++ b/src/lib/pbkdf/pgp_s2k/pgp_s2k.cpp
@@ -188,6 +188,11 @@ std::unique_ptr<PasswordHash> RFC4880_S2K_Family::default_params() const
return std::unique_ptr<PasswordHash>(new RFC4880_S2K(m_hash->clone(), 50331648));
}
+std::unique_ptr<PasswordHash> RFC4880_S2K_Family::from_iterations(size_t iter) const
+ {
+ return std::unique_ptr<PasswordHash>(new RFC4880_S2K(m_hash->clone(), iter));
+ }
+
RFC4880_S2K::RFC4880_S2K(HashFunction* hash, size_t iterations) :
m_hash(hash),
m_iterations(iterations)
diff --git a/src/lib/pbkdf/pgp_s2k/pgp_s2k.h b/src/lib/pbkdf/pgp_s2k/pgp_s2k.h
index b2c16d9ed..820fa3801 100644
--- a/src/lib/pbkdf/pgp_s2k/pgp_s2k.h
+++ b/src/lib/pbkdf/pgp_s2k/pgp_s2k.h
@@ -143,6 +143,8 @@ class BOTAN_PUBLIC_API(2,8) RFC4880_S2K_Family final : public PasswordHashFamily
*/
std::unique_ptr<PasswordHash> default_params() const override;
+ std::unique_ptr<PasswordHash> from_iterations(size_t iter) const override;
+
std::unique_ptr<PasswordHash> from_params(
size_t iter, size_t, size_t) const override;
private:
diff --git a/src/lib/pbkdf/pwdhash.h b/src/lib/pbkdf/pwdhash.h
index 7ecf111c6..d4a205340 100644
--- a/src/lib/pbkdf/pwdhash.h
+++ b/src/lib/pbkdf/pwdhash.h
@@ -41,9 +41,13 @@ class BOTAN_PUBLIC_API(2,8) PasswordHash
/**
* Some password hashing algorithms have a parallelism parameter.
- * If not supported by some algorithm, just returns 1
+ * If the algorithm does not support this notion, then the
+ * function returns zero. This allows distinguishing between a
+ * password hash which just does not support parallel operation,
+ * vs one that does support parallel operation but which has been
+ * configured to use a single lane.
*/
- virtual size_t parallelism() const { return 1; }
+ virtual size_t parallelism() const { return 0; }
/**
* Returns an estimate of the total memory usage required to perform this
@@ -119,7 +123,7 @@ class BOTAN_PUBLIC_API(2,8) PasswordHashFamily
*/
virtual std::unique_ptr<PasswordHash> tune(size_t output_len,
std::chrono::milliseconds msec,
- size_t max_memory_usage_mb = 128) const = 0;
+ size_t max_memory_usage_mb = 0) const = 0;
/**
* Return some default parameter set for this PBKDF that should be good
@@ -129,6 +133,15 @@ class BOTAN_PUBLIC_API(2,8) PasswordHashFamily
virtual std::unique_ptr<PasswordHash> default_params() const = 0;
/**
+ * Return a parameter chosen based on a rough approximation with the
+ * specified iteration count. The exact value this returns for a particular
+ * algorithm may change from over time. Think of it as an alternative to
+ * tune, where time is expressed in terms of PBKDF2 iterations rather than
+ * milliseconds.
+ */
+ virtual std::unique_ptr<PasswordHash> from_iterations(size_t iterations) const = 0;
+
+ /**
* Create a password hash using some scheme specific format.
* Eg PBKDF2 and PGP-S2K set iterations in i1
* Scrypt uses N,r,p in i{1-3}
diff --git a/src/lib/pbkdf/scrypt/scrypt.cpp b/src/lib/pbkdf/scrypt/scrypt.cpp
index e7f2fd96b..826438926 100644
--- a/src/lib/pbkdf/scrypt/scrypt.cpp
+++ b/src/lib/pbkdf/scrypt/scrypt.cpp
@@ -43,7 +43,6 @@ std::unique_ptr<PasswordHash> Scrypt_Family::tune(size_t output_length,
*
* Compute stime(8192,1,1) as baseline and extrapolate
*/
- //printf("max mem %d\n", max_memory_usage_mb);
const size_t max_memory_usage = max_memory_usage_mb * 1024 * 1024;
// Starting parameters
@@ -82,6 +81,8 @@ std::unique_ptr<PasswordHash> Scrypt_Family::tune(size_t output_length,
}
}
+ // Now double N as many times as we can
+
while(max_memory_usage == 0 || scrypt_memory_usage(N, r, p)*2 < max_memory_usage)
{
if(target_nsec / est_nsec >= 2)
@@ -93,6 +94,8 @@ std::unique_ptr<PasswordHash> Scrypt_Family::tune(size_t output_length,
break;
}
+ // If we have extra runtime budget, increment p
+
if(target_nsec / est_nsec > 2)
p *= std::min<size_t>(1024, (target_nsec / est_nsec));
@@ -104,6 +107,23 @@ std::unique_ptr<PasswordHash> Scrypt_Family::from_params(size_t N, size_t r, siz
return std::unique_ptr<PasswordHash>(new Scrypt(N, r, p));
}
+std::unique_ptr<PasswordHash> Scrypt_Family::from_iterations(size_t iter) const
+ {
+ const size_t r = 8;
+ const size_t p = 1;
+
+ size_t N = 8192;
+
+ if(iter > 50000)
+ N = 16384;
+ if(iter > 100000)
+ N = 32768;
+ if(iter > 150000)
+ N = 65536;
+
+ return std::unique_ptr<PasswordHash>(new Scrypt(N, r, p));
+ }
+
Scrypt::Scrypt(size_t N, size_t r, size_t p) :
m_N(N), m_r(r), m_p(p)
{
diff --git a/src/lib/pbkdf/scrypt/scrypt.h b/src/lib/pbkdf/scrypt/scrypt.h
index 8db46f779..42d0f0a3b 100644
--- a/src/lib/pbkdf/scrypt/scrypt.h
+++ b/src/lib/pbkdf/scrypt/scrypt.h
@@ -59,6 +59,8 @@ class BOTAN_PUBLIC_API(2,8) Scrypt_Family final : public PasswordHashFamily
std::unique_ptr<PasswordHash> default_params() const override;
+ std::unique_ptr<PasswordHash> from_iterations(size_t iter) const override;
+
std::unique_ptr<PasswordHash> from_params(
size_t N, size_t r, size_t p) const override;
};
diff --git a/src/lib/pubkey/pbes2/pbes2.cpp b/src/lib/pubkey/pbes2/pbes2.cpp
index e9c2a9df1..995f93c47 100644
--- a/src/lib/pubkey/pbes2/pbes2.cpp
+++ b/src/lib/pubkey/pbes2/pbes2.cpp
@@ -99,9 +99,6 @@ secure_vector<uint8_t> derive_key(const std::string& passphrase,
size_t key_length,
AlgorithmIdentifier& kdf_algo)
{
- // TODO should be configurable
- const size_t MAX_PBKDF_MEMORY = 32;
-
const secure_vector<uint8_t> salt = rng.random_vec(12);
if(digest == "Scrypt")
@@ -115,7 +112,7 @@ secure_vector<uint8_t> derive_key(const std::string& passphrase,
if(msec_in_iterations_out)
{
const std::chrono::milliseconds msec(*msec_in_iterations_out);
- pwhash = pwhash_fam->tune(key_length, msec, MAX_PBKDF_MEMORY);
+ pwhash = pwhash_fam->tune(key_length, msec);
}
else if(iterations_if_msec_null <= 100000)
{
@@ -123,9 +120,7 @@ secure_vector<uint8_t> derive_key(const std::string& passphrase,
}
else
{
- //const std::chrono::milliseconds msec(iterations_if_msec_null / 100000);
- //pwhash = pwhash_fam->tune(key_length, msec, MAX_PBKDF_MEMORY);
- pwhash = pwhash_fam->default_params();
+ pwhash = pwhash_fam->from_iterations(iterations_if_msec_null);
}
secure_vector<uint8_t> key(key_length);
@@ -170,11 +165,11 @@ secure_vector<uint8_t> derive_key(const std::string& passphrase,
if(msec_in_iterations_out)
{
const std::chrono::milliseconds msec(*msec_in_iterations_out);
- pwhash = pwhash_fam->tune(key_length, msec, MAX_PBKDF_MEMORY);
+ pwhash = pwhash_fam->tune(key_length, msec);
}
else
{
- pwhash = pwhash_fam->from_params(iterations_if_msec_null);
+ pwhash = pwhash_fam->from_iterations(iterations_if_msec_null);
}
secure_vector<uint8_t> key(key_length);