// Copyright 2017 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <string.h>

#include <memory>
#include <string>
#include <vector>

#include <base/logging.h>
#include <base/strings/string_number_conversions.h>
#include <chromeos/dbus/service_constants.h>
#include <gtest/gtest.h>
#include <openssl/hmac.h>
#include <openssl/sha.h>

#include "hammerd/mock_dbus_wrapper.h"
#include "hammerd/mock_pair_utils.h"
#include "hammerd/mock_update_fw.h"
#include "hammerd/pair_utils.h"

namespace hammerd {

namespace {
// Curve25519 test vector from the NaCl distribution.
const char kAlicePrivateStr[] =
    "77076D0A7318A57D3C16C17251B26645DF4C2F87EBC0992AB177FBA51DB92C2A";
const char kAlicePublicStr[] =
    "8520F0098930A754748B7DDCB43EF75A0DBF3A0D26381AF4EBA4A98EAA9B4E6A";
const char kBobPrivateStr[] =
    "5DAB087E624A8A4B79E17F8B83800EE66F3BB1292618B6FD1C2F8B27FF88E0EB";
const char kBobPublicStr[] =
    "DE9EDB7D7B7DC1B4D35B61C2ECE435373F8343C85B78674DADFC7E146F882B4F";

// Self-created test vector.
const char kNonceStr[] = "19A50A637080D93812AD65C8C5205786";
const char kAuthenticatorStr[] = "61372D572BC47539D1539AE0F395AAE3";
}  // namespace

using testing::_;
using testing::DoAll;
using testing::InSequence;
using testing::Return;

// Convert the test vector from Hex-encoded string to data.
class TestVector {
 public:
  TestVector() {
    base::HexStringToBytes(kAlicePrivateStr, &alice_private_);
    base::HexStringToBytes(kAlicePublicStr, &alice_public_);
    base::HexStringToBytes(kBobPrivateStr, &bob_private_);
    base::HexStringToBytes(kBobPublicStr, &bob_public_);
    base::HexStringToBytes(kNonceStr, &nonce_);
    base::HexStringToBytes(kAuthenticatorStr, &authenticator_);
  }

  std::vector<uint8_t> alice_private_;
  std::vector<uint8_t> alice_public_;
  std::vector<uint8_t> bob_private_;
  std::vector<uint8_t> bob_public_;
  std::vector<uint8_t> nonce_;
  std::vector<uint8_t> authenticator_;
};

// Check the size of destination and source is the same, and then copy the data.
void CheckMemcpy(uint8_t* dest, size_t size, const std::vector<uint8_t>& src) {
  ASSERT_EQ(size, src.size());
  memcpy(dest, src.data(), size);
}

ACTION_P3(SetChallengeRequest, public_key, private_key, nonce) {
  CheckMemcpy(arg0->public_key, X25519_PUBLIC_VALUE_LEN, public_key);
  CheckMemcpy(arg0->nonce, kHMACNonceLength, nonce);
  CheckMemcpy(arg1, X25519_PRIVATE_KEY_LEN, private_key);
}

ACTION_P4(SetChallengeResponse, status, public_key, authenticator, ret) {
  auto resp = reinterpret_cast<PairChallengeResponse*>(arg2);
  resp->status = static_cast<uint8_t>(status);
  if (public_key.size() > 0)
    CheckMemcpy(resp->public_key, X25519_PUBLIC_VALUE_LEN, public_key);
  if (authenticator.size() > 0)
    CheckMemcpy(resp->authenticator, kHMACAuthenticatorLength, authenticator);
  return ret;
}

// Verify PairManager method.
// In the normal case, the host side uses Alice's key, and Hammer side users
// Bob's key.
class PairTest : public testing::Test {
 public:
  void SetUp() override {
    // Make the request payload with Alice's key pair and the nonce.
    PairChallengeRequest fake_request;
    CheckMemcpy(
        fake_request.public_key, X25519_PUBLIC_VALUE_LEN, tv_.alice_public_);
    CheckMemcpy(fake_request.nonce, kHMACNonceLength, tv_.nonce_);
    request_payload_.assign(reinterpret_cast<const char*>(&fake_request),
                            sizeof(fake_request));

    // Always generate the request with Alice's key pair and the nonce.
    EXPECT_CALL(pair_manager_, GenerateChallenge(_, _))
        .WillRepeatedly(SetChallengeRequest(
            tv_.alice_public_, tv_.alice_private_, tv_.nonce_));
  }

