/* Copyright (c) 2020, Google Inc.
 *
 * Permission to use, copy, modify, and/or distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */

#include <assert.h>
#include <string.h>

#include <openssl/aead.h>
#include <openssl/bytestring.h>
#include <openssl/curve25519.h>
#include <openssl/digest.h>
#include <openssl/err.h>
#include <openssl/evp_errors.h>
#include <openssl/hkdf.h>
#include <openssl/sha.h>

#include "../internal.h"
#include "internal.h"


// This file implements draft-irtf-cfrg-hpke-07.

#define KEM_CONTEXT_LEN (2 * X25519_PUBLIC_VALUE_LEN)

// HPKE KEM scheme IDs.
#define HPKE_DHKEM_X25519_HKDF_SHA256 0x0020

// This is strlen("HPKE") + 3 * sizeof(uint16_t).
#define HPKE_SUITE_ID_LEN 10

#define HPKE_MODE_BASE 0
#define HPKE_MODE_PSK 1

static const char kHpkeRfcId[] = "HPKE-07";

static int add_label_string(CBB *cbb, const char *label) {
  return CBB_add_bytes(cbb, (const uint8_t *)label, strlen(label));
}

// The suite_id for the KEM is defined as concat("KEM", I2OSP(kem_id, 2)). Note
// that the suite_id used outside of the KEM also includes the kdf_id and
// aead_id.
static const uint8_t kX25519SuiteID[] = {
    'K', 'E', 'M', HPKE_DHKEM_X25519_HKDF_SHA256 >> 8,
    HPKE_DHKEM_X25519_HKDF_SHA256 & 0x00ff};

// The suite_id for non-KEM pieces of HPKE is defined as concat("HPKE",
// I2OSP(kem_id, 2), I2OSP(kdf_id, 2), I2OSP(aead_id, 2)).
static int hpke_build_suite_id(uint8_t out[HPKE_SUITE_ID_LEN], uint16_t kdf_id,
                               uint16_t aead_id) {
  CBB cbb;
  int ret = CBB_init_fixed(&cbb, out, HPKE_SUITE_ID_LEN) &&
            add_label_string(&cbb, "HPKE") &&
            CBB_add_u16(&cbb, HPKE_DHKEM_X25519_HKDF_SHA256) &&
            CBB_add_u16(&cbb, kdf_id) &&
            CBB_add_u16(&cbb, aead_id);
  CBB_cleanup(&cbb);
  return ret;
}

static int hpke_labeled_extract(const EVP_MD *hkdf_md, uint8_t *out_key,
                                size_t *out_len, const uint8_t *salt,
                                size_t salt_len, const uint8_t *suite_id,
                                size_t suite_id_len, const char *label,
                                const uint8_t *ikm, size_t ikm_len) {
  // labeledIKM = concat("RFCXXXX ", suite_id, label, IKM)
  CBB labeled_ikm;
  int ok = CBB_init(&labeled_ikm, 0) &&
           add_label_string(&labeled_ikm, kHpkeRfcId) &&
           CBB_add_bytes(&labeled_ikm, suite_id, suite_id_len) &&
           add_label_string(&labeled_ikm, label) &&
           CBB_add_bytes(&labeled_ikm, ikm, ikm_len) &&
           HKDF_extract(out_key, out_len, hkdf_md, CBB_data(&labeled_ikm),
                        CBB_len(&labeled_ikm), salt, salt_len);
  CBB_cleanup(&labeled_ikm);
  return ok;
}

