Botan 3.13.0
Crypto and TLS for C&
Botan::Scrypt Class Referencefinal

#include <scrypt.h>

Inheritance diagram for Botan::Scrypt:
Botan::PasswordHash

Public Member Functions

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 uint8_t ad[], size_t ad_len, const uint8_t key[], size_t key_len) const
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 override
void hash (std::span< uint8_t > out, std::string_view password, std::span< const uint8_t > salt) const
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
size_t iterations () const override
size_t memory_param () const override
size_t parallelism () const override
 Scrypt (size_t N, size_t r, size_t p)
virtual bool supports_associated_data () const
virtual bool supports_keyed_operation () const
std::string to_string () const override
size_t total_memory_usage () const override

Detailed Description

Scrypt key derivation function (RFC 7914)

Definition at line 21 of file scrypt.h.

Constructor & Destructor Documentation

◆ Scrypt()

Botan::Scrypt::Scrypt ( size_t N,
size_t r,
size_t p )

Definition at line 153 of file scrypt.cpp.

153 : m_N(N), m_r(r), m_p(p) {
154 if(!is_power_of_2(N)) {
155 throw Invalid_Argument("Scrypt N parameter must be a power of 2");
156 }
157
158 if(p == 0 || p > 1024) {
159 throw Invalid_Argument("Invalid or unsupported scrypt p");
160 }
161 if(r == 0 || r > 256) {
162 throw Invalid_Argument("Invalid or unsupported scrypt r");
163 }
164 if(N < 1 || N > MAX_SCRYPT_N) {
165 throw Invalid_Argument("Invalid or unsupported scrypt N");
166 }
167
168 if(const auto memory_usage = scrypt_memory_usage(N, r, p)) {
169 if(memory_usage > MAX_SCRYPT_MEMORY_BYTES) {
170 throw Invalid_Argument("Scrypt parameters exceed maximum allowed memory limit");
171 }
172 } else {
173 throw Invalid_Argument("Scrypt parameters are too large for this platform");
174 }
175}
BOTAN_FORCE_INLINE constexpr bool is_power_of_2(T arg)
Definition bit_ops.h:62

References Botan::is_power_of_2().

Member Function Documentation

◆ derive_key() [1/2]

void Botan::PasswordHash::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 uint8_t ad[],
size_t ad_len,
const uint8_t key[],
size_t key_len ) const
virtualinherited

Derive a key from a password plus additional data and/or a secret key

Currently this is only supported for Argon2. Using a non-empty AD or key with other algorithms will cause a Not_Implemented exception.

Parameters
outbuffer to store the derived key, must be of out_len bytes
out_lenthe desired length of the key to produce
passwordthe password to derive the key from
password_lenthe length of password in bytes
salta randomly chosen salt
salt_lenlength of salt in bytes
adsome additional data
ad_lenlength of ad in bytes
keya secret key
key_lenlength of key in bytes

This function is const, but is not thread safe. Different threads should either use unique objects, or serialize all access.

Reimplemented in Botan::Argon2.

Definition at line 39 of file pwdhash.cpp.

48 {
49 BOTAN_UNUSED(ad, key);
50
51 if(ad_len == 0 && key_len == 0) {
52 return this->derive_key(out, out_len, password, password_len, salt, salt_len);
53 } else {
54 throw Not_Implemented("PasswordHash " + this->to_string() + " does not support AD or key");
55 }
56}
#define BOTAN_UNUSED
Definition assert.h:144
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 std::string to_string() const =0

References BOTAN_UNUSED, derive_key(), and to_string().

◆ derive_key() [2/2]

void Botan::Scrypt::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
overridevirtual

Derive a new key under the current Scrypt parameter set

Implements Botan::PasswordHash.

Definition at line 232 of file scrypt.cpp.

237 {
238 if(output_len == 0) {
239 return;
240 }
241
242 const size_t N = memory_param();
243 const size_t p = parallelism();
244 const size_t r = iterations();
245
246 const size_t S = mul_or_throw(size_t(128), r, "Scrypt S size overflow");
247 secure_vector<uint8_t> B(mul_or_throw(p, S, "Scrypt B size overflow"));
248 // temp space
249 secure_vector<uint8_t> V(mul_or_throw(N + 1, S, "Scrypt V size overflow"));
250
251 auto hmac_sha256 = MessageAuthenticationCode::create_or_throw("HMAC(SHA-256)");
252
253 try {
254 hmac_sha256->set_key(as_span_of_bytes(password, password_len));
255 } catch(Invalid_Key_Length&) {
256 throw Invalid_Argument("Scrypt cannot accept passphrases of the provided length");
257 }
258
259 pbkdf2(*hmac_sha256, B.data(), B.size(), salt, salt_len, 1);
260
261 // these can be parallel
262 for(size_t i = 0; i != p; ++i) {
263 scryptROMmix(r, N, &B[128 * r * i], V);
264 }
265
266 pbkdf2(*hmac_sha256, output, output_len, B.data(), B.size(), 1);
267}
static std::unique_ptr< MessageAuthenticationCode > create_or_throw(std::string_view algo_spec, std::string_view provider="")
Definition mac.cpp:149
size_t memory_param() const override
Definition scrypt.h:41
size_t iterations() const override
Definition scrypt.h:37
size_t parallelism() const override
Definition scrypt.h:39
constexpr T mul_or_throw(T a, T b, std::string_view msg)
Definition int_utils.h:81
std::span< const uint8_t > as_span_of_bytes(const char *s, size_t len)
Definition mem_utils.h:59
std::vector< T, secure_allocator< T > > secure_vector
Definition secmem.h:128
size_t pbkdf2(MessageAuthenticationCode &prf, uint8_t out[], size_t out_len, std::string_view password, const uint8_t salt[], size_t salt_len, size_t iterations, std::chrono::milliseconds msec)
Definition pbkdf2.cpp:73

