// Copyright 2015 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.

// Test methods that run on a real TPM

#include "cryptohome/tpm_live_test.h"

#include <stdint.h>

#include <map>
#include <memory>
#include <set>
#include <utility>

#include <base/macros.h>
#include <base/memory/ptr_util.h>
#include <base/optional.h>
#include <crypto/scoped_openssl_types.h>
#include <crypto/sha2.h>
#include <openssl/bn.h>
#include <openssl/evp.h>
#include <openssl/rsa.h>
#include <openssl/x509.h>

#include "cryptohome/cryptolib.h"
#include "cryptohome/signature_sealing_backend.h"

#include <openssl/err.h>

#if !USE_TPM2
#include <trousers/scoped_tss_type.h>
#include <trousers/tss.h>
#include <trousers/trousers.h>  // NOLINT(build/include_alpha) - needs tss.h

#include "cryptohome/tpm_impl.h"
#endif  // !USE_TPM2

using brillo::Blob;
using brillo::BlobFromString;
using brillo::BlobToString;
using brillo::SecureBlob;

namespace cryptohome {

namespace {

// Scoped setter of the owner password of the global Tpm instance.
// Does nothing if the version is different from |TPM_1_2|.
class ScopedTpmOwnerPasswordSetter {
 public:
  explicit ScopedTpmOwnerPasswordSetter(const SecureBlob& owner_password)
      : tpm_(Tpm::GetSingleton()) {
    if (ShouldApply()) {
      tpm_->GetOwnerPassword(&previous_tpm_owner_password_);
      tpm_->SetOwnerPassword(owner_password);
    }
  }

  ~ScopedTpmOwnerPasswordSetter() {
    if (ShouldApply())
      tpm_->SetOwnerPassword(previous_tpm_owner_password_);
  }

 private:
  bool ShouldApply() const { return tpm_->GetVersion() == Tpm::TPM_1_2; }