static int hpke_labeled_expand(const EVP_MD *hkdf_md, uint8_t *out_key,
                               size_t out_len, const uint8_t *prk,
                               size_t prk_len, const uint8_t *suite_id,
                               size_t suite_id_len, const char *label,
                               const uint8_t *info, size_t info_len) {
  // labeledInfo = concat(I2OSP(L, 2), "RFCXXXX ", suite_id, label, info)
  CBB labeled_info;
  int ok = CBB_init(&labeled_info, 0) &&
           CBB_add_u16(&labeled_info, out_len) &&
           add_label_string(&labeled_info, kHpkeRfcId) &&
           CBB_add_bytes(&labeled_info, suite_id, suite_id_len) &&
           add_label_string(&labeled_info, label) &&
           CBB_add_bytes(&labeled_info, info, info_len) &&
           HKDF_expand(out_key, out_len, hkdf_md, prk, prk_len,
                       CBB_data(&labeled_info), CBB_len(&labeled_info));
  CBB_cleanup(&labeled_info);
  return ok;
}

static int hpke_extract_and_expand(const EVP_MD *hkdf_md, uint8_t *out_key,
                                   size_t out_len,
                                   const uint8_t dh[X25519_PUBLIC_VALUE_LEN],
                                   const uint8_t kem_context[KEM_CONTEXT_LEN]) {
  uint8_t prk[EVP_MAX_MD_SIZE];
  size_t prk_len;
  static const char kEaePrkLabel[] = "eae_prk";
  if (!hpke_labeled_extract(hkdf_md, prk, &prk_len, NULL, 0, kX25519SuiteID,
                            sizeof(kX25519SuiteID), kEaePrkLabel, dh,
                            X25519_PUBLIC_VALUE_LEN)) {
    return 0;
  }
  static const char kPRKExpandLabel[] = "shared_secret";
  if (!hpke_labeled_expand(hkdf_md, out_key, out_len, prk, prk_len,
                           kX25519SuiteID, sizeof(kX25519SuiteID),
                           kPRKExpandLabel, kem_context, KEM_CONTEXT_LEN)) {
    return 0;
  }
  return 1;
}

const EVP_AEAD *EVP_HPKE_get_aead(uint16_t aead_id) {
  switch (aead_id) {
    case EVP_HPKE_AEAD_AES_128_GCM:
      return EVP_aead_aes_128_gcm();
    case EVP_HPKE_AEAD_AES_256_GCM:
      return EVP_aead_aes_256_gcm();
    case EVP_HPKE_AEAD_CHACHA20POLY1305:
      return EVP_aead_chacha20_poly1305();
  }
  OPENSSL_PUT_ERROR(EVP, ERR_R_INTERNAL_ERROR);
  return NULL;
}

const EVP_MD *EVP_HPKE_get_hkdf_md(uint16_t kdf_id) {
  switch (kdf_id) {
    case EVP_HPKE_HKDF_SHA256:
      return EVP_sha256();
    case EVP_HPKE_HKDF_SHA384:
      return EVP_sha384();
    case EVP_HPKE_HKDF_SHA512:
      return EVP_sha512();
  }
  OPENSSL_PUT_ERROR(EVP, ERR_R_INTERNAL_ERROR);
  return NULL;
}

