diff --git a/build/source_list.bzl b/build/source_list.bzl
index 110f0da..afc80c7 100644
--- a/build/source_list.bzl
+++ b/build/source_list.bzl
@@ -1093,6 +1093,12 @@
     "http2/test_tools/http2_frame_builder_test.cc",
     "http2/test_tools/http2_random_test.cc",
     "http2/test_tools/random_decoder_test_base_test.cc",
+    "oblivious_http/buffers/oblivious_http_integration_test.cc",
+    "oblivious_http/buffers/oblivious_http_request_test.cc",
+    "oblivious_http/buffers/oblivious_http_response_test.cc",
+    "oblivious_http/common/oblivious_http_header_key_config_test.cc",
+    "oblivious_http/oblivious_http_client_test.cc",
+    "oblivious_http/oblivious_http_gateway_test.cc",
     "quic/core/congestion_control/bandwidth_sampler_test.cc",
     "quic/core/congestion_control/bbr2_simulator_test.cc",
     "quic/core/congestion_control/bbr_sender_test.cc",
@@ -1438,6 +1444,20 @@
 binary_http_srcs = [
     "binary_http/binary_http_message.cc",
 ]
+oblivious_http_hdrs = [
+    "oblivious_http/buffers/oblivious_http_request.h",
+    "oblivious_http/buffers/oblivious_http_response.h",
+    "oblivious_http/common/oblivious_http_header_key_config.h",
+    "oblivious_http/oblivious_http_client.h",
+    "oblivious_http/oblivious_http_gateway.h",
+]
+oblivious_http_srcs = [
+    "oblivious_http/buffers/oblivious_http_request.cc",
+    "oblivious_http/buffers/oblivious_http_response.cc",
+    "oblivious_http/common/oblivious_http_header_key_config.cc",
+    "oblivious_http/oblivious_http_client.cc",
+    "oblivious_http/oblivious_http_gateway.cc",
+]
 qbone_hdrs = [
     "quic/qbone/bonnet/icmp_reachable.h",
     "quic/qbone/bonnet/icmp_reachable_interface.h",
diff --git a/build/source_list.gni b/build/source_list.gni
index 94401df..53814a2 100644
--- a/build/source_list.gni
+++ b/build/source_list.gni
@@ -1093,6 +1093,12 @@
     "src/quiche/http2/test_tools/http2_frame_builder_test.cc",
     "src/quiche/http2/test_tools/http2_random_test.cc",
     "src/quiche/http2/test_tools/random_decoder_test_base_test.cc",
+    "src/quiche/oblivious_http/buffers/oblivious_http_integration_test.cc",
+    "src/quiche/oblivious_http/buffers/oblivious_http_request_test.cc",
+    "src/quiche/oblivious_http/buffers/oblivious_http_response_test.cc",
+    "src/quiche/oblivious_http/common/oblivious_http_header_key_config_test.cc",
+    "src/quiche/oblivious_http/oblivious_http_client_test.cc",
+    "src/quiche/oblivious_http/oblivious_http_gateway_test.cc",
     "src/quiche/quic/core/congestion_control/bandwidth_sampler_test.cc",
     "src/quiche/quic/core/congestion_control/bbr2_simulator_test.cc",
     "src/quiche/quic/core/congestion_control/bbr_sender_test.cc",
@@ -1438,6 +1444,20 @@
 binary_http_srcs = [
     "src/quiche/binary_http/binary_http_message.cc",
 ]
+oblivious_http_hdrs = [
+    "src/quiche/oblivious_http/buffers/oblivious_http_request.h",
+    "src/quiche/oblivious_http/buffers/oblivious_http_response.h",
+    "src/quiche/oblivious_http/common/oblivious_http_header_key_config.h",
+    "src/quiche/oblivious_http/oblivious_http_client.h",
+    "src/quiche/oblivious_http/oblivious_http_gateway.h",
+]
+oblivious_http_srcs = [
+    "src/quiche/oblivious_http/buffers/oblivious_http_request.cc",
+    "src/quiche/oblivious_http/buffers/oblivious_http_response.cc",
+    "src/quiche/oblivious_http/common/oblivious_http_header_key_config.cc",
+    "src/quiche/oblivious_http/oblivious_http_client.cc",
+    "src/quiche/oblivious_http/oblivious_http_gateway.cc",
+]
 qbone_hdrs = [
     "src/quiche/quic/qbone/bonnet/icmp_reachable.h",
     "src/quiche/quic/qbone/bonnet/icmp_reachable_interface.h",
diff --git a/build/source_list.json b/build/source_list.json
index 599ccdd..a877e81 100644
--- a/build/source_list.json
+++ b/build/source_list.json
@@ -1092,6 +1092,12 @@
     "quiche/http2/test_tools/http2_frame_builder_test.cc",
     "quiche/http2/test_tools/http2_random_test.cc",
     "quiche/http2/test_tools/random_decoder_test_base_test.cc",
+    "quiche/oblivious_http/buffers/oblivious_http_integration_test.cc",
+    "quiche/oblivious_http/buffers/oblivious_http_request_test.cc",
+    "quiche/oblivious_http/buffers/oblivious_http_response_test.cc",
+    "quiche/oblivious_http/common/oblivious_http_header_key_config_test.cc",
+    "quiche/oblivious_http/oblivious_http_client_test.cc",
+    "quiche/oblivious_http/oblivious_http_gateway_test.cc",
     "quiche/quic/core/congestion_control/bandwidth_sampler_test.cc",
     "quiche/quic/core/congestion_control/bbr2_simulator_test.cc",
     "quiche/quic/core/congestion_control/bbr_sender_test.cc",
@@ -1437,6 +1443,20 @@
   "binary_http_srcs": [
     "quiche/binary_http/binary_http_message.cc"
   ],
+  "oblivious_http_hdrs": [
+    "quiche/oblivious_http/buffers/oblivious_http_request.h",
+    "quiche/oblivious_http/buffers/oblivious_http_response.h",
+    "quiche/oblivious_http/common/oblivious_http_header_key_config.h",
+    "quiche/oblivious_http/oblivious_http_client.h",
+    "quiche/oblivious_http/oblivious_http_gateway.h"
+  ],
+  "oblivious_http_srcs": [
+    "quiche/oblivious_http/buffers/oblivious_http_request.cc",
+    "quiche/oblivious_http/buffers/oblivious_http_response.cc",
+    "quiche/oblivious_http/common/oblivious_http_header_key_config.cc",
+    "quiche/oblivious_http/oblivious_http_client.cc",
+    "quiche/oblivious_http/oblivious_http_gateway.cc"
+  ],
   "qbone_hdrs": [
     "quiche/quic/qbone/bonnet/icmp_reachable.h",
     "quiche/quic/qbone/bonnet/icmp_reachable_interface.h",
diff --git a/quiche/oblivious_http/buffers/oblivious_http_integration_test.cc b/quiche/oblivious_http/buffers/oblivious_http_integration_test.cc
new file mode 100644
index 0000000..7ed02c1
--- /dev/null
+++ b/quiche/oblivious_http/buffers/oblivious_http_integration_test.cc
@@ -0,0 +1,115 @@
+#include <stdint.h>
+
+#include <string>
+
+#include "absl/strings/escaping.h"
+#include "openssl/hpke.h"
+#include "quiche/common/platform/api/quiche_test.h"
+#include "quiche/oblivious_http/buffers/oblivious_http_response.h"
+
+namespace quiche {
+namespace {
+
+struct ObliviousHttpResponseTestStrings {
+  std::string test_case_name;
+  uint8_t key_id;
+  std::string request_plaintext;
+  std::string response_plaintext;
+};
+
+std::string GetHpkePrivateKey() {
+  absl::string_view hpke_key_hex =
+      "b77431ecfa8f4cfc30d6e467aafa06944dffe28cb9dd1409e33a3045f5adc8a1";
+  return absl::HexStringToBytes(hpke_key_hex);
+}
+
+std::string GetHpkePublicKey() {
+  absl::string_view public_key =
+      "6d21cfe09fbea5122f9ebc2eb2a69fcc4f06408cd54aac934f012e76fcdcef62";
+  return absl::HexStringToBytes(public_key);
+}
+
+const ObliviousHttpHeaderKeyConfig GetOhttpKeyConfig(uint8_t key_id,
+                                                     uint16_t kem_id,
+                                                     uint16_t kdf_id,
+                                                     uint16_t aead_id) {
+  auto ohttp_key_config =
+      ObliviousHttpHeaderKeyConfig::Create(key_id, kem_id, kdf_id, aead_id);
+  EXPECT_TRUE(ohttp_key_config.ok());
+  return std::move(ohttp_key_config.value());
+}
+
+bssl::UniquePtr<EVP_HPKE_KEY> ConstructHpkeKey(
+    absl::string_view hpke_key,
+    const ObliviousHttpHeaderKeyConfig &ohttp_key_config) {
+  bssl::UniquePtr<EVP_HPKE_KEY> bssl_hpke_key(EVP_HPKE_KEY_new());
+  EXPECT_NE(bssl_hpke_key, nullptr);
+  EXPECT_TRUE(EVP_HPKE_KEY_init(
+      bssl_hpke_key.get(), ohttp_key_config.GetHpkeKem(),
+      reinterpret_cast<const uint8_t *>(hpke_key.data()), hpke_key.size()));
+  return bssl_hpke_key;
+}
+}  // namespace
+
+absl::StatusOr<ObliviousHttpRequest>
+CreateClientObliviousRequestWithSeedForTesting(
+    absl::string_view plaintext_payload, absl::string_view hpke_public_key,
+    const ObliviousHttpHeaderKeyConfig &ohttp_key_config,
+    absl::string_view seed) {
+  return ObliviousHttpRequest::EncapsulateWithSeed(
+      plaintext_payload, hpke_public_key, ohttp_key_config, seed);
+}
+
+using ObliviousHttpParameterizedTest =
+    test::QuicheTestWithParam<ObliviousHttpResponseTestStrings>;
+
+TEST_P(ObliviousHttpParameterizedTest, TestEndToEndWithOfflineStrings) {
+  // For each test case, verify end to end request-handling and
+  // response-handling.
+  const ObliviousHttpResponseTestStrings &test = GetParam();
+
+  auto ohttp_key_config =
+      GetOhttpKeyConfig(test.key_id, EVP_HPKE_DHKEM_X25519_HKDF_SHA256,
+                        EVP_HPKE_HKDF_SHA256, EVP_HPKE_AES_256_GCM);
+  // Round-trip request flow.
+  auto client_req_encap = ObliviousHttpRequest::CreateClientObliviousRequest(
+      test.request_plaintext, GetHpkePublicKey(), ohttp_key_config);
+  EXPECT_TRUE(client_req_encap.ok());
+  ASSERT_FALSE(client_req_encap->EncapsulateAndSerialize().empty());
+  auto server_req_decap = ObliviousHttpRequest::CreateServerObliviousRequest(
+      client_req_encap->EncapsulateAndSerialize(),
+      *(ConstructHpkeKey(GetHpkePrivateKey(), ohttp_key_config)),
+      ohttp_key_config);
+  EXPECT_TRUE(server_req_decap.ok());
+  EXPECT_EQ(server_req_decap->GetPlaintextData(), test.request_plaintext);
+
+  // Round-trip response flow.
+  auto server_resp_encap = ObliviousHttpResponse::CreateServerObliviousResponse(
+      test.response_plaintext,
+      *(server_req_decap->oblivious_http_request_context()));
+  EXPECT_TRUE(server_resp_encap.ok());
+  ASSERT_FALSE(server_resp_encap->EncapsulateAndSerialize().empty());
+  auto client_resp_decap = ObliviousHttpResponse::CreateClientObliviousResponse(
+      server_resp_encap->EncapsulateAndSerialize(),
+      *(client_req_encap->oblivious_http_request_context()));
+  EXPECT_TRUE(client_resp_decap.ok());
+  EXPECT_EQ(client_resp_decap->GetPlaintextData(), test.response_plaintext);
+}
+
+INSTANTIATE_TEST_SUITE_P(
+    ObliviousHttpParameterizedTests, ObliviousHttpParameterizedTest,
+    testing::ValuesIn<ObliviousHttpResponseTestStrings>(
+        {{"test_case_1", 4, "test request 1", "test response 1"},
+         {"test_case_2", 6, "test request 2", "test response 2"},
+         {"test_case_3", 7, "test request 3", "test response 3"},
+         {"test_case_4", 2, "test request 4", "test response 4"},
+         {"test_case_5", 1, "test request 5", "test response 5"},
+         {"test_case_6", 7, "test request 6", "test response 6"},
+         {"test_case_7", 3, "test request 7", "test response 7"},
+         {"test_case_8", 9, "test request 8", "test response 8"},
+         {"test_case_9", 3, "test request 9", "test response 9"},
+         {"test_case_10", 4, "test request 10", "test response 10"}}),
+    [](const testing::TestParamInfo<ObliviousHttpParameterizedTest::ParamType>
+           &info) { return info.param.test_case_name; });
+
+}  // namespace quiche
diff --git a/quiche/oblivious_http/buffers/oblivious_http_request.cc b/quiche/oblivious_http/buffers/oblivious_http_request.cc
new file mode 100644
index 0000000..ca26e4e
--- /dev/null
+++ b/quiche/oblivious_http/buffers/oblivious_http_request.cc
@@ -0,0 +1,194 @@
+#include "quiche/oblivious_http/buffers/oblivious_http_request.h"
+
+#include <stddef.h>
+#include <stdint.h>
+
+#include <memory>
+#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/hpke.h"
+#include "quiche/common/platform/api/quiche_logging.h"
+#include "quiche/common/quiche_crypto_logging.h"
+
+namespace quiche {
+// Ctor.
+ObliviousHttpRequest::Context::Context(
+    bssl::UniquePtr<EVP_HPKE_CTX> hpke_context, std::string encapsulated_key)
+    : hpke_context_(std::move(hpke_context)),
+      encapsulated_key_(std::move(encapsulated_key)) {}
+
+// Ctor.
+ObliviousHttpRequest::ObliviousHttpRequest(
+    bssl::UniquePtr<EVP_HPKE_CTX> hpke_context, std::string encapsulated_key,
+    const ObliviousHttpHeaderKeyConfig& ohttp_key_config,
+    std::string req_ciphertext, std::string req_plaintext)
+    : oblivious_http_request_context_(
+          new Context(std::move(hpke_context), std::move(encapsulated_key))),
+      key_config_(ohttp_key_config),
+      request_ciphertext_(std::move(req_ciphertext)),
+      request_plaintext_(std::move(req_plaintext)) {}
+
+// Request Decapsulation.
+absl::StatusOr<ObliviousHttpRequest>
+ObliviousHttpRequest::CreateServerObliviousRequest(
+    absl::string_view encrypted_data, const EVP_HPKE_KEY& gateway_key,
+    const ObliviousHttpHeaderKeyConfig& ohttp_key_config) {
+  if (EVP_HPKE_KEY_kem(&gateway_key) == nullptr) {
+    return absl::InvalidArgumentError(
+        "Invalid input param. Failed to import gateway_key.");
+  }
+  bssl::UniquePtr<EVP_HPKE_CTX> gateway_ctx(EVP_HPKE_CTX_new());
+  if (gateway_ctx == nullptr) {
+    return SslErrorAsStatus("Failed to initialize Gateway/Server's Context.");
+  }
+  // TODO(anov) Add ParseOhttpPayloadHeader(QuicheDataReader) to read fields out
+  // of payload, and eliminate sub-stringing.
+  auto is_hdr_ok = ohttp_key_config.ParseOhttpPayloadHeader(encrypted_data);
+  if (!is_hdr_ok.ok()) {
+    return is_hdr_ok;
+  }
+  absl::string_view enc_plus_ciphertext =
+      encrypted_data.substr(ObliviousHttpHeaderKeyConfig::kHeaderLength);
+
+  size_t enc_key_len = EVP_HPKE_KEM_enc_len(EVP_HPKE_KEY_kem(&gateway_key));
+  if (enc_plus_ciphertext.size() < enc_key_len) {
+    return absl::FailedPreconditionError(absl::StrCat(
+        "Failed to extract encapsulation key of expected len=", enc_key_len,
+        "from payload."));
+  }
+  absl::string_view enc_key_received =
+      enc_plus_ciphertext.substr(0, enc_key_len);
+  std::string info = ohttp_key_config.SerializeRecipientContextInfo();
+  if (!EVP_HPKE_CTX_setup_recipient(
+          gateway_ctx.get(), &gateway_key, ohttp_key_config.GetHpkeKdf(),
+          ohttp_key_config.GetHpkeAead(),
+          reinterpret_cast<const uint8_t*>(enc_key_received.data()),
+          enc_key_received.size(),
+          reinterpret_cast<const uint8_t*>(info.data()), info.size())) {
+    return SslErrorAsStatus("Failed to setup recipient context");
+  }
+
+  absl::string_view ciphertext_received =
+      enc_plus_ciphertext.substr(enc_key_len);
+
+  // Decrypt the message.
+  std::string decrypted(ciphertext_received.size(), '\0');
+  size_t decrypted_len;
+  if (!EVP_HPKE_CTX_open(
+          gateway_ctx.get(), reinterpret_cast<uint8_t*>(decrypted.data()),
+          &decrypted_len, decrypted.size(),
+          reinterpret_cast<const uint8_t*>(ciphertext_received.data()),
+          ciphertext_received.size(), nullptr, 0)) {
+    return SslErrorAsStatus("Failed to decrypt.");
+  }
+  decrypted.resize(decrypted_len);
+  return ObliviousHttpRequest(
+      std::move(gateway_ctx), std::string(enc_key_received), ohttp_key_config,
+      std::string(ciphertext_received), std::move(decrypted));
+}
+
+// Request Encapsulation.
+absl::StatusOr<ObliviousHttpRequest>
+ObliviousHttpRequest::CreateClientObliviousRequest(
+    absl::string_view plaintext_payload, absl::string_view hpke_public_key,
+    const ObliviousHttpHeaderKeyConfig& ohttp_key_config) {
+  return EncapsulateWithSeed(plaintext_payload, hpke_public_key,
+                             ohttp_key_config, "");
+}
+
+absl::StatusOr<ObliviousHttpRequest> ObliviousHttpRequest::EncapsulateWithSeed(
+    absl::string_view plaintext_payload, absl::string_view hpke_public_key,
+    const ObliviousHttpHeaderKeyConfig& ohttp_key_config,
+    absl::string_view seed) {
+  if (plaintext_payload.empty() || hpke_public_key.empty()) {
+    return absl::InvalidArgumentError("Invalid input.");
+  }
+  // Initialize HPKE key and context.
+  bssl::UniquePtr<EVP_HPKE_KEY> client_key(EVP_HPKE_KEY_new());
+  if (client_key == nullptr) {
+    return SslErrorAsStatus("Failed to initialize HPKE Client Key.");
+  }
+  bssl::UniquePtr<EVP_HPKE_CTX> client_ctx(EVP_HPKE_CTX_new());
+  if (client_ctx == nullptr) {
+    return SslErrorAsStatus("Failed to initialize HPKE Client Context.");
+  }
+  // Setup the sender (client)
+  std::string encapsulated_key(EVP_HPKE_MAX_ENC_LENGTH, '\0');
+  size_t enc_len;
+  std::string info = ohttp_key_config.SerializeRecipientContextInfo();
+  if (seed.empty()) {
+    if (!EVP_HPKE_CTX_setup_sender(
+            client_ctx.get(),
+            reinterpret_cast<uint8_t*>(encapsulated_key.data()), &enc_len,
+            encapsulated_key.size(), ohttp_key_config.GetHpkeKem(),
+            ohttp_key_config.GetHpkeKdf(), ohttp_key_config.GetHpkeAead(),
+            reinterpret_cast<const uint8_t*>(hpke_public_key.data()),
+            hpke_public_key.size(),
+            reinterpret_cast<const uint8_t*>(info.data()), info.size())) {
+      return SslErrorAsStatus(
+          "Failed to setup HPKE context with given public key param "
+          "hpke_public_key.");
+    }
+  } else {
+    if (!EVP_HPKE_CTX_setup_sender_with_seed_for_testing(
+            client_ctx.get(),
+            reinterpret_cast<uint8_t*>(encapsulated_key.data()), &enc_len,
+            encapsulated_key.size(), ohttp_key_config.GetHpkeKem(),
+            ohttp_key_config.GetHpkeKdf(), ohttp_key_config.GetHpkeAead(),
+            reinterpret_cast<const uint8_t*>(hpke_public_key.data()),
+            hpke_public_key.size(),
+            reinterpret_cast<const uint8_t*>(info.data()), info.size(),
+            reinterpret_cast<const uint8_t*>(seed.data()), seed.size())) {
+      return SslErrorAsStatus(
+          "Failed to setup HPKE context with given public key param "
+          "hpke_public_key and seed.");
+    }
+  }
+  encapsulated_key.resize(enc_len);
+  std::string ciphertext(
+      plaintext_payload.size() + EVP_HPKE_CTX_max_overhead(client_ctx.get()),
+      '\0');
+  size_t ciphertext_len;
+  if (!EVP_HPKE_CTX_seal(
+          client_ctx.get(), reinterpret_cast<uint8_t*>(ciphertext.data()),
+          &ciphertext_len, ciphertext.size(),
+          reinterpret_cast<const uint8_t*>(plaintext_payload.data()),
+          plaintext_payload.size(), nullptr, 0)) {
+    return SslErrorAsStatus(
+        "Failed to encrypt plaintext_payload with given public key param "
+        "hpke_public_key.");
+  }
+  ciphertext.resize(ciphertext_len);
+  if (encapsulated_key.empty() || ciphertext.empty()) {
+    return absl::InternalError(absl::StrCat(
+        "Failed to generate required data: ",
+        (encapsulated_key.empty() ? "encapsulated key is empty" : ""),
+        (ciphertext.empty() ? "encrypted data is empty" : ""), "."));
+  }
+
+  return ObliviousHttpRequest(
+      std::move(client_ctx), std::move(encapsulated_key), ohttp_key_config,
+      std::move(ciphertext), std::string(plaintext_payload));
+}
+
+// Request Serialize.
+// Builds request=[hdr, enc, ct].
+// https://www.ietf.org/archive/id/draft-ietf-ohai-ohttp-03.html#section-4.1-4.5
+std::string ObliviousHttpRequest::EncapsulateAndSerialize() const {
+  return absl::StrCat(key_config_.SerializeOhttpPayloadHeader(),
+                      oblivious_http_request_context_->encapsulated_key_,
+                      request_ciphertext_);
+}
+
+// Returns Decrypted blob in the case of server, and returns plaintext used by
+// the client while `CreateClientObliviousRequest`.
+absl::string_view ObliviousHttpRequest::GetPlaintextData() const {
+  return request_plaintext_;
+}
+
+}  // namespace quiche
diff --git a/quiche/oblivious_http/buffers/oblivious_http_request.h b/quiche/oblivious_http/buffers/oblivious_http_request.h
new file mode 100644
index 0000000..0807fc8
--- /dev/null
+++ b/quiche/oblivious_http/buffers/oblivious_http_request.h
@@ -0,0 +1,105 @@
+#ifndef QUICHE_OBLIVIOUS_HTTP_BUFFERS_OBLIVIOUS_HTTP_REQUEST_H_
+#define QUICHE_OBLIVIOUS_HTTP_BUFFERS_OBLIVIOUS_HTTP_REQUEST_H_
+
+#include <memory>
+#include <string>
+
+#include "absl/status/statusor.h"
+#include "absl/strings/string_view.h"
+#include "quiche/oblivious_http/common/oblivious_http_header_key_config.h"
+
+namespace quiche {
+// 1. Handles client side encryption of the payload that will subsequently be
+// added to HTTP POST body and passed on to Relay.
+// 2. Handles server side decryption of the payload received in HTTP POST body
+// from Relay.
+// https://www.ietf.org/archive/id/draft-ietf-ohai-ohttp-03.html#name-encapsulation-of-requests
+class QUICHE_EXPORT_PRIVATE ObliviousHttpRequest {
+ public:
+  // Holds the HPKE related data received from request. This context is created
+  // during request processing, and subsequently passed into response handling
+  // in `ObliviousHttpResponse`.
+  class Context {
+   public:
+    ~Context() = default;
+
+   private:
+    explicit Context(bssl::UniquePtr<EVP_HPKE_CTX> hpke_context,
+                     std::string encapsulated_key);
+
+    // All accessors must be friends to read `Context`.
+    friend class ObliviousHttpRequest;
+    friend class ObliviousHttpResponse;
+    // Tests which need access.
+    friend class
+        ObliviousHttpRequest_TestDecapsulateWithSpecAppendixAExample_Test;
+    friend class ObliviousHttpRequest_TestEncapsulatedRequestStructure_Test;
+    friend class
+        ObliviousHttpRequest_TestEncapsulatedOhttpEncryptedPayload_Test;
+    friend class ObliviousHttpRequest_TestDeterministicSeededOhttpRequest_Test;
+    friend class ObliviousHttpResponse_EndToEndTestForResponse_Test;
+    friend class ObliviousHttpResponse_TestEncapsulateWithQuicheRandom_Test;
+
+    bssl::UniquePtr<EVP_HPKE_CTX> hpke_context_;
+    const std::string encapsulated_key_;
+  };
+  // Parse the OHTTP request from the given `encrypted_data`.
+  // On success, returns obj that callers will use to `GetPlaintextData`.
+  // Generic Usecase : server-side calls this method in the context of Request.
+  static absl::StatusOr<ObliviousHttpRequest> CreateServerObliviousRequest(
+      absl::string_view encrypted_data, const EVP_HPKE_KEY& gateway_key,
+      const ObliviousHttpHeaderKeyConfig& ohttp_key_config);
+
+  // Constructs an OHTTP request for the given `plaintext_payload`.
+  // On success, returns obj that callers will use to `EncapsulateAndSerialize`
+  // OHttp request.
+  static absl::StatusOr<ObliviousHttpRequest> CreateClientObliviousRequest(
+      absl::string_view plaintext_payload, absl::string_view hpke_public_key,
+      const ObliviousHttpHeaderKeyConfig& ohttp_key_config);
+
+  // Movable.
+  ObliviousHttpRequest(ObliviousHttpRequest&& other) = default;
+  ObliviousHttpRequest& operator=(ObliviousHttpRequest&& other) = default;
+
+  ~ObliviousHttpRequest() = default;
+
+  // Returns serialized OHTTP request bytestring.
+  std::string EncapsulateAndSerialize() const;
+
+  // Generic Usecase : server-side calls this method after Decapsulation using
+  // `CreateServerObliviousRequest`.
+  absl::string_view GetPlaintextData() const;
+
+  // Oblivious HTTP request context is created after successful creation of
+  // `this` object, and subsequently passed into the `ObliviousHttpResponse` for
+  // followup response handling.
+  std::shared_ptr<Context> oblivious_http_request_context() const {
+    return oblivious_http_request_context_;
+  }
+
+ private:
+  friend absl::StatusOr<ObliviousHttpRequest>
+  CreateClientObliviousRequestWithSeedForTesting(
+      absl::string_view plaintext_payload, absl::string_view hpke_public_key,
+      const ObliviousHttpHeaderKeyConfig& ohttp_key_config,
+      absl::string_view seed);
+
+  explicit ObliviousHttpRequest(
+      bssl::UniquePtr<EVP_HPKE_CTX> hpke_context, std::string encapsulated_key,
+      const ObliviousHttpHeaderKeyConfig& ohttp_key_config,
+      std::string req_ciphertext, std::string req_plaintext);
+
+  static absl::StatusOr<ObliviousHttpRequest> EncapsulateWithSeed(
+      absl::string_view plaintext_payload, absl::string_view hpke_public_key,
+      const ObliviousHttpHeaderKeyConfig& ohttp_key_config,
+      absl::string_view seed);
+
+  std::shared_ptr<Context> oblivious_http_request_context_;
+  ObliviousHttpHeaderKeyConfig key_config_;
+  std::string request_ciphertext_;
+  std::string request_plaintext_;
+};
+
+}  // namespace quiche
+
+#endif  // QUICHE_OBLIVIOUS_HTTP_BUFFERS_OBLIVIOUS_HTTP_REQUEST_H_
diff --git a/quiche/oblivious_http/buffers/oblivious_http_request_test.cc b/quiche/oblivious_http/buffers/oblivious_http_request_test.cc
new file mode 100644
index 0000000..91ca8e9
--- /dev/null
+++ b/quiche/oblivious_http/buffers/oblivious_http_request_test.cc
@@ -0,0 +1,275 @@
+#include "quiche/oblivious_http/buffers/oblivious_http_request.h"
+
+#include <stddef.h>
+
+#include <cstdint>
+#include <memory>
+#include <string>
+#include <utility>
+
+#include "absl/status/status.h"
+#include "absl/status/statusor.h"
+#include "absl/strings/escaping.h"
+#include "absl/strings/str_cat.h"
+#include "absl/strings/string_view.h"
+#include "openssl/hkdf.h"
+#include "openssl/hpke.h"
+#include "quiche/common/platform/api/quiche_test.h"
+#include "quiche/common/quiche_data_reader.h"
+#include "quiche/oblivious_http/common/oblivious_http_header_key_config.h"
+
+namespace quiche {
+
+absl::StatusOr<ObliviousHttpRequest>
+CreateClientObliviousRequestWithSeedForTesting(
+    absl::string_view plaintext_payload, absl::string_view hpke_public_key,
+    const ObliviousHttpHeaderKeyConfig &ohttp_key_config,
+    absl::string_view seed) {
+  return ObliviousHttpRequest::EncapsulateWithSeed(
+      plaintext_payload, hpke_public_key, ohttp_key_config, seed);
+}
+
+namespace {
+const uint32_t kHeaderLength = ObliviousHttpHeaderKeyConfig::kHeaderLength;
+std::string GetHpkePrivateKey() {
+  absl::string_view hpke_key_hex =
+      "b77431ecfa8f4cfc30d6e467aafa06944dffe28cb9dd1409e33a3045f5adc8a1";
+  return absl::HexStringToBytes(hpke_key_hex);
+}
+
+std::string GetHpkePublicKey() {
+  absl::string_view public_key =
+      "6d21cfe09fbea5122f9ebc2eb2a69fcc4f06408cd54aac934f012e76fcdcef62";
+  return absl::HexStringToBytes(public_key);
+}
+
+std::string GetSeed() {
+  absl::string_view seed =
+      "52c4a758a802cd8b936eceea314432798d5baf2d7e9235dc084ab1b9cfa2f736";
+  return absl::HexStringToBytes(seed);
+}
+
+std::string GetSeededEncapsulatedKey() {
+  absl::string_view encapsulated_key =
+      "37fda3567bdbd628e88668c3c8d7e97d1d1253b6d4ea6d44c150f741f1bf4431";
+  return absl::HexStringToBytes(encapsulated_key);
+}
+
+bssl::UniquePtr<EVP_HPKE_KEY> ConstructHpkeKey(
+    absl::string_view hpke_key,
+    const ObliviousHttpHeaderKeyConfig &ohttp_key_config) {
+  bssl::UniquePtr<EVP_HPKE_KEY> bssl_hpke_key(EVP_HPKE_KEY_new());
+  EXPECT_NE(bssl_hpke_key, nullptr);
+  EXPECT_TRUE(EVP_HPKE_KEY_init(
+      bssl_hpke_key.get(), ohttp_key_config.GetHpkeKem(),
+      reinterpret_cast<const uint8_t *>(hpke_key.data()), hpke_key.size()));
+  return bssl_hpke_key;
+}
+
+const ObliviousHttpHeaderKeyConfig GetOhttpKeyConfig(uint8_t key_id,
+                                                     uint16_t kem_id,
+                                                     uint16_t kdf_id,
+                                                     uint16_t aead_id) {
+  auto ohttp_key_config =
+      ObliviousHttpHeaderKeyConfig::Create(key_id, kem_id, kdf_id, aead_id);
+  EXPECT_TRUE(ohttp_key_config.ok());
+  return std::move(ohttp_key_config.value());
+}
+}  // namespace
+
+// Direct test example from OHttp spec.
+// https://www.ietf.org/archive/id/draft-ietf-ohai-ohttp-03.html#appendix-A
+TEST(ObliviousHttpRequest, TestDecapsulateWithSpecAppendixAExample) {
+  auto ohttp_key_config =
+      GetOhttpKeyConfig(/*key_id=*/1, EVP_HPKE_DHKEM_X25519_HKDF_SHA256,
+                        EVP_HPKE_HKDF_SHA256, EVP_HPKE_AES_128_GCM);
+
+  // X25519 Secret key (priv key).
+  // https://www.ietf.org/archive/id/draft-ietf-ohai-ohttp-03.html#appendix-A-2
+  constexpr absl::string_view kX25519SecretKey =
+      "3c168975674b2fa8e465970b79c8dcf09f1c741626480bd4c6162fc5b6a98e1a";
+
+  // Encapsulated request.
+  // https://www.ietf.org/archive/id/draft-ietf-ohai-ohttp-03.html#appendix-A-14
+  constexpr absl::string_view kEncapsulatedRequest =
+      "010020000100014b28f881333e7c164ffc499ad9796f877f4e1051ee6d31bad19dec96c2"
+      "08b4726374e469135906992e1268c594d2a10c695d858c40a026e7965e7d86b83dd440b2"
+      "c0185204b4d63525";
+
+  // Initialize Request obj to Decapsulate (decrypt).
+  auto instance = ObliviousHttpRequest::CreateServerObliviousRequest(
+      absl::HexStringToBytes(kEncapsulatedRequest),
+      *(ConstructHpkeKey(absl::HexStringToBytes(kX25519SecretKey),
+                         ohttp_key_config)),
+      ohttp_key_config);
+  ASSERT_TRUE(instance.ok());
+  auto decrypted = instance->GetPlaintextData();
+
+  // Encapsulated/Ephemeral public key.
+  // https://www.ietf.org/archive/id/draft-ietf-ohai-ohttp-03.html#appendix-A-10
+  constexpr absl::string_view kExpectedEphemeralPublicKey =
+      "4b28f881333e7c164ffc499ad9796f877f4e1051ee6d31bad19dec96c208b472";
+  EXPECT_EQ(instance->oblivious_http_request_context()->encapsulated_key_,
+            absl::HexStringToBytes(kExpectedEphemeralPublicKey));
+
+  // Binary HTTP message.
+  // https://www.ietf.org/archive/id/draft-ietf-ohai-ohttp-03.html#appendix-A-6
+  constexpr absl::string_view kExpectedBinaryHTTPMessage =
+      "00034745540568747470730b6578616d706c652e636f6d012f";
+  EXPECT_EQ(decrypted, absl::HexStringToBytes(kExpectedBinaryHTTPMessage));
+}
+
+TEST(ObliviousHttpRequest, TestEncapsulatedRequestStructure) {
+  uint8_t test_key_id = 7;
+  uint16_t test_kem_id = EVP_HPKE_DHKEM_X25519_HKDF_SHA256;
+  uint16_t test_kdf_id = EVP_HPKE_HKDF_SHA256;
+  uint16_t test_aead_id = EVP_HPKE_AES_256_GCM;
+  absl::string_view plaintext = "test";
+  auto instance = ObliviousHttpRequest::CreateClientObliviousRequest(
+      plaintext, GetHpkePublicKey(),
+      GetOhttpKeyConfig(test_key_id, test_kem_id, test_kdf_id, test_aead_id));
+  ASSERT_TRUE(instance.ok());
+  auto payload_bytes = instance->EncapsulateAndSerialize();
+  EXPECT_GE(payload_bytes.size(), kHeaderLength);
+  // Parse header.
+  QuicheDataReader reader(payload_bytes);
+  uint8_t key_id;
+  EXPECT_TRUE(reader.ReadUInt8(&key_id));
+  EXPECT_EQ(key_id, test_key_id);
+  uint16_t kem_id;
+  EXPECT_TRUE(reader.ReadUInt16(&kem_id));
+  EXPECT_EQ(kem_id, test_kem_id);
+  uint16_t kdf_id;
+  EXPECT_TRUE(reader.ReadUInt16(&kdf_id));
+  EXPECT_EQ(kdf_id, test_kdf_id);
+  uint16_t aead_id;
+  EXPECT_TRUE(reader.ReadUInt16(&aead_id));
+  EXPECT_EQ(aead_id, test_aead_id);
+  auto client_encapsulated_key =
+      instance->oblivious_http_request_context()->encapsulated_key_;
+  EXPECT_EQ(client_encapsulated_key.size(), X25519_PUBLIC_VALUE_LEN);
+  auto enc_key_plus_ciphertext = payload_bytes.substr(kHeaderLength);
+  auto packed_encapsulated_key =
+      enc_key_plus_ciphertext.substr(0, X25519_PUBLIC_VALUE_LEN);
+  EXPECT_EQ(packed_encapsulated_key, client_encapsulated_key);
+  auto ciphertext = enc_key_plus_ciphertext.substr(X25519_PUBLIC_VALUE_LEN);
+  EXPECT_GE(ciphertext.size(), plaintext.size());
+}
+
+TEST(ObliviousHttpRequest, TestDeterministicSeededOhttpRequest) {
+  auto ohttp_key_config =
+      GetOhttpKeyConfig(4, EVP_HPKE_DHKEM_X25519_HKDF_SHA256,
+                        EVP_HPKE_HKDF_SHA256, EVP_HPKE_AES_256_GCM);
+  auto encapsulated = CreateClientObliviousRequestWithSeedForTesting(
+      "test", GetHpkePublicKey(), ohttp_key_config, GetSeed());
+  ASSERT_TRUE(encapsulated.ok());
+  EXPECT_EQ(encapsulated->oblivious_http_request_context()->encapsulated_key_,
+            GetSeededEncapsulatedKey());
+  absl::string_view expected_encrypted_request =
+      "9f37cfed07d0111ecd2c34f794671759bcbd922a";
+  EXPECT_NE(encapsulated->oblivious_http_request_context()->hpke_context_,
+            nullptr);
+  size_t encapsulated_key_len = EVP_HPKE_KEM_enc_len(EVP_HPKE_CTX_kem(
+      encapsulated->oblivious_http_request_context()->hpke_context_.get()));
+  int encrypted_payload_offset = kHeaderLength + encapsulated_key_len;
+  EXPECT_EQ(
+      encapsulated->EncapsulateAndSerialize().substr(encrypted_payload_offset),
+      absl::HexStringToBytes(expected_encrypted_request));
+}
+
+TEST(ObliviousHttpRequest,
+     TestSeededEncapsulatedKeySamePlaintextsSameCiphertexts) {
+  auto ohttp_key_config =
+      GetOhttpKeyConfig(8, EVP_HPKE_DHKEM_X25519_HKDF_SHA256,
+                        EVP_HPKE_HKDF_SHA256, EVP_HPKE_AES_256_GCM);
+  auto req_with_same_plaintext_1 =
+      CreateClientObliviousRequestWithSeedForTesting(
+          "same plaintext", GetHpkePublicKey(), ohttp_key_config, GetSeed());
+  ASSERT_TRUE(req_with_same_plaintext_1.ok());
+  auto ciphertext_1 = req_with_same_plaintext_1->EncapsulateAndSerialize();
+  auto req_with_same_plaintext_2 =
+      CreateClientObliviousRequestWithSeedForTesting(
+          "same plaintext", GetHpkePublicKey(), ohttp_key_config, GetSeed());
+  ASSERT_TRUE(req_with_same_plaintext_2.ok());
+  auto ciphertext_2 = req_with_same_plaintext_2->EncapsulateAndSerialize();
+  EXPECT_EQ(ciphertext_1, ciphertext_2);
+}
+
+TEST(ObliviousHttpRequest,
+     TestSeededEncapsulatedKeyDifferentPlaintextsDifferentCiphertexts) {
+  auto ohttp_key_config =
+      GetOhttpKeyConfig(8, EVP_HPKE_DHKEM_X25519_HKDF_SHA256,
+                        EVP_HPKE_HKDF_SHA256, EVP_HPKE_AES_256_GCM);
+  auto req_with_different_plaintext_1 =
+      CreateClientObliviousRequestWithSeedForTesting(
+          "different 1", GetHpkePublicKey(), ohttp_key_config, GetSeed());
+  ASSERT_TRUE(req_with_different_plaintext_1.ok());
+  auto ciphertext_1 = req_with_different_plaintext_1->EncapsulateAndSerialize();
+  auto req_with_different_plaintext_2 =
+      CreateClientObliviousRequestWithSeedForTesting(
+          "different 2", GetHpkePublicKey(), ohttp_key_config, GetSeed());
+  ASSERT_TRUE(req_with_different_plaintext_2.ok());
+  auto ciphertext_2 = req_with_different_plaintext_2->EncapsulateAndSerialize();
+  EXPECT_NE(ciphertext_1, ciphertext_2);
+}
+
+TEST(ObliviousHttpRequest, TestInvalidInputsOnClientSide) {
+  auto ohttp_key_config =
+      GetOhttpKeyConfig(30, EVP_HPKE_DHKEM_X25519_HKDF_SHA256,
+                        EVP_HPKE_HKDF_SHA256, EVP_HPKE_AES_256_GCM);
+  // Empty plaintext.
+  EXPECT_EQ(ObliviousHttpRequest::CreateClientObliviousRequest(
+                /*plaintext_payload*/ "", GetHpkePublicKey(), ohttp_key_config)
+                .status()
+                .code(),
+            absl::StatusCode::kInvalidArgument);
+  // Empty HPKE public key.
+  EXPECT_EQ(ObliviousHttpRequest::CreateClientObliviousRequest(
+                "some plaintext",
+                /*hpke_public_key*/ "", ohttp_key_config)
+                .status()
+                .code(),
+            absl::StatusCode::kInvalidArgument);
+}
+
+TEST(ObliviousHttpRequest, TestInvalidInputsOnServerSide) {
+  auto ohttp_key_config =
+      GetOhttpKeyConfig(4, EVP_HPKE_DHKEM_X25519_HKDF_SHA256,
+                        EVP_HPKE_HKDF_SHA256, EVP_HPKE_AES_256_GCM);
+  // Empty encrypted payload.
+  EXPECT_EQ(ObliviousHttpRequest::CreateServerObliviousRequest(
+                /*encrypted_data*/ "",
+                *(ConstructHpkeKey(GetHpkePrivateKey(), ohttp_key_config)),
+                ohttp_key_config)
+                .status()
+                .code(),
+            absl::StatusCode::kInvalidArgument);
+  // Empty EVP_HPKE_KEY struct.
+  EXPECT_EQ(ObliviousHttpRequest::CreateServerObliviousRequest(
+                absl::StrCat(ohttp_key_config.SerializeOhttpPayloadHeader(),
+                             GetSeededEncapsulatedKey(),
+                             "9f37cfed07d0111ecd2c34f794671759bcbd922a"),
+                /*gateway_key*/ {}, ohttp_key_config)
+                .status()
+                .code(),
+            absl::StatusCode::kInvalidArgument);
+}
+
+TEST(ObliviousHttpRequest, EndToEndTestForRequest) {
+  auto ohttp_key_config =
+      GetOhttpKeyConfig(5, EVP_HPKE_DHKEM_X25519_HKDF_SHA256,
+                        EVP_HPKE_HKDF_SHA256, EVP_HPKE_AES_256_GCM);
+  auto encapsulate = ObliviousHttpRequest::CreateClientObliviousRequest(
+      "test", GetHpkePublicKey(), ohttp_key_config);
+  ASSERT_TRUE(encapsulate.ok());
+  auto oblivious_request = encapsulate->EncapsulateAndSerialize();
+  auto decapsulate = ObliviousHttpRequest::CreateServerObliviousRequest(
+      oblivious_request,
+      *(ConstructHpkeKey(GetHpkePrivateKey(), ohttp_key_config)),
+      ohttp_key_config);
+  ASSERT_TRUE(decapsulate.ok());
+  auto decrypted = decapsulate->GetPlaintextData();
+  EXPECT_EQ(decrypted, "test");
+}
+
+}  // namespace quiche
diff --git a/quiche/oblivious_http/buffers/oblivious_http_response.cc b/quiche/oblivious_http/buffers/oblivious_http_response.cc
new file mode 100644
index 0000000..4ab7092
--- /dev/null
+++ b/quiche/oblivious_http/buffers/oblivious_http_response.cc
@@ -0,0 +1,352 @@
+#include "quiche/oblivious_http/buffers/oblivious_http_response.h"
+
+#include <stddef.h>
+#include <stdint.h>
+
+#include <algorithm>
+#include <memory>
+#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/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/oblivious_http/common/oblivious_http_header_key_config.h"
+
+namespace quiche {
+namespace {
+// Generate a random string.
+std::string random(QuicheRandom* quiche_random, size_t len) {
+  std::string token(len, '\0');
+  if (quiche_random == nullptr) {
+    quiche_random = QuicheRandom::GetInstance();
+  }
+  quiche_random->RandBytes(token.data(), token.size());
+  return token;
+}
+}  // namespace
+
+// Ctor.
+ObliviousHttpResponse::ObliviousHttpResponse(std::string resp_nonce,
+                                             std::string resp_ciphertext,
+                                             std::string resp_plaintext)
+    : response_nonce_(resp_nonce),
+      response_ciphertext_(resp_ciphertext),
+      response_plaintext_(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.ietf.org/archive/id/draft-ietf-ohai-ohttp-03.html#section-4.2-4
+absl::StatusOr<ObliviousHttpResponse>
+ObliviousHttpResponse::CreateClientObliviousResponse(
+    absl::string_view encrypted_data,
+    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 "
+        "Decapsulation on Client-side.");
+  }
+  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()));
+  }
+  if (encrypted_data.empty()) {
+    return absl::InvalidArgumentError("Empty encrypted_data input param.");
+  }
+
+  absl::StatusOr<CommonAeadParamsResult> aead_params_st =
+      GetCommonAeadParams(oblivious_http_request_context);
+  if (!aead_params_st.ok()) {
+    return aead_params_st.status();
+  }
+
+  // secret_len = [max(Nn, Nk)] where Nk and Nn are the length of AEAD
+  // key and nonce associated with HPKE context.
+  // https://www.ietf.org/archive/id/draft-ietf-ohai-ohttp-03.html#section-4.2-2.1
+  size_t secret_len = aead_params_st.value().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.ietf.org/archive/id/draft-ietf-ohai-ohttp-03.html#section-4.2-2.2
+  absl::string_view response_nonce = encrypted_data.substr(0, secret_len);
+  absl::string_view encrypted_response = encrypted_data.substr(secret_len);
+
+  // Steps (1, 3 to 5) + AEAD context SetUp before 6th step is performed in
+  // CommonOperations.
+  auto common_ops_st = CommonOperationsToEncapDecap(
+      response_nonce, oblivious_http_request_context,
+      aead_params_st.value().aead_key_len,
+      aead_params_st.value().aead_nonce_len, aead_params_st.value().secret_len);
+  if (!common_ops_st.ok()) {
+    return common_ops_st.status();
+  }
+
+  std::string decrypted(encrypted_response.size(), '\0');
+  size_t decrypted_len;
+
+  // Decrypt with initialized AEAD context.
+  // response, error = Open(aead_key, aead_nonce, "", ct)
+  // https://www.ietf.org/archive/id/draft-ietf-ohai-ohttp-03.html#section-4.2-6
+  if (!EVP_AEAD_CTX_open(
+          common_ops_st.value().aead_ctx.get(),
+          reinterpret_cast<uint8_t*>(decrypted.data()), &decrypted_len,
+          decrypted.size(),
+          reinterpret_cast<const uint8_t*>(
+              common_ops_st.value().aead_nonce.data()),
+          aead_params_st.value().aead_nonce_len,
+          reinterpret_cast<const uint8_t*>(encrypted_response.data()),
+          encrypted_response.size(), nullptr, 0)) {
+    return SslErrorAsStatus(
+        "Failed to decrypt the response with derived AEAD key and nonce.");
+  }
+  decrypted.resize(decrypted_len);
+  ObliviousHttpResponse oblivious_response(
+      std::string(response_nonce), std::string(encrypted_response), decrypted);
+  return std::move(oblivious_response);
+}
+
+// Response Encapsulation.
+// Follows the Ohttp spec section-4.2 (Encapsulation of Responses) Ref
+// https://www.ietf.org/archive/id/draft-ietf-ohai-ohttp-03.html#section-4.2
+// 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(
+    absl::string_view plaintext_payload,
+    ObliviousHttpRequest::Context& oblivious_http_request_context,
+    QuicheRandom* quiche_random) {
+  if (oblivious_http_request_context.hpke_context_ == nullptr) {
+    return absl::FailedPreconditionError(
+        "HPKE context wasn't initialized before proceeding with this Response "
+        "Encapsulation on Server-side.");
+  }
+  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()));
+  }
+  if (plaintext_payload.empty()) {
+    return absl::InvalidArgumentError("Empty plaintext_payload input param.");
+  }
+  absl::StatusOr<CommonAeadParamsResult> aead_params_st =
+      GetCommonAeadParams(oblivious_http_request_context);
+  if (!aead_params_st.ok()) {
+    return aead_params_st.status();
+  }
+  // response_nonce = random(max(Nn, Nk))
+  // https://www.ietf.org/archive/id/draft-ietf-ohai-ohttp-03.html#section-4.2-2.2
+  std::string response_nonce(random(quiche_random, aead_params_st->secret_len));
+
+  // Steps (1, 3 to 5) + AEAD context SetUp before 6th step is performed in
+  // CommonOperations.
+  auto common_ops_st = CommonOperationsToEncapDecap(
+      response_nonce, oblivious_http_request_context,
+      aead_params_st.value().aead_key_len,
+      aead_params_st.value().aead_nonce_len, aead_params_st.value().secret_len);
+  if (!common_ops_st.ok()) {
+    return common_ops_st.status();
+  }
+
+  // ct = Seal(aead_key, aead_nonce, "", response)
+  // https://www.ietf.org/archive/id/draft-ietf-ohai-ohttp-03.html#section-4.2-2.6
+  std::string ciphertext(
+      plaintext_payload.size() +
+          EVP_AEAD_max_overhead(EVP_HPKE_AEAD_aead(EVP_HPKE_CTX_aead(
+              oblivious_http_request_context.hpke_context_.get()))),
+      '\0');
+  size_t ciphertext_len;
+  if (!EVP_AEAD_CTX_seal(
+          common_ops_st.value().aead_ctx.get(),
+          reinterpret_cast<uint8_t*>(ciphertext.data()), &ciphertext_len,
+          ciphertext.size(),
+          reinterpret_cast<const uint8_t*>(
+              common_ops_st.value().aead_nonce.data()),
+          aead_params_st.value().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.");
+  }
+  ciphertext.resize(ciphertext_len);
+  if (response_nonce.empty() || ciphertext.empty()) {
+    return absl::InternalError(absl::StrCat(
+        "ObliviousHttpResponse Object wasn't initialized with required fields.",
+        (response_nonce.empty() ? "Generated nonce is empty." : ""),
+        (ciphertext.empty() ? "Generated Encrypted payload is empty." : "")));
+  }
+  ObliviousHttpResponse oblivious_response(response_nonce, ciphertext,
+                                           std::string(plaintext_payload));
+  return std::move(oblivious_response);
+}
+
+// Serialize.
+// enc_response = concat(response_nonce, ct)
+// https://www.ietf.org/archive/id/draft-ietf-ohai-ohttp-03.html#section-4.2-4
+std::string ObliviousHttpResponse::EncapsulateAndSerialize() const {
+  return absl::StrCat(response_nonce_, response_ciphertext_);
+}
+
+// Decrypted blob.
+absl::string_view 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) {
+  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 std::move(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 spec.
+// https://www.ietf.org/archive/id/draft-ietf-ohai-ohttp-03.html#section-4.2-4
+absl::StatusOr<ObliviousHttpResponse::CommonOperationsResult>
+ObliviousHttpResponse::CommonOperationsToEncapDecap(
+    absl::string_view response_nonce,
+    ObliviousHttpRequest::Context& oblivious_http_request_context,
+    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.ietf.org/archive/id/draft-ietf-ohai-ohttp-03.html#section-4.2-2.1
+  std::string secret(secret_len, '\0');
+  absl::string_view resp_label =
+      ObliviousHttpHeaderKeyConfig::kOhttpResponseLabel;
+  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.ietf.org/archive/id/draft-ietf-ohai-ohttp-03.html#section-4.2-2.3
+  std::string salt = absl::StrCat(
+      oblivious_http_request_context.encapsulated_key_, response_nonce);
+
+  // prk = Extract(salt, secret)
+  // https://www.ietf.org/archive/id/draft-ietf-ohai-ohttp-03.html#section-4.2-2.3
+  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.ietf.org/archive/id/draft-ietf-ohai-ohttp-03.html#section-4.2-2.4
+  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.ietf.org/archive/id/draft-ietf-ohai-ohttp-03.html#section-4.2-2.5
+  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 std::move(result);
+}
+
+}  // namespace quiche
diff --git a/quiche/oblivious_http/buffers/oblivious_http_response.h b/quiche/oblivious_http/buffers/oblivious_http_response.h
new file mode 100644
index 0000000..3ebd25d
--- /dev/null
+++ b/quiche/oblivious_http/buffers/oblivious_http_response.h
@@ -0,0 +1,97 @@
+#ifndef QUICHE_OBLIVIOUS_HTTP_BUFFERS_OBLIVIOUS_HTTP_RESPONSE_H_
+#define QUICHE_OBLIVIOUS_HTTP_BUFFERS_OBLIVIOUS_HTTP_RESPONSE_H_
+
+#include <stddef.h>
+
+#include <string>
+
+#include "absl/status/statusor.h"
+#include "absl/strings/string_view.h"
+#include "quiche/common/quiche_random.h"
+#include "quiche/oblivious_http/buffers/oblivious_http_request.h"
+
+namespace quiche {
+
+class QUICHE_EXPORT_PRIVATE ObliviousHttpResponse {
+ public:
+  // Parse and decrypt the OHttp response using ObliviousHttpContext context obj
+  // that was returned from `CreateClientObliviousRequest` method. On success,
+  // returns obj that callers will use to `GetDecryptedMessage`.
+  // @params: Note that `oblivious_http_request_context` is required to stay
+  // alive only for the lifetime of this factory method call.
+  static absl::StatusOr<ObliviousHttpResponse> CreateClientObliviousResponse(
+      absl::string_view encrypted_data,
+      ObliviousHttpRequest::Context& oblivious_http_request_context);
+
+  // Encrypt the input param `plaintext_payload` and create OHttp response using
+  // ObliviousHttpContext context obj that was returned from
+  // `CreateServerObliviousRequest` method. On success, returns obj that callers
+  // will use to `Serialize` OHttp response. Generic Usecase : server-side calls
+  // this method in the context of Response.
+  // @params: Note that `oblivious_http_request_context` is required to stay
+  // alive only for the lifetime of this factory method call.
+  // @params: If callers do not provide `quiche_random`, it will be initialized
+  // to default supplied `QuicheRandom::GetInstance()`. It's recommended that
+  // callers initialize `QuicheRandom* quiche_random` as a Singleton instance
+  // within their code and pass in the same, in order to have optimized random
+  // string generation. `quiche_random` is required to stay alive only for the
+  // lifetime of this factory method call.
+  static absl::StatusOr<ObliviousHttpResponse> CreateServerObliviousResponse(
+      absl::string_view plaintext_payload,
+      ObliviousHttpRequest::Context& oblivious_http_request_context,
+      QuicheRandom* quiche_random = nullptr);
+
+  // Copyable.
+  ObliviousHttpResponse(const ObliviousHttpResponse& other) = default;
+  ObliviousHttpResponse& operator=(const ObliviousHttpResponse& other) =
+      default;
+
+  // Movable.
+  ObliviousHttpResponse(ObliviousHttpResponse&& other) = default;
+  ObliviousHttpResponse& operator=(ObliviousHttpResponse&& other) = default;
+
+  ~ObliviousHttpResponse() = default;
+
+  // Generic Usecase : server-side calls this method in the context of Response
+  // to serialize OHTTP response that will be returned to client-side.
+  // Returns serialized OHTTP response bytestring.
+  std::string EncapsulateAndSerialize() const;
+
+  absl::string_view GetPlaintextData() const;
+
+ private:
+  struct CommonAeadParamsResult {
+    const EVP_AEAD* evp_hpke_aead;
+    const size_t aead_key_len;
+    const size_t aead_nonce_len;
+    const size_t secret_len;
+  };
+
+  struct CommonOperationsResult {
+    bssl::UniquePtr<EVP_AEAD_CTX> aead_ctx;
+    const std::string aead_nonce;
+  };
+
+  explicit ObliviousHttpResponse(std::string resp_nonce,
+                                 std::string resp_ciphertext,
+                                 std::string resp_plaintext);
+
+  // Determines AEAD key len(Nk), AEAD nonce len(Nn) based on HPKE context and
+  // further estimates secret_len = std::max(Nk, Nn)
+  static absl::StatusOr<CommonAeadParamsResult> GetCommonAeadParams(
+      ObliviousHttpRequest::Context& oblivious_http_request_context);
+  // Performs operations related to response handling that are common between
+  // client and server.
+  static absl::StatusOr<CommonOperationsResult> CommonOperationsToEncapDecap(
+      absl::string_view response_nonce,
+      ObliviousHttpRequest::Context& oblivious_http_request_context,
+      const size_t aead_key_len, const size_t aead_nonce_len,
+      const size_t secret_len);
+  std::string response_nonce_;
+  std::string response_ciphertext_;
+  std::string response_plaintext_;
+};
+
+}  // namespace quiche
+
+#endif  // QUICHE_OBLIVIOUS_HTTP_BUFFERS_OBLIVIOUS_HTTP_RESPONSE_H_
diff --git a/quiche/oblivious_http/buffers/oblivious_http_response_test.cc b/quiche/oblivious_http/buffers/oblivious_http_response_test.cc
new file mode 100644
index 0000000..775ba56
--- /dev/null
+++ b/quiche/oblivious_http/buffers/oblivious_http_response_test.cc
@@ -0,0 +1,220 @@
+#include "quiche/oblivious_http/buffers/oblivious_http_response.h"
+
+#include <stddef.h>
+#include <stdint.h>
+#include <string.h>
+
+#include <memory>
+#include <string>
+#include <utility>
+
+#include "absl/status/statusor.h"
+#include "absl/strings/escaping.h"
+#include "absl/strings/str_cat.h"
+#include "absl/strings/string_view.h"
+#include "openssl/hpke.h"
+#include "quiche/common/platform/api/quiche_test.h"
+#include "quiche/oblivious_http/buffers/oblivious_http_request.h"
+
+namespace quiche {
+
+absl::StatusOr<ObliviousHttpRequest>
+CreateClientObliviousRequestWithSeedForTesting(
+    absl::string_view plaintext_payload, absl::string_view hpke_public_key,
+    const ObliviousHttpHeaderKeyConfig &ohttp_key_config,
+    absl::string_view seed) {
+  return ObliviousHttpRequest::EncapsulateWithSeed(
+      plaintext_payload, hpke_public_key, ohttp_key_config, seed);
+}
+
+namespace {
+std::string GetHpkePrivateKey() {
+  absl::string_view hpke_key_hex =
+      "b77431ecfa8f4cfc30d6e467aafa06944dffe28cb9dd1409e33a3045f5adc8a1";
+  return absl::HexStringToBytes(hpke_key_hex);
+}
+
+std::string GetHpkePublicKey() {
+  absl::string_view public_key =
+      "6d21cfe09fbea5122f9ebc2eb2a69fcc4f06408cd54aac934f012e76fcdcef62";
+  return absl::HexStringToBytes(public_key);
+}
+
+std::string GetSeed() {
+  absl::string_view seed =
+      "52c4a758a802cd8b936eceea314432798d5baf2d7e9235dc084ab1b9cfa2f736";
+  return absl::HexStringToBytes(seed);
+}
+
+std::string GetSeededEncapsulatedKey() {
+  absl::string_view encapsulated_key =
+      "37fda3567bdbd628e88668c3c8d7e97d1d1253b6d4ea6d44c150f741f1bf4431";
+  return absl::HexStringToBytes(encapsulated_key);
+}
+
+const ObliviousHttpHeaderKeyConfig GetOhttpKeyConfig(uint8_t key_id,
+                                                     uint16_t kem_id,
+                                                     uint16_t kdf_id,
+                                                     uint16_t aead_id) {
+  auto ohttp_key_config =
+      ObliviousHttpHeaderKeyConfig::Create(key_id, kem_id, kdf_id, aead_id);
+  EXPECT_TRUE(ohttp_key_config.ok());
+  return std::move(ohttp_key_config.value());
+}
+
+bssl::UniquePtr<EVP_HPKE_CTX> GetSeededClientContext(uint8_t key_id,
+                                                     uint16_t kem_id,
+                                                     uint16_t kdf_id,
+                                                     uint16_t aead_id) {
+  bssl::UniquePtr<EVP_HPKE_CTX> client_ctx(EVP_HPKE_CTX_new());
+  std::string encapsulated_key(EVP_HPKE_MAX_ENC_LENGTH, '\0');
+  size_t enc_len;
+  std::string info = GetOhttpKeyConfig(key_id, kem_id, kdf_id, aead_id)
+                         .SerializeRecipientContextInfo();
+
+  EXPECT_TRUE(EVP_HPKE_CTX_setup_sender_with_seed_for_testing(
+      client_ctx.get(), reinterpret_cast<uint8_t *>(encapsulated_key.data()),
+      &enc_len, encapsulated_key.size(), EVP_hpke_x25519_hkdf_sha256(),
+      EVP_hpke_hkdf_sha256(), EVP_hpke_aes_256_gcm(),
+      reinterpret_cast<const uint8_t *>(GetHpkePublicKey().data()),
+      GetHpkePublicKey().size(), reinterpret_cast<const uint8_t *>(info.data()),
+      info.size(), reinterpret_cast<const uint8_t *>(GetSeed().data()),
+      GetSeed().size()));
+  encapsulated_key.resize(enc_len);
+  EXPECT_EQ(encapsulated_key, GetSeededEncapsulatedKey());
+  return client_ctx;
+}
+
+bssl::UniquePtr<EVP_HPKE_KEY> ConstructHpkeKey(
+    absl::string_view hpke_key,
+    const ObliviousHttpHeaderKeyConfig &ohttp_key_config) {
+  bssl::UniquePtr<EVP_HPKE_KEY> bssl_hpke_key(EVP_HPKE_KEY_new());
+  EXPECT_NE(bssl_hpke_key, nullptr);
+  EXPECT_TRUE(EVP_HPKE_KEY_init(
+      bssl_hpke_key.get(), ohttp_key_config.GetHpkeKem(),
+      reinterpret_cast<const uint8_t *>(hpke_key.data()), hpke_key.size()));
+  return bssl_hpke_key;
+}
+
+const ObliviousHttpRequest SetUpObliviousHttpContext(
+    uint8_t key_id, uint16_t kem_id, uint16_t kdf_id, uint16_t aead_id,
+    absl::string_view plaintext) {
+  auto ohttp_key_config = GetOhttpKeyConfig(key_id, kem_id, kdf_id, aead_id);
+  auto client_request_encapsulate =
+      CreateClientObliviousRequestWithSeedForTesting(
+          plaintext, GetHpkePublicKey(), ohttp_key_config, GetSeed());
+  EXPECT_TRUE(client_request_encapsulate.ok());
+  auto oblivious_request =
+      client_request_encapsulate->EncapsulateAndSerialize();
+  auto server_request_decapsulate =
+      ObliviousHttpRequest::CreateServerObliviousRequest(
+          oblivious_request,
+          *(ConstructHpkeKey(GetHpkePrivateKey(), ohttp_key_config)),
+          ohttp_key_config);
+  EXPECT_TRUE(server_request_decapsulate.ok());
+  return std::move(server_request_decapsulate.value());
+}
+
+// QuicheRandom implementation.
+// Just fills the buffer with repeated chars that's initialized in seed.
+class TestQuicheRandom : public QuicheRandom {
+ public:
+  TestQuicheRandom(char seed) : seed_(seed) {}
+  ~TestQuicheRandom() override {}
+
+  void RandBytes(void *data, size_t len) override { memset(data, seed_, len); }
+
+  uint64_t RandUint64() override {
+    uint64_t random_int;
+    memset(&random_int, seed_, sizeof(random_int));
+    return random_int;
+  }
+
+  void InsecureRandBytes(void *data, size_t len) override {
+    return RandBytes(data, len);
+  }
+  uint64_t InsecureRandUint64() override { return RandUint64(); }
+
+ private:
+  char seed_;
+};
+
+size_t GetResponseNonceLength(const EVP_HPKE_CTX &hpke_context) {
+  EXPECT_NE(&hpke_context, nullptr);
+  const EVP_AEAD *evp_hpke_aead =
+      EVP_HPKE_AEAD_aead(EVP_HPKE_CTX_aead(&hpke_context));
+  EXPECT_NE(evp_hpke_aead, nullptr);
+  // Nk = [AEAD key len], is determined by BSSL.
+  const size_t aead_key_len = EVP_AEAD_key_length(evp_hpke_aead);
+  // Nn = [AEAD nonce len], is determined by BSSL.
+  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);
+  return secret_len;
+}
+
+TEST(ObliviousHttpResponse, TestDecapsulateReceivedResponse) {
+  // Construct encrypted payload with plaintext: "test response"
+  absl::string_view encrypted_response =
+      "39d5b03c02c97e216df444e4681007105974d4df1585aae05e7b53f3ccdb55d51f711d48"
+      "eeefbc1a555d6d928e35df33fd23c23846fa7b083e30692f7b";
+  auto decapsulated = ObliviousHttpResponse::CreateClientObliviousResponse(
+      absl::HexStringToBytes(encrypted_response),
+      *(SetUpObliviousHttpContext(4, EVP_HPKE_DHKEM_X25519_HKDF_SHA256,
+                                  EVP_HPKE_HKDF_SHA256, EVP_HPKE_AES_256_GCM,
+                                  "test")
+            .oblivious_http_request_context()));
+  EXPECT_TRUE(decapsulated.ok());
+  auto decrypted = decapsulated->GetPlaintextData();
+  EXPECT_EQ(decrypted, "test response");
+}
+}  // namespace
+
+TEST(ObliviousHttpResponse, EndToEndTestForResponse) {
+  auto oblivious_ctx = ObliviousHttpRequest::Context(
+      GetSeededClientContext(5, EVP_HPKE_DHKEM_X25519_HKDF_SHA256,
+                             EVP_HPKE_HKDF_SHA256, EVP_HPKE_AES_256_GCM),
+      GetSeededEncapsulatedKey());
+  auto server_response_encapsulate =
+      ObliviousHttpResponse::CreateServerObliviousResponse("test response",
+                                                           oblivious_ctx);
+  EXPECT_TRUE(server_response_encapsulate.ok());
+  auto oblivious_response =
+      server_response_encapsulate->EncapsulateAndSerialize();
+  auto client_response_encapsulate =
+      ObliviousHttpResponse::CreateClientObliviousResponse(oblivious_response,
+                                                           oblivious_ctx);
+  auto decrypted = client_response_encapsulate->GetPlaintextData();
+  EXPECT_EQ(decrypted, "test response");
+}
+
+TEST(ObliviousHttpResponse, TestEncapsulateWithQuicheRandom) {
+  auto random = TestQuicheRandom('z');
+  auto server_seeded_request = SetUpObliviousHttpContext(
+      6, EVP_HPKE_DHKEM_X25519_HKDF_SHA256, EVP_HPKE_HKDF_SHA256,
+      EVP_HPKE_AES_256_GCM, "test");
+  auto server_response_encapsulate =
+      ObliviousHttpResponse::CreateServerObliviousResponse(
+          "test response",
+          *(server_seeded_request.oblivious_http_request_context()), &random);
+  EXPECT_TRUE(server_response_encapsulate.ok());
+  std::string response_nonce =
+      server_response_encapsulate->EncapsulateAndSerialize().substr(
+          0, GetResponseNonceLength(
+                 *(server_seeded_request.oblivious_http_request_context()
+                       ->hpke_context_)));
+  EXPECT_EQ(
+      response_nonce,
+      std::string(GetResponseNonceLength(
+                      *(server_seeded_request.oblivious_http_request_context()
+                            ->hpke_context_)),
+                  'z'));
+  absl::string_view expected_encrypted_response =
+      "2a3271ac4e6a501f51d0264d3dd7d0bc8a06973b58e89c26d6dac06144";
+  EXPECT_EQ(server_response_encapsulate->EncapsulateAndSerialize().substr(
+                GetResponseNonceLength(
+                    *(server_seeded_request.oblivious_http_request_context()
+                          ->hpke_context_))),
+            absl::HexStringToBytes(expected_encrypted_response));
+}
+
+}  // namespace quiche
diff --git a/quiche/oblivious_http/common/oblivious_http_header_key_config.cc b/quiche/oblivious_http/common/oblivious_http_header_key_config.cc
new file mode 100644
index 0000000..d378b4c
--- /dev/null
+++ b/quiche/oblivious_http/common/oblivious_http_header_key_config.cc
@@ -0,0 +1,282 @@
+#include "quiche/oblivious_http/common/oblivious_http_header_key_config.h"
+
+#include <cstdint>
+
+#include "absl/memory/memory.h"
+#include "absl/status/status.h"
+#include "absl/strings/str_cat.h"
+#include "absl/strings/string_view.h"
+#include "openssl/base.h"
+#include "openssl/hpke.h"
+#include "quiche/common/platform/api/quiche_logging.h"
+#include "quiche/common/quiche_data_writer.h"
+#include "quiche/common/quiche_endian.h"
+
+namespace quiche {
+namespace {
+
+absl::StatusOr<const EVP_HPKE_KEM*> CheckKemId(uint16_t kem_id) {
+  switch (kem_id) {
+    case EVP_HPKE_DHKEM_X25519_HKDF_SHA256:
+      return EVP_hpke_x25519_hkdf_sha256();
+    default:
+      return absl::UnimplementedError("No support for this KEM ID.");
+  }
+}
+
+absl::StatusOr<const EVP_HPKE_KDF*> CheckKdfId(uint16_t kdf_id) {
+  switch (kdf_id) {
+    case EVP_HPKE_HKDF_SHA256:
+      return EVP_hpke_hkdf_sha256();
+    default:
+      return absl::UnimplementedError("No support for this KDF ID.");
+  }
+}
+
+absl::StatusOr<const EVP_HPKE_AEAD*> CheckAeadId(uint16_t aead_id) {
+  switch (aead_id) {
+    case EVP_HPKE_AES_128_GCM:
+      return EVP_hpke_aes_128_gcm();
+    case EVP_HPKE_AES_256_GCM:
+      return EVP_hpke_aes_256_gcm();
+    case EVP_HPKE_CHACHA20_POLY1305:
+      return EVP_hpke_chacha20_poly1305();
+    default:
+      return absl::UnimplementedError("No support for this AEAD ID.");
+  }
+}
+
+}  // namespace
+
+ObliviousHttpHeaderKeyConfig::ObliviousHttpHeaderKeyConfig(uint8_t key_id,
+                                                           uint16_t kem_id,
+                                                           uint16_t kdf_id,
+                                                           uint16_t aead_id)
+    : key_id_(key_id), kem_id_(kem_id), kdf_id_(kdf_id), aead_id_(aead_id) {}
+
+absl::StatusOr<ObliviousHttpHeaderKeyConfig>
+ObliviousHttpHeaderKeyConfig::Create(uint8_t key_id, uint16_t kem_id,
+                                     uint16_t kdf_id, uint16_t aead_id) {
+  ObliviousHttpHeaderKeyConfig instance(key_id, kem_id, kdf_id, aead_id);
+  auto is_config_ok = instance.ValidateKeyConfig();
+  if (!is_config_ok.ok()) {
+    return is_config_ok;
+  }
+  return instance;
+}
+
+absl::Status ObliviousHttpHeaderKeyConfig::ValidateKeyConfig() const {
+  auto supported_kem = CheckKemId(kem_id_);
+  if (!supported_kem.ok()) {
+    return absl::InvalidArgumentError(
+        absl::StrCat("Unsupported KEM ID:", kem_id_));
+  }
+  auto supported_kdf = CheckKdfId(kdf_id_);
+  if (!supported_kdf.ok()) {
+    return absl::InvalidArgumentError(
+        absl::StrCat("Unsupported KDF ID:", kdf_id_));
+  }
+  auto supported_aead = CheckAeadId(aead_id_);
+  if (!supported_aead.ok()) {
+    return absl::InvalidArgumentError(
+        absl::StrCat("Unsupported AEAD ID:", aead_id_));
+  }
+  return absl::OkStatus();
+}
+
+const EVP_HPKE_KEM* ObliviousHttpHeaderKeyConfig::GetHpkeKem() const {
+  auto kem = CheckKemId(kem_id_);
+  QUICHE_CHECK_OK(kem.status());
+  return kem.value();
+}
+const EVP_HPKE_KDF* ObliviousHttpHeaderKeyConfig::GetHpkeKdf() const {
+  auto kdf = CheckKdfId(kdf_id_);
+  QUICHE_CHECK_OK(kdf.status());
+  return kdf.value();
+}
+const EVP_HPKE_AEAD* ObliviousHttpHeaderKeyConfig::GetHpkeAead() const {
+  auto aead = CheckAeadId(aead_id_);
+  QUICHE_CHECK_OK(aead.status());
+  return aead.value();
+}
+
+std::string ObliviousHttpHeaderKeyConfig::SerializeRecipientContextInfo()
+    const {
+  uint8_t zero_byte = 0x00;
+  int buf_len = kOhttpRequestLabel.size() + kHeaderLength + sizeof(zero_byte);
+  std::string info(buf_len, '\0');
+  QuicheDataWriter writer(info.size(), info.data());
+  QUICHE_CHECK(writer.WriteStringPiece(kOhttpRequestLabel));
+  QUICHE_CHECK(writer.WriteUInt8(zero_byte));  // Zero byte.
+  QUICHE_CHECK(writer.WriteUInt8(key_id_));
+  QUICHE_CHECK(writer.WriteUInt16(kem_id_));
+  QUICHE_CHECK(writer.WriteUInt16(kdf_id_));
+  QUICHE_CHECK(writer.WriteUInt16(aead_id_));
+  return info;
+}
+
+/**
+ * Follows IETF Ohttp spec, section 4.1 (Encapsulation of Requests).
+ * https://www.ietf.org/archive/id/draft-ietf-ohai-ohttp-03.html#section-4.1-10
+ */
+absl::Status ObliviousHttpHeaderKeyConfig::ParseOhttpPayloadHeader(
+    absl::string_view payload_bytes) const {
+  if (payload_bytes.empty()) {
+    return absl::InvalidArgumentError("Empty request payload.");
+  }
+  QuicheDataReader reader(payload_bytes);
+  uint8_t key_id;
+  if (!reader.ReadUInt8(&key_id)) {
+    return absl::InvalidArgumentError("Failed to read key_id from header.");
+  }
+  if (key_id != key_id_) {
+    return absl::InvalidArgumentError(
+        absl::StrCat("KeyID in request:", static_cast<uint16_t>(key_id),
+                     " doesn't match with server's public key "
+                     "configuration KeyID:",
+                     static_cast<uint16_t>(key_id_)));
+  }
+  uint16_t kem_id;
+  if (!reader.ReadUInt16(&kem_id)) {
+    return absl::InvalidArgumentError("Failed to read kem_id from header.");
+  }
+  if (kem_id != kem_id_) {
+    return absl::InvalidArgumentError(
+        absl::StrCat("Received Invalid kemID:", kem_id, " Expected:", kem_id_));
+  }
+  uint16_t kdf_id;
+  if (!reader.ReadUInt16(&kdf_id)) {
+    return absl::InvalidArgumentError("Failed to read kdf_id from header.");
+  }
+  if (kdf_id != kdf_id_) {
+    return absl::InvalidArgumentError(
+        absl::StrCat("Received Invalid kdfID:", kdf_id, " Expected:", kdf_id_));
+  }
+  uint16_t aead_id;
+  if (!reader.ReadUInt16(&aead_id)) {
+    return absl::InvalidArgumentError("Failed to read aead_id from header.");
+  }
+  if (aead_id != aead_id_) {
+    return absl::InvalidArgumentError(absl::StrCat(
+        "Received Invalid aeadID:", aead_id, " Expected:", aead_id_));
+  }
+  return absl::OkStatus();
+}
+
+absl::StatusOr<uint8_t>
+ObliviousHttpHeaderKeyConfig::ParseKeyIdFromObliviousHttpRequestPayload(
+    absl::string_view payload_bytes) {
+  if (payload_bytes.empty()) {
+    return absl::InvalidArgumentError("Empty request payload.");
+  }
+  QuicheDataReader reader(payload_bytes);
+  uint8_t key_id;
+  if (!reader.ReadUInt8(&key_id)) {
+    return absl::InvalidArgumentError("Failed to read key_id from payload.");
+  }
+  return key_id;
+}
+
+std::string ObliviousHttpHeaderKeyConfig::SerializeOhttpPayloadHeader() const {
+  int buf_len =
+      sizeof(key_id_) + sizeof(kem_id_) + sizeof(kdf_id_) + sizeof(aead_id_);
+  std::string hdr(buf_len, '\0');
+  QuicheDataWriter writer(hdr.size(), hdr.data());
+  QUICHE_CHECK(writer.WriteUInt8(key_id_));
+  QUICHE_CHECK(writer.WriteUInt16(kem_id_));   // kemID
+  QUICHE_CHECK(writer.WriteUInt16(kdf_id_));   // kdfID
+  QUICHE_CHECK(writer.WriteUInt16(aead_id_));  // aeadID
+  return hdr;
+}
+
+absl::StatusOr<ObliviousHttpKeyConfigs>
+ObliviousHttpKeyConfigs::ParseConcatenatedKeys(absl::string_view key_config) {
+  ConfigMap configs;
+  PublicKeyMap keys;
+  auto reader = QuicheDataReader(key_config);
+  while (!reader.IsDoneReading()) {
+    absl::Status status = ReadSingleKeyConfig(reader, configs, keys);
+    if (!status.ok()) return status;
+  }
+  return ObliviousHttpKeyConfigs(std::move(configs), std::move(keys));
+}
+
+ObliviousHttpHeaderKeyConfig ObliviousHttpKeyConfigs::PreferredConfig() const {
+  // configs_ is forced to have at least one object during construction.
+  return configs_.begin()->second.front();
+}
+
+absl::StatusOr<absl::string_view> ObliviousHttpKeyConfigs::GetPublicKeyForId(
+    uint8_t key_id) const {
+  auto key = public_keys_.find(key_id);
+  if (key == public_keys_.end()) {
+    return absl::NotFoundError("No public key found for key_id");
+  }
+  return key->second;
+}
+
+namespace {
+// https://www.rfc-editor.org/rfc/rfc9180#section-7.1
+// TODO(kmg): Switch to BoringSSL's EVP_HPKE_KEM_public_key_len()
+// https://boringssl-review.googlesource.com/c/boringssl/+/54605
+absl::StatusOr<uint16_t> KeyLength(uint16_t kem_id) {
+  switch (kem_id) {
+    case EVP_HPKE_DHKEM_X25519_HKDF_SHA256:
+      return 32;
+    default:
+      return absl::InvalidArgumentError(
+          "Unsupported kem_id; public key length is unknown.");
+  }
+}
+}  // namespace
+
+absl::Status ObliviousHttpKeyConfigs::ReadSingleKeyConfig(
+    QuicheDataReader& reader, ConfigMap& configs, PublicKeyMap& keys) {
+  uint8_t key_id;
+  uint16_t kem_id;
+  // First byte: key_id; next two bytes: kem_id.
+  if (!reader.ReadUInt8(&key_id) || !reader.ReadUInt16(&kem_id)) {
+    return absl::InvalidArgumentError("Invalid key_config!");
+  }
+
+  // Public key length depends on the kem_id.
+  auto maybe_key_length = KeyLength(kem_id);
+  if (!maybe_key_length.ok()) {
+    return maybe_key_length.status();
+  }
+  const int key_length = maybe_key_length.value();
+  std::string key_str(key_length, '\0');
+  if (!reader.ReadBytes(key_str.data(), key_length)) {
+    return absl::InvalidArgumentError("Invalid key_config!");
+  }
+  if (!keys.insert({key_id, std::move(key_str)}).second) {
+    return absl::InvalidArgumentError("Duplicate key_id's in key_config!");
+  }
+
+  // Extract the algorithms for this public key.
+  absl::string_view alg_bytes;
+  // Read the 16-bit length, then read that many bytes into alg_bytes.
+  if (!reader.ReadStringPiece16(&alg_bytes)) {
+    return absl::InvalidArgumentError("Invalid key_config!");
+  }
+  QuicheDataReader sub_reader(alg_bytes);
+  while (!sub_reader.IsDoneReading()) {
+    uint16_t kdf_id;
+    uint16_t aead_id;
+    if (!sub_reader.ReadUInt16(&kdf_id) || !sub_reader.ReadUInt16(&aead_id)) {
+      return absl::InvalidArgumentError("Invalid key_config!");
+    }
+
+    absl::StatusOr<ObliviousHttpHeaderKeyConfig> maybe_cfg =
+        ObliviousHttpHeaderKeyConfig::Create(key_id, kem_id, kdf_id, aead_id);
+    if (!maybe_cfg.ok()) {
+      // TODO(kmg): Add support to ignore key types in the server response that
+      // aren't supported by the client.
+      return maybe_cfg.status();
+    }
+    configs[key_id].emplace_back(std::move(maybe_cfg.value()));
+  }
+  return absl::OkStatus();
+}
+
+}  // namespace quiche
diff --git a/quiche/oblivious_http/common/oblivious_http_header_key_config.h b/quiche/oblivious_http/common/oblivious_http_header_key_config.h
new file mode 100644
index 0000000..1c89bc3
--- /dev/null
+++ b/quiche/oblivious_http/common/oblivious_http_header_key_config.h
@@ -0,0 +1,150 @@
+#ifndef QUICHE_OBLIVIOUS_HTTP_COMMON_OBLIVIOUS_HTTP_HEADER_KEY_CONFIG_H_
+#define QUICHE_OBLIVIOUS_HTTP_COMMON_OBLIVIOUS_HTTP_HEADER_KEY_CONFIG_H_
+
+#include <stdint.h>
+
+#include "absl/container/btree_map.h"
+#include "absl/container/flat_hash_map.h"
+#include "absl/status/status.h"
+#include "absl/status/statusor.h"
+#include "absl/strings/string_view.h"
+#include "openssl/base.h"
+#include "quiche/common/platform/api/quiche_export.h"
+#include "quiche/common/quiche_data_reader.h"
+
+namespace quiche {
+
+class QUICHE_EXPORT_PRIVATE ObliviousHttpHeaderKeyConfig {
+ public:
+  // https://www.ietf.org/archive/id/draft-ietf-ohai-ohttp-03.html#section-4.1-4.2
+  static constexpr absl::string_view kOhttpRequestLabel =
+      "message/bhttp request";
+  static constexpr absl::string_view kOhttpResponseLabel =
+      "message/bhttp response";
+  // Length of the Oblivious HTTP header.
+  static constexpr uint32_t kHeaderLength =
+      sizeof(uint8_t) + (3 * sizeof(uint16_t));
+  static constexpr absl::string_view kKeyHkdfInfo = "key";
+  static constexpr absl::string_view kNonceHkdfInfo = "nonce";
+
+  static absl::StatusOr<ObliviousHttpHeaderKeyConfig> Create(uint8_t key_id,
+                                                             uint16_t kem_id,
+                                                             uint16_t kdf_id,
+                                                             uint16_t aead_id);
+
+  // Copyable to support stack allocated pass-by-value for trivial data members.
+  ObliviousHttpHeaderKeyConfig(const ObliviousHttpHeaderKeyConfig& other) =
+      default;
+  ObliviousHttpHeaderKeyConfig& operator=(
+      const ObliviousHttpHeaderKeyConfig& other) = default;
+
+  // Movable.
+  ObliviousHttpHeaderKeyConfig(ObliviousHttpHeaderKeyConfig&& other) = default;
+  ObliviousHttpHeaderKeyConfig& operator=(
+      ObliviousHttpHeaderKeyConfig&& other) = default;
+
+  ~ObliviousHttpHeaderKeyConfig() = default;
+
+  const EVP_HPKE_KEM* GetHpkeKem() const;
+  const EVP_HPKE_KDF* GetHpkeKdf() const;
+  const EVP_HPKE_AEAD* GetHpkeAead() const;
+
+  uint8_t GetKeyId() const { return key_id_; }
+  uint16_t GetHpkeKemId() const { return kem_id_; }
+  uint16_t GetHpkeKdfId() const { return kdf_id_; }
+  uint16_t GetHpkeAeadId() const { return aead_id_; }
+
+  // Build HPKE context info ["message/bhttp request", 0x00, keyID(1 byte),
+  // kemID(2 bytes), kdfID(2 bytes), aeadID(2 bytes)] in network byte order and
+  // return a sequence of bytes(bytestring).
+  // https://www.ietf.org/archive/id/draft-ietf-ohai-ohttp-03.html#section-4.1-10
+  std::string SerializeRecipientContextInfo() const;
+
+  // TODO(anov): Replace with ObliviousRequest/Response abstraction
+  // Parses the below Header
+  // [keyID(1 byte), kemID(2 bytes), kdfID(2 bytes), aeadID(2 bytes)]
+  // from the payload received in Ohttp Request, and verifies that these values
+  // match with the info stored in `this` namely [key_id_, kem_id_, kdf_id_,
+  // aead_id_]
+  // https://www.ietf.org/archive/id/draft-ietf-ohai-ohttp-03.html#section-4.1-7
+  absl::Status ParseOhttpPayloadHeader(absl::string_view payload_bytes) const;
+
+  // Extracts Key ID from the OHTTP Request payload.
+  static absl::StatusOr<uint8_t> ParseKeyIdFromObliviousHttpRequestPayload(
+      absl::string_view payload_bytes);
+
+  // Build Request header according to network byte order and return string.
+  std::string SerializeOhttpPayloadHeader() const;
+
+ private:
+  // Constructor
+  explicit ObliviousHttpHeaderKeyConfig(uint8_t key_id, uint16_t kem_id,
+                                        uint16_t kdf_id, uint16_t aead_id);
+
+  // Helps validate Key configuration for supported schemes.
+  absl::Status ValidateKeyConfig() const;
+
+  // Public Key configuration hosted by Gateway to facilitate Oblivious HTTP
+  // HPKE encryption.
+  // https://www.ietf.org/archive/id/draft-ietf-ohai-ohttp-03.html#name-key-configuration-encoding
+  uint8_t key_id_;
+  uint16_t kem_id_;
+  uint16_t kdf_id_;
+  uint16_t aead_id_;
+};
+
+// Contains multiple ObliviousHttpHeaderKeyConfig objects and associated private
+// keys.  An ObliviousHttpHeaderKeyConfigs object can be constructed from the
+// "Key Configuration" defined in the Oblivious HTTP spec.  Multiple key
+// configurations maybe be supported by the server.
+//
+// See https://www.ietf.org/archive/id/draft-ietf-ohai-ohttp-04.html#section-3
+// for details of the "Key Configuration" spec.
+//
+// ObliviousHttpKeyConfigs objects are immutable after construction.
+class QUICHE_EXPORT_PRIVATE ObliviousHttpKeyConfigs {
+ public:
+  // Parses the "application/ohttp-keys" media type, which is a byte string
+  // formatted according to the spec:
+  // https://www.ietf.org/archive/id/draft-ietf-ohai-ohttp-04.html#section-3
+  static absl::StatusOr<ObliviousHttpKeyConfigs> ParseConcatenatedKeys(
+      absl::string_view key_configs);
+
+  int NumKeys() const { return public_keys_.size(); }
+
+  // Returns a preferred config to use.  The preferred key is the key with
+  // the highest key_id.  If more than one configuration exists for the
+  // preferred key any configuration may be returned.
+  //
+  // These methods are useful in the (common) case where only one key
+  // configuration is supported by the server.
+  ObliviousHttpHeaderKeyConfig PreferredConfig() const;
+
+  absl::StatusOr<absl::string_view> GetPublicKeyForId(uint8_t key_id) const;
+
+  // TODO(kmg): Add methods to somehow access other non-preferred key
+  // configurations.
+
+ private:
+  using PublicKeyMap = absl::flat_hash_map<uint8_t, std::string>;
+  using ConfigMap =
+      absl::btree_map<uint8_t, std::vector<ObliviousHttpHeaderKeyConfig>,
+                      std::greater<uint8_t>>;
+
+  ObliviousHttpKeyConfigs(ConfigMap cm, PublicKeyMap km)
+      : configs_(std::move(cm)), public_keys_(std::move(km)) {}
+
+  static absl::Status ReadSingleKeyConfig(QuicheDataReader& reader,
+                                          ConfigMap& configs,
+                                          PublicKeyMap& keys);
+
+  // A mapping from key_id to ObliviousHttpHeaderKeyConfig objects for that key.
+  const ConfigMap configs_;
+
+  // A mapping from key_id to the public key for that key_id.
+  const PublicKeyMap public_keys_;
+};
+
+}  // namespace quiche
+
+#endif  // QUICHE_OBLIVIOUS_HTTP_COMMON_OBLIVIOUS_HTTP_HEADER_KEY_CONFIG_H_
diff --git a/quiche/oblivious_http/common/oblivious_http_header_key_config_test.cc b/quiche/oblivious_http/common/oblivious_http_header_key_config_test.cc
new file mode 100644
index 0000000..0227ee4
--- /dev/null
+++ b/quiche/oblivious_http/common/oblivious_http_header_key_config_test.cc
@@ -0,0 +1,202 @@
+#include "quiche/oblivious_http/common/oblivious_http_header_key_config.h"
+
+#include <cstdint>
+
+#include "absl/strings/escaping.h"
+#include "openssl/hpke.h"
+#include "quiche/common/platform/api/quiche_logging.h"
+#include "quiche/common/platform/api/quiche_test.h"
+#include "quiche/common/quiche_data_writer.h"
+
+namespace quiche {
+namespace {
+using ::testing::AllOf;
+using ::testing::Property;
+using ::testing::StrEq;
+
+/**
+ * Build Request header.
+ */
+std::string BuildHeader(uint8_t key_id, uint16_t kem_id, uint16_t kdf_id,
+                        uint16_t aead_id) {
+  int buf_len =
+      sizeof(key_id) + sizeof(kem_id) + sizeof(kdf_id) + sizeof(aead_id);
+  std::string hdr(buf_len, '\0');
+  QuicheDataWriter writer(hdr.size(), hdr.data());
+  EXPECT_TRUE(writer.WriteUInt8(key_id));
+  EXPECT_TRUE(writer.WriteUInt16(kem_id));   // kemID
+  EXPECT_TRUE(writer.WriteUInt16(kdf_id));   // kdfID
+  EXPECT_TRUE(writer.WriteUInt16(aead_id));  // aeadID
+  return hdr;
+}
+
+TEST(ObliviousHttpHeaderKeyConfig, TestSerializeRecipientContextInfo) {
+  uint8_t key_id = 3;
+  uint16_t kem_id = EVP_HPKE_DHKEM_X25519_HKDF_SHA256;
+  uint16_t kdf_id = EVP_HPKE_HKDF_SHA256;
+  uint16_t aead_id = EVP_HPKE_AES_256_GCM;
+  absl::string_view ohttp_req_label = "message/bhttp request";
+  std::string expected(ohttp_req_label);
+  uint8_t zero_byte = 0x00;
+  int buf_len = ohttp_req_label.size() + sizeof(zero_byte) + sizeof(key_id) +
+                sizeof(kem_id) + sizeof(kdf_id) + sizeof(aead_id);
+  expected.reserve(buf_len);
+  expected.push_back(zero_byte);
+  std::string ohttp_cfg(BuildHeader(key_id, kem_id, kdf_id, aead_id));
+  expected.insert(expected.end(), ohttp_cfg.begin(), ohttp_cfg.end());
+  auto instance =
+      ObliviousHttpHeaderKeyConfig::Create(key_id, kem_id, kdf_id, aead_id);
+  ASSERT_TRUE(instance.ok());
+  EXPECT_EQ(instance.value().SerializeRecipientContextInfo(), expected);
+}
+
+TEST(ObliviousHttpHeaderKeyConfig, TestValidKeyConfig) {
+  auto valid_key_config = ObliviousHttpHeaderKeyConfig::Create(
+      2, EVP_HPKE_DHKEM_X25519_HKDF_SHA256, EVP_HPKE_HKDF_SHA256,
+      EVP_HPKE_AES_256_GCM);
+  ASSERT_TRUE(valid_key_config.ok());
+}
+
+TEST(ObliviousHttpHeaderKeyConfig, TestInvalidKeyConfig) {
+  auto invalid_kem = ObliviousHttpHeaderKeyConfig::Create(
+      3, 0, EVP_HPKE_HKDF_SHA256, EVP_HPKE_AES_256_GCM);
+  EXPECT_EQ(invalid_kem.status().code(), absl::StatusCode::kInvalidArgument);
+  auto invalid_kdf = ObliviousHttpHeaderKeyConfig::Create(
+      3, EVP_HPKE_DHKEM_X25519_HKDF_SHA256, 0, EVP_HPKE_AES_256_GCM);
+  EXPECT_EQ(invalid_kdf.status().code(), absl::StatusCode::kInvalidArgument);
+  auto invalid_aead = ObliviousHttpHeaderKeyConfig::Create(
+      3, EVP_HPKE_DHKEM_X25519_HKDF_SHA256, EVP_HPKE_HKDF_SHA256, 0);
+  EXPECT_EQ(invalid_kdf.status().code(), absl::StatusCode::kInvalidArgument);
+}
+
+TEST(ObliviousHttpHeaderKeyConfig, TestParsingValidHeader) {
+  auto instance = ObliviousHttpHeaderKeyConfig::Create(
+      5, EVP_HPKE_DHKEM_X25519_HKDF_SHA256, EVP_HPKE_HKDF_SHA256,
+      EVP_HPKE_AES_256_GCM);
+  ASSERT_TRUE(instance.ok());
+  std::string good_hdr(BuildHeader(5, EVP_HPKE_DHKEM_X25519_HKDF_SHA256,
+                                   EVP_HPKE_HKDF_SHA256, EVP_HPKE_AES_256_GCM));
+  ASSERT_TRUE(instance.value().ParseOhttpPayloadHeader(good_hdr).ok());
+}
+
+TEST(ObliviousHttpHeaderKeyConfig, TestParsingInvalidHeader) {
+  auto instance = ObliviousHttpHeaderKeyConfig::Create(
+      8, EVP_HPKE_DHKEM_X25519_HKDF_SHA256, EVP_HPKE_HKDF_SHA256,
+      EVP_HPKE_AES_256_GCM);
+  ASSERT_TRUE(instance.ok());
+  std::string keyid_mismatch_hdr(
+      BuildHeader(0, EVP_HPKE_DHKEM_X25519_HKDF_SHA256, EVP_HPKE_HKDF_SHA256,
+                  EVP_HPKE_AES_256_GCM));
+  EXPECT_EQ(instance.value().ParseOhttpPayloadHeader(keyid_mismatch_hdr).code(),
+            absl::StatusCode::kInvalidArgument);
+  std::string invalid_hpke_hdr(BuildHeader(8, 0, 0, 0));
+  EXPECT_EQ(instance.value().ParseOhttpPayloadHeader(invalid_hpke_hdr).code(),
+            absl::StatusCode::kInvalidArgument);
+}
+
+TEST(ObliviousHttpHeaderKeyConfig, TestParsingKeyIdFromObliviousHttpRequest) {
+  std::string key_id(sizeof(uint8_t), '\0');
+  QuicheDataWriter writer(key_id.size(), key_id.data());
+  EXPECT_TRUE(writer.WriteUInt8(99));
+  auto parsed_key_id =
+      ObliviousHttpHeaderKeyConfig::ParseKeyIdFromObliviousHttpRequestPayload(
+          key_id);
+  ASSERT_TRUE(parsed_key_id.ok());
+  EXPECT_EQ(parsed_key_id.value(), 99);
+}
+
+TEST(ObliviousHttpHeaderKeyConfig, TestCopyable) {
+  auto obj1 = ObliviousHttpHeaderKeyConfig::Create(
+      4, EVP_HPKE_DHKEM_X25519_HKDF_SHA256, EVP_HPKE_HKDF_SHA256,
+      EVP_HPKE_AES_256_GCM);
+  ASSERT_TRUE(obj1.ok());
+  auto copy_obj1_to_obj2 = obj1.value();
+  EXPECT_EQ(copy_obj1_to_obj2.kHeaderLength, obj1->kHeaderLength);
+  EXPECT_EQ(copy_obj1_to_obj2.SerializeRecipientContextInfo(),
+            obj1->SerializeRecipientContextInfo());
+}
+
+TEST(ObliviousHttpHeaderKeyConfig, TestSerializeOhttpPayloadHeader) {
+  auto instance = ObliviousHttpHeaderKeyConfig::Create(
+      7, EVP_HPKE_DHKEM_X25519_HKDF_SHA256, EVP_HPKE_HKDF_SHA256,
+      EVP_HPKE_AES_128_GCM);
+  ASSERT_TRUE(instance.ok());
+  EXPECT_EQ(instance->SerializeOhttpPayloadHeader(),
+            BuildHeader(7, EVP_HPKE_DHKEM_X25519_HKDF_SHA256,
+                        EVP_HPKE_HKDF_SHA256, EVP_HPKE_AES_128_GCM));
+}
+
+MATCHER_P(HasKeyId, id, "") {
+  *result_listener << "has key_id=" << arg.GetKeyId();
+  return arg.GetKeyId() == id;
+}
+MATCHER_P(HasKemId, id, "") {
+  *result_listener << "has kem_id=" << arg.GetHpkeKemId();
+  return arg.GetHpkeKemId() == id;
+}
+MATCHER_P(HasKdfId, id, "") {
+  *result_listener << "has kdf_id=" << arg.GetHpkeKdfId();
+  return arg.GetHpkeKdfId() == id;
+}
+MATCHER_P(HasAeadId, id, "") {
+  *result_listener << "has aead_id=" << arg.GetHpkeAeadId();
+  return arg.GetHpkeAeadId() == id;
+}
+
+TEST(ObliviousHttpKeyConfigs, SingleKeyConfig) {
+  std::string key = absl::HexStringToBytes(
+      "4b0020f83e0a17cbdb18d2684dd2a9b087a43e5f3fa3fa27a049bc746a6e97a1e0244b00"
+      "0400010002");
+  auto configs = ObliviousHttpKeyConfigs::ParseConcatenatedKeys(key).value();
+  EXPECT_THAT(configs, Property(&ObliviousHttpKeyConfigs::NumKeys, 1));
+  EXPECT_THAT(
+      configs.PreferredConfig(),
+      AllOf(HasKeyId(0x4b), HasKemId(EVP_HPKE_DHKEM_X25519_HKDF_SHA256),
+            HasKdfId(EVP_HPKE_HKDF_SHA256), HasAeadId(EVP_HPKE_AES_256_GCM)));
+  EXPECT_THAT(
+      configs.GetPublicKeyForId(configs.PreferredConfig().GetKeyId()).value(),
+      StrEq(absl::HexStringToBytes(
+          "f83e0a17cbdb18d2684dd2a9b087a43e5f3fa3fa27a049bc746a6e97a1e0244b")));
+}
+
+TEST(ObliviousHttpKeyConfigs, TwoSimilarKeyConfigs) {
+  std::string key = absl::HexStringToBytes(
+      "4b0020f83e0a17cbdb18d2684dd2a9b087a43e5f3fa3fa27a049bc746a6e97a1e0244b00"
+      "0400010002"  // Intentional concatenation
+      "4f0020f83e0a17cbdb18d2684dd2a9b087a43e5f3fa3fa27a049bc746a6e97a1e0244b00"
+      "0400010001");
+  EXPECT_THAT(ObliviousHttpKeyConfigs::ParseConcatenatedKeys(key).value(),
+              Property(&ObliviousHttpKeyConfigs::NumKeys, 2));
+  EXPECT_THAT(
+      ObliviousHttpKeyConfigs::ParseConcatenatedKeys(key)->PreferredConfig(),
+      AllOf(HasKeyId(0x4f), HasKemId(EVP_HPKE_DHKEM_X25519_HKDF_SHA256),
+            HasKdfId(EVP_HPKE_HKDF_SHA256), HasAeadId(EVP_HPKE_AES_128_GCM)));
+}
+
+TEST(ObliviousHttpKeyConfigs, RFCExample) {
+  std::string key = absl::HexStringToBytes(
+      "01002031e1f05a740102115220e9af918f738674aec95f54db6e04eb705aae8e79815500"
+      "080001000100010003");
+  auto configs = ObliviousHttpKeyConfigs::ParseConcatenatedKeys(key).value();
+  EXPECT_THAT(configs, Property(&ObliviousHttpKeyConfigs::NumKeys, 1));
+  EXPECT_THAT(
+      configs.PreferredConfig(),
+      AllOf(HasKeyId(0x01), HasKemId(EVP_HPKE_DHKEM_X25519_HKDF_SHA256),
+            HasKdfId(EVP_HPKE_HKDF_SHA256), HasAeadId(EVP_HPKE_AES_128_GCM)));
+  EXPECT_THAT(
+      configs.GetPublicKeyForId(configs.PreferredConfig().GetKeyId()).value(),
+      StrEq(absl::HexStringToBytes(
+          "31e1f05a740102115220e9af918f738674aec95f54db6e04eb705aae8e798155")));
+}
+
+TEST(ObliviousHttpKeyConfigs, DuplicateKeyId) {
+  std::string key = absl::HexStringToBytes(
+      "4b0020f83e0a17cbdb18d2684dd2a9b087a43e5f3fa3fa27a049bc746a6e97a1e0244b00"
+      "0400010002"  // Intentional concatenation
+      "4b0020f83e0a17cbdb18d2684dd2a9b087a43e5f3fa3fb27a049bc746a6e97a1e0244b00"
+      "0400010001");
+  EXPECT_FALSE(ObliviousHttpKeyConfigs::ParseConcatenatedKeys(key).ok());
+}
+
+}  // namespace
+}  // namespace quiche
diff --git a/quiche/oblivious_http/oblivious_http_client.cc b/quiche/oblivious_http/oblivious_http_client.cc
new file mode 100644
index 0000000..5bbf74c
--- /dev/null
+++ b/quiche/oblivious_http/oblivious_http_client.cc
@@ -0,0 +1,91 @@
+#include "quiche/oblivious_http/oblivious_http_client.h"
+
+#include <stddef.h>
+#include <stdint.h>
+
+#include <memory>
+#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 "quiche/common/quiche_crypto_logging.h"
+
+namespace quiche {
+
+namespace {
+
+// Use BoringSSL's setup_sender API to validate whether the HPKE public key
+// input provided by the user is valid.
+absl::Status ValidateClientParameters(
+    absl::string_view hpke_public_key,
+    const ObliviousHttpHeaderKeyConfig& ohttp_key_config) {
+  // Initialize HPKE client context and check if context can be setup with the
+  // given public key to verify if the public key is indeed valid.
+  bssl::UniquePtr<EVP_HPKE_CTX> client_ctx(EVP_HPKE_CTX_new());
+  if (client_ctx == nullptr) {
+    return SslErrorAsStatus(
+        "Failed to initialize HPKE ObliviousHttpClientSender Context.");
+  }
+  // Setup the sender (client)
+  std::string encapsulated_key(EVP_HPKE_MAX_ENC_LENGTH, '\0');
+  size_t enc_len;
+  absl::string_view info = "verify if given HPKE public key is valid";
+  if (!EVP_HPKE_CTX_setup_sender(
+          client_ctx.get(), reinterpret_cast<uint8_t*>(encapsulated_key.data()),
+          &enc_len, encapsulated_key.size(), ohttp_key_config.GetHpkeKem(),
+          ohttp_key_config.GetHpkeKdf(), ohttp_key_config.GetHpkeAead(),
+          reinterpret_cast<const uint8_t*>(hpke_public_key.data()),
+          hpke_public_key.size(), reinterpret_cast<const uint8_t*>(info.data()),
+          info.size())) {
+    return SslErrorAsStatus(
+        "Failed to setup HPKE context with given public key param "
+        "hpke_public_key.");
+  }
+  return absl::OkStatus();
+}
+
+}  // namespace
+
+// Constructor.
+ObliviousHttpClient::ObliviousHttpClient(
+    std::string client_public_key,
+    const ObliviousHttpHeaderKeyConfig& ohttp_key_config)
+    : hpke_public_key_(std::move(client_public_key)),
+      ohttp_key_config_(ohttp_key_config) {}
+
+// Initialize Bssl.
+absl::StatusOr<ObliviousHttpClient> ObliviousHttpClient::Create(
+    absl::string_view hpke_public_key,
+    const ObliviousHttpHeaderKeyConfig& ohttp_key_config) {
+  if (hpke_public_key.empty()) {
+    return absl::InvalidArgumentError("Invalid/Empty HPKE public key.");
+  }
+  auto is_valid_input =
+      ValidateClientParameters(hpke_public_key, ohttp_key_config);
+  if (!is_valid_input.ok()) {
+    return absl::InvalidArgumentError(
+        absl::StrCat("Invalid input received in method parameters. ",
+                     is_valid_input.message()));
+  }
+  return ObliviousHttpClient(std::string(hpke_public_key), ohttp_key_config);
+}
+
+absl::StatusOr<ObliviousHttpRequest>
+ObliviousHttpClient::CreateObliviousHttpRequest(
+    absl::string_view plaintext_data) const {
+  return ObliviousHttpRequest::CreateClientObliviousRequest(
+      plaintext_data, hpke_public_key_, ohttp_key_config_);
+}
+
+absl::StatusOr<ObliviousHttpResponse>
+ObliviousHttpClient::DecryptObliviousHttpResponse(
+    absl::string_view encrypted_data,
+    ObliviousHttpRequest::Context& oblivious_http_request_context) const {
+  return ObliviousHttpResponse::CreateClientObliviousResponse(
+      encrypted_data, oblivious_http_request_context);
+}
+
+}  // namespace quiche
diff --git a/quiche/oblivious_http/oblivious_http_client.h b/quiche/oblivious_http/oblivious_http_client.h
new file mode 100644
index 0000000..10a2f60
--- /dev/null
+++ b/quiche/oblivious_http/oblivious_http_client.h
@@ -0,0 +1,80 @@
+#ifndef QUICHE_OBLIVIOUS_HTTP_OBLIVIOUS_HTTP_CLIENT_H_
+#define QUICHE_OBLIVIOUS_HTTP_OBLIVIOUS_HTTP_CLIENT_H_
+
+#include <string>
+
+#include "absl/status/statusor.h"
+#include "absl/strings/string_view.h"
+#include "openssl/base.h"
+#include "openssl/hpke.h"
+#include "quiche/common/platform/api/quiche_export.h"
+#include "quiche/oblivious_http/buffers/oblivious_http_request.h"
+#include "quiche/oblivious_http/buffers/oblivious_http_response.h"
+#include "quiche/oblivious_http/common/oblivious_http_header_key_config.h"
+
+namespace quiche {
+// 1. Facilitates client side to intiate OHttp request flow by initializing the
+// HPKE public key obtained from server, and subsequently uses it to encrypt the
+// Binary HTTP request payload.
+// 2. After initializing this class with server's HPKE public key, users can
+// call `CreateObliviousHttpRequest` which constructs OHTTP request of the input
+// payload(Binary HTTP request).
+// 3. Handles decryption of response (that's in the form of encrypted Binary
+// HTTP response) that will be sent back from Server-to-Relay and
+// Relay-to-client in HTTP POST body.
+// 4. Handles BoringSSL HPKE context setup and bookkeeping.
+
+// This class is immutable (except moves) and thus trivially thread-safe.
+class QUICHE_EXPORT_PRIVATE ObliviousHttpClient {
+ public:
+  static absl::StatusOr<ObliviousHttpClient> Create(
+      absl::string_view hpke_public_key,
+      const ObliviousHttpHeaderKeyConfig& ohttp_key_config);
+
+  // Copyable.
+  ObliviousHttpClient(const ObliviousHttpClient& other) = default;
+  ObliviousHttpClient& operator=(const ObliviousHttpClient& other) = default;
+
+  // Movable.
+  ObliviousHttpClient(ObliviousHttpClient&& other) = default;
+  ObliviousHttpClient& operator=(ObliviousHttpClient&& other) = default;
+
+  ~ObliviousHttpClient() = default;
+
+  // After successful `Create`, callers will use the returned object to
+  // repeatedly call into this method in order to create Oblivious HTTP request
+  // with the initialized HPKE public key. Call sequence: Create ->
+  // CreateObliviousHttpRequest -> DecryptObliviousHttpResponse.
+  // Eg.,
+  //   auto ohttp_client_object = ObliviousHttpClient::Create( <HPKE
+  //    public key>, <OHTTP key configuration described in
+  //    `oblivious_http_header_key_config.h`>);
+  //   auto encrypted_request1 =
+  //    ohttp_client_object.CreateObliviousHttpRequest("binary http string 1");
+  //   auto encrypted_request2 =
+  //    ohttp_client_object.CreateObliviousHttpRequest("binary http string 2");
+  absl::StatusOr<ObliviousHttpRequest> CreateObliviousHttpRequest(
+      absl::string_view plaintext_data) const;
+
+  // After `CreateObliviousHttpRequest` operation, callers on client-side will
+  // extract `oblivious_http_request_context` from the returned object
+  // `ObliviousHttpRequest` and pass in to this method in order to decrypt the
+  // response that's received from Gateway for the given request at hand.
+  absl::StatusOr<ObliviousHttpResponse> DecryptObliviousHttpResponse(
+      absl::string_view encrypted_data,
+      ObliviousHttpRequest::Context& oblivious_http_request_context) const;
+
+ private:
+  explicit ObliviousHttpClient(
+      std::string client_public_key,
+      const ObliviousHttpHeaderKeyConfig& ohttp_key_config);
+  std::string hpke_public_key_;
+  // Holds server's keyID and HPKE related IDs that's published under HPKE
+  // public Key configuration.
+  // https://www.ietf.org/archive/id/draft-ietf-ohai-ohttp-03.html#name-key-configuration
+  ObliviousHttpHeaderKeyConfig ohttp_key_config_;
+};
+
+}  // namespace quiche
+
+#endif  // QUICHE_OBLIVIOUS_HTTP_OBLIVIOUS_HTTP_CLIENT_H_
diff --git a/quiche/oblivious_http/oblivious_http_client_test.cc b/quiche/oblivious_http/oblivious_http_client_test.cc
new file mode 100644
index 0000000..0382b05
--- /dev/null
+++ b/quiche/oblivious_http/oblivious_http_client_test.cc
@@ -0,0 +1,246 @@
+#include "quiche/oblivious_http/oblivious_http_client.h"
+
+#include <stdint.h>
+
+#include <memory>
+#include <string>
+#include <utility>
+
+#include "absl/status/status.h"
+#include "absl/status/statusor.h"
+#include "absl/strings/escaping.h"
+#include "absl/strings/string_view.h"
+#include "quiche/common/platform/api/quiche_test.h"
+#include "quiche/common/platform/api/quiche_thread.h"
+
+namespace quiche {
+
+std::string GetHpkePrivateKey() {
+  // Dev/Test private key generated using Keystore.
+  absl::string_view hpke_key_hex =
+      "b77431ecfa8f4cfc30d6e467aafa06944dffe28cb9dd1409e33a3045f5adc8a1";
+  return absl::HexStringToBytes(hpke_key_hex);
+}
+
+std::string GetHpkePublicKey() {
+  // Dev/Test public key generated using Keystore.
+  absl::string_view public_key =
+      "6d21cfe09fbea5122f9ebc2eb2a69fcc4f06408cd54aac934f012e76fcdcef62";
+  return absl::HexStringToBytes(public_key);
+}
+
+const ObliviousHttpHeaderKeyConfig GetOhttpKeyConfig(uint8_t key_id,
+                                                     uint16_t kem_id,
+                                                     uint16_t kdf_id,
+                                                     uint16_t aead_id) {
+  auto ohttp_key_config =
+      ObliviousHttpHeaderKeyConfig::Create(key_id, kem_id, kdf_id, aead_id);
+  EXPECT_TRUE(ohttp_key_config.ok());
+  return std::move(ohttp_key_config.value());
+}
+
+bssl::UniquePtr<EVP_HPKE_KEY> ConstructHpkeKey(
+    absl::string_view hpke_key,
+    const ObliviousHttpHeaderKeyConfig &ohttp_key_config) {
+  bssl::UniquePtr<EVP_HPKE_KEY> bssl_hpke_key(EVP_HPKE_KEY_new());
+  EXPECT_NE(bssl_hpke_key, nullptr);
+  EXPECT_TRUE(EVP_HPKE_KEY_init(
+      bssl_hpke_key.get(), ohttp_key_config.GetHpkeKem(),
+      reinterpret_cast<const uint8_t *>(hpke_key.data()), hpke_key.size()));
+  return bssl_hpke_key;
+}
+
+TEST(ObliviousHttpClient, TestEncapsulate) {
+  auto client = ObliviousHttpClient::Create(
+      GetHpkePublicKey(),
+      GetOhttpKeyConfig(8, EVP_HPKE_DHKEM_X25519_HKDF_SHA256,
+                        EVP_HPKE_HKDF_SHA256, EVP_HPKE_AES_256_GCM));
+  ASSERT_TRUE(client.ok());
+  auto encrypted_req = client->CreateObliviousHttpRequest("test string 1");
+  ASSERT_TRUE(encrypted_req.ok());
+  auto serialized_encrypted_req = encrypted_req->EncapsulateAndSerialize();
+  ASSERT_FALSE(serialized_encrypted_req.empty());
+}
+
+TEST(ObliviousHttpClient, TestEncryptingMultipleRequestsWithSingleInstance) {
+  auto client = ObliviousHttpClient::Create(
+      GetHpkePublicKey(),
+      GetOhttpKeyConfig(1, EVP_HPKE_DHKEM_X25519_HKDF_SHA256,
+                        EVP_HPKE_HKDF_SHA256, EVP_HPKE_AES_256_GCM));
+  ASSERT_TRUE(client.ok());
+  auto ohttp_req_1 = client->CreateObliviousHttpRequest("test string 1");
+  ASSERT_TRUE(ohttp_req_1.ok());
+  auto serialized_ohttp_req_1 = ohttp_req_1->EncapsulateAndSerialize();
+  ASSERT_FALSE(serialized_ohttp_req_1.empty());
+  auto ohttp_req_2 = client->CreateObliviousHttpRequest("test string 2");
+  ASSERT_TRUE(ohttp_req_2.ok());
+  auto serialized_ohttp_req_2 = ohttp_req_2->EncapsulateAndSerialize();
+  ASSERT_FALSE(serialized_ohttp_req_2.empty());
+  EXPECT_NE(serialized_ohttp_req_1, serialized_ohttp_req_2);
+}
+
+TEST(ObliviousHttpClient, TestInvalidHPKEKey) {
+  // Invalid public key.
+  EXPECT_EQ(ObliviousHttpClient::Create(
+                "Invalid HPKE key",
+                GetOhttpKeyConfig(50, EVP_HPKE_DHKEM_X25519_HKDF_SHA256,
+                                  EVP_HPKE_HKDF_SHA256, EVP_HPKE_AES_256_GCM))
+                .status()
+                .code(),
+            absl::StatusCode::kInvalidArgument);
+  // Empty public key.
+  EXPECT_EQ(ObliviousHttpClient::Create(
+                /*hpke_public_key*/ "",
+                GetOhttpKeyConfig(50, EVP_HPKE_DHKEM_X25519_HKDF_SHA256,
+                                  EVP_HPKE_HKDF_SHA256, EVP_HPKE_AES_256_GCM))
+                .status()
+                .code(),
+            absl::StatusCode::kInvalidArgument);
+}
+
+TEST(ObliviousHttpClient,
+     TestTwoSamePlaintextsWillGenerateDifferentEncryptedPayloads) {
+  // Due to the nature of the encapsulated_key generated in HPKE being unique
+  // for every request, expect different encrypted payloads when encrypting same
+  // plaintexts.
+  auto client = ObliviousHttpClient::Create(
+      GetHpkePublicKey(),
+      GetOhttpKeyConfig(1, EVP_HPKE_DHKEM_X25519_HKDF_SHA256,
+                        EVP_HPKE_HKDF_SHA256, EVP_HPKE_AES_256_GCM));
+  ASSERT_TRUE(client.ok());
+  auto encrypted_request_1 =
+      client->CreateObliviousHttpRequest("same plaintext");
+  ASSERT_TRUE(encrypted_request_1.ok());
+  auto serialized_encrypted_request_1 =
+      encrypted_request_1->EncapsulateAndSerialize();
+  ASSERT_FALSE(serialized_encrypted_request_1.empty());
+  auto encrypted_request_2 =
+      client->CreateObliviousHttpRequest("same plaintext");
+  ASSERT_TRUE(encrypted_request_2.ok());
+  auto serialized_encrypted_request_2 =
+      encrypted_request_2->EncapsulateAndSerialize();
+  ASSERT_FALSE(serialized_encrypted_request_2.empty());
+  EXPECT_NE(serialized_encrypted_request_1, serialized_encrypted_request_2);
+}
+
+TEST(ObliviousHttpClient, TestObliviousResponseHandling) {
+  auto ohttp_key_config =
+      GetOhttpKeyConfig(1, EVP_HPKE_DHKEM_X25519_HKDF_SHA256,
+                        EVP_HPKE_HKDF_SHA256, EVP_HPKE_AES_256_GCM);
+  auto encapsulate_req_on_client =
+      ObliviousHttpRequest::CreateClientObliviousRequest(
+          "test", GetHpkePublicKey(), ohttp_key_config);
+  ASSERT_TRUE(encapsulate_req_on_client.ok());
+  auto decapsulate_req_on_gateway =
+      ObliviousHttpRequest::CreateServerObliviousRequest(
+          encapsulate_req_on_client->EncapsulateAndSerialize(),
+          *(ConstructHpkeKey(GetHpkePrivateKey(), ohttp_key_config)),
+          ohttp_key_config);
+  ASSERT_TRUE(decapsulate_req_on_gateway.ok());
+  auto encapsulate_resp_on_gateway =
+      ObliviousHttpResponse::CreateServerObliviousResponse(
+          "test response",
+          *(decapsulate_req_on_gateway->oblivious_http_request_context()));
+  ASSERT_TRUE(encapsulate_resp_on_gateway.ok());
+
+  auto client =
+      ObliviousHttpClient::Create(GetHpkePublicKey(), ohttp_key_config);
+  ASSERT_TRUE(client.ok());
+  auto decapsulate_resp_on_client = client->DecryptObliviousHttpResponse(
+      absl::string_view(encapsulate_resp_on_gateway->EncapsulateAndSerialize()),
+      *(encapsulate_req_on_client->oblivious_http_request_context()));
+  ASSERT_TRUE(decapsulate_resp_on_client.ok());
+  EXPECT_EQ(decapsulate_resp_on_client->GetPlaintextData(), "test response");
+}
+
+TEST(ObliviousHttpClient,
+     DecryptResponseReceivedByTheClientUsingServersObliviousContext) {
+  auto ohttp_key_config =
+      GetOhttpKeyConfig(1, EVP_HPKE_DHKEM_X25519_HKDF_SHA256,
+                        EVP_HPKE_HKDF_SHA256, EVP_HPKE_AES_256_GCM);
+  auto encapsulate_req_on_client =
+      ObliviousHttpRequest::CreateClientObliviousRequest(
+          "test", GetHpkePublicKey(), ohttp_key_config);
+  ASSERT_TRUE(encapsulate_req_on_client.ok());
+  auto decapsulate_req_on_gateway =
+      ObliviousHttpRequest::CreateServerObliviousRequest(
+          encapsulate_req_on_client->EncapsulateAndSerialize(),
+          *(ConstructHpkeKey(GetHpkePrivateKey(), ohttp_key_config)),
+          ohttp_key_config);
+  ASSERT_TRUE(decapsulate_req_on_gateway.ok());
+  auto encapsulate_resp_on_gateway =
+      ObliviousHttpResponse::CreateServerObliviousResponse(
+          "test response",
+          *(decapsulate_req_on_gateway->oblivious_http_request_context()));
+  ASSERT_TRUE(encapsulate_resp_on_gateway.ok());
+
+  auto client =
+      ObliviousHttpClient::Create(GetHpkePublicKey(), ohttp_key_config);
+  ASSERT_TRUE(client.ok());
+  auto decapsulate_resp_on_client = client->DecryptObliviousHttpResponse(
+      absl::string_view(encapsulate_resp_on_gateway->EncapsulateAndSerialize()),
+      *(decapsulate_req_on_gateway->oblivious_http_request_context()));
+  ASSERT_TRUE(decapsulate_resp_on_client.ok());
+  EXPECT_EQ(decapsulate_resp_on_client->GetPlaintextData(), "test response");
+}
+
+TEST(ObliviousHttpGatewayReceiver, TestWithMultipleThreads) {
+  class TestQuicheThread : public QuicheThread {
+   public:
+    TestQuicheThread(const ObliviousHttpClient& client,
+                     std::string request_payload,
+                     ObliviousHttpHeaderKeyConfig ohttp_key_config)
+        : QuicheThread("client_thread"),
+          client_(client),
+          request_payload_(request_payload),
+          ohttp_key_config_(ohttp_key_config) {}
+
+   protected:
+    void Run() override {
+      auto encrypted_request =
+          client_.CreateObliviousHttpRequest(request_payload_);
+      ASSERT_TRUE(encrypted_request.ok());
+      ASSERT_FALSE(encrypted_request->EncapsulateAndSerialize().empty());
+      // Setup recipient and get encrypted response payload.
+      auto decapsulate_req_on_gateway =
+          ObliviousHttpRequest::CreateServerObliviousRequest(
+              encrypted_request->EncapsulateAndSerialize(),
+              *(ConstructHpkeKey(GetHpkePrivateKey(), ohttp_key_config_)),
+              ohttp_key_config_);
+      ASSERT_TRUE(decapsulate_req_on_gateway.ok());
+      auto encapsulate_resp_on_gateway =
+          ObliviousHttpResponse::CreateServerObliviousResponse(
+              "test response",
+              *(decapsulate_req_on_gateway->oblivious_http_request_context()));
+      ASSERT_TRUE(encapsulate_resp_on_gateway.ok());
+      ASSERT_FALSE(
+          encapsulate_resp_on_gateway->EncapsulateAndSerialize().empty());
+
+      auto decrypted_response = client_.DecryptObliviousHttpResponse(
+          encapsulate_resp_on_gateway->EncapsulateAndSerialize(),
+          *(encrypted_request->oblivious_http_request_context()));
+      ASSERT_TRUE(decrypted_response.ok());
+      ASSERT_FALSE(decrypted_response->GetPlaintextData().empty());
+    }
+
+   private:
+    const ObliviousHttpClient& client_;
+    std::string request_payload_;
+    ObliviousHttpHeaderKeyConfig ohttp_key_config_;
+  };
+
+  auto ohttp_key_config =
+      GetOhttpKeyConfig(1, EVP_HPKE_DHKEM_X25519_HKDF_SHA256,
+                        EVP_HPKE_HKDF_SHA256, EVP_HPKE_AES_256_GCM);
+  auto client =
+      ObliviousHttpClient::Create(GetHpkePublicKey(), ohttp_key_config);
+
+  TestQuicheThread t1(*client, "test request 1", ohttp_key_config);
+  TestQuicheThread t2(*client, "test request 2", ohttp_key_config);
+  t1.Start();
+  t2.Start();
+  t1.Join();
+  t2.Join();
+}
+
+}  // namespace quiche
diff --git a/quiche/oblivious_http/oblivious_http_gateway.cc b/quiche/oblivious_http/oblivious_http_gateway.cc
new file mode 100644
index 0000000..d8a4eb0
--- /dev/null
+++ b/quiche/oblivious_http/oblivious_http_gateway.cc
@@ -0,0 +1,66 @@
+#include "quiche/oblivious_http/oblivious_http_gateway.h"
+
+#include <stdint.h>
+
+#include <memory>
+#include <utility>
+
+#include "absl/memory/memory.h"
+#include "absl/status/status.h"
+#include "absl/status/statusor.h"
+#include "absl/strings/string_view.h"
+#include "quiche/common/quiche_crypto_logging.h"
+#include "quiche/common/quiche_random.h"
+
+namespace quiche {
+
+// Constructor.
+ObliviousHttpGateway::ObliviousHttpGateway(
+    bssl::UniquePtr<EVP_HPKE_KEY> recipient_key,
+    const ObliviousHttpHeaderKeyConfig& ohttp_key_config,
+    QuicheRandom* quiche_random)
+    : server_hpke_key_(std::move(recipient_key)),
+      ohttp_key_config_(ohttp_key_config),
+      quiche_random_(quiche_random) {}
+
+// Initialize ObliviousHttpGatewayReceiver(Recipient/Server) context.
+absl::StatusOr<ObliviousHttpGateway> ObliviousHttpGateway::Create(
+    absl::string_view hpke_private_key,
+    const ObliviousHttpHeaderKeyConfig& ohttp_key_config,
+    QuicheRandom* quiche_random) {
+  if (hpke_private_key.empty()) {
+    return absl::InvalidArgumentError("Invalid/Empty HPKE private key.");
+  }
+  // Initialize HPKE key and context.
+  bssl::UniquePtr<EVP_HPKE_KEY> recipient_key(EVP_HPKE_KEY_new());
+  if (recipient_key == nullptr) {
+    return SslErrorAsStatus(
+        "Failed to initialize ObliviousHttpGatewayReceiver/Server's Key.");
+  }
+  if (!EVP_HPKE_KEY_init(
+          recipient_key.get(), ohttp_key_config.GetHpkeKem(),
+          reinterpret_cast<const uint8_t*>(hpke_private_key.data()),
+          hpke_private_key.size())) {
+    return SslErrorAsStatus("Failed to import HPKE private key.");
+  }
+  if (quiche_random == nullptr) quiche_random = QuicheRandom::GetInstance();
+  return ObliviousHttpGateway(std::move(recipient_key), ohttp_key_config,
+                              quiche_random);
+}
+
+absl::StatusOr<ObliviousHttpRequest>
+ObliviousHttpGateway::DecryptObliviousHttpRequest(
+    absl::string_view encrypted_data) const {
+  return ObliviousHttpRequest::CreateServerObliviousRequest(
+      encrypted_data, *(server_hpke_key_), ohttp_key_config_);
+}
+
+absl::StatusOr<ObliviousHttpResponse>
+ObliviousHttpGateway::CreateObliviousHttpResponse(
+    absl::string_view plaintext_data,
+    ObliviousHttpRequest::Context& oblivious_http_request_context) const {
+  return ObliviousHttpResponse::CreateServerObliviousResponse(
+      plaintext_data, oblivious_http_request_context, quiche_random_);
+}
+
+}  // namespace quiche
diff --git a/quiche/oblivious_http/oblivious_http_gateway.h b/quiche/oblivious_http/oblivious_http_gateway.h
new file mode 100644
index 0000000..8f70356
--- /dev/null
+++ b/quiche/oblivious_http/oblivious_http_gateway.h
@@ -0,0 +1,82 @@
+#ifndef QUICHE_OBLIVIOUS_HTTP_OBLIVIOUS_HTTP_GATEWAY_H_
+#define QUICHE_OBLIVIOUS_HTTP_OBLIVIOUS_HTTP_GATEWAY_H_
+
+#include <memory>
+
+#include "absl/status/statusor.h"
+#include "absl/strings/string_view.h"
+#include "openssl/base.h"
+#include "openssl/hpke.h"
+#include "quiche/common/platform/api/quiche_export.h"
+#include "quiche/common/quiche_random.h"
+#include "quiche/oblivious_http/buffers/oblivious_http_request.h"
+#include "quiche/oblivious_http/buffers/oblivious_http_response.h"
+#include "quiche/oblivious_http/common/oblivious_http_header_key_config.h"
+
+namespace quiche {
+// 1. Handles server side decryption of the payload received in HTTP POST body
+// from Relay.
+// 2. Handles server side encryption of response (that's in the form of Binary
+// HTTP) that will be sent back to Relay in HTTP POST body.
+// 3. Handles BSSL initialization and HPKE context bookkeeping.
+
+// This class is immutable (except moves) and thus trivially thread-safe,
+// assuming the `QuicheRandom* quiche_random` passed in with `Create` is
+// thread-safe. Note that default `QuicheRandom::GetInstance()` is thread-safe.
+class QUICHE_EXPORT_PRIVATE ObliviousHttpGateway {
+ public:
+  // @params: If callers would like to pass in their own `QuicheRandom`
+  // instance, they can make use of the param `quiche_random`. Otherwise, the
+  // default `QuicheRandom::GetInstance()` will be used.
+  static absl::StatusOr<ObliviousHttpGateway> Create(
+      absl::string_view hpke_private_key,
+      const ObliviousHttpHeaderKeyConfig& ohttp_key_config,
+      QuicheRandom* quiche_random = nullptr);
+
+  // only Movable (due to `UniquePtr server_hpke_key_`).
+  ObliviousHttpGateway(ObliviousHttpGateway&& other) = default;
+  ObliviousHttpGateway& operator=(ObliviousHttpGateway&& other) = default;
+
+  ~ObliviousHttpGateway() = default;
+
+  // After successful `Create`, callers will use the returned object to
+  // repeatedly call into this method in order to create Oblivious HTTP request
+  // with the initialized HPKE private key. Call sequence: Create ->
+  // DecryptObliviousHttpRequest -> CreateObliviousHttpResponse.
+  // Eg.,
+  //   auto ohttp_server_object = ObliviousHttpGateway::Create( <HPKE
+  //    private key>, <OHTTP key configuration described in
+  //    `oblivious_http_header_key_config.h`>);
+  //   auto decrypted_request1 =
+  //    ohttp_server_object.DecryptObliviousHttpRequest(<encrypted binary http
+  //    1>);
+  //   auto decrypted_request2 =
+  //    ohttp_server_object.DecryptObliviousHttpRequest(<encrypted binary http
+  //    2>);
+  absl::StatusOr<ObliviousHttpRequest> DecryptObliviousHttpRequest(
+      absl::string_view encrypted_data) const;
+
+  // After `DecryptObliviousHttpRequest` operation, callers on server-side will
+  // extract `oblivious_http_request_context` from the returned object
+  // `ObliviousHttpRequest` and pass in to this method in order to handle the
+  // response flow back to the client.
+  absl::StatusOr<ObliviousHttpResponse> CreateObliviousHttpResponse(
+      absl::string_view plaintext_data,
+      ObliviousHttpRequest::Context& oblivious_http_request_context) const;
+
+ private:
+  explicit ObliviousHttpGateway(
+      bssl::UniquePtr<EVP_HPKE_KEY> recipient_key,
+      const ObliviousHttpHeaderKeyConfig& ohttp_key_config,
+      QuicheRandom* quiche_random);
+  bssl::UniquePtr<EVP_HPKE_KEY> server_hpke_key_;
+  // Holds server's keyID and HPKE related IDs that's published under HPKE
+  // public Key configuration.
+  // https://www.ietf.org/archive/id/draft-ietf-ohai-ohttp-03.html#name-key-configuration
+  ObliviousHttpHeaderKeyConfig ohttp_key_config_;
+  QuicheRandom* quiche_random_;
+};
+
+}  // namespace quiche
+
+#endif  // QUICHE_OBLIVIOUS_HTTP_OBLIVIOUS_HTTP_GATEWAY_H_
diff --git a/quiche/oblivious_http/oblivious_http_gateway_test.cc b/quiche/oblivious_http/oblivious_http_gateway_test.cc
new file mode 100644
index 0000000..5482c1c
--- /dev/null
+++ b/quiche/oblivious_http/oblivious_http_gateway_test.cc
@@ -0,0 +1,228 @@
+#include "quiche/oblivious_http/oblivious_http_gateway.h"
+
+#include <stdint.h>
+
+#include <string>
+#include <utility>
+
+#include "absl/status/status.h"
+#include "absl/status/statusor.h"
+#include "absl/strings/escaping.h"
+#include "absl/strings/string_view.h"
+#include "quiche/common/platform/api/quiche_test.h"
+#include "quiche/common/platform/api/quiche_thread.h"
+#include "quiche/common/quiche_random.h"
+#include "quiche/oblivious_http/buffers/oblivious_http_request.h"
+
+namespace quiche {
+namespace {
+
+std::string GetHpkePrivateKey() {
+  // Dev/Test private key generated using Keystore.
+  absl::string_view hpke_key_hex =
+      "b77431ecfa8f4cfc30d6e467aafa06944dffe28cb9dd1409e33a3045f5adc8a1";
+  return absl::HexStringToBytes(hpke_key_hex);
+}
+
+std::string GetHpkePublicKey() {
+  // Dev/Test public key generated using Keystore.
+  absl::string_view public_key =
+      "6d21cfe09fbea5122f9ebc2eb2a69fcc4f06408cd54aac934f012e76fcdcef62";
+  return absl::HexStringToBytes(public_key);
+}
+
+const ObliviousHttpHeaderKeyConfig GetOhttpKeyConfig(uint8_t key_id,
+                                                     uint16_t kem_id,
+                                                     uint16_t kdf_id,
+                                                     uint16_t aead_id) {
+  auto ohttp_key_config =
+      ObliviousHttpHeaderKeyConfig::Create(key_id, kem_id, kdf_id, aead_id);
+  EXPECT_TRUE(ohttp_key_config.ok());
+  return std::move(ohttp_key_config.value());
+}
+
+TEST(ObliviousHttpGateway, TestProvisioningKeyAndDecapsulate) {
+  // X25519 Secret key (priv key).
+  // https://www.ietf.org/archive/id/draft-ietf-ohai-ohttp-03.html#appendix-A-2
+  constexpr absl::string_view kX25519SecretKey =
+      "3c168975674b2fa8e465970b79c8dcf09f1c741626480bd4c6162fc5b6a98e1a";
+
+  auto instance = ObliviousHttpGateway::Create(
+      /*hpke_private_key*/ absl::HexStringToBytes(kX25519SecretKey),
+      /*ohttp_key_config*/ GetOhttpKeyConfig(
+          /*key_id=*/1, EVP_HPKE_DHKEM_X25519_HKDF_SHA256, EVP_HPKE_HKDF_SHA256,
+          EVP_HPKE_AES_128_GCM));
+
+  // Encapsulated request.
+  // https://www.ietf.org/archive/id/draft-ietf-ohai-ohttp-03.html#appendix-A-14
+  constexpr absl::string_view kEncapsulatedRequest =
+      "010020000100014b28f881333e7c164ffc499ad9796f877f4e1051ee6d31bad19dec96c2"
+      "08b4726374e469135906992e1268c594d2a10c695d858c40a026e7965e7d86b83dd440b2"
+      "c0185204b4d63525";
+
+  auto decrypted_req = instance->DecryptObliviousHttpRequest(
+      absl::HexStringToBytes(kEncapsulatedRequest));
+  ASSERT_TRUE(decrypted_req.ok());
+  ASSERT_FALSE(decrypted_req->GetPlaintextData().empty());
+}
+
+TEST(ObliviousHttpGateway, TestDecryptingMultipleRequestsWithSingleInstance) {
+  auto instance = ObliviousHttpGateway::Create(
+      GetHpkePrivateKey(),
+      GetOhttpKeyConfig(1, EVP_HPKE_DHKEM_X25519_HKDF_SHA256,
+                        EVP_HPKE_HKDF_SHA256, EVP_HPKE_AES_256_GCM));
+  // plaintext: "test request 1"
+  absl::string_view encrypted_req_1 =
+      "010020000100025f20b60306b61ad9ecad389acd752ca75c4e2969469809fe3d84aae137"
+      "f73e4ccfe9ba71f12831fdce6c8202fbd38a84c5d8a73ac4c8ea6c10592594845f";
+  auto decapsulated_req_1 = instance->DecryptObliviousHttpRequest(
+      absl::HexStringToBytes(encrypted_req_1));
+  ASSERT_TRUE(decapsulated_req_1.ok());
+  ASSERT_FALSE(decapsulated_req_1->GetPlaintextData().empty());
+
+  // plaintext: "test request 2"
+  absl::string_view encrypted_req_2 =
+      "01002000010002285ebc2fcad72cc91b378050cac29a62feea9cd97829335ee9fc87e672"
+      "4fa13ff2efdff620423d54225d3099088e7b32a5165f805a5d922918865a0a447a";
+  auto decapsulated_req_2 = instance->DecryptObliviousHttpRequest(
+      absl::HexStringToBytes(encrypted_req_2));
+  ASSERT_TRUE(decapsulated_req_2.ok());
+  ASSERT_FALSE(decapsulated_req_2->GetPlaintextData().empty());
+}
+
+TEST(ObliviousHttpGateway, TestInvalidHPKEKey) {
+  // Invalid private key.
+  EXPECT_EQ(ObliviousHttpGateway::Create(
+                "Invalid HPKE key",
+                GetOhttpKeyConfig(70, EVP_HPKE_DHKEM_X25519_HKDF_SHA256,
+                                  EVP_HPKE_HKDF_SHA256, EVP_HPKE_AES_256_GCM))
+                .status()
+                .code(),
+            absl::StatusCode::kInternal);
+  // Empty private key.
+  EXPECT_EQ(ObliviousHttpGateway::Create(
+                /*hpke_private_key*/ "",
+                GetOhttpKeyConfig(70, EVP_HPKE_DHKEM_X25519_HKDF_SHA256,
+                                  EVP_HPKE_HKDF_SHA256, EVP_HPKE_AES_256_GCM))
+                .status()
+                .code(),
+            absl::StatusCode::kInvalidArgument);
+}
+
+TEST(ObliviousHttpGateway, TestObliviousResponseHandling) {
+  auto ohttp_key_config =
+      GetOhttpKeyConfig(3, EVP_HPKE_DHKEM_X25519_HKDF_SHA256,
+                        EVP_HPKE_HKDF_SHA256, EVP_HPKE_AES_256_GCM);
+  auto instance =
+      ObliviousHttpGateway::Create(GetHpkePrivateKey(), ohttp_key_config);
+  ASSERT_TRUE(instance.ok());
+  auto encapsualte_request_on_client =
+      ObliviousHttpRequest::CreateClientObliviousRequest(
+          "test", GetHpkePublicKey(), ohttp_key_config);
+  ASSERT_TRUE(encapsualte_request_on_client.ok());
+  // Setup Recipient to allow setting up the HPKE context, and subsequently use
+  // it to encrypt the response.
+  auto decapsulated_req_on_server = instance->DecryptObliviousHttpRequest(
+      encapsualte_request_on_client->EncapsulateAndSerialize());
+  ASSERT_TRUE(decapsulated_req_on_server.ok());
+  auto encapsulate_resp_on_gateway = instance->CreateObliviousHttpResponse(
+      "some response",
+      *(decapsulated_req_on_server->oblivious_http_request_context()));
+  ASSERT_TRUE(encapsulate_resp_on_gateway.ok());
+  ASSERT_FALSE(encapsulate_resp_on_gateway->EncapsulateAndSerialize().empty());
+}
+
+TEST(ObliviousHttpGateway,
+     TestHandlingMultipleResponsesForMultipleRequestsWithSingleInstance) {
+  auto instance = ObliviousHttpGateway::Create(
+      GetHpkePrivateKey(),
+      GetOhttpKeyConfig(1, EVP_HPKE_DHKEM_X25519_HKDF_SHA256,
+                        EVP_HPKE_HKDF_SHA256, EVP_HPKE_AES_256_GCM),
+      QuicheRandom::GetInstance());
+  // Setup contexts first.
+  auto decrypted_request_1 = instance->DecryptObliviousHttpRequest(
+      absl::HexStringToBytes("010020000100025f20b60306b61ad9ecad389acd752ca75c4"
+                             "e2969469809fe3d84aae137"
+                             "f73e4ccfe9ba71f12831fdce6c8202fbd38a84c5d8a73ac4c"
+                             "8ea6c10592594845f"));
+  ASSERT_TRUE(decrypted_request_1.ok());
+  auto decrypted_request_2 = instance->DecryptObliviousHttpRequest(
+      absl::HexStringToBytes("01002000010002285ebc2fcad72cc91b378050cac29a62fee"
+                             "a9cd97829335ee9fc87e672"
+                             "4fa13ff2efdff620423d54225d3099088e7b32a5165f805a5"
+                             "d922918865a0a447a"));
+  ASSERT_TRUE(decrypted_request_2.ok());
+
+  // Extract contexts and handle the response for each corresponding request.
+  auto oblivious_request_context_1 =
+      decrypted_request_1->oblivious_http_request_context();
+  EXPECT_NE(oblivious_request_context_1, nullptr);
+  auto encrypted_response_1 = instance->CreateObliviousHttpResponse(
+      "test response 1", *(oblivious_request_context_1));
+  ASSERT_TRUE(encrypted_response_1.ok());
+  ASSERT_FALSE(encrypted_response_1->EncapsulateAndSerialize().empty());
+
+  auto oblivious_request_context_2 =
+      decrypted_request_1->oblivious_http_request_context();
+  EXPECT_NE(oblivious_request_context_2, nullptr);
+  auto encrypted_response_2 = instance->CreateObliviousHttpResponse(
+      "test response 2", *(oblivious_request_context_2));
+  ASSERT_TRUE(encrypted_response_2.ok());
+  ASSERT_FALSE(encrypted_response_2->EncapsulateAndSerialize().empty());
+}
+
+TEST(ObliviousHttpGateway, TestWithMultipleThreads) {
+  class TestQuicheThread : public QuicheThread {
+   public:
+    TestQuicheThread(const ObliviousHttpGateway& gateway_receiver,
+                     std::string request_payload, std::string response_payload)
+        : QuicheThread("gateway_thread"),
+          gateway_receiver_(gateway_receiver),
+          request_payload_(request_payload),
+          response_payload_(response_payload) {}
+
+   protected:
+    void Run() override {
+      auto decrypted_request =
+          gateway_receiver_.DecryptObliviousHttpRequest(request_payload_);
+      ASSERT_TRUE(decrypted_request.ok());
+      ASSERT_FALSE(decrypted_request->GetPlaintextData().empty());
+      auto encrypted_response = gateway_receiver_.CreateObliviousHttpResponse(
+          response_payload_,
+          *(decrypted_request->oblivious_http_request_context()));
+      ASSERT_TRUE(encrypted_response.ok());
+      ASSERT_FALSE(encrypted_response->EncapsulateAndSerialize().empty());
+    }
+
+   private:
+    const ObliviousHttpGateway& gateway_receiver_;
+    std::string request_payload_, response_payload_;
+  };
+
+  auto gateway_receiver = ObliviousHttpGateway::Create(
+      GetHpkePrivateKey(),
+      GetOhttpKeyConfig(1, EVP_HPKE_DHKEM_X25519_HKDF_SHA256,
+                        EVP_HPKE_HKDF_SHA256, EVP_HPKE_AES_256_GCM),
+      QuicheRandom::GetInstance());
+
+  TestQuicheThread t1(
+      *gateway_receiver,
+      absl::HexStringToBytes("010020000100025f20b60306b61ad9ecad389acd752ca75c4"
+                             "e2969469809fe3d84aae137"
+                             "f73e4ccfe9ba71f12831fdce6c8202fbd38a84c5d8a73ac4c"
+                             "8ea6c10592594845f"),
+      "test response 1");
+  TestQuicheThread t2(
+      *gateway_receiver,
+      absl::HexStringToBytes("01002000010002285ebc2fcad72cc91b378050cac29a62fee"
+                             "a9cd97829335ee9fc87e672"
+                             "4fa13ff2efdff620423d54225d3099088e7b32a5165f805a5"
+                             "d922918865a0a447a"),
+      "test response 2");
+  t1.Start();
+  t2.Start();
+  t1.Join();
+  t2.Join();
+}
+}  // namespace
+}  // namespace quiche
