// Copyright 2016 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/firmware_management_parameters.h"

#include <arpa/inet.h>
#include <limits.h>
#include <stdint.h>

#include <string>
#include <vector>

#include <base/logging.h>
#include <base/strings/string_split.h>
#include <brillo/secure_blob.h>
#include <openssl/sha.h>

#include "cryptohome/cryptolib.h"

extern "C" {
#include "cryptohome/crc8.h"
}

using brillo::SecureBlob;

namespace {
const uint32_t kNvramVersionV1_0 = 0x10;
}

namespace cryptohome {

// Defines the raw NVRAM contents.
struct FirmwareManagementParametersRawV1_0 {
  uint8_t crc;
  uint8_t struct_size;
  // Data after this is covered by the crc
  uint8_t struct_version;  // Set to kNvramVersionV1_0
  uint8_t reserved0;
  uint32_t flags;
  uint8_t developer_key_hash[SHA256_DIGEST_LENGTH];
} __attribute__((packed));


// Index must match firmware; see README.firmware_management_parameters
const uint32_t FirmwareManagementParameters::kNvramIndex = 0x100a;
const uint32_t FirmwareManagementParameters::kNvramBytes =
  sizeof(struct FirmwareManagementParametersRawV1_0);
const uint32_t FirmwareManagementParameters::kCrcDataOffset = 2;

FirmwareManagementParameters::FirmwareManagementParameters(Tpm* tpm)
  : tpm_(tpm),
    raw_(new FirmwareManagementParametersRawV1_0()) {
}

FirmwareManagementParameters::~FirmwareManagementParameters() {
}

bool FirmwareManagementParameters::TpmIsReady() const {
  if (!tpm_) {
    LOG(ERROR) << "TpmIsReady: no tpm_ instance.";
    return false;
  }
  if (!tpm_->IsEnabled()) {
    LOG(ERROR) << "TpmIsReady: is not enabled.";
    return false;
  }
  if (!tpm_->IsOwned()) {
    LOG(ERROR) << "TpmIsReady: is not owned.";
    return false;
  }
  return true;
}

bool FirmwareManagementParameters::HasAuthorization() const {
  if (!TpmIsReady()) {
    LOG(ERROR) << "HasAuthorization: TPM not ready.";
    return false;
  }
  // Need owner password to create or destroy NVRAM spaces
  brillo::Blob owner_password;
  if (tpm_->GetOwnerPassword(&owner_password) && owner_password.size() != 0) {
    return true;
  }
  LOG(INFO) << "HasAuthorization: TPM Owner password not available.";
  return false;
}

bool FirmwareManagementParameters::Destroy(void) {
  if (!HasAuthorization()) {
    LOG(ERROR) << "Destroy() called with insufficient authorization.";
    return false;
  }

  // Only destroy the space if it exists
  if (tpm_->IsNvramDefined(kNvramIndex) && !tpm_->DestroyNvram(kNvramIndex)) {
    return false;
  }

  loaded_ = false;
  return true;
}

bool FirmwareManagementParameters::Create(void) {
  uint32_t nvram_bytes;

  // Make sure we have what we need now.
  if (!HasAuthorization()) {
    LOG(ERROR) << "Create() called with insufficient authorization.";
    return false;
  }
  if (!Destroy()) {
    LOG(ERROR) << "Failed to destroy Firmware Management Parameters data "
      "before creation.";
    return false;
  }

  nvram_bytes = kNvramBytes;

  // Use a WriteDefine space with no PCR0 locking
  if (!tpm_->DefineNvram(kNvramIndex, nvram_bytes,
                         Tpm::kTpmNvramWriteDefine |
                             Tpm::kTpmNvramFirmwareReadable)) {
    LOG(ERROR) << "Create() failed to defined NVRAM space.";
    return false;
  }

  LOG(INFO) << "Firmware Management Parameters created.";
  return true;
}

bool FirmwareManagementParameters::Load(void) {
  if (loaded_) {
    return true;
  }

  if (!tpm_->IsNvramDefined(kNvramIndex)) {
    LOG(INFO) << "Load() called with no NVRAM space defined.";
    return false;
  }

  SecureBlob nvram_data(0);
  if (!tpm_->ReadNvram(kNvramIndex, &nvram_data)) {
    LOG(ERROR) << "Load() could not read from NVRAM space.";
    return false;
  }

  // Make sure we've read enough data for a 1.0 struct
  unsigned int nvram_size = nvram_data.size();
  if (nvram_size < kNvramBytes) {
    LOG(ERROR) << "Load() found unexpected NVRAM size: " << nvram_size;
    return false;
  }

  // Copy the raw data
  memcpy(raw_.get(), nvram_data.data(), kNvramBytes);

  // Verify the size
  if (raw_->struct_size != nvram_size) {
    LOG(ERROR) << "Load() found unexpected NVRAM size: " << nvram_size;
    return false;
  }

  // Verify the CRC
  uint8_t crc = crc8(nvram_data.data() + kCrcDataOffset,
                     nvram_size - kCrcDataOffset);
  if (crc != raw_->crc) {
    LOG(ERROR) << "Load() got bad CRC";
    return false;
  }

  // We are a 1.0 reader, so we can read 1.x structs
  if ((raw_->struct_version >> 4) != (kNvramVersionV1_0 >> 4)) {
    LOG(ERROR) << "Load() got incompatible NVRAM version: "
               << (unsigned int)raw_->struct_version;
    return false;
  }
  // We don't need to check minor version, because all 1.x structs are
  // compatible with us

  DLOG(INFO) << "Load() successfully loaded NVRAM data.";
  loaded_ = true;
  return true;
}

bool FirmwareManagementParameters::Store(uint32_t flags,
                                 const brillo::Blob* developer_key_hash) {
  if (!TpmIsReady()) {
    LOG(ERROR) << "Store() called when TPM was not ready!";
    return false;
  }

  // Ensure we have the space ready.
  if (!tpm_->IsNvramDefined(kNvramIndex)) {
    LOG(ERROR) << "Store() called with no NVRAM space.";
    return false;
  }
  if (tpm_->IsNvramLocked(kNvramIndex)) {
    LOG(ERROR) << "Store() called with a locked NVRAM space.";
    return false;
  }

  // Check defined NVRAM size.
  unsigned int nvram_size = tpm_->GetNvramSize(kNvramIndex);
  if (nvram_size != kNvramBytes) {
    LOG(ERROR) << "Store() found unexpected NVRAM size " << nvram_size << ".";
    return false;
  }

  // Reset the NVRAM contents
  loaded_ = false;
  memset(raw_.get(), 0, kNvramBytes);
  raw_->struct_size = kNvramBytes;
  raw_->struct_version = kNvramVersionV1_0;
  raw_->flags = flags;

  // Store the hash, if any
  if (developer_key_hash) {
    // Make sure hash is the right size
    if ((developer_key_hash->size() != sizeof(raw_->developer_key_hash))) {
      LOG(ERROR) << "Store() called with bad hash size "
                 << developer_key_hash->size() << ".";
      return false;
    }

    memcpy(raw_->developer_key_hash, developer_key_hash->data(),
           sizeof(raw_->developer_key_hash));
  }

  // Recalculate the CRC
  const uint8_t *raw8 = reinterpret_cast<uint8_t*>(raw_.get());
  raw_->crc = crc8(raw8 + kCrcDataOffset,
                   raw_->struct_size - kCrcDataOffset);

  // Write the data to nvram
  SecureBlob nvram_data(raw_->struct_size);
  memcpy(nvram_data.data(), raw_.get(), raw_->struct_size);
  if (!tpm_->WriteNvram(kNvramIndex, nvram_data)) {
    LOG(ERROR) << "Store() failed to write to NVRAM";
    return false;
  }

  // Lock nvram index for writing.
  if (!tpm_->WriteLockNvram(kNvramIndex)) {
    LOG(ERROR) << "Store() failed to lock the NVRAM space";
    return false;
  }

  // Ensure the space is now locked.
  if (!tpm_->IsNvramLocked(kNvramIndex)) {
    LOG(ERROR) << "NVRAM space did not lock as expected.";
    return false;
  }

  loaded_ = true;
  return true;
}

bool FirmwareManagementParameters::GetFlags(uint32_t* flags) {
  CHECK(flags);

  // Load if needed
  if (!Load()) {
    return false;
  }

  *flags = raw_->flags;
  return true;
}

bool FirmwareManagementParameters::GetDeveloperKeyHash(brillo::Blob* hash) {
  CHECK(hash);

  // Load if needed
  if (!Load()) {
    return false;
  }

  hash->resize(sizeof(raw_->developer_key_hash));
  memcpy(hash->data(), raw_->developer_key_hash, hash->size());
  return true;
}

}  // namespace cryptohome
