// Copyright 2018 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 "cryptohome/mount_encrypted/tlcl_stub.h"

#include <algorithm>

#include <base/logging.h>

#include <openssl/sha.h>

#include <vboot/tlcl.h>

#include <brillo/secure_blob.h>

#include "cryptohome/cryptolib.h"
#include "cryptohome/mount_encrypted/tpm.h"

namespace {

#if !USE_TPM2

const uint8_t kEndorsementKeyModulus[] = {
    0xde, 0x3b, 0x6a, 0x3c, 0x55, 0xe0, 0x9f, 0x81, 0x67, 0xeb, 0xa6, 0x31,
    0x93, 0x88, 0xa7, 0xcd, 0xf6, 0xea, 0x7d, 0x25, 0x7c, 0x61, 0x9c, 0x52,
    0xfc, 0xa4, 0x96, 0x91, 0xd2, 0x87, 0x9a, 0x17, 0xc4, 0x88, 0x06, 0x9e,
    0x14, 0x01, 0xc8, 0x11, 0x0b, 0x5b, 0x86, 0xae, 0x60, 0x39, 0x5d, 0xb2,
    0x16, 0x4e, 0x8a, 0x92, 0x26, 0x8e, 0xbe, 0x9f, 0xdb, 0x02, 0xe9, 0x64,
    0xe6, 0xbd, 0x49, 0x2b, 0x8f, 0xda, 0x7d, 0xea, 0xbd, 0x80, 0x1d, 0xbc,
    0xc0, 0x7b, 0x68, 0x2b, 0xf4, 0xb6, 0xa4, 0x45, 0xf6, 0x94, 0xca, 0x16,
    0x4d, 0x1f, 0xbb, 0x86, 0xe2, 0x31, 0xc4, 0xf4, 0xa4, 0xa1, 0x06, 0xf3,
    0x12, 0x17, 0xa9, 0xbd, 0x61, 0xd2, 0x47, 0x70, 0x87, 0x05, 0x21, 0x0b,
    0x14, 0x96, 0x89, 0xb4, 0x8c, 0x57, 0x80, 0x7d, 0xed, 0xc9, 0x13, 0x2c,
    0xc2, 0xb3, 0xb4, 0x8f, 0x49, 0xd5, 0xfd, 0x9c, 0x32, 0x3e, 0x07, 0x7a,
    0xd5, 0xdc, 0xdc, 0x59, 0xa7, 0x6a, 0xc4, 0xaf, 0xbb, 0xe0, 0x46, 0x65,
    0x40, 0x16, 0x1c, 0x95, 0xb1, 0xea, 0xdd, 0x7e, 0x78, 0x1c, 0x61, 0x6f,
    0x3a, 0x57, 0xc5, 0x81, 0xea, 0x03, 0x5e, 0x7b, 0xe6, 0x3e, 0xbc, 0x9e,
    0x79, 0x38, 0xfd, 0x46, 0xd9, 0x2c, 0xa0, 0x59, 0xf0, 0xd5, 0x55, 0xe3,
    0x65, 0xa2, 0xda, 0xd1, 0xc4, 0x98, 0x15, 0xbd, 0x1d, 0x3a, 0x8a, 0xc9,
    0x93, 0xea, 0x33, 0x99, 0x45, 0xd7, 0x7b, 0x4f, 0x1b, 0x3b, 0xb0, 0x97,
    0xbf, 0x07, 0xe1, 0x4b, 0x14, 0xd4, 0x96, 0x98, 0x5a, 0x65, 0x74, 0xbb,
    0xce, 0x62, 0xeb, 0xca, 0xdc, 0x29, 0x4d, 0x3f, 0xbb, 0x8b, 0x26, 0xb1,
    0x8d, 0xad, 0x8e, 0x67, 0xc3, 0x11, 0xdd, 0xeb, 0x1a, 0xf2, 0xff, 0x0c,
    0x1a, 0x49, 0xa0, 0x66, 0x9d, 0x83, 0x39, 0xf0, 0x0d, 0x53, 0x86, 0x38,
    0x72, 0x26, 0xd1, 0xb7,
};

const size_t kMaxDelegationFamilyTableSize = 8;

#endif  // !USE_TPM2

const uint8_t kVersionVendorSpecific[] = {
    0x04, 0x20, 0x03, 0x6f, 0x00, 0x74, 0x70,
    0x6d, 0x33, 0x38, 0xff, 0xff, 0xff,
};

}  // namespace

