diff options
Diffstat (limited to 'src/lib')
-rw-r--r-- | src/lib/pbkdf/pbkdf2/pbkdf2.cpp | 5 | ||||
-rw-r--r-- | src/lib/pbkdf/pbkdf2/pbkdf2.h | 2 | ||||
-rw-r--r-- | src/lib/pbkdf/pgp_s2k/pgp_s2k.cpp | 5 | ||||
-rw-r--r-- | src/lib/pbkdf/pgp_s2k/pgp_s2k.h | 2 | ||||
-rw-r--r-- | src/lib/pbkdf/pwdhash.h | 19 | ||||
-rw-r--r-- | src/lib/pbkdf/scrypt/scrypt.cpp | 22 | ||||
-rw-r--r-- | src/lib/pbkdf/scrypt/scrypt.h | 2 | ||||
-rw-r--r-- | src/lib/pubkey/pbes2/pbes2.cpp | 13 |
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); |