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