Botan 3.4.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 <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 * @param out a span where the derived key will be placed
75 * @param password the password to derive the key from
76 * @param salt a randomly chosen salt
77 *
78 * This function is const, but is not thread safe. Different threads should
79 * either use unique objects, or serialize all access.
80 */
81 void hash(std::span<uint8_t> out, std::string_view password, std::span<const uint8_t> salt) const {
82 this->derive_key(out.data(), out.size(), password.data(), password.size(), salt.data(), salt.size());
83 }
84
85 /**
86 * Hash a password into a bitstring
87 *
88 * @param out a span where the derived key will be placed
89 * @param password the password to derive the key from
90 * @param salt a randomly chosen salt
91 * @param associated_data some additional data
92 * @param key a secret key
93 *
94 * This function is const, but is not thread safe. Different threads should
95 * either use unique objects, or serialize all access.
96 */
97 void hash(std::span<uint8_t> out,
98 std::string_view password,
99 std::span<const uint8_t> salt,
100 std::span<const uint8_t> associated_data,
101 std::span<const uint8_t> key) const {
102 this->derive_key(out.data(),
103 out.size(),
104 password.data(),
105 password.size(),
106 salt.data(),
107 salt.size(),
108 associated_data.data(),
109 associated_data.size(),
110 key.data(),
111 key.size());
112 }
113
114 /**
115 * Derive a key from a password
116 *
117 * @param out buffer to store the derived key, must be of out_len bytes
118 * @param out_len the desired length of the key to produce
119 * @param password the password to derive the key from
120 * @param password_len the length of password in bytes
121 * @param salt a randomly chosen salt
122 * @param salt_len length of salt in bytes
123 *
124 * This function is const, but is not thread safe. Different threads should
125 * either use unique objects, or serialize all access.
126 */
127 virtual void derive_key(uint8_t out[],
128 size_t out_len,
129 const char* password,
130 size_t password_len,
131 const uint8_t salt[],
132 size_t salt_len) const = 0;
133
134 /**
135 * Derive a key from a password plus additional data and/or a secret key
136 *
137 * Currently this is only supported for Argon2. Using a non-empty AD or key
138 * with other algorithms will cause a Not_Implemented exception.
139 *
140 * @param out buffer to store the derived key, must be of out_len bytes
141 * @param out_len the desired length of the key to produce
142 * @param password the password to derive the key from
143 * @param password_len the length of password in bytes
144 * @param salt a randomly chosen salt
145 * @param salt_len length of salt in bytes
146 * @param ad some additional data
147 * @param ad_len length of ad in bytes
148 * @param key a secret key
149 * @param key_len length of key in bytes
150 *
151 * This function is const, but is not thread safe. Different threads should
152 * either use unique objects, or serialize all access.
153 */
154 virtual void derive_key(uint8_t out[],
155 size_t out_len,
156 const char* password,
157 size_t password_len,
158 const uint8_t salt[],
159 size_t salt_len,
160 const uint8_t ad[],
161 size_t ad_len,
162 const uint8_t key[],
163 size_t key_len) const;
164};
165
167 public:
168 /**
169 * Create an instance based on a name
170 * If provider is empty then best available is chosen.
171 * @param algo_spec algorithm name
172 * @param provider provider implementation to choose
173 * @return a null pointer if the algo/provider combination cannot be found
174 */
175 static std::unique_ptr<PasswordHashFamily> create(std::string_view algo_spec, std::string_view provider = "");
176
177 /**
178 * Create an instance based on a name, or throw if the
179 * algo/provider combination cannot be found. If provider is
180 * empty then best available is chosen.
181 */
182 static std::unique_ptr<PasswordHashFamily> create_or_throw(std::string_view algo_spec,
183 std::string_view provider = "");
184
185 /**
186 * @return list of available providers for this algorithm, empty if not available
187 */
188 static std::vector<std::string> providers(std::string_view algo_spec);
189
190 virtual ~PasswordHashFamily() = default;
191
192 /**
193 * @return name of this PasswordHash
194 */
195 virtual std::string name() const = 0;
196
197 /**
198 * Return a new parameter set tuned for this machine
199 * @param output_length how long the output length will be
200 * @param msec the desired execution time in milliseconds
201 *
202 * @param max_memory_usage_mb some password hash functions can use a tunable
203 * amount of memory, in this case max_memory_usage limits the amount of RAM
204 * the returned parameters will require, in mebibytes (2**20 bytes). It may
205 * require some small amount above the request. Set to zero to place no
206 * limit at all.
207 * @param tuning_msec how long to run the tuning loop
208 */
209 virtual std::unique_ptr<PasswordHash> tune(
210 size_t output_length,
211 std::chrono::milliseconds msec,
212 size_t max_memory_usage_mb = 0,
213 std::chrono::milliseconds tuning_msec = std::chrono::milliseconds(10)) const = 0;
214
215 /**
216 * Return some default parameter set for this PBKDF that should be good
217 * enough for most users. The value returned may change over time as
218 * processing power and attacks improve.
219 */
220 virtual std::unique_ptr<PasswordHash> default_params() const = 0;
221
222 /**
223 * Return a parameter chosen based on a rough approximation with the
224 * specified iteration count. The exact value this returns for a particular
225 * algorithm may change from over time. Think of it as an alternative to
226 * tune, where time is expressed in terms of PBKDF2 iterations rather than
227 * milliseconds.
228 */
229 virtual std::unique_ptr<PasswordHash> from_iterations(size_t iterations) const = 0;
230
231 /**
232 * Create a password hash using some scheme specific format. Parameters are as follows:
233 * - For PBKDF2, PGP-S2K, and Bcrypt-PBKDF, i1 is iterations
234 * - Scrypt uses N, r, p for i{1-3}
235 * - Argon2 family uses memory (in KB), iterations, and parallelism for i{1-3}
236 *
237 * All unneeded parameters should be set to 0 or left blank.
238 */
239 virtual std::unique_ptr<PasswordHash> from_params(size_t i1, size_t i2 = 0, size_t i3 = 0) const = 0;
240};
241
242} // namespace Botan
243
244#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:97
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:81
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