  Tpm* const tpm_;
  SecureBlob previous_tpm_owner_password_;
};

}  // namespace

TpmLiveTest::TpmLiveTest() : tpm_(Tpm::GetSingleton()) {}

bool TpmLiveTest::RunLiveTests(const SecureBlob& owner_password,
                               bool tpm2_use_system_owner_password) {
  if (!PCRKeyTest()) {
    LOG(ERROR) << "Error running PCRKeyTest.";
    return false;
  }
  if (!MultiplePCRKeyTest()) {
    LOG(ERROR) << "Error running MultiplePCRKeyTest.";
    return false;
  }
  if (!DecryptionKeyTest()) {
    LOG(ERROR) << "Error running Decryption test.";
    return false;
  }
  if (!SealToPcrWithAuthorizationTest()) {
    LOG(ERROR) << "Error running SealToPcrWithAuthorizationTest.";
    return false;
  }
  const Tpm::TpmVersion tpm_version = tpm_->GetVersion();
  if ((tpm_version == Tpm::TPM_1_2 && !owner_password.empty()) ||
      (tpm_version == Tpm::TPM_2_0 && tpm2_use_system_owner_password)) {
    if (!NvramTest(owner_password)) {
      LOG(ERROR) << "Error running NvramTest.";
      return false;
    }
  }
  if (tpm_version != Tpm::TPM_1_2 || !owner_password.empty()) {
    if (!SignatureSealedSecretTest(owner_password)) {
      LOG(ERROR) << "Error running SignatureSealedSecretTest.";
      return false;
    }
  }
  LOG(INFO) << "All tests run successfully.";
  return true;
}

bool TpmLiveTest::SignData(const SecureBlob& pcr_bound_key,
                           const SecureBlob& public_key_der,
                           int index) {
  SecureBlob input_data("input_data");
  SecureBlob signature;
  if (!tpm_->Sign(pcr_bound_key, input_data, index, &signature)) {
    LOG(ERROR) << "Error signing with PCR bound key.";
    return false;
  }
  const unsigned char* public_key_data = public_key_der.data();
  crypto::ScopedRSA rsa(
      d2i_RSAPublicKey(nullptr, &public_key_data, public_key_der.size()));
  if (!rsa.get()) {
    LOG(ERROR) << "Failed to decode public key.";
    return false;
  }
  SecureBlob digest = CryptoLib::Sha256(input_data);
  if (!RSA_verify(NID_sha256, digest.data(), digest.size(),
                  signature.data(), signature.size(), rsa.get())) {
    LOG(ERROR) << "Failed to verify signature.";
    return false;
  }
  return true;
}

bool TpmLiveTest::EncryptAndDecryptData(
    const SecureBlob& pcr_bound_key,
    const std::map<uint32_t, std::string>& pcr_map) {
  ScopedKeyHandle handle;
  if (tpm_->LoadWrappedKey(pcr_bound_key, &handle) != Tpm::kTpmRetryNone) {
    LOG(ERROR) << "Error loading wrapped key.";
    return false;
  }
  SecureBlob aes_key(32, 'a');
  SecureBlob plaintext(32, 'b');
  SecureBlob ciphertext;
  if (tpm_->EncryptBlob(handle.value(), plaintext, aes_key, &ciphertext) !=
      Tpm::kTpmRetryNone) {
    LOG(ERROR) << "Error encrypting blob.";
    return false;
  }
  SecureBlob decrypted_plaintext;
  if (tpm_->DecryptBlob(handle.value(), ciphertext, aes_key, pcr_map,
                        &decrypted_plaintext) != Tpm::kTpmRetryNone) {
    LOG(ERROR) << "Error decrypting the data.";
    return false;
  }
  if (plaintext != decrypted_plaintext) {
    LOG(ERROR) << "Decrypted plaintext does not match plaintext.";
    return false;
  }
  return true;
}

bool TpmLiveTest::PCRKeyTest() {
  LOG(INFO) << "PCRKeyTest started";
  uint32_t index = 5;
  Blob pcr_data;
  if (!tpm_->ReadPCR(index, &pcr_data)) {
    LOG(ERROR) << "Error reading pcr value from TPM.";
    return false;
  }
  SecureBlob pcr_bound_key1;  // Sign key
  SecureBlob pcr_bound_key2;  // Decrypt key
  SecureBlob pcr_bound_key3;  // Sign and decrypt key
  SecureBlob public_key_der1;
  SecureBlob public_key_der2;
  SecureBlob public_key_der3;
  SecureBlob creation_blob1;
  SecureBlob creation_blob2;
  SecureBlob creation_blob3;
  std::map<uint32_t, std::string> pcr_map({{index, BlobToString(pcr_data)}});
  // Create the keys.
  if (!tpm_->CreatePCRBoundKey(pcr_map, AsymmetricKeyUsage::kSignKey,
      &pcr_bound_key1, &public_key_der1, &creation_blob1)) {
    LOG(ERROR) << "Error creating PCR bound signing key.";
    return false;
  }
  if (!tpm_->CreatePCRBoundKey(pcr_map, AsymmetricKeyUsage::kDecryptKey,
      &pcr_bound_key2, &public_key_der2, &creation_blob2)) {
    LOG(ERROR) << "Error creating PCR bound decryption key.";
    return false;
  }
  if (!tpm_->CreatePCRBoundKey(pcr_map, AsymmetricKeyUsage::kDecryptAndSignKey,
      &pcr_bound_key3, &public_key_der3, &creation_blob3)) {
    LOG(ERROR) << "Error creating PCR bound decrypt and sign key.";
    return false;
  }
  if (!tpm_->VerifyPCRBoundKey(pcr_map, pcr_bound_key1, creation_blob1) ||
      !tpm_->VerifyPCRBoundKey(pcr_map, pcr_bound_key2, creation_blob2) ||
      !tpm_->VerifyPCRBoundKey(pcr_map, pcr_bound_key3, creation_blob3)) {
    LOG(ERROR) << "Error verifying PCR bound key.";
    return false;
  }
  // Check that signing key works.
  if (!SignData(pcr_bound_key1, public_key_der1, index)) {
    LOG(ERROR) << "Error signing the blob.";
    return false;
  }
  // Check that the key cannot be used to decrypt the data.
  if (EncryptAndDecryptData(pcr_bound_key1, pcr_map)) {
    LOG(ERROR) << "Decrypting the blob succeeded with signing only key.";
    return false;
  }
  // Check that the decryption key works as intended.
  if (!EncryptAndDecryptData(pcr_bound_key2, pcr_map)) {
    LOG(ERROR) << "Error decrypting the blob.";
    return false;
  }
  // Check that signing data doesn't work (only for TPM2).
  if (tpm_->GetVersion() != Tpm::TPM_1_2) {
    if (SignData(pcr_bound_key2, public_key_der2, index)) {
      LOG(ERROR) << "Signing data succeeded with decryption only key.";
      return false;
    }
  }
  // Check that the key created for decryption and signing works for both.
  if (!EncryptAndDecryptData(pcr_bound_key3, pcr_map)) {
    LOG(ERROR) << "Error decrypting the blob.";
    return false;
  }
  if (!SignData(pcr_bound_key3, public_key_der3, index)) {
    LOG(ERROR) << "Error signing the blob.";
    return false;
  }
  // Extend PCR to invalidate the keys.
  if (!tpm_->ExtendPCR(index, BlobFromString("01234567890123456789"))) {
    LOG(ERROR) << "Error extending PCR.";
    return false;
  }
  if (SignData(pcr_bound_key1, public_key_der1, index)) {
    LOG(ERROR) << "Sign succeeded without the correct PCR state.";
    return false;
  }
  if (EncryptAndDecryptData(pcr_bound_key2, pcr_map)) {
    LOG(ERROR) << "Decryption succeeded without the correct PCR state.";
    return false;
  }
  if (SignData(pcr_bound_key3, public_key_der3, index)) {
    LOG(ERROR) << "Sign succeeded without the correct PCR state.";
    return false;
  }
  if (EncryptAndDecryptData(pcr_bound_key3, pcr_map)) {
    LOG(ERROR) << "Decryption succeeded without the correct PCR state.";
    return false;
  }
  LOG(INFO) << "PCRKeyTest ended successfully.";
  return true;
}

bool TpmLiveTest::MultiplePCRKeyTest() {
  LOG(INFO) << "MultiplePCRKeyTest started";
  uint32_t index1 = 7;
  uint32_t index2 = 12;
  Blob pcr_data1;
  Blob pcr_data2;
  if (!tpm_->ReadPCR(index1, &pcr_data1) ||
      !tpm_->ReadPCR(index2, &pcr_data2)) {
    LOG(ERROR) << "Error reading pcr value from TPM.";
    return false;
  }
  SecureBlob pcr_bound_key;
  SecureBlob public_key_der;
  SecureBlob creation_blob;
  std::map<uint32_t, std::string> pcr_map(
      {{index1, BlobToString(pcr_data1)}, {index2, BlobToString(pcr_data2)}});
  if (!tpm_->CreatePCRBoundKey(pcr_map, AsymmetricKeyUsage::kDecryptKey,
                               &pcr_bound_key, &public_key_der,
                               &creation_blob)) {
    LOG(ERROR) << "Error creating PCR bound key.";
    return false;
  }
  ScopedKeyHandle handle;
  if (tpm_->LoadWrappedKey(pcr_bound_key, &handle) != Tpm::kTpmRetryNone) {
    LOG(ERROR) << "Error loading wrapped key.";
    return false;
  }
  SecureBlob aes_key(32, 'a');
  SecureBlob plaintext(32, 'b');
  SecureBlob ciphertext;
  if (tpm_->EncryptBlob(handle.value(), plaintext, aes_key, &ciphertext) !=
      Tpm::kTpmRetryNone) {
    LOG(ERROR) << "Error encrypting blob.";
    return false;
  }
  SecureBlob decrypted_plaintext;
  if (tpm_->DecryptBlob(handle.value(), ciphertext, aes_key, pcr_map,
                        &decrypted_plaintext) != Tpm::kTpmRetryNone) {
    LOG(ERROR) << "Error decrypting blob.";
    return false;
  }
  if (plaintext != decrypted_plaintext) {
    LOG(ERROR) << "Decrypted plaintext does not match plaintext.";
    return false;
  }
  if (!tpm_->VerifyPCRBoundKey(pcr_map, pcr_bound_key, creation_blob)) {
    LOG(ERROR) << "Error verifying PCR bound key.";
    return false;
  }
  // Extend a PCR that is bound to the key, to invalidate it.
  if (!tpm_->ExtendPCR(index2, BlobFromString("01234567890123456789"))) {
    LOG(ERROR) << "Error extending PCR.";
    return false;
  }
  // Check that the text cannot be decrypted anymore, after the PCR change.
  if (tpm_->DecryptBlob(handle.value(), ciphertext, aes_key, pcr_map,
                        &decrypted_plaintext) == Tpm::kTpmRetryNone) {
    LOG(ERROR) << "Decrypt succeeded without the correct PCR state.";
    return false;
  }
  if (!tpm_->ReadPCR(index2, &pcr_data2)) {
    LOG(ERROR) << "Error reading pcr value from TPM.";
    return false;
  }
  // Check that the text cannot be decrypted even with the right PCR values.
  pcr_map[index2] = BlobToString(pcr_data2);
  if (tpm_->DecryptBlob(handle.value(), ciphertext, aes_key, pcr_map,
                        &decrypted_plaintext) == Tpm::kTpmRetryNone) {
    LOG(ERROR) << "Decrypt succeeded without the correct PCR state.";
    return false;
  }
  // Check that VerifyPCRBoundKey also fails.
  if (tpm_->VerifyPCRBoundKey(pcr_map, pcr_bound_key, creation_blob)) {
    LOG(ERROR) << "VerifyPCRBoundKey succeeded without the correct PCR state.";
    return false;
  }
  // Check that even a newly encrypted text cannot be decrypted.
  if (tpm_->EncryptBlob(handle.value(), plaintext, aes_key, &ciphertext) !=
      Tpm::kTpmRetryNone) {
    LOG(ERROR) << "Error encrypting blob.";
    return false;
  }
  if (tpm_->DecryptBlob(handle.value(), ciphertext, aes_key, pcr_map,
                        &decrypted_plaintext) == Tpm::kTpmRetryNone) {
    LOG(ERROR) << "Decrypt succeeded without the correct PCR state.";
    return false;
  }
  LOG(INFO) << "MultiplePCRKeyTest ended successfully.";
  return true;
}

bool TpmLiveTest::DecryptionKeyTest() {
  LOG(INFO) << "DecryptionKeyTest started";
  SecureBlob n;
  SecureBlob p;
  uint32_t tpm_key_bits = 2048;
  if (!CryptoLib::CreateRsaKey(tpm_key_bits, &n, &p)) {
    LOG(ERROR) << "Error creating RSA key.";
    return false;
  }
  SecureBlob wrapped_key;
  if (!tpm_->WrapRsaKey(n, p, &wrapped_key)) {
    LOG(ERROR) << "Error wrapping RSA key.";
    return false;
  }
  ScopedKeyHandle handle;
  if (tpm_->LoadWrappedKey(wrapped_key, &handle) != Tpm::kTpmRetryNone) {
    LOG(ERROR) << "Error loading key.";
    return false;
  }
  SecureBlob aes_key(32, 'a');
  SecureBlob plaintext(32, 'b');
  SecureBlob ciphertext;
  if (tpm_->EncryptBlob(handle.value(), plaintext, aes_key, &ciphertext) !=
      Tpm::kTpmRetryNone) {
    LOG(ERROR) << "Error encrypting blob.";
    return false;
  }
  SecureBlob decrypted_plaintext;
  if (tpm_->DecryptBlob(handle.value(), ciphertext, aes_key,
                        std::map<uint32_t, std::string>(),
                        &decrypted_plaintext) != Tpm::kTpmRetryNone) {
    LOG(ERROR) << "Error decrypting blob.";
    return false;
  }
  if (plaintext != decrypted_plaintext) {
    LOG(ERROR) << "Decrypted plaintext does not match plaintext.";
    return false;
  }
  LOG(INFO) << "DecryptionKeyTest ended successfully.";
  return true;
}

bool TpmLiveTest::SealToPcrWithAuthorizationTest() {
  LOG(INFO) << "SealToPcrWithAuthorizationTest started";
  SecureBlob n;
  SecureBlob p;
  uint32_t tpm_key_bits = 2048;
  if (!CryptoLib::CreateRsaKey(tpm_key_bits, &n, &p)) {
    LOG(ERROR) << "Error creating RSA key.";
    return false;
  }
  SecureBlob wrapped_key;
  if (!tpm_->WrapRsaKey(n, p, &wrapped_key)) {
    LOG(ERROR) << "Error wrapping RSA key.";
    return false;
  }
  ScopedKeyHandle handle;
  if (tpm_->LoadWrappedKey(wrapped_key, &handle) != Tpm::kTpmRetryNone) {
    LOG(ERROR) << "Error loading key.";
    return false;
  }

  uint32_t index1 = 4;
  uint32_t index2 = 11;
  std::map<uint32_t, std::string> pcr_map({{index1, ""}, {index2, ""}});
  SecureBlob plaintext(32, 'a');
  SecureBlob auth_blob(256, 'b');
  SecureBlob ciphertext;
  if (tpm_->SealToPcrWithAuthorization(handle.value(), plaintext, auth_blob,
                                       pcr_map, &ciphertext) !=
      Tpm::kTpmRetryNone) {
    LOG(ERROR) << "Error sealing the blob.";
    return false;
  }
  SecureBlob unsealed_text;
  if (tpm_->UnsealWithAuthorization(handle.value(), ciphertext, auth_blob,
                                    pcr_map, &unsealed_text) !=
      Tpm::kTpmRetryNone) {
    LOG(ERROR) << "Error unsealing blob.";
    return false;
  }
  if (plaintext != unsealed_text) {
    LOG(ERROR) << "Unsealed plaintext does not match plaintext.";
    return false;
  }

  // Check that unsealing doesn't work with wrong auth_blob.
  auth_blob.char_data()[255] = 'a';
  if (tpm_->UnsealWithAuthorization(handle.value(), ciphertext, auth_blob,
                                    pcr_map, &unsealed_text) ==
      Tpm::kTpmRetryNone && plaintext == unsealed_text) {
    LOG(ERROR) << "UnsealWithAuthorization failed to fail.";
    return false;
  }

  LOG(INFO) << "SealToPcrWithAuthorizationTest ended successfully.";
  return true;
}

bool TpmLiveTest::NvramTest(const SecureBlob& owner_password) {
  LOG(INFO) << "NvramTest started";
  const ScopedTpmOwnerPasswordSetter scoped_tpm_owner_password_setter(
      owner_password);
  uint32_t index = 12;
  SecureBlob nvram_data("nvram_data");
  if (tpm_->IsNvramDefined(index)) {
    if (!tpm_->DestroyNvram(index)) {
      LOG(ERROR) << "Error destroying old Nvram.";
      return false;
    }
    if (tpm_->IsNvramDefined(index)) {
      LOG(ERROR) << "Nvram still defined after it was destroyed.";
      return false;
    }
  }
  if (!tpm_->DefineNvram(index, nvram_data.size(),
                         Tpm::kTpmNvramWriteDefine |
                         Tpm::kTpmNvramBindToPCR0)) {
    LOG(ERROR) << "Defining Nvram index.";
    return false;
  }
  if (!tpm_->IsNvramDefined(index)) {
    LOG(ERROR) << "Nvram index is not defined after creating.";
    return false;
  }
  if (tpm_->GetNvramSize(index) != nvram_data.size()) {
    LOG(ERROR) << "Nvram space is of incorrect size.";
    return false;
  }
  if (tpm_->IsNvramLocked(index)) {
    LOG(ERROR) << "Nvram should not be locked before writing.";
    return false;
  }
  if (!tpm_->WriteNvram(index, nvram_data)) {
    LOG(ERROR) << "Error writing to Nvram.";
    return false;
  }
  if (!tpm_->WriteLockNvram(index)) {
    LOG(ERROR) << "Error locking Nvram space.";
    return false;
  }
  if (!tpm_->IsNvramLocked(index)) {
    LOG(ERROR) << "Nvram should be locked after locking.";
    return false;
  }
  SecureBlob data;
  if (!tpm_->ReadNvram(index, &data)) {
    LOG(ERROR) << "Error reading from Nvram.";
    return false;
  }
  if (data != nvram_data) {
    LOG(ERROR) << "Data read from Nvram did not match data written.";
    return false;
  }
  if (tpm_->WriteNvram(index, nvram_data)) {
    LOG(ERROR) << "We should not be able to write to a locked Nvram space.";
    return false;
  }
  if (!tpm_->DestroyNvram(index)) {
    LOG(ERROR) << "Error destroying Nvram space.";
    return false;
  }
  if (tpm_->IsNvramDefined(index)) {
    LOG(ERROR) << "Nvram still defined after it was destroyed.";
    return false;
  }
  LOG(INFO) << "NvramTest ended successfully.";
  return true;
}

namespace {

struct SignatureSealedSecretTestCaseParam {
  SignatureSealedSecretTestCaseParam(
      const std::string& test_case_description,
      Tpm* tpm,
      int key_size_bits,
      const std::vector<ChallengeSignatureAlgorithm>& supported_algorithms,
      base::Optional<ChallengeSignatureAlgorithm> expected_algorithm,
      int openssl_algorithm_nid)
      : test_case_description(test_case_description),
        tpm(tpm),
        key_size_bits(key_size_bits),
        supported_algorithms(supported_algorithms),
        expected_algorithm(expected_algorithm),
        openssl_algorithm_nid(openssl_algorithm_nid) {}

