Coverage Report

Created: 2022-01-14 08:07

/src/botan/build/include/botan/pwdhash.h
Line
Count
Source (jump to first uncovered line)
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
16
namespace Botan {
17
18
/**
19
* Base class for password based key derivation functions.
20
*
21
* Converts a password into a key using a salt and iterated hashing to
22
* make brute force attacks harder.
23
*/
24
class BOTAN_PUBLIC_API(2,8) PasswordHash
25
   {
26
   public:
27
0
      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
0
      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
0
      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
0
      virtual size_t total_memory_usage() const { return 0; }
60
61
      /**
62
      * Derive a key from a password
63
      *
64
      * @param out buffer to store the derived key, must be of out_len bytes
65
      * @param out_len the desired length of the key to produce
66
      * @param password the password to derive the key from
67
      * @param password_len the length of password in bytes
68
      * @param salt a randomly chosen salt
69
      * @param salt_len length of salt in bytes
70
      *
71
      * This function is const, but is not thread safe. Different threads should
72
      * either use unique objects, or serialize all access.
73
      */
74
      virtual void derive_key(uint8_t out[], size_t out_len,
75
                              const char* password, size_t password_len,
76
                              const uint8_t salt[], size_t salt_len) const = 0;
77
78
      /**
79
      * Derive a key from a password plus additional data and/or a secret key
80
      *
81
      * Currently this is only supported for Argon2. Using a non-empty AD or key
82
      * with other algorithms will cause a Not_Implemented exception.
83
      *
84
      * @param out buffer to store the derived key, must be of out_len bytes
85
      * @param out_len the desired length of the key to produce
86
      * @param password the password to derive the key from
87
      * @param password_len the length of password in bytes
88
      * @param salt a randomly chosen salt
89
      * @param salt_len length of salt in bytes
90
      * @param ad some additional data
91
      * @param ad_len length of ad in bytes
92
      * @param key a secret key
93
      * @param key_len length of key in bytes
94
      *
95
      * This function is const, but is not thread safe. Different threads should
96
      * either use unique objects, or serialize all access.
97
      */
98
      virtual void derive_key(uint8_t out[], size_t out_len,
99
                              const char* password, size_t password_len,
100
                              const uint8_t salt[], size_t salt_len,
101
                              const uint8_t ad[], size_t ad_len,
102
                              const uint8_t key[], size_t key_len) const;
103
   };
104
105
class BOTAN_PUBLIC_API(2,8) PasswordHashFamily
106
   {
107
   public:
108
      /**
109
      * Create an instance based on a name
110
      * If provider is empty then best available is chosen.
111
      * @param algo_spec algorithm name
112
      * @param provider provider implementation to choose
113
      * @return a null pointer if the algo/provider combination cannot be found
114
      */
115
      static std::unique_ptr<PasswordHashFamily> create(const std::string& algo_spec,
116
                                                        const std::string& provider = "");
117
118
      /**
119
      * Create an instance based on a name, or throw if the
120
      * algo/provider combination cannot be found. If provider is
121
      * empty then best available is chosen.
122
      */
123
      static std::unique_ptr<PasswordHashFamily>
124
         create_or_throw(const std::string& algo_spec,
125
                         const std::string& provider = "");
126
127
      /**
128
      * @return list of available providers for this algorithm, empty if not available
129
      */
130
      static std::vector<std::string> providers(const std::string& algo_spec);
131
132
0
      virtual ~PasswordHashFamily() = default;
133
134
      /**
135
      * @return name of this PasswordHash
136
      */
137
      virtual std::string name() const = 0;
138
139
      /**
140
      * Return a new parameter set tuned for this machine
141
      * @param output_length how long the output length will be
142
      * @param msec the desired execution time in milliseconds
143
      *
144
      * @param max_memory_usage_mb some password hash functions can use a tunable
145
      * amount of memory, in this case max_memory_usage limits the amount of RAM
146
      * the returned parameters will require, in mebibytes (2**20 bytes). It may
147
      * require some small amount above the request. Set to zero to place no
148
      * limit at all.
149
      */
150
      virtual std::unique_ptr<PasswordHash> tune(size_t output_length,
151
                                                 std::chrono::milliseconds msec,
152
                                                 size_t max_memory_usage_mb = 0) const = 0;
153
154
      /**
155
      * Return some default parameter set for this PBKDF that should be good
156
      * enough for most users. The value returned may change over time as
157
      * processing power and attacks improve.
158
      */
159
      virtual std::unique_ptr<PasswordHash> default_params() const = 0;
160
161
      /**
162
      * Return a parameter chosen based on a rough approximation with the
163
      * specified iteration count. The exact value this returns for a particular
164
      * algorithm may change from over time. Think of it as an alternative to
165
      * tune, where time is expressed in terms of PBKDF2 iterations rather than
166
      * milliseconds.
167
      */
168
      virtual std::unique_ptr<PasswordHash> from_iterations(size_t iterations) const = 0;
169
170
      /**
171
      * Create a password hash using some scheme specific format. Parameters are as follows:
172
      * - For PBKDF2, PGP-S2K, and Bcrypt-PBKDF, i1 is iterations
173
      * - Scrypt uses N, r, p for i{1-3}
174
      * - Argon2 family uses memory (in KB), iterations, and parallelism for i{1-3}
175
      *
176
      * All unneeded parameters should be set to 0 or left blank.
177
      */
178
      virtual std::unique_ptr<PasswordHash> from_params(
179
         size_t i1,
180
         size_t i2 = 0,
181
         size_t i3 = 0) const = 0;
182
   };
183
184
}
185
186
#endif