// 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_, NULL);
  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,
                                                NULL);  // 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 NULL for the authorization
  // delegate.
  TPM_RC result = factory_.GetTpm()->ReadPublicSync(kSaltingKey,
                                                    "",  // SaltingKey name.
                                                    &public_data,
                                                    &out_name,
                                                    &qualified_name,
                                                    NULL);  // 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,
                                   NULL);
  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
