xref: /aosp_15_r20/external/libchrome/crypto/p224_spake.h (revision 635a864187cb8b6c713ff48b7e790a6b21769273)
1*635a8641SAndroid Build Coastguard Worker // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2*635a8641SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*635a8641SAndroid Build Coastguard Worker // found in the LICENSE file.
4*635a8641SAndroid Build Coastguard Worker 
5*635a8641SAndroid Build Coastguard Worker #ifndef CRYPTO_P224_SPAKE_H_
6*635a8641SAndroid Build Coastguard Worker #define CRYPTO_P224_SPAKE_H_
7*635a8641SAndroid Build Coastguard Worker 
8*635a8641SAndroid Build Coastguard Worker #include <stdint.h>
9*635a8641SAndroid Build Coastguard Worker 
10*635a8641SAndroid Build Coastguard Worker #include <string>
11*635a8641SAndroid Build Coastguard Worker 
12*635a8641SAndroid Build Coastguard Worker #include "base/gtest_prod_util.h"
13*635a8641SAndroid Build Coastguard Worker #include "base/strings/string_piece.h"
14*635a8641SAndroid Build Coastguard Worker #include "crypto/p224.h"
15*635a8641SAndroid Build Coastguard Worker #include "crypto/sha2.h"
16*635a8641SAndroid Build Coastguard Worker 
17*635a8641SAndroid Build Coastguard Worker namespace crypto {
18*635a8641SAndroid Build Coastguard Worker 
19*635a8641SAndroid Build Coastguard Worker // P224EncryptedKeyExchange implements SPAKE2, a variant of Encrypted
20*635a8641SAndroid Build Coastguard Worker // Key Exchange. It allows two parties that have a secret common
21*635a8641SAndroid Build Coastguard Worker // password to establish a common secure key by exchanging messages
22*635a8641SAndroid Build Coastguard Worker // over an insecure channel without disclosing the password.
23*635a8641SAndroid Build Coastguard Worker //
24*635a8641SAndroid Build Coastguard Worker // The password can be low entropy as authenticating with an attacker only
25*635a8641SAndroid Build Coastguard Worker // gives the attacker a one-shot password oracle. No other information about
26*635a8641SAndroid Build Coastguard Worker // the password is leaked. (However, you must be sure to limit the number of
27*635a8641SAndroid Build Coastguard Worker // permitted authentication attempts otherwise they get many one-shot oracles.)
28*635a8641SAndroid Build Coastguard Worker //
29*635a8641SAndroid Build Coastguard Worker // The protocol requires several RTTs (actually two, but you shouldn't assume
30*635a8641SAndroid Build Coastguard Worker // that.) To use the object, call GetNextMessage() and pass that message to the
31*635a8641SAndroid Build Coastguard Worker // peer. Get a message from the peer and feed it into ProcessMessage. Then
32*635a8641SAndroid Build Coastguard Worker // examine the return value of ProcessMessage:
33*635a8641SAndroid Build Coastguard Worker //   kResultPending: Another round is required. Call GetNextMessage and repeat.
34*635a8641SAndroid Build Coastguard Worker //   kResultFailed: The authentication has failed. You can get a human readable
35*635a8641SAndroid Build Coastguard Worker //       error message by calling error().
36*635a8641SAndroid Build Coastguard Worker //   kResultSuccess: The authentication was successful.
37*635a8641SAndroid Build Coastguard Worker //
38*635a8641SAndroid Build Coastguard Worker // In each exchange, each peer always sends a message.
39*635a8641SAndroid Build Coastguard Worker class CRYPTO_EXPORT P224EncryptedKeyExchange {
40*635a8641SAndroid Build Coastguard Worker  public:
41*635a8641SAndroid Build Coastguard Worker   enum Result {
42*635a8641SAndroid Build Coastguard Worker     kResultPending,
43*635a8641SAndroid Build Coastguard Worker     kResultFailed,
44*635a8641SAndroid Build Coastguard Worker     kResultSuccess,
45*635a8641SAndroid Build Coastguard Worker   };
46*635a8641SAndroid Build Coastguard Worker 
47*635a8641SAndroid Build Coastguard Worker   // PeerType's values are named client and server due to convention. But
48*635a8641SAndroid Build Coastguard Worker   // they could be called "A" and "B" as far as the protocol is concerned so
49*635a8641SAndroid Build Coastguard Worker   // long as the two parties don't both get the same label.
50*635a8641SAndroid Build Coastguard Worker   enum PeerType {
51*635a8641SAndroid Build Coastguard Worker     kPeerTypeClient,
52*635a8641SAndroid Build Coastguard Worker     kPeerTypeServer,
53*635a8641SAndroid Build Coastguard Worker   };
54*635a8641SAndroid Build Coastguard Worker 
55*635a8641SAndroid Build Coastguard Worker   // peer_type: the type of the local authentication party.
56*635a8641SAndroid Build Coastguard Worker   // password: secret session password. Both parties to the
57*635a8641SAndroid Build Coastguard Worker   //     authentication must pass the same value. For the case of a
58*635a8641SAndroid Build Coastguard Worker   //     TLS connection, see RFC 5705.
59*635a8641SAndroid Build Coastguard Worker   P224EncryptedKeyExchange(PeerType peer_type, base::StringPiece password);
60*635a8641SAndroid Build Coastguard Worker 
61*635a8641SAndroid Build Coastguard Worker   // GetNextMessage returns a byte string which must be passed to the other
62*635a8641SAndroid Build Coastguard Worker   // party in the authentication.
63*635a8641SAndroid Build Coastguard Worker   const std::string& GetNextMessage();
64*635a8641SAndroid Build Coastguard Worker 
65*635a8641SAndroid Build Coastguard Worker   // ProcessMessage processes a message which must have been generated by a
66*635a8641SAndroid Build Coastguard Worker   // call to GetNextMessage() by the other party.
67*635a8641SAndroid Build Coastguard Worker   Result ProcessMessage(base::StringPiece message);
68*635a8641SAndroid Build Coastguard Worker 
69*635a8641SAndroid Build Coastguard Worker   // In the event that ProcessMessage() returns kResultFailed, error will
70*635a8641SAndroid Build Coastguard Worker   // return a human readable error message.
71*635a8641SAndroid Build Coastguard Worker   const std::string& error() const;
72*635a8641SAndroid Build Coastguard Worker 
73*635a8641SAndroid Build Coastguard Worker   // The key established as result of the key exchange. Must be called
74*635a8641SAndroid Build Coastguard Worker   // at then end after ProcessMessage() returns kResultSuccess.
75*635a8641SAndroid Build Coastguard Worker   const std::string& GetKey() const;
76*635a8641SAndroid Build Coastguard Worker 
77*635a8641SAndroid Build Coastguard Worker   // The key established as result of the key exchange. Can be called after
78*635a8641SAndroid Build Coastguard Worker   // the first ProcessMessage()
79*635a8641SAndroid Build Coastguard Worker   const std::string& GetUnverifiedKey() const;
80*635a8641SAndroid Build Coastguard Worker 
81*635a8641SAndroid Build Coastguard Worker  private:
82*635a8641SAndroid Build Coastguard Worker   // The authentication state machine is very simple and each party proceeds
83*635a8641SAndroid Build Coastguard Worker   // through each of these states, in order.
84*635a8641SAndroid Build Coastguard Worker   enum State {
85*635a8641SAndroid Build Coastguard Worker     kStateInitial,
86*635a8641SAndroid Build Coastguard Worker     kStateRecvDH,
87*635a8641SAndroid Build Coastguard Worker     kStateSendHash,
88*635a8641SAndroid Build Coastguard Worker     kStateRecvHash,
89*635a8641SAndroid Build Coastguard Worker     kStateDone,
90*635a8641SAndroid Build Coastguard Worker   };
91*635a8641SAndroid Build Coastguard Worker 
92*635a8641SAndroid Build Coastguard Worker   FRIEND_TEST_ALL_PREFIXES(MutualAuth, ExpectedValues);
93*635a8641SAndroid Build Coastguard Worker 
94*635a8641SAndroid Build Coastguard Worker   void Init();
95*635a8641SAndroid Build Coastguard Worker 
96*635a8641SAndroid Build Coastguard Worker   // Sets internal random scalar. Should be used by tests only.
97*635a8641SAndroid Build Coastguard Worker   void SetXForTesting(const std::string& x);
98*635a8641SAndroid Build Coastguard Worker 
99*635a8641SAndroid Build Coastguard Worker   State state_;
100*635a8641SAndroid Build Coastguard Worker   const bool is_server_;
101*635a8641SAndroid Build Coastguard Worker   // next_message_ contains a value for GetNextMessage() to return.
102*635a8641SAndroid Build Coastguard Worker   std::string next_message_;
103*635a8641SAndroid Build Coastguard Worker   std::string error_;
104*635a8641SAndroid Build Coastguard Worker 
105*635a8641SAndroid Build Coastguard Worker   // CalculateHash computes the verification hash for the given peer and writes
106*635a8641SAndroid Build Coastguard Worker   // |kSHA256Length| bytes at |out_digest|.
107*635a8641SAndroid Build Coastguard Worker   void CalculateHash(PeerType peer_type,
108*635a8641SAndroid Build Coastguard Worker                      const std::string& client_masked_dh,
109*635a8641SAndroid Build Coastguard Worker                      const std::string& server_masked_dh,
110*635a8641SAndroid Build Coastguard Worker                      const std::string& k,
111*635a8641SAndroid Build Coastguard Worker                      uint8_t* out_digest);
112*635a8641SAndroid Build Coastguard Worker 
113*635a8641SAndroid Build Coastguard Worker   // x_ is the secret Diffie-Hellman exponent (see paper referenced in .cc
114*635a8641SAndroid Build Coastguard Worker   // file).
115*635a8641SAndroid Build Coastguard Worker   uint8_t x_[p224::kScalarBytes];
116*635a8641SAndroid Build Coastguard Worker   // pw_ is SHA256(P(password), P(session))[:28] where P() prepends a uint32_t,
117*635a8641SAndroid Build Coastguard Worker   // big-endian length prefix (see paper referenced in .cc file).
118*635a8641SAndroid Build Coastguard Worker   uint8_t pw_[p224::kScalarBytes];
119*635a8641SAndroid Build Coastguard Worker   // expected_authenticator_ is used to store the hash value expected from the
120*635a8641SAndroid Build Coastguard Worker   // other party.
121*635a8641SAndroid Build Coastguard Worker   uint8_t expected_authenticator_[kSHA256Length];
122*635a8641SAndroid Build Coastguard Worker 
123*635a8641SAndroid Build Coastguard Worker   std::string key_;
124*635a8641SAndroid Build Coastguard Worker };
125*635a8641SAndroid Build Coastguard Worker 
126*635a8641SAndroid Build Coastguard Worker }  // namespace crypto
127*635a8641SAndroid Build Coastguard Worker 
128*635a8641SAndroid Build Coastguard Worker #endif  // CRYPTO_P224_SPAKE_H_
129