8 #include <botan/passhash9.h>
9 #include <botan/loadstor.h>
10 #include <botan/libstate.h>
11 #include <botan/pbkdf2.h>
12 #include <botan/b64_filt.h>
13 #include <botan/pipe.h>
19 const std::string MAGIC_PREFIX =
"$9$";
21 const size_t WORKFACTOR_BYTES = 2;
22 const size_t ALGID_BYTES = 1;
23 const size_t SALT_BYTES = 12;
24 const size_t PASSHASH9_PBKDF_OUTPUT_LEN = 24;
26 const size_t WORK_FACTOR_SCALE = 10000;
28 MessageAuthenticationCode* get_pbkdf_prf(
byte alg_id)
37 return af.make_mac(
"HMAC(SHA-256)");
39 return af.make_mac(
"CMAC(Blowfish)");
41 catch(Algorithm_Not_Found) {}
64 const size_t kdf_iterations = WORK_FACTOR_SCALE * work_factor;
69 &salt[0], salt.
size(),
70 kdf_iterations).bits_of();
78 pipe.
write(pbkdf2_output);
86 const size_t BINARY_LENGTH =
89 PASSHASH9_PBKDF_OUTPUT_LEN +
92 const size_t BASE64_LENGTH =
93 MAGIC_PREFIX.size() + (BINARY_LENGTH * 8) / 6;
95 if(hash.size() != BASE64_LENGTH)
98 for(
size_t i = 0; i != MAGIC_PREFIX.size(); ++i)
99 if(hash[i] != MAGIC_PREFIX[i])
104 pipe.
write(hash.c_str() + MAGIC_PREFIX.size());
109 if(bin.
size() != BINARY_LENGTH)
112 byte alg_id = bin[0];
114 const size_t kdf_iterations =
117 if(kdf_iterations == 0)
128 PASSHASH9_PBKDF_OUTPUT_LEN,
130 &bin[ALGID_BYTES + WORKFACTOR_BYTES], SALT_BYTES,
134 &bin[ALGID_BYTES + WORKFACTOR_BYTES + SALT_BYTES],
135 PASSHASH9_PBKDF_OUTPUT_LEN);
virtual void randomize(byte output[], size_t length)=0
bool same_mem(const T *p1, const T *p2, size_t n)
std::string read_all_as_string(message_id=DEFAULT_MESSAGE)
void write(const byte in[], size_t length)
bool check_passhash9(const std::string &pass, const std::string &hash)
OctetString derive_key(size_t output_len, const std::string &passphrase, const byte salt[], size_t salt_len, size_t iterations) const
std::invalid_argument Invalid_Argument
byte get_byte(size_t byte_num, T input)
MessageAuthenticationCode * make_mac(const std::string &algo_spec, const std::string &provider="")
Algorithm_Factory & algorithm_factory() const
SecureVector< byte > bits_of() const
SecureVector< byte > read_all(message_id msg=DEFAULT_MESSAGE)
RandomNumberGenerator * rng
u16bit load_be< u16bit >(const byte in[], size_t off)
Library_State & global_state()
std::string generate_passhash9(const std::string &pass, RandomNumberGenerator &rng, u16bit work_factor, byte alg_id)
std::string to_string(u64bit n, size_t min_len)