#include "quiche/oblivious_http/buffers/oblivious_http_response.h"

#include <stddef.h>
#include <stdint.h>

#include <algorithm>
#include <string>
#include <utility>

#include "absl/status/status.h"
#include "absl/status/statusor.h"
#include "absl/strings/str_cat.h"
#include "absl/strings/string_view.h"
#include "openssl/aead.h"
#include "openssl/digest.h"
#include "openssl/hkdf.h"
#include "openssl/hpke.h"
#include "quiche/common/platform/api/quiche_bug_tracker.h"
#include "quiche/common/quiche_crypto_logging.h"
#include "quiche/common/quiche_random.h"
#include "quiche/common/quiche_status_utils.h"
#include "quiche/oblivious_http/buffers/oblivious_http_request.h"
#include "quiche/oblivious_http/common/oblivious_http_definitions.h"
#include "quiche/oblivious_http/common/oblivious_http_header_key_config.h"

namespace quiche {
namespace {
// Generate a random string.
void random(QuicheRandom* quiche_random, char* dest, size_t len) {
  if (quiche_random == nullptr) {
    quiche_random = QuicheRandom::GetInstance();
  }
  quiche_random->RandBytes(dest, len);
}
}  // namespace

// Ctor.
ObliviousHttpResponse::ObliviousHttpResponse(std::string encrypted_data,
                                             std::string resp_plaintext)
    : encrypted_data_(std::move(encrypted_data)),
      response_plaintext_(std::move(resp_plaintext)) {}

// Response Decapsulation.
// 1. Extract resp_nonce
// 2. Build prk (pseudorandom key) using HKDF_Extract
// 3. Derive aead_key using HKDF_Labeled_Expand
// 4. Derive aead_nonce using HKDF_Labeled_Expand
// 5. Setup AEAD context and Decrypt.
// https://www.rfc-editor.org/rfc/rfc9458.html#section-4.4-3
absl::StatusOr<ObliviousHttpResponse>
ObliviousHttpResponse::CreateClientObliviousResponse(
    std::string encrypted_data,
    ObliviousHttpRequest::Context& oblivious_http_request_context,
    absl::string_view resp_label) {
  if (encrypted_data.empty()) {
    return absl::InvalidArgumentError("Empty encrypted_data input param.");
  }

  QUICHE_ASSIGN_OR_RETURN(CommonAeadParamsResult aead_params_st,
                          GetCommonAeadParams(oblivious_http_request_context));

  // secret_len = [max(Nn, Nk)] where Nk and Nn are the length of AEAD
  // key and nonce associated with HPKE context.
  // https://www.rfc-editor.org/rfc/rfc9458.html#section-4.4-2.1.1
  size_t secret_len = aead_params_st.secret_len;
  if (encrypted_data.size() < secret_len) {
    return absl::InvalidArgumentError(
        absl::StrCat("Invalid input response. Failed to parse required minimum "
                     "expected_len=",
                     secret_len, " bytes."));
  }
  // Extract response_nonce. Step 2
  // https://www.rfc-editor.org/rfc/rfc9458.html#section-4.4-2.2.1
  absl::string_view response_nonce =
      absl::string_view(encrypted_data).substr(0, secret_len);
  absl::string_view encrypted_response =
      absl::string_view(encrypted_data).substr(secret_len);

  QUICHE_ASSIGN_OR_RETURN(
      AeadContextData aead_context_data,
      GetAeadContextData(oblivious_http_request_context, aead_params_st,
                         resp_label, response_nonce));

  // Decrypt with initialized AEAD context.
  // response, error = Open(aead_key, aead_nonce, "", ct)
  // https://www.rfc-editor.org/rfc/rfc9458.html#section-4.4-6
  // DecryptChunk with `is_final_chunk` as false is the same implementation as
  // decrypting the full encrypted response.
  QUICHE_ASSIGN_OR_RETURN(
      std::string decrypted,
      DecryptChunk(encrypted_response, aead_context_data,
                   aead_context_data.aead_nonce, /*is_final_chunk=*/false));
  ObliviousHttpResponse oblivious_response(std::move(encrypted_data),
                                           std::move(decrypted));
  return oblivious_response;
}

// Response Encapsulation.
// https://www.rfc-editor.org/rfc/rfc9458.html#section-4.4
// Use HPKE context from BoringSSL to export a secret and use it to Seal (AKA
// encrypt) the response back to the Sender(client)
absl::StatusOr<ObliviousHttpResponse>
ObliviousHttpResponse::CreateServerObliviousResponse(
    std::string plaintext_payload,
    ObliviousHttpRequest::Context& oblivious_http_request_context,
    absl::string_view response_label, QuicheRandom* quiche_random) {
  if (plaintext_payload.empty()) {
    return absl::InvalidArgumentError("Empty plaintext_payload input param.");
  }
  QUICHE_ASSIGN_OR_RETURN(CommonAeadParamsResult aead_params_st,
                          GetCommonAeadParams(oblivious_http_request_context));
  const size_t nonce_size = aead_params_st.secret_len;
  const size_t max_encrypted_data_size =
      nonce_size + plaintext_payload.size() +
      EVP_AEAD_max_overhead(EVP_HPKE_AEAD_aead(EVP_HPKE_CTX_aead(
          oblivious_http_request_context.hpke_context_.get())));
  std::string encrypted_data(max_encrypted_data_size, '\0');
  // response_nonce = random(max(Nn, Nk))
  // https://www.rfc-editor.org/rfc/rfc9458.html#section-4.4-2.2.1
  random(quiche_random, encrypted_data.data(), nonce_size);
  absl::string_view response_nonce =
      absl::string_view(encrypted_data).substr(0, nonce_size);

  // Steps (1, 3 to 5) + AEAD context SetUp before 6th step is performed in
  // CommonOperations.
  QUICHE_ASSIGN_OR_RETURN(
      CommonOperationsResult common_ops_st,
      CommonOperationsToEncapDecap(
          response_nonce, oblivious_http_request_context, response_label,
          aead_params_st.aead_key_len, aead_params_st.aead_nonce_len,
          aead_params_st.secret_len));

  // ct = Seal(aead_key, aead_nonce, "", response)
  // https://www.rfc-editor.org/rfc/rfc9458.html#section-4.4-2.2.1
  size_t ciphertext_len;
  if (!EVP_AEAD_CTX_seal(
          common_ops_st.aead_ctx.get(),
          reinterpret_cast<uint8_t*>(encrypted_data.data() + nonce_size),
          &ciphertext_len, encrypted_data.size() - nonce_size,
          reinterpret_cast<const uint8_t*>(common_ops_st.aead_nonce.data()),
          aead_params_st.aead_nonce_len,
          reinterpret_cast<const uint8_t*>(plaintext_payload.data()),
          plaintext_payload.size(), nullptr, 0)) {
    return SslErrorAsStatus(
        "Failed to encrypt the payload with derived AEAD key.");
  }
  encrypted_data.resize(nonce_size + ciphertext_len);
  if (nonce_size == 0 || ciphertext_len == 0) {
    return absl::InternalError(absl::StrCat(
        "ObliviousHttpResponse Object wasn't initialized with required fields.",
        (nonce_size == 0 ? "Generated nonce is empty." : ""),
        (ciphertext_len == 0 ? "Generated Encrypted payload is empty." : "")));
  }
  ObliviousHttpResponse oblivious_response(std::move(encrypted_data),
                                           std::move(plaintext_payload));
  return oblivious_response;
}

// Serialize.
// enc_response = concat(response_nonce, ct)
// https://www.rfc-editor.org/rfc/rfc9458.html#section-4.4-3
const std::string& ObliviousHttpResponse::EncapsulateAndSerialize() const {
  return encrypted_data_;
}

// Decrypted blob.
const std::string& ObliviousHttpResponse::GetPlaintextData() const {
  return response_plaintext_;
}

// This section mainly deals with common operations performed by both
// Sender(client) and Receiver(gateway) on ObliviousHttpResponse.

absl::StatusOr<ObliviousHttpResponse::CommonAeadParamsResult>
ObliviousHttpResponse::GetCommonAeadParams(
    ObliviousHttpRequest::Context& oblivious_http_request_context) {
  if (oblivious_http_request_context.hpke_context_ == nullptr) {
    return absl::FailedPreconditionError(
        "HPKE context wasn't initialized before proceeding with this Response");
  }
  size_t expected_key_len = EVP_HPKE_KEM_enc_len(
      EVP_HPKE_CTX_kem(oblivious_http_request_context.hpke_context_.get()));
  if (oblivious_http_request_context.encapsulated_key_.size() !=
      expected_key_len) {
    return absl::InvalidArgumentError(absl::StrCat(
        "Invalid len for encapsulated_key arg. Expected:", expected_key_len,
        " Actual:", oblivious_http_request_context.encapsulated_key_.size()));
  }

  const EVP_AEAD* evp_hpke_aead = EVP_HPKE_AEAD_aead(
      EVP_HPKE_CTX_aead(oblivious_http_request_context.hpke_context_.get()));
  if (evp_hpke_aead == nullptr) {
    return absl::FailedPreconditionError(
        "Key Configuration not supported by HPKE AEADs. Check your key "
        "config.");
  }
  // Nk = [AEAD key len], is determined by BoringSSL.
  const size_t aead_key_len = EVP_AEAD_key_length(evp_hpke_aead);
  // Nn = [AEAD nonce len], is determined by BoringSSL.
  const size_t aead_nonce_len = EVP_AEAD_nonce_length(evp_hpke_aead);
  const size_t secret_len = std::max(aead_key_len, aead_nonce_len);
  CommonAeadParamsResult result{evp_hpke_aead, aead_key_len, aead_nonce_len,
                                secret_len};
  return result;
}

// Common Steps of AEAD key and AEAD nonce derivation common to both
// client(decapsulation) & Gateway(encapsulation) in handling
// Oblivious-Response. Ref Steps (1, 3-to-5, and setting up AEAD context in
// preparation for 6th step's Seal/Open) in the RFC.
// https://www.rfc-editor.org/rfc/rfc9458.html#section-4.4-3
absl::StatusOr<ObliviousHttpResponse::CommonOperationsResult>
ObliviousHttpResponse::CommonOperationsToEncapDecap(
    absl::string_view response_nonce,
    ObliviousHttpRequest::Context& oblivious_http_request_context,
    absl::string_view resp_label, const size_t aead_key_len,
    const size_t aead_nonce_len, const size_t secret_len) {
  if (response_nonce.empty()) {
    return absl::InvalidArgumentError("Invalid input params.");
  }
  // secret = context.Export("message/bhttp response", Nk)
  // Export secret of len [max(Nn, Nk)] where Nk and Nn are the length of AEAD
  // key and nonce associated with context.
  // https://www.rfc-editor.org/rfc/rfc9458.html#section-4.4-2.1.1
  std::string secret(secret_len, '\0');
  if (!EVP_HPKE_CTX_export(oblivious_http_request_context.hpke_context_.get(),
                           reinterpret_cast<uint8_t*>(secret.data()),
                           secret.size(),
                           reinterpret_cast<const uint8_t*>(resp_label.data()),
                           resp_label.size())) {
    return SslErrorAsStatus("Failed to export secret.");
  }

  // salt = concat(enc, response_nonce)
  // https://www.rfc-editor.org/rfc/rfc9458.html#section-4.4-2.3.1
  std::string salt = absl::StrCat(
      oblivious_http_request_context.encapsulated_key_, response_nonce);

  // prk = Extract(salt, secret)
  // https://www.rfc-editor.org/rfc/rfc9458.html#section-4.4-2.3.1
  std::string pseudorandom_key(EVP_MAX_MD_SIZE, '\0');
  size_t prk_len;
  auto evp_md = EVP_HPKE_KDF_hkdf_md(
      EVP_HPKE_CTX_kdf(oblivious_http_request_context.hpke_context_.get()));
  if (evp_md == nullptr) {
    QUICHE_BUG(Invalid Key Configuration
               : Unsupported BoringSSL HPKE KDFs)
        << "Update KeyConfig to support only BoringSSL HKDFs.";
    return absl::FailedPreconditionError(
        "Key Configuration not supported by BoringSSL HPKE KDFs. Check your "
        "Key "
        "Config.");
  }
  if (!HKDF_extract(
          reinterpret_cast<uint8_t*>(pseudorandom_key.data()), &prk_len, evp_md,
          reinterpret_cast<const uint8_t*>(secret.data()), secret_len,
          reinterpret_cast<const uint8_t*>(salt.data()), salt.size())) {
    return SslErrorAsStatus(
        "Failed to derive pesudorandom key from salt and secret.");
  }
  pseudorandom_key.resize(prk_len);

  // aead_key = Expand(prk, "key", Nk)
  // https://www.rfc-editor.org/rfc/rfc9458.html#section-4.4-2.4.1
  std::string aead_key(aead_key_len, '\0');
  absl::string_view hkdf_info = ObliviousHttpHeaderKeyConfig::kKeyHkdfInfo;
  // All currently supported KDFs are HKDF-based. See CheckKdfId in
  // `ObliviousHttpHeaderKeyConfig`.
  if (!HKDF_expand(reinterpret_cast<uint8_t*>(aead_key.data()), aead_key_len,
                   evp_md,
                   reinterpret_cast<const uint8_t*>(pseudorandom_key.data()),
                   prk_len, reinterpret_cast<const uint8_t*>(hkdf_info.data()),
                   hkdf_info.size())) {
    return SslErrorAsStatus(
        "Failed to expand AEAD key using pseudorandom key(prk).");
  }

  // aead_nonce = Expand(prk, "nonce", Nn)
  // https://www.rfc-editor.org/rfc/rfc9458.html#section-4.4-2.5.1
  std::string aead_nonce(aead_nonce_len, '\0');
  hkdf_info = ObliviousHttpHeaderKeyConfig::kNonceHkdfInfo;
  // All currently supported KDFs are HKDF-based. See CheckKdfId in
  // `ObliviousHttpHeaderKeyConfig`.
  if (!HKDF_expand(reinterpret_cast<uint8_t*>(aead_nonce.data()),
                   aead_nonce_len, evp_md,
                   reinterpret_cast<const uint8_t*>(pseudorandom_key.data()),
                   prk_len, reinterpret_cast<const uint8_t*>(hkdf_info.data()),
                   hkdf_info.size())) {
    return SslErrorAsStatus(
        "Failed to expand AEAD nonce using pseudorandom key(prk).");
  }

  const EVP_AEAD* evp_hpke_aead = EVP_HPKE_AEAD_aead(
      EVP_HPKE_CTX_aead(oblivious_http_request_context.hpke_context_.get()));
  if (evp_hpke_aead == nullptr) {
    return absl::FailedPreconditionError(
        "Key Configuration not supported by HPKE AEADs. Check your key "
        "config.");
  }

  // Setup AEAD context for subsequent Seal/Open operation in response handling.
  bssl::UniquePtr<EVP_AEAD_CTX> aead_ctx(EVP_AEAD_CTX_new(
      evp_hpke_aead, reinterpret_cast<const uint8_t*>(aead_key.data()),
      aead_key.size(), 0));
  if (aead_ctx == nullptr) {
    return SslErrorAsStatus("Failed to initialize AEAD context.");
  }
  if (!EVP_AEAD_CTX_init(aead_ctx.get(), evp_hpke_aead,
                         reinterpret_cast<const uint8_t*>(aead_key.data()),
                         aead_key.size(), 0, nullptr)) {
    return SslErrorAsStatus(
        "Failed to initialize AEAD context with derived key.");
  }
  CommonOperationsResult result{std::move(aead_ctx), std::move(aead_nonce)};
  return result;
}

absl::StatusOr<ObliviousHttpResponse::AeadContextData>
ObliviousHttpResponse::GetAeadContextData(
    ObliviousHttpRequest::Context& oblivious_http_request_context,
    CommonAeadParamsResult& aead_params, absl::string_view response_label,
    absl::string_view response_nonce) {
  // Steps (1, 3 to 5) + AEAD context SetUp before 6th step is performed in
  // CommonOperations.
  // https://www.rfc-editor.org/rfc/rfc9458.html#section-4.4-3
  QUICHE_ASSIGN_OR_RETURN(
      CommonOperationsResult common_ops_st,
      CommonOperationsToEncapDecap(
          response_nonce, oblivious_http_request_context, response_label,
          aead_params.aead_key_len, aead_params.aead_nonce_len,
          aead_params.secret_len));
  return AeadContextData{std::move(common_ops_st.aead_ctx),
                         std::move(common_ops_st.aead_nonce)};
}

// Encrypts the chunk following
// https://www.ietf.org/archive/id/draft-ietf-ohai-chunked-ohttp-05.html#section-6.1
// The plaintext payload can only be empty if this is the final chunk. The chunk
// nonce cannot be empty. If the operation succeeds then the returned encrypted
// data is guaranteed to be non-empty.
absl::StatusOr<std::string> ObliviousHttpResponse::EncryptChunk(
    ObliviousHttpRequest::Context& oblivious_http_request_context,
    const AeadContextData& aead_context_data,
    absl::string_view plaintext_payload, absl::string_view chunk_nonce,
    bool is_final_chunk) {
  // Empty plaintext_payload is only allowed for the final chunk.
  if (!is_final_chunk && plaintext_payload.empty()) {
    return absl::InvalidArgumentError(
        "A non-final chunk MUST NOT contain a zero-length plaintext.");
  }
  if (chunk_nonce.empty()) {
    return absl::InvalidArgumentError("Chunk nonce cannot be empty.");
  }

  uint8_t* ad = nullptr;
  size_t ad_len = 0;
  if (is_final_chunk) {
    ad = const_cast<uint8_t*>(kFinalAdBytes);
    ad_len = sizeof(kFinalAdBytes);
  }

  const size_t max_encrypted_data_size =
      plaintext_payload.size() +
      EVP_AEAD_max_overhead(EVP_HPKE_AEAD_aead(EVP_HPKE_CTX_aead(
          oblivious_http_request_context.hpke_context_.get())));
  std::string encrypted_data(max_encrypted_data_size, '\0');
  size_t ciphertext_len;

  if (!EVP_AEAD_CTX_seal(
          aead_context_data.aead_ctx.get(),
          reinterpret_cast<uint8_t*>(encrypted_data.data()), &ciphertext_len,
          encrypted_data.size(),
          reinterpret_cast<const uint8_t*>(chunk_nonce.data()),
          aead_context_data.aead_nonce.size(),
          reinterpret_cast<const uint8_t*>(plaintext_payload.data()),
          plaintext_payload.size(), ad, ad_len)) {
    return SslErrorAsStatus(
        "Failed to encrypt the payload with derived AEAD key.");
  }
  encrypted_data.resize(ciphertext_len);
  if (ciphertext_len == 0) {
    return absl::InternalError("Generated Encrypted payload cannot be empty.");
  }
  return encrypted_data;
}

absl::StatusOr<std::string> ObliviousHttpResponse::DecryptChunk(
    absl::string_view encrypted_chunk, const AeadContextData& aead_context_data,
    absl::string_view chunk_nonce, bool is_final_chunk) {
  uint8_t* ad = nullptr;
  size_t ad_len = 0;
  if (is_final_chunk) {
    ad = const_cast<uint8_t*>(kFinalAdBytes);
    ad_len = sizeof(kFinalAdBytes);
  }

  std::string decrypted(encrypted_chunk.size(), '\0');
  size_t decrypted_len;
  if (!EVP_AEAD_CTX_open(
          aead_context_data.aead_ctx.get(),
          reinterpret_cast<uint8_t*>(decrypted.data()), &decrypted_len,
          decrypted.size(),
          reinterpret_cast<const uint8_t*>(chunk_nonce.data()),
          aead_context_data.aead_nonce.size(),
          reinterpret_cast<const uint8_t*>(encrypted_chunk.data()),
          encrypted_chunk.size(), ad, ad_len)) {
    return SslErrorAsStatus(
        "Failed to decrypt the response with derived AEAD key and nonce.",
        absl::StatusCode::kInvalidArgument);
  }
  if (decrypted_len == 0 && !is_final_chunk) {
    return absl::InvalidArgumentError(
        "Decrypted non-final chunk plaintext is zero-length. A non-final chunk "
        "MUST NOT contain a zero-length plaintext.");
  }
  decrypted.resize(decrypted_len);
  return decrypted;
}

absl::StatusOr<ObliviousHttpResponse::ChunkCounter>
ObliviousHttpResponse::ChunkCounter::Create(std::string nonce) {
  if (nonce.empty()) {
    return absl::InvalidArgumentError("Nonce must not be empty.");
  }
  return ObliviousHttpResponse::ChunkCounter(std::move(nonce));
}

ObliviousHttpResponse::ChunkCounter::ChunkCounter(std::string nonce)
    : nonce_(std::move(nonce)), encoded_counter_(nonce_.size(), '\0') {}

void ObliviousHttpResponse::ChunkCounter::Increment() {
  uint64_t pos = nonce_.size();
  // Start with the least significant byte and increment it by 1, if it wraps
  // then proceed to the next byte and repeat.
  do {
    pos--;
    encoded_counter_[pos] += static_cast<uint8_t>(1);
  } while (pos != 0 && encoded_counter_[pos] == '\0');
  if (pos == 0 && encoded_counter_[pos] == '\0') {
    // Counter has wrapped.
    limit_exceeded_ = true;
  }
}

std::string ObliviousHttpResponse::ChunkCounter::GetChunkNonce() const {
  std::string chunk_nonce(nonce_.size(), '\0');
  for (size_t i = 0; i < chunk_nonce.size(); i++) {
    chunk_nonce[i] = nonce_[i] ^ encoded_counter_[i];
  }
  return chunk_nonce;
}
}  // namespace quiche
