Botan 2.19.1
Crypto and TLS for C&
argon2fmt.cpp
Go to the documentation of this file.
1/**
2* (C) 2019 Jack Lloyd
3*
4* Botan is released under the Simplified BSD License (see license.txt)
5*/
6
7#include <botan/argon2.h>
8#include <botan/rng.h>
9#include <botan/base64.h>
10#include <botan/parsing.h>
11#include <sstream>
12
13namespace Botan {
14
15namespace {
16
17std::string strip_padding(std::string s)
18 {
19 while(s.size() > 0 && s[s.size()-1] == '=')
20 s.resize(s.size() - 1);
21 return s;
22 }
23
24}
25
26std::string argon2_generate_pwhash(const char* password, size_t password_len,
28 size_t p, size_t M, size_t t,
29 uint8_t y, size_t salt_len, size_t output_len)
30 {
31 std::vector<uint8_t> salt(salt_len);
32 rng.randomize(salt.data(), salt.size());
33
34 std::vector<uint8_t> output(output_len);
35 argon2(output.data(), output.size(),
36 password, password_len,
37 salt.data(), salt.size(),
38 nullptr, 0,
39 nullptr, 0,
40 y, p, M, t);
41
42 std::ostringstream oss;
43
44 if(y == 0)
45 oss << "$argon2d$";
46 else if(y == 1)
47 oss << "$argon2i$";
48 else
49 oss << "$argon2id$";
50
51 oss << "v=19$m=" << M << ",t=" << t << ",p=" << p << "$";
52 oss << strip_padding(base64_encode(salt)) << "$" << strip_padding(base64_encode(output));
53
54 return oss.str();
55 }
56
57bool argon2_check_pwhash(const char* password, size_t password_len,
58 const std::string& input_hash)
59 {
60 const std::vector<std::string> parts = split_on(input_hash, '$');
61
62 if(parts.size() != 5)
63 return false;
64
65 uint8_t family = 0;
66
67 if(parts[0] == "argon2d")
68 family = 0;
69 else if(parts[0] == "argon2i")
70 family = 1;
71 else if(parts[0] == "argon2id")
72 family = 2;
73 else
74 return false;
75
76 if(parts[1] != "v=19")
77 return false;
78
79 const std::vector<std::string> params = split_on(parts[2], ',');
80
81 if(params.size() != 3)
82 return false;
83
84 size_t M = 0, t = 0, p = 0;
85
86 for(auto param_str : params)
87 {
88 const std::vector<std::string> param = split_on(param_str, '=');
89
90 if(param.size() != 2)
91 return false;
92
93 const std::string key = param[0];
94 const size_t val = to_u32bit(param[1]);
95 if(key == "m")
96 M = val;
97 else if(key == "t")
98 t = val;
99 else if(key == "p")
100 p = val;
101 else
102 return false;
103 }
104
105 std::vector<uint8_t> salt(base64_decode_max_output(parts[3].size()));
106 salt.resize(base64_decode(salt.data(), parts[3], false));
107
108 std::vector<uint8_t> hash(base64_decode_max_output(parts[4].size()));
109 hash.resize(base64_decode(hash.data(), parts[4], false));
110
111 if(hash.size() < 4)
112 return false;
113
114 std::vector<uint8_t> generated(hash.size());
115 argon2(generated.data(), generated.size(),
116 password, password_len,
117 salt.data(), salt.size(),
118 nullptr, 0,
119 nullptr, 0,
120 family, p, M, t);
121
122 return constant_time_compare(generated.data(), hash.data(), generated.size());
123 }
124
125}
virtual void randomize(uint8_t output[], size_t length)=0
Definition: alg_id.cpp:13
std::vector< std::string > split_on(const std::string &str, char delim)
Definition: parsing.cpp:148
void argon2(uint8_t output[], size_t output_len, const char *password, size_t password_len, const uint8_t salt[], size_t salt_len, const uint8_t key[], size_t key_len, const uint8_t ad[], size_t ad_len, uint8_t mode, size_t threads, size_t M, size_t t)
Definition: argon2.cpp:410
size_t base64_encode(char out[], const uint8_t in[], size_t input_length, size_t &input_consumed, bool final_inputs)
Definition: base64.cpp:185
size_t base64_decode(uint8_t out[], const char in[], size_t input_length, size_t &input_consumed, bool final_inputs, bool ignore_ws)
Definition: base64.cpp:200
bool constant_time_compare(const uint8_t x[], const uint8_t y[], size_t len)
Definition: mem_ops.h:82
bool argon2_check_pwhash(const char *password, size_t password_len, const std::string &hash)
Definition: argon2fmt.cpp:57
size_t base64_decode_max_output(size_t input_length)
Definition: base64.cpp:243
uint32_t to_u32bit(const std::string &str)
Definition: parsing.cpp:35
std::string argon2_generate_pwhash(const char *password, size_t password_len, RandomNumberGenerator &rng, size_t p, size_t M, size_t t, uint8_t y=2, size_t salt_len=16, size_t output_len=32)
Definition: argon2fmt.cpp:26
MechanismType hash
size_t salt_len
Definition: x509_obj.cpp:25