Botan  2.1.0
Crypto and TLS for C++11
pbkdf.cpp
Go to the documentation of this file.
1 /*
2 * PBKDF
3 * (C) 2012 Jack Lloyd
4 *
5 * Botan is released under the Simplified BSD License (see license.txt)
6 */
7 
8 #include <botan/pbkdf.h>
9 #include <botan/scan_name.h>
10 
11 #if defined(BOTAN_HAS_PBKDF1)
12 #include <botan/pbkdf1.h>
13 #endif
14 
15 #if defined(BOTAN_HAS_PBKDF2)
16 #include <botan/pbkdf2.h>
17 #endif
18 
19 namespace Botan {
20 
21 std::unique_ptr<PBKDF> PBKDF::create(const std::string& algo_spec,
22  const std::string& provider)
23  {
24  const SCAN_Name req(algo_spec);
25 
26 #if defined(BOTAN_HAS_PBKDF2)
27  if(req.algo_name() == "PBKDF2")
28  {
29  // TODO OpenSSL
30 
31  if(provider.empty() || provider == "base")
32  {
33  if(auto mac = MessageAuthenticationCode::create(req.arg(0)))
34  return std::unique_ptr<PBKDF>(new PKCS5_PBKDF2(mac.release()));
35 
36  if(auto mac = MessageAuthenticationCode::create("HMAC(" + req.arg(0) + ")"))
37  return std::unique_ptr<PBKDF>(new PKCS5_PBKDF2(mac.release()));
38  }
39 
40  return nullptr;
41  }
42 #endif
43 
44 #if defined(BOTAN_HAS_PBKDF1)
45  if(req.algo_name() == "PBKDF1" && req.arg_count() == 1)
46  {
47  if(auto hash = HashFunction::create(req.arg(0)))
48  return std::unique_ptr<PBKDF>(new PKCS5_PBKDF1(hash.release()));
49 
50  }
51 #endif
52 
53  BOTAN_UNUSED(req);
54  BOTAN_UNUSED(provider);
55 
56  return nullptr;
57  }
58 
59 std::vector<std::string> PBKDF::providers(const std::string& algo_spec)
60  {
61  return probe_providers_of<PBKDF>(algo_spec, { "base", "openssl" });
62  }
63 
64 void PBKDF::pbkdf_timed(uint8_t out[], size_t out_len,
65  const std::string& passphrase,
66  const uint8_t salt[], size_t salt_len,
67  std::chrono::milliseconds msec,
68  size_t& iterations) const
69  {
70  iterations = pbkdf(out, out_len, passphrase, salt, salt_len, 0, msec);
71  }
72 
73 void PBKDF::pbkdf_iterations(uint8_t out[], size_t out_len,
74  const std::string& passphrase,
75  const uint8_t salt[], size_t salt_len,
76  size_t iterations) const
77  {
78  if(iterations == 0)
79  throw Invalid_Argument(name() + ": Invalid iteration count");
80 
81  const size_t iterations_run = pbkdf(out, out_len, passphrase,
82  salt, salt_len, iterations,
83  std::chrono::milliseconds(0));
84  BOTAN_ASSERT_EQUAL(iterations, iterations_run, "Expected PBKDF iterations");
85  }
86 
88  const std::string& passphrase,
89  const uint8_t salt[], size_t salt_len,
90  size_t iterations) const
91  {
92  secure_vector<uint8_t> out(out_len);
93  pbkdf_iterations(out.data(), out_len, passphrase, salt, salt_len, iterations);
94  return out;
95  }
96 
98  const std::string& passphrase,
99  const uint8_t salt[], size_t salt_len,
100  std::chrono::milliseconds msec,
101  size_t& iterations) const
102  {
103  secure_vector<uint8_t> out(out_len);
104  pbkdf_timed(out.data(), out_len, passphrase, salt, salt_len, msec, iterations);
105  return out;
106  }
107 
108 }
std::string arg(size_t i) const
Definition: scan_name.cpp:122
static std::unique_ptr< PBKDF > create(const std::string &algo_spec, const std::string &provider="")
Definition: pbkdf.cpp:21
static std::unique_ptr< MessageAuthenticationCode > create(const std::string &algo_spec, const std::string &provider="")
Definition: mac.cpp:43
static std::vector< std::string > providers(const std::string &algo_spec)
Definition: pbkdf.cpp:59
size_t arg_count() const
Definition: scan_name.h:50
virtual std::string name() const =0
void pbkdf_timed(uint8_t out[], size_t out_len, const std::string &passphrase, const uint8_t salt[], size_t salt_len, std::chrono::milliseconds msec, size_t &iterations) const
Definition: pbkdf.cpp:64
std::vector< T, secure_allocator< T >> secure_vector
Definition: secmem.h:121
#define BOTAN_UNUSED(v)
Definition: assert.h:92
#define BOTAN_ASSERT_EQUAL(expr1, expr2, assertion_made)
Definition: assert.h:53
virtual size_t pbkdf(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) const =0
static std::unique_ptr< HashFunction > create(const std::string &algo_spec, const std::string &provider="")
Definition: hash.cpp:93
Definition: alg_id.cpp:13
const std::string & algo_name() const
Definition: scan_name.h:45
void pbkdf_iterations(uint8_t out[], size_t out_len, const std::string &passphrase, const uint8_t salt[], size_t salt_len, size_t iterations) const
Definition: pbkdf.cpp:73
MechanismType hash