TlclStub* TlclStub::g_instance = nullptr;

TlclStub::TlclStub() {
  g_instance = this;
}

TlclStub::~TlclStub() {
  g_instance = nullptr;
}

TlclStub::NvramSpaceData* TlclStub::GetSpace(uint32_t index) {
  return &nvram_spaces_[index];
}

void TlclStub::SetOwned(const std::vector<uint8_t>& owner_auth) {
  owner_auth_ = owner_auth;
}

bool TlclStub::IsOwned() {
  return !owner_auth_.empty();
}

void TlclStub::Clear() {
  owner_auth_.clear();
  pcr_values_.clear();
#if !USE_TPM2
  delegation_family_id_ = 0;
  delegation_family_table_.clear();
#endif
}

void TlclStub::Reset() {
  for (auto& entry : nvram_spaces_) {
    entry.second.read_locked = false;
    entry.second.write_locked = false;
  }
}

void TlclStub::SetPCRValue(uint32_t index,
                           const uint8_t value[TPM_PCR_DIGEST]) {
  memcpy(pcr_values_[index], value, TPM_PCR_DIGEST);
}

TlclStub* TlclStub::Get() {
  CHECK(g_instance);
  return g_instance;
}

uint32_t TlclStub::GetOwnership(uint8_t* owned) {
  *owned = is_owned();
  return TPM_SUCCESS;
}

uint32_t TlclStub::GetRandom(uint8_t* data, uint32_t length, uint32_t* size) {
  memset(data, '0x5a', length);
  *size = length;
  return TPM_SUCCESS;
}

uint32_t TlclStub::DefineSpace(uint32_t index, uint32_t perm, uint32_t size) {
  return DefineSpaceEx(nullptr, 0, index, perm, size, nullptr, 0);
}

uint32_t TlclStub::DefineSpaceEx(const uint8_t* owner_auth,
                                 uint32_t owner_auth_size,
                                 uint32_t index,
                                 uint32_t perm,
                                 uint32_t size,
                                 const void* auth_policy,
                                 uint32_t auth_policy_size) {
  bool authenticated = false;

#if USE_TPM2
  // NVRAM space creation in normal mode only works as long as the TPM isn't
  // owned yet. Only non-existing spaces can be defined.
  authenticated = !is_owned() && nvram_spaces_.count(index) == 0;
#else
  std::vector<uint8_t> in_auth(owner_auth, owner_auth + owner_auth_size);
  authenticated = is_owned() && in_auth == owner_auth_;
#endif

  if (!authenticated) {
    return TPM_E_AUTHFAIL;
  }

  nvram_spaces_[index] = NvramSpaceData();
  nvram_spaces_[index].attributes = perm;
  if (auth_policy) {
    nvram_spaces_[index].policy.resize(auth_policy_size);
    memcpy(nvram_spaces_[index].policy.data(), auth_policy, auth_policy_size);
  } else {
    nvram_spaces_[index].policy.clear();
  }
  nvram_spaces_[index].contents.resize(size);

  return TPM_SUCCESS;
}

uint32_t TlclStub::GetPermissions(uint32_t index, uint32_t* permissions) {
  return WithSpace(index, [=](NvramSpaceData* space) {
    *permissions = space->attributes;
    return TPM_SUCCESS;
  });
}

