// Copyright 2015 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 "trunks/session_manager_impl.h"

#include <cstring>
#include <vector>

#include <base/logging.h>
#include <base/strings/string_number_conversions.h>
#include <gmock/gmock.h>
#include <gtest/gtest.h>

#include "trunks/error_codes.h"
#include "trunks/mock_tpm.h"
#include "trunks/mock_tpm_cache.h"
#include "trunks/tpm_generated.h"
#include "trunks/trunks_factory_for_test.h"

using testing::_;
using testing::DoAll;
using testing::NiceMock;
using testing::Return;
using testing::SetArgPointee;

namespace {

// TODO(b/150264096): create a shared HexDecode in libhwsec and use that in this
// file instead.
void HexDecode(const char* hex, size_t expected_length, void* out) {
  std::vector<uint8_t> bytes;
  CHECK(base::HexStringToBytes(hex, &bytes));
  CHECK_EQ(bytes.size(), expected_length);
  memcpy(out, bytes.data(), expected_length);
}

}  // namespace

namespace trunks {

class SessionManagerTest : public testing::Test {
 public:
  SessionManagerTest() : session_manager_(factory_) {
  }
  ~SessionManagerTest() override {}

  void SetUp() override {
    factory_.set_tpm(&mock_tpm_);
    factory_.set_tpm_cache(&mock_tpm_cache_);
  }

  void SetHandle(TPM_HANDLE handle) {
    session_manager_.session_handle_ = handle;
  }

  TPM2B_PUBLIC_KEY_RSA GetValidRSAPublicKey() {
    const char kValidModulus[] =
        "A1D50D088994000492B5F3ED8A9C5FC8772706219F4C063B2F6A8C6B74D3AD6B"
        "212A53D01DABB34A6261288540D420D3BA59ED279D859DE6227A7AB6BD88FADD"
        "FC3078D465F4DF97E03A52A587BD0165AE3B180FE7B255B7BEDC1BE81CB1383F"
        "E9E46F9312B1EF28F4025E7D332E33F4416525FEB8F0FC7B815E8FBB79CDABE6"
        "327B5A155FEF13F559A7086CB8A543D72AD6ECAEE2E704FF28824149D7F4E393"
        "D3C74E721ACA97F7ADBE2CCF7B4BCC165F7380F48065F2C8370F25F066091259"
        "D14EA362BAF236E3CD8771A94BDEDA3900577143A238AB92B6C55F11DEFAFB31"
        "7D1DC5B6AE210C52B008D87F2A7BFF6EB5C4FB32D6ECEC6505796173951A3167";
    TPM2B_PUBLIC_KEY_RSA rsa;
    rsa.size = 256;
    HexDecode(kValidModulus, rsa.size, rsa.buffer);
    return rsa;
  }

  TPMS_ECC_POINT GetValidEccPoint() {
    const char kEccPublicX[] =
        "C833DFF9E3A01C28CB3256572FA7B133ADE6B71C98BBA2EFD7C236A5659C619C";
    const char kEccPublicY[] =
        "831CFF0AFBAFF18307FDCDB12E50AB73F4DE7A5869A1EA388F38F19AF3BF5324";
    TPMS_ECC_POINT point;

    point.x.size = kEccKeySize;
    point.y.size = kEccKeySize;
    HexDecode(kEccPublicX, point.x.size, point.x.buffer);
    HexDecode(kEccPublicY, point.y.size, point.y.buffer);

    return point;
  }

 protected:
  TrunksFactoryForTest factory_;
  NiceMock<MockTpm> mock_tpm_;
  NiceMock<MockTpmCache> mock_tpm_cache_;

