Botan  2.11.0
Crypto and TLS for C++11
pwdhash.cpp
Go to the documentation of this file.
1 /*
2 * (C) 2018 Ribose Inc
3 *
4 * Botan is released under the Simplified BSD License (see license.txt)
5 */
6 
7 #include <botan/pwdhash.h>
8 #include <botan/exceptn.h>
9 #include <botan/scan_name.h>
10 
11 #if defined(BOTAN_HAS_PBKDF2)
12  #include <botan/pbkdf2.h>
13 #endif
14 
15 #if defined(BOTAN_HAS_PGP_S2K)
16  #include <botan/pgp_s2k.h>
17 #endif
18 
19 #if defined(BOTAN_HAS_SCRYPT)
20  #include <botan/scrypt.h>
21 #endif
22 
23 #if defined(BOTAN_HAS_ARGON2)
24  #include <botan/argon2.h>
25 #endif
26 
27 #if defined(BOTAN_HAS_PBKDF_BCRYPT)
28  #include <botan/bcrypt_pbkdf.h>
29 #endif
30 
31 namespace Botan {
32 
33 std::unique_ptr<PasswordHashFamily> PasswordHashFamily::create(const std::string& algo_spec,
34  const std::string& provider)
35  {
36  const SCAN_Name req(algo_spec);
37 
38 #if defined(BOTAN_HAS_PBKDF2)
39  if(req.algo_name() == "PBKDF2")
40  {
41  // TODO OpenSSL
42 
43  if(provider.empty() || provider == "base")
44  {
45  if(auto mac = MessageAuthenticationCode::create(req.arg(0)))
46  return std::unique_ptr<PasswordHashFamily>(new PBKDF2_Family(mac.release()));
47 
48  if(auto mac = MessageAuthenticationCode::create("HMAC(" + req.arg(0) + ")"))
49  return std::unique_ptr<PasswordHashFamily>(new PBKDF2_Family(mac.release()));
50  }
51 
52  return nullptr;
53  }
54 #endif
55 
56 #if defined(BOTAN_HAS_SCRYPT)
57  if(req.algo_name() == "Scrypt")
58  {
59  return std::unique_ptr<PasswordHashFamily>(new Scrypt_Family);
60  }
61 #endif
62 
63 #if defined(BOTAN_HAS_ARGON2)
64  if(req.algo_name() == "Argon2d")
65  {
66  return std::unique_ptr<PasswordHashFamily>(new Argon2_Family(0));
67  }
68  else if(req.algo_name() == "Argon2i")
69  {
70  return std::unique_ptr<PasswordHashFamily>(new Argon2_Family(1));
71  }
72  else if(req.algo_name() == "Argon2id")
73  {
74  return std::unique_ptr<PasswordHashFamily>(new Argon2_Family(2));
75  }
76 #endif
77 
78 #if defined(BOTAN_HAS_PBKDF_BCRYPT)
79  if(req.algo_name() == "Bcrypt-PBKDF")
80  {
81  return std::unique_ptr<PasswordHashFamily>(new Bcrypt_PBKDF_Family);
82  }
83 #endif
84 
85 #if defined(BOTAN_HAS_PGP_S2K)
86  if(req.algo_name() == "OpenPGP-S2K" && req.arg_count() == 1)
87  {
88  if(auto hash = HashFunction::create(req.arg(0)))
89  {
90  return std::unique_ptr<PasswordHashFamily>(new RFC4880_S2K_Family(hash.release()));
91  }
92  }
93 #endif
94 
95  BOTAN_UNUSED(req);
96  BOTAN_UNUSED(provider);
97 
98  return nullptr;
99  }
100 
101 //static
102 std::unique_ptr<PasswordHashFamily>
103 PasswordHashFamily::create_or_throw(const std::string& algo,
104  const std::string& provider)
105  {
106  if(auto pbkdf = PasswordHashFamily::create(algo, provider))
107  {
108  return pbkdf;
109  }
110  throw Lookup_Error("PasswordHashFamily", algo, provider);
111  }
112 
113 std::vector<std::string> PasswordHashFamily::providers(const std::string& algo_spec)
114  {
115  return probe_providers_of<PasswordHashFamily>(algo_spec, { "base", "openssl" });
116  }
117 
118 }
size_t arg_count() const
Definition: scan_name.h:54
static std::unique_ptr< MessageAuthenticationCode > create(const std::string &algo_spec, const std::string &provider="")
Definition: mac.cpp:46
static std::vector< std::string > providers(const std::string &algo_spec)
Definition: pwdhash.cpp:113
static std::unique_ptr< PasswordHashFamily > create_or_throw(const std::string &algo_spec, const std::string &provider="")
Definition: pwdhash.cpp:103
std::string arg(size_t i) const
Definition: scan_name.cpp:124
static std::unique_ptr< HashFunction > create(const std::string &algo_spec, const std::string &provider="")
Definition: hash.cpp:110
Definition: alg_id.cpp:13
static std::unique_ptr< PasswordHashFamily > create(const std::string &algo_spec, const std::string &provider="")
Definition: pwdhash.cpp:33
#define BOTAN_UNUSED(...)
Definition: assert.h:142
const std::string & algo_name() const
Definition: scan_name.h:49
MechanismType hash