static int hpke_key_schedule(EVP_HPKE_CTX *hpke, uint8_t mode,
                             const uint8_t *shared_secret,
                             size_t shared_secret_len, const uint8_t *info,
                             size_t info_len, const uint8_t *psk,
                             size_t psk_len, const uint8_t *psk_id,
                             size_t psk_id_len) {
  // Verify the PSK inputs.
  switch (mode) {
    case HPKE_MODE_BASE:
      // This is an internal error, unreachable from the caller.
      assert(psk_len == 0 && psk_id_len == 0);
      break;
    case HPKE_MODE_PSK:
      if (psk_len == 0 || psk_id_len == 0) {
        OPENSSL_PUT_ERROR(EVP, EVP_R_EMPTY_PSK);
        return 0;
      }
      break;
    default:
      return 0;
  }

  // Attempt to get an EVP_AEAD*.
  const EVP_AEAD *aead = EVP_HPKE_get_aead(hpke->aead_id);
  if (aead == NULL) {
    return 0;
  }

  uint8_t suite_id[HPKE_SUITE_ID_LEN];
  if (!hpke_build_suite_id(suite_id, hpke->kdf_id, hpke->aead_id)) {
    return 0;
  }

  // psk_id_hash = LabeledExtract("", "psk_id_hash", psk_id)
  static const char kPskIdHashLabel[] = "psk_id_hash";
  uint8_t psk_id_hash[EVP_MAX_MD_SIZE];
  size_t psk_id_hash_len;
  if (!hpke_labeled_extract(hpke->hkdf_md, psk_id_hash, &psk_id_hash_len, NULL,
                            0, suite_id, sizeof(suite_id), kPskIdHashLabel,
                            psk_id, psk_id_len)) {
    return 0;
  }

  // info_hash = LabeledExtract("", "info_hash", info)
  static const char kInfoHashLabel[] = "info_hash";
  uint8_t info_hash[EVP_MAX_MD_SIZE];
  size_t info_hash_len;
  if (!hpke_labeled_extract(hpke->hkdf_md, info_hash, &info_hash_len, NULL, 0,
                            suite_id, sizeof(suite_id), kInfoHashLabel, info,
                            info_len)) {
    return 0;
  }

  // key_schedule_context = concat(mode, psk_id_hash, info_hash)
  uint8_t context[sizeof(uint8_t) + 2 * EVP_MAX_MD_SIZE];
  size_t context_len;
  CBB context_cbb;
  if (!CBB_init_fixed(&context_cbb, context, sizeof(context)) ||
      !CBB_add_u8(&context_cbb, mode) ||
      !CBB_add_bytes(&context_cbb, psk_id_hash, psk_id_hash_len) ||
      !CBB_add_bytes(&context_cbb, info_hash, info_hash_len) ||
      !CBB_finish(&context_cbb, NULL, &context_len)) {
    return 0;
  }

  // secret = LabeledExtract(shared_secret, "secret", psk)
  static const char kSecretExtractLabel[] = "secret";
  uint8_t secret[EVP_MAX_MD_SIZE];
  size_t secret_len;
  if (!hpke_labeled_extract(hpke->hkdf_md, secret, &secret_len, shared_secret,
                            shared_secret_len, suite_id, sizeof(suite_id),
                            kSecretExtractLabel, psk, psk_len)) {
    return 0;
  }

  // key = LabeledExpand(secret, "key", key_schedule_context, Nk)
  static const char kKeyExpandLabel[] = "key";
  uint8_t key[EVP_AEAD_MAX_KEY_LENGTH];
  const size_t kKeyLen = EVP_AEAD_key_length(aead);
  if (!hpke_labeled_expand(hpke->hkdf_md, key, kKeyLen, secret, secret_len,
                           suite_id, sizeof(suite_id), kKeyExpandLabel, context,
                           context_len)) {
    return 0;
  }

  // Initialize the HPKE context's AEAD context, storing a copy of |key|.
  if (!EVP_AEAD_CTX_init(&hpke->aead_ctx, aead, key, kKeyLen, 0, NULL)) {
    return 0;
  }

  // base_nonce = LabeledExpand(secret, "base_nonce", key_schedule_context, Nn)
  static const char kNonceExpandLabel[] = "base_nonce";
  if (!hpke_labeled_expand(hpke->hkdf_md, hpke->base_nonce,
                           EVP_AEAD_nonce_length(aead), secret, secret_len,
                           suite_id, sizeof(suite_id), kNonceExpandLabel,
                           context, context_len)) {
    return 0;
  }

  // exporter_secret = LabeledExpand(secret, "exp", key_schedule_context, Nh)
  static const char kExporterSecretExpandLabel[] = "exp";
  if (!hpke_labeled_expand(hpke->hkdf_md, hpke->exporter_secret,
                           EVP_MD_size(hpke->hkdf_md), secret, secret_len,
                           suite_id, sizeof(suite_id),
                           kExporterSecretExpandLabel, context, context_len)) {
    return 0;
  }

  return 1;
}

