// Copyright 2021 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/user_secret_stash.h"

#include <base/test/scoped_chromeos_version_info.h>
#include <brillo/secure_blob.h>
#include <gtest/gtest.h>
#include <libhwsec-foundation/crypto/aes.h>
#include <libhwsec-foundation/utility/crypto.h>

#include <algorithm>
#include <limits>
#include <memory>
#include <optional>
#include <type_traits>
#include <utility>

#include "cryptohome/cryptohome_common.h"
#include "cryptohome/flatbuffer_schemas/user_secret_stash_container.h"
#include "cryptohome/flatbuffer_schemas/user_secret_stash_payload.h"
#include "cryptohome/storage/encrypted_container/filesystem_key.h"
#include "cryptohome/storage/file_system_keyset.h"
#include "cryptohome/storage/file_system_keyset_test_utils.h"

using ::hwsec_foundation::AesGcmDecrypt;
using ::hwsec_foundation::AesGcmEncrypt;
using ::hwsec_foundation::kAesGcm256KeySize;
using ::hwsec_foundation::utility::CreateSecureRandomBlob;

namespace cryptohome {

namespace {

bool FindBlobInBlob(const brillo::Blob& haystack,
                    const brillo::SecureBlob& needle) {
  return std::search(haystack.begin(), haystack.end(), needle.begin(),
                     needle.end()) != haystack.end();
}

class UserSecretStashTest : public ::testing::Test {
 protected:
  // Fake file system keyset data:
  const brillo::SecureBlob kFek = brillo::SecureBlob("fek");
  const brillo::SecureBlob kFnek = brillo::SecureBlob("fnek");
  const brillo::SecureBlob kFekSalt = brillo::SecureBlob("fek-salt");
  const brillo::SecureBlob kFnekSalt = brillo::SecureBlob("fnek-salt");
  const brillo::SecureBlob kFekSig = brillo::SecureBlob("fek-sig");
  const brillo::SecureBlob kFnekSig = brillo::SecureBlob("fnek-sig");
  const brillo::SecureBlob kChapsKey = brillo::SecureBlob("chaps-key");
  const FileSystemKeyset kFileSystemKeyset = FileSystemKeyset(
      FileSystemKey{
          .fek = kFek,
          .fnek = kFnek,
          .fek_salt = kFekSalt,
          .fnek_salt = kFnekSalt,
      },
      FileSystemKeyReference{
          .fek_sig = kFekSig,
          .fnek_sig = kFnekSig,
      },
      kChapsKey);

  // Fake USS Main Key.
  const brillo::SecureBlob kMainKey =
      brillo::SecureBlob(kAesGcm256KeySize, 0xA);

  void SetUp() override {
    stash_ = UserSecretStash::CreateRandom(kFileSystemKeyset);
    ASSERT_TRUE(stash_);
  }

