//
// Copyright (C) 2014 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//

#include <string>

#include <gtest/gtest.h>

#include "trunks/hmac_authorization_delegate.h"

namespace trunks {

TEST(HmacAuthorizationDelegateTest, UninitializedSessionTest) {
  HmacAuthorizationDelegate delegate;
  std::string dummy;
  std::string p_hash("test");
  EXPECT_FALSE(delegate.GetCommandAuthorization(p_hash, false, false, &dummy));
  EXPECT_EQ(0u, dummy.size());
  EXPECT_FALSE(delegate.CheckResponseAuthorization(p_hash, dummy));
  EXPECT_FALSE(delegate.EncryptCommandParameter(&dummy));
  EXPECT_FALSE(delegate.DecryptResponseParameter(&dummy));
}

TEST(HmacAuthorizationDelegateTest, SessionKeyTest) {
  HmacAuthorizationDelegate delegate;
  TPM2B_NONCE nonce;
  nonce.size = kAesKeySize;
  memset(nonce.buffer, 0, nonce.size);
  TPM_HANDLE dummy_handle = HMAC_SESSION_FIRST;
  EXPECT_TRUE(delegate.InitSession(dummy_handle, nonce, nonce, std::string(),
                                   std::string(), false));
  EXPECT_EQ(0u, delegate.session_key_.size());

  std::string dummy_auth = std::string("authorization");
  std::string dummy_salt = std::string("salt");
  EXPECT_TRUE(delegate.InitSession(dummy_handle, nonce, nonce, dummy_salt,
                                   dummy_auth, false));
  EXPECT_EQ(kHashDigestSize, delegate.session_key_.size());
  // TODO(usanghi): Use TCG TPM2.0 test vectors when available.
  std::string expected_key(
      "\xfb\x2f\x3c\x33\x65\x3e\xdc\x47"
      "\xda\xbe\x4e\xb7\xf4\x6c\x19\x4d"
      "\xea\x50\xb2\x11\x54\x45\x32\x73"
      "\x47\x38\xef\xb3\x4a\x82\x29\x94",
      kHashDigestSize);
  EXPECT_EQ(0, expected_key.compare(delegate.session_key_));
}

TEST(HmacAuthorizationDelegateTest, EncryptDecryptTest) {
  HmacAuthorizationDelegate delegate;
  std::string plaintext_parameter("parameter");
  std::string encrypted_parameter(plaintext_parameter);
  // Test with session not initialized.
  EXPECT_FALSE(delegate.EncryptCommandParameter(&encrypted_parameter));
  EXPECT_FALSE(delegate.DecryptResponseParameter(&encrypted_parameter));
  // Test with encryption not enabled.
  TPM_HANDLE dummy_handle = HMAC_SESSION_FIRST;
  TPM2B_NONCE nonce;
  nonce.size = kAesKeySize;
  std::string salt("salt");
  ASSERT_TRUE(delegate.InitSession(dummy_handle, nonce, nonce, salt,
                                   std::string(), false));
  EXPECT_TRUE(delegate.EncryptCommandParameter(&encrypted_parameter));
  EXPECT_EQ(0, plaintext_parameter.compare(encrypted_parameter));
  EXPECT_TRUE(delegate.DecryptResponseParameter(&encrypted_parameter));
  EXPECT_EQ(0, plaintext_parameter.compare(encrypted_parameter));
  // Test with encryption enabled.
  ASSERT_TRUE(delegate.InitSession(dummy_handle, nonce, nonce, salt,
                                   std::string(), true));
  EXPECT_TRUE(delegate.EncryptCommandParameter(&encrypted_parameter));
  EXPECT_NE(0, plaintext_parameter.compare(encrypted_parameter));
  // Calling EncryptCommandParameter regenerated the caller_nonce.
  // We need to manually switch tpm_nonce and caller_nonce to ensure
  // that DecryptResponseParameter has the correct nonces.
  delegate.tpm_nonce_ = delegate.caller_nonce_;
  delegate.caller_nonce_ = nonce;
  EXPECT_TRUE(delegate.DecryptResponseParameter(&encrypted_parameter));
  EXPECT_EQ(0, plaintext_parameter.compare(encrypted_parameter));
}

class HmacAuthorizationDelegateFixture : public testing::Test {
 public:
  HmacAuthorizationDelegateFixture() {}
  ~HmacAuthorizationDelegateFixture() override {}