// The number of bytes written to |out_shared_secret| is the size of the KEM's
// KDF (currently we only support SHA256).
static int hpke_encap(EVP_HPKE_CTX *hpke,
                      uint8_t out_shared_secret[SHA256_DIGEST_LENGTH],
                      const uint8_t public_key_r[X25519_PUBLIC_VALUE_LEN],
                      const uint8_t ephemeral_private[X25519_PRIVATE_KEY_LEN],
                      const uint8_t ephemeral_public[X25519_PUBLIC_VALUE_LEN]) {
  uint8_t dh[X25519_PUBLIC_VALUE_LEN];
  if (!X25519(dh, ephemeral_private, public_key_r)) {
    OPENSSL_PUT_ERROR(EVP, EVP_R_INVALID_PEER_KEY);
    return 0;
  }

  uint8_t kem_context[KEM_CONTEXT_LEN];
  OPENSSL_memcpy(kem_context, ephemeral_public, X25519_PUBLIC_VALUE_LEN);
  OPENSSL_memcpy(kem_context + X25519_PUBLIC_VALUE_LEN, public_key_r,
                 X25519_PUBLIC_VALUE_LEN);
  if (!hpke_extract_and_expand(EVP_sha256(), out_shared_secret,
                               SHA256_DIGEST_LENGTH, dh, kem_context)) {
    return 0;
  }
  return 1;
}

static int hpke_decap(const EVP_HPKE_CTX *hpke,
                      uint8_t out_shared_secret[SHA256_DIGEST_LENGTH],
                      const uint8_t enc[X25519_PUBLIC_VALUE_LEN],
                      const uint8_t public_key_r[X25519_PUBLIC_VALUE_LEN],
                      const uint8_t secret_key_r[X25519_PRIVATE_KEY_LEN]) {
  uint8_t dh[X25519_PUBLIC_VALUE_LEN];
  if (!X25519(dh, secret_key_r, enc)) {
    OPENSSL_PUT_ERROR(EVP, EVP_R_INVALID_PEER_KEY);
    return 0;
  }
  uint8_t kem_context[KEM_CONTEXT_LEN];
  OPENSSL_memcpy(kem_context, enc, X25519_PUBLIC_VALUE_LEN);
  OPENSSL_memcpy(kem_context + X25519_PUBLIC_VALUE_LEN, public_key_r,
                 X25519_PUBLIC_VALUE_LEN);
  if (!hpke_extract_and_expand(EVP_sha256(), out_shared_secret,
                               SHA256_DIGEST_LENGTH, dh, kem_context)) {
    return 0;
  }
  return 1;
}

void EVP_HPKE_CTX_init(EVP_HPKE_CTX *ctx) {
  OPENSSL_memset(ctx, 0, sizeof(EVP_HPKE_CTX));
  EVP_AEAD_CTX_zero(&ctx->aead_ctx);
}

void EVP_HPKE_CTX_cleanup(EVP_HPKE_CTX *ctx) {
  EVP_AEAD_CTX_cleanup(&ctx->aead_ctx);
}

int EVP_HPKE_CTX_setup_base_s_x25519(EVP_HPKE_CTX *hpke, uint8_t *out_enc,
                                     size_t out_enc_len, uint16_t kdf_id,
                                     uint16_t aead_id,
                                     const uint8_t *peer_public_value,
                                     size_t peer_public_value_len,
                                     const uint8_t *info, size_t info_len) {
  if (out_enc_len != X25519_PUBLIC_VALUE_LEN) {
    OPENSSL_PUT_ERROR(EVP, EVP_R_INVALID_BUFFER_SIZE);
    return 0;
  }

  // The GenerateKeyPair() step technically belongs in the KEM's Encap()
  // function, but we've moved it up a layer to make it easier for tests to
  // inject an ephemeral keypair.
  uint8_t ephemeral_private[X25519_PRIVATE_KEY_LEN];
  X25519_keypair(out_enc, ephemeral_private);
  return EVP_HPKE_CTX_setup_base_s_x25519_for_test(
      hpke, kdf_id, aead_id, peer_public_value, peer_public_value_len, info,
      info_len, ephemeral_private, sizeof(ephemeral_private), out_enc,
      out_enc_len);
}