  SignatureSealedSecretTestCaseParam(SignatureSealedSecretTestCaseParam&&) =
      default;

  static SignatureSealedSecretTestCaseParam MakeSuccessful(
      const std::string& test_case_description,
      Tpm* tpm,
      int key_size_bits,
      const std::vector<ChallengeSignatureAlgorithm>& supported_algorithms,
      ChallengeSignatureAlgorithm expected_algorithm,
      int openssl_algorithm_nid) {
    return SignatureSealedSecretTestCaseParam(
        test_case_description, tpm, key_size_bits, supported_algorithms,
        expected_algorithm, openssl_algorithm_nid);
  }

  static SignatureSealedSecretTestCaseParam MakeFailing(
      const std::string& test_case_description,
      Tpm* tpm,
      int key_size_bits,
      const std::vector<ChallengeSignatureAlgorithm>& supported_algorithms) {
    return SignatureSealedSecretTestCaseParam(
        test_case_description, tpm, key_size_bits, supported_algorithms, {}, 0);
  }

  bool expect_success() const { return expected_algorithm.has_value(); }

  std::string test_case_description;
  Tpm* tpm;
  int key_size_bits;
  std::vector<ChallengeSignatureAlgorithm> supported_algorithms;
  base::Optional<ChallengeSignatureAlgorithm> expected_algorithm;
  int openssl_algorithm_nid;
};

class SignatureSealedSecretTestCase final {
 public:
  using UnsealingSession = SignatureSealingBackend::UnsealingSession;

