// Copyright 2020 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/pin_weaver_auth_block.h"

#include "cryptohome/cryptolib.h"
#include "cryptohome/tpm.h"
#include "cryptohome/vault_keyset.h"

#include <map>
#include <string>

#include <base/optional.h>
#include <brillo/secure_blob.h>

#include "cryptohome/vault_keyset.pb.h"

namespace cryptohome {

namespace {

constexpr int kDefaultSecretSize = 32;

CryptoError ConvertLeError(int le_error) {
  switch (le_error) {
    case LE_CRED_ERROR_INVALID_LE_SECRET:
      return CryptoError::CE_LE_INVALID_SECRET;
    case LE_CRED_ERROR_TOO_MANY_ATTEMPTS:
      return CryptoError::CE_TPM_DEFEND_LOCK;
    case LE_CRED_ERROR_INVALID_LABEL:
      return CryptoError::CE_OTHER_FATAL;
    case LE_CRED_ERROR_HASH_TREE:
      return CryptoError::CE_OTHER_FATAL;
    case LE_CRED_ERROR_PCR_NOT_MATCH:
      // We might want to return an error here that will make the device
      // reboot.
      LOG(ERROR) << "PCR in unexpected state.";
      return CryptoError::CE_LE_INVALID_SECRET;
    default:
      return CryptoError::CE_OTHER_FATAL;
  }
}

void LogLERetCode(int le_error) {
  switch (le_error) {
    case LE_CRED_ERROR_NO_FREE_LABEL:
      LOG(ERROR) << "No free label available in hash tree.";
      break;
    case LE_CRED_ERROR_HASH_TREE:
      LOG(ERROR) << "Hash tree error.";
      break;
  }
}

bool GetValidPCRValues(const std::string& obfuscated_username,
                       ValidPcrCriteria* valid_pcr_criteria) {
  brillo::Blob default_pcr_str(std::begin(kDefaultPcrValue),
                               std::end(kDefaultPcrValue));

  // The digest used for validation of PCR values by pinweaver is sha256 of
  // the current PCR value of index 4.
  // Step 1 - calculate expected values of PCR4 initially
  // (kDefaultPcrValue = 0) and after user logins
  // (sha256(initial_value | user_specific_digest)).
  // Step 2 - calculate digest of those values, to support multi-PCR case,
  // where all those expected values for all PCRs are sha256'ed togetheri
  brillo::Blob default_digest = CryptoLib::Sha256(default_pcr_str);

  // The second valid digest is the one obtained from the future value of
  // PCR4, after it's extended by |obfuscated_username|. Compute the value of
  // PCR4 after it will be extended first, which is
  // sha256(default_value + sha256(extend_text)).
  brillo::Blob obfuscated_username_digest = CryptoLib::Sha256(
      brillo::Blob(obfuscated_username.begin(), obfuscated_username.end()));
  brillo::Blob combined_pcr_and_username(default_pcr_str);
  combined_pcr_and_username.insert(
      combined_pcr_and_username.end(),
      std::make_move_iterator(obfuscated_username_digest.begin()),
      std::make_move_iterator(obfuscated_username_digest.end()));

  brillo::Blob extended_arc_pcr_value =
      CryptoLib::Sha256(combined_pcr_and_username);

  // The second valid digest used by pinweaver for validation will be
  // sha256 of the extended value of pcr4.
  brillo::Blob extended_digest = CryptoLib::Sha256(extended_arc_pcr_value);

  ValidPcrValue default_pcr_value;
  memset(default_pcr_value.bitmask, 0, 2);
  default_pcr_value.bitmask[kTpmSingleUserPCR / 8] = 1u << kTpmSingleUserPCR;
  default_pcr_value.digest =
      std::string(default_digest.begin(), default_digest.end());
  valid_pcr_criteria->push_back(default_pcr_value);

  ValidPcrValue extended_pcr_value;
  memset(extended_pcr_value.bitmask, 0, 2);
  extended_pcr_value.bitmask[kTpmSingleUserPCR / 8] = 1u << kTpmSingleUserPCR;
  extended_pcr_value.digest =
      std::string(extended_digest.begin(), extended_digest.end());
  valid_pcr_criteria->push_back(extended_pcr_value);

  return true;
}

// String used as vector in HMAC operation to derive vkk_seed from High Entropy
// secret.
const char kHESecretHmacData[] = "vkk_seed";

// A default delay schedule to be used for LE Credentials.
// The format for a delay schedule entry is as follows:
//
// (number_of_incorrect_attempts, delay before_next_attempt)
//
// The default schedule is for the first 5 incorrect attempts to have no delay,
// and no further attempts allowed.
const struct {
  uint32_t attempts;
  uint32_t delay;
} kDefaultDelaySchedule[] = {
    {5, UINT32_MAX},
};

}  // namespace

PinWeaverAuthBlock::PinWeaverAuthBlock(LECredentialManager* le_manager,
                                       TpmInit* tpm_init)
    : le_manager_(le_manager), tpm_init_(tpm_init) {
  CHECK_NE(le_manager, nullptr);
  CHECK_NE(tpm_init, nullptr);
}

base::Optional<AuthBlockState> PinWeaverAuthBlock::Create(
    const AuthInput& auth_input, KeyBlobs* key_blobs, CryptoError* error) {
  DCHECK(key_blobs);

  // TODO(kerrnel): This may not be needed, but is currently retained to
  // maintain the original logic.
  if (!tpm_init_->HasCryptohomeKey())
    tpm_init_->SetupTpm(/*load_key=*/true);

  brillo::SecureBlob le_secret(kDefaultSecretSize);
  brillo::SecureBlob kdf_skey(kDefaultSecretSize);
  brillo::SecureBlob le_iv(kAesBlockSize);
  if (!CryptoLib::DeriveSecretsScrypt(auth_input.user_input.value(),
                                      auth_input.salt.value(),
                                      {&le_secret, &kdf_skey, &le_iv})) {
    return base::nullopt;
  }

  // Create a randomly generated high entropy secret, derive VKKSeed from it,
  // and use that to generate a VKK. The HE secret will be stored in the
  // LECredentialManager, along with the LE secret (which is |le_secret| here).
  brillo::SecureBlob he_secret =
      CryptoLib::CreateSecureRandomBlob(kDefaultSecretSize);

  // Derive the VKK_seed by performing an HMAC on he_secret.
  brillo::SecureBlob vkk_seed = CryptoLib::HmacSha256(
      he_secret, brillo::BlobFromString(kHESecretHmacData));

  // Generate and store random new IVs for file-encryption keys and
  // chaps key encryption.
  const auto fek_iv = CryptoLib::CreateSecureRandomBlob(kAesBlockSize);
  const auto chaps_iv = CryptoLib::CreateSecureRandomBlob(kAesBlockSize);

  SerializedVaultKeyset serialized;
  serialized.set_le_fek_iv(fek_iv.data(), fek_iv.size());
  serialized.set_le_chaps_iv(chaps_iv.data(), chaps_iv.size());

  brillo::SecureBlob vkk_key = CryptoLib::HmacSha256(kdf_skey, vkk_seed);

  key_blobs->vkk_key = vkk_key;
  key_blobs->vkk_iv = fek_iv;
  key_blobs->chaps_iv = chaps_iv;
  key_blobs->auth_iv = le_iv;

  // Once we are able to correctly set up the VaultKeyset encryption,
  // store the LE and HE credential in the LECredentialManager.

  // Use the default delay schedule for now.
  std::map<uint32_t, uint32_t> delay_sched;
  for (const auto& entry : kDefaultDelaySchedule) {
    delay_sched[entry.attempts] = entry.delay;
  }

  brillo::SecureBlob reset_secret = auth_input.reset_secret.value();
  ValidPcrCriteria valid_pcr_criteria;
  if (!GetValidPCRValues(auth_input.obfuscated_username.value(),
                         &valid_pcr_criteria)) {
    return base::nullopt;
  }

  uint64_t label;
  int ret =
      le_manager_->InsertCredential(le_secret, he_secret, reset_secret,
                                    delay_sched, valid_pcr_criteria, &label);
  if (ret != LE_CRED_SUCCESS) {
    LogLERetCode(ret);
    PopulateError(error, ConvertLeError(ret));
    return base::nullopt;
  }
  serialized.set_flags(SerializedVaultKeyset::LE_CREDENTIAL);
  serialized.set_le_label(label);

  return {{serialized}};
}

bool PinWeaverAuthBlock::Derive(const AuthInput& auth_input,
                                const AuthBlockState& state,
                                KeyBlobs* key_blobs,
                                CryptoError* error) {
  DCHECK(key_blobs);
  DCHECK(state.vault_keyset != base::nullopt);
  const SerializedVaultKeyset& serialized = state.vault_keyset.value();

  CHECK(serialized.flags() & SerializedVaultKeyset::LE_CREDENTIAL);

  brillo::SecureBlob le_secret(kDefaultAesKeySize);
  brillo::SecureBlob kdf_skey(kDefaultAesKeySize);
  brillo::SecureBlob le_iv(kAesBlockSize);
  brillo::SecureBlob salt(serialized.salt().begin(), serialized.salt().end());
  if (!CryptoLib::DeriveSecretsScrypt(auth_input.user_input.value(), salt,
                                      {&le_secret, &kdf_skey, &le_iv})) {
    PopulateError(error, CryptoError::CE_OTHER_FATAL);
    return false;
  }

  key_blobs->reset_secret = brillo::SecureBlob();
  key_blobs->chaps_iv = brillo::SecureBlob(serialized.le_chaps_iv().begin(),
                                           serialized.le_chaps_iv().end());

  // Try to obtain the HE Secret from the LECredentialManager.
  brillo::SecureBlob he_secret;
  int ret =
      le_manager_->CheckCredential(serialized.le_label(), le_secret, &he_secret,
                                   &key_blobs->reset_secret.value());

  if (ret != LE_CRED_SUCCESS) {
    PopulateError(error, ConvertLeError(ret));
    return false;
  }

  key_blobs->vkk_iv = brillo::SecureBlob(serialized.le_fek_iv().begin(),
                                         serialized.le_fek_iv().end());

  brillo::SecureBlob vkk_seed = CryptoLib::HmacSha256(
      he_secret, brillo::BlobFromString(kHESecretHmacData));
  key_blobs->vkk_key = CryptoLib::HmacSha256(kdf_skey, vkk_seed);

  return true;
}

}  // namespace cryptohome