  std::unique_ptr<UserSecretStash> stash_;
};

}  // namespace

TEST_F(UserSecretStashTest, CreateRandom) {
  // The secrets should be created randomly and never collide (in practice).
  EXPECT_THAT(stash_->GetFileSystemKeyset(),
              FileSystemKeysetEquals(kFileSystemKeyset));
}

// Basic test of the `CreateRandomMainKey()` method.
TEST_F(UserSecretStashTest, CreateRandomMainKey) {
  brillo::SecureBlob main_key = UserSecretStash::CreateRandomMainKey();
  EXPECT_FALSE(main_key.empty());
}

// Test the secret main keys created by `CreateRandomMainKey()` don't repeat (in
// practice).
TEST_F(UserSecretStashTest, CreateRandomMainKeyNotConstant) {
  brillo::SecureBlob main_key_1 = UserSecretStash::CreateRandomMainKey();
  brillo::SecureBlob main_key_2 = UserSecretStash::CreateRandomMainKey();
  EXPECT_NE(main_key_1, main_key_2);
}

// Verify the getters/setters of the wrapped key fields.
TEST_F(UserSecretStashTest, MainKeyWrapping) {
  const char kWrappingId1[] = "id1";
  const char kWrappingId2[] = "id2";
  const brillo::SecureBlob kWrappingKey1(kAesGcm256KeySize, 0xB);
  const brillo::SecureBlob kWrappingKey2(kAesGcm256KeySize, 0xC);

  // Initially there's no wrapped key.
  EXPECT_FALSE(stash_->HasWrappedMainKey(kWrappingId1));
  EXPECT_FALSE(stash_->HasWrappedMainKey(kWrappingId2));

  // And the main key wrapped with two wrapping keys.
  EXPECT_TRUE(stash_->AddWrappedMainKey(kMainKey, kWrappingId1, kWrappingKey1));
  EXPECT_TRUE(stash_->HasWrappedMainKey(kWrappingId1));
  EXPECT_TRUE(stash_->AddWrappedMainKey(kMainKey, kWrappingId2, kWrappingKey2));
  EXPECT_TRUE(stash_->HasWrappedMainKey(kWrappingId2));
  // Duplicate wrapping IDs aren't allowed.
  EXPECT_FALSE(
      stash_->AddWrappedMainKey(kMainKey, kWrappingId1, kWrappingKey1));

  // The main key can be unwrapped using any of the wrapping keys.
  std::optional<brillo::SecureBlob> got_main_key1 =
      stash_->UnwrapMainKey(kWrappingId1, kWrappingKey1);
  ASSERT_TRUE(got_main_key1);
  EXPECT_EQ(*got_main_key1, kMainKey);
  std::optional<brillo::SecureBlob> got_main_key2 =
      stash_->UnwrapMainKey(kWrappingId2, kWrappingKey2);
  ASSERT_TRUE(got_main_key2);
  EXPECT_EQ(*got_main_key2, kMainKey);

  // Removal of one wrapped key block preserves the other.
  EXPECT_TRUE(stash_->RemoveWrappedMainKey(kWrappingId1));
  EXPECT_FALSE(stash_->HasWrappedMainKey(kWrappingId1));
  EXPECT_TRUE(stash_->HasWrappedMainKey(kWrappingId2));
  // Removing a non-existing wrapped key block fails.
  EXPECT_FALSE(stash_->RemoveWrappedMainKey(kWrappingId1));
}

TEST_F(UserSecretStashTest, GetEncryptedUSS) {
  // Add two reset secrets to make sure encryption covers those.
  brillo::SecureBlob reset_secret1 =
      CreateSecureRandomBlob(CRYPTOHOME_RESET_SECRET_LENGTH);
  brillo::SecureBlob reset_secret2 =
      CreateSecureRandomBlob(CRYPTOHOME_RESET_SECRET_LENGTH);
  ASSERT_TRUE(stash_->SetResetSecretForLabel("label1", reset_secret1));
  ASSERT_TRUE(stash_->SetResetSecretForLabel("label2", reset_secret2));

  std::optional<brillo::Blob> uss_container =
      stash_->GetEncryptedContainer(kMainKey);
  ASSERT_NE(std::nullopt, uss_container);

  // No raw secrets in the encrypted USS, which is written to disk.
  EXPECT_FALSE(
      FindBlobInBlob(*uss_container, stash_->GetFileSystemKeyset().Key().fek));
  EXPECT_FALSE(FindBlobInBlob(*uss_container, reset_secret1));
  EXPECT_FALSE(FindBlobInBlob(*uss_container, reset_secret2));
}

TEST_F(UserSecretStashTest, EncryptAndDecryptUSS) {
  ASSERT_TRUE(stash_->SetResetSecretForLabel("label1", {0xAA, 0xBB}));

  std::optional<brillo::Blob> uss_container =
      stash_->GetEncryptedContainer(kMainKey);
  ASSERT_NE(std::nullopt, uss_container);

  std::unique_ptr<UserSecretStash> stash2 =
      UserSecretStash::FromEncryptedContainer(uss_container.value(), kMainKey);
  ASSERT_TRUE(stash2);

  EXPECT_THAT(stash_->GetFileSystemKeyset(),
              FileSystemKeysetEquals(stash2->GetFileSystemKeyset()));
  EXPECT_EQ(stash_->GetResetSecretForLabel("label1").value(),
            stash2->GetResetSecretForLabel("label1").value());
}

// Test that deserialization fails on an empty blob. Normally this never occurs,
// but we verify to be resilient against accidental or intentional file
// corruption.
TEST_F(UserSecretStashTest, DecryptErrorEmptyBuf) {
  EXPECT_FALSE(UserSecretStash::FromEncryptedContainer(
      /*flatbuffer=*/brillo::Blob(), kMainKey));
}

// Test that deserialization fails on a corrupted flatbuffer. Normally this
// never occurs, but we verify to be resilient against accidental or intentional
// file corruption.
TEST_F(UserSecretStashTest, DecryptErrorCorruptedBuf) {
  std::optional<brillo::Blob> uss_container =
      stash_->GetEncryptedContainer(kMainKey);
  ASSERT_NE(std::nullopt, uss_container);

  brillo::Blob corrupted_uss_container = *uss_container;
  for (uint8_t& byte : corrupted_uss_container)
    byte ^= 1;

  EXPECT_FALSE(UserSecretStash::FromEncryptedContainer(corrupted_uss_container,
                                                       kMainKey));
}

// Test that decryption fails on an empty decryption key.
TEST_F(UserSecretStashTest, DecryptErrorEmptyKey) {
  std::optional<brillo::Blob> uss_container =
      stash_->GetEncryptedContainer(kMainKey);
  ASSERT_NE(std::nullopt, uss_container);

  EXPECT_FALSE(
      UserSecretStash::FromEncryptedContainer(*uss_container, /*main_key=*/{}));
}

// Test that decryption fails on a decryption key of a wrong size.
TEST_F(UserSecretStashTest, DecryptErrorKeyBadSize) {
  std::optional<brillo::Blob> uss_container =
      stash_->GetEncryptedContainer(kMainKey);
  ASSERT_NE(std::nullopt, uss_container);

  brillo::SecureBlob bad_size_main_key = kMainKey;
  bad_size_main_key.resize(kAesGcm256KeySize - 1);

  EXPECT_FALSE(UserSecretStash::FromEncryptedContainer(*uss_container,
                                                       bad_size_main_key));
}

// Test that decryption fails on a wrong decryption key.
TEST_F(UserSecretStashTest, DecryptErrorWrongKey) {
  std::optional<brillo::Blob> uss_container =
      stash_->GetEncryptedContainer(kMainKey);
  ASSERT_NE(std::nullopt, uss_container);

  brillo::SecureBlob wrong_main_key = kMainKey;
  wrong_main_key[0] ^= 1;

  EXPECT_FALSE(
      UserSecretStash::FromEncryptedContainer(*uss_container, wrong_main_key));
}

// Test that wrapped key blocks are [de]serialized correctly.
TEST_F(UserSecretStashTest, EncryptAndDecryptUSSWithWrappedKeys) {
  const char kWrappingId1[] = "id1";
  const char kWrappingId2[] = "id2";
  const brillo::SecureBlob kWrappingKey1(kAesGcm256KeySize, 0xB);
  const brillo::SecureBlob kWrappingKey2(kAesGcm256KeySize, 0xC);

  // Add wrapped key blocks.
  EXPECT_TRUE(stash_->AddWrappedMainKey(kMainKey, kWrappingId1, kWrappingKey1));
  EXPECT_TRUE(stash_->AddWrappedMainKey(kMainKey, kWrappingId2, kWrappingKey2));

  // Do the serialization-deserialization roundtrip with the USS.
  std::optional<brillo::Blob> uss_container =
      stash_->GetEncryptedContainer(kMainKey);
  ASSERT_NE(std::nullopt, uss_container);
  std::unique_ptr<UserSecretStash> stash2 =
      UserSecretStash::FromEncryptedContainer(uss_container.value(), kMainKey);
  ASSERT_TRUE(stash2);

  // The wrapped key blocks are present in the loaded stash and can be
  // decrypted.
  EXPECT_TRUE(stash2->HasWrappedMainKey(kWrappingId1));
  EXPECT_TRUE(stash2->HasWrappedMainKey(kWrappingId2));
  std::optional<brillo::SecureBlob> got_main_key1 =
      stash2->UnwrapMainKey(kWrappingId1, kWrappingKey1);
  ASSERT_TRUE(got_main_key1);
  EXPECT_EQ(*got_main_key1, kMainKey);
}

// Test that the USS can be loaded and decrypted using the wrapping key stored
// in it.
TEST_F(UserSecretStashTest, EncryptAndDecryptUSSViaWrappedKey) {
  // Add a wrapped key block.
  const char kWrappingId[] = "id";
  const brillo::SecureBlob kWrappingKey(kAesGcm256KeySize, 0xB);
  EXPECT_TRUE(stash_->AddWrappedMainKey(kMainKey, kWrappingId, kWrappingKey));

  // Encrypt the USS.
  std::optional<brillo::Blob> uss_container =
      stash_->GetEncryptedContainer(kMainKey);
  ASSERT_NE(std::nullopt, uss_container);

  // The USS can be decrypted using the wrapping key.
  brillo::SecureBlob unwrapped_main_key;
  std::unique_ptr<UserSecretStash> stash2 =
      UserSecretStash::FromEncryptedContainerWithWrappingKey(
          uss_container.value(), kWrappingId, kWrappingKey,
          &unwrapped_main_key);
  ASSERT_TRUE(stash2);
  EXPECT_THAT(stash_->GetFileSystemKeyset(),
              FileSystemKeysetEquals(stash2->GetFileSystemKeyset()));
  EXPECT_EQ(unwrapped_main_key, kMainKey);
}

// Test the USS experiment state is off by default, but can be toggled in tests.
TEST_F(UserSecretStashTest, ExperimentState) {
  // The experiment is off by default.
  EXPECT_FALSE(IsUserSecretStashExperimentEnabled());

  // Verify the test can toggle the experiment state.
  SetUserSecretStashExperimentForTesting(/*enabled=*/true);
  EXPECT_TRUE(IsUserSecretStashExperimentEnabled());

  // Unset the experiment override to avoid affecting other test cases.
  SetUserSecretStashExperimentForTesting(/*enabled=*/std::nullopt);
}

// Test that a newly created USS has the current OS version stored.
TEST_F(UserSecretStashTest, OsVersion) {
  constexpr char kLsbRelease[] =
      "CHROMEOS_RELEASE_NAME=Chrome "
      "OS\nCHROMEOS_RELEASE_VERSION=11012.0.2018_08_28_1422\n";
  base::test::ScopedChromeOSVersionInfo scoped_version(
      kLsbRelease, /*lsb_release_time=*/base::Time());

  std::unique_ptr<UserSecretStash> stash1 =
      UserSecretStash::CreateRandom(kFileSystemKeyset);
  ASSERT_TRUE(stash1);
  EXPECT_EQ(stash1->GetCreatedOnOsVersion(), "11012.0.2018_08_28_1422");
}

// Test that the OS version is stored in the USS and doesn't change even when
// the OS updates.
TEST_F(UserSecretStashTest, OsVersionStays) {
  constexpr char kLsbRelease1[] =
      "CHROMEOS_RELEASE_NAME=Chrome "
      "OS\nCHROMEOS_RELEASE_VERSION=11012.0.2018_08_28_1422\n";
  constexpr char kLsbRelease2[] =
      "CHROMEOS_RELEASE_NAME=Chrome "
      "OS\nCHROMEOS_RELEASE_VERSION=22222.0.2028_01_01_9999\n";

  // Create and encrypt the USS on the version 1.
  std::optional<brillo::Blob> uss_container;
  {
    base::test::ScopedChromeOSVersionInfo scoped_version1(
        kLsbRelease1, /*lsb_release_time=*/base::Time());
    std::unique_ptr<UserSecretStash> stash1 =
        UserSecretStash::CreateRandom(kFileSystemKeyset);
    ASSERT_TRUE(stash1);
    uss_container = stash1->GetEncryptedContainer(kMainKey);
    ASSERT_TRUE(uss_container.has_value());
  }

  // Decrypt the USS on the version 2. Check that the field still mentions
  // version 1.
  {
    base::test::ScopedChromeOSVersionInfo scoped_version2(
        kLsbRelease2, /*lsb_release_time=*/base::Time());
    std::unique_ptr<UserSecretStash> stash2 =
        UserSecretStash::FromEncryptedContainer(uss_container.value(),
                                                kMainKey);
    ASSERT_TRUE(stash2);
    EXPECT_EQ(stash2->GetCreatedOnOsVersion(), "11012.0.2018_08_28_1422");
  }
}

// Test that the USS is correctly created and loaded even when reading the OS
// version fails.
TEST_F(UserSecretStashTest, MissingOsVersion) {
  // Note: Normally unit tests don't have access to a CrOS /etc/lsb-release
  // anyway, but this override guarantees that the test passes regardless of
  // that.
  base::test::ScopedChromeOSVersionInfo scoped_version(
      /*lsb_release=*/"", /*lsb_release_time=*/base::Time());

  // A newly created USS should have an empty OS version.
  std::unique_ptr<UserSecretStash> stash =
      UserSecretStash::CreateRandom(kFileSystemKeyset);
  ASSERT_TRUE(stash);
  EXPECT_TRUE(stash->GetCreatedOnOsVersion().empty());

  // Do a encrypt-decrypt roundtrip and verify the OS version is still empty.
  std::optional<brillo::Blob> uss_container =
      stash_->GetEncryptedContainer(kMainKey);
  ASSERT_TRUE(uss_container.has_value());
  std::unique_ptr<UserSecretStash> stash2 =
      UserSecretStash::FromEncryptedContainer(uss_container.value(), kMainKey);
  ASSERT_TRUE(stash2);
  EXPECT_TRUE(stash2->GetCreatedOnOsVersion().empty());
}

// Test that SetResetSecretForLabel does not overwrite if a reset secret already
// exists.
TEST_F(UserSecretStashTest, DoubleInsertResetSecret) {
  brillo::SecureBlob reset_secret1 = {0xAA, 0xBB, 0xCC};
  brillo::SecureBlob reset_secret2 = {0xDD, 0xEE, 0x11};
  brillo::SecureBlob reset_secret3 = {0x22, 0x33, 0x44};

  EXPECT_TRUE(stash_->SetResetSecretForLabel("label1", reset_secret1));
  EXPECT_TRUE(stash_->SetResetSecretForLabel("label2", reset_secret2));
  EXPECT_FALSE(stash_->SetResetSecretForLabel("label1", reset_secret3));

  EXPECT_EQ(reset_secret1, stash_->GetResetSecretForLabel("label1").value());
}

// Fixture that helps to read/manipulate the USS flatbuffer's internals using
// the flatbuffer C++ bindings.
class UserSecretStashInternalsTest : public UserSecretStashTest {
 protected:
  void SetUp() override {
    ASSERT_NO_FATAL_FAILURE(UserSecretStashTest::SetUp());
    ASSERT_NO_FATAL_FAILURE(UpdateBindingStrusts());
  }