  SignatureSealedSecretTestCase(SignatureSealedSecretTestCaseParam param,
                                const SecureBlob& owner_password)
      : param_(std::move(param)), owner_password_(owner_password) {
    LOG(INFO) << "SignatureSealedSecretTestCase: " << param_.key_size_bits
              << "-bit key, " << param_.test_case_description;
  }

  ~SignatureSealedSecretTestCase() { CleanUpDelegate(); }

  bool SetUp() {
    if (!GenerateRsaKey(param_.key_size_bits, &pkey_, &key_spki_der_)) {
      LOG(ERROR) << "Error generating the RSA key";
      return false;
    }
    if (!InitDelegate()) {
      LOG(ERROR) << "Error creating the delegate";
      return false;
    }
    return true;
  }

  bool Run() {
    if (!param_.expect_success()) {
      if (!CheckSecretCreationFails()) {
        LOG(ERROR) << "Error: successfully created secret unexpectedly";
        return false;
      }
      return true;
    }
    // Create a secret.
    SignatureSealedData sealed_secret_data;
    if (!CreateSecret(&sealed_secret_data)) {
      LOG(ERROR) << "Error creating a secret";
      return false;
    }
    // Unseal the secret.
    Blob first_challenge_value;
    Blob first_challenge_signature;
    SecureBlob first_unsealed_value;
    if (!Unseal(sealed_secret_data, &first_challenge_value,
                &first_challenge_signature, &first_unsealed_value)) {
      LOG(ERROR) << "Error unsealing a secret";
      return false;
    }
    // Unseal the secret again - the challenge is different, but the result is
    // the same.
    Blob second_challenge_value;
    Blob second_challenge_signature;
    SecureBlob second_unsealed_value;
    if (!Unseal(sealed_secret_data, &second_challenge_value,
                &second_challenge_signature, &second_unsealed_value)) {
      LOG(ERROR) << "Error unsealing secret for the second time";
      return false;
    }
    if (first_challenge_value == second_challenge_value) {
      LOG(ERROR) << "Error: challenge value collision";
      return false;
    }
    if (first_unsealed_value != second_unsealed_value) {
      LOG(ERROR) << "Error: unsealing result differs";
      return false;
    }
    // Unsealing with a bad challenge response fails.
    if (!CheckUnsealingFailsWithOldSignature(sealed_secret_data,
                                             first_challenge_signature) ||
        !CheckUnsealingFailsWithBadAlgorithmSignature(sealed_secret_data) ||
        !CheckUnsealingFailsWithBadSignature(sealed_secret_data)) {
      LOG(ERROR) << "Failed testing against bad challenge responses";
      return false;
    }
    // Unsealing with a bad key fails.
    if (!CheckUnsealingFailsWithWrongAlgorithm(sealed_secret_data) ||
        !CheckUnsealingFailsWithWrongKey(sealed_secret_data)) {
      LOG(ERROR) << "Failed testing against bad keys";
      return false;
    }
    // Create and unseal another secret - it has a different value.
    SignatureSealedData another_sealed_secret_data;
    if (!CreateSecret(&another_sealed_secret_data)) {
      LOG(ERROR) << "Error creating another secret";
      return false;
    }
    Blob third_challenge_value;
    Blob third_challenge_signature;
    SecureBlob third_unsealed_value;
    if (!Unseal(another_sealed_secret_data, &third_challenge_value,
                &third_challenge_signature, &third_unsealed_value)) {
      LOG(ERROR) << "Error unsealing another secret";
      return false;
    }
    if (first_unsealed_value == third_unsealed_value) {
      LOG(ERROR) << "Error: secret value collision";
      return false;
    }
    // Unsealing after PCRs change fails.
    if (!CheckUnsealingFailsWithChangedPcrs(another_sealed_secret_data)) {
      LOG(ERROR) << "Failed testing against changed PCRs";
      return false;
    }
    return true;
  }

