Botan
1.11.15
|
00001 /* 00002 * PBKDF1 00003 * (C) 1999-2007 Jack Lloyd 00004 * 00005 * Botan is released under the Simplified BSD License (see license.txt) 00006 */ 00007 00008 #include <botan/internal/pbkdf_utils.h> 00009 #include <botan/pbkdf1.h> 00010 #include <botan/exceptn.h> 00011 00012 namespace Botan { 00013 00014 BOTAN_REGISTER_PBKDF_1HASH(PKCS5_PBKDF1, "PBKDF1") 00015 00016 size_t PKCS5_PBKDF1::pbkdf(byte output_buf[], size_t output_len, 00017 const std::string& passphrase, 00018 const byte salt[], size_t salt_len, 00019 size_t iterations, 00020 std::chrono::milliseconds msec) const 00021 { 00022 if(output_len > m_hash->output_length()) 00023 throw Invalid_Argument("PKCS5_PBKDF1: Requested output length too long"); 00024 00025 m_hash->update(passphrase); 00026 m_hash->update(salt, salt_len); 00027 secure_vector<byte> key = m_hash->final(); 00028 00029 const auto start = std::chrono::high_resolution_clock::now(); 00030 size_t iterations_performed = 1; 00031 00032 while(true) 00033 { 00034 if(iterations == 0) 00035 { 00036 if(iterations_performed % 10000 == 0) 00037 { 00038 auto time_taken = std::chrono::high_resolution_clock::now() - start; 00039 auto msec_taken = std::chrono::duration_cast<std::chrono::milliseconds>(time_taken); 00040 if(msec_taken > msec) 00041 break; 00042 } 00043 } 00044 else if(iterations_performed == iterations) 00045 break; 00046 00047 m_hash->update(key); 00048 m_hash->final(&key[0]); 00049 00050 ++iterations_performed; 00051 } 00052 00053 copy_mem(output_buf, &key[0], output_len); 00054 return iterations_performed; 00055 } 00056 00057 }