Botan 3.11.0
Crypto and TLS for C&
pwdhash.h
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#ifndef BOTAN_PWDHASH_H_
8#define BOTAN_PWDHASH_H_
9
10#include <botan/types.h>
11#include <memory>
12#include <optional>
13#include <span>
14#include <string>
15#include <vector>
16
17#if !defined(BOTAN_IS_BEING_BUILT)
18 #include <chrono>
19#endif
20
21namespace Botan {
22
23/**
24* Base class for password based key derivation functions.
25*
26* Converts a password into a key using a salt and iterated hashing to
27* make brute force attacks harder.
28*/
29class BOTAN_PUBLIC_API(2, 8) PasswordHash /* NOLINT(*-special-member-functions) */ {
30 public:
31 virtual ~PasswordHash() = default;
32
33 virtual std::string to_string() const = 0;
34
35 /**
36 * Most password hashes have some notion of iterations.
37 */
38 virtual size_t iterations() const = 0;
39
40 /**
41 * Some password hashing algorithms have a parameter which controls how
42 * much memory is used. If not supported by some algorithm, returns 0.
43 */
44 virtual size_t memory_param() const { return 0; }
45
46 /**
47 * Some password hashing algorithms have a parallelism parameter.
48 * If the algorithm does not support this notion, then the
49 * function returns zero. This allows distinguishing between a
50 * password hash which just does not support parallel operation,
51 * vs one that does support parallel operation but which has been
52 * configured to use a single lane.
53 */
54 virtual size_t parallelism() const { return 0; }
55
56 /**
57 * Returns an estimate of the total number of bytes required to perform this
58 * key derivation.
59 *
60 * If this algorithm uses a small and constant amount of memory, with no
61 * effort made towards being memory hard, this function returns 0.
62 */
63 virtual size_t total_memory_usage() const { return 0; }
64
65 /**
66 * @returns true if this password hash supports supplying a key
67 */
68 virtual bool supports_keyed_operation() const { return false; }
69
70 /**
71 * @returns true if this password hash supports supplying associated data
72 */
73 virtual bool supports_associated_data() const { return false; }
74
75 /**
76 * Hash a password into a bitstring
77 *
78 * Derive a key from the specified @p password and @p salt, placing it into
79 * @p out.
80 *
81 * @param out a span where the derived key will be placed
82 * @param password the password to derive the key from
83 * @param salt a randomly chosen salt
84 *
85 * This function is const, but is not thread safe. Different threads should
86 * either use unique objects, or serialize all access.
87 */
88 void hash(std::span<uint8_t> out, std::string_view password, std::span<const uint8_t> salt) const {
89 this->derive_key(out.data(), out.size(), password.data(), password.size(), salt.data(), salt.size());
90 }
91
92 /**
93 * Hash a password into a bitstring
94 *
95 * Derive a key from the specified @p password, @p salt, @p
96 * associated_data, and secret @p key, placing it into @p out. The
97 * @p associated_data and @p key are both allowed to be empty. Currently
98 * non-empty AD/key is only supported with Argon2.
99 *
100 * @param out a span where the derived key will be placed
101 * @param password the password to derive the key from
102 * @param salt a randomly chosen salt
103 * @param associated_data some additional data
104 * @param key a secret key
105 *
106 * This function is const, but is not thread safe. Different threads should
107 * either use unique objects, or serialize all access.
108 */
109 void hash(std::span<uint8_t> out,
110 std::string_view password,
111 std::span<const uint8_t> salt,
112 std::span<const uint8_t> associated_data,
113 std::span<const uint8_t> key) const {
114 this->derive_key(out.data(),
115 out.size(),
116 password.data(),
117 password.size(),
118 salt.data(),
119 salt.size(),
120 associated_data.data(),
121 associated_data.size(),
122 key.data(),
123 key.size());
124 }
125
126 /**
127 * Derive a key from a password
128 *
129 * @param out buffer to store the derived key, must be of out_len bytes
130 * @param out_len the desired length of the key to produce
131 * @param password the password to derive the key from
132 * @param password_len the length of password in bytes
133 * @param salt a randomly chosen salt
134 * @param salt_len length of salt in bytes
135 *
136 * This function is const, but is not thread safe. Different threads should
137 * either use unique objects, or serialize all access.
138 */
139 virtual void derive_key(uint8_t out[],
140 size_t out_len,
141 const char* password,
142 size_t password_len,
143 const uint8_t salt[],
144 size_t salt_len) const = 0;
145
146 /**
147 * Derive a key from a password plus additional data and/or a secret key
148 *
149 * Currently this is only supported for Argon2. Using a non-empty AD or key
150 * with other algorithms will cause a Not_Implemented exception.
151 *
152 * @param out buffer to store the derived key, must be of out_len bytes
153 * @param out_len the desired length of the key to produce
154 * @param password the password to derive the key from
155 * @param password_len the length of password in bytes
156 * @param salt a randomly chosen salt
157 * @param salt_len length of salt in bytes
158 * @param ad some additional data
159 * @param ad_len length of ad in bytes
160 * @param key a secret key
161 * @param key_len length of key in bytes
162 *
163 * This function is const, but is not thread safe. Different threads should
164 * either use unique objects, or serialize all access.
165 */
166 virtual void derive_key(uint8_t out[],
167 size_t out_len,
168 const char* password,
169 size_t password_len,
170 const uint8_t salt[],
171 size_t salt_len,
172 const uint8_t ad[],
173 size_t ad_len,
174 const uint8_t key[],
175 size_t key_len) const;
176};
177
178class BOTAN_PUBLIC_API(2, 8) PasswordHashFamily /* NOLINT(*-special-member-functions) */ {
179 public:
180 /**
181 * Create an instance based on a name
182 * If provider is empty then best available is chosen.
183 * @param algo_spec algorithm name
184 * @param provider provider implementation to choose
185 * @return a null pointer if the algo/provider combination cannot be found
186 */
187 static std::unique_ptr<PasswordHashFamily> create(std::string_view algo_spec, std::string_view provider = "");
188
189 /**
190 * Create an instance based on a name, or throw if the
191 * algo/provider combination cannot be found. If provider is
192 * empty then best available is chosen.
193 */
194 static std::unique_ptr<PasswordHashFamily> create_or_throw(std::string_view algo_spec,
195 std::string_view provider = "");
196
197 /**
198 * @return list of available providers for this algorithm, empty if not available
199 */
200 static std::vector<std::string> providers(std::string_view algo_spec);
201
202 virtual ~PasswordHashFamily() = default;
203
204 /**
205 * @return name of this PasswordHash
206 */
207 virtual std::string name() const = 0;
208
209 /**
210 * Return a new parameter set tuned for this machine
211 *
212 * Return a password hash instance tuned to run for approximately @p msec
213 * milliseconds when producing an output of length @p output_length.
214 * (Accuracy may vary, use the command line utility ``botan pbkdf_tune`` to
215 * check.)
216 *
217 * The parameters will be selected to use at most @p max_memory_usage_mb
218 * megabytes of memory, or if left as zero any size is allowed.
219 *
220 * This function works by running a short tuning loop to estimate the
221 * performance of the algorithm, then scaling the parameters appropriately
222 * to hit the target size. The length of time the tuning loop runs can be
223 * controlled using the @p tuning_msec parameter.
224 *
225 * @param output_length how long the output length will be
226 * @param desired_runtime_msec the desired execution time in milliseconds
227 *
228 * @param max_memory_usage_mb some password hash functions can use a
229 * tunable amount of memory, in this case max_memory_usage limits the
230 * amount of RAM the returned parameters will require, in mebibytes (2**20
231 * bytes). It may require some small amount above the request. Set to nullopt
232 * to place no limit at all.
233 * @param tuning_msec how long to run the tuning loop
234 */
235 virtual std::unique_ptr<PasswordHash> tune_params(size_t output_length,
236 uint64_t desired_runtime_msec,
237 std::optional<size_t> max_memory_usage_mb = {},
238 uint64_t tuning_msec = 10) const = 0;
239
240#if !defined(BOTAN_IS_BEING_BUILT)
241 /**
242 * Return a new parameter set tuned for this machine
243 *
244 * Return a password hash instance tuned to run for approximately @p msec
245 * milliseconds when producing an output of length @p output_length.
246 * (Accuracy may vary, use the command line utility ``botan pbkdf_tune`` to
247 * check.)
248 *
249 * The parameters will be selected to use at most @p max_memory_usage_mb
250 * megabytes of memory, or if left as zero any size is allowed.
251 *
252 * This function works by running a short tuning loop to estimate the
253 * performance of the algorithm, then scaling the parameters appropriately
254 * to hit the target size. The length of time the tuning loop runs can be
255 * controlled using the @p tuning_msec parameter.
256 *
257 * @param output_length how long the output length will be
258 * @param msec the desired execution time in milliseconds
259 *
260 * @param max_memory_usage_mb some password hash functions can use a
261 * tunable amount of memory, in this case max_memory_usage limits the
262 * amount of RAM the returned parameters will require, in mebibytes (2**20
263 * bytes). It may require some small amount above the request. Set to zero
264 * to place no limit at all.
265 * @param tuning_msec how long to run the tuning loop
266 *
267 * TODO(Botan4) remove this
268 */
269 BOTAN_DEPRECATED("Use tune_params instead")
270 std::unique_ptr<PasswordHash> tune(size_t output_length,
271 std::chrono::milliseconds msec,
272 size_t max_memory_usage_mb = 0,
273 std::chrono::milliseconds tuning_msec = std::chrono::milliseconds(10)) const {
274 std::optional<size_t> max_memory_opt;
275 if(max_memory_usage_mb > 0) {
276 max_memory_opt = max_memory_usage_mb;
277 }
278
279 return this->tune_params(output_length,
280 static_cast<uint64_t>(msec.count()),
281 max_memory_opt,
282 static_cast<uint64_t>(tuning_msec.count()));
283 }
284#endif
285 /**
286 * Return some default parameter set for this PBKDF that should be good
287 * enough for most users. The value returned may change over time as
288 * processing power and attacks improve.
289 */
290 virtual std::unique_ptr<PasswordHash> default_params() const = 0;
291
292 /**
293 * Return a parameter chosen based on a rough approximation with the
294 * specified iteration count. The exact value this returns for a particular
295 * algorithm may change from over time. Think of it as an alternative to
296 * tune, where time is expressed in terms of PBKDF2 iterations rather than
297 * milliseconds.
298 */
299 virtual std::unique_ptr<PasswordHash> from_iterations(size_t iterations) const = 0;
300
301 /**
302 * Create a password hash using some scheme specific format. Parameters are as follows:
303 * - For PBKDF2, PGP-S2K, and Bcrypt-PBKDF, i1 is iterations
304 * - Scrypt uses N, r, p for i{1-3}
305 * - Argon2 family uses memory (in KB), iterations, and parallelism for i{1-3}
306 *
307 * All unneeded parameters should be set to 0 or left blank.
308 */
309 virtual std::unique_ptr<PasswordHash> from_params(size_t i1, size_t i2 = 0, size_t i3 = 0) const = 0;
310};
311
312} // namespace Botan
313
314#endif
#define BOTAN_PUBLIC_API(maj, min)
Definition api.h:21
#define BOTAN_DEPRECATED(msg)
Definition api.h:73
virtual std::string name() const =0
static std::unique_ptr< PasswordHashFamily > create_or_throw(std::string_view algo_spec, std::string_view provider="")
Definition pwdhash.cpp:110
virtual std::unique_ptr< PasswordHash > from_iterations(size_t iterations) const =0
static std::vector< std::string > providers(std::string_view algo_spec)
Definition pwdhash.cpp:118
virtual ~PasswordHashFamily()=default
virtual std::unique_ptr< PasswordHash > default_params() const =0
static std::unique_ptr< PasswordHashFamily > create(std::string_view algo_spec, std::string_view provider="")
Definition pwdhash.cpp:54
virtual std::unique_ptr< PasswordHash > from_params(size_t i1, size_t i2=0, size_t i3=0) const =0
std::unique_ptr< PasswordHash > tune(size_t output_length, std::chrono::milliseconds msec, size_t max_memory_usage_mb=0, std::chrono::milliseconds tuning_msec=std::chrono::milliseconds(10)) const
Definition pwdhash.h:270
virtual std::unique_ptr< PasswordHash > tune_params(size_t output_length, uint64_t desired_runtime_msec, std::optional< size_t > max_memory_usage_mb={}, uint64_t tuning_msec=10) const =0
void hash(std::span< uint8_t > out, std::string_view password, std::span< const uint8_t > salt, std::span< const uint8_t > associated_data, std::span< const uint8_t > key) const
Definition pwdhash.h:109
virtual bool supports_keyed_operation() const
Definition pwdhash.h:68
void hash(std::span< uint8_t > out, std::string_view password, std::span< const uint8_t > salt) const
Definition pwdhash.h:88
virtual size_t total_memory_usage() const
Definition pwdhash.h:63
virtual size_t parallelism() const
Definition pwdhash.h:54
virtual size_t iterations() const =0
virtual ~PasswordHash()=default
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 bool supports_associated_data() const
Definition pwdhash.h:73
virtual size_t memory_param() const
Definition pwdhash.h:44
virtual std::string to_string() const =0