diff options
Diffstat (limited to 'src/pbkdf/pbkdf1/pbkdf1.cpp')
-rw-r--r-- | src/pbkdf/pbkdf1/pbkdf1.cpp | 38 |
1 files changed, 28 insertions, 10 deletions
diff --git a/src/pbkdf/pbkdf1/pbkdf1.cpp b/src/pbkdf/pbkdf1/pbkdf1.cpp index 7f0939b8f..d51cbdc18 100644 --- a/src/pbkdf/pbkdf1/pbkdf1.cpp +++ b/src/pbkdf/pbkdf1/pbkdf1.cpp @@ -13,28 +13,46 @@ namespace Botan { /* * Return a PKCS#5 PBKDF1 derived key */ -OctetString PKCS5_PBKDF1::derive_key(size_t key_len, - const std::string& passphrase, - const byte salt[], size_t salt_size, - size_t iterations) const +std::pair<size_t, OctetString> +PKCS5_PBKDF1::key_derivation(size_t key_len, + const std::string& passphrase, + const byte salt[], size_t salt_len, + size_t iterations, + std::chrono::milliseconds msec) const { - if(iterations == 0) - throw Invalid_Argument("PKCS5_PBKDF1: Invalid iteration count"); - if(key_len > hash->output_length()) throw Invalid_Argument("PKCS5_PBKDF1: Requested output length too long"); hash->update(passphrase); - hash->update(salt, salt_size); + hash->update(salt, salt_len); secure_vector<byte> key = hash->final(); - for(size_t j = 1; j != iterations; ++j) + const auto start = std::chrono::high_resolution_clock::now(); + size_t iterations_performed = 1; + + while(true) { + if(iterations == 0) + { + if(iterations_performed % 8192 == 0) + { + auto time_taken = std::chrono::high_resolution_clock::now() - start; + auto msec_taken = std::chrono::duration_cast<std::chrono::milliseconds>(time_taken); + if(msec_taken > msec) + break; + } + } + else if(iterations_performed == iterations) + break; + hash->update(key); hash->final(&key[0]); + + ++iterations_performed; } - return OctetString(&key[0], std::min<size_t>(key_len, key.size())); + return std::make_pair(iterations_performed, + OctetString(&key[0], std::min(key_len, key.size()))); } } |