  // Populates |uss_container_struct_| and |uss_payload_struct_| based on
  // |stash_|.
  void UpdateBindingStrusts() {
    // Encrypt the USS.
    std::optional<brillo::Blob> uss_container =
        stash_->GetEncryptedContainer(kMainKey);
    ASSERT_TRUE(uss_container);

    // Unpack the wrapped USS flatbuffer to |uss_container_struct_|.
    std::optional<UserSecretStashContainer> uss_container_struct =
        UserSecretStashContainer::Deserialize(uss_container.value());
    ASSERT_TRUE(uss_container_struct);
    uss_container_struct_ = std::move(uss_container_struct.value());

    // Decrypt and unpack the USS flatbuffer to |uss_payload_struct_|.
    brillo::SecureBlob uss_payload;
    ASSERT_TRUE(AesGcmDecrypt(
        brillo::SecureBlob(uss_container_struct_.ciphertext),
        /*ad=*/std::nullopt, brillo::SecureBlob(uss_container_struct_.gcm_tag),
        kMainKey, brillo::SecureBlob(uss_container_struct_.iv), &uss_payload));
    std::optional<UserSecretStashPayload> uss_payload_struct =
        UserSecretStashPayload::Deserialize(uss_payload);
    ASSERT_TRUE(uss_payload_struct);
    uss_payload_struct_ = std::move(*uss_payload_struct);
  }

