Botan: src/constructs/srp6/srp6.cpp Source File

Botan 1.10.16

srp6.cpp
Go to the documentation of this file.
1 /*
2 * SRP-6a (RFC 5054 compatatible)
3 * (C) 2011,2012 Jack Lloyd
4 *
5 * Distributed under the terms of the Botan license
6 */
7
8 #include <botan/srp6.h>
9 #include <botan/dl_group.h>
10 #include <botan/libstate.h>
11 #include <botan/numthry.h>
12 #include <memory>
13
14 namespace Botan {
15
16 namespace {
17
18 BigInt hash_seq(const std::string& hash_id,
19 size_t pad_to,
20 const BigInt& in1,
21 const BigInt& in2)
22 {
23 std::auto_ptr<HashFunction> hash_fn(
24 global_state().algorithm_factory().make_hash_function(hash_id));
25
26 hash_fn->update(BigInt::encode_1363(in1, pad_to));
27 hash_fn->update(BigInt::encode_1363(in2, pad_to));
28
29 return BigInt::decode(hash_fn->final());
30 }
31
32 BigInt hash_seq(const std::string& hash_id,
33 size_t pad_to,
34 const BigInt& in1,
35 const BigInt& in2,
36 const BigInt& in3)
37 {
38 std::auto_ptr<HashFunction> hash_fn(
39 global_state().algorithm_factory().make_hash_function(hash_id));
40
41 hash_fn->update(BigInt::encode_1363(in1, pad_to));
42 hash_fn->update(BigInt::encode_1363(in2, pad_to));
43 hash_fn->update(BigInt::encode_1363(in3, pad_to));
44
45 return BigInt::decode(hash_fn->final());
46 }
47
48 BigInt compute_x(const std::string& hash_id,
49 const std::string& identifier,
50 const std::string& password,
51 const MemoryRegion<byte>& salt)
52 {
53 std::auto_ptr<HashFunction> hash_fn(
54 global_state().algorithm_factory().make_hash_function(hash_id));
55
56 hash_fn->update(identifier);
57 hash_fn->update(":");
58 hash_fn->update(password);
59
60 SecureVector<byte> inner_h = hash_fn->final();
61
62 hash_fn->update(salt);
63 hash_fn->update(inner_h);
64
65 SecureVector<byte> outer_h = hash_fn->final();
66
67 return BigInt::decode(outer_h);
68 }
69
70 }
71
72 std::string srp6_group_identifier(const BigInt& N, const BigInt& g)
73 {
74 /*
75 This function assumes that only one 'standard' SRP parameter set has
76 been defined for a particular bitsize. As of this writing that is the case.
77 */
78 try
79 {
80 const std::string group_name = "modp/srp/" + to_string(N.bits());
81
82 DL_Group group(group_name);
83
84 if(group.get_p() == N && group.get_g() == g)
85 return group_name;
86
87 throw std::runtime_error("Unknown SRP params");
88 }
89 catch(...)
90 {
91 throw Invalid_Argument("Bad SRP group parameters");
92 }
93 }
94
95 std::pair<BigInt, SymmetricKey>
96 srp6_client_agree(const std::string& identifier,
97 const std::string& password,
98 const std::string& group_id,
99 const std::string& hash_id,
100 const MemoryRegion<byte>& salt,
101 const BigInt& B,
102 RandomNumberGenerator& rng)
103 {
104 DL_Group group(group_id);
105 const BigInt& g = group.get_g();
106 const BigInt& p = group.get_p();
107
108 const size_t p_bytes = group.get_p().bytes();
109
110 if(B <= 0 || B >= p)
111 throw std::runtime_error("Invalid SRP parameter from server");
112
113 BigInt k = hash_seq(hash_id, p_bytes, p, g);
114
115 BigInt a(rng, 256);
116
117 BigInt A = power_mod(g, a, p);
118
119 BigInt u = hash_seq(hash_id, p_bytes, A, B);
120
121 const BigInt x = compute_x(hash_id, identifier, password, salt);
122
123 BigInt S = power_mod((B - (k * power_mod(g, x, p))) % p, (a + (u * x)), p);
124
125 SymmetricKey Sk(BigInt::encode_1363(S, p_bytes));
126
127 return std::make_pair(A, Sk);
128 }
129
130 BigInt generate_srp6_verifier(const std::string& identifier,
131 const std::string& password,
132 const MemoryRegion<byte>& salt,
133 const std::string& group_id,
134 const std::string& hash_id)
135 {
136 const BigInt x = compute_x(hash_id, identifier, password, salt);
137
138 DL_Group group(group_id);
139 return power_mod(group.get_g(), x, group.get_p());
140 }
141
142 BigInt SRP6_Server_Session::step1(const BigInt& v,
143 const std::string& group_id,
144 const std::string& hash_id,
145 RandomNumberGenerator& rng)
146 {
147 DL_Group group(group_id);
148 const BigInt& g = group.get_g();
149 const BigInt& p = group.get_p();
150
151 p_bytes = p.bytes();
152
153 BigInt k = hash_seq(hash_id, p_bytes, p, g);
154
155 BigInt b(rng, 256);
156
157 B = (v*k + power_mod(g, b, p)) % p;
158
159 this->v = v;
160 this->b = b;
161 this->p = p;
162 this->hash_id = hash_id;
163
164 return B;
165 }
166
167 SymmetricKey SRP6_Server_Session::step2(const BigInt& A)
168 {
169 if(A <= 0 || A >= p)
170 throw std::runtime_error("Invalid SRP parameter from client");
171
172 BigInt u = hash_seq(hash_id, p_bytes, A, B);
173
174 BigInt S = power_mod(A * power_mod(v, u, p), b, p);
175
176 return BigInt::encode_1363(S, p_bytes);
177 }
178
179 }
Botan::OctetString
Definition: symkey.h:19
Botan::generate_srp6_verifier
BigInt generate_srp6_verifier(const std::string &identifier, const std::string &password, const MemoryRegion< byte > &salt, const std::string &group_id, const std::string &hash_id)
Definition: srp6.cpp:130
Botan::BigInt
Definition: bigint.h:22
Botan::RandomNumberGenerator
Definition: rng.h:20
Botan::BigInt::bits
size_t bits() const
Definition: bigint.cpp:253
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:142
Botan::DL_Group::get_g
const BigInt & get_g() const
Definition: dl_group.cpp:185
Botan::Invalid_Argument
std::invalid_argument Invalid_Argument
Definition: exceptn.h:20
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 MemoryRegion< byte > &salt, const BigInt &B, RandomNumberGenerator &rng)
Definition: srp6.cpp:96
Botan::SRP6_Server_Session::step2
SymmetricKey step2(const BigInt &A)
Definition: srp6.cpp:167
Botan::DL_Group
Definition: dl_group.h:20
Botan::DL_Group::get_p
const BigInt & get_p() const
Definition: dl_group.cpp:176
Botan::Global_State_Management::global_state
Library_State & global_state()
Definition: global_state.cpp:32
Botan::MemoryRegion< byte >
Botan
Definition: algo_base.h:14
Botan::BigInt::bytes
size_t bytes() const
Definition: bigint.cpp:245
Botan::power_mod
BigInt power_mod(const BigInt &base, const BigInt &exp, const BigInt &mod)
Definition: numthry.cpp:366
Botan::BigInt::decode
static BigInt decode(const byte buf[], size_t length, Base base=Binary)
Definition: big_code.cpp:102
Botan::to_string
std::string to_string(u64bit n, size_t min_len)
Definition: parsing.cpp:42
Botan::BigInt::encode_1363
static SecureVector< byte > encode_1363(const BigInt &n, size_t bytes)
Definition: big_code.cpp:78
Botan::srp6_group_identifier
std::string srp6_group_identifier(const BigInt &N, const BigInt &g)
Definition: srp6.cpp:72