 private:
  static constexpr uint32_t kPcrIndexToExtend = 16;  // The Debug PCR.
  const std::set<uint32_t> kPcrIndexes{0, kPcrIndexToExtend};
  static constexpr uint8_t kDelegateFamilyLabel = 100;
  static constexpr uint8_t kDelegateLabel = 101;

  Tpm* tpm() { return param_.tpm; }

  SignatureSealingBackend* backend() {
    return tpm()->GetSignatureSealingBackend();
  }

  static bool GenerateRsaKey(int key_size_bits,
                             crypto::ScopedEVP_PKEY* pkey,
                             Blob* key_spki_der) {
    crypto::ScopedEVP_PKEY_CTX pkey_context(
        EVP_PKEY_CTX_new_id(EVP_PKEY_RSA, nullptr));
    if (!pkey_context)
      return false;
    if (EVP_PKEY_keygen_init(pkey_context.get()) <= 0)
      return false;
    if (EVP_PKEY_CTX_set_rsa_keygen_bits(pkey_context.get(), key_size_bits) <=
        0) {
      return false;
    }
    EVP_PKEY* pkey_raw = nullptr;
    if (EVP_PKEY_keygen(pkey_context.get(), &pkey_raw) <= 0)
      return false;
    pkey->reset(pkey_raw);
    // Obtain the DER-encoded Subject Public Key Info.
    const int key_spki_der_length = i2d_PUBKEY(pkey->get(), nullptr);
    if (key_spki_der_length < 0)
      return false;
    key_spki_der->resize(key_spki_der_length);
    unsigned char* key_spki_der_buffer = key_spki_der->data();
    return i2d_PUBKEY(pkey->get(), &key_spki_der_buffer) ==
           key_spki_der->size();
  }

  // Creates the TPM 1.2 delegate.
  bool InitDelegate() {
    if (tpm()->GetVersion() != Tpm::TPM_1_2)
      return true;
    const ScopedTpmOwnerPasswordSetter scoped_tpm_owner_password_setter(
        owner_password_);
    return tpm()->CreateDelegate(kPcrIndexes, kDelegateFamilyLabel,
                                 kDelegateLabel, &delegate_blob_,
                                 &delegate_secret_);
  }