int EVP_HPKE_CTX_setup_base_s_x25519_for_test(
    EVP_HPKE_CTX *hpke, uint16_t kdf_id, uint16_t aead_id,
    const uint8_t *peer_public_value, size_t peer_public_value_len,
    const uint8_t *info, size_t info_len, const uint8_t *ephemeral_private,
    size_t ephemeral_private_len, const uint8_t *ephemeral_public,
    size_t ephemeral_public_len) {
  if (peer_public_value_len != X25519_PUBLIC_VALUE_LEN) {
    OPENSSL_PUT_ERROR(EVP, EVP_R_INVALID_PEER_KEY);
    return 0;
  }
  if (ephemeral_private_len != X25519_PRIVATE_KEY_LEN ||
      ephemeral_public_len != X25519_PUBLIC_VALUE_LEN) {
    OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR);
    return 0;
  }

  hpke->is_sender = 1;
  hpke->kdf_id = kdf_id;
  hpke->aead_id = aead_id;
  hpke->hkdf_md = EVP_HPKE_get_hkdf_md(kdf_id);
  if (hpke->hkdf_md == NULL) {
    return 0;
  }
  uint8_t shared_secret[SHA256_DIGEST_LENGTH];
  if (!hpke_encap(hpke, shared_secret, peer_public_value, ephemeral_private,
                  ephemeral_public) ||
      !hpke_key_schedule(hpke, HPKE_MODE_BASE, shared_secret,
                         sizeof(shared_secret), info, info_len, NULL, 0, NULL,
                         0)) {
    return 0;
  }
  return 1;
}

int EVP_HPKE_CTX_setup_base_r_x25519(EVP_HPKE_CTX *hpke, uint16_t kdf_id,
                                     uint16_t aead_id, const uint8_t *enc,
                                     size_t enc_len, const uint8_t *public_key,
                                     size_t public_key_len,
                                     const uint8_t *private_key,
                                     size_t private_key_len,
                                     const uint8_t *info, size_t info_len) {
  if (enc_len != X25519_PUBLIC_VALUE_LEN) {
    OPENSSL_PUT_ERROR(EVP, EVP_R_INVALID_PEER_KEY);
    return 0;
  }
  if (public_key_len != X25519_PUBLIC_VALUE_LEN ||
      private_key_len != X25519_PRIVATE_KEY_LEN) {
    OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR);
    return 0;
  }

  hpke->is_sender = 0;
  hpke->kdf_id = kdf_id;
  hpke->aead_id = aead_id;
  hpke->hkdf_md = EVP_HPKE_get_hkdf_md(kdf_id);
  if (hpke->hkdf_md == NULL) {
    return 0;
  }
  uint8_t shared_secret[SHA256_DIGEST_LENGTH];
  if (!hpke_decap(hpke, shared_secret, enc, public_key, private_key) ||
      !hpke_key_schedule(hpke, HPKE_MODE_BASE, shared_secret,
                         sizeof(shared_secret), info, info_len, NULL, 0, NULL,
                         0)) {
    return 0;
  }
  return 1;
}

