// 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/cryptorecovery/fake_recovery_mediator_crypto.h"

#include <algorithm>
#include <optional>
#include <utility>
#include <vector>

#include <base/logging.h>
#include <base/memory/ptr_util.h>
#include <base/stl_util.h>
#include <brillo/secure_blob.h>
#include <libhwsec-foundation/crypto/aes.h>
#include <libhwsec-foundation/crypto/big_num_util.h>
#include <libhwsec-foundation/crypto/ecdh_hkdf.h>
#include <libhwsec-foundation/crypto/elliptic_curve.h>
#include <libhwsec-foundation/crypto/error_util.h>
#include <libhwsec-foundation/crypto/rsa.h>
#include <libhwsec-foundation/crypto/secure_blob_util.h>

#include "cryptohome/cryptohome_common.h"
#include "cryptohome/cryptorecovery/recovery_crypto.h"
#include "cryptohome/cryptorecovery/recovery_crypto_hsm_cbor_serialization.h"
#include "cryptohome/cryptorecovery/recovery_crypto_util.h"

using ::hwsec_foundation::AesGcmDecrypt;
using ::hwsec_foundation::AesGcmEncrypt;
using ::hwsec_foundation::CreateBigNumContext;
using ::hwsec_foundation::CreateSecureRandomBlob;
using ::hwsec_foundation::EllipticCurve;
using ::hwsec_foundation::GenerateEcdhHkdfSymmetricKey;
using ::hwsec_foundation::kAesGcm256KeySize;
using ::hwsec_foundation::ScopedBN_CTX;
using ::hwsec_foundation::SecureBlobToBigNum;
using ::hwsec_foundation::VerifyRsaSignatureSha256;