uint32_t TlclStub::GetSpaceInfo(uint32_t index,
                                uint32_t* permissions,
                                uint32_t* size,
                                void* auth_policy,
                                uint32_t* auth_policy_size) {
  return WithSpace(index, [=](NvramSpaceData* space) {
    if (space->policy.size() > *auth_policy_size) {
      *auth_policy_size = space->policy.size();
      return TPM_E_BUFFER_SIZE;
    }

    *permissions = space->attributes;
    *size = space->contents.size();
    memcpy(auth_policy, space->policy.data(), space->policy.size());
    *auth_policy_size = space->policy.size();
    return TPM_SUCCESS;
  });
}

uint32_t TlclStub::Write(uint32_t index, const void* data, uint32_t length) {
  return WithSpace(index, [=](NvramSpaceData* space) {
    if (length > space->contents.size()) {
      return TPM_E_INTERNAL_ERROR;  // should be TPM_NOSPACE
    }
    if (space->write_locked) {
      return TPM_E_INTERNAL_ERROR;  // should be TPM_AREA_LOCKED
    }
    memcpy(space->contents.data(), data, length);
#if USE_TPM2
    space->attributes |= TPMA_NV_WRITTEN;
#endif
    return TPM_SUCCESS;
  });
}

uint32_t TlclStub::Read(uint32_t index, void* data, uint32_t length) {
  return WithSpace(index, [=](NvramSpaceData* space) {
#if USE_TPM2
    if ((space->attributes & TPMA_NV_WRITTEN) != TPMA_NV_WRITTEN) {
      return TPM_E_INTERNAL_ERROR;  // should be TPM_RC_NV_UNINITIALIZED
    }
#endif
    if (length > space->contents.size()) {
      return TPM_E_INTERNAL_ERROR;  // should be TPM_NOSPACE
    }
    if (space->read_locked) {
      return TPM_E_INTERNAL_ERROR;  // should be TPM_AREA_LOCKED
    }
    memcpy(data, space->contents.data(),
           std::min(space->contents.size(), static_cast<size_t>(length)));
    return TPM_SUCCESS;
  });
}

uint32_t TlclStub::WriteLock(uint32_t index) {
  return WithSpace(index, [=](NvramSpaceData* space) {
    if (space->write_locked) {
      return TPM_E_INTERNAL_ERROR;  // should be TPM_AREA_LOCKED
    }
    space->write_locked = true;
    return TPM_SUCCESS;
  });
}

uint32_t TlclStub::ReadLock(uint32_t index) {
  return WithSpace(index, [=](NvramSpaceData* space) {
    if (space->read_locked) {
      return TPM_E_INTERNAL_ERROR;  // should be TPM_AREA_LOCKED
    }
    space->read_locked = true;
    return TPM_SUCCESS;
  });
}

uint32_t TlclStub::PCRRead(uint32_t index, void *data, uint32_t length) {
  if (length < TPM_PCR_DIGEST) {
    return TPM_E_BUFFER_SIZE;
  }

  auto entry = pcr_values_.find(index);
  if (entry != pcr_values_.end()) {
    memcpy(data, entry->second, TPM_PCR_DIGEST);
  } else {
    memset(data, 0, TPM_PCR_DIGEST);
  }

  return TPM_SUCCESS;
}

uint32_t TlclStub::GetVersion(uint32_t* vendor, uint64_t* firmware_version,
                        uint8_t* vendor_specific_buf,
                        size_t* vendor_specific_buf_size) {
  if (*vendor_specific_buf_size < sizeof(kVersionVendorSpecific)) {
    return TPM_E_BUFFER_SIZE;
  }

  *vendor = 0x49465800;
  *firmware_version = 0x420;
  memcpy(vendor_specific_buf, kVersionVendorSpecific,
         sizeof(kVersionVendorSpecific));
  *vendor_specific_buf_size = sizeof(kVersionVendorSpecific);

  return TPM_SUCCESS;
}