  // Converts |uss_container_struct_| => "container flatbuffer".
  brillo::Blob GetFlatbufferFromUssContainerStruct() const {
    std::optional<brillo::Blob> serialized = uss_container_struct_.Serialize();
    if (!serialized.has_value()) {
      ADD_FAILURE() << "Failed to serialize UserSecretStashContainer";
      return brillo::Blob();
    }
    return serialized.value();
  }

  // Converts |uss_payload_struct_| => "payload flatbuffer" =>
  // UserSecretStashContainer => "container flatbuffer".
  brillo::Blob GetFlatbufferFromUssPayloadStruct() const {
    return GetFlatbufferFromUssPayloadBlob(PackUssPayloadStruct());
  }

  // Converts |uss_payload_struct_| => "payload flatbuffer".
  brillo::SecureBlob PackUssPayloadStruct() const {
    std::optional<brillo::SecureBlob> serialized =
        uss_payload_struct_.Serialize();
    if (!serialized.has_value()) {
      ADD_FAILURE() << "Failed to serialize UserSecretStashPayload";
      return brillo::SecureBlob();
    }
    return serialized.value();
  }

  // Converts "payload flatbuffer" => UserSecretStashContainer => "container
  // flatbuffer".
  brillo::Blob GetFlatbufferFromUssPayloadBlob(
      const brillo::SecureBlob& uss_payload) const {
    // Encrypt the packed |uss_payload_struct_|.
    brillo::SecureBlob iv, tag, ciphertext;
    EXPECT_TRUE(AesGcmEncrypt(uss_payload, /*ad=*/std::nullopt, kMainKey, &iv,
                              &tag, &ciphertext));

    // Create a copy of |uss_container_struct_|, with the encrypted blob
    // replaced.
    UserSecretStashContainer new_uss_container_struct = uss_container_struct_;
    new_uss_container_struct.ciphertext =
        brillo::Blob(ciphertext.begin(), ciphertext.end());
    new_uss_container_struct.iv = brillo::Blob(iv.begin(), iv.end());
    new_uss_container_struct.gcm_tag = brillo::Blob(tag.begin(), tag.end());

    // Pack |new_uss_container_struct|.
    std::optional<brillo::Blob> serialized =
        new_uss_container_struct.Serialize();
    if (!serialized.has_value()) {
      ADD_FAILURE() << "Failed to seralize the USS container";
      return brillo::Blob();
    }
    return serialized.value();
  }

