// Copyright 2019 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 <cstdint>
#include <optional>
#include <string>
#include <utility>

#include <base/bind.h>
#include <base/callback_helpers.h>
#include <base/check.h>
#include <base/hash/sha1.h>
#include <base/logging.h>
#include <base/run_loop.h>
#include <base/strings/string_number_conversions.h>
#include <crypto/scoped_openssl_types.h>
#include <crypto/sha2.h>
#include <openssl/err.h>
#include <openssl/evp.h>
#include <openssl/sha.h>
#include <trunks/error_codes.h>
#include <trunks/trunks_factory_impl.h>

#include "sealed_storage/sealed_storage.h"

namespace {
// Default D-Bus call Timeout
constexpr base::TimeDelta kDefaultTimeout = base::Minutes(2);

// Version tag at the start of serialized sealed blob.
enum SerializedVer : char {
  kSerializedVer1 = 0x01,
  kSerializedVer2 = 0x02,
};

// Magic value, sha256 of which is extended to PCRs when requested.
constexpr char kExtendMagic[] = "SealedStorage";

constexpr size_t kPolicySize = crypto::kSHA256Length;
constexpr size_t kPCRSize = crypto::kSHA256Length;

// RAII version of SHA256_CTX, with auto-initialization on instantiation
// and auto-cleanup on leaving scope.
class SecureSHA256_CTX {
 public:
  SecureSHA256_CTX() { SHA256_Init(&ctx_); }
  ~SecureSHA256_CTX() { OPENSSL_cleanse(&ctx_, sizeof(ctx_)); }
  SHA256_CTX* get() { return &ctx_; }

 private:
  SHA256_CTX ctx_;
};

// Get value to extend to a requested PCR.
std::string GetExtendValue() {
  return crypto::SHA256HashString(kExtendMagic);
}

// Get the expected initial PCR value before anything is extended to it.
std::string GetInitialPCRValue() {
  return std::string(kPCRSize, 0);
}

// Generate AES-256 key from Z point: key = SHA256(z.x)
brillo::SecureBlob GetKeyFromZ(const trunks::TPM2B_ECC_POINT& z) {
  SecureSHA256_CTX ctx;
  const trunks::TPM2B_ECC_PARAMETER& x = z.point.x;
  SHA256_Update(ctx.get(), x.buffer, x.size);
  brillo::SecureBlob key(crypto::kSHA256Length);
  SHA256_Final(key.data(), ctx.get());
  return key;
}

// Get a PCR0 value corresponding to one of the known modes.
std::string GetPCR0ValueForMode(const sealed_storage::BootMode& mode) {
  std::string mode_str(std::cbegin(mode), std::cend(mode));
  std::string mode_digest = base::SHA1HashString(mode_str);
  mode_digest.resize(kPCRSize);
  return crypto::SHA256HashString(GetInitialPCRValue() + mode_digest);
}

// Universal hex dump of any container with .data() and .size()
template <typename T>
std::string HexDump(const T& obj) {
  return base::HexEncode(obj.data(), obj.size());
}

// Checks error code returned from the TPM. On error, prints to the log and
// returns false. On success, returns true.
bool CheckTpmResult(trunks::TPM_RC result, std::string op) {
  if (result == trunks::TPM_RC_SUCCESS) {
    return true;
  }

  LOG(ERROR) << "Failed to " << op << ": " << trunks::GetErrorString(result);
  return false;
}

// Returns the string representing the openssl error.
std::string GetOpenSSLError() {
  BIO* bio = BIO_new(BIO_s_mem());
  ERR_print_errors(bio);
  char* data = NULL;
  int data_len = BIO_get_mem_data(bio, &data);
  std::string error_string(data, data_len);
  BIO_free(bio);
  return error_string;
}

void ReportOpenSSLError(const std::string& op_name) {
  LOG(ERROR) << "Failed to " << op_name;
  VLOG(1) << "Error details: " << GetOpenSSLError();
}

// Gets policy data from serialized blob.
// Returns std::nullopt in case of error.
std::optional<std::string> DeserializePolicyDigest(
    std::string* serialized_data) {
  DCHECK(serialized_data);

  uint16_t size;
  if (trunks::Parse_uint16_t(serialized_data, &size,
                             nullptr /* value_bytes */) !=
      trunks::TPM_RC_SUCCESS) {
    LOG(ERROR) << "Failed to parse policy digest size";
    return std::nullopt;
  }
  if (serialized_data->size() < size) {
    LOG(ERROR) << "Policy digest longer than the remaining sealed data: "
               << serialized_data->size() << " < " << size;
    return std::nullopt;
  }

  std::string policy_digest = serialized_data->substr(0, size);
  serialized_data->erase(0, size);
  if (policy_digest.size() != kPolicySize) {
    LOG(ERROR) << "Unexpected policy digest size: " << policy_digest.size();
    return std::nullopt;
  }
  return policy_digest;
}

}  // namespace

