// Copyright 2020 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 "hwsec-test-utils/fake_pca_agent/tpm1_struct_utils.h"

#include <memory>
#include <string>

#include <arpa/inet.h>
#include <base/hash/sha1.h>
#include <base/memory/free_deleter.h>
#include <base/optional.h>
#include <base/sys_byteorder.h>
#include <crypto/scoped_openssl_types.h>
#include <trousers/trousers.h>
#include <trousers/tss.h>

#include "hwsec-test-utils/common/openssl_utility.h"

#define TPM_LOG(severity, result)                               \
  LOG(severity) << "TPM error 0x" << std::hex << result << " (" \
                << Trspi_Error_String(result) << "): "

namespace hwsec_test_utils {
namespace fake_pca_agent {

namespace {

constexpr int kWellKnownExponent = 65537;
constexpr int kExpectedPcrLength = 20;

// The implementation of attestation service always selects 16 bits.
constexpr int kSelectBitmapSize = 2;

}  // namespace

crypto::ScopedEVP_PKEY TpmPublicKeyToEVP(
    const std::string& serialized_tpm_pubkey, std::string* public_key_digest) {
  // Parse the serialized TPM_PUBKEY.
  UINT64 offset = 0;
  TPM_PUBKEY parsed = {};
  TSS_RESULT result = Trspi_UnloadBlob_PUBKEY_s(
      &offset,
      reinterpret_cast<BYTE*>(const_cast<char*>(serialized_tpm_pubkey.data())),
      serialized_tpm_pubkey.length(), &parsed);
  if (result != TSS_SUCCESS) {
    TPM_LOG(ERROR, result) << "Failed to parse TPM_PUBKEY.";
    return nullptr;
  }

  // Prevent memory leak.
  std::unique_ptr<BYTE, base::FreeDeleter> scoped_key(parsed.pubKey.key);
  std::unique_ptr<BYTE, base::FreeDeleter> scoped_parms(
      parsed.algorithmParms.parms);
  if (offset != serialized_tpm_pubkey.length()) {
    LOG(ERROR) << "Found garbage data after the TPM_PUBKEY.";
    return nullptr;
  }
  TPM_RSA_KEY_PARMS parms;
  UINT64 parms_offset = 0;
  result = Trspi_UnloadBlob_RSA_KEY_PARMS_s(
      &parms_offset, parsed.algorithmParms.parms,
      parsed.algorithmParms.parmSize, &parms);
  if (TPM_ERROR(result)) {
    TPM_LOG(ERROR, result) << "Failed to parse RSA_KEY_PARMS.";
    return nullptr;
  }
  if (parms_offset != parsed.algorithmParms.parmSize) {
    LOG(ERROR) << "Find garbage data after the TPM_PUBKEY.";
    return nullptr;
  }
  std::unique_ptr<BYTE, base::FreeDeleter> scoped_exponent(parms.exponent);
  crypto::ScopedRSA rsa(RSA_new());
  if (!rsa) {
    LOG(ERROR) << "Failed to allocate RSA: " << GetOpenSSLError();
    return nullptr;
  }
  crypto::ScopedBIGNUM e(BN_new()), n(BN_new());
  if (!e || !n) {
    LOG(ERROR) << "Failed to allocate RSA or BIGNUM.";
    return nullptr;
  }

  // Get the public exponent.
  if (parms.exponentSize == 0) {
    if (!BN_set_word(e.get(), kWellKnownExponent)) {
      LOG(ERROR) << "Failed to set exponent to WellKnownExponent.";
      return nullptr;
    }
  } else {
    if (!BN_bin2bn(parms.exponent, parms.exponentSize, e.get())) {
      LOG(ERROR) << "Failed to convert exponent to BIGNUM.";
      return nullptr;
    }
  }
  // Get the modulus.
  if (!BN_bin2bn(parsed.pubKey.key, parsed.pubKey.keyLength, n.get())) {
    LOG(ERROR) << "Failed to convert public key to BIGNUM.";
    return nullptr;
  }
  if (!RSA_set0_key(rsa.get(), n.release(), e.release(), nullptr)) {
    LOG(ERROR) << ": Failed to set exponent or modulus.";
    return nullptr;
  }
  crypto::ScopedEVP_PKEY key(EVP_PKEY_new());
  if (!key) {
    LOG(ERROR) << ": Failed to call EVP_PKEY_new: " << GetOpenSSLError();
    return nullptr;
  }
  if (EVP_PKEY_set1_RSA(key.get(), rsa.get()) != 1) {
    LOG(ERROR) << ": Failed to call EVP_PKEY_set1_RSA: " << GetOpenSSLError();
    return nullptr;
  }
  // Calculate the public key digest if needed.
  if (public_key_digest != nullptr) {
    *public_key_digest = base::SHA1HashString(std::string(
        parsed.pubKey.key, parsed.pubKey.key + parsed.pubKey.keyLength));
  }

  return key;
}

std::string ToPcrComposite(uint32_t pcr_index, const std::string& pcr_value) {
  // Unfortunately trousers doesn't provide useful helpers to do this so we have
  // to do it here.
  CHECK_EQ(pcr_value.length(), kExpectedPcrLength);
  struct __attribute__((packed)) {
    // Corresponding to TPM_PCR_SELECTION.sizeOfSelect.
    uint16_t select_size{htons(kSelectBitmapSize)};
    // Corresponding to TPM_PCR_SELECTION.pcrSelect.
    uint8_t select_bitmap[kSelectBitmapSize];
    // Corresponding to  TPM_PCR_COMPOSITE.valueSize.
    uint32_t value_size{htonl(kExpectedPcrLength)};
  } composite_header = {0};
  static_assert(sizeof(composite_header) ==
                    sizeof(uint16_t) + kSelectBitmapSize + sizeof(uint32_t),
                "Expect no padding between composite struct.");

  // Sets upt the bitmap.
  composite_header.select_bitmap[pcr_index / 8] = 1 << (pcr_index % 8);

  composite_header.select_size = (htons(2u));
  composite_header.select_bitmap[pcr_index / 8] = 1 << (pcr_index % 8);
  composite_header.value_size = htonl(pcr_value.length());

  const char* composite_header_buffer =
      reinterpret_cast<const char*>(&composite_header);
  return std::string(composite_header_buffer, sizeof(composite_header)) +
         pcr_value;
}

std::string Serialize(TPM_ASYM_CA_CONTENTS* contents) {
  std::unique_ptr<BYTE[]> blob(
      std::make_unique<BYTE[]>(sizeof(*contents) + contents->sessionKey.size));
  UINT64 offset = 0;
  Trspi_LoadBlob_ASYM_CA_CONTENTS(&offset, blob.get(), contents);
  return std::string(blob.get(), blob.get() + offset);
}

std::string Serialize(TPM_SYM_CA_ATTESTATION* contents) {
  std::unique_ptr<BYTE[]> blob(
      std::make_unique<BYTE[]>(sizeof(*contents) + contents->credSize));
  UINT64 offset = 0;
  Trspi_LoadBlob_SYM_CA_ATTESTATION(&offset, blob.get(), contents);
  return std::string(blob.get(), blob.get() + offset);
}

base::Optional<std::string> ParseDigestFromTpmCertifyInfo(
    const std::string& serialized) {
  TPM_CERTIFY_INFO parsed{};
  uint64_t offset = 0;
  TSS_RESULT result = Trspi_UnloadBlob_CERTIFY_INFO(
      &offset, reinterpret_cast<BYTE*>(const_cast<char*>(serialized.data())),
      &parsed);
  if (result != TSS_SUCCESS) {
    TPM_LOG(ERROR, result) << "Failed to parse TPM_CERTIFY_INFO.";
    return {};
  }

  // Prevent memory leak.
  std::unique_ptr<BYTE, base::FreeDeleter> scoped_key(
      parsed.algorithmParms.parms);
  return std::string(
      parsed.pubkeyDigest.digest,
      parsed.pubkeyDigest.digest + sizeof(parsed.pubkeyDigest.digest));
}

}  // namespace fake_pca_agent
}  // namespace hwsec_test_utils