References Botan::as_span_of_bytes(), Botan::MessageAuthenticationCode::create_or_throw(), iterations(), memory_param(), Botan::mul_or_throw(), parallelism(), and Botan::pbkdf2().

◆ hash() [1/2]

void Botan::PasswordHash::hash ( std::span< uint8_t > out,
std::string_view password,
std::span< const uint8_t > salt ) const
inlineinherited

Hash a password into a bitstring

Derive a key from the specified password and salt, placing it into out.

Parameters
outa span where the derived key will be placed
passwordthe password to derive the key from
salta randomly chosen salt

This function is const, but is not thread safe. Different threads should either use unique objects, or serialize all access.

Definition at line 95 of file pwdhash.h.

95 {
96 this->derive_key(out.data(), out.size(), password.data(), password.size(), salt.data(), salt.size());
97 }

References derive_key().

Referenced by Botan::PKCS12_KDF::PKCS12_KDF(), and Botan::RFC4880_S2K::RFC4880_S2K().

◆ hash() [2/2]

void Botan::PasswordHash::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
inlineinherited

Hash a password into a bitstring

Derive a key from the specified password, salt, associated_data, and secret key, placing it into out. The associated_data and key are both allowed to be empty. Currently non-empty AD/key is only supported with Argon2.

Parameters
outa span where the derived key will be placed
passwordthe password to derive the key from
salta randomly chosen salt
associated_datasome additional data
keya secret key

This function is const, but is not thread safe. Different threads should either use unique objects, or serialize all access.

Definition at line 116 of file pwdhash.h.

120 {
121 this->derive_key(out.data(),
122 out.size(),
123 password.data(),
124 password.size(),
125 salt.data(),
126 salt.size(),
127 associated_data.data(),
128 associated_data.size(),
129 key.data(),
130 key.size());
131 }

References derive_key().

◆ iterations()

size_t Botan::Scrypt::iterations ( ) const
inlineoverridevirtual

Most password hashes have some notion of iterations.

Implements Botan::PasswordHash.

Definition at line 37 of file scrypt.h.

37{ return m_r; }

Referenced by derive_key(), and total_memory_usage().

◆ memory_param()

size_t Botan::Scrypt::memory_param ( ) const
inlineoverridevirtual

Some password hashing algorithms have a parameter which controls how much memory is used. If not supported by some algorithm, returns 0.

Reimplemented from Botan::PasswordHash.

Definition at line 41 of file scrypt.h.

41{ return m_N; }

Referenced by derive_key(), and total_memory_usage().

◆ parallelism()

size_t Botan::Scrypt::parallelism ( ) const
inlineoverridevirtual

Some password hashing algorithms have a parallelism parameter. If the algorithm does not support this notion, then the function returns zero. This allows distinguishing between a password hash which just does not support parallel operation, vs one that does support parallel operation but which has been configured to use a single lane.

Reimplemented from Botan::PasswordHash.

Definition at line 39 of file scrypt.h.

39{ return m_p; }

Referenced by derive_key(), and total_memory_usage().

◆ supports_associated_data()

virtual bool Botan::PasswordHash::supports_associated_data ( ) const
inlinevirtualinherited

Query if this password hash supports associated data

Returns
true if this password hash supports supplying associated data

Reimplemented in Botan::Argon2.

Definition at line 80 of file pwdhash.h.

80{ return false; }

◆ supports_keyed_operation()

virtual bool Botan::PasswordHash::supports_keyed_operation ( ) const
inlinevirtualinherited

Query if this password hash supports a symmetric key

Returns
true if this password hash supports supplying a key

Reimplemented in Botan::Argon2.

Definition at line 73 of file pwdhash.h.

73{ return false; }

◆ to_string()

std::string Botan::Scrypt::to_string ( ) const
overridevirtual

Return a free-form string identifying the algorithm and parameters

Implements Botan::PasswordHash.

Definition at line 177 of file scrypt.cpp.

177 {
178 return fmt("Scrypt({},{},{})", m_N, m_r, m_p);
179}
std::string fmt(std::string_view format, const T &... args)
Definition fmt.h:53

References Botan::fmt().

◆ total_memory_usage()

size_t Botan::Scrypt::total_memory_usage ( ) const
overridevirtual

Returns an estimate of the total number of bytes 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.

Reimplemented from Botan::PasswordHash.

Definition at line 181 of file scrypt.cpp.

181 {
182 const size_t N = memory_param();
183 const size_t p = parallelism();
184 const size_t r = iterations();
185
186 const auto consumption = scrypt_memory_usage(N, r, p);
187 BOTAN_ASSERT_NOMSG(consumption.has_value());
188 return consumption.value();
189}
#define BOTAN_ASSERT_NOMSG(expr)
Definition assert.h:75

References BOTAN_ASSERT_NOMSG, iterations(), memory_param(), and parallelism().


The documentation for this class was generated from the following files: