blob: 823bd459d4cdf76b4d139565b6d85632ed69a922 [file] [log] [blame]
[email protected]cf211882012-07-11 07:19:141// Copyright (c) 2012 The Chromium Authors. All rights reserved.
[email protected]d9a262d2011-11-22 01:29:372// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef CRYPTO_P224_SPAKE_H_
6#define CRYPTO_P224_SPAKE_H_
[email protected]d9a262d2011-11-22 01:29:377
avidd373b8b2015-12-21 21:34:438#include <stdint.h>
9
davidben6004dc52017-02-03 04:15:2910#include <string>
11
avidd373b8b2015-12-21 21:34:4312#include "base/gtest_prod_util.h"
13#include "base/strings/string_piece.h"
davidben6004dc52017-02-03 04:15:2914#include "crypto/p224.h"
15#include "crypto/sha2.h"
[email protected]d9a262d2011-11-22 01:29:3716
17namespace crypto {
18
[email protected]78df46a2011-12-13 07:00:1919// P224EncryptedKeyExchange implements SPAKE2, a variant of Encrypted
20// Key Exchange. It allows two parties that have a secret common
21// password to establish a common secure key by exchanging messages
Vitaly Bukabd85b5692014-12-10 07:54:1522// over an insecure channel without disclosing the password.
[email protected]d9a262d2011-11-22 01:29:3723//
24// The password can be low entropy as authenticating with an attacker only
25// gives the attacker a one-shot password oracle. No other information about
26// the password is leaked. (However, you must be sure to limit the number of
27// permitted authentication attempts otherwise they get many one-shot oracles.)
28//
29// The protocol requires several RTTs (actually two, but you shouldn't assume
vitalybukad1203602015-01-29 20:49:4930// that.) To use the object, call GetNextMessage() and pass that message to the
[email protected]d9a262d2011-11-22 01:29:3731// peer. Get a message from the peer and feed it into ProcessMessage. Then
32// examine the return value of ProcessMessage:
vitalybukad1203602015-01-29 20:49:4933// kResultPending: Another round is required. Call GetNextMessage and repeat.
[email protected]d9a262d2011-11-22 01:29:3734// kResultFailed: The authentication has failed. You can get a human readable
35// error message by calling error().
36// kResultSuccess: The authentication was successful.
37//
38// In each exchange, each peer always sends a message.
39class CRYPTO_EXPORT P224EncryptedKeyExchange {
40 public:
41 enum Result {
42 kResultPending,
43 kResultFailed,
44 kResultSuccess,
45 };
46
47 // PeerType's values are named client and server due to convention. But
48 // they could be called "A" and "B" as far as the protocol is concerned so
49 // long as the two parties don't both get the same label.
50 enum PeerType {
51 kPeerTypeClient,
52 kPeerTypeServer,
53 };
54
55 // peer_type: the type of the local authentication party.
[email protected]78df46a2011-12-13 07:00:1956 // password: secret session password. Both parties to the
57 // authentication must pass the same value. For the case of a
58 // TLS connection, see RFC 5705.
David Benjamincda45eb2017-11-06 18:16:5259 P224EncryptedKeyExchange(PeerType peer_type, base::StringPiece password);
[email protected]d9a262d2011-11-22 01:29:3760
vitalybukad1203602015-01-29 20:49:4961 // GetNextMessage returns a byte string which must be passed to the other
62 // party in the authentication.
63 const std::string& GetNextMessage();
[email protected]d9a262d2011-11-22 01:29:3764
65 // ProcessMessage processes a message which must have been generated by a
vitalybukad1203602015-01-29 20:49:4966 // call to GetNextMessage() by the other party.
David Benjamincda45eb2017-11-06 18:16:5267 Result ProcessMessage(base::StringPiece message);
[email protected]d9a262d2011-11-22 01:29:3768
69 // In the event that ProcessMessage() returns kResultFailed, error will
70 // return a human readable error message.
71 const std::string& error() const;
72
[email protected]78df46a2011-12-13 07:00:1973 // The key established as result of the key exchange. Must be called
74 // at then end after ProcessMessage() returns kResultSuccess.
Vitaly Bukafb2ccf62014-12-04 17:15:2075 const std::string& GetKey() const;
76
77 // The key established as result of the key exchange. Can be called after
78 // the first ProcessMessage()
79 const std::string& GetUnverifiedKey() const;
[email protected]78df46a2011-12-13 07:00:1980
[email protected]d9a262d2011-11-22 01:29:3781 private:
82 // The authentication state machine is very simple and each party proceeds
83 // through each of these states, in order.
84 enum State {
85 kStateInitial,
86 kStateRecvDH,
87 kStateSendHash,
88 kStateRecvHash,
89 kStateDone,
90 };
91
Vitaly Bukabd85b5692014-12-10 07:54:1592 FRIEND_TEST_ALL_PREFIXES(MutualAuth, ExpectedValues);
93
94 void Init();
95
96 // Sets internal random scalar. Should be used by tests only.
97 void SetXForTesting(const std::string& x);
98
[email protected]d9a262d2011-11-22 01:29:3799 State state_;
100 const bool is_server_;
vitalybukad1203602015-01-29 20:49:49101 // next_message_ contains a value for GetNextMessage() to return.
[email protected]d9a262d2011-11-22 01:29:37102 std::string next_message_;
103 std::string error_;
104
105 // CalculateHash computes the verification hash for the given peer and writes
106 // |kSHA256Length| bytes at |out_digest|.
avidd373b8b2015-12-21 21:34:43107 void CalculateHash(PeerType peer_type,
108 const std::string& client_masked_dh,
109 const std::string& server_masked_dh,
110 const std::string& k,
111 uint8_t* out_digest);
[email protected]d9a262d2011-11-22 01:29:37112
113 // x_ is the secret Diffie-Hellman exponent (see paper referenced in .cc
114 // file).
avidd373b8b2015-12-21 21:34:43115 uint8_t x_[p224::kScalarBytes];
116 // pw_ is SHA256(P(password), P(session))[:28] where P() prepends a uint32_t,
Vitaly Bukabd85b5692014-12-10 07:54:15117 // big-endian length prefix (see paper referenced in .cc file).
avidd373b8b2015-12-21 21:34:43118 uint8_t pw_[p224::kScalarBytes];
[email protected]d9a262d2011-11-22 01:29:37119 // expected_authenticator_ is used to store the hash value expected from the
120 // other party.
avidd373b8b2015-12-21 21:34:43121 uint8_t expected_authenticator_[kSHA256Length];
[email protected]78df46a2011-12-13 07:00:19122
123 std::string key_;
[email protected]d9a262d2011-11-22 01:29:37124};
125
126} // namespace crypto
127
128#endif // CRYPTO_P224_SPAKE_H_