1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
|
/*
* (C) 2018 Ribose Inc
*
* Botan is released under the Simplified BSD License (see license.txt)
*/
#ifndef BOTAN_PWDHASH_H_
#define BOTAN_PWDHASH_H_
#include <botan/types.h>
#include <string>
#include <memory>
#include <vector>
#include <chrono>
namespace Botan {
/**
* Base class for password based key derivation functions.
*
* Converts a password into a key using a salt and iterated hashing to
* make brute force attacks harder.
*/
class BOTAN_PUBLIC_API(2,8) PasswordHash
{
public:
virtual ~PasswordHash() = default;
virtual std::string to_string() const = 0;
/**
* Most password hashes have some notion of iterations.
*/
virtual size_t iterations() const = 0;
/**
* Some password hashing algorithms have a parameter which controls how
* much memory is used. If not supported by some algorithm, returns 0.
*/
virtual size_t memory_param() const { return 0; }
/**
* Some password hashing algorithms have a parallelism parameter.
* If not supported by some algorithm, just returns 1
*/
virtual size_t parallelism() const { return 1; }
/**
* Returns an estimate of the total memory usage required to perform this
* key derivation.
*
* If this algorithm uses a small and constant amount of memory, with no
* effort made towards being memory hard, this function returns 0.
*/
virtual size_t total_memory_usage() const { return 0; }
/**
* Derive a key from a password
*
* @param out buffer to store the derived key, must be of out_len bytes
* @param out_len the desired length of the key to produce
* @param password the password to derive the key from
* @param password_len the length of password in bytes
* @param salt a randomly chosen salt
* @param salt_len length of salt in bytes
*
* This function is const, but is not thread safe. Different threads should
* either use unique objects, or serialize all access.
*/
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;
};
class BOTAN_PUBLIC_API(2,8) PasswordHashFamily
{
public:
/**
* Create an instance based on a name
* If provider is empty then best available is chosen.
* @param algo_spec algorithm name
* @param provider provider implementation to choose
* @return a null pointer if the algo/provider combination cannot be found
*/
static std::unique_ptr<PasswordHashFamily> create(const std::string& algo_spec,
const std::string& provider = "");
/**
* Create an instance based on a name, or throw if the
* algo/provider combination cannot be found. If provider is
* empty then best available is chosen.
*/
static std::unique_ptr<PasswordHashFamily>
create_or_throw(const std::string& algo_spec,
const std::string& provider = "");
/**
* @return list of available providers for this algorithm, empty if not available
*/
static std::vector<std::string> providers(const std::string& algo_spec);
virtual ~PasswordHashFamily() = default;
/**
* @return name of this PasswordHash
*/
virtual std::string name() const = 0;
/**
* Return a new parameter set tuned for this machine
* @param output_length how long the output length will be
* @param msec the desired execution time in milliseconds
*
* @param max_memory_usage some password hash functions can use a tunable
* amount of memory, in this case max_memory_usage limits the amount of RAM
* the returned parameters will require, in mebibytes (2**20 bytes). It may
* require some small amount above the request. Set to zero to place no
* limit at all.
*/
virtual std::unique_ptr<PasswordHash> tune(size_t output_len,
std::chrono::milliseconds msec,
size_t max_memory_usage_mb = 128) const = 0;
/**
* Return some default parameter set for this PBKDF that should be good
* enough for most users. The value returned may change over time as
* processing power and attacks improve.
*/
virtual std::unique_ptr<PasswordHash> default_params() const = 0;
/**
* Create a password hash using some scheme specific format.
* Eg PBKDF2 and PGP-S2K set iterations in i1
* Scrypt uses N,r,p in i{1-3}
* Bcrypt-PBKDF just has iterations
* Argon2{i,d,id} would use iterations, memory, parallelism for i{1-3},
* and Argon2 type is part of the family.
*
* Values not needed should be set to 0
*/
virtual std::unique_ptr<PasswordHash> from_params(
size_t i1,
size_t i2 = 0,
size_t i3 = 0) const = 0;
};
}
#endif
|