OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 // This code implements SPAKE2, a variant of EKE: | 5 // This code implements SPAKE2, a variant of EKE: |
6 // http://www.di.ens.fr/~pointche/pub.php?reference=AbPo04 | 6 // http://www.di.ens.fr/~pointche/pub.php?reference=AbPo04 |
7 | 7 |
8 #include <crypto/p224_spake.h> | 8 #include <crypto/p224_spake.h> |
9 | 9 |
| 10 #include <algorithm> |
| 11 |
10 #include <base/logging.h> | 12 #include <base/logging.h> |
11 #include <crypto/p224.h> | 13 #include <crypto/p224.h> |
12 #include <crypto/random.h> | 14 #include <crypto/random.h> |
13 #include <crypto/secure_util.h> | 15 #include <crypto/secure_util.h> |
14 | 16 |
15 namespace { | 17 namespace { |
16 | 18 |
17 // The following two points (M and N in the protocol) are verifiable random | 19 // The following two points (M and N in the protocol) are verifiable random |
18 // points on the curve and can be generated with the following code: | 20 // points on the curve and can be generated with the following code: |
19 | 21 |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
98 P224EncryptedKeyExchange::P224EncryptedKeyExchange( | 100 P224EncryptedKeyExchange::P224EncryptedKeyExchange( |
99 PeerType peer_type, const base::StringPiece& password) | 101 PeerType peer_type, const base::StringPiece& password) |
100 : state_(kStateInitial), | 102 : state_(kStateInitial), |
101 is_server_(peer_type == kPeerTypeServer) { | 103 is_server_(peer_type == kPeerTypeServer) { |
102 memset(&x_, 0, sizeof(x_)); | 104 memset(&x_, 0, sizeof(x_)); |
103 memset(&expected_authenticator_, 0, sizeof(expected_authenticator_)); | 105 memset(&expected_authenticator_, 0, sizeof(expected_authenticator_)); |
104 | 106 |
105 // x_ is a random scalar. | 107 // x_ is a random scalar. |
106 RandBytes(x_, sizeof(x_)); | 108 RandBytes(x_, sizeof(x_)); |
107 | 109 |
108 // X = g**x_ | |
109 p224::Point X; | |
110 p224::ScalarBaseMult(x_, &X); | |
111 | |
112 // Calculate |password| hash to get SPAKE password value. | 110 // Calculate |password| hash to get SPAKE password value. |
113 SHA256HashString(std::string(password.data(), password.length()), | 111 SHA256HashString(std::string(password.data(), password.length()), |
114 pw_, sizeof(pw_)); | 112 pw_, sizeof(pw_)); |
115 | 113 |
| 114 Init(); |
| 115 } |
| 116 |
| 117 void P224EncryptedKeyExchange::Init() { |
| 118 // X = g**x_ |
| 119 p224::Point X; |
| 120 p224::ScalarBaseMult(x_, &X); |
| 121 |
116 // The client masks the Diffie-Hellman value, X, by adding M**pw and the | 122 // The client masks the Diffie-Hellman value, X, by adding M**pw and the |
117 // server uses N**pw. | 123 // server uses N**pw. |
118 p224::Point MNpw; | 124 p224::Point MNpw; |
119 p224::ScalarMult(is_server_ ? kN : kM, pw_, &MNpw); | 125 p224::ScalarMult(is_server_ ? kN : kM, pw_, &MNpw); |
120 | 126 |
121 // X* = X + (N|M)**pw | 127 // X* = X + (N|M)**pw |
122 p224::Point Xstar; | 128 p224::Point Xstar; |
123 p224::Add(X, MNpw, &Xstar); | 129 p224::Add(X, MNpw, &Xstar); |
124 | 130 |
125 next_message_ = Xstar.ToString(); | 131 next_message_ = Xstar.ToString(); |
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
246 } | 252 } |
247 | 253 |
248 const std::string& P224EncryptedKeyExchange::GetUnverifiedKey() const { | 254 const std::string& P224EncryptedKeyExchange::GetUnverifiedKey() const { |
249 // Key is already final when state is kStateSendHash. Subsequent states are | 255 // Key is already final when state is kStateSendHash. Subsequent states are |
250 // used only for verification of the key. Some users may combine verification | 256 // used only for verification of the key. Some users may combine verification |
251 // with sending verifiable data instead of |expected_authenticator_|. | 257 // with sending verifiable data instead of |expected_authenticator_|. |
252 DCHECK_GE(state_, kStateSendHash); | 258 DCHECK_GE(state_, kStateSendHash); |
253 return key_; | 259 return key_; |
254 } | 260 } |
255 | 261 |
| 262 void P224EncryptedKeyExchange::SetXForTesting(const std::string& x) { |
| 263 memset(&x_, 0, sizeof(x_)); |
| 264 memcpy(&x_, x.data(), std::min(x.size(), sizeof(x_))); |
| 265 Init(); |
| 266 } |
| 267 |
256 } // namespace crypto | 268 } // namespace crypto |
OLD | NEW |