namespace cryptohome {
namespace cryptorecovery {
namespace {

brillo::SecureBlob GetMediatorShareHkdfInfo() {
  return brillo::SecureBlob(RecoveryCrypto::kMediatorShareHkdfInfoValue);
}

brillo::SecureBlob GetRequestPayloadPlainTextHkdfInfo() {
  return brillo::SecureBlob(
      RecoveryCrypto::kRequestPayloadPlainTextHkdfInfoValue);
}

brillo::SecureBlob GetResponsePayloadPlainTextHkdfInfo() {
  return brillo::SecureBlob(
      RecoveryCrypto::kResponsePayloadPlainTextHkdfInfoValue);
}

bool GetRecoveryRequestFromProto(
    const CryptoRecoveryRpcRequest& recovery_request_proto,
    RecoveryRequest* recovery_request) {
  if (!recovery_request_proto.has_cbor_cryptorecoveryrequest()) {
    LOG(ERROR)
        << "No cbor_cryptorecoveryrequest field in recovery_request_proto";
    return false;
  }
  brillo::SecureBlob recovery_request_cbor(
      recovery_request_proto.cbor_cryptorecoveryrequest().begin(),
      recovery_request_proto.cbor_cryptorecoveryrequest().end());
  if (!DeserializeRecoveryRequestFromCbor(recovery_request_cbor,
                                          recovery_request)) {
    LOG(ERROR) << "Unable to deserialize Recovery Request";
    return false;
  }
  return true;
}

bool GenerateRecoveryRequestProto(
    const RecoveryResponse& response,
    CryptoRecoveryRpcResponse* recovery_response) {
  brillo::SecureBlob recovery_response_cbor;
  if (!SerializeRecoveryResponseToCbor(response, &recovery_response_cbor)) {
    LOG(ERROR) << "Failed to serialize Recovery Response to cbor";
    return false;
  }
  recovery_response->set_protocol_version(1);
  recovery_response->set_cbor_cryptorecoveryresponse(
      recovery_response_cbor.data(), recovery_response_cbor.size());
  return true;
}

}  // namespace

// Hardcoded fake mediator and epoch public and private keys. Do not use them in
// production! Keys were generated at random using
// EllipticCurve::GenerateKeysAsSecureBlobs method and converted to hex.
static const char kFakeMediatorPublicKeyHex[] =
    "041C66FD08151D1C34EA5003F7C24557D2E4802535AA4F65EDBE3CD495CFE060387D00D5D2"
    "5D859B26C5134F1AD00F2230EAB72A47F46DF23407CF68FB18C509DE";
static const char kFakeMediatorPrivateKeyHex[] =
    "B7A01DA624ECF448D9F7E1B07236EA2930A17C9A31AD60E43E01A8FEA934AB1C";
static const char kFakeEpochPrivateKeyHex[] =
    "2DC064DBE7473CE2E617C689E3D1D71568E1B09EA6CEC5CB4463A66C06F1B535";
static const char kFakeEpochPublicKeyHex[] =
    "045D8393CDEF671228CB0D8454BBB6F2AAA18E05834BB6DBBD05721FC81ED3BED33D08A8EF"
    "D44F6786CAE7ADEB8E26A355CD9714F59C78F063A3CA3A7D74877A8A";

std::unique_ptr<FakeRecoveryMediatorCrypto>
FakeRecoveryMediatorCrypto::Create() {
  ScopedBN_CTX context = CreateBigNumContext();
  if (!context.get()) {
    LOG(ERROR) << "Failed to allocate BN_CTX structure";
    return nullptr;
  }
  std::optional<EllipticCurve> ec =
      EllipticCurve::Create(RecoveryCrypto::kCurve, context.get());
  if (!ec) {
    LOG(ERROR) << "Failed to create EllipticCurve";
    return nullptr;
  }
  return base::WrapUnique(new FakeRecoveryMediatorCrypto(std::move(*ec)));
}

FakeRecoveryMediatorCrypto::FakeRecoveryMediatorCrypto(EllipticCurve ec)
    : ec_(std::move(ec)) {}

// static
bool FakeRecoveryMediatorCrypto::GetFakeMediatorPublicKey(
    brillo::SecureBlob* mediator_pub_key) {
  if (!brillo::SecureBlob::HexStringToSecureBlob(kFakeMediatorPublicKeyHex,
                                                 mediator_pub_key)) {
    LOG(ERROR) << "Failed to convert hex to SecureBlob";
    return false;
  }
  return true;
}

// static
bool FakeRecoveryMediatorCrypto::GetFakeMediatorPrivateKey(
    brillo::SecureBlob* mediator_priv_key) {
  if (!brillo::SecureBlob::HexStringToSecureBlob(kFakeMediatorPrivateKeyHex,
                                                 mediator_priv_key)) {
    LOG(ERROR) << "Failed to convert hex to SecureBlob";
    return false;
  }
  return true;
}

// static
bool FakeRecoveryMediatorCrypto::GetFakeEpochPublicKey(
    brillo::SecureBlob* epoch_pub_key) {
  if (!brillo::SecureBlob::HexStringToSecureBlob(kFakeEpochPublicKeyHex,
                                                 epoch_pub_key)) {
    LOG(ERROR) << "Failed to convert hex to SecureBlob";
    return false;
  }
  return true;
}

// static
bool FakeRecoveryMediatorCrypto::GetFakeEpochPrivateKey(
    brillo::SecureBlob* epoch_priv_key) {
  if (!brillo::SecureBlob::HexStringToSecureBlob(kFakeEpochPrivateKeyHex,
                                                 epoch_priv_key)) {
    LOG(ERROR) << "Failed to convert hex to SecureBlob";
    return false;
  }
  return true;
}

// static
bool FakeRecoveryMediatorCrypto::GetFakeEpochResponse(
    CryptoRecoveryEpochResponse* epoch_response) {
  brillo::SecureBlob epoch_pub_key;
  if (!GetFakeEpochPublicKey(&epoch_pub_key)) {
    LOG(ERROR) << "Failed to get fake epoch public key";
    return false;
  }
  brillo::SecureBlob epoch_metadata_cbor;
  cbor::Value::MapValue meta_data_cbor;
  meta_data_cbor.emplace("meta_data_cbor_key", "meta_data_cbor_value");
  if (!SerializeCborForTesting(cbor::Value(meta_data_cbor),
                               &epoch_metadata_cbor)) {
    LOG(ERROR) << "Failed to create epoch_metadata_cbor";
    return false;
  }
  epoch_response->set_protocol_version(1);
  epoch_response->set_epoch_pub_key(epoch_pub_key.data(), epoch_pub_key.size());
  epoch_response->set_epoch_meta_data(epoch_metadata_cbor.data(),
                                      epoch_metadata_cbor.size());
  return true;
}

bool FakeRecoveryMediatorCrypto::DecryptMediatorShare(
    const brillo::SecureBlob& mediator_priv_key,
    const RecoveryCrypto::EncryptedMediatorShare& encrypted_mediator_share,
    brillo::SecureBlob* mediator_share) const {
  ScopedBN_CTX context = CreateBigNumContext();
  if (!context.get()) {
    LOG(ERROR) << "Failed to allocate BN_CTX structure";
    return false;
  }

  crypto::ScopedBIGNUM mediator_priv_key_bn =
      SecureBlobToBigNum(mediator_priv_key);
  if (!mediator_priv_key_bn) {
    LOG(ERROR) << "Failed to convert mediator_priv_key to BIGNUM";
    return false;
  }
  crypto::ScopedEC_POINT ephemeral_pub_key = ec_.SecureBlobToPoint(
      encrypted_mediator_share.ephemeral_pub_key, context.get());
  if (!ephemeral_pub_key) {
    LOG(ERROR) << "Failed to convert ephemeral_pub_key SecureBlob to EC_POINT";
    return false;
  }
  crypto::ScopedEC_POINT shared_secret_point = ComputeEcdhSharedSecretPoint(
      ec_, *ephemeral_pub_key, *mediator_priv_key_bn);
  if (!shared_secret_point) {
    LOG(ERROR) << "Failed to compute shared_secret_point";
    return false;
  }
  brillo::SecureBlob aes_gcm_key;
  if (!GenerateEcdhHkdfSymmetricKey(
          ec_, *shared_secret_point, encrypted_mediator_share.ephemeral_pub_key,
          GetMediatorShareHkdfInfo(),
          /*hkdf_salt=*/brillo::SecureBlob(), RecoveryCrypto::kHkdfHash,
          kAesGcm256KeySize, &aes_gcm_key)) {
    LOG(ERROR) << "Failed to generate ECDH+HKDF recipient key for mediator "
                  "share decryption";
    return false;
  }

  if (!AesGcmDecrypt(encrypted_mediator_share.encrypted_data,
                     /*ad=*/std::nullopt, encrypted_mediator_share.tag,
                     aes_gcm_key, encrypted_mediator_share.iv,
                     mediator_share)) {
    LOG(ERROR) << "Failed to perform AES-GCM decryption";
    return false;
  }

  return true;
}

bool FakeRecoveryMediatorCrypto::DecryptHsmPayloadPlainText(
    const brillo::SecureBlob& mediator_priv_key,
    const HsmPayload& hsm_payload,
    brillo::SecureBlob* plain_text) const {
  ScopedBN_CTX context = CreateBigNumContext();
  if (!context.get()) {
    LOG(ERROR) << "Failed to allocate BN_CTX structure";
    return false;
  }

  brillo::SecureBlob publisher_pub_key_blob;
  if (!GetBytestringValueFromCborMapByKeyForTesting(hsm_payload.associated_data,
                                                    kPublisherPublicKey,
                                                    &publisher_pub_key_blob)) {
    LOG(ERROR) << "Unable to deserialize publisher_pub_key from hsm_payload";
    return false;
  }
  crypto::ScopedBIGNUM mediator_priv_key_bn =
      SecureBlobToBigNum(mediator_priv_key);
  if (!mediator_priv_key_bn) {
    LOG(ERROR) << "Failed to convert mediator_priv_key to BIGNUM";
    return false;
  }
  crypto::ScopedEC_POINT publisher_pub_key =
      ec_.SecureBlobToPoint(publisher_pub_key_blob, context.get());
  if (!publisher_pub_key) {
    LOG(ERROR) << "Failed to convert publisher_pub_key_blob to EC_POINT";
    return false;
  }
  crypto::ScopedEC_POINT shared_secret_point = ComputeEcdhSharedSecretPoint(
      ec_, *publisher_pub_key, *mediator_priv_key_bn);
  if (!shared_secret_point) {
    LOG(ERROR) << "Failed to compute shared_secret_point";
    return false;
  }
  brillo::SecureBlob aes_gcm_key;
  if (!GenerateEcdhHkdfSymmetricKey(
          ec_, *shared_secret_point, publisher_pub_key_blob,
          GetMediatorShareHkdfInfo(),
          /*hkdf_salt=*/brillo::SecureBlob(), RecoveryCrypto::kHkdfHash,
          kAesGcm256KeySize, &aes_gcm_key)) {
    LOG(ERROR) << "Failed to generate ECDH+HKDF recipient key for HSM "
                  "plaintext decryption";
    return false;
  }

  if (!AesGcmDecrypt(hsm_payload.cipher_text, hsm_payload.associated_data,
                     hsm_payload.tag, aes_gcm_key, hsm_payload.iv,
                     plain_text)) {
    LOG(ERROR) << "Failed to perform AES-GCM decryption";
    return false;
  }

  return true;
}

bool FakeRecoveryMediatorCrypto::DecryptRequestPayloadPlainText(
    const brillo::SecureBlob& epoch_priv_key,
    const RequestPayload& request_payload,
    brillo::SecureBlob* plain_text) const {
  ScopedBN_CTX context = CreateBigNumContext();
  if (!context.get()) {
    LOG(ERROR) << "Failed to allocate BN_CTX structure";
    return false;
  }

  brillo::SecureBlob salt;
  if (!GetBytestringValueFromCborMapByKeyForTesting(
          request_payload.associated_data, kRequestPayloadSalt, &salt)) {
    LOG(ERROR) << "Unable to deserialize salt from request_payload";
    return false;
  }
  HsmPayload hsm_payload;
  if (!GetHsmPayloadFromRequestAdForTesting(request_payload.associated_data,
                                            &hsm_payload)) {
    LOG(ERROR) << "Unable to deserialize hsm_payload from request_payload";
    return false;
  }
  brillo::SecureBlob channel_pub_key_blob;
  if (!GetBytestringValueFromCborMapByKeyForTesting(hsm_payload.associated_data,
                                                    kChannelPublicKey,
                                                    &channel_pub_key_blob)) {
    LOG(ERROR) << "Unable to deserialize channel_pub_key from "
                  "hsm_payload.associated_data";
    return false;
  }

  crypto::ScopedBIGNUM epoch_priv_key_bn = SecureBlobToBigNum(epoch_priv_key);
  if (!epoch_priv_key_bn) {
    LOG(ERROR) << "Failed to convert epoch_priv_key to BIGNUM";
    return false;
  }
  crypto::ScopedEC_POINT channel_pub_key =
      ec_.SecureBlobToPoint(channel_pub_key_blob, context.get());
  if (!channel_pub_key) {
    LOG(ERROR) << "Failed to convert channel_pub_key_blob to EC_POINT";
    return false;
  }
  crypto::ScopedEC_POINT shared_secret_point =
      ComputeEcdhSharedSecretPoint(ec_, *channel_pub_key, *epoch_priv_key_bn);
  if (!shared_secret_point) {
    LOG(ERROR) << "Failed to compute shared_secret_point";
    return false;
  }
  brillo::SecureBlob aes_gcm_key;
  if (!GenerateEcdhHkdfSymmetricKey(
          ec_, *shared_secret_point, channel_pub_key_blob,
          GetRequestPayloadPlainTextHkdfInfo(), salt, RecoveryCrypto::kHkdfHash,
          kAesGcm256KeySize, &aes_gcm_key)) {
    LOG(ERROR) << "Failed to generate ECDH+HKDF recipient key for request "
                  "payload decryption";
    return false;
  }

  if (!AesGcmDecrypt(request_payload.cipher_text,
                     request_payload.associated_data, request_payload.tag,
                     aes_gcm_key, request_payload.iv, plain_text)) {
    LOG(ERROR) << "Failed to perform AES-GCM decryption of request_payload";
    return false;
  }

  return true;
}

bool FakeRecoveryMediatorCrypto::MediateHsmPayload(
    const brillo::SecureBlob& mediator_priv_key,
    const brillo::SecureBlob& epoch_pub_key,
    const brillo::SecureBlob& epoch_priv_key,
    const brillo::SecureBlob& ephemeral_pub_inv_key,
    const HsmPayload& hsm_payload,
    CryptoRecoveryRpcResponse* recovery_response_proto) const {
  ScopedBN_CTX context = CreateBigNumContext();
  if (!context.get()) {
    LOG(ERROR) << "Failed to allocate BN_CTX structure";
    return false;
  }

  brillo::SecureBlob hsm_plain_text_cbor;
  if (!DecryptHsmPayloadPlainText(mediator_priv_key, hsm_payload,
                                  &hsm_plain_text_cbor)) {
    LOG(ERROR) << "Unable to decrypt hsm_plain_text_cbor in hsm_payload";
    return false;
  }

  HsmPlainText hsm_plain_text;
  if (!DeserializeHsmPlainTextFromCbor(hsm_plain_text_cbor, &hsm_plain_text)) {
    LOG(ERROR) << "Unable to deserialize hsm_plain_text_cbor";
    return false;
  }

  crypto::ScopedBIGNUM mediator_share_bn =
      SecureBlobToBigNum(hsm_plain_text.mediator_share);
  if (!mediator_share_bn) {
    LOG(ERROR) << "Failed to convert SecureBlob to BIGNUM";
    return false;
  }
  crypto::ScopedEC_POINT dealer_pub_point =
      ec_.SecureBlobToPoint(hsm_plain_text.dealer_pub_key, context.get());
  if (!dealer_pub_point) {
    LOG(ERROR) << "Failed to convert SecureBlob to EC_POINT";
    return false;
  }
  // Performs scalar multiplication of dealer_pub_key and mediator_share.
  brillo::SecureBlob mediator_dh;
  crypto::ScopedEC_POINT mediator_dh_point =
      ec_.Multiply(*dealer_pub_point, *mediator_share_bn, context.get());
  if (!mediator_dh_point) {
    LOG(ERROR) << "Failed to perform scalar multiplication";
    return false;
  }
  // Perform addition of mediator_dh_point and ephemeral_pub_inv_key.
  crypto::ScopedEC_POINT ephemeral_pub_inv_point =
      ec_.SecureBlobToPoint(ephemeral_pub_inv_key, context.get());
  if (!ephemeral_pub_inv_point) {
    LOG(ERROR) << "Failed to convert SecureBlob to EC_POINT";
    return false;
  }
  crypto::ScopedEC_POINT mediated_point =
      ec_.Add(*mediator_dh_point, *ephemeral_pub_inv_point, context.get());
  if (!mediated_point) {
    LOG(ERROR) << "Failed to add mediator_dh_point and ephemeral_pub_inv_point";
    return false;
  }
  if (!ec_.PointToSecureBlob(*mediated_point, &mediator_dh, context.get())) {
    LOG(ERROR) << "Failed to convert EC_POINT to SecureBlob";
    return false;
  }

  brillo::SecureBlob salt =
      CreateSecureRandomBlob(RecoveryCrypto::kHkdfSaltLength);
  ResponsePayload response_payload;
  HsmResponseAssociatedData response_ad;
  response_ad.response_payload_salt = salt;
  if (!SerializeHsmResponseAssociatedDataToCbor(
          response_ad, &response_payload.associated_data)) {
    LOG(ERROR) << "Unable to serialize response payload associated data";
    return false;
  }

  brillo::SecureBlob response_plain_text_cbor;
  HsmResponsePlainText response_plain_text;
  response_plain_text.mediated_point = mediator_dh;
  response_plain_text.dealer_pub_key = hsm_plain_text.dealer_pub_key;
  response_plain_text.key_auth_value = hsm_plain_text.key_auth_value;
  if (!SerializeHsmResponsePlainTextToCbor(response_plain_text,
                                           &response_plain_text_cbor)) {
    LOG(ERROR) << "Unable to serialize response plain text";
    return false;
  }

  brillo::SecureBlob channel_pub_key_blob;
  if (!GetBytestringValueFromCborMapByKeyForTesting(hsm_payload.associated_data,
                                                    kChannelPublicKey,
                                                    &channel_pub_key_blob)) {
    LOG(ERROR) << "Unable to deserialize channel_pub_key from hsm_payload";
    return false;
  }

  crypto::ScopedBIGNUM epoch_priv_key_bn = SecureBlobToBigNum(epoch_priv_key);
  if (!epoch_priv_key_bn) {
    LOG(ERROR) << "Failed to convert epoch_priv_key to BIGNUM";
    return false;
  }
  crypto::ScopedEC_POINT channel_pub_key =
      ec_.SecureBlobToPoint(channel_pub_key_blob, context.get());
  if (!channel_pub_key) {
    LOG(ERROR) << "Failed to convert channel_pub_key_blob to EC_POINT";
    return false;
  }
  crypto::ScopedEC_POINT shared_secret_point =
      ComputeEcdhSharedSecretPoint(ec_, *channel_pub_key, *epoch_priv_key_bn);
  if (!shared_secret_point) {
    LOG(ERROR) << "Failed to compute shared_secret_point";
    return false;
  }
  brillo::SecureBlob aes_gcm_key;
  // The static nature of `channel_pub_key` (G*s) and `epoch_pub_key` (G*r)
  // requires the need to utilize a randomized salt value in the HKDF
  // computation.
  if (!GenerateEcdhHkdfSymmetricKey(ec_, *shared_secret_point, epoch_pub_key,
                                    GetResponsePayloadPlainTextHkdfInfo(), salt,
                                    RecoveryCrypto::kHkdfHash,
                                    kAesGcm256KeySize, &aes_gcm_key)) {
    LOG(ERROR)
        << "Failed to generate ECDH+HKDF recipient key for Recovery Request "
           "plaintext encryption";
    return false;
  }

  if (!AesGcmEncrypt(response_plain_text_cbor, response_payload.associated_data,
                     aes_gcm_key, &response_payload.iv, &response_payload.tag,
                     &response_payload.cipher_text)) {
    LOG(ERROR) << "Failed to perform AES-GCM encryption of response_payload";
    return false;
  }

  RecoveryResponse recovery_response;
  recovery_response.response_payload = std::move(response_payload);
  recovery_response.error_code = 0;
  if (!GenerateRecoveryRequestProto(recovery_response,
                                    recovery_response_proto)) {
    LOG(ERROR) << "Failed to generate Recovery Response proto";
    return false;
  }
  return true;
}

bool FakeRecoveryMediatorCrypto::MediateRequestPayload(
    const brillo::SecureBlob& epoch_pub_key,
    const brillo::SecureBlob& epoch_priv_key,
    const brillo::SecureBlob& mediator_priv_key,
    const CryptoRecoveryRpcRequest& recovery_request_proto,
    CryptoRecoveryRpcResponse* recovery_response_proto) const {
  ScopedBN_CTX context = CreateBigNumContext();
  if (!context.get()) {
    LOG(ERROR) << "Failed to allocate BN_CTX structure";
    return false;
  }
  // Parse out the rsa_signature in Recovery Request
  RecoveryRequest recovery_request;
  if (!GetRecoveryRequestFromProto(recovery_request_proto, &recovery_request)) {
    LOG(ERROR) << "Couldn't get recovery request from recovery_request_proto";
    return false;
  }
  // Parse out the rsa_public_key, which is in Hsm Associated Data. Hsm
  // Associated Data is in Hsm Payload, and it is in the Associated Data of
  // Request Payload
  RequestPayload request_payload;
  if (!DeserializeRecoveryRequestPayloadFromCbor(
          recovery_request.request_payload, &request_payload)) {
    LOG(ERROR) << "Failed to deserialize Request payload.";
    return false;
  }
  HsmPayload hsm_payload;
  if (!GetHsmPayloadFromRequestAdForTesting(request_payload.associated_data,
                                            &hsm_payload)) {
    LOG(ERROR) << "Unable to extract hsm_payload from request_payload";
    return false;
  }
  HsmAssociatedData hsm_associated_data;
  if (!DeserializeHsmAssociatedDataFromCbor(hsm_payload.associated_data,
                                            &hsm_associated_data)) {
    LOG(ERROR) << "Unable to deserialize hsm_associated_data_cbor";
    return false;
  }

  // If the recovery request is sent from devices with TPM2.0, no RSA signature
  // is attached to be verified and the public key wrapped in AD1 would be
  // empty.
  if (!hsm_associated_data.rsa_public_key.empty() ||
      !recovery_request.rsa_signature.empty()) {
    // Verify RSA signature with RSA public key and request payload
    if (!VerifyRsaSignatureSha256(recovery_request.request_payload,
                                  recovery_request.rsa_signature,
                                  hsm_associated_data.rsa_public_key)) {
      LOG(ERROR)
          << "Unable to initiate verifying rsa signature in request_payload";
      return false;
    }
  }

  brillo::SecureBlob request_plain_text_cbor;
  if (!DecryptRequestPayloadPlainText(epoch_priv_key, request_payload,
                                      &request_plain_text_cbor)) {
    LOG(ERROR) << "Unable to decrypt plain text in request_payload";
    return false;
  }

  RecoveryRequestPlainText plain_text;
  if (!DeserializeRecoveryRequestPlainTextFromCbor(request_plain_text_cbor,
                                                   &plain_text)) {
    LOG(ERROR)
        << "Unable to deserialize Recovery Request request_plain_text_cbor";
    return false;
  }

  if (!MediateHsmPayload(mediator_priv_key, epoch_pub_key, epoch_priv_key,
                         plain_text.ephemeral_pub_inv_key, hsm_payload,
                         recovery_response_proto)) {
    LOG(ERROR) << "Unable to mediate hsm_payload";
    return false;
  }

  return true;
}

}  // namespace cryptorecovery
}  // namespace cryptohome
