// 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 <string>
#include <utility>

#include <base/bind.h>
#include <base/bind_helpers.h>
#include <base/hash/sha1.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 <tpm_manager/client/tpm_ownership_dbus_proxy.h>
#include <trunks/error_codes.h>
#include <trunks/trunks_factory_impl.h>

#include "sealed_storage/sealed_storage.h"

namespace {

// 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 an 'empty policy' digest for the case when no PCR bindings are specified.
std::string GetEmptyPolicy() {
  return std::string(kPolicySize, 0);
}

// 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 knwon 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;
}

// Sends a request to the tpm_managerd, waits for a response (or an error)
// and fills it into the provides reply protobuf (only the error fields in
// case of error).
template <typename MethodType, typename ReplyProtoType>
void SendRequestAndWait(const MethodType& method, ReplyProtoType* reply_proto) {
  auto handler = [](ReplyProtoType* target, base::RunLoop* loop,
                    const ReplyProtoType& reply) {
    *target = reply;
    loop->Quit();
  };

  base::RunLoop loop;
  auto callback = base::Bind(handler, reply_proto, &loop);
  method.Run(callback);
  loop.Run();
}

// 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 base::nullopt in case of error.
base::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 base::nullopt;
  }
  if (serialized_data->size() < size) {
    LOG(ERROR) << "Policy digest longer than the remaining sealed data: "
                << serialized_data->size() << " < " << size;
    return base::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 base::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.
  base::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.
  base::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,
                             tpm_manager::TpmOwnershipInterface* 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() {
  auto proxy = std::make_unique<tpm_manager::TpmOwnershipDBusProxy>();
  if (!proxy->Initialize()) {
    LOG(ERROR) << "Failed to initialize TpmOwnershipDBusProxy";
    proxy.reset(nullptr);
  }
  return proxy;
}

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

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

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

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

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

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

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

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

  Key key;
  if (!key.Init(priv_seeds, pub_seeds)) {
    return base::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");
}

base::Optional<bool> SealedStorage::CheckState() const {
  if (!CheckInitialized()) {
    return base::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 base::nullopt;
    }
    if (value != pcr_val.second) {
      return false;
    }
  }

  return true;
}

bool SealedStorage::PrepareSealingKeyObject(
    const base::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::string policy_digest;
  if (!policy_.pcr_map.empty()) {
    auto tpm_utility = trunks_factory_->GetTpmUtility();
    auto result = tpm_utility->GetPolicyDigestForPcrValues(
        policy_.pcr_map, false /* use_auth_value */, &policy_digest);
    if (!CheckTpmResult(result, "calculate policy")) {
      return false;
    }
  } else {
    policy_digest = GetEmptyPolicy();
  }
  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;
  auto method = base::Bind(&tpm_manager::TpmOwnershipInterface::GetTpmStatus,
                           base::Unretained(tpm_ownership_), request);
  tpm_manager::GetTpmStatusReply tpm_status;
  SendRequestAndWait(method, &tpm_status);
  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(base::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;
    }
  }
  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;
}

base::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 base::nullopt;
  }
  if (pub_seeds.policy_digest->size() != kPolicySize) {
    LOG(ERROR) << "Unexpected policy digest size during serialization: "
               << pub_seeds.policy_digest->size();
    return base::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 base::nullopt;
  }
  if (trunks::Serialize_TPM2B_DIGEST(pub_seeds.iv, &serialized_data) !=
      trunks::TPM_RC_SUCCESS) {
    LOG(ERROR) << "Failed to serialize IV";
    return base::nullopt;
  }

  if (encrypted_data.size() > UINT16_MAX) {
    LOG(ERROR) << "Too long encrypted data: " << encrypted_data.size();
    return base::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) {
    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;
}

base::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 base::nullopt;
  }

  crypto::ScopedEVP_CIPHER_CTX ctx(EVP_CIPHER_CTX_new());
  if (!ctx) {
    ReportOpenSSLError("allocate encryption context");
    return base::nullopt;
  }
  if (!EVP_EncryptInit_ex(ctx.get(), GetCipher(), nullptr, key_.data(),
                          iv_.data())) {
    ReportOpenSSLError("initialize encryption context");
    return base::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 base::nullopt;
  }
  if (encrypted_size < 0 || encrypted_size > max_encrypted_size) {
    LOG(ERROR) << "Unexpected encrypted data size: " << encrypted_size << " > "
               << max_encrypted_size;
    return base::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 base::nullopt;
  }
  if (encrypted_size_final < 0) {
    LOG(ERROR) << "Unexpected size for final encryption block: "
               << encrypted_size_final;
    return base::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 base::nullopt;
  }
  encrypted_data.resize(encrypted_size);

  return encrypted_data;
}

base::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 base::nullopt;
  }

  if (!EVP_DecryptInit_ex(ctx.get(), GetCipher(), nullptr, key_.data(),
                          iv_.data())) {
    ReportOpenSSLError("initialize decryption context");
    return base::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 base::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 base::nullopt;
  }
  if (decrypted_size < 0 || decrypted_size > max_decrypted_size) {
    LOG(ERROR) << "Unexpected decrypted data size: " << decrypted_size << " > "
               << max_decrypted_size;
    return base::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 base::nullopt;
  }
  if (decrypted_size_final < 0) {
    LOG(ERROR) << "Unexpected size for final decryption block: "
               << decrypted_size_final;
    return base::nullopt;
  }
  decrypted_size += decrypted_size_final;
  if (decrypted_size != expected_size_) {
    LOG(ERROR) << "Unexpected decrypted data size: "
               << decrypted_size << " != " << expected_size_;
    return base::nullopt;
  }
  decrypted_data.resize(decrypted_size);

  return decrypted_data;
}

}  // namespace sealed_storage