namespace sealed_storage {

// Structure to hold the key and IV for software-based AES encryption and
// decryption.
struct Key {
 public:
  static const EVP_CIPHER* GetCipher() { return EVP_aes_256_cbc(); }
  static uint16_t GetIVSize() { return EVP_CIPHER_iv_length(GetCipher()); }
  static uint16_t GetKeySize() { return EVP_CIPHER_key_length(GetCipher()); }
  static uint16_t GetBlockSize() { return EVP_CIPHER_block_size(GetCipher()); }

  // Initializes the structure from private and public seeds resulting from
  // TPM-based ECDHE operation.
  bool Init(const PrivSeeds& priv_seeds, const PubSeeds& pub_seeds);

  // Encrypts the plain data using the initialized key and IV. In case of error,
  // returns nullopt.
  std::optional<Data> Encrypt(const SecretData& plain_data) const;

  // Decrypts the data using the initialized key and IV. Verifies that the
  // resulting plaintext size matches the |expected size_|. In case of error,
  // returns nullopt.
  std::optional<SecretData> Decrypt(const Data& encrypted_data) const;

 private:
  brillo::SecureBlob key_;
  brillo::Blob iv_;
  uint16_t expected_size_;
};

Policy::PcrMap::value_type Policy::BootModePCR(const BootMode& mode) {
  return {0, GetPCR0ValueForMode(mode)};
}

Policy::PcrMap::value_type Policy::UnchangedPCR(uint32_t pcr_num) {
  return {pcr_num, GetInitialPCRValue()};
}

SealedStorage::SealedStorage(
    const Policy& policy,
    trunks::TrunksFactory* trunks_factory,
    org::chromium::TpmManagerProxyInterface* tpm_ownership)
    : policy_(policy),
      trunks_factory_(trunks_factory),
      tpm_ownership_(tpm_ownership) {
  DCHECK(trunks_factory_);
  DCHECK(tpm_ownership_);
}

SealedStorage::SealedStorage(const Policy& policy)
    : policy_(policy),
      dft_trunks_factory_(CreateTrunksFactory()),
      dft_tpm_ownership_(CreateTpmOwnershipInterface()) {
  trunks_factory_ = dft_trunks_factory_.get();
  tpm_ownership_ = dft_tpm_ownership_.get();
  DCHECK(trunks_factory_);
  DCHECK(tpm_ownership_);
}

ScopedTrunksFactory SealedStorage::CreateTrunksFactory() {
  auto factory = std::make_unique<trunks::TrunksFactoryImpl>();
  if (!factory->Initialize()) {
    LOG(ERROR) << "Failed to initialize TrunksFactory";
    factory.reset(nullptr);
  }
  return factory;
}

ScopedTpmOwnership SealedStorage::CreateTpmOwnershipInterface() {
  static scoped_refptr<dbus::Bus> bus;
  if (!bus) {
    dbus::Bus::Options options;
    options.bus_type = dbus::Bus::SYSTEM;
    bus = base::MakeRefCounted<dbus::Bus>(options);
    CHECK(bus->Connect()) << "Failed to connect to system D-Bus";
  }
  auto proxy = std::make_unique<org::chromium::TpmManagerProxy>(bus);
  return proxy;
}

std::optional<Data> SealedStorage::Seal(const SecretData& plain_data) const {
  if (!CheckInitialized()) {
    return std::nullopt;
  }

  PrivSeeds priv_seeds;
  PubSeeds pub_seeds;
  if (!CreateEncryptionSeeds(&priv_seeds, &pub_seeds)) {
    return std::nullopt;
  }
  pub_seeds.plain_size = plain_data.size();
  VLOG(2) << "Created encryption seeds";

  Key key;
  if (!key.Init(priv_seeds, pub_seeds)) {
    return std::nullopt;
  }
  VLOG(2) << "Created encryption key";

  auto encrypted_data = key.Encrypt(plain_data);
  if (!encrypted_data) {
    return std::nullopt;
  }
  VLOG(2) << "Encrypted data";

  return SerializeSealedBlob(pub_seeds, encrypted_data.value());
}

std::optional<SecretData> SealedStorage::Unseal(const Data& sealed_data) const {
  if (!CheckInitialized()) {
    return std::nullopt;
  }

  PubSeeds pub_seeds;
  Data encrypted_data;
  if (!DeserializeSealedBlob(sealed_data, &pub_seeds, &encrypted_data)) {
    return std::nullopt;
  }
  VLOG(2) << "Deserialized sealed blob";

  PrivSeeds priv_seeds;
  if (!RestoreEncryptionSeeds(pub_seeds, &priv_seeds)) {
    return std::nullopt;
  }
  VLOG(2) << "Restored encryption seeds";

  Key key;
  if (!key.Init(priv_seeds, pub_seeds)) {
    return std::nullopt;
  }
  VLOG(2) << "Created encryption key";

  return key.Decrypt(encrypted_data);
}

bool SealedStorage::ExtendPCR(uint32_t pcr_num) const {
  if (!CheckInitialized()) {
    return false;
  }
  auto tpm_utility = trunks_factory_->GetTpmUtility();

  return CheckTpmResult(
      tpm_utility->ExtendPCR(pcr_num, GetExtendValue(), nullptr), "extend PCR");
}

std::optional<bool> SealedStorage::CheckState() const {
  if (!CheckInitialized()) {
    return std::nullopt;
  }
  auto tpm_utility = trunks_factory_->GetTpmUtility();

  for (const auto& pcr_val : policy_.pcr_map) {
    if (pcr_val.second.empty()) {
      continue;
    }
    std::string value;
    auto result = tpm_utility->ReadPCR(pcr_val.first, &value);
    if (!CheckTpmResult(result, "read PCR")) {
      return std::nullopt;
    }
    if (value != pcr_val.second) {
      return false;
    }
  }

  return true;
}

bool SealedStorage::PrepareSealingKeyObject(
    const std::optional<std::string>& expected_digest,
    trunks::TPM_HANDLE* key_handle,
    std::string* key_name,
    std::string* resulting_digest) const {
  CHECK(key_handle);
  CHECK(key_name);

  std::string endorsement_password;
  if (!GetEndorsementPassword(&endorsement_password)) {
    return false;
  }
  VLOG(2) << "Obtained endorsement password";

  std::unique_ptr<trunks::PolicySession> trial_session =
      trunks_factory_->GetTrialSession();
  trunks::TPM_RC result = trial_session->StartUnboundSession(true, false);
  if (!CheckTpmResult(result, "start trial session")) {
    return false;
  }

  if (!policy_.pcr_map.empty()) {
    auto tpm_utility = trunks_factory_->GetTpmUtility();
    result = tpm_utility->AddPcrValuesToPolicySession(
        policy_.pcr_map, false /* use_auth_value */, trial_session.get());
    if (!CheckTpmResult(result, "calculate pcr policy")) {
      return false;
    }
  }

  if (!policy_.secret.empty()) {
    if (!AddSecretToSession(trial_session.get())) {
      return false;
    }
  }

  std::string policy_digest;
  result = trial_session->GetDigest(&policy_digest);
  if (!CheckTpmResult(result, "Get policy digest")) {
    return false;
  }

  VLOG(2) << "Created policy digest: " << HexDump(policy_digest);
  if (expected_digest.has_value() && expected_digest.value() != policy_digest) {
    VLOG(2) << "Expected policy digest: " << HexDump(expected_digest.value());
    LOG(ERROR) << "Policy mismatch";
    return false;
  }
  if (resulting_digest) {
    *resulting_digest = policy_digest;
  }

  trunks::TPMS_SENSITIVE_CREATE sensitive = {};
  memset(&sensitive, 0, sizeof(sensitive));
  sensitive.user_auth = trunks::Make_TPM2B_DIGEST("");
  sensitive.data = trunks::Make_TPM2B_SENSITIVE_DATA("");

  trunks::TPMT_PUBLIC public_area = {};
  memset(&public_area, 0, sizeof(public_area));
  public_area.type = trunks::TPM_ALG_ECC;
  public_area.name_alg = trunks::TPM_ALG_SHA256;
  public_area.auth_policy = trunks::Make_TPM2B_DIGEST(policy_digest);
  public_area.object_attributes =
      trunks::kFixedTPM | trunks::kFixedParent | trunks::kSensitiveDataOrigin |
      trunks::kAdminWithPolicy | trunks::kDecrypt | trunks::kNoDA;
  public_area.parameters.ecc_detail.symmetric.algorithm = trunks::TPM_ALG_NULL;
  public_area.parameters.ecc_detail.scheme.scheme = trunks::TPM_ALG_NULL;
  public_area.parameters.ecc_detail.curve_id = trunks::TPM_ECC_NIST_P256;
  public_area.parameters.ecc_detail.kdf.scheme = trunks::TPM_ALG_NULL;
  public_area.unique.ecc.x = trunks::Make_TPM2B_ECC_PARAMETER("");
  public_area.unique.ecc.y = trunks::Make_TPM2B_ECC_PARAMETER("");

  auto endorsement_auth =
      trunks_factory_->GetPasswordAuthorization(endorsement_password);
  std::string rh_endorsement_name;
  trunks::Serialize_TPM_HANDLE(trunks::TPM_RH_ENDORSEMENT,
                               &rh_endorsement_name);

  return CreatePrimaryKeyObject(
      "sealing key object", trunks::TPM_RH_ENDORSEMENT, rh_endorsement_name,
      sensitive, public_area, endorsement_auth.get(), key_handle, key_name);
}

bool SealedStorage::GetEndorsementPassword(std::string* password) const {
  CHECK(password);

  if (!tpm_ownership_) {
    LOG(ERROR) << "TpmOwnershipInterface is not initialized";
    return false;
  }

  tpm_manager::GetTpmStatusRequest request;
  tpm_manager::GetTpmStatusReply tpm_status;
  brillo::ErrorPtr error;
  if (!tpm_ownership_->GetTpmStatus(request, &tpm_status, &error,
                                    kDefaultTimeout.InMilliseconds())) {
    LOG(ERROR) << "Failed to call DefineSpace: " << error->GetMessage();
    return false;
  }
  if (tpm_status.status() != tpm_manager::STATUS_SUCCESS) {
    LOG(ERROR) << "Failed to get TpmStatus: " << tpm_status.status();
    return false;
  }
  *password = tpm_status.local_data().endorsement_password();
  return true;
}

bool SealedStorage::CreatePrimaryKeyObject(
    const std::string& object_descr,
    trunks::TPM_HANDLE parent_handle,
    const std::string& parent_name,
    const trunks::TPMS_SENSITIVE_CREATE& sensitive,
    const trunks::TPMT_PUBLIC& public_area,
    trunks::AuthorizationDelegate* auth_delegate,
    trunks::TPM_HANDLE* object_handle,
    std::string* object_name) const {
  DCHECK(object_handle);
  DCHECK(object_name);

  trunks::TPML_PCR_SELECTION creation_pcrs = {};
  trunks::TPM2B_PUBLIC out_public = {};
  trunks::TPM2B_CREATION_DATA out_creation_data = {};
  trunks::TPM2B_DIGEST out_creation_hash = {};
  trunks::TPMT_TK_CREATION out_creation_ticket = {};

  trunks::TPM2B_NAME out_name = {};
  auto result = trunks_factory_->GetTpm()->CreatePrimarySync(
      parent_handle, parent_name,
      trunks::Make_TPM2B_SENSITIVE_CREATE(sensitive),
      trunks::Make_TPM2B_PUBLIC(public_area),
      trunks::Make_TPM2B_DATA("") /* outside_info */, creation_pcrs,
      object_handle, &out_public, &out_creation_data, &out_creation_hash,
      &out_creation_ticket, &out_name, auth_delegate);
  if (!CheckTpmResult(result, std::string("create ") + object_descr)) {
    return false;
  }
  *object_name = trunks::StringFrom_TPM2B_NAME(out_name);
  VLOG(2) << "Created " << object_descr << ": " << *object_handle;

  return true;
}

bool SealedStorage::CheckInitialized() const {
  if (!trunks_factory_ || !trunks_factory_->GetTpm()) {
    LOG(ERROR) << "TrunksFactory is not initialized";
    return false;
  }
  return true;
}

bool SealedStorage::CreateEncryptionSeeds(PrivSeeds* priv_seeds,
                                          PubSeeds* pub_seeds) const {
  DCHECK(priv_seeds);
  DCHECK(pub_seeds);

  trunks::TPM_HANDLE key_handle;
  std::string key_name;
  std::string resulting_digest;
  if (!PrepareSealingKeyObject(std::nullopt, &key_handle, &key_name,
                               &resulting_digest)) {
    return false;
  }
  pub_seeds->policy_digest = std::move(resulting_digest);

  auto result = trunks_factory_->GetTpm()->ECDH_KeyGenSync(
      key_handle, key_name, &priv_seeds->z_point, &pub_seeds->pub_point,
      nullptr /* authorization_delegate */);
  if (!CheckTpmResult(result, "generate ECDH keypair")) {
    return false;
  }
  VLOG(2) << "Generated ECDH keypair";

  result = trunks_factory_->GetTpm()->GetRandomSync(
      Key::GetIVSize(), &pub_seeds->iv, nullptr /* authorization_delegate */);
  if (!CheckTpmResult(result, "generate IV")) {
    return false;
  }
  VLOG(2) << "Generated IV";

  return true;
}

bool SealedStorage::RestoreEncryptionSeeds(const PubSeeds& pub_seeds,
                                           PrivSeeds* priv_seeds) const {
  DCHECK(priv_seeds);

  trunks::TPM_HANDLE key_handle;
  std::string key_name;
  if (!PrepareSealingKeyObject(pub_seeds.policy_digest, &key_handle, &key_name,
                               nullptr)) {
    return false;
  }

  auto policy_session = trunks_factory_->GetPolicySession();
  auto result = policy_session->StartUnboundSession(true, false);
  if (!CheckTpmResult(result, "start policy session")) {
    return false;
  }

  if (!policy_.pcr_map.empty()) {
    result = policy_session->PolicyPCR(policy_.pcr_map);
    if (!CheckTpmResult(result, "restrict policy to PCRs")) {
      return false;
    }
  }

  if (!policy_.secret.empty()) {
    if (!AddSecretToSession(policy_session.get())) {
      return false;
    }
  }

  VLOG(2) << "Created policy session";

  result = trunks_factory_->GetTpm()->ECDH_ZGenSync(
      key_handle, key_name, pub_seeds.pub_point, &priv_seeds->z_point,
      policy_session->GetDelegate());
  if (!CheckTpmResult(result, "restore ECDH Z point")) {
    return false;
  }
  VLOG(2) << "Restored ECDH Z point";

  return true;
}

std::optional<Data> SealedStorage::SerializeSealedBlob(
    const PubSeeds& pub_seeds, const Data& encrypted_data) const {
  std::string serialized_data(1, kSerializedVer2);

  trunks::Serialize_uint16_t(pub_seeds.plain_size, &serialized_data);

  if (!pub_seeds.policy_digest.has_value()) {
    LOG(ERROR) << "Missing policy digest during serialization";
    return std::nullopt;
  }
  if (pub_seeds.policy_digest->size() != kPolicySize) {
    LOG(ERROR) << "Unexpected policy digest size during serialization: "
               << pub_seeds.policy_digest->size();
    return std::nullopt;
  }
  trunks::Serialize_uint16_t(pub_seeds.policy_digest->size(), &serialized_data);
  serialized_data.append(pub_seeds.policy_digest->begin(),
                         pub_seeds.policy_digest->end());

  if (trunks::Serialize_TPM2B_ECC_POINT(
          pub_seeds.pub_point, &serialized_data) != trunks::TPM_RC_SUCCESS) {
    LOG(ERROR) << "Failed to serialize public point";
    return std::nullopt;
  }
  if (trunks::Serialize_TPM2B_DIGEST(pub_seeds.iv, &serialized_data) !=
      trunks::TPM_RC_SUCCESS) {
    LOG(ERROR) << "Failed to serialize IV";
    return std::nullopt;
  }

  if (encrypted_data.size() > UINT16_MAX) {
    LOG(ERROR) << "Too long encrypted data: " << encrypted_data.size();
    return std::nullopt;
  }
  uint16_t size = encrypted_data.size();
  trunks::Serialize_uint16_t(size, &serialized_data);
  serialized_data.append(encrypted_data.begin(), encrypted_data.end());
  return Data(serialized_data.begin(), serialized_data.end());
}

bool SealedStorage::DeserializeSealedBlob(const Data& sealed_data,
                                          PubSeeds* pub_seeds,
                                          Data* encrypted_data) const {
  DCHECK(pub_seeds);
  DCHECK(encrypted_data);

  std::string serialized_data(sealed_data.begin(), sealed_data.end());
  if (serialized_data.empty()) {
    LOG(ERROR) << "Empty sealed data";
    return false;
  }

  uint8_t version = serialized_data[0];
  serialized_data.erase(0, 1);
  switch (version) {
    case kSerializedVer1:
      pub_seeds->plain_size = plain_size_for_v1_;
      pub_seeds->policy_digest.reset();
      break;
    case kSerializedVer2:
      if (trunks::Parse_uint16_t(&serialized_data, &pub_seeds->plain_size,
                                 nullptr /* value_bytes */) !=
          trunks::TPM_RC_SUCCESS) {
        LOG(ERROR) << "Failed to parse plain data size";
        return false;
      }
      pub_seeds->policy_digest = DeserializePolicyDigest(&serialized_data);
      if (!pub_seeds->policy_digest.has_value()) {
        LOG(ERROR) << "Failed to parse policy digest";
        return false;
      }
      break;
    default:
      LOG(ERROR) << "Unexpected serialized version: " << version;
      return false;
  }

  if (trunks::Parse_TPM2B_ECC_POINT(&serialized_data, &pub_seeds->pub_point,
                                    nullptr /* value_bytes */) !=
          trunks::TPM_RC_SUCCESS ||
      !pub_seeds->pub_point.size) {
    LOG(ERROR) << "Failed to parse public point";
    return false;
  }
  if (trunks::Parse_TPM2B_DIGEST(&serialized_data, &pub_seeds->iv,
                                 nullptr /* value_bytes */) !=
      trunks::TPM_RC_SUCCESS) {
    LOG(ERROR) << "Failed to parse IV";
    return false;
  }

  uint16_t size;
  if (trunks::Parse_uint16_t(&serialized_data, &size,
                             nullptr /* value_bytes */) !=
      trunks::TPM_RC_SUCCESS) {
    LOG(ERROR) << "Failed to parse encrypted data size";
    return false;
  }
  if (serialized_data.size() != size) {
    LOG(ERROR) << "Unexpected encrypted data size: " << serialized_data.size()
               << " != " << size;
    return false;
  }
  encrypted_data->assign(serialized_data.begin(), serialized_data.end());
  return true;
}

bool Key::Init(const PrivSeeds& priv_seeds, const PubSeeds& pub_seeds) {
  if (pub_seeds.iv.size != GetIVSize()) {
    LOG(ERROR) << "Unexpected input IV size: " << pub_seeds.iv.size;
    return false;
  }
  iv_.assign(pub_seeds.iv.buffer, pub_seeds.iv.buffer + pub_seeds.iv.size);
  if (iv_.size() != GetIVSize()) {
    LOG(ERROR) << "Unexpected IV size: " << iv_.size();
    return false;
  }
  key_ = GetKeyFromZ(priv_seeds.z_point);
  if (key_.size() != GetKeySize()) {
    LOG(ERROR) << "Unexpected key size: " << key_.size();
    return false;
  }
  expected_size_ = pub_seeds.plain_size;
  return true;
}

std::optional<Data> Key::Encrypt(const SecretData& plain_data) const {
  if (plain_data.size() != expected_size_) {
    LOG(ERROR) << "Unexpected plain data size: " << plain_data.size()
               << " != " << expected_size_;
    return std::nullopt;
  }

  crypto::ScopedEVP_CIPHER_CTX ctx(EVP_CIPHER_CTX_new());
  if (!ctx) {
    ReportOpenSSLError("allocate encryption context");
    return std::nullopt;
  }
  if (!EVP_EncryptInit_ex(ctx.get(), GetCipher(), nullptr, key_.data(),
                          iv_.data())) {
    ReportOpenSSLError("initialize encryption context");
    return std::nullopt;
  }

  const size_t max_encrypted_size = plain_data.size() + GetBlockSize();
  Data encrypted_data(max_encrypted_size);
  int encrypted_size;
  if (!EVP_EncryptUpdate(
          ctx.get(), static_cast<unsigned char*>(encrypted_data.data()),
          &encrypted_size, plain_data.data(), plain_data.size())) {
    ReportOpenSSLError("encrypt");
    return std::nullopt;
  }
  if (encrypted_size < 0 || encrypted_size > max_encrypted_size) {
    LOG(ERROR) << "Unexpected encrypted data size: " << encrypted_size << " > "
               << max_encrypted_size;
    return std::nullopt;
  }

  unsigned char* final_buf = nullptr;
  if (encrypted_size < max_encrypted_size) {
    final_buf =
        static_cast<unsigned char*>(encrypted_data.data() + encrypted_size);
  }
  int encrypted_size_final = 0;
  if (!EVP_EncryptFinal_ex(ctx.get(), final_buf, &encrypted_size_final)) {
    ReportOpenSSLError("finalize encryption");
    return std::nullopt;
  }
  if (encrypted_size_final < 0) {
    LOG(ERROR) << "Unexpected size for final encryption block: "
               << encrypted_size_final;
    return std::nullopt;
  }
  encrypted_size += encrypted_size_final;
  if (encrypted_size > max_encrypted_size) {
    LOG(ERROR) << "Unexpected encrypted data size after finalization: "
               << encrypted_size << " > " << max_encrypted_size;
    return std::nullopt;
  }
  encrypted_data.resize(encrypted_size);

  return encrypted_data;
}

std::optional<SecretData> Key::Decrypt(const Data& encrypted_data) const {
  crypto::ScopedEVP_CIPHER_CTX ctx(EVP_CIPHER_CTX_new());
  if (!ctx) {
    ReportOpenSSLError("allocate decryption context");
    return std::nullopt;
  }

  if (!EVP_DecryptInit_ex(ctx.get(), GetCipher(), nullptr, key_.data(),
                          iv_.data())) {
    ReportOpenSSLError("initialize decryption context");
    return std::nullopt;
  }

  const size_t max_decrypted_size = encrypted_data.size() + GetBlockSize();
  if (max_decrypted_size < expected_size_) {
    LOG(ERROR) << "Not enough data for expected size: " << encrypted_data.size()
               << " leads to max " << max_decrypted_size << " < "
               << expected_size_;
    return std::nullopt;
  }
  SecretData decrypted_data(max_decrypted_size);
  int decrypted_size;
  if (!EVP_DecryptUpdate(
          ctx.get(), static_cast<unsigned char*>(decrypted_data.data()),
          &decrypted_size, encrypted_data.data(), encrypted_data.size())) {
    ReportOpenSSLError("decrypt");
    return std::nullopt;
  }
  if (decrypted_size < 0 || decrypted_size > max_decrypted_size) {
    LOG(ERROR) << "Unexpected decrypted data size: " << decrypted_size << " > "
               << max_decrypted_size;
    return std::nullopt;
  }

  unsigned char* final_buf = nullptr;
  if (decrypted_size < max_decrypted_size) {
    final_buf =
        static_cast<unsigned char*>(decrypted_data.data() + decrypted_size);
  }
  int decrypted_size_final = 0;
  if (!EVP_DecryptFinal_ex(ctx.get(), final_buf, &decrypted_size_final)) {
    ReportOpenSSLError("finalize decryption");
    return std::nullopt;
  }
  if (decrypted_size_final < 0) {
    LOG(ERROR) << "Unexpected size for final decryption block: "
               << decrypted_size_final;
    return std::nullopt;
  }
  decrypted_size += decrypted_size_final;
  if (decrypted_size != expected_size_) {
    LOG(ERROR) << "Unexpected decrypted data size: " << decrypted_size
               << " != " << expected_size_;
    return std::nullopt;
  }
  decrypted_data.resize(decrypted_size);

  return decrypted_data;
}

bool SealedStorage::AddSecretToSession(trunks::PolicySession* session) const {
  DCHECK(!policy_.secret.empty());
  DCHECK(session);

  std::string policy_digest;
  trunks::TPM_RC result = session->GetDigest(&policy_digest);
  if (!CheckTpmResult(result, "Get policy digest")) {
    return false;
  }

  result = session->PolicyOR({policy_digest, policy_.secret.to_string()});
  if (!CheckTpmResult(result, "create policy with secret included in digest")) {
    return false;
  }
  return true;
}

}  // namespace sealed_storage
