aboutsummaryrefslogtreecommitdiffstats
path: root/src/lib/pbkdf/pbkdf2/pbkdf2.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/pbkdf/pbkdf2/pbkdf2.cpp')
-rw-r--r--src/lib/pbkdf/pbkdf2/pbkdf2.cpp84
1 files changed, 46 insertions, 38 deletions
diff --git a/src/lib/pbkdf/pbkdf2/pbkdf2.cpp b/src/lib/pbkdf/pbkdf2/pbkdf2.cpp
index 146dd15b0..0ff412bc5 100644
--- a/src/lib/pbkdf/pbkdf2/pbkdf2.cpp
+++ b/src/lib/pbkdf/pbkdf2/pbkdf2.cpp
@@ -27,51 +27,49 @@ PKCS5_PBKDF2* PKCS5_PBKDF2::make(const Spec& spec)
return nullptr;
}
-/*
-* Return a PKCS #5 PBKDF2 derived key
-*/
-std::pair<size_t, OctetString>
-PKCS5_PBKDF2::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
+size_t
+pbkdf2(MessageAuthenticationCode& prf,
+ byte out[],
+ size_t out_len,
+ const std::string& passphrase,
+ const byte salt[], size_t salt_len,
+ size_t iterations,
+ std::chrono::milliseconds msec)
{
- if(key_len == 0)
- return std::make_pair(iterations, OctetString());
+ clear_mem(out, out_len);
+
+ if(out_len == 0)
+ return 0;
try
{
- mac->set_key(reinterpret_cast<const byte*>(passphrase.data()),
- passphrase.length());
+ prf.set_key(reinterpret_cast<const byte*>(passphrase.data()), passphrase.size());
}
catch(Invalid_Key_Length)
{
- throw Exception(name() + " cannot accept passphrases of length " +
- std::to_string(passphrase.length()));
+ throw std::runtime_error("PBKDF2 with " + prf.name() +
+ " cannot accept passphrases of length " +
+ std::to_string(passphrase.size()));
}
- secure_vector<byte> key(key_len);
-
- byte* T = &key[0];
-
- secure_vector<byte> U(mac->output_length());
+ const size_t prf_sz = prf.output_length();
+ secure_vector<byte> U(prf_sz);
- const size_t blocks_needed = round_up(key_len, mac->output_length()) / mac->output_length();
+ const size_t blocks_needed = round_up(out_len, prf_sz) / prf_sz;
std::chrono::microseconds usec_per_block =
std::chrono::duration_cast<std::chrono::microseconds>(msec) / blocks_needed;
u32bit counter = 1;
- while(key_len)
+ while(out_len)
{
- size_t T_size = std::min<size_t>(mac->output_length(), key_len);
+ const size_t prf_output = std::min<size_t>(prf_sz, out_len);
- mac->update(salt, salt_len);
- mac->update_be(counter);
- mac->final(&U[0]);
+ prf.update(salt, salt_len);
+ prf.update_be(counter++);
+ prf.final(&U[0]);
- xor_buf(T, &U[0], T_size);
+ xor_buf(out, &U[0], prf_output);
if(iterations == 0)
{
@@ -86,9 +84,9 @@ PKCS5_PBKDF2::key_derivation(size_t key_len,
while(true)
{
- mac->update(U);
- mac->final(&U[0]);
- xor_buf(T, &U[0], T_size);
+ prf.update(U);
+ prf.final(&U[0]);
+ xor_buf(out, &U[0], prf_output);
iterations++;
/*
@@ -96,7 +94,7 @@ PKCS5_PBKDF2::key_derivation(size_t key_len,
avoids confusion, and likely some broken implementations
break on getting completely randomly distributed values
*/
- if(iterations % 1000 == 0)
+ if(iterations % 10000 == 0)
{
auto time_taken = std::chrono::high_resolution_clock::now() - start;
auto usec_taken = std::chrono::duration_cast<std::chrono::microseconds>(time_taken);
@@ -109,18 +107,28 @@ PKCS5_PBKDF2::key_derivation(size_t key_len,
{
for(size_t i = 1; i != iterations; ++i)
{
- mac->update(U);
- mac->final(&U[0]);
- xor_buf(T, &U[0], T_size);
+ prf.update(U);
+ prf.final(&U[0]);
+ xor_buf(out, &U[0], prf_output);
}
}
- key_len -= T_size;
- T += T_size;
- ++counter;
+ out_len -= prf_output;
+ out += prf_output;
}
- return std::make_pair(iterations, key);
+ return iterations;
}
+size_t
+PKCS5_PBKDF2::pbkdf(byte key[], size_t key_len,
+ const std::string& passphrase,
+ const byte salt[], size_t salt_len,
+ size_t iterations,
+ std::chrono::milliseconds msec) const
+ {
+ return pbkdf2(*mac.get(), key, key_len, passphrase, salt, salt_len, iterations, msec);
+ }
+
+
}