// Copyright 2022 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/auth_blocks/auth_block_utility_impl.h"

#include <memory>
#include <optional>
#include <string>
#include <utility>
#include <variant>

#include <base/files/file_path.h>
#include <base/files/scoped_temp_dir.h>
#include <base/test/bind.h>
#include <brillo/cryptohome.h>
#include <brillo/secure_blob.h>
#include <gmock/gmock.h>
#include <gtest/gtest.h>
#include <libhwsec-foundation/crypto/scrypt.h>
#include <libhwsec-foundation/error/testing_helper.h>

#include "cryptohome/auth_blocks/auth_block.h"
#include "cryptohome/auth_blocks/auth_block_state.h"
#include "cryptohome/auth_blocks/auth_block_type.h"
#include "cryptohome/auth_blocks/challenge_credential_auth_block.h"
#include "cryptohome/auth_blocks/double_wrapped_compat_auth_block.h"
#include "cryptohome/auth_blocks/libscrypt_compat_auth_block.h"
#include "cryptohome/auth_blocks/pin_weaver_auth_block.h"
#include "cryptohome/auth_blocks/tpm_bound_to_pcr_auth_block.h"
#include "cryptohome/auth_blocks/tpm_ecc_auth_block.h"
#include "cryptohome/auth_blocks/tpm_not_bound_to_pcr_auth_block.h"
#include "cryptohome/challenge_credentials/mock_challenge_credentials_helper.h"
#include "cryptohome/credentials.h"
#include "cryptohome/crypto.h"
#include "cryptohome/crypto_error.h"
#include "cryptohome/fake_le_credential_backend.h"
#include "cryptohome/filesystem_layout.h"
#include "cryptohome/key_objects.h"
#include "cryptohome/le_credential_manager_impl.h"
#include "cryptohome/mock_cryptohome_keys_manager.h"
#include "cryptohome/mock_key_challenge_service.h"
#include "cryptohome/mock_keyset_management.h"
#include "cryptohome/mock_le_credential_manager.h"
#include "cryptohome/mock_platform.h"
#include "cryptohome/mock_tpm.h"
#include "cryptohome/mock_vault_keyset.h"
#include "cryptohome/vault_keyset.h"

using ::cryptohome::error::CryptohomeCryptoError;
using ::cryptohome::error::CryptohomeLECredError;
using ::hwsec::TPMErrorBase;
using ::hwsec_foundation::DeriveSecretsScrypt;
using ::hwsec_foundation::error::testing::ReturnError;
using ::testing::_;
using ::testing::ByMove;
using ::testing::DoAll;
using ::testing::Exactly;
using ::testing::Mock;
using ::testing::NiceMock;
using ::testing::Return;
using ::testing::SaveArg;
using ::testing::SetArgPointee;

namespace cryptohome {

namespace {
constexpr char kUser[] = "Test User";
}  // namespace

class AuthBlockUtilityImplTest : public ::testing::Test {
 public:
  AuthBlockUtilityImplTest() : crypto_(&platform_) {}
  AuthBlockUtilityImplTest(const AuthBlockUtilityImplTest&) = delete;
  AuthBlockUtilityImplTest& operator=(const AuthBlockUtilityImplTest&) = delete;
  virtual ~AuthBlockUtilityImplTest() {}

  void SetUp() override {
    // Setup salt for brillo functions.
    keyset_management_ = std::make_unique<KeysetManagement>(
        &platform_, &crypto_, std::make_unique<VaultKeysetFactory>());
    system_salt_ =
        brillo::SecureBlob(*brillo::cryptohome::home::GetSystemSalt());
  }

