// 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/hmac_authorization_delegate.h"

#include <base/logging.h>
#include <base/stl_util.h>
#include <crypto/secure_util.h>
#include <openssl/aes.h>
#include <openssl/hmac.h>
#include <openssl/rand.h>

namespace trunks {

namespace {

const uint32_t kDigestBits = 256;
const uint16_t kNonceMinSize = 16;
const uint16_t kNonceMaxSize = 32;
const uint8_t kDecryptSession = 1 << 5;
const uint8_t kEncryptSession = 1 << 6;
const uint8_t kLabelSize = 4;
const size_t kAesIVSize = 16;
const uint32_t kTpmBufferSize = 4096;

}  // namespace

HmacAuthorizationDelegate::HmacAuthorizationDelegate()
    : session_handle_(0),
      is_parameter_encryption_enabled_(false),
      nonce_generated_(false),
      future_authorization_value_set_(false),
      use_entity_authorization_for_encryption_only_(false) {
  tpm_nonce_.size = 0;
  caller_nonce_.size = 0;
}

HmacAuthorizationDelegate::~HmacAuthorizationDelegate() {}

bool HmacAuthorizationDelegate::GetCommandAuthorization(
    const std::string& command_hash,
    bool is_command_parameter_encryption_possible,
    bool is_response_parameter_encryption_possible,
    std::string* authorization) {
  if (!session_handle_) {
    authorization->clear();
    LOG(ERROR) << "Delegate being used before Initialization,";
    return false;
  }
  TPMS_AUTH_COMMAND auth;
  auth.session_handle = session_handle_;
  if (!nonce_generated_) {
    RegenerateCallerNonce();
  }
  auth.nonce = caller_nonce_;
  auth.session_attributes = kContinueSession;
  if (is_parameter_encryption_enabled_) {
    if (is_command_parameter_encryption_possible) {
      auth.session_attributes |= kDecryptSession;
    }
    if (is_response_parameter_encryption_possible) {
      auth.session_attributes |= kEncryptSession;
    }
  }
  // We reset the |nonce_generated| flag in preparation of the next command.
  nonce_generated_ = false;
  std::string attributes_bytes;
  CHECK_EQ(Serialize_TPMA_SESSION(auth.session_attributes, &attributes_bytes),
           TPM_RC_SUCCESS)
      << "Error serializing session attributes.";

  std::string hmac_data;
  std::string hmac_key;
  if (!use_entity_authorization_for_encryption_only_) {
    hmac_key = session_key_ + entity_authorization_value_;
  } else {
    hmac_key = session_key_;
  }
  hmac_data.append(command_hash);
  hmac_data.append(reinterpret_cast<const char*>(caller_nonce_.buffer),
                   caller_nonce_.size);
  hmac_data.append(reinterpret_cast<const char*>(tpm_nonce_.buffer),
                   tpm_nonce_.size);
  hmac_data.append(attributes_bytes);
  std::string digest = HmacSha256(hmac_key, hmac_data);
  auth.hmac = Make_TPM2B_DIGEST(digest);

  TPM_RC serialize_error = Serialize_TPMS_AUTH_COMMAND(auth, authorization);
  if (serialize_error != TPM_RC_SUCCESS) {
    LOG(ERROR) << "Could not serialize command auth.";
    return false;
  }
  return true;
}

bool HmacAuthorizationDelegate::CheckResponseAuthorization(
    const std::string& response_hash, const std::string& authorization) {
  if (!session_handle_) {
    return false;
  }
  TPMS_AUTH_RESPONSE auth_response;
  std::string mutable_auth_string(authorization);
  TPM_RC parse_error;
  std::string auth_bytes;
  parse_error = Parse_TPMS_AUTH_RESPONSE(&mutable_auth_string, &auth_response,
                                         &auth_bytes);
  if (authorization.size() != auth_bytes.size()) {
    LOG(ERROR) << "Authorization string was of wrong length.";
    return false;
  }
  if (parse_error != TPM_RC_SUCCESS) {
    LOG(ERROR) << "Could not parse authorization response.";
    return false;
  }
  if (!mutable_auth_string.empty()) {
    LOG(ERROR) << "Authorization string was of wrong length.";
    return false;
  }
  if (auth_response.hmac.size != kHashDigestSize) {
    LOG(ERROR) << "TPM auth hmac was incorrect size.";
    return false;
  }
  if (auth_response.nonce.size < kNonceMinSize ||
      auth_response.nonce.size > kNonceMaxSize) {
    LOG(ERROR) << "TPM_nonce is not the correct length.";
    return false;
  }
  tpm_nonce_ = auth_response.nonce;
  std::string attributes_bytes;
  CHECK_EQ(Serialize_TPMA_SESSION(auth_response.session_attributes,
                                  &attributes_bytes),
           TPM_RC_SUCCESS)
      << "Error serializing session attributes.";

  std::string hmac_data;
  std::string hmac_key;
  if (!use_entity_authorization_for_encryption_only_) {
    // In a special case with TPM2_HierarchyChangeAuth, we need to use the
    // auth_value that was set.
    if (future_authorization_value_set_) {
      hmac_key = session_key_ + future_authorization_value_;
      future_authorization_value_set_ = false;
    } else {
      hmac_key = session_key_ + entity_authorization_value_;
    }
  } else {
    hmac_key = session_key_;
  }
  hmac_data.append(response_hash);
  hmac_data.append(reinterpret_cast<const char*>(tpm_nonce_.buffer),
                   tpm_nonce_.size);
  hmac_data.append(reinterpret_cast<const char*>(caller_nonce_.buffer),
                   caller_nonce_.size);
  hmac_data.append(attributes_bytes);
  std::string digest = HmacSha256(hmac_key, hmac_data);
  CHECK_EQ(digest.size(), auth_response.hmac.size);
  if (!crypto::SecureMemEqual(digest.data(), auth_response.hmac.buffer,
                              digest.size())) {
    LOG(ERROR) << "Authorization response hash did not match expected value.";
    return false;
  }
  return true;
}

bool HmacAuthorizationDelegate::EncryptCommandParameter(
    std::string* parameter) {
  CHECK(parameter);
  if (!session_handle_) {
    LOG(ERROR) << __func__ << ": Invalid session handle.";
    return false;
  }
  if (!is_parameter_encryption_enabled_) {
    // No parameter encryption enabled.
    return true;
  }
  if (parameter->size() > kTpmBufferSize) {
    LOG(ERROR) << "Parameter size is too large for TPM decryption.";
    return false;
  }
  RegenerateCallerNonce();
  nonce_generated_ = true;
  AesOperation(parameter, caller_nonce_, tpm_nonce_, AES_ENCRYPT);
  return true;
}

bool HmacAuthorizationDelegate::DecryptResponseParameter(
    std::string* parameter) {
  CHECK(parameter);
  if (!session_handle_) {
    LOG(ERROR) << __func__ << ": Invalid session handle.";
    return false;
  }
  if (!is_parameter_encryption_enabled_) {
    // No parameter decryption enabled.
    return true;
  }
  if (parameter->size() > kTpmBufferSize) {
    LOG(ERROR) << "Parameter size is too large for TPM encryption.";
    return false;
  }
  AesOperation(parameter, tpm_nonce_, caller_nonce_, AES_DECRYPT);
  return true;
}

bool HmacAuthorizationDelegate::GetTpmNonce(std::string* nonce) {
  if (!tpm_nonce_.size)
    return false;
  nonce->assign(tpm_nonce_.buffer, tpm_nonce_.buffer + tpm_nonce_.size);
  return true;
}

bool HmacAuthorizationDelegate::InitSession(TPM_HANDLE session_handle,
                                            const TPM2B_NONCE& tpm_nonce,
                                            const TPM2B_NONCE& caller_nonce,
                                            const std::string& salt,
                                            const std::string& bind_auth_value,
                                            bool enable_parameter_encryption) {
  session_handle_ = session_handle;
  if (caller_nonce.size < kNonceMinSize || caller_nonce.size > kNonceMaxSize ||
      tpm_nonce.size < kNonceMinSize || tpm_nonce.size > kNonceMaxSize) {
    LOG(INFO) << "Session Nonces have to be between 16 and 32 bytes long.";
    return false;
  }
  tpm_nonce_ = tpm_nonce;
  caller_nonce_ = caller_nonce;
  std::string session_key_label("ATH", kLabelSize);
  is_parameter_encryption_enabled_ = enable_parameter_encryption;
  if (salt.length() == 0 && bind_auth_value.length() == 0) {
    // SessionKey is set to the empty string for unsalted and
    // unbound sessions.
    session_key_ = std::string();
  } else {
    session_key_ = CreateKey(bind_auth_value + salt, session_key_label,
                             tpm_nonce_, caller_nonce_);
  }
  return true;
}

void HmacAuthorizationDelegate::set_future_authorization_value(
    const std::string& auth_value) {
  future_authorization_value_ = auth_value;
  future_authorization_value_set_ = true;
}

std::string HmacAuthorizationDelegate::CreateKey(
    const std::string& hmac_key,
    const std::string& label,
    const TPM2B_NONCE& nonce_newer,
    const TPM2B_NONCE& nonce_older) {
  std::string counter;
  std::string digest_size_bits;
  if (Serialize_uint32_t(1, &counter) != TPM_RC_SUCCESS ||
      Serialize_uint32_t(kDigestBits, &digest_size_bits) != TPM_RC_SUCCESS) {
    LOG(ERROR) << "Error serializing uint32_t during session key generation.";
    return std::string();
  }
  CHECK_EQ(counter.size(), sizeof(uint32_t));
  CHECK_EQ(digest_size_bits.size(), sizeof(uint32_t));
  CHECK_EQ(label.size(), kLabelSize);

  std::string data;
  data.append(counter);
  data.append(label);
  data.append(reinterpret_cast<const char*>(nonce_newer.buffer),
              nonce_newer.size);
  data.append(reinterpret_cast<const char*>(nonce_older.buffer),
              nonce_older.size);
  data.append(digest_size_bits);
  std::string key = HmacSha256(hmac_key, data);
  return key;
}

std::string HmacAuthorizationDelegate::HmacSha256(const std::string& key,
                                                  const std::string& data) {
  unsigned char digest[EVP_MAX_MD_SIZE];
  unsigned int digest_length;
  HMAC(EVP_sha256(), key.data(), key.size(),
       reinterpret_cast<const unsigned char*>(data.data()), data.size(), digest,
       &digest_length);
  CHECK_EQ(digest_length, kHashDigestSize);
  return std::string(reinterpret_cast<char*>(digest), digest_length);
}

void HmacAuthorizationDelegate::AesOperation(std::string* parameter,
                                             const TPM2B_NONCE& nonce_newer,
                                             const TPM2B_NONCE& nonce_older,
                                             int operation_type) {
  std::string label("CFB", kLabelSize);
  std::string compound_key =
      CreateKey(session_key_ + entity_authorization_value_, label, nonce_newer,
                nonce_older);
  CHECK_EQ(compound_key.size(), kAesKeySize + kAesIVSize);
  unsigned char aes_key[kAesKeySize];
  unsigned char aes_iv[kAesIVSize];
  memcpy(aes_key, &compound_key[0], kAesKeySize);
  memcpy(aes_iv, &compound_key[kAesKeySize], kAesIVSize);
  AES_KEY key;
  int iv_offset = 0;
  AES_set_encrypt_key(aes_key, kAesKeySize * 8, &key);
  unsigned char decrypted[kTpmBufferSize];
  AES_cfb128_encrypt(reinterpret_cast<const unsigned char*>(parameter->data()),
                     decrypted, parameter->size(), &key, aes_iv, &iv_offset,
                     operation_type);
  memcpy(base::data(*parameter), decrypted, parameter->size());
}

void HmacAuthorizationDelegate::RegenerateCallerNonce() {
  CHECK(session_handle_);
  // RAND_bytes takes a signed number, but since nonce_size is guaranteed to be
  // less than 32 bytes and greater than 16 we dont have to worry about it.
  CHECK_EQ(RAND_bytes(caller_nonce_.buffer, caller_nonce_.size), 1)
      << "Error regenerating a cryptographically random nonce.";
}

}  // namespace trunks
