// 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.
//
// FuzzedCommanTransceiver is a test transceiver for fuzzing TPM commands and
// responses.

#include <arpa/inet.h>
#include <cstring>

#include <base/callback.h>

#include "trunks/fuzzed_command_transceiver.h"
#include "trunks/tpm_generated.h"

namespace {

// TPM message header size.
constexpr size_t kHeaderSize = 10;
// Probability in % of generating a pure random value or byte stream.
constexpr uint32_t kPureRandomProb = 5;
// Probability in % of generating an error response.
constexpr uint32_t kErrorResponseProb = 20;
// Probability in % of generating a response of minimal size.
constexpr uint32_t kMinimalResponseProb = 80;

std::string BuildHeader(uint16_t tag, uint32_t size, uint32_t code) {
  std::string header;
  trunks::Serialize_uint16_t(tag, &header);
  trunks::Serialize_uint32_t(size, &header);
  trunks::Serialize_uint32_t(code, &header);
  return header;
}

bool ParseHeader(const std::string& command, uint16_t* tag, uint32_t* size,
                 uint32_t* code) {
  std::string header(command, 0, kHeaderSize);
  if (trunks::Parse_uint16_t(&header, tag, nullptr)) {
    return false;
  }
  if (trunks::Parse_uint32_t(&header, size, nullptr)) {
    return false;
  }
  if (trunks::Parse_uint32_t(&header, code, nullptr)) {
    return false;
  }
  return true;
}

}  // namespace

namespace trunks {

FuzzedCommandTransceiver::FuzzedCommandTransceiver(
    base::FuzzedDataProvider* const data_provider, size_t max_message_size)
      : data_provider_(data_provider), max_message_size_(max_message_size) {
  CHECK(data_provider);
}

void FuzzedCommandTransceiver::SendCommand(
    const std::string& command,
    const ResponseCallback& callback) {
  callback.Run(SendCommandAndWait(command));
}

std::string FuzzedCommandTransceiver::SendCommandAndWait(
    const std::string& command) {
  return ConsumeResponseForCommand(command);
}

std::string FuzzedCommandTransceiver::ConsumeCommand() {
  // With low probability return a completely random message.
  if (ConsumeBoolWithProbability(kPureRandomProb)) {
    return ConsumeRandomMessage();
  }

  // Build a valid message.
  uint16_t tag = ConsumeCommandTag();
  uint32_t code = ConsumeCommandCode();
  std::string handles = ConsumeHandles(GetNumberOfRequestHandles(code));
  std::string payload = ConsumePayload(kHeaderSize + handles.size());

  return BuildHeader(tag, kHeaderSize + handles.size() + payload.size(),
                     code) + handles + payload;
}

std::string FuzzedCommandTransceiver::ConsumeResponseForCommand(
    const std::string& command) {
  // With low probability return a completely random message.
  if (ConsumeBoolWithProbability(kPureRandomProb)) {
    return ConsumeRandomMessage();
  }

  // Parse command, use defaults in case of parsing errors.
  uint16_t cmd_tag = TPM_ST_NO_SESSIONS;
  uint32_t cmd_code = TPM_CC_FIRST;
  uint32_t cmd_size = 0;
  ParseHeader(command, &cmd_tag, &cmd_size, &cmd_code);

  // Decide if we want to return an error or success.
  uint32_t resp_code;
  std::string handles;
  if (ConsumeBoolWithProbability(kErrorResponseProb)) {
    resp_code = ConsumeResponseCode();
  } else {
    resp_code = TPM_RC_SUCCESS;
    handles = ConsumeHandles(GetNumberOfResponseHandles(cmd_code));
  }

  // Error or success, with high probability return response of minimal size.
  std::string payload;
  if (!ConsumeBoolWithProbability(kMinimalResponseProb)) {
    payload = ConsumePayload(kHeaderSize + handles.size());
  }

  return BuildHeader(cmd_tag, kHeaderSize + handles.size() + payload.size(),
                     resp_code) + handles + payload;
}

uint32_t FuzzedCommandTransceiver::ConsumeCommandCode() {
  // Decide between realistic and purely random value.
  if (ConsumeBoolWithProbability(kPureRandomProb)) {
    return ConsumeUint32();
  }
  return data_provider_->ConsumeUint32InRange(TPM_CC_FIRST, TPM_CC_LAST);
}

uint32_t FuzzedCommandTransceiver::ConsumeResponseCode() {
  // Decide between realistic and purely random value.
  if (ConsumeBoolWithProbability(kPureRandomProb)) {
    return ConsumeUint32();
  }
  uint32_t rc = data_provider_->ConsumeUint32InRange(0, 0xFFF);
  if (data_provider_->ConsumeBool()) {
    // Generate WARN or FMT0 error RC.
    rc &= 0x97F;
  } else {
    // Generate FMT1 error RC.
    rc |= RC_FMT1;
  }
  return rc;
}

uint16_t FuzzedCommandTransceiver::ConsumeCommandTag() {
  // Decide between realistic and purely random value.
  if (ConsumeBoolWithProbability(kPureRandomProb)) {
    return data_provider_->ConsumeUint16();
  }
  if (data_provider_->ConsumeBool()) {
    return TPM_ST_SESSIONS;
  }
  return TPM_ST_NO_SESSIONS;
}

std::string FuzzedCommandTransceiver::ConsumeHandles(size_t qnt_handles) {
  std::string handles;
  for (; qnt_handles > 0; --qnt_handles) {
    Serialize_uint32_t(ConsumeHandle(), &handles);
  }
  return handles;
}

uint32_t FuzzedCommandTransceiver::ConsumeHandle() {
  uint32_t handle = ConsumeUint32();
  // Decide between realistic and purely random value.
  if (!ConsumeBoolWithProbability(kPureRandomProb)) {
    handle &= 0xC3000003u;
  }
  return handle;
}

std::string FuzzedCommandTransceiver::ConsumePayload(size_t pre_payload_size) {
    if (max_message_size_ <= pre_payload_size) {
      return std::string();
    }
    return data_provider_->ConsumeRandomLengthString(
        max_message_size_ - pre_payload_size);
}

bool FuzzedCommandTransceiver::ConsumeBoolWithProbability(
    uint32_t probability) {
  return data_provider_->ConsumeUint32InRange(0, 99) < probability;
}

std::string FuzzedCommandTransceiver::ConsumeRandomMessage() {
  return data_provider_->ConsumeRandomLengthString(max_message_size_);
}

uint32_t FuzzedCommandTransceiver::ConsumeUint32() {
  return data_provider_->ConsumeUint32InRange(0, 0xFFFFFFFFu);
}

}  // namespace trunks
