// Copyright 2014 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/tpm_handle.h"

#include <fcntl.h>
#include <unistd.h>

#include <base/callback.h>
#include <base/check_op.h>
#include <base/logging.h>
#include <base/posix/eintr_wrapper.h>
#include <base/threading/platform_thread.h>
#include <base/time/time.h>

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

namespace trunks {

namespace {

const char kTpmDevice[] = "/dev/tpm0";
const uint32_t kTpmBufferSize = 4096;
const int kInvalidFileDescriptor = -1;

// Retry parameters for opening /dev/tpm0.
// How long do we wait after the first try?
constexpr base::TimeDelta kInitialRetry = base::TimeDelta::FromSecondsD(0.1);
// When we retry the next time, how much longer do we wait?
constexpr double kRetryMultiplier = 2.0;
// How many times to retry?
constexpr int kMaxRetry = 5;
// Total of 4 wait time between 5 retries.
// sum 0.1*2^k for k = 0 to 3 = 1.5s
// Note that if this period is not enough, upstart will still respawn trunksd
// after it all fall through.

TPM_CC GetCommandCode(const std::string& command) {
  std::string buffer = command;
  TPM_ST tag;
  UINT32 command_size;
  TPM_CC command_code = 0;
  // Parse the header to get the command code
  TPM_RC rc = Parse_TPM_ST(&buffer, &tag, nullptr);
  DCHECK_EQ(rc, TPM_RC_SUCCESS);
  rc = Parse_UINT32(&buffer, &command_size, nullptr);
  DCHECK_EQ(rc, TPM_RC_SUCCESS);
  rc = Parse_TPM_CC(&buffer, &command_code, nullptr);
  DCHECK_EQ(rc, TPM_RC_SUCCESS);
  return command_code;
}

TPM_RC GetResponseCode(const std::string& response) {
  std::string buffer = response;
  TPM_ST tag;
  UINT32 response_size;
  TPM_RC response_code = 0;
  // Parse the header to get the command code
  TPM_RC rc = Parse_TPM_ST(&buffer, &tag, nullptr);
  DCHECK_EQ(rc, TPM_RC_SUCCESS);
  rc = Parse_UINT32(&buffer, &response_size, nullptr);
  DCHECK_EQ(rc, TPM_RC_SUCCESS);
  rc = Parse_TPM_RC(&buffer, &response_code, nullptr);
  DCHECK_EQ(rc, TPM_RC_SUCCESS);
  return response_code;
}

}  // namespace

TpmHandle::TpmHandle() : fd_(kInvalidFileDescriptor) {}

TpmHandle::~TpmHandle() {
  int result = IGNORE_EINTR(close(fd_));
  if (result == -1) {
    PLOG(ERROR) << "TPM: couldn't close " << kTpmDevice;
  }
  LOG(INFO) << "TPM: " << kTpmDevice << " closed successfully";
}

bool TpmHandle::Init() {
  if (fd_ != kInvalidFileDescriptor) {
    VLOG(1) << "Tpm already initialized.";
    return true;
  }
  base::TimeDelta current_wait = kInitialRetry;
  for (int i = 0; i < kMaxRetry; i++) {
    fd_ = HANDLE_EINTR(open(kTpmDevice, O_RDWR));
    if (fd_ == kInvalidFileDescriptor) {
      PLOG(ERROR) << "TPM: Error opening tpm0 file descriptor at "
                  << kTpmDevice;
      if (i == kMaxRetry - 1) {
        // If we get here, it doesn't work.
        return false;
      }
      base::PlatformThread::Sleep(current_wait);
      current_wait = current_wait * kRetryMultiplier;
      continue;
    }
    LOG(INFO) << "TPM: " << kTpmDevice << " opened successfully";
    break;
  }
  return true;
}

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

std::string TpmHandle::SendCommandAndWait(const std::string& command) {
  std::string response;
  TPM_RC result = SendCommandInternal(command, &response);
  if (result != TPM_RC_SUCCESS) {
    response = CreateErrorResponse(result);
    // Send the command code and system uptime of the first timeout command
    if (errno == ETIME) {
      static bool has_reported = false;
      if (!has_reported) {
        TrunksMetrics metrics;
        TPM_CC command_code = GetCommandCode(command);
        if (metrics.ReportTpmHandleTimeoutCommandAndTime(result, command_code))
          has_reported = true;
      }
    }
  }
  TPM_RC response_code = GetResponseCode(response);
  if (response_code != TPM_RC_SUCCESS) {
    TrunksMetrics metrics;
    metrics.ReportTpmErrorCode(response_code);
  }
  return response;
}

TPM_RC TpmHandle::SendCommandInternal(const std::string& command,
                                      std::string* response) {
  CHECK_NE(fd_, kInvalidFileDescriptor);
  int result = HANDLE_EINTR(write(fd_, command.data(), command.length()));
  if (result < 0 && errno == EREMOTEIO) {
    // Retry once in case the error is caused by late wakeup from sleep.
    // Repeated error should lead to failure.
    LOG(WARNING) << "TPM: Retrying write after Remote I/O error.";
    result = HANDLE_EINTR(write(fd_, command.data(), command.length()));
  }
  if (result < 0) {
    PLOG(ERROR) << "TPM: Error writing to TPM handle.";
    return TRUNKS_RC_WRITE_ERROR;
  }
  if (static_cast<size_t>(result) != command.length()) {
    LOG(ERROR) << "TPM: Error writing to TPM handle: " << result << " vs "
               << command.length();
    return TRUNKS_RC_WRITE_ERROR;
  }
  char response_buf[kTpmBufferSize];
  result = HANDLE_EINTR(read(fd_, response_buf, kTpmBufferSize));
  if (result < 0) {
    PLOG(ERROR) << "TPM: Error reading from TPM handle.";
    return TRUNKS_RC_READ_ERROR;
  }
  response->assign(response_buf, static_cast<size_t>(result));
  return TPM_RC_SUCCESS;
}

}  // namespace trunks
