This source file includes following definitions.
- is_server_
 
- GetMessage
 
- ProcessMessage
 
- CalculateHash
 
- error
 
- GetKey
 
#include <crypto/p224_spake.h>
#include <base/logging.h>
#include <crypto/p224.h>
#include <crypto/random.h>
#include <crypto/secure_util.h>
namespace {
const crypto::p224::Point kM = {
  {174237515, 77186811, 235213682, 33849492,
   33188520, 48266885, 177021753, 81038478},
  {104523827, 245682244, 266509668, 236196369,
   28372046, 145351378, 198520366, 113345994},
  {1, 0, 0, 0, 0, 0, 0},
};
const crypto::p224::Point kN = {
  {136176322, 263523628, 251628795, 229292285,
   5034302, 185981975, 171998428, 11653062},
  {197567436, 51226044, 60372156, 175772188,
   42075930, 8083165, 160827401, 65097570},
  {1, 0, 0, 0, 0, 0, 0},
};
}  
namespace crypto {
P224EncryptedKeyExchange::P224EncryptedKeyExchange(
    PeerType peer_type, const base::StringPiece& password)
    : state_(kStateInitial),
      is_server_(peer_type == kPeerTypeServer) {
  memset(&x_, 0, sizeof(x_));
  memset(&expected_authenticator_, 0, sizeof(expected_authenticator_));
  
  RandBytes(x_, sizeof(x_));
  
  p224::Point X;
  p224::ScalarBaseMult(x_, &X);
  
  SHA256HashString(std::string(password.data(), password.length()),
                   pw_, sizeof(pw_));
  
  
  p224::Point MNpw;
  p224::ScalarMult(is_server_ ? kN : kM, pw_, &MNpw);
  
  p224::Point Xstar;
  p224::Add(X, MNpw, &Xstar);
  next_message_ = Xstar.ToString();
}
const std::string& P224EncryptedKeyExchange::GetMessage() {
  if (state_ == kStateInitial) {
    state_ = kStateRecvDH;
    return next_message_;
  } else if (state_ == kStateSendHash) {
    state_ = kStateRecvHash;
    return next_message_;
  }
  LOG(FATAL) << "P224EncryptedKeyExchange::GetMessage called in"
                " bad state " << state_;
  next_message_ = "";
  return next_message_;
}
P224EncryptedKeyExchange::Result P224EncryptedKeyExchange::ProcessMessage(
    const base::StringPiece& message) {
  if (state_ == kStateRecvHash) {
    
    
    if (message.size() != sizeof(expected_authenticator_)) {
      error_ = "peer's hash had an incorrect size";
      return kResultFailed;
    }
    if (!SecureMemEqual(message.data(), expected_authenticator_,
                        message.size())) {
      error_ = "peer's hash had incorrect value";
      return kResultFailed;
    }
    state_ = kStateDone;
    return kResultSuccess;
  }
  if (state_ != kStateRecvDH) {
    LOG(FATAL) << "P224EncryptedKeyExchange::ProcessMessage called in"
                  " bad state " << state_;
    error_ = "internal error";
    return kResultFailed;
  }
  
  p224::Point Ystar;
  if (!Ystar.SetFromString(message)) {
    error_ = "failed to parse peer's masked Diffie-Hellman value";
    return kResultFailed;
  }
  
  p224::Point MNpw, minus_MNpw, Y, k;
  p224::ScalarMult(is_server_ ? kM : kN, pw_, &MNpw);
  p224::Negate(MNpw, &minus_MNpw);
  
  p224::Add(Ystar, minus_MNpw, &Y);
  
  p224::ScalarMult(Y, x_, &k);
  
  key_ = k.ToString();
  std::string client_masked_dh, server_masked_dh;
  if (is_server_) {
    client_masked_dh = message.as_string();
    server_masked_dh = next_message_;
  } else {
    client_masked_dh = next_message_;
    server_masked_dh = message.as_string();
  }
  
  
  uint8 client_hash[kSHA256Length], server_hash[kSHA256Length];
  CalculateHash(kPeerTypeClient, client_masked_dh, server_masked_dh, key_,
                client_hash);
  CalculateHash(kPeerTypeServer, client_masked_dh, server_masked_dh, key_,
                server_hash);
  const uint8* my_hash = is_server_ ? server_hash : client_hash;
  const uint8* their_hash = is_server_ ? client_hash : server_hash;
  next_message_ =
      std::string(reinterpret_cast<const char*>(my_hash), kSHA256Length);
  memcpy(expected_authenticator_, their_hash, kSHA256Length);
  state_ = kStateSendHash;
  return kResultPending;
}
void P224EncryptedKeyExchange::CalculateHash(
    PeerType peer_type,
    const std::string& client_masked_dh,
    const std::string& server_masked_dh,
    const std::string& k,
    uint8* out_digest) {
  std::string hash_contents;
  if (peer_type == kPeerTypeServer) {
    hash_contents = "server";
  } else {
    hash_contents = "client";
  }
  hash_contents += client_masked_dh;
  hash_contents += server_masked_dh;
  hash_contents +=
      std::string(reinterpret_cast<const char *>(pw_), sizeof(pw_));
  hash_contents += k;
  SHA256HashString(hash_contents, out_digest, kSHA256Length);
}
const std::string& P224EncryptedKeyExchange::error() const {
  return error_;
}
const std::string& P224EncryptedKeyExchange::GetKey() {
  DCHECK_EQ(state_, kStateDone);
  return key_;
}
}