 protected:
  MockPlatform platform_;
  Crypto crypto_;
  brillo::SecureBlob system_salt_;
  NiceMock<MockCryptohomeKeysManager> cryptohome_keys_manager_;
  NiceMock<MockTpm> tpm_;
  std::unique_ptr<KeysetManagement> keyset_management_;
  std::unique_ptr<AuthBlockUtilityImpl> auth_block_utility_impl_;
  NiceMock<MockChallengeCredentialsHelper> challenge_credentials_helper_;
};

// Test that CreateKeyBlobsWithAuthBlock creates AuthBlockState and KeyBlobs
// with PinWeaverAuthBlock when the AuthBlock type is low entropy credential.
TEST_F(AuthBlockUtilityImplTest, CreatePinweaverAuthBlockTest) {
  // Setup mock expectations and test inputs for low entropy AuthBlock.
  brillo::SecureBlob passkey(20, 'A');
  Credentials credentials(kUser, passkey);
  brillo::SecureBlob reset_secret(32, 'S');
  brillo::SecureBlob le_secret;

  MockLECredentialManager* le_cred_manager = new MockLECredentialManager();

  EXPECT_CALL(*le_cred_manager, InsertCredential(_, _, _, _, _, _))
      .WillOnce(
          DoAll(SaveArg<0>(&le_secret), ReturnError<CryptohomeLECredError>()));
  crypto_.set_le_manager_for_testing(
      std::unique_ptr<cryptohome::LECredentialManager>(le_cred_manager));
  crypto_.Init(&tpm_, &cryptohome_keys_manager_);

  auth_block_utility_impl_ = std::make_unique<AuthBlockUtilityImpl>(
      keyset_management_.get(), &crypto_, &platform_);

  // Test
  KeyBlobs out_key_blobs;
  AuthBlockState out_state;
  EXPECT_TRUE(auth_block_utility_impl_
                  ->CreateKeyBlobsWithAuthBlock(AuthBlockType::kPinWeaver,
                                                credentials, reset_secret,
                                                out_state, out_key_blobs)
                  .ok());

  // Verify that a PinWeaver AuthBlock is generated.
  EXPECT_TRUE(std::holds_alternative<PinWeaverAuthBlockState>(out_state.state));
  auto& pinweaver_state = std::get<PinWeaverAuthBlockState>(out_state.state);
  EXPECT_TRUE(pinweaver_state.salt.has_value());
}

// Test that DeriveKeyBlobsWithAuthBlock derives KeyBlobs with
// PinWeaverAuthBlock type when the Authblock type is low entropy credential.
TEST_F(AuthBlockUtilityImplTest, DerivePinWeaverAuthBlock) {
  // Setup mock expectations and test inputs for low entropy AuthBlock.
  brillo::SecureBlob passkey(20, 'C');
  Credentials credentials(kUser, passkey);
  brillo::SecureBlob le_secret(32);
  brillo::SecureBlob chaps_iv(16, 'F');
  brillo::SecureBlob fek_iv(16, 'X');
  brillo::SecureBlob salt(system_salt_);

  MockLECredentialManager* le_cred_manager = new MockLECredentialManager();

  crypto_.set_le_manager_for_testing(
      std::unique_ptr<cryptohome::LECredentialManager>(le_cred_manager));
  crypto_.Init(&tpm_, &cryptohome_keys_manager_);

  ASSERT_TRUE(DeriveSecretsScrypt(passkey, salt, {&le_secret}));

  ON_CALL(*le_cred_manager, CheckCredential(_, _, _, _))
      .WillByDefault(ReturnError<CryptohomeLECredError>());
  EXPECT_CALL(*le_cred_manager, CheckCredential(_, le_secret, _, _))
      .Times(Exactly(1));

  auth_block_utility_impl_ = std::make_unique<AuthBlockUtilityImpl>(
      keyset_management_.get(), &crypto_, &platform_);

  PinWeaverAuthBlockState pin_state = {
      .le_label = 0, .salt = salt, .chaps_iv = chaps_iv, .fek_iv = fek_iv};
  AuthBlockState auth_state = {.state = pin_state};

  // Test
  // No need to check for the KeyBlobs value, it is already being tested in
  // AuthBlock unittest.
  KeyBlobs out_key_blobs;
  EXPECT_TRUE(auth_block_utility_impl_
                  ->DeriveKeyBlobsWithAuthBlock(AuthBlockType::kPinWeaver,
                                                credentials, auth_state,
                                                out_key_blobs)
                  .ok());
}

// Test that CreateKeyBlobsWithAuthBlock creates AuthBlockState and KeyBlobs
// with TpmBoundToPcrAuthBlock when the AuthBlock type is
// AuthBlockType::kTpmBoundToPcr.
TEST_F(AuthBlockUtilityImplTest, CreateTpmBackedPcrBoundAuthBlock) {
  // Setup test inputs and the mock expectations..
  brillo::SecureBlob passkey(20, 'A');
  Credentials credentials(kUser, passkey);

  brillo::SecureBlob scrypt_derived_key;
  crypto_.Init(&tpm_, &cryptohome_keys_manager_);

  brillo::SecureBlob auth_value(256, 'a');
  EXPECT_CALL(tpm_, GetAuthValue(_, _, _))
      .WillOnce(DoAll(SaveArg<1>(&scrypt_derived_key),
                      SetArgPointee<2>(auth_value),
                      ReturnError<TPMErrorBase>()));
  EXPECT_CALL(tpm_, SealToPcrWithAuthorization(_, auth_value, _, _))
      .Times(Exactly(2));
  ON_CALL(tpm_, SealToPcrWithAuthorization(_, _, _, _))
      .WillByDefault(ReturnError<TPMErrorBase>());

  auth_block_utility_impl_ = std::make_unique<AuthBlockUtilityImpl>(
      keyset_management_.get(), &crypto_, &platform_);

  // Test
  KeyBlobs out_key_blobs;
  AuthBlockState out_state;
  EXPECT_TRUE(auth_block_utility_impl_
                  ->CreateKeyBlobsWithAuthBlock(AuthBlockType::kTpmBoundToPcr,
                                                credentials, std::nullopt,
                                                out_state, out_key_blobs)
                  .ok());

  // Verify that tpm backed pcr bound auth block is created.
  EXPECT_TRUE(
      std::holds_alternative<TpmBoundToPcrAuthBlockState>(out_state.state));
  EXPECT_NE(out_key_blobs.vkk_key, std::nullopt);
  EXPECT_NE(out_key_blobs.vkk_iv, std::nullopt);
  EXPECT_NE(out_key_blobs.chaps_iv, std::nullopt);
  auto& tpm_state = std::get<TpmBoundToPcrAuthBlockState>(out_state.state);
  EXPECT_TRUE(tpm_state.salt.has_value());
}

// Test that DeriveKeyBlobsWithAuthBlock derive KeyBlobs successfully with
// TpmBoundToPcrAuthBlock when the AuthBlock type is
// AuthBlockType::kTpmBoundToPcr.
TEST_F(AuthBlockUtilityImplTest, DeriveTpmBackedPcrBoundAuthBlock) {
  // Setup test inputs and the mock expectations.
  brillo::SecureBlob passkey(20, 'A');
  Credentials credentials(kUser, passkey);
  brillo::SecureBlob tpm_key(20, 'B');
  brillo::SecureBlob salt(system_salt_);
  crypto_.Init(&tpm_, &cryptohome_keys_manager_);

  // Make sure TpmAuthBlock calls DecryptTpmBoundToPcr in this case.
  EXPECT_CALL(tpm_, PreloadSealedData(_, _)).Times(Exactly(1));
  EXPECT_CALL(tpm_, GetAuthValue(_, _, _)).Times(Exactly(1));
  EXPECT_CALL(tpm_, UnsealWithAuthorization(_, _, _, _, _)).Times(Exactly(1));

  TpmBoundToPcrAuthBlockState tpm_state = {.scrypt_derived = true,
                                           .salt = salt,
                                           .tpm_key = tpm_key,
                                           .extended_tpm_key = tpm_key};
  AuthBlockState auth_state = {.state = tpm_state};

  // Test
  KeyBlobs out_key_blobs;
  auth_block_utility_impl_ = std::make_unique<AuthBlockUtilityImpl>(
      keyset_management_.get(), &crypto_, &platform_);

  EXPECT_TRUE(auth_block_utility_impl_
                  ->DeriveKeyBlobsWithAuthBlock(AuthBlockType::kTpmBoundToPcr,
                                                credentials, auth_state,
                                                out_key_blobs)
                  .ok());
}

// Test that CreateKeyBlobsWithAuthBlock creates AuthBlockState and KeyBlobs
// with TpmNotBoundToPcrAuthBlock when the AuthBlock type is
// AuthBlockType::kTpmNotBoundToPcr.
TEST_F(AuthBlockUtilityImplTest, CreateTpmBackedNonPcrBoundAuthBlock) {
  // Setup test inputs and the mock expectations.
  brillo::SecureBlob passkey(20, 'A');
  Credentials credentials(kUser, passkey);
  brillo::SecureBlob aes_key;
  crypto_.Init(&tpm_, &cryptohome_keys_manager_);

  EXPECT_CALL(tpm_, EncryptBlob(_, _, _, _))
      .WillOnce(DoAll(SaveArg<2>(&aes_key), ReturnError<TPMErrorBase>()));

  // Test
  auth_block_utility_impl_ = std::make_unique<AuthBlockUtilityImpl>(
      keyset_management_.get(), &crypto_, &platform_);
  KeyBlobs out_key_blobs;
  AuthBlockState out_state;
  EXPECT_TRUE(auth_block_utility_impl_
                  ->CreateKeyBlobsWithAuthBlock(
                      AuthBlockType::kTpmNotBoundToPcr, credentials,
                      std::nullopt, out_state, out_key_blobs)
                  .ok());

  // Verify that Tpm backed not pcr bound Authblock is created.
  EXPECT_TRUE(
      std::holds_alternative<TpmNotBoundToPcrAuthBlockState>(out_state.state));
  EXPECT_NE(out_key_blobs.vkk_key, std::nullopt);
  EXPECT_NE(out_key_blobs.vkk_iv, std::nullopt);
  EXPECT_NE(out_key_blobs.chaps_iv, std::nullopt);
  auto& tpm_state = std::get<TpmNotBoundToPcrAuthBlockState>(out_state.state);
  EXPECT_TRUE(tpm_state.salt.has_value());
}

// Test that DeriveKeyBlobsWithAuthBlock derive KeyBlobs successfully with
// TpmNotBoundToPcrAuthBlock when the AuthBlock type is
// AuthBlockType::kTpmNotBoundToPcr.
TEST_F(AuthBlockUtilityImplTest, DeriveTpmBackedNonPcrBoundAuthBlock) {
  // Setup test inputs and the mock expectations.
  brillo::SecureBlob passkey(20, 'A');
  Credentials credentials(kUser, passkey);
  brillo::SecureBlob tpm_key(20, 'B');
  brillo::SecureBlob salt(system_salt_);
  brillo::SecureBlob aes_key(32);
  crypto_.Init(&tpm_, &cryptohome_keys_manager_);
  ASSERT_TRUE(DeriveSecretsScrypt(passkey, salt, {&aes_key}));
  EXPECT_CALL(tpm_, DecryptBlob(_, tpm_key, aes_key, _)).Times(Exactly(1));

  TpmNotBoundToPcrAuthBlockState tpm_state = {
      .scrypt_derived = true, .salt = salt, .tpm_key = tpm_key};
  AuthBlockState auth_state = {.state = tpm_state};

  // Test
  KeyBlobs out_key_blobs;
  auth_block_utility_impl_ = std::make_unique<AuthBlockUtilityImpl>(
      keyset_management_.get(), &crypto_, &platform_);

  EXPECT_TRUE(
      auth_block_utility_impl_
          ->DeriveKeyBlobsWithAuthBlock(AuthBlockType::kTpmNotBoundToPcr,
                                        credentials, auth_state, out_key_blobs)
          .ok());
}

// Test that CreateKeyBlobsWithAuthBlock creates AuthBlockState and KeyBlobs
// with TpmEccAuthBlock when the AuthBlock type is AuthBlockType::kTpmEcc.
TEST_F(AuthBlockUtilityImplTest, CreateTpmBackedEccAuthBlock) {
  // Setup test inputs and the mock expectations.
  brillo::SecureBlob passkey(20, 'A');
  Credentials credentials(kUser, passkey);
  crypto_.Init(&tpm_, &cryptohome_keys_manager_);

  brillo::SecureBlob scrypt_derived_key;
  brillo::SecureBlob auth_value(32, 'a');
  Tpm::TpmVersionInfo version_info;
  version_info.manufacturer = 0x43524f53;
  EXPECT_CALL(tpm_, GetVersionInfo(_))
      .WillOnce(DoAll(SetArgPointee<0>(version_info), Return(true)));
  EXPECT_CALL(tpm_, GetEccAuthValue(_, _, _))
      .Times(Exactly(5))
      .WillOnce(DoAll(SaveArg<1>(&scrypt_derived_key),
                      SetArgPointee<2>(auth_value),
                      ReturnError<TPMErrorBase>()))
      .WillRepeatedly(
          DoAll(SetArgPointee<2>(auth_value), ReturnError<TPMErrorBase>()));
  EXPECT_CALL(tpm_, SealToPcrWithAuthorization(_, auth_value, _, _))
      .WillOnce(ReturnError<TPMErrorBase>())
      .WillOnce(ReturnError<TPMErrorBase>());

  auth_block_utility_impl_ = std::make_unique<AuthBlockUtilityImpl>(
      keyset_management_.get(), &crypto_, &platform_);

  // Test
  KeyBlobs out_key_blobs;
  AuthBlockState out_state;
  EXPECT_TRUE(auth_block_utility_impl_
                  ->CreateKeyBlobsWithAuthBlock(AuthBlockType::kTpmEcc,
                                                credentials, std::nullopt,
                                                out_state, out_key_blobs)
                  .ok());

  // Verify that Tpm Ecc AuthBlock is created.
  EXPECT_TRUE(std::holds_alternative<TpmEccAuthBlockState>(out_state.state));
  EXPECT_NE(out_key_blobs.vkk_key, std::nullopt);
  EXPECT_NE(out_key_blobs.vkk_iv, std::nullopt);
  EXPECT_NE(out_key_blobs.chaps_iv, std::nullopt);
  auto& tpm_state = std::get<TpmEccAuthBlockState>(out_state.state);
  EXPECT_TRUE(tpm_state.salt.has_value());
}

// Test that DeriveKeyBlobsWithAuthBlock derives KeyBlobs successfully with
// TpmEccAuthBlock when the AuthBlock type is
// AuthBlockType::kTpmEcc.
TEST_F(AuthBlockUtilityImplTest, DeriveTpmBackedEccAuthBlock) {
  // Setup test inputs and the mock expectations.
  brillo::SecureBlob passkey(20, 'A');
  Credentials credentials(kUser, passkey);
  brillo::SecureBlob salt(system_salt_);
  brillo::SecureBlob fake_hash(32, 'C');
  crypto_.Init(&tpm_, &cryptohome_keys_manager_);

  EXPECT_CALL(tpm_, GetPublicKeyHash(_, _))
      .WillOnce(
          DoAll(SetArgPointee<1>(fake_hash), ReturnError<TPMErrorBase>()));
  EXPECT_CALL(tpm_, PreloadSealedData(_, _)).Times(Exactly(1));
  EXPECT_CALL(tpm_, GetEccAuthValue(_, _, _)).Times(Exactly(5));

  brillo::SecureBlob fake_hvkkm(32, 'D');
  EXPECT_CALL(tpm_, UnsealWithAuthorization(_, _, _, _, _))
      .WillOnce(
          DoAll(SetArgPointee<4>(fake_hvkkm), ReturnError<TPMErrorBase>()));

  TpmEccAuthBlockState tpm_state;
  tpm_state.salt = salt;
  tpm_state.vkk_iv = brillo::SecureBlob(32, 'E');
  tpm_state.sealed_hvkkm = brillo::SecureBlob(32, 'F');
  tpm_state.extended_sealed_hvkkm = brillo::SecureBlob(32, 'G');
  tpm_state.auth_value_rounds = 5;
  tpm_state.tpm_public_key_hash = fake_hash;
  AuthBlockState auth_state = {.state = tpm_state};

  // Test
  KeyBlobs out_key_blobs;
  auth_block_utility_impl_ = std::make_unique<AuthBlockUtilityImpl>(
      keyset_management_.get(), &crypto_, &platform_);

  EXPECT_TRUE(auth_block_utility_impl_
                  ->DeriveKeyBlobsWithAuthBlock(AuthBlockType::kTpmEcc,
                                                credentials, auth_state,
                                                out_key_blobs)
                  .ok());
}

// Test that CreateKeyBlobsWithAuthBlock creates AuthBlockState with
// LibScryptCompatAuthBlock when the AuthBlock type is
// AuthBlockType::kLibScryptCompat.
TEST_F(AuthBlockUtilityImplTest, CreateScryptAuthBlockTest) {
  // Setup mock expectations and test inputs for low entropy AuthBlock.
  brillo::SecureBlob passkey(20, 'A');
  Credentials credentials(kUser, passkey);

  auth_block_utility_impl_ = std::make_unique<AuthBlockUtilityImpl>(
      keyset_management_.get(), &crypto_, &platform_);

  // Test
  KeyBlobs out_key_blobs;
  AuthBlockState out_state;
  EXPECT_TRUE(auth_block_utility_impl_
                  ->CreateKeyBlobsWithAuthBlock(AuthBlockType::kLibScryptCompat,
                                                credentials, std::nullopt,
                                                out_state, out_key_blobs)
                  .ok());

  // Verify that a script wrapped AuthBlock is generated.
  EXPECT_TRUE(
      std::holds_alternative<LibScryptCompatAuthBlockState>(out_state.state));
  auto& scrypt_state = std::get<LibScryptCompatAuthBlockState>(out_state.state);
  EXPECT_TRUE(scrypt_state.salt.has_value());
}

// Test that DeriveKeyBlobsWithAuthBlock derives AuthBlocks with
// LibScryptCompatAuthBlock when the AuthBlock type is
// AuthBlockType::kLibScryptCompat.
TEST_F(AuthBlockUtilityImplTest, DeriveScryptAuthBlock) {
  // Setup test inputs and the mock expectations.
  brillo::SecureBlob wrapped_keyset = {
      0x73, 0x63, 0x72, 0x79, 0x70, 0x74, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x08,
      0x00, 0x00, 0x00, 0x01, 0x4D, 0xEE, 0xFC, 0x79, 0x0D, 0x79, 0x08, 0x79,
      0xD5, 0xF6, 0x07, 0x65, 0xDF, 0x76, 0x5A, 0xAE, 0xD1, 0xBD, 0x1D, 0xCF,
      0x29, 0xF6, 0xFF, 0x5C, 0x31, 0x30, 0x23, 0xD1, 0x22, 0x17, 0xDF, 0x74,
      0x26, 0xD5, 0x11, 0x88, 0x8D, 0x40, 0xA6, 0x9C, 0xB9, 0x72, 0xCE, 0x37,
      0x71, 0xB7, 0x39, 0x0E, 0x3E, 0x34, 0x0F, 0x73, 0x29, 0xF4, 0x0F, 0x89,
      0x15, 0xF7, 0x6E, 0xA1, 0x5A, 0x29, 0x78, 0x21, 0xB7, 0xC0, 0x76, 0x50,
      0x14, 0x5C, 0xAD, 0x77, 0x53, 0xC9, 0xD0, 0xFE, 0xD1, 0xB9, 0x81, 0x32,
      0x75, 0x0E, 0x1E, 0x45, 0x34, 0xBD, 0x0B, 0xF7, 0xFA, 0xED, 0x9A, 0xD7,
      0x6B, 0xE4, 0x2F, 0xC0, 0x2F, 0x58, 0xBE, 0x3A, 0x26, 0xD1, 0x82, 0x41,
      0x09, 0x82, 0x7F, 0x17, 0xA8, 0x5C, 0x66, 0x0E, 0x24, 0x8B, 0x7B, 0xF5,
      0xEB, 0x0C, 0x6D, 0xAE, 0x19, 0x5C, 0x7D, 0xC4, 0x0D, 0x8D, 0xB2, 0x18,
      0x13, 0xD4, 0xC0, 0x32, 0x34, 0x15, 0xAE, 0x1D, 0xA1, 0x44, 0x2E, 0x80,
      0xD8, 0x00, 0x8A, 0xB9, 0xDD, 0xA4, 0xC0, 0x33, 0xAE, 0x26, 0xD3, 0xE6,
      0x53, 0xD6, 0x31, 0x5C, 0x4C, 0x10, 0xBB, 0xA9, 0xD5, 0x53, 0xD7, 0xAD,
      0xCD, 0x97, 0x20, 0x83, 0xFC, 0x18, 0x4B, 0x7F, 0xC1, 0xBD, 0x85, 0x43,
      0x12, 0x85, 0x4F, 0x6F, 0xAA, 0xDB, 0x58, 0xA0, 0x0F, 0x2C, 0xAB, 0xEA,
      0x74, 0x8E, 0x2C, 0x28, 0x01, 0x88, 0x48, 0xA5, 0x0A, 0xFC, 0x2F, 0xB4,
      0x59, 0x4B, 0xF6, 0xD9, 0xE5, 0x47, 0x94, 0x42, 0xA5, 0x61, 0x06, 0x8C,
      0x5A, 0x9C, 0xD3, 0xA6, 0x30, 0x2C, 0x13, 0xCA, 0xF1, 0xFF, 0xFE, 0x5C,
      0xE8, 0x21, 0x25, 0x9A, 0xE0, 0x50, 0xC3, 0x2F, 0x14, 0x71, 0x38, 0xD0,
      0xE7, 0x79, 0x5D, 0xF0, 0x71, 0x80, 0xF0, 0x3D, 0x05, 0xB6, 0xF7, 0x67,
      0x3F, 0x22, 0x21, 0x7A, 0xED, 0x48, 0xC4, 0x2D, 0xEA, 0x2E, 0xAE, 0xE9,
      0xA8, 0xFF, 0xA0, 0xB6, 0xB4, 0x0A, 0x94, 0x34, 0x40, 0xD1, 0x6C, 0x6C,
      0xC7, 0x90, 0x9C, 0xF7, 0xED, 0x0B, 0xED, 0x90, 0xB1, 0x4D, 0x6D, 0xB4,
      0x3D, 0x04, 0x7E, 0x7B, 0x16, 0x59, 0xFF, 0xFE};

  brillo::SecureBlob wrapped_chaps_key = {
      0x73, 0x63, 0x72, 0x79, 0x70, 0x74, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x08,
      0x00, 0x00, 0x00, 0x01, 0xC9, 0x80, 0xA1, 0x30, 0x82, 0x40, 0xE6, 0xCF,
      0xC8, 0x59, 0xE9, 0xB6, 0xB0, 0xE8, 0xBF, 0x95, 0x82, 0x79, 0x71, 0xF9,
      0x86, 0x8A, 0xCA, 0x53, 0x23, 0xCF, 0x31, 0xFE, 0x4B, 0xD2, 0xA5, 0x26,
      0xA4, 0x46, 0x3D, 0x35, 0xEF, 0x69, 0x02, 0xC4, 0xBF, 0x72, 0xDC, 0xF8,
      0x90, 0x77, 0xFB, 0x59, 0x0D, 0x41, 0xCB, 0x5B, 0x58, 0xC6, 0x08, 0x0F,
      0x19, 0x4E, 0xC8, 0x4A, 0x57, 0xE7, 0x63, 0x43, 0x39, 0x79, 0xD7, 0x6E,
      0x0D, 0xD0, 0xE4, 0x4F, 0xFA, 0x55, 0x32, 0xE1, 0x6B, 0xE4, 0xFF, 0x12,
      0xB1, 0xA3, 0x75, 0x9C, 0x44, 0x3A, 0x16, 0x68, 0x5C, 0x11, 0xD0, 0xA5,
      0x4C, 0x65, 0xB0, 0xBF, 0x04, 0x41, 0x94, 0xFE, 0xC5, 0xDD, 0x5C, 0x78,
      0x5B, 0x14, 0xA1, 0x3F, 0x0B, 0x17, 0x9C, 0x75, 0xA5, 0x9E, 0x36, 0x14,
      0x5B, 0xC4, 0xAC, 0x77, 0x28, 0xDE, 0xEB, 0xB4, 0x51, 0x5F, 0x33, 0x36};

  brillo::SecureBlob wrapped_reset_seed = {
      0x73, 0x63, 0x72, 0x79, 0x70, 0x74, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x08,
      0x00, 0x00, 0x00, 0x01, 0x7F, 0x40, 0x30, 0x51, 0x2F, 0x15, 0x62, 0x15,
      0xB1, 0x2E, 0x58, 0x27, 0x52, 0xE4, 0xFF, 0xC5, 0x3C, 0x1E, 0x19, 0x05,
      0x84, 0xD8, 0xE8, 0xD4, 0xFD, 0x8C, 0x33, 0xE8, 0x06, 0x1A, 0x38, 0x28,
      0x2D, 0xD7, 0x01, 0xD2, 0xB3, 0xE1, 0x95, 0xC3, 0x49, 0x63, 0x39, 0xA2,
      0xB2, 0xE3, 0xDA, 0xE2, 0x76, 0x40, 0x40, 0x11, 0xD1, 0x98, 0xD2, 0x03,
      0xFB, 0x60, 0xD0, 0xA1, 0xA5, 0xB5, 0x51, 0xAA, 0xEF, 0x6C, 0xB3, 0xAB,
      0x23, 0x65, 0xCA, 0x44, 0x84, 0x7A, 0x71, 0xCA, 0x0C, 0x36, 0x33, 0x7F,
      0x53, 0x06, 0x0E, 0x03, 0xBB, 0xC1, 0x9A, 0x9D, 0x40, 0x1C, 0x2F, 0x46,
      0xB7, 0x84, 0x00, 0x59, 0x5B, 0xD6, 0x53, 0xE4, 0x51, 0x82, 0xC2, 0x3D,
      0xF4, 0x46, 0xD2, 0xDD, 0xE5, 0x7A, 0x0A, 0xEB, 0xC8, 0x45, 0x7C, 0x37,
      0x01, 0xD5, 0x37, 0x4E, 0xE3, 0xC7, 0xBC, 0xC6, 0x5E, 0x25, 0xFE, 0xE2,
      0x05, 0x14, 0x60, 0x33, 0xB8, 0x1A, 0xF1, 0x17, 0xE1, 0x0C, 0x25, 0x00,
      0xA5, 0x0A, 0xD5, 0x03};

  brillo::SecureBlob passkey = {0x31, 0x35, 0x64, 0x64, 0x38, 0x38, 0x66, 0x36,
                                0x35, 0x31, 0x30, 0x65, 0x30, 0x64, 0x35, 0x64,
                                0x35, 0x35, 0x36, 0x35, 0x35, 0x35, 0x38, 0x36,
                                0x31, 0x32, 0x62, 0x37, 0x39, 0x36, 0x30, 0x65};

  Credentials credentials(kUser, passkey);

  LibScryptCompatAuthBlockState scrypt_state = {
      .wrapped_keyset = wrapped_keyset,
      .wrapped_chaps_key = wrapped_chaps_key,
      .wrapped_reset_seed = wrapped_reset_seed,
      .salt = system_salt_};
  AuthBlockState auth_state = {.state = scrypt_state};

  // Test
  KeyBlobs out_key_blobs;
  auth_block_utility_impl_ = std::make_unique<AuthBlockUtilityImpl>(
      keyset_management_.get(), &crypto_, &platform_);

  EXPECT_TRUE(auth_block_utility_impl_
                  ->DeriveKeyBlobsWithAuthBlock(AuthBlockType::kLibScryptCompat,
                                                credentials, auth_state,
                                                out_key_blobs)
                  .ok());
}

// Test that DeriveKeyBlobsWithAuthBlock derives AuthBlocks with
// DoubleWrappedCompatAuthBlock when the AuthBlock type is
// AuthBlockType::kDoubleWrappedCompat.
TEST_F(AuthBlockUtilityImplTest, DeriveDoubleWrappedAuthBlock) {
  // Setup test inputs and the mock expectations.
  crypto_.Init(&tpm_, &cryptohome_keys_manager_);
  brillo::SecureBlob wrapped_keyset = {
      0x73, 0x63, 0x72, 0x79, 0x70, 0x74, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x08,
      0x00, 0x00, 0x00, 0x01, 0x4D, 0xEE, 0xFC, 0x79, 0x0D, 0x79, 0x08, 0x79,
      0xD5, 0xF6, 0x07, 0x65, 0xDF, 0x76, 0x5A, 0xAE, 0xD1, 0xBD, 0x1D, 0xCF,
      0x29, 0xF6, 0xFF, 0x5C, 0x31, 0x30, 0x23, 0xD1, 0x22, 0x17, 0xDF, 0x74,
      0x26, 0xD5, 0x11, 0x88, 0x8D, 0x40, 0xA6, 0x9C, 0xB9, 0x72, 0xCE, 0x37,
      0x71, 0xB7, 0x39, 0x0E, 0x3E, 0x34, 0x0F, 0x73, 0x29, 0xF4, 0x0F, 0x89,
      0x15, 0xF7, 0x6E, 0xA1, 0x5A, 0x29, 0x78, 0x21, 0xB7, 0xC0, 0x76, 0x50,
      0x14, 0x5C, 0xAD, 0x77, 0x53, 0xC9, 0xD0, 0xFE, 0xD1, 0xB9, 0x81, 0x32,
      0x75, 0x0E, 0x1E, 0x45, 0x34, 0xBD, 0x0B, 0xF7, 0xFA, 0xED, 0x9A, 0xD7,
      0x6B, 0xE4, 0x2F, 0xC0, 0x2F, 0x58, 0xBE, 0x3A, 0x26, 0xD1, 0x82, 0x41,
      0x09, 0x82, 0x7F, 0x17, 0xA8, 0x5C, 0x66, 0x0E, 0x24, 0x8B, 0x7B, 0xF5,
      0xEB, 0x0C, 0x6D, 0xAE, 0x19, 0x5C, 0x7D, 0xC4, 0x0D, 0x8D, 0xB2, 0x18,
      0x13, 0xD4, 0xC0, 0x32, 0x34, 0x15, 0xAE, 0x1D, 0xA1, 0x44, 0x2E, 0x80,
      0xD8, 0x00, 0x8A, 0xB9, 0xDD, 0xA4, 0xC0, 0x33, 0xAE, 0x26, 0xD3, 0xE6,
      0x53, 0xD6, 0x31, 0x5C, 0x4C, 0x10, 0xBB, 0xA9, 0xD5, 0x53, 0xD7, 0xAD,
      0xCD, 0x97, 0x20, 0x83, 0xFC, 0x18, 0x4B, 0x7F, 0xC1, 0xBD, 0x85, 0x43,
      0x12, 0x85, 0x4F, 0x6F, 0xAA, 0xDB, 0x58, 0xA0, 0x0F, 0x2C, 0xAB, 0xEA,
      0x74, 0x8E, 0x2C, 0x28, 0x01, 0x88, 0x48, 0xA5, 0x0A, 0xFC, 0x2F, 0xB4,
      0x59, 0x4B, 0xF6, 0xD9, 0xE5, 0x47, 0x94, 0x42, 0xA5, 0x61, 0x06, 0x8C,
      0x5A, 0x9C, 0xD3, 0xA6, 0x30, 0x2C, 0x13, 0xCA, 0xF1, 0xFF, 0xFE, 0x5C,
      0xE8, 0x21, 0x25, 0x9A, 0xE0, 0x50, 0xC3, 0x2F, 0x14, 0x71, 0x38, 0xD0,
      0xE7, 0x79, 0x5D, 0xF0, 0x71, 0x80, 0xF0, 0x3D, 0x05, 0xB6, 0xF7, 0x67,
      0x3F, 0x22, 0x21, 0x7A, 0xED, 0x48, 0xC4, 0x2D, 0xEA, 0x2E, 0xAE, 0xE9,
      0xA8, 0xFF, 0xA0, 0xB6, 0xB4, 0x0A, 0x94, 0x34, 0x40, 0xD1, 0x6C, 0x6C,
      0xC7, 0x90, 0x9C, 0xF7, 0xED, 0x0B, 0xED, 0x90, 0xB1, 0x4D, 0x6D, 0xB4,
      0x3D, 0x04, 0x7E, 0x7B, 0x16, 0x59, 0xFF, 0xFE};

  brillo::SecureBlob wrapped_chaps_key = {
      0x73, 0x63, 0x72, 0x79, 0x70, 0x74, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x08,
      0x00, 0x00, 0x00, 0x01, 0xC9, 0x80, 0xA1, 0x30, 0x82, 0x40, 0xE6, 0xCF,
      0xC8, 0x59, 0xE9, 0xB6, 0xB0, 0xE8, 0xBF, 0x95, 0x82, 0x79, 0x71, 0xF9,
      0x86, 0x8A, 0xCA, 0x53, 0x23, 0xCF, 0x31, 0xFE, 0x4B, 0xD2, 0xA5, 0x26,
      0xA4, 0x46, 0x3D, 0x35, 0xEF, 0x69, 0x02, 0xC4, 0xBF, 0x72, 0xDC, 0xF8,
      0x90, 0x77, 0xFB, 0x59, 0x0D, 0x41, 0xCB, 0x5B, 0x58, 0xC6, 0x08, 0x0F,
      0x19, 0x4E, 0xC8, 0x4A, 0x57, 0xE7, 0x63, 0x43, 0x39, 0x79, 0xD7, 0x6E,
      0x0D, 0xD0, 0xE4, 0x4F, 0xFA, 0x55, 0x32, 0xE1, 0x6B, 0xE4, 0xFF, 0x12,
      0xB1, 0xA3, 0x75, 0x9C, 0x44, 0x3A, 0x16, 0x68, 0x5C, 0x11, 0xD0, 0xA5,
      0x4C, 0x65, 0xB0, 0xBF, 0x04, 0x41, 0x94, 0xFE, 0xC5, 0xDD, 0x5C, 0x78,
      0x5B, 0x14, 0xA1, 0x3F, 0x0B, 0x17, 0x9C, 0x75, 0xA5, 0x9E, 0x36, 0x14,
      0x5B, 0xC4, 0xAC, 0x77, 0x28, 0xDE, 0xEB, 0xB4, 0x51, 0x5F, 0x33, 0x36};

  brillo::SecureBlob wrapped_reset_seed = {
      0x73, 0x63, 0x72, 0x79, 0x70, 0x74, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x08,
      0x00, 0x00, 0x00, 0x01, 0x7F, 0x40, 0x30, 0x51, 0x2F, 0x15, 0x62, 0x15,
      0xB1, 0x2E, 0x58, 0x27, 0x52, 0xE4, 0xFF, 0xC5, 0x3C, 0x1E, 0x19, 0x05,
      0x84, 0xD8, 0xE8, 0xD4, 0xFD, 0x8C, 0x33, 0xE8, 0x06, 0x1A, 0x38, 0x28,
      0x2D, 0xD7, 0x01, 0xD2, 0xB3, 0xE1, 0x95, 0xC3, 0x49, 0x63, 0x39, 0xA2,
      0xB2, 0xE3, 0xDA, 0xE2, 0x76, 0x40, 0x40, 0x11, 0xD1, 0x98, 0xD2, 0x03,
      0xFB, 0x60, 0xD0, 0xA1, 0xA5, 0xB5, 0x51, 0xAA, 0xEF, 0x6C, 0xB3, 0xAB,
      0x23, 0x65, 0xCA, 0x44, 0x84, 0x7A, 0x71, 0xCA, 0x0C, 0x36, 0x33, 0x7F,
      0x53, 0x06, 0x0E, 0x03, 0xBB, 0xC1, 0x9A, 0x9D, 0x40, 0x1C, 0x2F, 0x46,
      0xB7, 0x84, 0x00, 0x59, 0x5B, 0xD6, 0x53, 0xE4, 0x51, 0x82, 0xC2, 0x3D,
      0xF4, 0x46, 0xD2, 0xDD, 0xE5, 0x7A, 0x0A, 0xEB, 0xC8, 0x45, 0x7C, 0x37,
      0x01, 0xD5, 0x37, 0x4E, 0xE3, 0xC7, 0xBC, 0xC6, 0x5E, 0x25, 0xFE, 0xE2,
      0x05, 0x14, 0x60, 0x33, 0xB8, 0x1A, 0xF1, 0x17, 0xE1, 0x0C, 0x25, 0x00,
      0xA5, 0x0A, 0xD5, 0x03};

  brillo::SecureBlob passkey = {0x31, 0x35, 0x64, 0x64, 0x38, 0x38, 0x66, 0x36,
                                0x35, 0x31, 0x30, 0x65, 0x30, 0x64, 0x35, 0x64,
                                0x35, 0x35, 0x36, 0x35, 0x35, 0x35, 0x38, 0x36,
                                0x31, 0x32, 0x62, 0x37, 0x39, 0x36, 0x30, 0x65};

  Credentials credentials(kUser, passkey);

  LibScryptCompatAuthBlockState scrypt_state = {
      .wrapped_keyset = wrapped_keyset,
      .wrapped_chaps_key = wrapped_chaps_key,
      .wrapped_reset_seed = wrapped_reset_seed,
      .salt = system_salt_};
  TpmNotBoundToPcrAuthBlockState tpm_state = {
      .scrypt_derived = false,
      .salt = system_salt_,
      .tpm_key = brillo::SecureBlob(20, 'A')};
  DoubleWrappedCompatAuthBlockState double_wrapped_state = {
      .scrypt_state = scrypt_state, .tpm_state = tpm_state};
  AuthBlockState auth_state = {.state = double_wrapped_state};

  // Test
  KeyBlobs out_key_blobs;
  auth_block_utility_impl_ = std::make_unique<AuthBlockUtilityImpl>(
      keyset_management_.get(), &crypto_, &platform_);

  EXPECT_TRUE(
      auth_block_utility_impl_
          ->DeriveKeyBlobsWithAuthBlock(AuthBlockType::kDoubleWrappedCompat,
                                        credentials, auth_state, out_key_blobs)
          .ok());
}

// Test that CreateKeyBlobsWithAuthBlock creates AuthBlockState with
// ChallengeCredentialAuthBlock when the AuthBlock type is
// AuthBlockType::kChallengeCredential.
TEST_F(AuthBlockUtilityImplTest, CreateChallengeCredentialAuthBlock) {
  // Setup mock expectations and test inputs for low entropy AuthBlock.
  brillo::SecureBlob passkey(20, 'A');
  Credentials credentials(kUser, passkey);

  auth_block_utility_impl_ = std::make_unique<AuthBlockUtilityImpl>(
      keyset_management_.get(), &crypto_, &platform_);

  // Test
  KeyBlobs out_key_blobs;
  AuthBlockState out_state;
  EXPECT_TRUE(auth_block_utility_impl_
                  ->CreateKeyBlobsWithAuthBlock(
                      AuthBlockType::kChallengeCredential, credentials,
                      std::nullopt, out_state, out_key_blobs)
                  .ok());

  // Verify that a script wrapped AuthBlock is generated.
  // TODO(betuls): Update verifications after the integration of the
  // asynchronous AuthBlock.
  EXPECT_TRUE(std::holds_alternative<ChallengeCredentialAuthBlockState>(
      out_state.state));
}

// Test that DeriveKeyBlobsWithAuthBlock derives AuthBlocks with
// ChallengeCredentialAuthBlock when the AuthBlock type is
// AuthBlockType::kChallengeCredential.
TEST_F(AuthBlockUtilityImplTest, DeriveChallengeCredentialAuthBlock) {
  // Setup test inputs.
  brillo::SecureBlob wrapped_keyset = {
      0x73, 0x63, 0x72, 0x79, 0x70, 0x74, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x08,
      0x00, 0x00, 0x00, 0x01, 0x4D, 0xEE, 0xFC, 0x79, 0x0D, 0x79, 0x08, 0x79,
      0xD5, 0xF6, 0x07, 0x65, 0xDF, 0x76, 0x5A, 0xAE, 0xD1, 0xBD, 0x1D, 0xCF,
      0x29, 0xF6, 0xFF, 0x5C, 0x31, 0x30, 0x23, 0xD1, 0x22, 0x17, 0xDF, 0x74,
      0x26, 0xD5, 0x11, 0x88, 0x8D, 0x40, 0xA6, 0x9C, 0xB9, 0x72, 0xCE, 0x37,
      0x71, 0xB7, 0x39, 0x0E, 0x3E, 0x34, 0x0F, 0x73, 0x29, 0xF4, 0x0F, 0x89,
      0x15, 0xF7, 0x6E, 0xA1, 0x5A, 0x29, 0x78, 0x21, 0xB7, 0xC0, 0x76, 0x50,
      0x14, 0x5C, 0xAD, 0x77, 0x53, 0xC9, 0xD0, 0xFE, 0xD1, 0xB9, 0x81, 0x32,
      0x75, 0x0E, 0x1E, 0x45, 0x34, 0xBD, 0x0B, 0xF7, 0xFA, 0xED, 0x9A, 0xD7,
      0x6B, 0xE4, 0x2F, 0xC0, 0x2F, 0x58, 0xBE, 0x3A, 0x26, 0xD1, 0x82, 0x41,
      0x09, 0x82, 0x7F, 0x17, 0xA8, 0x5C, 0x66, 0x0E, 0x24, 0x8B, 0x7B, 0xF5,
      0xEB, 0x0C, 0x6D, 0xAE, 0x19, 0x5C, 0x7D, 0xC4, 0x0D, 0x8D, 0xB2, 0x18,
      0x13, 0xD4, 0xC0, 0x32, 0x34, 0x15, 0xAE, 0x1D, 0xA1, 0x44, 0x2E, 0x80,
      0xD8, 0x00, 0x8A, 0xB9, 0xDD, 0xA4, 0xC0, 0x33, 0xAE, 0x26, 0xD3, 0xE6,
      0x53, 0xD6, 0x31, 0x5C, 0x4C, 0x10, 0xBB, 0xA9, 0xD5, 0x53, 0xD7, 0xAD,
      0xCD, 0x97, 0x20, 0x83, 0xFC, 0x18, 0x4B, 0x7F, 0xC1, 0xBD, 0x85, 0x43,
      0x12, 0x85, 0x4F, 0x6F, 0xAA, 0xDB, 0x58, 0xA0, 0x0F, 0x2C, 0xAB, 0xEA,
      0x74, 0x8E, 0x2C, 0x28, 0x01, 0x88, 0x48, 0xA5, 0x0A, 0xFC, 0x2F, 0xB4,
      0x59, 0x4B, 0xF6, 0xD9, 0xE5, 0x47, 0x94, 0x42, 0xA5, 0x61, 0x06, 0x8C,
      0x5A, 0x9C, 0xD3, 0xA6, 0x30, 0x2C, 0x13, 0xCA, 0xF1, 0xFF, 0xFE, 0x5C,
      0xE8, 0x21, 0x25, 0x9A, 0xE0, 0x50, 0xC3, 0x2F, 0x14, 0x71, 0x38, 0xD0,
      0xE7, 0x79, 0x5D, 0xF0, 0x71, 0x80, 0xF0, 0x3D, 0x05, 0xB6, 0xF7, 0x67,
      0x3F, 0x22, 0x21, 0x7A, 0xED, 0x48, 0xC4, 0x2D, 0xEA, 0x2E, 0xAE, 0xE9,
      0xA8, 0xFF, 0xA0, 0xB6, 0xB4, 0x0A, 0x94, 0x34, 0x40, 0xD1, 0x6C, 0x6C,
      0xC7, 0x90, 0x9C, 0xF7, 0xED, 0x0B, 0xED, 0x90, 0xB1, 0x4D, 0x6D, 0xB4,
      0x3D, 0x04, 0x7E, 0x7B, 0x16, 0x59, 0xFF, 0xFE};

  brillo::SecureBlob wrapped_chaps_key = {
      0x73, 0x63, 0x72, 0x79, 0x70, 0x74, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x08,
      0x00, 0x00, 0x00, 0x01, 0xC9, 0x80, 0xA1, 0x30, 0x82, 0x40, 0xE6, 0xCF,
      0xC8, 0x59, 0xE9, 0xB6, 0xB0, 0xE8, 0xBF, 0x95, 0x82, 0x79, 0x71, 0xF9,
      0x86, 0x8A, 0xCA, 0x53, 0x23, 0xCF, 0x31, 0xFE, 0x4B, 0xD2, 0xA5, 0x26,
      0xA4, 0x46, 0x3D, 0x35, 0xEF, 0x69, 0x02, 0xC4, 0xBF, 0x72, 0xDC, 0xF8,
      0x90, 0x77, 0xFB, 0x59, 0x0D, 0x41, 0xCB, 0x5B, 0x58, 0xC6, 0x08, 0x0F,
      0x19, 0x4E, 0xC8, 0x4A, 0x57, 0xE7, 0x63, 0x43, 0x39, 0x79, 0xD7, 0x6E,
      0x0D, 0xD0, 0xE4, 0x4F, 0xFA, 0x55, 0x32, 0xE1, 0x6B, 0xE4, 0xFF, 0x12,
      0xB1, 0xA3, 0x75, 0x9C, 0x44, 0x3A, 0x16, 0x68, 0x5C, 0x11, 0xD0, 0xA5,
      0x4C, 0x65, 0xB0, 0xBF, 0x04, 0x41, 0x94, 0xFE, 0xC5, 0xDD, 0x5C, 0x78,
      0x5B, 0x14, 0xA1, 0x3F, 0x0B, 0x17, 0x9C, 0x75, 0xA5, 0x9E, 0x36, 0x14,
      0x5B, 0xC4, 0xAC, 0x77, 0x28, 0xDE, 0xEB, 0xB4, 0x51, 0x5F, 0x33, 0x36};

  brillo::SecureBlob wrapped_reset_seed = {
      0x73, 0x63, 0x72, 0x79, 0x70, 0x74, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x08,
      0x00, 0x00, 0x00, 0x01, 0x7F, 0x40, 0x30, 0x51, 0x2F, 0x15, 0x62, 0x15,
      0xB1, 0x2E, 0x58, 0x27, 0x52, 0xE4, 0xFF, 0xC5, 0x3C, 0x1E, 0x19, 0x05,
      0x84, 0xD8, 0xE8, 0xD4, 0xFD, 0x8C, 0x33, 0xE8, 0x06, 0x1A, 0x38, 0x28,
      0x2D, 0xD7, 0x01, 0xD2, 0xB3, 0xE1, 0x95, 0xC3, 0x49, 0x63, 0x39, 0xA2,
      0xB2, 0xE3, 0xDA, 0xE2, 0x76, 0x40, 0x40, 0x11, 0xD1, 0x98, 0xD2, 0x03,
      0xFB, 0x60, 0xD0, 0xA1, 0xA5, 0xB5, 0x51, 0xAA, 0xEF, 0x6C, 0xB3, 0xAB,
      0x23, 0x65, 0xCA, 0x44, 0x84, 0x7A, 0x71, 0xCA, 0x0C, 0x36, 0x33, 0x7F,
      0x53, 0x06, 0x0E, 0x03, 0xBB, 0xC1, 0x9A, 0x9D, 0x40, 0x1C, 0x2F, 0x46,
      0xB7, 0x84, 0x00, 0x59, 0x5B, 0xD6, 0x53, 0xE4, 0x51, 0x82, 0xC2, 0x3D,
      0xF4, 0x46, 0xD2, 0xDD, 0xE5, 0x7A, 0x0A, 0xEB, 0xC8, 0x45, 0x7C, 0x37,
      0x01, 0xD5, 0x37, 0x4E, 0xE3, 0xC7, 0xBC, 0xC6, 0x5E, 0x25, 0xFE, 0xE2,
      0x05, 0x14, 0x60, 0x33, 0xB8, 0x1A, 0xF1, 0x17, 0xE1, 0x0C, 0x25, 0x00,
      0xA5, 0x0A, 0xD5, 0x03};

  brillo::SecureBlob passkey = {0x31, 0x35, 0x64, 0x64, 0x38, 0x38, 0x66, 0x36,
                                0x35, 0x31, 0x30, 0x65, 0x30, 0x64, 0x35, 0x64,
                                0x35, 0x35, 0x36, 0x35, 0x35, 0x35, 0x38, 0x36,
                                0x31, 0x32, 0x62, 0x37, 0x39, 0x36, 0x30, 0x65};

  Credentials credentials(kUser, passkey);

  LibScryptCompatAuthBlockState scrypt_state = {
      .wrapped_keyset = wrapped_keyset,
      .wrapped_chaps_key = wrapped_chaps_key,
      .wrapped_reset_seed = wrapped_reset_seed,
      .salt = system_salt_};
  ChallengeCredentialAuthBlockState cc_state = {.scrypt_state = scrypt_state};
  AuthBlockState auth_state = {.state = cc_state};

  // Test
  KeyBlobs out_key_blobs;
  auth_block_utility_impl_ = std::make_unique<AuthBlockUtilityImpl>(
      keyset_management_.get(), &crypto_, &platform_);

  EXPECT_TRUE(
      auth_block_utility_impl_
          ->DeriveKeyBlobsWithAuthBlock(AuthBlockType::kChallengeCredential,
                                        credentials, auth_state, out_key_blobs)
          .ok());
}

// Test that CreateKeyBlobsWithAuthBlockAsync creates AuthBlockState
// and KeyBlobs, internally using a SyncToAsyncAuthBlockAdapter for
// accessing the key material from TpmBoundToPcrAuthBlock.
TEST_F(AuthBlockUtilityImplTest, SyncToAsyncAdapterCreate) {
  // Setup test inputs and the mock expectations.
  brillo::SecureBlob passkey(20, 'A');
  Credentials credentials(kUser, passkey);

  brillo::SecureBlob scrypt_derived_key;
  crypto_.Init(&tpm_, &cryptohome_keys_manager_);

  brillo::SecureBlob auth_value(256, 'a');
  EXPECT_CALL(tpm_, GetAuthValue(_, _, _))
      .WillOnce(DoAll(SaveArg<1>(&scrypt_derived_key),
                      SetArgPointee<2>(auth_value),
                      ReturnError<TPMErrorBase>()));
  EXPECT_CALL(tpm_, SealToPcrWithAuthorization(_, auth_value, _, _))
      .Times(Exactly(2));
  ON_CALL(tpm_, SealToPcrWithAuthorization(_, _, _, _))
      .WillByDefault(ReturnError<TPMErrorBase>());

  auth_block_utility_impl_ = std::make_unique<AuthBlockUtilityImpl>(
      keyset_management_.get(), &crypto_, &platform_);

  AuthBlock::CreateCallback create_callback = base::BindLambdaForTesting(
      [&](CryptoStatus error, std::unique_ptr<KeyBlobs> blobs,
          std::unique_ptr<AuthBlockState> auth_state) {
        // Evaluate results of KeyBlobs and AuthBlockState returned by callback.
        EXPECT_TRUE(error.ok());
        EXPECT_TRUE(std::holds_alternative<TpmBoundToPcrAuthBlockState>(
            auth_state->state));
        EXPECT_NE(blobs->vkk_key, std::nullopt);
        EXPECT_NE(blobs->vkk_iv, std::nullopt);
        EXPECT_NE(blobs->chaps_iv, std::nullopt);
        // Verify that tpm backed pcr bound auth block is created.
        auto& tpm_state =
            std::get<TpmBoundToPcrAuthBlockState>(auth_state->state);
        EXPECT_TRUE(tpm_state.salt.has_value());
      });

  AuthInput auth_input = {
      credentials.passkey(), std::nullopt, /*locked_to_single_user*=*/
      credentials.GetObfuscatedUsername(), /*reset_secret*/ std::nullopt};

  // Test.
  EXPECT_EQ(true, auth_block_utility_impl_->CreateKeyBlobsWithAuthBlockAsync(
                      AuthBlockType::kTpmBoundToPcr, auth_input,
                      std::move(create_callback)));
}

// Test that DeriveKeyBlobsWithAuthBlockAsync derives KeyBlobs,
// internally using a SyncToAsyncAuthBlockAdapter for
// accessing the key material from TpmBoundToPcrAuthBlock.
TEST_F(AuthBlockUtilityImplTest, SyncToAsyncAdapterDerive) {
  // Setup test inputs and the mock expectations.
  brillo::SecureBlob passkey(20, 'A');
  Credentials credentials(kUser, passkey);
  brillo::SecureBlob tpm_key(20, 'B');
  brillo::SecureBlob salt(system_salt_);
  crypto_.Init(&tpm_, &cryptohome_keys_manager_);

  // Make sure TpmAuthBlock calls DecryptTpmBoundToPcr in this case.
  EXPECT_CALL(tpm_, PreloadSealedData(_, _)).Times(Exactly(1));
  EXPECT_CALL(tpm_, GetAuthValue(_, _, _)).Times(Exactly(1));
  EXPECT_CALL(tpm_, UnsealWithAuthorization(_, _, _, _, _)).Times(Exactly(1));

  TpmBoundToPcrAuthBlockState tpm_state = {.scrypt_derived = true,
                                           .salt = salt,
                                           .tpm_key = tpm_key,
                                           .extended_tpm_key = tpm_key};
  AuthBlockState auth_state = {.state = tpm_state};
  AuthInput auth_input = {credentials.passkey(),
                          /*locked_to_single_user=*/std::nullopt};

  auth_block_utility_impl_ = std::make_unique<AuthBlockUtilityImpl>(
      keyset_management_.get(), &crypto_, &platform_);

  // Test.
  AuthBlock::DeriveCallback derive_callback = base::BindLambdaForTesting(
      [&](CryptoStatus error, std::unique_ptr<KeyBlobs> blobs) {
        // Evaluate results of KeyBlobs returned by callback.
        EXPECT_TRUE(error.ok());
        EXPECT_NE(blobs->vkk_key, std::nullopt);
        EXPECT_NE(blobs->vkk_iv, std::nullopt);
        EXPECT_NE(blobs->chaps_iv, std::nullopt);
      });

  EXPECT_EQ(true, auth_block_utility_impl_->DeriveKeyBlobsWithAuthBlockAsync(
                      AuthBlockType::kTpmBoundToPcr, auth_input, auth_state,
                      std::move(derive_callback)));
}

// Test that CreateKeyBlobsWithAuthBlockAsync creates AuthBlockState
// and KeyBlobs, internally using a AsyncChallengeCredentialAuthBlock for
// accessing the key material.
TEST_F(AuthBlockUtilityImplTest, AsyncChallengeCredentialCreate) {
  brillo::SecureBlob passkey("passkey");
  Credentials credentials(kUser, passkey);
  crypto_.Init(&tpm_, &cryptohome_keys_manager_);

  EXPECT_CALL(challenge_credentials_helper_, GenerateNew(kUser, _, _, _, _))
      .WillOnce([&](auto&&, auto public_key_info, auto&&, auto&&,
                    auto&& callback) {
        auto info = std::make_unique<structure::SignatureChallengeInfo>();
        info->public_key_spki_der = public_key_info.public_key_spki_der;
        info->salt_signature_algorithm = public_key_info.signature_algorithm[0];
        auto passkey = std::make_unique<brillo::SecureBlob>("passkey");
        std::move(callback).Run(std::move(info), std::move(passkey));
      });

  auto mock_key_challenge_service =
      std::make_unique<NiceMock<MockKeyChallengeService>>();

  auth_block_utility_impl_ = std::make_unique<AuthBlockUtilityImpl>(
      keyset_management_.get(), &crypto_, &platform_,
      &challenge_credentials_helper_, std::move(mock_key_challenge_service),
      credentials.username());

  AuthBlock::CreateCallback create_callback = base::BindLambdaForTesting(
      [&](CryptoStatus error, std::unique_ptr<KeyBlobs> blobs,
          std::unique_ptr<AuthBlockState> auth_state) {
        // Evaluate results of KeyBlobs and AuthBlockState returned by callback.
        EXPECT_TRUE(error.ok());

        // Because the salt is generated randomly inside the auth block, this
        // test cannot check the exact values returned. The salt() could be
        // passed through in some test specific harness, but the underlying
        // scrypt code is tested in so many other places, it's unnecessary.
        EXPECT_FALSE(blobs->scrypt_key->derived_key().empty());
        EXPECT_FALSE(blobs->scrypt_key->ConsumeSalt().empty());

        EXPECT_FALSE(blobs->chaps_scrypt_key->derived_key().empty());
        EXPECT_FALSE(blobs->chaps_scrypt_key->ConsumeSalt().empty());

        EXPECT_FALSE(
            blobs->scrypt_wrapped_reset_seed_key->derived_key().empty());
        EXPECT_FALSE(
            blobs->scrypt_wrapped_reset_seed_key->ConsumeSalt().empty());

        ASSERT_TRUE(std::holds_alternative<ChallengeCredentialAuthBlockState>(
            auth_state->state));

        auto& tpm_state =
            std::get<ChallengeCredentialAuthBlockState>(auth_state->state);

        AuthInput auth_input{
            .challenge_credential_auth_input =
                ChallengeCredentialAuthInput{
                    .public_key_spki_der =
                        brillo::BlobFromString("public_key_spki_der"),
                    .challenge_signature_algorithms =
                        {structure::ChallengeSignatureAlgorithm::
                             kRsassaPkcs1V15Sha256},
                },
        };

        ASSERT_TRUE(tpm_state.keyset_challenge_info.has_value());
        EXPECT_EQ(tpm_state.keyset_challenge_info.value().public_key_spki_der,
                  auth_input.challenge_credential_auth_input.value()
                      .public_key_spki_der);
        EXPECT_EQ(
            tpm_state.keyset_challenge_info.value().salt_signature_algorithm,
            auth_input.challenge_credential_auth_input.value()
                .challenge_signature_algorithms[0]);
      });
  AuthInput auth_input;
  auth_input.obfuscated_username = credentials.GetObfuscatedUsername();
  auth_input.locked_to_single_user = false;
  auth_input.challenge_credential_auth_input = ChallengeCredentialAuthInput{
      .public_key_spki_der = brillo::BlobFromString("public_key_spki_der"),
      .challenge_signature_algorithms =
          {structure::ChallengeSignatureAlgorithm::kRsassaPkcs1V15Sha256},
  };

  // Test.
  EXPECT_EQ(true, auth_block_utility_impl_->CreateKeyBlobsWithAuthBlockAsync(
                      AuthBlockType::kChallengeCredential, auth_input,
                      std::move(create_callback)));
}

// The AsyncChallengeCredentialAuthBlock::Derive should work correctly.
TEST_F(AuthBlockUtilityImplTest, AsyncChallengeCredentialDerive) {
  brillo::SecureBlob passkey("passkey");
  Credentials credentials(kUser, passkey);
  crypto_.Init(&tpm_, &cryptohome_keys_manager_);

  AuthBlockState auth_state{
      .state =
          ChallengeCredentialAuthBlockState{
              .scrypt_state =
                  LibScryptCompatAuthBlockState{
                      .wrapped_keyset =
                          brillo::SecureBlob{
                              0x73, 0x63, 0x72, 0x79, 0x70, 0x74, 0x00, 0x0E,
                              0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x01,
                              0x4D, 0xEE, 0xFC, 0x79, 0x0D, 0x79, 0x08, 0x79,
                              0xD5, 0xF6, 0x07, 0x65, 0xDF, 0x76, 0x5A, 0xAE,
                              0xD1, 0xBD, 0x1D, 0xCF, 0x29, 0xF6, 0xFF, 0x5C,
                              0x31, 0x30, 0x23, 0xD1, 0x22, 0x17, 0xDF, 0x74,
                              0x26, 0xD5, 0x11, 0x88, 0x8D, 0x40, 0xA6, 0x9C,
                              0xB9, 0x72, 0xCE, 0x37, 0x71, 0xB7, 0x39, 0x0E,
                              0x3E, 0x34, 0x0F, 0x73, 0x29, 0xF4, 0x0F, 0x89,
                              0x15, 0xF7, 0x6E, 0xA1, 0x5A, 0x29, 0x78, 0x21,
                              0xB7, 0xC0, 0x76, 0x50, 0x14, 0x5C, 0xAD, 0x77,
                              0x53, 0xC9, 0xD0, 0xFE, 0xD1, 0xB9, 0x81, 0x32,
                              0x75, 0x0E, 0x1E, 0x45, 0x34, 0xBD, 0x0B, 0xF7,
                              0xFA, 0xED, 0x9A, 0xD7, 0x6B, 0xE4, 0x2F, 0xC0,
                              0x2F, 0x58, 0xBE, 0x3A, 0x26, 0xD1, 0x82, 0x41,
                              0x09, 0x82, 0x7F, 0x17, 0xA8, 0x5C, 0x66, 0x0E,
                              0x24, 0x8B, 0x7B, 0xF5, 0xEB, 0x0C, 0x6D, 0xAE,
                              0x19, 0x5C, 0x7D, 0xC4, 0x0D, 0x8D, 0xB2, 0x18,
                              0x13, 0xD4, 0xC0, 0x32, 0x34, 0x15, 0xAE, 0x1D,
                              0xA1, 0x44, 0x2E, 0x80, 0xD8, 0x00, 0x8A, 0xB9,
                              0xDD, 0xA4, 0xC0, 0x33, 0xAE, 0x26, 0xD3, 0xE6,
                              0x53, 0xD6, 0x31, 0x5C, 0x4C, 0x10, 0xBB, 0xA9,
                              0xD5, 0x53, 0xD7, 0xAD, 0xCD, 0x97, 0x20, 0x83,
                              0xFC, 0x18, 0x4B, 0x7F, 0xC1, 0xBD, 0x85, 0x43,
                              0x12, 0x85, 0x4F, 0x6F, 0xAA, 0xDB, 0x58, 0xA0,
                              0x0F, 0x2C, 0xAB, 0xEA, 0x74, 0x8E, 0x2C, 0x28,
                              0x01, 0x88, 0x48, 0xA5, 0x0A, 0xFC, 0x2F, 0xB4,
                              0x59, 0x4B, 0xF6, 0xD9, 0xE5, 0x47, 0x94, 0x42,
                              0xA5, 0x61, 0x06, 0x8C, 0x5A, 0x9C, 0xD3, 0xA6,
                              0x30, 0x2C, 0x13, 0xCA, 0xF1, 0xFF, 0xFE, 0x5C,
                              0xE8, 0x21, 0x25, 0x9A, 0xE0, 0x50, 0xC3, 0x2F,
                              0x14, 0x71, 0x38, 0xD0, 0xE7, 0x79, 0x5D, 0xF0,
                              0x71, 0x80, 0xF0, 0x3D, 0x05, 0xB6, 0xF7, 0x67,
                              0x3F, 0x22, 0x21, 0x7A, 0xED, 0x48, 0xC4, 0x2D,
                              0xEA, 0x2E, 0xAE, 0xE9, 0xA8, 0xFF, 0xA0, 0xB6,
                              0xB4, 0x0A, 0x94, 0x34, 0x40, 0xD1, 0x6C, 0x6C,
                              0xC7, 0x90, 0x9C, 0xF7, 0xED, 0x0B, 0xED, 0x90,
                              0xB1, 0x4D, 0x6D, 0xB4, 0x3D, 0x04, 0x7E, 0x7B,
                              0x16, 0x59, 0xFF, 0xFE},
                      .wrapped_chaps_key =
                          brillo::SecureBlob{
                              0x73, 0x63, 0x72, 0x79, 0x70, 0x74, 0x00, 0x0E,
                              0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x01,
                              0xC9, 0x80, 0xA1, 0x30, 0x82, 0x40, 0xE6, 0xCF,
                              0xC8, 0x59, 0xE9, 0xB6, 0xB0, 0xE8, 0xBF, 0x95,
                              0x82, 0x79, 0x71, 0xF9, 0x86, 0x8A, 0xCA, 0x53,
                              0x23, 0xCF, 0x31, 0xFE, 0x4B, 0xD2, 0xA5, 0x26,
                              0xA4, 0x46, 0x3D, 0x35, 0xEF, 0x69, 0x02, 0xC4,
                              0xBF, 0x72, 0xDC, 0xF8, 0x90, 0x77, 0xFB, 0x59,
                              0x0D, 0x41, 0xCB, 0x5B, 0x58, 0xC6, 0x08, 0x0F,
                              0x19, 0x4E, 0xC8, 0x4A, 0x57, 0xE7, 0x63, 0x43,
                              0x39, 0x79, 0xD7, 0x6E, 0x0D, 0xD0, 0xE4, 0x4F,
                              0xFA, 0x55, 0x32, 0xE1, 0x6B, 0xE4, 0xFF, 0x12,
                              0xB1, 0xA3, 0x75, 0x9C, 0x44, 0x3A, 0x16, 0x68,
                              0x5C, 0x11, 0xD0, 0xA5, 0x4C, 0x65, 0xB0, 0xBF,
                              0x04, 0x41, 0x94, 0xFE, 0xC5, 0xDD, 0x5C, 0x78,
                              0x5B, 0x14, 0xA1, 0x3F, 0x0B, 0x17, 0x9C, 0x75,
                              0xA5, 0x9E, 0x36, 0x14, 0x5B, 0xC4, 0xAC, 0x77,
                              0x28, 0xDE, 0xEB, 0xB4, 0x51, 0x5F, 0x33, 0x36},
                      .wrapped_reset_seed =
                          brillo::SecureBlob{
                              0x73, 0x63, 0x72, 0x79, 0x70, 0x74, 0x00, 0x0E,
                              0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x01,
                              0x7F, 0x40, 0x30, 0x51, 0x2F, 0x15, 0x62, 0x15,
                              0xB1, 0x2E, 0x58, 0x27, 0x52, 0xE4, 0xFF, 0xC5,
                              0x3C, 0x1E, 0x19, 0x05, 0x84, 0xD8, 0xE8, 0xD4,
                              0xFD, 0x8C, 0x33, 0xE8, 0x06, 0x1A, 0x38, 0x28,
                              0x2D, 0xD7, 0x01, 0xD2, 0xB3, 0xE1, 0x95, 0xC3,
                              0x49, 0x63, 0x39, 0xA2, 0xB2, 0xE3, 0xDA, 0xE2,
                              0x76, 0x40, 0x40, 0x11, 0xD1, 0x98, 0xD2, 0x03,
                              0xFB, 0x60, 0xD0, 0xA1, 0xA5, 0xB5, 0x51, 0xAA,
                              0xEF, 0x6C, 0xB3, 0xAB, 0x23, 0x65, 0xCA, 0x44,
                              0x84, 0x7A, 0x71, 0xCA, 0x0C, 0x36, 0x33, 0x7F,
                              0x53, 0x06, 0x0E, 0x03, 0xBB, 0xC1, 0x9A, 0x9D,
                              0x40, 0x1C, 0x2F, 0x46, 0xB7, 0x84, 0x00, 0x59,
                              0x5B, 0xD6, 0x53, 0xE4, 0x51, 0x82, 0xC2, 0x3D,
                              0xF4, 0x46, 0xD2, 0xDD, 0xE5, 0x7A, 0x0A, 0xEB,
                              0xC8, 0x45, 0x7C, 0x37, 0x01, 0xD5, 0x37, 0x4E,
                              0xE3, 0xC7, 0xBC, 0xC6, 0x5E, 0x25, 0xFE, 0xE2,
                              0x05, 0x14, 0x60, 0x33, 0xB8, 0x1A, 0xF1, 0x17,
                              0xE1, 0x0C, 0x25, 0x00, 0xA5, 0x0A, 0xD5, 0x03},
                  },
              .keyset_challenge_info =
                  structure::SignatureChallengeInfo{
                      .public_key_spki_der =
                          brillo::BlobFromString("public_key_spki_der"),
                      .salt_signature_algorithm = structure::
                          ChallengeSignatureAlgorithm::kRsassaPkcs1V15Sha256,
                  },
          },
  };

  brillo::SecureBlob scrypt_passkey = {
      0x31, 0x35, 0x64, 0x64, 0x38, 0x38, 0x66, 0x36, 0x35, 0x31, 0x30,
      0x65, 0x30, 0x64, 0x35, 0x64, 0x35, 0x35, 0x36, 0x35, 0x35, 0x35,
      0x38, 0x36, 0x31, 0x32, 0x62, 0x37, 0x39, 0x36, 0x30, 0x65};

  brillo::SecureBlob derived_key = {
      0x58, 0x2A, 0x41, 0x1F, 0xC0, 0x27, 0x2D, 0xC7, 0xF8, 0xEC, 0xA3,
      0x4E, 0xC0, 0x3F, 0x6C, 0x56, 0x6D, 0x88, 0x69, 0x3F, 0x50, 0x20,
      0x37, 0xE3, 0x77, 0x5F, 0xDD, 0xC3, 0x61, 0x2D, 0x27, 0xAD, 0xD3,
      0x55, 0x4D, 0x66, 0xE5, 0x83, 0xD2, 0x5E, 0x02, 0x0C, 0x22, 0x59,
      0x6C, 0x39, 0x35, 0x86, 0xEC, 0x46, 0xB0, 0x85, 0x89, 0xE3, 0x4C,
      0xB9, 0xE2, 0x0C, 0xA1, 0x27, 0x60, 0x85, 0x5A, 0x37};

  brillo::SecureBlob derived_chaps_key = {
      0x16, 0x53, 0xEE, 0x4D, 0x76, 0x47, 0x68, 0x09, 0xB3, 0x39, 0x1D,
      0xD3, 0x6F, 0xA2, 0x8F, 0x8A, 0x3E, 0xB3, 0x64, 0xDD, 0x4D, 0xC4,
      0x64, 0x6F, 0xE1, 0xB8, 0x82, 0x28, 0x68, 0x72, 0x68, 0x84, 0x93,
      0xE2, 0xDB, 0x2F, 0x27, 0x91, 0x08, 0x2C, 0xA0, 0xD9, 0xA1, 0x6E,
      0x6F, 0x0E, 0x13, 0x66, 0x1D, 0x94, 0x12, 0x6F, 0xF4, 0x98, 0x7B,
      0x44, 0x62, 0x57, 0x47, 0x33, 0x46, 0xD2, 0x30, 0x42};

  brillo::SecureBlob derived_reset_seed_key = {
      0xFA, 0x93, 0x57, 0xCE, 0x21, 0xBB, 0x82, 0x4D, 0x3A, 0x3B, 0x26,
      0x88, 0x8C, 0x7E, 0x61, 0x52, 0x52, 0xF0, 0x12, 0x25, 0xA3, 0x59,
      0xCA, 0x71, 0xD2, 0x0C, 0x52, 0x8A, 0x5B, 0x7A, 0x7D, 0xBF, 0x8E,
      0xC7, 0x4D, 0x1D, 0xB5, 0xF9, 0x01, 0xA6, 0xE5, 0x5D, 0x47, 0x2E,
      0xFD, 0x7C, 0x78, 0x1D, 0x9B, 0xAD, 0xE6, 0x71, 0x35, 0x2B, 0x32,
      0x1E, 0x59, 0x19, 0x47, 0x88, 0x92, 0x50, 0x28, 0x09};

  auto mock_key_challenge_service =
      std::make_unique<NiceMock<MockKeyChallengeService>>();

  auth_block_utility_impl_ = std::make_unique<AuthBlockUtilityImpl>(
      keyset_management_.get(), &crypto_, &platform_,
      &challenge_credentials_helper_, std::move(mock_key_challenge_service),
      credentials.username());

  EXPECT_CALL(challenge_credentials_helper_,
              Decrypt(kUser, _, _, /*locked_to_single_user=*/false, _, _))
      .WillOnce([&](auto&&, auto&&, auto&&, auto&&, auto&&, auto&& callback) {
        auto passkey = std::make_unique<brillo::SecureBlob>(scrypt_passkey);
        std::move(callback).Run(std::move(passkey));
      });
  // Test.
  AuthBlock::DeriveCallback derive_callback = base::BindLambdaForTesting(
      [&](CryptoStatus error, std::unique_ptr<KeyBlobs> blobs) {
        ASSERT_TRUE(error.ok());
        EXPECT_EQ(derived_key, blobs->scrypt_key->derived_key());
        EXPECT_EQ(derived_chaps_key, blobs->chaps_scrypt_key->derived_key());
        EXPECT_EQ(derived_reset_seed_key,
                  blobs->scrypt_wrapped_reset_seed_key->derived_key());
      });

  AuthInput auth_input = {credentials.passkey(),
                          /*locked_to_single_user=*/std::nullopt};
  auth_block_utility_impl_->DeriveKeyBlobsWithAuthBlockAsync(
      AuthBlockType::kChallengeCredential, auth_input, auth_state,
      std::move(derive_callback));
}

// Test that CreateKeyBlobsWithAuthBlockAsync fails, callback
// returns CE_OTHER_CRYPTO and nullptrs for AuthBlockState and
// KeyBlobs.
TEST_F(AuthBlockUtilityImplTest, CreateKeyBlobsWithAuthBlockAsyncFails) {
  // Setup test inputs and the mock expectations.
  brillo::SecureBlob passkey(20, 'A');
  Credentials credentials(kUser, passkey);

  brillo::SecureBlob scrypt_derived_key;
  crypto_.Init(&tpm_, &cryptohome_keys_manager_);

  auth_block_utility_impl_ = std::make_unique<AuthBlockUtilityImpl>(
      keyset_management_.get(), &crypto_, &platform_);

  AuthInput auth_input = {
      credentials.passkey(), std::nullopt /*locked_to_single_user*=*/,
      credentials.GetObfuscatedUsername(), std::nullopt /*reset_secret*/};

  AuthBlock::CreateCallback create_callback = base::BindLambdaForTesting(
      [&](CryptoStatus error, std::unique_ptr<KeyBlobs> blobs,
          std::unique_ptr<AuthBlockState> auth_state) {
        // Evaluate results of KeyBlobs and AuthBlockState returned by callback.
        EXPECT_EQ(error->local_crypto_error(), CryptoError::CE_OTHER_CRYPTO);
        EXPECT_EQ(blobs, nullptr);
        EXPECT_EQ(auth_state, nullptr);
      });

  // Test.
  EXPECT_EQ(false, auth_block_utility_impl_->CreateKeyBlobsWithAuthBlockAsync(
                       AuthBlockType::kMaxValue, auth_input,
                       std::move(create_callback)));
}

TEST_F(AuthBlockUtilityImplTest, CreateKeyBlobsWithAuthBlockWrongTypeFails) {
  // Setup mock expectations and test inputs for low entropy AuthBlock.
  brillo::SecureBlob passkey(20, 'A');
  Credentials credentials(kUser, passkey);

  auth_block_utility_impl_ = std::make_unique<AuthBlockUtilityImpl>(
      keyset_management_.get(), &crypto_, &platform_);

  // Test
  KeyBlobs out_key_blobs;
  AuthBlockState out_state;
  EXPECT_EQ(
      CryptoError::CE_OTHER_CRYPTO,
      auth_block_utility_impl_
          ->CreateKeyBlobsWithAuthBlock(AuthBlockType::kMaxValue, credentials,
                                        std::nullopt, out_state, out_key_blobs)
          ->local_crypto_error());
}

// Test that GetAuthBlockStateFromVaultKeyset() gives correct AuthblockState
// for each AuthBlock type.
TEST_F(AuthBlockUtilityImplTest, DeriveAuthBlockStateFromVaultKeysetTest) {
  brillo::SecureBlob chaps_iv(16, 'F');
  brillo::SecureBlob fek_iv(16, 'X');
  brillo::SecureBlob vkk_iv(16, 'Y');

  brillo::SecureBlob passkey(20, 'A');
  Credentials credentials(kUser, passkey);
  NiceMock<MockKeysetManagement> keyset_management;

  // PinWeaverAuthBlockState

  // Construct the vault keyset
  SerializedVaultKeyset serialized;
  serialized.set_flags(SerializedVaultKeyset::LE_CREDENTIAL);
  serialized.set_salt(system_salt_.data(), system_salt_.size());
  serialized.set_le_chaps_iv(chaps_iv.data(), chaps_iv.size());
  serialized.set_le_label(0);
  serialized.set_le_fek_iv(fek_iv.data(), fek_iv.size());

  auto vk = std::make_unique<VaultKeyset>();
  vk->InitializeFromSerialized(serialized);
  EXPECT_EQ(SerializedVaultKeyset::LE_CREDENTIAL, vk->GetFlags());

  KeyBlobs out_key_blobs;
  auth_block_utility_impl_ = std::make_unique<AuthBlockUtilityImpl>(
      &keyset_management, &crypto_, &platform_);

  // Test
  AuthBlockState out_state;
  EXPECT_CALL(keyset_management, GetVaultKeyset(_, _))
      .WillOnce(Return(ByMove(std::move(vk))));
  auth_block_utility_impl_->GetAuthBlockStateFromVaultKeyset(
      credentials.key_data().label(), credentials.GetObfuscatedUsername(),
      out_state);
  EXPECT_TRUE(std::holds_alternative<PinWeaverAuthBlockState>(out_state.state));

  // ChallengeCredentialAuthBlockState

  // Construct the vault keyset
  serialized.set_flags(SerializedVaultKeyset::SCRYPT_WRAPPED |
                       SerializedVaultKeyset::SIGNATURE_CHALLENGE_PROTECTED);
  auto vk1 = std::make_unique<VaultKeyset>();
  vk1->InitializeFromSerialized(serialized);

  // Test
  EXPECT_CALL(keyset_management, GetVaultKeyset(_, _))
      .WillOnce(Return(ByMove(std::move(vk1))));
  auth_block_utility_impl_->GetAuthBlockStateFromVaultKeyset(
      credentials.key_data().label(), credentials.GetObfuscatedUsername(),
      out_state);
  EXPECT_TRUE(std::holds_alternative<ChallengeCredentialAuthBlockState>(
      out_state.state));

  const ChallengeCredentialAuthBlockState* cc_state =
      std::get_if<ChallengeCredentialAuthBlockState>(&out_state.state);
  EXPECT_NE(cc_state, nullptr);

  // LibScryptCompatAuthBlockState

  // Construct the vault keyset
  serialized.set_flags(SerializedVaultKeyset::SCRYPT_WRAPPED);
  auto vk2 = std::make_unique<VaultKeyset>();
  vk2->InitializeFromSerialized(serialized);
  vk2->SetWrappedKeyset(brillo::SecureBlob("foo"));
  vk2->SetWrappedChapsKey(brillo::SecureBlob("bar"));
  vk2->SetWrappedResetSeed(brillo::SecureBlob("baz"));

  // Test
  EXPECT_CALL(keyset_management, GetVaultKeyset(_, _))
      .WillOnce(Return(ByMove(std::move(vk2))));
  auth_block_utility_impl_->GetAuthBlockStateFromVaultKeyset(
      credentials.key_data().label(), credentials.GetObfuscatedUsername(),
      out_state);
  EXPECT_TRUE(
      std::holds_alternative<LibScryptCompatAuthBlockState>(out_state.state));
  const LibScryptCompatAuthBlockState* scrypt_state =
      std::get_if<LibScryptCompatAuthBlockState>(&out_state.state);
  EXPECT_NE(scrypt_state, nullptr);
  EXPECT_TRUE(scrypt_state->wrapped_keyset.has_value());
  EXPECT_TRUE(scrypt_state->wrapped_chaps_key.has_value());
  EXPECT_TRUE(scrypt_state->wrapped_reset_seed.has_value());

  // DoubleWrappedCompatAuthBlockstate fail when TPM key is not present

  // Construct the vault keyset
  serialized.set_flags(SerializedVaultKeyset::SCRYPT_WRAPPED |
                       SerializedVaultKeyset::TPM_WRAPPED);
  auto vk3 = std::make_unique<VaultKeyset>();
  vk3->InitializeFromSerialized(serialized);

  // Test
  // Double scrypt fail test when tpm key is not set, failure in creating
  // sub-state TpmNotBoundToPcrAuthBlockState.
  EXPECT_CALL(keyset_management, GetVaultKeyset(_, _))
      .WillOnce(Return(ByMove(std::move(vk3))));
  auth_block_utility_impl_->GetAuthBlockStateFromVaultKeyset(
      credentials.key_data().label(), credentials.GetObfuscatedUsername(),
      out_state);
  EXPECT_FALSE(std::holds_alternative<DoubleWrappedCompatAuthBlockState>(
      out_state.state));

  // DoubleWrappedCompatAuthBlockstate success

  // Construct the vault keyset
  auto vk4 = std::make_unique<VaultKeyset>();
  vk4->InitializeFromSerialized(serialized);
  vk4->SetTPMKey(brillo::SecureBlob("tpmkey"));

  // Test
  EXPECT_CALL(keyset_management, GetVaultKeyset(_, _))
      .WillOnce(Return(ByMove(std::move(vk4))));
  auth_block_utility_impl_->GetAuthBlockStateFromVaultKeyset(
      credentials.key_data().label(), credentials.GetObfuscatedUsername(),
      out_state);
  EXPECT_TRUE(std::holds_alternative<DoubleWrappedCompatAuthBlockState>(
      out_state.state));

  const DoubleWrappedCompatAuthBlockState* double_wrapped_state =
      std::get_if<DoubleWrappedCompatAuthBlockState>(&out_state.state);
  EXPECT_NE(double_wrapped_state, nullptr);

  // TpmBoundToPcrAuthBlockState

  // Construct the vault keyset
  serialized.set_flags(SerializedVaultKeyset::TPM_WRAPPED |
                       SerializedVaultKeyset::SCRYPT_DERIVED |
                       SerializedVaultKeyset::PCR_BOUND);
  auto vk5 = std::make_unique<VaultKeyset>();
  vk5->InitializeFromSerialized(serialized);
  vk5->SetTpmPublicKeyHash(brillo::SecureBlob("publickeyhash"));
  vk5->SetTPMKey(brillo::SecureBlob("tpmkey"));
  vk5->SetExtendedTPMKey(brillo::SecureBlob("extpmkey"));

  // Test
  EXPECT_CALL(keyset_management, GetVaultKeyset(_, _))
      .WillOnce(Return(ByMove(std::move(vk5))));
  auth_block_utility_impl_->GetAuthBlockStateFromVaultKeyset(
      credentials.key_data().label(), credentials.GetObfuscatedUsername(),
      out_state);
  EXPECT_TRUE(
      std::holds_alternative<TpmBoundToPcrAuthBlockState>(out_state.state));

  const TpmBoundToPcrAuthBlockState* tpm_state =
      std::get_if<TpmBoundToPcrAuthBlockState>(&out_state.state);
  EXPECT_NE(tpm_state, nullptr);
  EXPECT_TRUE(tpm_state->scrypt_derived.value());
  EXPECT_TRUE(tpm_state->extended_tpm_key.has_value());
  EXPECT_TRUE(tpm_state->tpm_key.has_value());

  // TpmNotBoundToPcrAuthBlockState

  // Construct the vault keyset
  serialized.set_flags(SerializedVaultKeyset::TPM_WRAPPED);
  auto vk6 = std::make_unique<VaultKeyset>();
  vk6->InitializeFromSerialized(serialized);
  vk6->SetTpmPublicKeyHash(brillo::SecureBlob("publickeyhash"));
  vk6->SetTPMKey(brillo::SecureBlob("tpmkey"));
  // Test
  EXPECT_CALL(keyset_management, GetVaultKeyset(_, _))
      .WillOnce(Return(ByMove(std::move(vk6))));
  auth_block_utility_impl_->GetAuthBlockStateFromVaultKeyset(
      credentials.key_data().label(), credentials.GetObfuscatedUsername(),
      out_state);
  EXPECT_TRUE(
      std::holds_alternative<TpmNotBoundToPcrAuthBlockState>(out_state.state));
  const TpmNotBoundToPcrAuthBlockState* tpm_state2 =
      std::get_if<TpmNotBoundToPcrAuthBlockState>(&out_state.state);
  EXPECT_NE(tpm_state2, nullptr);
  EXPECT_FALSE(tpm_state2->scrypt_derived.value());
  EXPECT_TRUE(tpm_state2->tpm_key.has_value());

  // EccAuthBlockStateTest

  // Construct the vault keyset
  SerializedVaultKeyset serialized2;
  serialized2.set_password_rounds(5);
  serialized2.set_vkk_iv(vkk_iv.data(), vkk_iv.size());
  serialized2.set_flags(SerializedVaultKeyset::TPM_WRAPPED |
                        SerializedVaultKeyset::SCRYPT_DERIVED |
                        SerializedVaultKeyset::ECC |
                        SerializedVaultKeyset::PCR_BOUND);
  auto vk7 = std::make_unique<VaultKeyset>();
  vk7->InitializeFromSerialized(serialized2);
  vk7->SetTpmPublicKeyHash(brillo::SecureBlob("publickeyhash"));
  vk7->SetTPMKey(brillo::SecureBlob("tpmkey"));
  vk7->SetExtendedTPMKey(brillo::SecureBlob("extpmkey"));

  // Test
  EXPECT_CALL(keyset_management, GetVaultKeyset(_, _))
      .WillOnce(Return(ByMove(std::move(vk7))));
  auth_block_utility_impl_->GetAuthBlockStateFromVaultKeyset(
      credentials.key_data().label(), credentials.GetObfuscatedUsername(),
      out_state);
  EXPECT_TRUE(std::holds_alternative<TpmEccAuthBlockState>(out_state.state));

  const TpmEccAuthBlockState* tpm_ecc_state =
      std::get_if<TpmEccAuthBlockState>(&out_state.state);

  EXPECT_NE(tpm_ecc_state, nullptr);
  EXPECT_TRUE(tpm_ecc_state->salt.has_value());
  EXPECT_TRUE(tpm_ecc_state->sealed_hvkkm.has_value());
  EXPECT_TRUE(tpm_ecc_state->extended_sealed_hvkkm.has_value());
  EXPECT_TRUE(tpm_ecc_state->tpm_public_key_hash.has_value());
  EXPECT_TRUE(tpm_ecc_state->vkk_iv.has_value());
  EXPECT_EQ(tpm_ecc_state->auth_value_rounds.value(), 5);
}

TEST_F(AuthBlockUtilityImplTest, MatchAuthBlockForCreation) {
  brillo::SecureBlob passkey(20, 'A');
  Credentials credentials(kUser, passkey);
  crypto_.Init(&tpm_, &cryptohome_keys_manager_);
  auth_block_utility_impl_ = std::make_unique<AuthBlockUtilityImpl>(
      keyset_management_.get(), &crypto_, &platform_);

  // Test for kLibScryptCompat
  EXPECT_EQ(
      AuthBlockType::kLibScryptCompat,
      auth_block_utility_impl_->GetAuthBlockTypeForCreation(
          /*is_le_credential =*/false, /*is_challenge_credential =*/false));

  // Test for kPinWeaver
  KeyData key_data;
  key_data.mutable_policy()->set_low_entropy_credential(true);
  credentials.set_key_data(key_data);
  EXPECT_EQ(
      AuthBlockType::kPinWeaver,
      auth_block_utility_impl_->GetAuthBlockTypeForCreation(
          /*is_le_credential =*/true, /*is_challenge_credential =*/false));

  // Test for kChallengeResponse
  KeyData key_data2;
  key_data2.set_type(KeyData::KEY_TYPE_CHALLENGE_RESPONSE);
  credentials.set_key_data(key_data2);
  EXPECT_EQ(
      AuthBlockType::kChallengeCredential,
      auth_block_utility_impl_->GetAuthBlockTypeForCreation(
          /*is_le_credential =*/false, /*is_challenge_credential =*/true));

  // Test for Tpm backed AuthBlock types.
  ON_CALL(tpm_, IsOwned()).WillByDefault(Return(true));
  // credentials.key_data type shouldn't be challenge credential any more.
  KeyData key_data3;
  credentials.set_key_data(key_data3);

  // Test for kTpmEcc
  EXPECT_EQ(
      AuthBlockType::kTpmEcc,
      auth_block_utility_impl_->GetAuthBlockTypeForCreation(
          /*is_le_credential =*/false, /*is_challenge_credential =*/false));

  // Test for kTpmNotBoundToPcr (No TPM or no TPM2.0)
  EXPECT_CALL(tpm_, GetVersion()).WillOnce(Return(Tpm::TPM_1_2));
  EXPECT_EQ(
      AuthBlockType::kTpmNotBoundToPcr,
      auth_block_utility_impl_->GetAuthBlockTypeForCreation(
          /*is_le_credential =*/false, /*is_challenge_credential =*/false));

  // Test for kTpmBoundToPcr (TPM2.0 but no support for ECC key)
  EXPECT_CALL(tpm_, GetVersion()).WillOnce(Return(Tpm::TPM_2_0));
  EXPECT_CALL(cryptohome_keys_manager_, GetKeyLoader(CryptohomeKeyType::kECC))
      .WillOnce(Return(nullptr));
  EXPECT_EQ(
      AuthBlockType::kTpmBoundToPcr,
      auth_block_utility_impl_->GetAuthBlockTypeForCreation(
          /*is_le_credential =*/false, /*is_challenge_credential =*/false));
}

TEST_F(AuthBlockUtilityImplTest, MatchAuthBlockForDerivation) {
  // Setup
  brillo::SecureBlob passkey(20, 'A');
  Credentials credentials(kUser, passkey);

  SerializedVaultKeyset serialized;
  auto vk = std::make_unique<VaultKeyset>();

  NiceMock<MockKeysetManagement> keyset_management;
  auth_block_utility_impl_ = std::make_unique<AuthBlockUtilityImpl>(
      &keyset_management, &crypto_, &platform_);

  // Test for kLibScryptCompat
  serialized.set_flags(SerializedVaultKeyset::SCRYPT_WRAPPED);
  vk->InitializeFromSerialized(serialized);
  EXPECT_CALL(keyset_management, GetVaultKeyset(_, _))
      .WillOnce(Return(ByMove(std::move(vk))));
  EXPECT_EQ(
      AuthBlockType::kLibScryptCompat,
      auth_block_utility_impl_->GetAuthBlockTypeForDerivation(
          credentials.key_data().label(), credentials.GetObfuscatedUsername()));
  serialized.set_flags(SerializedVaultKeyset::SCRYPT_WRAPPED |
                       SerializedVaultKeyset::TPM_WRAPPED);
  vk = std::make_unique<VaultKeyset>();
  vk->InitializeFromSerialized(serialized);
  EXPECT_CALL(keyset_management, GetVaultKeyset(_, _))
      .WillOnce(Return(ByMove(std::move(vk))));
  EXPECT_NE(
      AuthBlockType::kLibScryptCompat,
      auth_block_utility_impl_->GetAuthBlockTypeForDerivation(
          credentials.key_data().label(), credentials.GetObfuscatedUsername()));

  // Test for DoubleWrappedCompat
  serialized.set_flags(SerializedVaultKeyset::SCRYPT_WRAPPED |
                       SerializedVaultKeyset::TPM_WRAPPED);
  vk = std::make_unique<VaultKeyset>();
  vk->InitializeFromSerialized(serialized);
  EXPECT_CALL(keyset_management, GetVaultKeyset(_, _))
      .WillOnce(Return(ByMove(std::move(vk))));
  EXPECT_EQ(
      AuthBlockType::kDoubleWrappedCompat,
      auth_block_utility_impl_->GetAuthBlockTypeForDerivation(
          credentials.key_data().label(), credentials.GetObfuscatedUsername()));

  // Test for kPinWeaver
  serialized.set_flags(SerializedVaultKeyset::LE_CREDENTIAL);
  vk = std::make_unique<VaultKeyset>();
  vk->InitializeFromSerialized(serialized);
  EXPECT_CALL(keyset_management, GetVaultKeyset(_, _))
      .WillOnce(Return(ByMove(std::move(vk))));
  EXPECT_EQ(
      AuthBlockType::kPinWeaver,
      auth_block_utility_impl_->GetAuthBlockTypeForDerivation(
          credentials.key_data().label(), credentials.GetObfuscatedUsername()));

  // Test for kChallengeResponse
  serialized.set_flags(SerializedVaultKeyset::SIGNATURE_CHALLENGE_PROTECTED);
  vk = std::make_unique<VaultKeyset>();
  vk->InitializeFromSerialized(serialized);
  EXPECT_CALL(keyset_management, GetVaultKeyset(_, _))
      .WillOnce(Return(ByMove(std::move(vk))));
  EXPECT_EQ(
      AuthBlockType::kChallengeCredential,
      auth_block_utility_impl_->GetAuthBlockTypeForDerivation(
          credentials.key_data().label(), credentials.GetObfuscatedUsername()));

  // Test for kTpmNotBoundToPcrFlags
  serialized.set_flags(SerializedVaultKeyset::TPM_WRAPPED);
  vk = std::make_unique<VaultKeyset>();
  vk->InitializeFromSerialized(serialized);
  EXPECT_CALL(keyset_management, GetVaultKeyset(_, _))
      .WillOnce(Return(ByMove(std::move(vk))));
  EXPECT_EQ(
      AuthBlockType::kTpmNotBoundToPcr,
      auth_block_utility_impl_->GetAuthBlockTypeForDerivation(
          credentials.key_data().label(), credentials.GetObfuscatedUsername()));
  serialized.set_flags(SerializedVaultKeyset::TPM_WRAPPED |
                       SerializedVaultKeyset::SCRYPT_WRAPPED);
  vk = std::make_unique<VaultKeyset>();
  vk->InitializeFromSerialized(serialized);
  EXPECT_CALL(keyset_management, GetVaultKeyset(_, _))
      .WillOnce(Return(ByMove(std::move(vk))));
  EXPECT_NE(
      AuthBlockType::kTpmNotBoundToPcr,
      auth_block_utility_impl_->GetAuthBlockTypeForDerivation(
          credentials.key_data().label(), credentials.GetObfuscatedUsername()));
  serialized.set_flags(SerializedVaultKeyset::TPM_WRAPPED |
                       SerializedVaultKeyset::PCR_BOUND);
  vk = std::make_unique<VaultKeyset>();
  vk->InitializeFromSerialized(serialized);
  EXPECT_CALL(keyset_management, GetVaultKeyset(_, _))
      .WillOnce(Return(ByMove(std::move(vk))));
  EXPECT_NE(
      AuthBlockType::kTpmNotBoundToPcr,
      auth_block_utility_impl_->GetAuthBlockTypeForDerivation(
          credentials.key_data().label(), credentials.GetObfuscatedUsername()));
  serialized.set_flags(SerializedVaultKeyset::TPM_WRAPPED |
                       SerializedVaultKeyset::ECC);
  vk = std::make_unique<VaultKeyset>();
  vk->InitializeFromSerialized(serialized);
  EXPECT_CALL(keyset_management, GetVaultKeyset(_, _))
      .WillOnce(Return(ByMove(std::move(vk))));
  EXPECT_NE(
      AuthBlockType::kTpmNotBoundToPcr,
      auth_block_utility_impl_->GetAuthBlockTypeForDerivation(
          credentials.key_data().label(), credentials.GetObfuscatedUsername()));

  // Test for kTpmEcc
  serialized.set_flags(SerializedVaultKeyset::TPM_WRAPPED |
                       SerializedVaultKeyset::SCRYPT_DERIVED |
                       SerializedVaultKeyset::PCR_BOUND |
                       SerializedVaultKeyset::ECC);
  vk = std::make_unique<VaultKeyset>();
  vk->InitializeFromSerialized(serialized);
  EXPECT_CALL(keyset_management, GetVaultKeyset(_, _))
      .WillOnce(Return(ByMove(std::move(vk))));
  EXPECT_EQ(
      AuthBlockType::kTpmEcc,
      auth_block_utility_impl_->GetAuthBlockTypeForDerivation(
          credentials.key_data().label(), credentials.GetObfuscatedUsername()));
  serialized.set_flags(
      SerializedVaultKeyset::TPM_WRAPPED |
      SerializedVaultKeyset::SCRYPT_DERIVED | SerializedVaultKeyset::PCR_BOUND |
      SerializedVaultKeyset::ECC | SerializedVaultKeyset::SCRYPT_WRAPPED);
  vk = std::make_unique<VaultKeyset>();
  vk->InitializeFromSerialized(serialized);
  EXPECT_CALL(keyset_management, GetVaultKeyset(_, _))
      .WillOnce(Return(ByMove(std::move(vk))));
  EXPECT_NE(
      AuthBlockType::kTpmEcc,
      auth_block_utility_impl_->GetAuthBlockTypeForDerivation(
          credentials.key_data().label(), credentials.GetObfuscatedUsername()));

  // Test for kTpmBoundToPcr
  serialized.set_flags(SerializedVaultKeyset::TPM_WRAPPED |
                       SerializedVaultKeyset::PCR_BOUND);
  vk = std::make_unique<VaultKeyset>();
  vk->InitializeFromSerialized(serialized);
  EXPECT_CALL(keyset_management, GetVaultKeyset(_, _))
      .WillOnce(Return(ByMove(std::move(vk))));
  EXPECT_EQ(
      AuthBlockType::kTpmBoundToPcr,
      auth_block_utility_impl_->GetAuthBlockTypeForDerivation(
          credentials.key_data().label(), credentials.GetObfuscatedUsername()));
  serialized.set_flags(SerializedVaultKeyset::TPM_WRAPPED |
                       SerializedVaultKeyset::PCR_BOUND |
                       SerializedVaultKeyset::ECC);
  vk = std::make_unique<VaultKeyset>();
  vk->InitializeFromSerialized(serialized);
  EXPECT_CALL(keyset_management, GetVaultKeyset(_, _))
      .WillOnce(Return(ByMove(std::move(vk))));
  EXPECT_NE(
      AuthBlockType::kTpmBoundToPcr,
      auth_block_utility_impl_->GetAuthBlockTypeForDerivation(
          credentials.key_data().label(), credentials.GetObfuscatedUsername()));
  serialized.set_flags(SerializedVaultKeyset::TPM_WRAPPED |
                       SerializedVaultKeyset::PCR_BOUND |
                       SerializedVaultKeyset::SCRYPT_WRAPPED);
  vk = std::make_unique<VaultKeyset>();
  vk->InitializeFromSerialized(serialized);
  EXPECT_CALL(keyset_management, GetVaultKeyset(_, _))
      .WillOnce(Return(ByMove(std::move(vk))));
  EXPECT_NE(
      AuthBlockType::kTpmBoundToPcr,
      auth_block_utility_impl_->GetAuthBlockTypeForDerivation(
          credentials.key_data().label(), credentials.GetObfuscatedUsername()));
}

TEST_F(AuthBlockUtilityImplTest, GetAsyncAuthBlockWithType) {
  brillo::SecureBlob passkey("passkey");
  Credentials credentials(kUser, passkey);
  crypto_.Init(&tpm_, &cryptohome_keys_manager_);
  auto mock_key_challenge_service =
      std::make_unique<NiceMock<MockKeyChallengeService>>();

  auth_block_utility_impl_ = std::make_unique<AuthBlockUtilityImpl>(
      keyset_management_.get(), &crypto_, &platform_,
      &challenge_credentials_helper_, std::move(mock_key_challenge_service),
      credentials.username());
  // Test. All fields are valid to get an AsyncChallengeCredentialAuthBlock.
  CryptoStatusOr<std::unique_ptr<AuthBlock>> auth_block =
      auth_block_utility_impl_->GetAsyncAuthBlockWithType(
          AuthBlockType::kChallengeCredential);
  EXPECT_TRUE(auth_block.ok());
  EXPECT_NE(auth_block.value(), nullptr);
}

TEST_F(AuthBlockUtilityImplTest, GetAsyncAuthBlockWithTypeFail) {
  brillo::SecureBlob passkey("passkey");
  Credentials credentials(kUser, passkey);
  crypto_.Init(&tpm_, &cryptohome_keys_manager_);
  // Test. No valid challenge_credentials, no valid key_challenge_service or
  // account_id.
  auth_block_utility_impl_ = std::make_unique<AuthBlockUtilityImpl>(
      keyset_management_.get(), &crypto_, &platform_);

  CryptoStatusOr<std::unique_ptr<AuthBlock>> auth_block =
      auth_block_utility_impl_->GetAsyncAuthBlockWithType(
          AuthBlockType::kChallengeCredential);
  EXPECT_FALSE(auth_block.ok());
}

}  // namespace cryptohome