 protected:
  MockPairManager pair_manager_;
  MockDBusWrapper dbus_wrapper_;
  std::string request_payload_;
  TestVector tv_;
  MockFirmwareUpdater fw_updater_;
};

// Hammer returns a valid response.
TEST_F(PairTest, ChallengePassed) {
  EXPECT_CALL(fw_updater_,
              SendSubcommandReceiveResponse(UpdateExtraCommand::kPairChallenge,
                                            request_payload_,
                                            _,
                                            sizeof(PairChallengeResponse)))
      .WillOnce(SetChallengeResponse(EcResponseStatus::kSuccess,
                                     tv_.bob_public_,
                                     tv_.authenticator_,
                                     true));
  EXPECT_CALL(dbus_wrapper_,
              SendSignalWithArgHelper(kPairChallengeSucceededSignal,
                                      tv_.bob_public_));
  EXPECT_EQ(pair_manager_.PairChallenge(&fw_updater_, &dbus_wrapper_),
            ChallengeStatus::kChallengePassed);
}

// Hammer returns an invalid response. The correct response should contain Bob's
// public key but it returns Alice's public key.
TEST_F(PairTest, ChallengeFailed) {
  EXPECT_CALL(fw_updater_,
              SendSubcommandReceiveResponse(UpdateExtraCommand::kPairChallenge,
                                            request_payload_,
                                            _,
                                            sizeof(PairChallengeResponse)))
      .WillOnce(SetChallengeResponse(EcResponseStatus::kSuccess,
                                     tv_.alice_public_,
                                     tv_.authenticator_,
                                     true));
  EXPECT_CALL(dbus_wrapper_, SendSignal(kPairChallengeFailedSignal));
  EXPECT_EQ(pair_manager_.PairChallenge(&fw_updater_, &dbus_wrapper_),
            ChallengeStatus::kChallengeFailed);
}

// Hammer only returns the kUnavailable status.
TEST_F(PairTest, ChallengeNeedInjectEntropy) {
  EXPECT_CALL(fw_updater_,
              SendSubcommandReceiveResponse(UpdateExtraCommand::kPairChallenge,
                                            request_payload_,
                                            _,
                                            sizeof(PairChallengeResponse)))
      .WillOnce(SetChallengeResponse(EcResponseStatus::kUnavailable,
                                     std::vector<uint8_t>(),
                                     std::vector<uint8_t>(),
                                     false));
  EXPECT_EQ(pair_manager_.PairChallenge(&fw_updater_, &dbus_wrapper_),
            ChallengeStatus::kNeedInjectEntropy);
}

// Hammer only returns the other error status.
TEST_F(PairTest, ChallengeUnknownError) {
  EXPECT_CALL(fw_updater_,
              SendSubcommandReceiveResponse(UpdateExtraCommand::kPairChallenge,
                                            request_payload_,
                                            _,
                                            sizeof(PairChallengeResponse)))
      .WillOnce(SetChallengeResponse(EcResponseStatus::kInvalidParam,
                                     std::vector<uint8_t>(),
                                     std::vector<uint8_t>(),
                                     false));
  EXPECT_CALL(dbus_wrapper_, SendSignal(kPairChallengeFailedSignal));
  EXPECT_EQ(pair_manager_.PairChallenge(&fw_updater_, &dbus_wrapper_),
            ChallengeStatus::kUnknownError);
}
}  // namespace hammerd
