Botan 3.0.0
Crypto and TLS for C&
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/internal/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
31namespace Botan {
32
33void PasswordHash::derive_key(uint8_t out[], size_t out_len,
34 const char* password, size_t password_len,
35 const uint8_t salt[], size_t salt_len,
36 const uint8_t ad[], size_t ad_len,
37 const uint8_t key[], size_t key_len) const
38 {
39 BOTAN_UNUSED(ad, key);
40
41 if(ad_len == 0 && key_len == 0)
42 return this->derive_key(out, out_len,
43 password, password_len,
44 salt, salt_len);
45 else
46 throw Not_Implemented("PasswordHash " + this->to_string() + " does not support AD or key");
47 }
48
49std::unique_ptr<PasswordHashFamily>
50PasswordHashFamily::create(std::string_view algo_spec,
51 std::string_view provider)
52 {
53 const SCAN_Name req(algo_spec);
54
55#if defined(BOTAN_HAS_PBKDF2)
56 if(req.algo_name() == "PBKDF2")
57 {
58 if(provider.empty() || provider == "base")
59 {
60 if(auto mac = MessageAuthenticationCode::create("HMAC(" + req.arg(0) + ")"))
61 return std::make_unique<PBKDF2_Family>(std::move(mac));
62
63 if(auto mac = MessageAuthenticationCode::create(req.arg(0)))
64 return std::make_unique<PBKDF2_Family>(std::move(mac));
65 }
66
67 return nullptr;
68 }
69#endif
70
71#if defined(BOTAN_HAS_SCRYPT)
72 if(req.algo_name() == "Scrypt")
73 {
74 return std::make_unique<Scrypt_Family>();
75 }
76#endif
77
78#if defined(BOTAN_HAS_ARGON2)
79 if(req.algo_name() == "Argon2d")
80 {
81 return std::make_unique<Argon2_Family>(static_cast<uint8_t>(0));
82 }
83 else if(req.algo_name() == "Argon2i")
84 {
85 return std::make_unique<Argon2_Family>(static_cast<uint8_t>(1));
86 }
87 else if(req.algo_name() == "Argon2id")
88 {
89 return std::make_unique<Argon2_Family>(static_cast<uint8_t>(2));
90 }
91#endif
92
93#if defined(BOTAN_HAS_PBKDF_BCRYPT)
94 if(req.algo_name() == "Bcrypt-PBKDF")
95 {
96 return std::make_unique<Bcrypt_PBKDF_Family>();
97 }
98#endif
99
100#if defined(BOTAN_HAS_PGP_S2K)
101 if(req.algo_name() == "OpenPGP-S2K" && req.arg_count() == 1)
102 {
103 if(auto hash = HashFunction::create(req.arg(0)))
104 {
105 return std::make_unique<RFC4880_S2K_Family>(std::move(hash));
106 }
107 }
108#endif
109
110 BOTAN_UNUSED(req);
111 BOTAN_UNUSED(provider);
112
113 return nullptr;
114 }
115
116//static
117std::unique_ptr<PasswordHashFamily>
119 std::string_view provider)
120 {
121 if(auto pbkdf = PasswordHashFamily::create(algo, provider))
122 {
123 return pbkdf;
124 }
125 throw Lookup_Error("PasswordHashFamily", algo, provider);
126 }
127
128std::vector<std::string> PasswordHashFamily::providers(std::string_view algo_spec)
129 {
130 return probe_providers_of<PasswordHashFamily>(algo_spec);
131 }
132
133}
#define BOTAN_UNUSED(...)
Definition: assert.h:141
static std::unique_ptr< HashFunction > create(std::string_view algo_spec, std::string_view provider="")
Definition: hash.cpp:102
static std::unique_ptr< MessageAuthenticationCode > create(std::string_view algo_spec, std::string_view provider="")
Definition: mac.cpp:46
static std::unique_ptr< PasswordHashFamily > create_or_throw(std::string_view algo_spec, std::string_view provider="")
Definition: pwdhash.cpp:118
static std::vector< std::string > providers(std::string_view algo_spec)
Definition: pwdhash.cpp:128
static std::unique_ptr< PasswordHashFamily > create(std::string_view algo_spec, std::string_view provider="")
Definition: pwdhash.cpp:50
virtual void derive_key(uint8_t out[], size_t out_len, const char *password, size_t password_len, const uint8_t salt[], size_t salt_len) const =0
virtual std::string to_string() const =0
std::string arg(size_t i) const
Definition: scan_name.cpp:129
size_t arg_count() const
Definition: scan_name.h:50
const std::string algo_name() const
Definition: scan_name.h:45
Definition: alg_id.cpp:12