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