// 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
