// 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 <string>

#include <base/logging.h>
#include <base/stl_util.h>
#include <crypto/scoped_openssl_types.h>
#include <openssl/err.h>
#include <openssl/rand.h>
#include <openssl/rsa.h>

#include "trunks/error_codes.h"
#include "trunks/tpm_generated.h"
#include "trunks/tpm_utility.h"

namespace {
const size_t kWellKnownExponent = 0x10001;
}  // namespace

namespace trunks {

SessionManagerImpl::SessionManagerImpl(const TrunksFactory& factory)
    : factory_(factory),
      session_handle_(kUninitializedHandle) {}

SessionManagerImpl::~SessionManagerImpl() {
  CloseSession();
}

void SessionManagerImpl::CloseSession() {
  if (session_handle_ == kUninitializedHandle) {
    return;
  }
  TPM_RC result = factory_.GetTpm()->FlushContextSync(session_handle_, nullptr);
  if (result != TPM_RC_SUCCESS) {
    LOG(WARNING) << "Error closing tpm session: " << GetErrorString(result);
  }
  session_handle_ = kUninitializedHandle;
}

TPM_RC SessionManagerImpl::StartSession(
    TPM_SE session_type,
    TPMI_DH_ENTITY bind_entity,
    const std::string& bind_authorization_value,
    bool enable_encryption,
    HmacAuthorizationDelegate* delegate) {
  CHECK(delegate);
  // If we already have an active session, close it.
  CloseSession();

  std::string salt(SHA1_DIGEST_SIZE, 0);
  unsigned char* salt_buffer =
      reinterpret_cast<unsigned char*>(string_as_array(&salt));
  CHECK_EQ(RAND_bytes(salt_buffer, salt.size()), 1)
      << "Error generating a cryptographically random salt.";
  // First we enccrypt the cryptographically secure salt using PKCS1_OAEP
  // padded RSA public key encryption. This is specified in TPM2.0
  // Part1 Architecture, Appendix B.10.2.
  std::string encrypted_salt;
  TPM_RC salt_result = EncryptSalt(salt, &encrypted_salt);
  if (salt_result != TPM_RC_SUCCESS) {
    LOG(ERROR) << "Error encrypting salt.";
    return salt_result;
  }

  TPM2B_ENCRYPTED_SECRET encrypted_secret =
      Make_TPM2B_ENCRYPTED_SECRET(encrypted_salt);
  // Then we use TPM2_StartAuthSession to start a HMAC session with the TPM.
  // The tpm returns the tpm_nonce and the session_handle referencing the
  // created session.
  TPMI_ALG_HASH hash_algorithm = TPM_ALG_SHA256;
  TPMT_SYM_DEF symmetric_algorithm;
  symmetric_algorithm.algorithm = TPM_ALG_AES;
  symmetric_algorithm.key_bits.aes = 128;
  symmetric_algorithm.mode.aes = TPM_ALG_CFB;

  TPM2B_NONCE nonce_caller;
  TPM2B_NONCE nonce_tpm;
  // We use sha1_digest_size here because that is the minimum length
  // needed for the nonce.
  nonce_caller.size = SHA1_DIGEST_SIZE;
  CHECK_EQ(RAND_bytes(nonce_caller.buffer, nonce_caller.size), 1)
      << "Error generating a cryptographically random nonce.";

  Tpm* tpm = factory_.GetTpm();
  // The TPM2 command below needs no authorization. This is why we can use
  // the empty string "", when referring to the handle names for the salting
  // key and the bind entity.
  TPM_RC tpm_result = tpm->StartAuthSessionSync(kSaltingKey,
                                                "",  // salt_handle_name.
                                                bind_entity,
                                                "",  // bind_entity_name.
                                                nonce_caller,
                                                encrypted_secret,
                                                session_type,
                                                symmetric_algorithm,
                                                hash_algorithm,
                                                &session_handle_,
                                                &nonce_tpm,
                                                nullptr);  // No Authorization.
  if (tpm_result) {
    LOG(ERROR) << "Error creating an authorization session: "
               << GetErrorString(tpm_result);
    return tpm_result;
  }
  bool hmac_result = delegate->InitSession(
    session_handle_,
    nonce_tpm,
    nonce_caller,
    salt,
    bind_authorization_value,
    enable_encryption);
  if (!hmac_result) {
    LOG(ERROR) << "Failed to initialize an authorization session delegate.";
    return TPM_RC_FAILURE;
  }
  return TPM_RC_SUCCESS;
}

TPM_RC SessionManagerImpl::EncryptSalt(const std::string& salt,
                                       std::string* encrypted_salt) {
  TPM2B_NAME out_name;
  TPM2B_NAME qualified_name;
  TPM2B_PUBLIC public_data;
  public_data.public_area.unique.rsa.size = 0;
  // The TPM2 Command below needs no authorization. Therefore we can simply
  // use the empty string for all the Key names, and pullptr for the
  // authorization delegate.
  TPM_RC result = factory_.GetTpm()->ReadPublicSync(
      kSaltingKey, "",  // SaltingKey name.
      &public_data, &out_name, &qualified_name, nullptr);  // No authorization
  if (result != TPM_RC_SUCCESS) {
    LOG(ERROR) << "Error fetching salting key public info.";
    return result;
  }
  crypto::ScopedRSA salting_rsa(RSA_new());
  salting_rsa.get()->e = BN_new();
  if (!salting_rsa.get()->e) {
    LOG(ERROR) << "Error creating exponent for RSA.";
    return TPM_RC_FAILURE;
  }
  BN_set_word(salting_rsa.get()->e, kWellKnownExponent);
  salting_rsa.get()->n = BN_bin2bn(public_data.public_area.unique.rsa.buffer,
                                   public_data.public_area.unique.rsa.size,
                                   nullptr);
  if (!salting_rsa.get()->n) {
    LOG(ERROR) << "Error setting public area of rsa key.";
    return TPM_RC_FAILURE;
  }
  // Label for RSAES-OAEP. Defined in TPM2.0 Part1 Architecture,
  // Appendix B.10.2.
  unsigned char oaep_param[7] = {'S', 'E', 'C', 'R', 'E', 'T', '\0'};
  std::string padded_input(RSA_size(salting_rsa.get()), 0);
  int rsa_result = RSA_padding_add_PKCS1_OAEP(
      reinterpret_cast<unsigned char*>(string_as_array(&padded_input)),
      padded_input.size(),
      reinterpret_cast<const unsigned char*>(salt.c_str()),
      salt.size(),
      oaep_param,
      arraysize(oaep_param));
  if (!rsa_result) {
    unsigned long err = ERR_get_error();  // NOLINT openssl types
    ERR_load_ERR_strings();
    ERR_load_crypto_strings();
    LOG(ERROR) << "EncryptSalt Error: " << err
               << ": " << ERR_lib_error_string(err)
               << ", " << ERR_func_error_string(err)
               << ", " << ERR_reason_error_string(err);
    return TPM_RC_FAILURE;
  }
  encrypted_salt->resize(padded_input.size());
  rsa_result = RSA_public_encrypt(
      padded_input.size(),
      reinterpret_cast<unsigned char*>(string_as_array(&padded_input)),
      reinterpret_cast<unsigned char*>(string_as_array(encrypted_salt)),
      salting_rsa.get(),
      RSA_NO_PADDING);
  if (rsa_result == -1) {
    unsigned long err = ERR_get_error();  // NOLINT openssl types
    ERR_load_ERR_strings();
    ERR_load_crypto_strings();
    LOG(ERROR) << "EncryptSalt Error: " << err
               << ": " << ERR_lib_error_string(err)
               << ", " << ERR_func_error_string(err)
               << ", " << ERR_reason_error_string(err);
    return TPM_RC_FAILURE;
  }
  return TPM_RC_SUCCESS;
}

}  // namespace trunks