uint32_t TlclStub::IFXFieldUpgradeInfo(TPM_IFX_FIELDUPGRADEINFO *info) {
  memset(info, 0, sizeof(*info));
  return TPM_SUCCESS;
}

#if !USE_TPM2

uint32_t TlclStub::ReadPubek(uint32_t* public_exponent,
                             uint8_t* modulus,
                             uint32_t* modulus_size) {
  if (*modulus_size < sizeof(kEndorsementKeyModulus)) {
    return TPM_E_BUFFER_SIZE;
  }
  *public_exponent = 2^16 - 1;
  memcpy(modulus, kEndorsementKeyModulus, sizeof(kEndorsementKeyModulus));
  *modulus_size = sizeof(kEndorsementKeyModulus);
  return TPM_SUCCESS;
}

uint32_t TlclStub::TakeOwnership(uint8_t enc_owner_auth[TPM_RSA_2048_LEN],
                                 uint8_t enc_srk_auth[TPM_RSA_2048_LEN],
                                 uint8_t owner_auth[TPM_AUTH_DATA_LEN]) {
  if (is_owned()) {
    return TPM_E_OWNER_SET;
  }

  // We'd ideally decrypt the secrets here to validate that they're correctly
  // encrypted and match |owner_auth_|, but this doesn't the additional coverage
  // we'd get is not worth the effort right now.
  owner_auth_.assign(owner_auth, owner_auth + TPM_AUTH_DATA_LEN);

  return TPM_SUCCESS;
}

uint32_t TlclStub::CreateDelegationFamily(uint8_t family_label) {
  if (is_owned()) {
    return TPM_E_OWNER_SET;
  }

  if (delegation_family_table_.size() >= kMaxDelegationFamilyTableSize) {
    return TPM_E_INTERNAL_ERROR;
  }

  delegation_family_table_.push_back(
      {0, family_label, ++delegation_family_id_, 1, 0});

  return TPM_SUCCESS;
}

uint32_t TlclStub::ReadDelegationFamilyTable(TPM_FAMILY_TABLE_ENTRY* table,
                                             uint32_t* table_size) {
  if (*table_size < delegation_family_table_.size()) {
    return TPM_E_BUFFER_SIZE;
  }

  *table_size = delegation_family_table_.size();
  std::copy(delegation_family_table_.begin(), delegation_family_table_.end(),
            table);

  return TPM_SUCCESS;
}

#endif  // !USE_TPM2

template<typename Action>
uint32_t TlclStub::WithSpace(uint32_t index, Action action) {
  auto entry = nvram_spaces_.find(index);
  if (entry == nvram_spaces_.end()) {
    return TPM_E_BADINDEX;
  }

  return action(&entry->second);
}

