Botan 2.1.0 Crypto and TLS for C++11

- Main Page
- Namespaces
- Classes
- Files

- File List
- File Members

pbkdf2.cpp
Go to the documentation of this file.
1 /*
2 * PBKDF2
3 * (C) 1999-2007 Jack Lloyd
4 *
5 * Botan is released under the Simplified BSD License (see license.txt)
6 */
7
8 #include <botan/pbkdf2.h>
9 #include <botan/loadstor.h>
10 #include <botan/internal/rounding.h>
11
12 namespace Botan {
13
14 size_t
15 pbkdf2(MessageAuthenticationCode& prf,
16 uint8_t out[],
17 size_t out_len,
18 const std::string& passphrase,
19 const uint8_t salt[], size_t salt_len,
20 size_t iterations,
21 std::chrono::milliseconds msec)
22 {
23 clear_mem(out, out_len);
24
25 if(out_len == 0)
26 return 0;
27
28 try
29 {
30 prf.set_key(reinterpret_cast<const uint8_t*>(passphrase.data()), passphrase.size());
31 }
32 catch(Invalid_Key_Length&)
33 {
34 throw Exception("PBKDF2 with " + prf.name() +
35 " cannot accept passphrases of length " +
36 std::to_string(passphrase.size()));
37 }
38
39 const size_t prf_sz = prf.output_length();
40 secure_vector<uint8_t> U(prf_sz);
41
42 const size_t blocks_needed = round_up(out_len, prf_sz) / prf_sz;
43
44 std::chrono::microseconds usec_per_block =
45 std::chrono::duration_cast<std::chrono::microseconds>(msec) / blocks_needed;
46
47 uint32_t counter = 1;
48 while(out_len)
49 {
50 const size_t prf_output = std::min<size_t>(prf_sz, out_len);
51
52 prf.update(salt, salt_len);
53 prf.update_be(counter++);
54 prf.final(U.data());
55
56 xor_buf(out, U.data(), prf_output);
57
58 if(iterations == 0)
59 {
60 /*
61 If no iterations set, run the first block to calibrate based
62 on how long hashing takes on whatever machine we're running on.
63 */
64
65 const auto start = std::chrono::high_resolution_clock::now();
66
67 iterations = 1; // the first iteration we did above
68
69 while(true)
70 {
71 prf.update(U);
72 prf.final(U.data());
73 xor_buf(out, U.data(), prf_output);
74 iterations++;
75
76 /*
77 Only break on relatively 'even' iterations. For one it
78 avoids confusion, and likely some broken implementations
79 break on getting completely randomly distributed values
80 */
81 if(iterations % 10000 == 0)
82 {
83 auto time_taken = std::chrono::high_resolution_clock::now() - start;
84 auto usec_taken = std::chrono::duration_cast<std::chrono::microseconds>(time_taken);
85 if(usec_taken > usec_per_block)
86 break;
87 }
88 }
89 }
90 else
91 {
92 for(size_t i = 1; i != iterations; ++i)
93 {
94 prf.update(U);
95 prf.final(U.data());
96 xor_buf(out, U.data(), prf_output);
97 }
98 }
99
100 out_len -= prf_output;
101 out += prf_output;
102 }
103
104 return iterations;
105 }
106
107 size_t
108 PKCS5_PBKDF2::pbkdf(uint8_t key[], size_t key_len,
109 const std::string& passphrase,
110 const uint8_t salt[], size_t salt_len,
111 size_t iterations,
112 std::chrono::milliseconds msec) const
113 {
114 return pbkdf2(*m_mac.get(), key, key_len, passphrase, salt, salt_len, iterations, msec);
115 }
116
117
118 }
Botan::xor_buf
void xor_buf(T out[], const T in[], size_t length)
Definition: mem_ops.h:115
Botan::Invalid_Key_Length
Definition: exceptn.h:98
Botan::Exception
Definition: exceptn.h:21
Botan::clear_mem
void clear_mem(T *ptr, size_t n)
Definition: mem_ops.h:57
Botan::MessageAuthenticationCode
Definition: mac.h:20
Botan::ASN1::to_string
std::string to_string(const BER_Object &obj)
Definition: asn1_obj.cpp:47
Botan::Buffered_Computation::final
void final(uint8_t out[])
Definition: buf_comp.h:89
Botan::secure_vector
std::vector< T, secure_allocator< T >> secure_vector
Definition: secmem.h:121
Botan::SymmetricAlgorithm::set_key
void set_key(const SymmetricKey &key)
Definition: sym_algo.h:66
Botan::SymmetricAlgorithm::name
virtual std::string name() const =0
Botan
Definition: alg_id.cpp:13
Botan::pbkdf2
size_t pbkdf2(MessageAuthenticationCode &prf, uint8_t out[], size_t out_len, const std::string &passphrase, const uint8_t salt[], size_t salt_len, size_t iterations, std::chrono::milliseconds msec)
Definition: pbkdf2.cpp:15
Botan::PKCS5_PBKDF2::pbkdf
size_t pbkdf(uint8_t output_buf[], size_t output_len, const std::string &passphrase, const uint8_t salt[], size_t salt_len, size_t iterations, std::chrono::milliseconds msec) const override
Definition: pbkdf2.cpp:108
Botan::Buffered_Computation::update
void update(const uint8_t in[], size_t length)
Definition: buf_comp.h:34
Botan::Buffered_Computation::update_be
void update_be(const T in)
Definition: buf_comp.h:58
Botan::round_up
size_t round_up(size_t n, size_t align_to)
Definition: rounding.h:22
Botan::Buffered_Computation::output_length
virtual size_t output_length() const =0