Botan 2.13.0 Crypto and TLS for C++11

- Main Page
- Namespaces
- Classes
- Files

- File List
- File Members

srp6.cpp
Go to the documentation of this file.
1 /*
2 * SRP-6a (RFC 5054 compatatible)
3 * (C) 2011,2012,2019 Jack Lloyd
4 *
5 * Botan is released under the Simplified BSD License (see license.txt)
6 */
7
8 #include <botan/srp6.h>
9 #include <botan/hash.h>
10 #include <botan/dl_group.h>
11 #include <botan/numthry.h>
12
13 namespace Botan {
14
15 namespace {
16
17 BigInt hash_seq(const std::string& hash_id,
18 size_t pad_to,
19 const BigInt& in1,
20 const BigInt& in2)
21 {
22 std::unique_ptr<HashFunction> hash_fn(HashFunction::create_or_throw(hash_id));
23
24 hash_fn->update(BigInt::encode_1363(in1, pad_to));
25 hash_fn->update(BigInt::encode_1363(in2, pad_to));
26
27 return BigInt::decode(hash_fn->final());
28 }
29
30 BigInt compute_x(const std::string& hash_id,
31 const std::string& identifier,
32 const std::string& password,
33 const std::vector<uint8_t>& salt)
34 {
35 std::unique_ptr<HashFunction> hash_fn(HashFunction::create_or_throw(hash_id));
36
37 hash_fn->update(identifier);
38 hash_fn->update(":");
39 hash_fn->update(password);
40
41 secure_vector<uint8_t> inner_h = hash_fn->final();
42
43 hash_fn->update(salt);
44 hash_fn->update(inner_h);
45
46 secure_vector<uint8_t> outer_h = hash_fn->final();
47
48 return BigInt::decode(outer_h);
49 }
50
51 }
52
53 std::string srp6_group_identifier(const BigInt& N, const BigInt& g)
54 {
55 /*
56 This function assumes that only one 'standard' SRP parameter set has
57 been defined for a particular bitsize. As of this writing that is the case.
58 */
59 try
60 {
61 const std::string group_name = "modp/srp/" + std::to_string(N.bits());
62
63 DL_Group group(group_name);
64
65 if(group.get_p() == N && group.get_g() == g)
66 return group_name;
67 }
68 catch(...)
69 {
70 }
71
72 // If we didn't return, the group was unknown or did not match
73 throw Invalid_Argument("Invalid or unknown SRP group parameters");
74 }
75
76 std::pair<BigInt, SymmetricKey>
77 srp6_client_agree(const std::string& identifier,
78 const std::string& password,
79 const std::string& group_id,
80 const std::string& hash_id,
81 const std::vector<uint8_t>& salt,
82 const BigInt& B,
83 RandomNumberGenerator& rng)
84 {
85 DL_Group group(group_id);
86 const size_t a_bits = group.exponent_bits();
87
88 return srp6_client_agree(identifier, password, group, hash_id, salt, B, a_bits, rng);
89 }
90
91 std::pair<BigInt, SymmetricKey>
92 srp6_client_agree(const std::string& identifier,
93 const std::string& password,
94 const DL_Group& group,
95 const std::string& hash_id,
96 const std::vector<uint8_t>& salt,
97 const BigInt& B,
98 const size_t a_bits,
99 RandomNumberGenerator& rng)
100 {
101 const BigInt& g = group.get_g();
102 const BigInt& p = group.get_p();
103
104 const size_t p_bytes = group.p_bytes();
105
106 if(B <= 0 || B >= p)
107 throw Decoding_Error("Invalid SRP parameter from server");
108
109 const BigInt k = hash_seq(hash_id, p_bytes, p, g);
110
111 const BigInt a(rng, a_bits);
112
113 const BigInt A = group.power_g_p(a, a_bits);
114
115 const BigInt u = hash_seq(hash_id, p_bytes, A, B);
116
117 const BigInt x = compute_x(hash_id, identifier, password, salt);
118
119 const BigInt S = power_mod(group.mod_p(B - (k * power_mod(g, x, p))),
120 group.mod_p(a + (u * x)), p);
121
122 const SymmetricKey Sk(BigInt::encode_1363(S, p_bytes));
123
124 return std::make_pair(A, Sk);
125 }
126
127 BigInt generate_srp6_verifier(const std::string& identifier,
128 const std::string& password,
129 const std::vector<uint8_t>& salt,
130 const std::string& group_id,
131 const std::string& hash_id)
132 {
133 DL_Group group(group_id);
134 return generate_srp6_verifier(identifier, password, salt, group, hash_id);
135 }
136
137 BigInt generate_srp6_verifier(const std::string& identifier,
138 const std::string& password,
139 const std::vector<uint8_t>& salt,
140 const DL_Group& group,
141 const std::string& hash_id)
142 {
143 const BigInt x = compute_x(hash_id, identifier, password, salt);
144 // FIXME: x should be size of hash fn so avoid computing x.bits() here
145 return group.power_g_p(x, x.bits());
146 }
147
148 BigInt SRP6_Server_Session::step1(const BigInt& v,
149 const std::string& group_id,
150 const std::string& hash_id,
151 RandomNumberGenerator& rng)
152 {
153 DL_Group group(group_id);
154 const size_t b_bits = group.exponent_bits();
155
156 return this->step1(v, group, hash_id, b_bits, rng);
157 }
158
159 BigInt SRP6_Server_Session::step1(const BigInt& v,
160 const DL_Group& group,
161 const std::string& hash_id,
162 size_t b_bits,
163 RandomNumberGenerator& rng)
164 {
165 const BigInt& g = group.get_g();
166 const BigInt& p = group.get_p();
167
168 m_p_bytes = p.bytes();
169 m_v = v;
170 m_b = BigInt(rng, b_bits);
171 m_p = p;
172 m_hash_id = hash_id;
173
174 const BigInt k = hash_seq(hash_id, m_p_bytes, p, g);
175
176 m_B = group.mod_p(v*k + group.power_g_p(m_b, b_bits));
177
178 return m_B;
179 }
180
181 SymmetricKey SRP6_Server_Session::step2(const BigInt& A)
182 {
183 if(A <= 0 || A >= m_p)
184 throw Decoding_Error("Invalid SRP parameter from client");
185
186 const BigInt u = hash_seq(m_hash_id, m_p_bytes, A, m_B);
187
188 const BigInt S = power_mod(A * power_mod(m_v, u, m_p), m_b, m_p);
189
190 return BigInt::encode_1363(S, m_p_bytes);
191 }
192
193 }
Botan::DL_Group::p_bytes
size_t p_bytes() const
Definition: dl_group.cpp:441
Botan::Invalid_Argument
Definition: exceptn.h:136
Botan::HashFunction::create_or_throw
static std::unique_ptr< HashFunction > create_or_throw(const std::string &algo_spec, const std::string &provider="")
Definition: hash.cpp:344
Botan::OctetString
Definition: symkey.h:19
Botan::BigInt
Definition: bigint.h:24
Botan::power_mod
BigInt power_mod(const BigInt &base, const BigInt &exp, const BigInt &mod)
Definition: numthry.cpp:451
Botan::RandomNumberGenerator
Definition: rng.h:24
Botan::srp6_client_agree
std::pair< BigInt, SymmetricKey > srp6_client_agree(const std::string &identifier, const std::string &password, const std::string &group_id, const std::string &hash_id, const std::vector< uint8_t > &salt, const BigInt &B, RandomNumberGenerator &rng)
Definition: srp6.cpp:77
Botan::SRP6_Server_Session::step1
BigInt step1(const BigInt &v, const std::string &group_id, const std::string &hash_id, RandomNumberGenerator &rng)
Definition: srp6.cpp:148
Botan::DL_Group::get_p
const BigInt & get_p() const
Definition: dl_group.cpp:410
Botan::ASN1::to_string
std::string to_string(const BER_Object &obj)
Definition: asn1_obj.cpp:213
Botan::SRP6_Server_Session::step2
SymmetricKey step2(const BigInt &A)
Definition: srp6.cpp:181
Botan::Decoding_Error
Definition: exceptn.h:199
Botan::BigInt::bits
size_t bits() const
Definition: bigint.cpp:288
Botan::DL_Group
Definition: dl_group.h:23
Botan::DL_Group::get_g
const BigInt & get_g() const
Definition: dl_group.cpp:418
Botan::DL_Group::mod_p
BigInt mod_p(const BigInt &x) const
Definition: dl_group.cpp:474
Botan::DL_Group::exponent_bits
size_t exponent_bits() const
Definition: dl_group.cpp:463
Botan
Definition: alg_id.cpp:13
Botan::DL_Group::power_g_p
BigInt power_g_p(const BigInt &x) const
Definition: dl_group.cpp:520
Botan::BigInt::decode
static BigInt decode(const uint8_t buf[], size_t length)
Definition: bigint.h:798
Botan::BigInt::encode_1363
static secure_vector< uint8_t > encode_1363(const BigInt &n, size_t bytes)
Definition: big_code.cpp:111
Botan::generate_srp6_verifier
BigInt generate_srp6_verifier(const std::string &identifier, const std::string &password, const std::vector< uint8_t > &salt, const std::string &group_id, const std::string &hash_id)
Definition: srp6.cpp:127
Botan::srp6_group_identifier
std::string srp6_group_identifier(const BigInt &N, const BigInt &g)
Definition: srp6.cpp:53
Botan::BigInt::bytes
size_t bytes() const
Definition: bigint.cpp:273