  // Deletes the TPM 1.2 delegate and family from the TPM's NVRAM. Not doing
  // that will result in the NVRAM space exhaustion after several launches of
  // the test.
  void CleanUpDelegate() {
#if !USE_TPM2
    CHECK_EQ(Tpm::TPM_1_2, tpm()->GetVersion());
    using trousers::ScopedTssContext;
    using trousers::ScopedTssMemory;
    using trousers::ScopedTssObject;
    if (delegate_blob_.empty() || delegate_secret_.empty())
      return;
    // Obtain the TPM context and handle with the owner authorization.
    const ScopedTpmOwnerPasswordSetter scoped_tpm_owner_password_setter(
        owner_password_);
    ScopedTssContext tpm_context;
    TSS_HTPM tpm_handle = 0;
    if (!static_cast<TpmImpl*>(tpm())->ConnectContextAsOwner(tpm_context.ptr(),
                                                             &tpm_handle)) {
      LOG(ERROR)
          << "Failed to clean up the delegate: error connecting to the TPM";
      return;
    }
    // Obtain all TPM delegates and delegate families.
    UINT32 family_table_size = 0;
    TSS_FAMILY_TABLE_ENTRY* family_table_ptr = nullptr;
    UINT32 delegate_table_size = 0;
    TSS_DELEGATION_TABLE_ENTRY* delegate_table_ptr = nullptr;
    TSS_RESULT tss_result = Tspi_TPM_Delegate_ReadTables(
        tpm_context, &family_table_size, &family_table_ptr,
        &delegate_table_size, &delegate_table_ptr);
    if (TPM_ERROR(tss_result)) {
      LOG(ERROR)
          << "Failed to clean up the delegate: error reading delegate table: "
          << Trspi_Error_String(tss_result);
      return;
    }
    ScopedTssMemory scoped_family_table(
        tpm_context, reinterpret_cast<BYTE*>(family_table_ptr));
    ScopedTssMemory scoped_delegate_table(
        tpm_context, reinterpret_cast<BYTE*>(delegate_table_ptr));
    // Invalidate the delegate families which have the test label. Note that
    // this removes from the NVRAM both the delegate families and the delegates
    // themselves.
    int invalidated_family_count = 0;
    UINT64 family_table_offset = 0;
    for (int family_index = 0; family_index < family_table_size;
         ++family_index) {
      TSS_FAMILY_TABLE_ENTRY family_entry;
      Trspi_UnloadBlob_TSS_FAMILY_TABLE_ENTRY(
          &family_table_offset, scoped_family_table.value(), &family_entry);
      if (family_entry.label == kDelegateFamilyLabel) {
        ScopedTssObject<TSS_HDELFAMILY> family_handle(tpm_context);
        tss_result = Tspi_TPM_Delegate_GetFamily(
            tpm_handle, family_entry.familyID, family_handle.ptr());
        if (TPM_ERROR(tss_result)) {
          LOG(ERROR) << "Failed to clean up the delegate: error getting "
                        "delegate family handle: "
                     << Trspi_Error_String(tss_result);
          continue;
        }
        tss_result =
            Tspi_TPM_Delegate_InvalidateFamily(tpm_handle, family_handle);
        if (TPM_ERROR(tss_result)) {
          LOG(ERROR) << "Failed to clean up the delegate: error invalidating "
                        "delegate family: "
                     << Trspi_Error_String(tss_result);
          continue;
        }
        ++invalidated_family_count;
      }
    }
    if (!invalidated_family_count) {
      LOG(ERROR) << "Failed to clean up the delegate: no entry was "
                    "successfully invalidated";
      return;
    }
    VLOG(1) << "Delegate families cleaned up: " << invalidated_family_count;
#endif  // !USE_TPM2
  }

  bool CreateSecret(SignatureSealedData* sealed_secret_data) {
    std::map<uint32_t, Blob> pcr_values;
    if (!GetCurrentPcrValues(&pcr_values)) {
      LOG(ERROR) << "Error reading PCR values";
      return false;
    }
    if (!backend()->CreateSealedSecret(key_spki_der_,
                                       param_.supported_algorithms,
                                       {pcr_values, pcr_values}, delegate_blob_,
                                       delegate_secret_, sealed_secret_data)) {
      LOG(ERROR) << "Error creating signature-sealed secret";
      return false;
    }
    return true;
  }

  bool CheckSecretCreationFails() {
    std::map<uint32_t, Blob> pcr_values;
    if (!GetCurrentPcrValues(&pcr_values)) {
      LOG(ERROR) << "Error reading PCR values";
      return false;
    }
    SignatureSealedData sealed_secret_data;
    if (backend()->CreateSealedSecret(
            key_spki_der_, param_.supported_algorithms, {pcr_values},
            delegate_blob_, delegate_secret_, &sealed_secret_data)) {
      LOG(ERROR) << "Error: secret creation completed unexpectedly";
      return false;
    }
    return true;
  }

  bool GetCurrentPcrValues(std::map<uint32_t, Blob>* pcr_values) {
    for (auto pcr_index : kPcrIndexes) {
      if (!tpm()->ReadPCR(pcr_index, &(*pcr_values)[pcr_index])) {
        LOG(ERROR) << "Error reading PCR value " << pcr_index;
        return false;
      }
    }
    return true;
  }

  bool Unseal(const SignatureSealedData& sealed_secret_data,
              Blob* challenge_value,
              Blob* challenge_signature,
              SecureBlob* unsealed_value) {
    std::unique_ptr<UnsealingSession> unsealing_session(
        backend()->CreateUnsealingSession(sealed_secret_data, key_spki_der_,
                                          param_.supported_algorithms,
                                          delegate_blob_, delegate_secret_));
    if (!unsealing_session) {
      LOG(ERROR) << "Error starting the unsealing session";
      return false;
    }
    if (unsealing_session->GetChallengeAlgorithm() !=
        *param_.expected_algorithm) {
      LOG(ERROR) << "Wrong challenge signature algorithm";
      return false;
    }
    *challenge_value = unsealing_session->GetChallengeValue();
    if (challenge_value->empty()) {
      LOG(ERROR) << "The challenge is empty";
      return false;
    }
    if (!SignWithKey(*challenge_value, param_.openssl_algorithm_nid,
                     challenge_signature)) {
      LOG(ERROR) << "Error generating signature of challenge";
      return false;
    }
    if (!unsealing_session->Unseal(*challenge_signature, unsealed_value)) {
      LOG(ERROR) << "Error unsealing the secret";
      return false;
    }
    if (unsealed_value->empty()) {
      LOG(ERROR) << "Error: empty unsealing result";
      return false;
    }
    return true;
  }