int EVP_HPKE_CTX_setup_psk_s_x25519(EVP_HPKE_CTX *hpke, uint8_t *out_enc,
                                    size_t out_enc_len, uint16_t kdf_id,
                                    uint16_t aead_id,
                                    const uint8_t *peer_public_value,
                                    size_t peer_public_value_len,
                                    const uint8_t *info, size_t info_len,
                                    const uint8_t *psk, size_t psk_len,
                                    const uint8_t *psk_id, size_t psk_id_len) {
  if (out_enc_len != X25519_PUBLIC_VALUE_LEN) {
    OPENSSL_PUT_ERROR(EVP, EVP_R_INVALID_BUFFER_SIZE);
    return 0;
  }

  // The GenerateKeyPair() step technically belongs in the KEM's Encap()
  // function, but we've moved it up a layer to make it easier for tests to
  // inject an ephemeral keypair.
  uint8_t ephemeral_private[X25519_PRIVATE_KEY_LEN];
  X25519_keypair(out_enc, ephemeral_private);
  return EVP_HPKE_CTX_setup_psk_s_x25519_for_test(
      hpke, kdf_id, aead_id, peer_public_value, peer_public_value_len, info,
      info_len, psk, psk_len, psk_id, psk_id_len, ephemeral_private,
      sizeof(ephemeral_private), out_enc, out_enc_len);
}

int EVP_HPKE_CTX_setup_psk_s_x25519_for_test(
    EVP_HPKE_CTX *hpke, uint16_t kdf_id, uint16_t aead_id,
    const uint8_t *peer_public_value, size_t peer_public_value_len,
    const uint8_t *info, size_t info_len, const uint8_t *psk, size_t psk_len,
    const uint8_t *psk_id, size_t psk_id_len, const uint8_t *ephemeral_private,
    size_t ephemeral_private_len, const uint8_t *ephemeral_public,
    size_t ephemeral_public_len) {
  if (peer_public_value_len != X25519_PUBLIC_VALUE_LEN) {
    OPENSSL_PUT_ERROR(EVP, EVP_R_INVALID_PEER_KEY);
    return 0;
  }
  if (ephemeral_private_len != X25519_PRIVATE_KEY_LEN ||
      ephemeral_public_len != X25519_PUBLIC_VALUE_LEN) {
    OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR);
    return 0;
  }

  hpke->is_sender = 1;
  hpke->kdf_id = kdf_id;
  hpke->aead_id = aead_id;
  hpke->hkdf_md = EVP_HPKE_get_hkdf_md(kdf_id);
  if (hpke->hkdf_md == NULL) {
    return 0;
  }
  uint8_t shared_secret[SHA256_DIGEST_LENGTH];
  if (!hpke_encap(hpke, shared_secret, peer_public_value, ephemeral_private,
                  ephemeral_public) ||
      !hpke_key_schedule(hpke, HPKE_MODE_PSK, shared_secret,
                         sizeof(shared_secret), info, info_len, psk, psk_len,
                         psk_id, psk_id_len)) {
    return 0;
  }
  return 1;
}

int EVP_HPKE_CTX_setup_psk_r_x25519(
    EVP_HPKE_CTX *hpke, uint16_t kdf_id, uint16_t aead_id, const uint8_t *enc,
    size_t enc_len, const uint8_t *public_key, size_t public_key_len,
    const uint8_t *private_key, size_t private_key_len, const uint8_t *info,
    size_t info_len, const uint8_t *psk, size_t psk_len, const uint8_t *psk_id,
    size_t psk_id_len) {
  if (enc_len != X25519_PUBLIC_VALUE_LEN) {
    OPENSSL_PUT_ERROR(EVP, EVP_R_INVALID_PEER_KEY);
    return 0;
  }
  if (public_key_len != X25519_PUBLIC_VALUE_LEN ||
      private_key_len != X25519_PRIVATE_KEY_LEN) {
    OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR);
    return 0;
  }

  hpke->is_sender = 0;
  hpke->kdf_id = kdf_id;
  hpke->aead_id = aead_id;
  hpke->hkdf_md = EVP_HPKE_get_hkdf_md(kdf_id);
  if (hpke->hkdf_md == NULL) {
    return 0;
  }
  uint8_t shared_secret[SHA256_DIGEST_LENGTH];
  if (!hpke_decap(hpke, shared_secret, enc, public_key, private_key) ||
      !hpke_key_schedule(hpke, HPKE_MODE_PSK, shared_secret,
                         sizeof(shared_secret), info, info_len, psk, psk_len,
                         psk_id, psk_id_len)) {
    return 0;
  }
  return 1;
}