  void SetUp() override {
    session_handle_ = HMAC_SESSION_FIRST;
    session_nonce_.size = kAesKeySize;
    memset(session_nonce_.buffer, 0, kAesKeySize);
    ASSERT_TRUE(delegate_.InitSession(session_handle_,
                                      session_nonce_,  // TPM nonce.
                                      session_nonce_,  // Caller nonce.
                                      std::string(),   // Salt.
                                      std::string(),   // Bind auth value.
                                      false));         // Enable encryption.
  }

 protected:
  TPM_HANDLE session_handle_;
  TPM2B_NONCE session_nonce_;
  HmacAuthorizationDelegate delegate_;
};

TEST_F(HmacAuthorizationDelegateFixture, NonceRegenerationTest) {
  ASSERT_TRUE(delegate_.InitSession(session_handle_,
                                    session_nonce_,  // TPM nonce.
                                    session_nonce_,  // Caller nonce.
                                    std::string(),   // Salt.
                                    std::string(),   // Bind auth value.
                                    true));          // Enable encryption.
  TPM2B_NONCE original_nonce = session_nonce_;
  EXPECT_EQ(delegate_.caller_nonce_.size, original_nonce.size);
  EXPECT_EQ(0, memcmp(delegate_.caller_nonce_.buffer, original_nonce.buffer,
                      original_nonce.size));
  // First we check that performing GetCommandAuthorization resets the nonce.
  std::string command_hash;
  std::string authorization;
  TPMS_AUTH_COMMAND auth_command;
  EXPECT_TRUE(delegate_.GetCommandAuthorization(command_hash, false, false,
                                                &authorization));
  EXPECT_EQ(TPM_RC_SUCCESS,
            Parse_TPMS_AUTH_COMMAND(&authorization, &auth_command, nullptr));
  EXPECT_EQ(delegate_.caller_nonce_.size, original_nonce.size);
  EXPECT_EQ(auth_command.nonce.size, original_nonce.size);
  EXPECT_NE(0, memcmp(delegate_.caller_nonce_.buffer, original_nonce.buffer,
                      original_nonce.size));
  EXPECT_EQ(0, memcmp(delegate_.caller_nonce_.buffer, auth_command.nonce.buffer,
                      auth_command.nonce.size));
  // Now we check that GetCommandAuthorization does not reset nonce
  // when EncryptCommandParameter is called first.
  original_nonce = delegate_.caller_nonce_;
  std::string parameter;
  EXPECT_TRUE(delegate_.EncryptCommandParameter(&parameter));
  EXPECT_EQ(delegate_.caller_nonce_.size, original_nonce.size);
  EXPECT_NE(0, memcmp(delegate_.caller_nonce_.buffer, original_nonce.buffer,
                      original_nonce.size));
  EXPECT_TRUE(delegate_.nonce_generated_);
  original_nonce = delegate_.caller_nonce_;
  EXPECT_TRUE(delegate_.GetCommandAuthorization(command_hash, false, false,
                                                &authorization));
  EXPECT_EQ(TPM_RC_SUCCESS,
            Parse_TPMS_AUTH_COMMAND(&authorization, &auth_command, nullptr));
  EXPECT_EQ(delegate_.caller_nonce_.size, original_nonce.size);
  EXPECT_EQ(auth_command.nonce.size, original_nonce.size);
  EXPECT_EQ(0, memcmp(delegate_.caller_nonce_.buffer, original_nonce.buffer,
                      original_nonce.size));
  EXPECT_EQ(0, memcmp(delegate_.caller_nonce_.buffer, auth_command.nonce.buffer,
                      auth_command.nonce.size));
}

TEST_F(HmacAuthorizationDelegateFixture, CommandAuthTest) {
  std::string command_hash;
  std::string authorization;
  EXPECT_TRUE(delegate_.GetCommandAuthorization(command_hash, false, false,
                                                &authorization));
  TPMS_AUTH_COMMAND auth_command;
  std::string auth_bytes;
  EXPECT_EQ(TPM_RC_SUCCESS, Parse_TPMS_AUTH_COMMAND(
                                &authorization, &auth_command, &auth_bytes));
  EXPECT_EQ(auth_command.session_handle, session_handle_);
  EXPECT_EQ(auth_command.nonce.size, session_nonce_.size);
  EXPECT_EQ(kContinueSession, auth_command.session_attributes);
  EXPECT_EQ(kHashDigestSize, auth_command.hmac.size);
}

TEST_F(HmacAuthorizationDelegateFixture, ResponseAuthTest) {
  TPMS_AUTH_RESPONSE auth_response;
  auth_response.session_attributes = kContinueSession;
  auth_response.nonce.size = kAesKeySize;
  memset(auth_response.nonce.buffer, 0, kAesKeySize);
  auth_response.hmac.size = kHashDigestSize;
  // TODO(usanghi): Use TCG TPM2.0 test vectors when available.
  uint8_t hmac_buffer[kHashDigestSize] = {
      0x37, 0x69, 0xaf, 0x12, 0xff, 0x4d, 0xbf, 0x44, 0xe5, 0x16, 0xa2,
      0x2d, 0x1d, 0x05, 0x12, 0xe8, 0xbc, 0x42, 0x51, 0x6d, 0x59, 0xe8,
      0xbf, 0x40, 0x1e, 0xa3, 0x46, 0xa4, 0xd6, 0x0d, 0xcc, 0xf7};
  memcpy(auth_response.hmac.buffer, hmac_buffer, kHashDigestSize);
  std::string response_hash;
  std::string authorization;
  EXPECT_EQ(TPM_RC_SUCCESS,
            Serialize_TPMS_AUTH_RESPONSE(auth_response, &authorization));
  EXPECT_TRUE(
      delegate_.CheckResponseAuthorization(response_hash, authorization));
}

TEST_F(HmacAuthorizationDelegateFixture, SessionAttributes) {
  const uint8_t kDecryptSession = 1 << 5;
  const uint8_t kEncryptSession = 1 << 6;

  // Encryption disabled and not possible for command.
  std::string authorization;
  EXPECT_TRUE(delegate_.GetCommandAuthorization(std::string(), false, false,
                                                &authorization));
  TPMS_AUTH_COMMAND auth_command;
  std::string auth_bytes;
  EXPECT_EQ(TPM_RC_SUCCESS, Parse_TPMS_AUTH_COMMAND(
                                &authorization, &auth_command, &auth_bytes));
  EXPECT_EQ(kContinueSession, auth_command.session_attributes);

  // Encryption disabled and possible for command.
  EXPECT_TRUE(delegate_.GetCommandAuthorization(std::string(), true, true,
                                                &authorization));
  EXPECT_EQ(TPM_RC_SUCCESS, Parse_TPMS_AUTH_COMMAND(
                                &authorization, &auth_command, &auth_bytes));
  EXPECT_EQ(kContinueSession, auth_command.session_attributes);

  // Encryption enabled and not possible for command.
  ASSERT_TRUE(delegate_.InitSession(session_handle_,
                                    session_nonce_,  // TPM nonce.
                                    session_nonce_,  // Caller nonce.
                                    std::string(),   // Salt.
                                    std::string(),   // Bind auth value.
                                    true));          // Enable encryption.
  EXPECT_TRUE(delegate_.GetCommandAuthorization(std::string(), false, false,
                                                &authorization));
  EXPECT_EQ(TPM_RC_SUCCESS, Parse_TPMS_AUTH_COMMAND(
                                &authorization, &auth_command, &auth_bytes));
  EXPECT_EQ(kContinueSession, auth_command.session_attributes);

  // Encryption enabled and possible only for command input.
  EXPECT_TRUE(delegate_.GetCommandAuthorization(std::string(), true, false,
                                                &authorization));
  EXPECT_EQ(TPM_RC_SUCCESS, Parse_TPMS_AUTH_COMMAND(
                                &authorization, &auth_command, &auth_bytes));
  EXPECT_EQ(kContinueSession | kDecryptSession,
            auth_command.session_attributes);

  // Encryption enabled and possible only for command output.
  EXPECT_TRUE(delegate_.GetCommandAuthorization(std::string(), false, true,
                                                &authorization));
  EXPECT_EQ(TPM_RC_SUCCESS, Parse_TPMS_AUTH_COMMAND(
                                &authorization, &auth_command, &auth_bytes));
  EXPECT_EQ(kContinueSession | kEncryptSession,
            auth_command.session_attributes);

  // Encryption enabled and possible for command input and output.
  EXPECT_TRUE(delegate_.GetCommandAuthorization(std::string(), true, true,
                                                &authorization));
  EXPECT_EQ(TPM_RC_SUCCESS, Parse_TPMS_AUTH_COMMAND(
                                &authorization, &auth_command, &auth_bytes));
  EXPECT_EQ(kContinueSession | kEncryptSession | kDecryptSession,
            auth_command.session_attributes);
}

}  // namespace trunks