  bool CheckUnsealingFailsWithOldSignature(
      const SignatureSealedData& sealed_secret_data,
      const Blob& challenge_signature) {
    std::unique_ptr<UnsealingSession> unsealing_session(
        backend()->CreateUnsealingSession(sealed_secret_data, key_spki_der_,
                                          param_.supported_algorithms,
                                          delegate_blob_, delegate_secret_));
    if (!unsealing_session) {
      LOG(ERROR) << "Error starting the unsealing session";
      return false;
    }
    SecureBlob unsealed_value;
    if (unsealing_session->Unseal(challenge_signature, &unsealed_value)) {
      LOG(ERROR)
          << "Error: unsealing completed with an old challenge signature";
      return false;
    }
    return true;
  }

  bool CheckUnsealingFailsWithBadAlgorithmSignature(
      const SignatureSealedData& sealed_secret_data) {
    std::unique_ptr<UnsealingSession> unsealing_session(
        backend()->CreateUnsealingSession(sealed_secret_data, key_spki_der_,
                                          param_.supported_algorithms,
                                          delegate_blob_, delegate_secret_));
    if (!unsealing_session) {
      LOG(ERROR) << "Error starting the unsealing session";
      return false;
    }
    const int wrong_openssl_algorithm_nid =
        param_.openssl_algorithm_nid == NID_sha1 ? NID_sha256 : NID_sha1;
    Blob challenge_signature;
    if (!SignWithKey(unsealing_session->GetChallengeValue(),
                     wrong_openssl_algorithm_nid, &challenge_signature)) {
      LOG(ERROR) << "Error generating signature of challenge";
      return false;
    }
    SecureBlob unsealed_value;
    if (unsealing_session->Unseal(challenge_signature, &unsealed_value)) {
      LOG(ERROR) << "Error: unsealing completed with a wrong signature";
      return false;
    }
    return true;
  }

  bool CheckUnsealingFailsWithBadSignature(
      const SignatureSealedData& sealed_secret_data) {
    std::unique_ptr<UnsealingSession> unsealing_session(
        backend()->CreateUnsealingSession(sealed_secret_data, key_spki_der_,
                                          param_.supported_algorithms,
                                          delegate_blob_, delegate_secret_));
    if (!unsealing_session) {
      LOG(ERROR) << "Error starting the unsealing session";
      return false;
    }
    Blob challenge_signature;
    if (!SignWithKey(unsealing_session->GetChallengeValue(),
                     param_.openssl_algorithm_nid, &challenge_signature)) {
      LOG(ERROR) << "Error generating signature of challenge";
      return false;
    }
    challenge_signature.front() ^= 1;
    SecureBlob unsealed_value;
    if (unsealing_session->Unseal(challenge_signature, &unsealed_value)) {
      LOG(ERROR) << "Error: unsealing completed with a wrong signature";
      return false;
    }
    return true;
  }

  bool CheckUnsealingFailsWithWrongAlgorithm(
      const SignatureSealedData& sealed_secret_data) {
    const ChallengeSignatureAlgorithm wrong_algorithm =
        *param_.expected_algorithm == CHALLENGE_RSASSA_PKCS1_V1_5_SHA1
            ? CHALLENGE_RSASSA_PKCS1_V1_5_SHA256
            : CHALLENGE_RSASSA_PKCS1_V1_5_SHA1;
    if (backend()->CreateUnsealingSession(sealed_secret_data, key_spki_der_,
                                          {wrong_algorithm}, delegate_blob_,
                                          delegate_secret_)) {
      LOG(ERROR) << "Error: unsealing session creation completed with a "
                    "wrong algorithm";
      return false;
    }
    return true;
  }

  bool CheckUnsealingFailsWithWrongKey(
      const SignatureSealedData& sealed_secret_data) {
    crypto::ScopedEVP_PKEY other_pkey;
    Blob other_key_spki_der;
    if (!GenerateRsaKey(param_.key_size_bits, &other_pkey,
                        &other_key_spki_der)) {
      LOG(ERROR) << "Error generating the other RSA key";
      return false;
    }
    if (backend()->CreateUnsealingSession(
            sealed_secret_data, other_key_spki_der, param_.supported_algorithms,
            delegate_blob_, delegate_secret_)) {
      LOG(ERROR)
          << "Error: unsealing session creation completed with a wrong key";
      return false;
    }
    return true;
  }

  bool CheckUnsealingFailsWithChangedPcrs(
      const SignatureSealedData& sealed_secret_data) {
    if (!tpm()->ExtendPCR(kPcrIndexToExtend,
                          BlobFromString("01234567890123456789"))) {
      LOG(ERROR) << "Error extending PCR";
      return false;
    }
    std::unique_ptr<UnsealingSession> unsealing_session(
        backend()->CreateUnsealingSession(sealed_secret_data, key_spki_der_,
                                          param_.supported_algorithms,
                                          delegate_blob_, delegate_secret_));
    if (!unsealing_session) {
      // Unsealing expectedly failed, so the test is passed. (Whether it fails
      // here or below after Unseal() depends on the specific
      // SignatureSealingBackend implementation.)
      return true;
    }
    Blob challenge_signature;
    if (!SignWithKey(unsealing_session->GetChallengeValue(),
                     param_.openssl_algorithm_nid, &challenge_signature)) {
      LOG(ERROR) << "Error generating signature of challenge";
      return false;
    }
    SecureBlob unsealed_value;
    if (unsealing_session->Unseal(challenge_signature, &unsealed_value)) {
      LOG(ERROR) << "Error: unsealing completed with changed PCRs";
      return false;
    }
    return true;
  }