  // TODO(b/150265750): Create MockHmacAuthorizationDelegate and add unit tests
  // for the RSA and ECC session secret generation workflow.
  HmacAuthorizationDelegate delegate_;
  SessionManagerImpl session_manager_;
};

TEST_F(SessionManagerTest, CloseSessionSuccess) {
  TPM_HANDLE handle = TPM_RH_FIRST;
  SetHandle(handle);
  EXPECT_CALL(mock_tpm_, FlushContextSync(handle, nullptr))
      .WillOnce(Return(TPM_RC_SUCCESS));
  session_manager_.CloseSession();
}

TEST_F(SessionManagerTest, CloseSessionNoHandle) {
  TPM_HANDLE handle = kUninitializedHandle;
  SetHandle(handle);
  EXPECT_CALL(mock_tpm_, FlushContextSync(handle, nullptr)).Times(0);
  session_manager_.CloseSession();
}

TEST_F(SessionManagerTest, GetSessionHandleTest) {
  TPM_HANDLE handle = TPM_RH_FIRST;
  EXPECT_EQ(kUninitializedHandle, session_manager_.GetSessionHandle());
  SetHandle(handle);
  EXPECT_EQ(handle, session_manager_.GetSessionHandle());
}

TEST_F(SessionManagerTest, StartRsaSessionSuccess) {
  TPM_SE session_type = TPM_SE_TRIAL;
  TPMT_PUBLIC public_area;
  public_area.type = TPM_ALG_RSA;
  public_area.unique.rsa = GetValidRSAPublicKey();
  EXPECT_CALL(mock_tpm_cache_, GetSaltingKeyPublicArea(_))
      .WillOnce(DoAll(SetArgPointee<0>(public_area), Return(TPM_RC_SUCCESS)));
  TPM_HANDLE handle = TPM_RH_FIRST;
  TPM2B_NONCE nonce;
  nonce.size = 20;
  EXPECT_CALL(mock_tpm_, StartAuthSessionSyncShort(_, handle, _, _,
                                                   session_type, _, _, _, _, _))
      .WillOnce(DoAll(SetArgPointee<8>(nonce), Return(TPM_RC_SUCCESS)));
  EXPECT_EQ(TPM_RC_SUCCESS, session_manager_.StartSession(
                                session_type, handle, "", true, false,
                                &delegate_));
}

TEST_F(SessionManagerTest, StartEccSessionSuccess) {
  TPM_SE session_type = TPM_SE_TRIAL;
  TPMT_PUBLIC public_area;
  public_area.type = TPM_ALG_ECC;
  public_area.name_alg = TPM_ALG_SHA256;
  public_area.unique.ecc = GetValidEccPoint();
  EXPECT_CALL(mock_tpm_cache_, GetSaltingKeyPublicArea(_))
      .WillOnce(DoAll(SetArgPointee<0>(public_area), Return(TPM_RC_SUCCESS)));
  TPM_HANDLE handle = TPM_RH_FIRST;
  TPM2B_NONCE nonce;
  nonce.size = 20;
  EXPECT_CALL(mock_tpm_, StartAuthSessionSyncShort(_, handle, _, _,
                                                   session_type, _, _, _, _, _))
      .WillOnce(DoAll(SetArgPointee<8>(nonce), Return(TPM_RC_SUCCESS)));
  EXPECT_EQ(session_manager_.StartSession(session_type, handle, "", true, false,
                                          &delegate_),
            TPM_RC_SUCCESS);
}

TEST_F(SessionManagerTest, StartSessionGetSaltingKeyError) {
  EXPECT_CALL(mock_tpm_cache_, GetSaltingKeyPublicArea(_))
      .WillOnce(Return(TPM_RC_FAILURE));
  EXPECT_EQ(session_manager_.StartSession(TPM_SE_TRIAL, TPM_RH_NULL, "", true,
                                          false, &delegate_),
            TPM_RC_FAILURE);
}

TEST_F(SessionManagerTest, StartSessionBadSaltingKey) {
  TPMT_PUBLIC public_area;
  public_area.type = TPM_ALG_RSA;
  public_area.unique.rsa.size = 32;
  EXPECT_CALL(mock_tpm_cache_, GetSaltingKeyPublicArea(_))
      .WillOnce(DoAll(SetArgPointee<0>(public_area), Return(TPM_RC_SUCCESS)));
  EXPECT_EQ(TRUNKS_RC_SESSION_SETUP_ERROR,
            session_manager_.StartSession(TPM_SE_TRIAL, TPM_RH_NULL, "",
                                          true, false, &delegate_));

  public_area.type = TPM_ALG_ECC;
  public_area.unique.ecc.x.size = 1;
  public_area.unique.ecc.y.size = 1;
  EXPECT_CALL(mock_tpm_cache_, GetSaltingKeyPublicArea(_))
      .WillOnce(DoAll(SetArgPointee<0>(public_area), Return(TPM_RC_SUCCESS)));
  EXPECT_EQ(TRUNKS_RC_SESSION_SETUP_ERROR,
            session_manager_.StartSession(TPM_SE_TRIAL, TPM_RH_NULL, "",
                                          true, false, &delegate_));
}

TEST_F(SessionManagerTest, StartSessionFailure) {
  TPMT_PUBLIC public_area;
  public_area.type = TPM_ALG_RSA;
  public_area.unique.rsa = GetValidRSAPublicKey();
  EXPECT_CALL(mock_tpm_cache_, GetSaltingKeyPublicArea(_))
      .WillOnce(DoAll(SetArgPointee<0>(public_area), Return(TPM_RC_SUCCESS)));
  EXPECT_CALL(mock_tpm_,
              StartAuthSessionSyncShort(_, TPM_RH_NULL, _, _, _, _, _, _, _, _))
      .WillOnce(Return(TPM_RC_FAILURE));
  EXPECT_EQ(TPM_RC_FAILURE,
            session_manager_.StartSession(TPM_SE_TRIAL, TPM_RH_NULL, "",
                                          true, false, &delegate_));
}

TEST_F(SessionManagerTest, StartSessionBadNonce) {
  TPM_SE session_type = TPM_SE_TRIAL;
  TPMT_PUBLIC public_area;
  public_area.type = TPM_ALG_RSA;
  public_area.unique.rsa = GetValidRSAPublicKey();
  EXPECT_CALL(mock_tpm_cache_, GetSaltingKeyPublicArea(_))
      .WillOnce(DoAll(SetArgPointee<0>(public_area), Return(TPM_RC_SUCCESS)));
  TPM_HANDLE handle = TPM_RH_FIRST;
  TPM2B_NONCE nonce;
  nonce.size = 0;
  EXPECT_CALL(mock_tpm_, StartAuthSessionSyncShort(_, handle, _, _,
                                                   session_type, _, _, _, _, _))
      .WillOnce(DoAll(SetArgPointee<8>(nonce), Return(TPM_RC_SUCCESS)));
  EXPECT_EQ(TPM_RC_FAILURE, session_manager_.StartSession(
                                session_type, handle, "", true, false,
                                &delegate_));
}

}  // namespace trunks