static void hpke_nonce(const EVP_HPKE_CTX *hpke, uint8_t *out_nonce,
                       size_t nonce_len) {
  assert(nonce_len >= 8);

  // Write padded big-endian bytes of |hpke->seq| to |out_nonce|.
  OPENSSL_memset(out_nonce, 0, nonce_len);
  uint64_t seq_copy = hpke->seq;
  for (size_t i = 0; i < 8; i++) {
    out_nonce[nonce_len - i - 1] = seq_copy & 0xff;
    seq_copy >>= 8;
  }

  // XOR the encoded sequence with the |hpke->base_nonce|.
  for (size_t i = 0; i < nonce_len; i++) {
    out_nonce[i] ^= hpke->base_nonce[i];
  }
}

size_t EVP_HPKE_CTX_max_overhead(const EVP_HPKE_CTX *hpke) {
  assert(hpke->is_sender);
  return EVP_AEAD_max_overhead(hpke->aead_ctx.aead);
}

int EVP_HPKE_CTX_open(EVP_HPKE_CTX *hpke, uint8_t *out, size_t *out_len,
                      size_t max_out_len, const uint8_t *in, size_t in_len,
                      const uint8_t *ad, size_t ad_len) {
  if (hpke->is_sender) {
    OPENSSL_PUT_ERROR(EVP, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
    return 0;
  }
  if (hpke->seq == UINT64_MAX) {
    OPENSSL_PUT_ERROR(EVP, ERR_R_OVERFLOW);
    return 0;
  }

  uint8_t nonce[EVP_AEAD_MAX_NONCE_LENGTH];
  const size_t nonce_len = EVP_AEAD_nonce_length(hpke->aead_ctx.aead);
  hpke_nonce(hpke, nonce, nonce_len);

  if (!EVP_AEAD_CTX_open(&hpke->aead_ctx, out, out_len, max_out_len, nonce,
                         nonce_len, in, in_len, ad, ad_len)) {
    return 0;
  }
  hpke->seq++;
  return 1;
}

int EVP_HPKE_CTX_seal(EVP_HPKE_CTX *hpke, uint8_t *out, size_t *out_len,
                      size_t max_out_len, const uint8_t *in, size_t in_len,
                      const uint8_t *ad, size_t ad_len) {
  if (!hpke->is_sender) {
    OPENSSL_PUT_ERROR(EVP, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
    return 0;
  }
  if (hpke->seq == UINT64_MAX) {
    OPENSSL_PUT_ERROR(EVP, ERR_R_OVERFLOW);
    return 0;
  }

  uint8_t nonce[EVP_AEAD_MAX_NONCE_LENGTH];
  const size_t nonce_len = EVP_AEAD_nonce_length(hpke->aead_ctx.aead);
  hpke_nonce(hpke, nonce, nonce_len);

  if (!EVP_AEAD_CTX_seal(&hpke->aead_ctx, out, out_len, max_out_len, nonce,
                         nonce_len, in, in_len, ad, ad_len)) {
    return 0;
  }
  hpke->seq++;
  return 1;
}

int EVP_HPKE_CTX_export(const EVP_HPKE_CTX *hpke, uint8_t *out,
                        size_t secret_len, const uint8_t *context,
                        size_t context_len) {
  uint8_t suite_id[HPKE_SUITE_ID_LEN];
  if (!hpke_build_suite_id(suite_id, hpke->kdf_id, hpke->aead_id)) {
    return 0;
  }
  static const char kExportExpandLabel[] = "sec";
  if (!hpke_labeled_expand(hpke->hkdf_md, out, secret_len,
                           hpke->exporter_secret, EVP_MD_size(hpke->hkdf_md),
                           suite_id, sizeof(suite_id), kExportExpandLabel,
                           context, context_len)) {
    return 0;
  }
  return 1;
}