  bool SignWithKey(const Blob& unhashed_data,
                   int algorithm_nid,
                   Blob* signature) {
    signature->resize(EVP_PKEY_size(pkey_.get()));
    crypto::ScopedEVP_MD_CTX sign_context(EVP_MD_CTX_create());
    EVP_MD_CTX_init(sign_context.get());
    unsigned signature_size = 0;
    if (!sign_context) {
      LOG(ERROR) << "Error creating signing context";
      return false;
    }
    if (!EVP_SignInit(sign_context.get(), EVP_get_digestbynid(algorithm_nid))) {
      LOG(ERROR) << "Error initializing signature operation";
      return false;
    }
    if (!EVP_SignUpdate(sign_context.get(), unhashed_data.data(),
                        unhashed_data.size())) {
      LOG(ERROR) << "Error updating signature operation with data";
      return false;
    }
    if (!EVP_SignFinal(sign_context.get(), signature->data(), &signature_size,
                       pkey_.get())) {
      LOG(ERROR) << "Error finalizing signature operation";
      return false;
    }
    CHECK_LE(signature_size, signature->size());
    signature->resize(signature_size);
    return true;
  }

  const SignatureSealedSecretTestCaseParam param_;
  const SecureBlob owner_password_;
  Blob delegate_blob_;
  Blob delegate_secret_;
  crypto::ScopedEVP_PKEY pkey_;
  Blob key_spki_der_;

  DISALLOW_COPY_AND_ASSIGN(SignatureSealedSecretTestCase);
};

}  // namespace

bool TpmLiveTest::SignatureSealedSecretTest(const SecureBlob& owner_password) {
  using TestCaseParam = SignatureSealedSecretTestCaseParam;
  if (!tpm_->GetSignatureSealingBackend()) {
    // Not supported by the Tpm implementation, just skip the test.
    return true;
  }
  LOG(INFO) << "SignatureSealedSecretTest started";
  std::vector<TestCaseParam> test_case_params;
  for (int key_size_bits : {1024, 2048}) {
    test_case_params.push_back(TestCaseParam::MakeSuccessful(
        "SHA-1", tpm_, key_size_bits, {CHALLENGE_RSASSA_PKCS1_V1_5_SHA1},
        CHALLENGE_RSASSA_PKCS1_V1_5_SHA1, NID_sha1));
    if (tpm_->GetVersion() == Tpm::TPM_1_2) {
      test_case_params.push_back(
          TestCaseParam::MakeFailing("SHA-256", tpm_, key_size_bits,
                                     {CHALLENGE_RSASSA_PKCS1_V1_5_SHA256}));
      test_case_params.push_back(
          TestCaseParam::MakeFailing("SHA-384", tpm_, key_size_bits,
                                     {CHALLENGE_RSASSA_PKCS1_V1_5_SHA384}));
      test_case_params.push_back(
          TestCaseParam::MakeFailing("SHA-512", tpm_, key_size_bits,
                                     {CHALLENGE_RSASSA_PKCS1_V1_5_SHA512}));
      test_case_params.push_back(TestCaseParam::MakeSuccessful(
          "{SHA-1,SHA-256}", tpm_, key_size_bits,
          {CHALLENGE_RSASSA_PKCS1_V1_5_SHA256,
           CHALLENGE_RSASSA_PKCS1_V1_5_SHA1},
          CHALLENGE_RSASSA_PKCS1_V1_5_SHA1, NID_sha1));
    } else {
      test_case_params.push_back(TestCaseParam::MakeSuccessful(
          "SHA-256", tpm_, key_size_bits, {CHALLENGE_RSASSA_PKCS1_V1_5_SHA256},
          CHALLENGE_RSASSA_PKCS1_V1_5_SHA256, NID_sha256));
      test_case_params.push_back(TestCaseParam::MakeSuccessful(
          "SHA-384", tpm_, key_size_bits, {CHALLENGE_RSASSA_PKCS1_V1_5_SHA384},
          CHALLENGE_RSASSA_PKCS1_V1_5_SHA384, NID_sha384));
      test_case_params.push_back(TestCaseParam::MakeSuccessful(
          "SHA-512", tpm_, key_size_bits, {CHALLENGE_RSASSA_PKCS1_V1_5_SHA512},
          CHALLENGE_RSASSA_PKCS1_V1_5_SHA512, NID_sha512));
      test_case_params.push_back(TestCaseParam::MakeSuccessful(
          "{SHA-384,SHA-256,SHA-512}", tpm_, key_size_bits,
          {CHALLENGE_RSASSA_PKCS1_V1_5_SHA384,
           CHALLENGE_RSASSA_PKCS1_V1_5_SHA256,
           CHALLENGE_RSASSA_PKCS1_V1_5_SHA512},
          CHALLENGE_RSASSA_PKCS1_V1_5_SHA384, NID_sha384));
      test_case_params.push_back(TestCaseParam::MakeSuccessful(
          "{SHA-1,SHA-256}", tpm_, key_size_bits,
          {CHALLENGE_RSASSA_PKCS1_V1_5_SHA1,
           CHALLENGE_RSASSA_PKCS1_V1_5_SHA256},
          CHALLENGE_RSASSA_PKCS1_V1_5_SHA256, NID_sha256));
    }
  }
  for (auto&& test_case_param : test_case_params) {
    SignatureSealedSecretTestCase test_case(std::move(test_case_param),
                                            owner_password);
    if (!test_case.SetUp() || !test_case.Run())
      return false;
  }
  LOG(INFO) << "SignatureSealedSecretTest ended successfully.";
  return true;
}

}  // namespace cryptohome
