7#include <botan/argon2.h>
8#include <botan/exceptn.h>
9#include <botan/internal/timer.h>
10#include <botan/internal/fmt.h>
21 BOTAN_ARG_CHECK(m_p >= 1 && m_p <= 128,
"Invalid Argon2 threads parameter");
22 BOTAN_ARG_CHECK(m_M >= 8*m_p && m_M <= 8192*1024,
"Invalid Argon2 M parameter");
27 const char* password,
size_t password_len,
28 const uint8_t salt[],
size_t salt_len)
const
30 argon2(output, output_len,
31 password, password_len,
38 const char* password,
size_t password_len,
39 const uint8_t salt[],
size_t salt_len,
40 const uint8_t ad[],
size_t ad_len,
41 const uint8_t key[],
size_t key_len)
const
43 argon2(output, output_len,
44 password, password_len,
52std::string argon2_family_name(uint8_t f)
71 return fmt(
"{}({},{},{})",
72 argon2_family_name(m_family),
78 if(m_family != 0 && m_family != 1 && m_family != 2)
84 return argon2_family_name(m_family);
88 std::chrono::milliseconds msec,
90 std::chrono::milliseconds tune_time)
const
92 const size_t max_kib = (max_memory == 0) ? 256*1024 : max_memory*1024;
96 const size_t tune_M = (msec >= std::chrono::milliseconds(200) ? 128 : 36) * 1024;
100 Timer timer(
"Argon2");
105 uint8_t output[64] = { 0 };
106 pwhash->derive_key(output,
sizeof(output),
116 const uint64_t measured_time = timer.
value() / (timer.
events() * (tune_M / M));
118 const uint64_t target_nsec = msec.count() *
static_cast<uint64_t
>(1000000);
130 uint64_t est_nsec = measured_time;
132 if(est_nsec < target_nsec && M < max_kib)
134 const uint64_t desired_cost_increase = (target_nsec + est_nsec - 1) / est_nsec;
135 const uint64_t mem_headroom = max_kib / M;
137 const uint64_t M_mult = std::min(desired_cost_increase, mem_headroom);
138 M *=
static_cast<size_t>(M_mult);
142 if(est_nsec < target_nsec / 2)
144 const uint64_t desired_cost_increase = (target_nsec + est_nsec - 1) / est_nsec;
145 t *=
static_cast<size_t>(desired_cost_increase);
163 const size_t M = iter;
171 return std::make_unique<Argon2>(m_family, M, t, p);
#define BOTAN_ARG_CHECK(expr, msg)
std::unique_ptr< PasswordHash > from_params(size_t M, size_t t, size_t p) const override
std::string name() const override
Argon2_Family(uint8_t family)
std::unique_ptr< PasswordHash > tune(size_t output_length, std::chrono::milliseconds msec, size_t max_memory, std::chrono::milliseconds tune_msec) const override
std::unique_ptr< PasswordHash > default_params() const override
std::unique_ptr< PasswordHash > from_iterations(size_t iter) const override
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
std::string to_string() const override
Argon2(uint8_t family, size_t M, size_t t, size_t p)
void run_until_elapsed(std::chrono::milliseconds msec, F f)
std::string fmt(std::string_view format, const T &... args)