  UserSecretStashContainer uss_container_struct_;
  UserSecretStashPayload uss_payload_struct_;
};

// Verify that the test fixture correctly generates the USS flatbuffers from the
// binding structs.
TEST_F(UserSecretStashInternalsTest, SmokeTest) {
  EXPECT_TRUE(UserSecretStash::FromEncryptedContainer(
      GetFlatbufferFromUssPayloadBlob(PackUssPayloadStruct()), kMainKey));
  EXPECT_TRUE(UserSecretStash::FromEncryptedContainer(
      GetFlatbufferFromUssPayloadStruct(), kMainKey));
  EXPECT_TRUE(UserSecretStash::FromEncryptedContainer(
      GetFlatbufferFromUssContainerStruct(), kMainKey));
}

// Test that decryption fails when the USS payload is a corrupted flatbuffer.
// Normally this never occurs, but we verify to be resilient against accidental
// or intentional file corruption.
TEST_F(UserSecretStashInternalsTest, DecryptErrorBadPayload) {
  brillo::SecureBlob uss_payload = PackUssPayloadStruct();
  for (uint8_t& byte : uss_payload)
    byte ^= 1;

  EXPECT_FALSE(UserSecretStash::FromEncryptedContainer(
      GetFlatbufferFromUssPayloadBlob(uss_payload), kMainKey));
}

// Test that decryption fails when the USS payload is a truncated flatbuffer.
// Normally this never occurs, but we verify to be resilient against accidental
// or intentional file corruption.
TEST_F(UserSecretStashInternalsTest, DecryptErrorPayloadBadSize) {
  brillo::SecureBlob uss_payload = PackUssPayloadStruct();
  uss_payload.resize(uss_payload.size() / 2);

  EXPECT_FALSE(UserSecretStash::FromEncryptedContainer(
      GetFlatbufferFromUssPayloadBlob(uss_payload), kMainKey));
}

// Test that decryption fails when the encryption algorithm is not set. Normally
// this never occurs, but we verify to be resilient against accidental or
// intentional file corruption.
TEST_F(UserSecretStashInternalsTest, DecryptErrorNoAlgorithm) {
  uss_container_struct_.encryption_algorithm.reset();

  EXPECT_FALSE(UserSecretStash::FromEncryptedContainer(
      GetFlatbufferFromUssContainerStruct(), kMainKey));
}

// Test that decryption fails when the encryption algorithm is unknown. Normally
// this never occurs, but we verify to be resilient against accidental or
// intentional file corruption.
TEST_F(UserSecretStashInternalsTest, DecryptErrorUnknownAlgorithm) {
  uss_container_struct_
      .encryption_algorithm = static_cast<UserSecretStashEncryptionAlgorithm>(
      std::numeric_limits<
          std::underlying_type_t<UserSecretStashEncryptionAlgorithm>>::max());

  EXPECT_FALSE(UserSecretStash::FromEncryptedContainer(
      GetFlatbufferFromUssContainerStruct(), kMainKey));
}

// Test that decryption fails when the ciphertext field is missing. Normally
// this never occurs, but we verify to be resilient against accidental or
// intentional file corruption.
TEST_F(UserSecretStashInternalsTest, DecryptErrorNoCiphertext) {
  uss_container_struct_.ciphertext.clear();

  EXPECT_FALSE(UserSecretStash::FromEncryptedContainer(
      GetFlatbufferFromUssContainerStruct(), kMainKey));
}

// Test that decryption fails when the ciphertext field is corrupted. Normally
// this never occurs, but we verify to be resilient against accidental or
// intentional file corruption.
TEST_F(UserSecretStashInternalsTest, DecryptErrorCorruptedCiphertext) {
  for (uint8_t& byte : uss_container_struct_.ciphertext)
    byte ^= 1;

  EXPECT_FALSE(UserSecretStash::FromEncryptedContainer(
      GetFlatbufferFromUssContainerStruct(), kMainKey));
}

// Test that decryption fails when the iv field is missing. Normally this never
// occurs, but we verify to be resilient against accidental or intentional file
// corruption.
TEST_F(UserSecretStashInternalsTest, DecryptErrorNoIv) {
  uss_container_struct_.iv.clear();

  EXPECT_FALSE(UserSecretStash::FromEncryptedContainer(
      GetFlatbufferFromUssContainerStruct(), kMainKey));
}

// Test that decryption fails when the iv field has a wrong value. Normally this
// never occurs, but we verify to be resilient against accidental or intentional
// file corruption.
TEST_F(UserSecretStashInternalsTest, DecryptErrorWrongIv) {
  uss_container_struct_.iv[0] ^= 1;

  EXPECT_FALSE(UserSecretStash::FromEncryptedContainer(
      GetFlatbufferFromUssContainerStruct(), kMainKey));
}

// Test that decryption fails when the iv field is of a wrong size. Normally
// this never occurs, but we verify to be resilient against accidental or
// intentional file corruption.
TEST_F(UserSecretStashInternalsTest, DecryptErrorIvBadSize) {
  uss_container_struct_.iv.resize(uss_container_struct_.iv.size() - 1);

  EXPECT_FALSE(UserSecretStash::FromEncryptedContainer(
      GetFlatbufferFromUssContainerStruct(), kMainKey));
}

// Test that decryption fails when the gcm_tag field is missing. Normally this
// never occurs, but we verify to be resilient against accidental or intentional
// file corruption.
TEST_F(UserSecretStashInternalsTest, DecryptErrorNoGcmTag) {
  uss_container_struct_.gcm_tag.clear();

  EXPECT_FALSE(UserSecretStash::FromEncryptedContainer(
      GetFlatbufferFromUssContainerStruct(), kMainKey));
}

// Test that decryption fails when the gcm_tag field has a wrong value.
TEST_F(UserSecretStashInternalsTest, DecryptErrorWrongGcmTag) {
  uss_container_struct_.gcm_tag[0] ^= 1;

  EXPECT_FALSE(UserSecretStash::FromEncryptedContainer(
      GetFlatbufferFromUssContainerStruct(), kMainKey));
}

// Test that decryption fails when the gcm_tag field is of a wrong size.
// Normally this never occurs, but we verify to be resilient against accidental
// or intentional file corruption.
TEST_F(UserSecretStashInternalsTest, DecryptErrorGcmTagBadSize) {
  uss_container_struct_.gcm_tag.resize(uss_container_struct_.gcm_tag.size() -
                                       1);

  EXPECT_FALSE(UserSecretStash::FromEncryptedContainer(
      GetFlatbufferFromUssContainerStruct(), kMainKey));
}

// Test the decryption fails when the payload's FEK field is missing. Normally
// this never occurs, but we verify to be resilient against accidental or
// intentional file corruption.
TEST_F(UserSecretStashInternalsTest, DecryptErrorNoFek) {
  uss_payload_struct_.fek.clear();

  EXPECT_FALSE(UserSecretStash::FromEncryptedContainer(
      GetFlatbufferFromUssPayloadStruct(), kMainKey));
}

// Test the decryption fails when the payload's FNEK field is missing. Normally
// this never occurs, but we verify to be resilient against accidental or
// intentional file corruption.
TEST_F(UserSecretStashInternalsTest, DecryptErrorNoFnek) {
  uss_payload_struct_.fnek.clear();

  EXPECT_FALSE(UserSecretStash::FromEncryptedContainer(
      GetFlatbufferFromUssPayloadStruct(), kMainKey));
}

// Test the decryption fails when the payload's FEK salt field is missing.
// Normally this never occurs, but we verify to be resilient against accidental
// or intentional file corruption.
TEST_F(UserSecretStashInternalsTest, DecryptErrorNoFekSalt) {
  uss_payload_struct_.fek_salt.clear();

  EXPECT_FALSE(UserSecretStash::FromEncryptedContainer(
      GetFlatbufferFromUssPayloadStruct(), kMainKey));
}

// Test the decryption fails when the payload's FNEK salt field is missing.
// Normally this never occurs, but we verify to be resilient against accidental
// or intentional file corruption.
TEST_F(UserSecretStashInternalsTest, DecryptErrorNoFnekSalt) {
  uss_payload_struct_.fnek_salt.clear();

  EXPECT_FALSE(UserSecretStash::FromEncryptedContainer(
      GetFlatbufferFromUssPayloadStruct(), kMainKey));
}

// Test the decryption fails when the payload's FEK signature field is missing.
// Normally this never occurs, but we verify to be resilient against accidental
// or intentional file corruption.
TEST_F(UserSecretStashInternalsTest, DecryptErrorNoFekSig) {
  uss_payload_struct_.fek_sig.clear();

  EXPECT_FALSE(UserSecretStash::FromEncryptedContainer(
      GetFlatbufferFromUssPayloadStruct(), kMainKey));
}

// Test the decryption fails when the payload's FNEK signature field is missing.
// Normally this never occurs, but we verify to be resilient against accidental
// or intentional file corruption.
TEST_F(UserSecretStashInternalsTest, DecryptErrorNoFnekSig) {
  uss_payload_struct_.fnek_sig.clear();

  EXPECT_FALSE(UserSecretStash::FromEncryptedContainer(
      GetFlatbufferFromUssPayloadStruct(), kMainKey));
}

// Test the decryption fails when the payload's Chaps key field is missing.
// Normally this never occurs, but we verify to be resilient against accidental
// or intentional file corruption.
TEST_F(UserSecretStashInternalsTest, DecryptErrorNoChapsKey) {
  uss_payload_struct_.chaps_key.clear();

  EXPECT_FALSE(UserSecretStash::FromEncryptedContainer(
      GetFlatbufferFromUssPayloadStruct(), kMainKey));
}

// Fixture that prebundles the USS object with a wrapped key block.
class UserSecretStashInternalsWrappingTest
    : public UserSecretStashInternalsTest {
 protected:
  const char* const kWrappingId = "id";
  const brillo::SecureBlob kWrappingKey =
      brillo::SecureBlob(kAesGcm256KeySize, 0xB);

  void SetUp() override {
    ASSERT_NO_FATAL_FAILURE(UserSecretStashInternalsTest::SetUp());
    EXPECT_TRUE(stash_->AddWrappedMainKey(kMainKey, kWrappingId, kWrappingKey));
    ASSERT_NO_FATAL_FAILURE(UpdateBindingStrusts());
  }
};

// Verify that the test fixture correctly generates the flatbuffers from the
// Object API.
TEST_F(UserSecretStashInternalsWrappingTest, SmokeTest) {
  brillo::SecureBlob main_key;
  EXPECT_TRUE(UserSecretStash::FromEncryptedContainerWithWrappingKey(
      GetFlatbufferFromUssContainerStruct(), kWrappingId, kWrappingKey,
      &main_key));
  EXPECT_EQ(main_key, kMainKey);
}

// Test that decryption via wrapping key fails when the only block's wrapping_id
// is empty. Normally this never occurs, but we verify to be resilient against
// accidental or intentional file corruption.
TEST_F(UserSecretStashInternalsWrappingTest, ErrorNoWrappingId) {
  uss_container_struct_.wrapped_key_blocks[0].wrapping_id = std::string();

  brillo::SecureBlob main_key;
  EXPECT_FALSE(UserSecretStash::FromEncryptedContainerWithWrappingKey(
      GetFlatbufferFromUssContainerStruct(), kWrappingId, kWrappingKey,
      &main_key));
}

// Test that decryption via wrapping key succeeds despite having an extra block
// with an empty wrapping_id (this block should be ignored). Normally this never
// occurs, but we verify to be resilient against accidental or intentional file
// corruption.
TEST_F(UserSecretStashInternalsWrappingTest, SuccessWithExtraNoWrappingId) {
  UserSecretStashWrappedKeyBlock key_block_clone =
      uss_container_struct_.wrapped_key_blocks[0];
  key_block_clone.wrapping_id = std::string();
  uss_container_struct_.wrapped_key_blocks.push_back(key_block_clone);

  brillo::SecureBlob main_key;
  EXPECT_TRUE(UserSecretStash::FromEncryptedContainerWithWrappingKey(
      GetFlatbufferFromUssContainerStruct(), kWrappingId, kWrappingKey,
      &main_key));
}

// Test that decryption via wrapping key succeeds despite having an extra block
// with a duplicate wrapping_id (this block should be ignored). Normally this
// never occurs, but we verify to be resilient against accidental or intentional
// file corruption.
TEST_F(UserSecretStashInternalsWrappingTest, SuccessWithDuplicateWrappingId) {
  UserSecretStashWrappedKeyBlock key_block_clone =
      uss_container_struct_.wrapped_key_blocks[0];
  uss_container_struct_.wrapped_key_blocks.push_back(key_block_clone);

  brillo::SecureBlob main_key;
  EXPECT_TRUE(UserSecretStash::FromEncryptedContainerWithWrappingKey(
      GetFlatbufferFromUssContainerStruct(), kWrappingId, kWrappingKey,
      &main_key));
}

// Test that decryption via wrapping key fails when the algorithm is not
// specified in the stored block. Normally this never occurs, but we verify to
// be resilient against accidental or intentional file corruption.
TEST_F(UserSecretStashInternalsWrappingTest, ErrorNoAlgorithm) {
  uss_container_struct_.wrapped_key_blocks[0].encryption_algorithm =
      std::nullopt;

  brillo::SecureBlob main_key;
  EXPECT_FALSE(UserSecretStash::FromEncryptedContainerWithWrappingKey(
      GetFlatbufferFromUssContainerStruct(), kWrappingId, kWrappingKey,
      &main_key));
}

// Test that decryption via wrapping key fails when the algorithm is unknown.
// Normally this never occurs, but we verify to be resilient against accidental
// or intentional file corruption.
TEST_F(UserSecretStashInternalsWrappingTest, ErrorUnknownAlgorithm) {
  uss_container_struct_.wrapped_key_blocks[0]
      .encryption_algorithm = static_cast<UserSecretStashEncryptionAlgorithm>(
      std::numeric_limits<
          std::underlying_type_t<UserSecretStashEncryptionAlgorithm>>::max());

  brillo::SecureBlob main_key;
  EXPECT_FALSE(UserSecretStash::FromEncryptedContainerWithWrappingKey(
      GetFlatbufferFromUssContainerStruct(), kWrappingId, kWrappingKey,
      &main_key));
}

// Test that decryption via wrapping key fails when the encrypted_key is empty
// in the stored block.
TEST_F(UserSecretStashInternalsWrappingTest, ErrorEmptyEncryptedKey) {
  uss_container_struct_.wrapped_key_blocks[0].encrypted_key.clear();

  brillo::SecureBlob main_key;
  EXPECT_FALSE(UserSecretStash::FromEncryptedContainerWithWrappingKey(
      GetFlatbufferFromUssContainerStruct(), kWrappingId, kWrappingKey,
      &main_key));
}

// Test that decryption via wrapping key fails when the encrypted_key in the
// stored block is corrupted.
TEST_F(UserSecretStashInternalsWrappingTest, ErrorBadEncryptedKey) {
  uss_container_struct_.wrapped_key_blocks[0].encrypted_key[0] ^= 1;

  brillo::SecureBlob main_key;
  EXPECT_FALSE(UserSecretStash::FromEncryptedContainerWithWrappingKey(
      GetFlatbufferFromUssContainerStruct(), kWrappingId, kWrappingKey,
      &main_key));
}

// Test that decryption via wrapping key fails when the iv is empty in the
// stored block. Normally this never occurs, but we verify to be resilient
// against accidental or intentional file corruption.
TEST_F(UserSecretStashInternalsWrappingTest, ErrorNoIv) {
  uss_container_struct_.wrapped_key_blocks[0].iv.clear();

  brillo::SecureBlob main_key;
  EXPECT_FALSE(UserSecretStash::FromEncryptedContainerWithWrappingKey(
      GetFlatbufferFromUssContainerStruct(), kWrappingId, kWrappingKey,
      &main_key));
}

// Test that decryption via wrapping key fails when the iv in the stored block
// is corrupted. Normally this never occurs, but we verify to be resilient
// against accidental or intentional file corruption.
TEST_F(UserSecretStashInternalsWrappingTest, ErrorWrongIv) {
  uss_container_struct_.wrapped_key_blocks[0].iv[0] ^= 1;

  brillo::SecureBlob main_key;
  EXPECT_FALSE(UserSecretStash::FromEncryptedContainerWithWrappingKey(
      GetFlatbufferFromUssContainerStruct(), kWrappingId, kWrappingKey,
      &main_key));
}

// Test that decryption via wrapping key fails when the iv in the stored block
// is of wrong size. Normally this never occurs, but we verify to be resilient
// against accidental or intentional file corruption.
TEST_F(UserSecretStashInternalsWrappingTest, ErrorIvBadSize) {
  uss_container_struct_.wrapped_key_blocks[0].iv.resize(
      uss_container_struct_.wrapped_key_blocks[0].iv.size() - 1);

  brillo::SecureBlob main_key;
  EXPECT_FALSE(UserSecretStash::FromEncryptedContainerWithWrappingKey(
      GetFlatbufferFromUssContainerStruct(), kWrappingId, kWrappingKey,
      &main_key));
}

// Test that decryption via wrapping key fails when the gcm_tag is empty in the
// stored block. Normally this never occurs, but we verify to be resilient
// against accidental or intentional file corruption.
TEST_F(UserSecretStashInternalsWrappingTest, ErrorNoGcmTag) {
  uss_container_struct_.wrapped_key_blocks[0].gcm_tag.clear();

  brillo::SecureBlob main_key;
  EXPECT_FALSE(UserSecretStash::FromEncryptedContainerWithWrappingKey(
      GetFlatbufferFromUssContainerStruct(), kWrappingId, kWrappingKey,
      &main_key));
}

// Test that decryption via wrapping key fails when the gcm_tag in the stored
// block is corrupted. Normally this never occurs, but we verify to be resilient
// against accidental or intentional file corruption.
TEST_F(UserSecretStashInternalsWrappingTest, ErrorWrongGcmTag) {
  uss_container_struct_.wrapped_key_blocks[0].gcm_tag[0] ^= 1;

  brillo::SecureBlob main_key;
  EXPECT_FALSE(UserSecretStash::FromEncryptedContainerWithWrappingKey(
      GetFlatbufferFromUssContainerStruct(), kWrappingId, kWrappingKey,
      &main_key));
}

// Test that decryption via wrapping key fails when the gcm_tag in the stored
// block is of wrong size. Normally this never occurs, but we verify to be
// resilient against accidental or intentional file corruption.
TEST_F(UserSecretStashInternalsWrappingTest, ErrorGcmTagBadSize) {
  uss_container_struct_.wrapped_key_blocks[0].gcm_tag.resize(
      uss_container_struct_.wrapped_key_blocks[0].gcm_tag.size() - 1);

  brillo::SecureBlob main_key;
  EXPECT_FALSE(UserSecretStash::FromEncryptedContainerWithWrappingKey(
      GetFlatbufferFromUssContainerStruct(), kWrappingId, kWrappingKey,
      &main_key));
}

}  // namespace cryptohome