extern "C" {

uint32_t TlclLibInit(void) {
  // Check that a stub has been set up.
  CHECK(TlclStub::Get());
  return TPM_SUCCESS;
}

uint32_t TlclLibClose(void) {
  return TPM_SUCCESS;
}

uint32_t TlclGetOwnership(uint8_t* owned) {
  return TlclStub::Get()->GetOwnership(owned);
}

uint32_t TlclGetRandom(uint8_t* data, uint32_t length, uint32_t* size) {
  return TlclStub::Get()->GetRandom(data, length, size);
}

uint32_t TlclDefineSpace(uint32_t index, uint32_t perm, uint32_t size) {
  return TlclStub::Get()->DefineSpace(index, perm, size);
}

uint32_t TlclDefineSpaceEx(const uint8_t* owner_auth,
                           uint32_t owner_auth_size,
                           uint32_t index,
                           uint32_t perm,
                           uint32_t size,
                           const void* auth_policy,
                           uint32_t auth_policy_size) {
  return TlclStub::Get()->DefineSpaceEx(owner_auth, owner_auth_size, index,
                                        perm, size, auth_policy,
                                        auth_policy_size);
}

uint32_t TlclGetPermissions(uint32_t index, uint32_t *permissions) {
  return TlclStub::Get()->GetPermissions(index, permissions);
}

uint32_t TlclGetSpaceInfo(uint32_t index,
                          uint32_t* attributes,
                          uint32_t* size,
                          void* auth_policy,
                          uint32_t* auth_policy_size) {
  return TlclStub::Get()->GetSpaceInfo(index, attributes, size, auth_policy,
                                       auth_policy_size);
}

uint32_t TlclWrite(uint32_t index, const void *data, uint32_t length) {
  return TlclStub::Get()->Write(index, data, length);
}

uint32_t TlclRead(uint32_t index, void *data, uint32_t length) {
  return TlclStub::Get()->Read(index, data, length);
}

uint32_t TlclWriteLock(uint32_t index) {
  return TlclStub::Get()->WriteLock(index);
}

uint32_t TlclReadLock(uint32_t index) {
  return TlclStub::Get()->ReadLock(index);
}

uint32_t TlclPCRRead(uint32_t index, void *data, uint32_t length) {
  return TlclStub::Get()->PCRRead(index, data, length);
}

uint32_t TlclInitNvAuthPolicy(uint32_t pcr_selection_bitmap,
                              const uint8_t pcr_values[][TPM_PCR_DIGEST],
                              void* auth_policy,
                              uint32_t* auth_policy_size) {
  int buffer_size = *auth_policy_size;
  *auth_policy_size = SHA256_DIGEST_LENGTH;
  if (buffer_size < SHA256_DIGEST_LENGTH) {
    return TPM_E_BUFFER_SIZE;
  }

  std::vector<uint8_t> input(32);
  for (int index = 0; index < 32; ++index) {
    input[index] = (pcr_selection_bitmap & (1 << index)) != 0;
    if (input[index]) {
      input.insert(input.end(), *pcr_values, *pcr_values + TPM_PCR_DIGEST);
      ++pcr_values;
    }
  }

  brillo::SecureBlob digest = cryptohome::CryptoLib::Sha256ToSecureBlob(input);
  memcpy(auth_policy, digest.data(), digest.size());
  return TPM_SUCCESS;
}

uint32_t TlclGetVersion(uint32_t* vendor, uint64_t* firmware_version,
                        uint8_t* vendor_specific_buf,
                        size_t* vendor_specific_buf_size) {
  return TlclStub::Get()->GetVersion(
      vendor, firmware_version, vendor_specific_buf, vendor_specific_buf_size);
}

uint32_t TlclIFXFieldUpgradeInfo(TPM_IFX_FIELDUPGRADEINFO *info) {
  return TlclStub::Get()->IFXFieldUpgradeInfo(info);
}

#if !USE_TPM2

uint32_t TlclReadPubek(uint32_t* public_exponent,
                       uint8_t* modulus,
                       uint32_t* modulus_size) {
  return TlclStub::Get()->ReadPubek(public_exponent, modulus, modulus_size);
}

uint32_t TlclTakeOwnership(uint8_t enc_owner_auth[TPM_RSA_2048_LEN],
                           uint8_t enc_srk_auth[TPM_RSA_2048_LEN],
                           uint8_t owner_auth[TPM_AUTH_DATA_LEN]) {
  return TlclStub::Get()->TakeOwnership(enc_owner_auth, enc_srk_auth,
                                        owner_auth);
}

uint32_t TlclCreateDelegationFamily(uint8_t family_label) {
  return TlclStub::Get()->CreateDelegationFamily(family_label);
}

uint32_t TlclReadDelegationFamilyTable(TPM_FAMILY_TABLE_ENTRY *table,
                                       uint32_t* table_size) {
  return TlclStub::Get()->ReadDelegationFamilyTable(table, table_size);
}

#endif  // !USE_TPM2

}  // extern "C"
