/* Copyright (c) 2016, 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 <openssl/ssl.h>

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

#include <algorithm>
#include <utility>

#include <openssl/aead.h>
#include <openssl/aes.h>
#include <openssl/bytestring.h>
#include <openssl/chacha.h>
#include <openssl/digest.h>
#include <openssl/hkdf.h>
#include <openssl/hmac.h>
#include <openssl/mem.h>

#include "../crypto/fipsmodule/tls/internal.h"
#include "../crypto/internal.h"
#include "internal.h"


BSSL_NAMESPACE_BEGIN

static bool init_key_schedule(SSL_HANDSHAKE *hs, SSLTranscript *transcript,
                              uint16_t version, const SSL_CIPHER *cipher) {
  if (!transcript->InitHash(version, cipher)) {
    return false;
  }

  // Initialize the secret to the zero key.
  hs->secret.clear();
  hs->secret.Resize(transcript->DigestLen());
  return true;
}

static bool hkdf_extract_to_secret(SSL_HANDSHAKE *hs,
                                   const SSLTranscript &transcript,
                                   Span<const uint8_t> in) {
  size_t len;
  if (!HKDF_extract(hs->secret.data(), &len, transcript.Digest(), in.data(),
                    in.size(), hs->secret.data(), hs->secret.size())) {
    return false;
  }
  assert(len == hs->secret.size());
  return true;
}

bool tls13_init_key_schedule(SSL_HANDSHAKE *hs, Span<const uint8_t> psk) {
  if (!init_key_schedule(hs, &hs->transcript, ssl_protocol_version(hs->ssl),
                         hs->new_cipher)) {
    return false;
  }

  // Handback includes the whole handshake transcript, so we cannot free the
  // transcript buffer in the handback case.
  if (!hs->handback) {
    hs->transcript.FreeBuffer();
  }
  return hkdf_extract_to_secret(hs, hs->transcript, psk);
}

bool tls13_init_early_key_schedule(SSL_HANDSHAKE *hs,
                                   const SSL_SESSION *session) {
  assert(!hs->ssl->server);
  // When offering ECH, early data is associated with ClientHelloInner, not
  // ClientHelloOuter.
  SSLTranscript *transcript =
      hs->selected_ech_config ? &hs->inner_transcript : &hs->transcript;
  return init_key_schedule(hs, transcript,
                           ssl_session_protocol_version(session),
                           session->cipher) &&
         hkdf_extract_to_secret(hs, *transcript, session->secret);
}

static Span<const char> label_to_span(const char *label) {
  return MakeConstSpan(label, strlen(label));
}

static bool hkdf_expand_label_with_prefix(Span<uint8_t> out,
                                          const EVP_MD *digest,
                                          Span<const uint8_t> secret,
                                          Span<const uint8_t> label_prefix,
                                          Span<const char> label,
                                          Span<const uint8_t> hash) {
  // This is a copy of CRYPTO_tls13_hkdf_expand_label, but modified to take an
  // arbitrary prefix for the label instead of using the hardcoded "tls13 "
  // prefix.
  CBB cbb, child;
  uint8_t *hkdf_label = NULL;
  size_t hkdf_label_len;
  CBB_zero(&cbb);
  if (!CBB_init(&cbb,
                2 + 1 + label_prefix.size() + label.size() + 1 + hash.size()) ||
      !CBB_add_u16(&cbb, out.size()) ||
      !CBB_add_u8_length_prefixed(&cbb, &child) ||
      !CBB_add_bytes(&child, label_prefix.data(), label_prefix.size()) ||
      !CBB_add_bytes(&child, reinterpret_cast<const uint8_t *>(label.data()),
                     label.size()) ||
      !CBB_add_u8_length_prefixed(&cbb, &child) ||
      !CBB_add_bytes(&child, hash.data(), hash.size()) ||
      !CBB_finish(&cbb, &hkdf_label, &hkdf_label_len)) {
    CBB_cleanup(&cbb);
    return false;
  }

  const int ret = HKDF_expand(out.data(), out.size(), digest, secret.data(),
                              secret.size(), hkdf_label, hkdf_label_len);
  OPENSSL_free(hkdf_label);
  return ret == 1;
}

static bool hkdf_expand_label(Span<uint8_t> out, const EVP_MD *digest,
                              Span<const uint8_t> secret,
                              Span<const char> label, Span<const uint8_t> hash,
                              bool is_dtls) {
  if (is_dtls) {
    static const uint8_t kDTLS13LabelPrefix[] = "dtls13";
    return hkdf_expand_label_with_prefix(
        out, digest, secret,
        MakeConstSpan(kDTLS13LabelPrefix, sizeof(kDTLS13LabelPrefix) - 1),
        label, hash);
  }
  return CRYPTO_tls13_hkdf_expand_label(
             out.data(), out.size(), digest, secret.data(), secret.size(),
             reinterpret_cast<const uint8_t *>(label.data()), label.size(),
             hash.data(), hash.size()) == 1;
}

static const char kTLS13LabelDerived[] = "derived";

bool tls13_advance_key_schedule(SSL_HANDSHAKE *hs, Span<const uint8_t> in) {
  uint8_t derive_context[EVP_MAX_MD_SIZE];
  unsigned derive_context_len;
  return EVP_Digest(nullptr, 0, derive_context, &derive_context_len,
                    hs->transcript.Digest(), nullptr) &&
         hkdf_expand_label(MakeSpan(hs->secret), hs->transcript.Digest(),
                           hs->secret, label_to_span(kTLS13LabelDerived),
                           MakeConstSpan(derive_context, derive_context_len),
                           SSL_is_dtls(hs->ssl)) &&
         hkdf_extract_to_secret(hs, hs->transcript, in);
}

// derive_secret_with_transcript derives a secret of length
// |transcript.DigestLen()| and writes the result in |out| with the given label,
// the current base secret, and the state of |transcript|. It returns true on
// success and false on error.
static bool derive_secret_with_transcript(
    const SSL_HANDSHAKE *hs, InplaceVector<uint8_t, SSL_MAX_MD_SIZE> *out,
    const SSLTranscript &transcript, Span<const char> label) {
  uint8_t context_hash[EVP_MAX_MD_SIZE];
  size_t context_hash_len;
  if (!transcript.GetHash(context_hash, &context_hash_len)) {
    return false;
  }

  out->ResizeForOverwrite(transcript.DigestLen());
  return hkdf_expand_label(MakeSpan(*out), transcript.Digest(), hs->secret,
                           label, MakeConstSpan(context_hash, context_hash_len),
                           SSL_is_dtls(hs->ssl));
}

static bool derive_secret(SSL_HANDSHAKE *hs,
                          InplaceVector<uint8_t, SSL_MAX_MD_SIZE> *out,
                          Span<const char> label) {
  return derive_secret_with_transcript(hs, out, hs->transcript, label);
}

bool tls13_set_traffic_key(SSL *ssl, enum ssl_encryption_level_t level,
                           enum evp_aead_direction_t direction,
                           const SSL_SESSION *session,
                           Span<const uint8_t> traffic_secret) {
  uint16_t version = ssl_session_protocol_version(session);
  const EVP_MD *digest = ssl_session_get_digest(session);
  bool is_dtls = SSL_is_dtls(ssl);
  UniquePtr<SSLAEADContext> traffic_aead;
  if (SSL_is_quic(ssl)) {
    // Install a placeholder SSLAEADContext so that SSL accessors work. The
    // encryption itself will be handled by the SSL_QUIC_METHOD.
    traffic_aead = SSLAEADContext::CreatePlaceholderForQUIC(session->cipher);
  } else {
    // Look up cipher suite properties.
    const EVP_AEAD *aead;
    size_t discard;
    if (!ssl_cipher_get_evp_aead(&aead, &discard, &discard, session->cipher,
                                 version)) {
      return false;
    }

    // Derive the key and IV.
    uint8_t key_buf[EVP_AEAD_MAX_KEY_LENGTH], iv_buf[EVP_AEAD_MAX_NONCE_LENGTH];
    auto key = MakeSpan(key_buf).first(EVP_AEAD_key_length(aead));
    auto iv = MakeSpan(iv_buf).first(EVP_AEAD_nonce_length(aead));
    if (!hkdf_expand_label(key, digest, traffic_secret, label_to_span("key"),
                           {}, is_dtls) ||
        !hkdf_expand_label(iv, digest, traffic_secret, label_to_span("iv"), {},
                           is_dtls)) {
      return false;
    }

    traffic_aead = SSLAEADContext::Create(direction, session->ssl_version,
                                          session->cipher, key, {}, iv);
  }

  if (!traffic_aead) {
    return false;
  }

  if (direction == evp_aead_open) {
    if (!ssl->method->set_read_state(ssl, level, std::move(traffic_aead),
                                     traffic_secret)) {
      return false;
    }
    ssl->s3->read_traffic_secret.CopyFrom(traffic_secret);
  } else {
    if (!ssl->method->set_write_state(ssl, level, std::move(traffic_aead),
                                      traffic_secret)) {
      return false;
    }
    ssl->s3->write_traffic_secret.CopyFrom(traffic_secret);
  }

  return true;
}

namespace {

class AESRecordNumberEncrypter : public RecordNumberEncrypter {
 public:
  bool SetKey(Span<const uint8_t> key) override {
    return AES_set_encrypt_key(key.data(), key.size() * 8, &key_) == 0;
  }

  bool GenerateMask(Span<uint8_t> out, Span<const uint8_t> sample) override {
    if (sample.size() < AES_BLOCK_SIZE || out.size() > AES_BLOCK_SIZE) {
      return false;
    }
    uint8_t mask[AES_BLOCK_SIZE];
    AES_encrypt(sample.data(), mask, &key_);
    OPENSSL_memcpy(out.data(), mask, out.size());
    return true;
  }

 private:
  AES_KEY key_;
};

class AES128RecordNumberEncrypter : public AESRecordNumberEncrypter {
 public:
  size_t KeySize() override { return 16; }
};

class AES256RecordNumberEncrypter : public AESRecordNumberEncrypter {
 public:
  size_t KeySize() override { return 32; }
};

class ChaChaRecordNumberEncrypter : public RecordNumberEncrypter {
 public:
  size_t KeySize() override { return kKeySize; }

  bool SetKey(Span<const uint8_t> key) override {
    if (key.size() != kKeySize) {
      return false;
    }
    OPENSSL_memcpy(key_, key.data(), key.size());
    return true;
  }

  bool GenerateMask(Span<uint8_t> out, Span<const uint8_t> sample) override {
    // RFC 9147 section 4.2.3 uses the first 4 bytes of the sample as the
    // counter and the next 12 bytes as the nonce. If we have less than 4+12=16
    // bytes in the sample, then we'll read past the end of the |sample| buffer.
    // The counter is interpreted as little-endian per RFC 8439.
    if (sample.size() < 16) {
      return false;
    }
    uint32_t counter = CRYPTO_load_u32_le(sample.data());
    Span<const uint8_t> nonce = sample.subspan(4);
    OPENSSL_memset(out.data(), 0, out.size());
    CRYPTO_chacha_20(out.data(), out.data(), out.size(), key_, nonce.data(),
                     counter);
    return true;
  }

 private:
  static constexpr size_t kKeySize = 32;
  uint8_t key_[kKeySize];
};

#if defined(BORINGSSL_UNSAFE_FUZZER_MODE)
class NullRecordNumberEncrypter : public RecordNumberEncrypter {
 public:
  size_t KeySize() override { return 0; }
  bool SetKey(Span<const uint8_t> key) override { return true; }
  bool GenerateMask(Span<uint8_t> out, Span<const uint8_t> sample) override {
    OPENSSL_memset(out.data(), 0, out.size());
    return true;
  }
};
#endif  // BORINGSSL_UNSAFE_FUZZER_MODE

}  // namespace

UniquePtr<RecordNumberEncrypter> RecordNumberEncrypter::Create(
    const SSL_CIPHER *cipher, Span<const uint8_t> traffic_secret) {
  const EVP_MD *digest = ssl_get_handshake_digest(TLS1_3_VERSION, cipher);
  UniquePtr<RecordNumberEncrypter> ret;
#if defined(BORINGSSL_UNSAFE_FUZZER_MODE)
  ret = MakeUnique<NullRecordNumberEncrypter>();
#else
  if (cipher->algorithm_enc == SSL_AES128GCM) {
    ret = MakeUnique<AES128RecordNumberEncrypter>();
  } else if (cipher->algorithm_enc == SSL_AES256GCM) {
    ret = MakeUnique<AES256RecordNumberEncrypter>();
  } else if (cipher->algorithm_enc == SSL_CHACHA20POLY1305) {
    ret = MakeUnique<ChaChaRecordNumberEncrypter>();
  } else {
    OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
  }
#endif  // BORINGSSL_UNSAFE_FUZZER_MODE
  if (ret == nullptr) {
    return nullptr;
  }

  uint8_t rne_key_buf[RecordNumberEncrypter::kMaxKeySize];
  auto rne_key = MakeSpan(rne_key_buf).first(ret->KeySize());
  if (!hkdf_expand_label(rne_key, digest, traffic_secret, label_to_span("sn"),
                         {}, /*is_dtls=*/true) ||
      !ret->SetKey(rne_key)) {
    return nullptr;
  }
  return ret;
}

static const char kTLS13LabelExporter[] = "exp master";

static const char kTLS13LabelClientEarlyTraffic[] = "c e traffic";
static const char kTLS13LabelClientHandshakeTraffic[] = "c hs traffic";
static const char kTLS13LabelServerHandshakeTraffic[] = "s hs traffic";
static const char kTLS13LabelClientApplicationTraffic[] = "c ap traffic";
static const char kTLS13LabelServerApplicationTraffic[] = "s ap traffic";

bool tls13_derive_early_secret(SSL_HANDSHAKE *hs) {
  SSL *const ssl = hs->ssl;
  // When offering ECH on the client, early data is associated with
  // ClientHelloInner, not ClientHelloOuter.
  const SSLTranscript &transcript = (!ssl->server && hs->selected_ech_config)
                                        ? hs->inner_transcript
                                        : hs->transcript;
  if (!derive_secret_with_transcript(
          hs, &hs->early_traffic_secret, transcript,
          label_to_span(kTLS13LabelClientEarlyTraffic)) ||
      !ssl_log_secret(ssl, "CLIENT_EARLY_TRAFFIC_SECRET",
                      hs->early_traffic_secret)) {
    return false;
  }
  return true;
}

bool tls13_derive_handshake_secrets(SSL_HANDSHAKE *hs) {
  SSL *const ssl = hs->ssl;
  if (!derive_secret(hs, &hs->client_handshake_secret,
                     label_to_span(kTLS13LabelClientHandshakeTraffic)) ||
      !ssl_log_secret(ssl, "CLIENT_HANDSHAKE_TRAFFIC_SECRET",
                      hs->client_handshake_secret) ||
      !derive_secret(hs, &hs->server_handshake_secret,
                     label_to_span(kTLS13LabelServerHandshakeTraffic)) ||
      !ssl_log_secret(ssl, "SERVER_HANDSHAKE_TRAFFIC_SECRET",
                      hs->server_handshake_secret)) {
    return false;
  }

  return true;
}

bool tls13_derive_application_secrets(SSL_HANDSHAKE *hs) {
  SSL *const ssl = hs->ssl;
  if (!derive_secret(hs, &hs->client_traffic_secret_0,
                     label_to_span(kTLS13LabelClientApplicationTraffic)) ||
      !ssl_log_secret(ssl, "CLIENT_TRAFFIC_SECRET_0",
                      hs->client_traffic_secret_0) ||
      !derive_secret(hs, &hs->server_traffic_secret_0,
                     label_to_span(kTLS13LabelServerApplicationTraffic)) ||
      !ssl_log_secret(ssl, "SERVER_TRAFFIC_SECRET_0",
                      hs->server_traffic_secret_0) ||
      !derive_secret(hs, &ssl->s3->exporter_secret,
                     label_to_span(kTLS13LabelExporter)) ||
      !ssl_log_secret(ssl, "EXPORTER_SECRET", ssl->s3->exporter_secret)) {
    return false;
  }

  return true;
}

static const char kTLS13LabelApplicationTraffic[] = "traffic upd";

bool tls13_rotate_traffic_key(SSL *ssl, enum evp_aead_direction_t direction) {
  Span<uint8_t> secret = direction == evp_aead_open
                             ? MakeSpan(ssl->s3->read_traffic_secret)
                             : MakeSpan(ssl->s3->write_traffic_secret);

  const SSL_SESSION *session = SSL_get_session(ssl);
  const EVP_MD *digest = ssl_session_get_digest(session);
  return hkdf_expand_label(secret, digest, secret,
                           label_to_span(kTLS13LabelApplicationTraffic), {},
                           SSL_is_dtls(ssl)) &&
         tls13_set_traffic_key(ssl, ssl_encryption_application, direction,
                               session, secret);
}

static const char kTLS13LabelResumption[] = "res master";

bool tls13_derive_resumption_secret(SSL_HANDSHAKE *hs) {
  return derive_secret(hs, &hs->new_session->secret,
                       label_to_span(kTLS13LabelResumption));
}

static const char kTLS13LabelFinished[] = "finished";

// tls13_verify_data sets |out| to be the HMAC of |context| using a derived
// Finished key for both Finished messages and the PSK binder. |out| must have
// space available for |EVP_MAX_MD_SIZE| bytes.
static bool tls13_verify_data(uint8_t *out, size_t *out_len,
                              const EVP_MD *digest, uint16_t version,
                              Span<const uint8_t> secret,
                              Span<const uint8_t> context, bool is_dtls) {
  uint8_t key_buf[EVP_MAX_MD_SIZE];
  auto key = MakeSpan(key_buf, EVP_MD_size(digest));
  unsigned len;
  if (!hkdf_expand_label(key, digest, secret,
                         label_to_span(kTLS13LabelFinished), {}, is_dtls) ||
      HMAC(digest, key.data(), key.size(), context.data(), context.size(), out,
           &len) == nullptr) {
    return false;
  }
  *out_len = len;
  return true;
}

bool tls13_finished_mac(SSL_HANDSHAKE *hs, uint8_t *out, size_t *out_len,
                        bool is_server) {
  Span<const uint8_t> traffic_secret =
      is_server ? hs->server_handshake_secret : hs->client_handshake_secret;

  uint8_t context_hash[EVP_MAX_MD_SIZE];
  size_t context_hash_len;
  if (!hs->transcript.GetHash(context_hash, &context_hash_len) ||
      !tls13_verify_data(out, out_len, hs->transcript.Digest(),
                         hs->ssl->s3->version, traffic_secret,
                         MakeConstSpan(context_hash, context_hash_len),
                         SSL_is_dtls(hs->ssl))) {
    return false;
  }
  return true;
}

static const char kTLS13LabelResumptionPSK[] = "resumption";

bool tls13_derive_session_psk(SSL_SESSION *session, Span<const uint8_t> nonce,
                              bool is_dtls) {
  const EVP_MD *digest = ssl_session_get_digest(session);
  // The session initially stores the resumption_master_secret, which we
  // override with the PSK.
  assert(session->secret.size() == EVP_MD_size(digest));
  return hkdf_expand_label(MakeSpan(session->secret), digest, session->secret,
                           label_to_span(kTLS13LabelResumptionPSK), nonce,
                           is_dtls);
}

static const char kTLS13LabelExportKeying[] = "exporter";

bool tls13_export_keying_material(SSL *ssl, Span<uint8_t> out,
                                  Span<const uint8_t> secret,
                                  Span<const char> label,
                                  Span<const uint8_t> context) {
  if (secret.empty()) {
    assert(0);
    OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
    return false;
  }

  const EVP_MD *digest = ssl_session_get_digest(SSL_get_session(ssl));

  uint8_t hash_buf[EVP_MAX_MD_SIZE];
  uint8_t export_context_buf[EVP_MAX_MD_SIZE];
  unsigned hash_len;
  unsigned export_context_len;
  if (!EVP_Digest(context.data(), context.size(), hash_buf, &hash_len, digest,
                  nullptr) ||
      !EVP_Digest(nullptr, 0, export_context_buf, &export_context_len, digest,
                  nullptr)) {
    return false;
  }

  auto hash = MakeConstSpan(hash_buf, hash_len);
  auto export_context = MakeConstSpan(export_context_buf, export_context_len);
  uint8_t derived_secret_buf[EVP_MAX_MD_SIZE];
  auto derived_secret = MakeSpan(derived_secret_buf, EVP_MD_size(digest));
  return hkdf_expand_label(derived_secret, digest, secret, label,
                           export_context, SSL_is_dtls(ssl)) &&
         hkdf_expand_label(out, digest, derived_secret,
                           label_to_span(kTLS13LabelExportKeying), hash,
                           SSL_is_dtls(ssl));
}

static const char kTLS13LabelPSKBinder[] = "res binder";

static bool tls13_psk_binder(uint8_t *out, size_t *out_len,
                             const SSL_SESSION *session,
                             const SSLTranscript &transcript,
                             Span<const uint8_t> client_hello,
                             size_t binders_len, bool is_dtls) {
  const EVP_MD *digest = ssl_session_get_digest(session);

  // Compute the binder key.
  //
  // TODO(davidben): Ideally we wouldn't recompute early secret and the binder
  // key each time.
  uint8_t binder_context[EVP_MAX_MD_SIZE];
  unsigned binder_context_len;
  uint8_t early_secret[EVP_MAX_MD_SIZE] = {0};
  size_t early_secret_len;
  uint8_t binder_key_buf[EVP_MAX_MD_SIZE] = {0};
  auto binder_key = MakeSpan(binder_key_buf, EVP_MD_size(digest));
  if (!EVP_Digest(nullptr, 0, binder_context, &binder_context_len, digest,
                  nullptr) ||
      !HKDF_extract(early_secret, &early_secret_len, digest,
                    session->secret.data(), session->secret.size(), nullptr,
                    0) ||
      !hkdf_expand_label(
          binder_key, digest, MakeConstSpan(early_secret, early_secret_len),
          label_to_span(kTLS13LabelPSKBinder),
          MakeConstSpan(binder_context, binder_context_len), is_dtls)) {
    return false;
  }

  // Hash the transcript and truncated ClientHello.
  if (client_hello.size() < binders_len) {
    OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
    return false;
  }
  auto truncated = client_hello.subspan(0, client_hello.size() - binders_len);
  uint8_t context[EVP_MAX_MD_SIZE];
  unsigned context_len;
  ScopedEVP_MD_CTX ctx;
  if (!is_dtls) {
    if (!transcript.CopyToHashContext(ctx.get(), digest) ||
        !EVP_DigestUpdate(ctx.get(), truncated.data(), truncated.size()) ||
        !EVP_DigestFinal_ex(ctx.get(), context, &context_len)) {
      return false;
    }
  } else {
    // In DTLS 1.3, the transcript hash is computed over only the TLS 1.3
    // handshake messages (i.e. only type and length in the header), not the
    // full DTLSHandshake messages that are in |truncated|. This code pulls
    // the header and body out of the truncated ClientHello and writes those
    // to the hash context so the correct binder value is computed.
    if (truncated.size() < DTLS1_HM_HEADER_LENGTH) {
      return false;
    }
    auto header = truncated.subspan(0, 4);
    auto body = truncated.subspan(12);
    if (!transcript.CopyToHashContext(ctx.get(), digest) ||
        !EVP_DigestUpdate(ctx.get(), header.data(), header.size()) ||
        !EVP_DigestUpdate(ctx.get(), body.data(), body.size()) ||
        !EVP_DigestFinal_ex(ctx.get(), context, &context_len)) {
      return false;
    }
  }

  if (!tls13_verify_data(out, out_len, digest, session->ssl_version, binder_key,
                         MakeConstSpan(context, context_len), is_dtls)) {
    return false;
  }

  assert(*out_len == EVP_MD_size(digest));
  return true;
}

bool tls13_write_psk_binder(const SSL_HANDSHAKE *hs,
                            const SSLTranscript &transcript, Span<uint8_t> msg,
                            size_t *out_binder_len) {
  const SSL *const ssl = hs->ssl;
  const EVP_MD *digest = ssl_session_get_digest(ssl->session.get());
  const size_t hash_len = EVP_MD_size(digest);
  // We only offer one PSK, so the binders are a u16 and u8 length
  // prefix, followed by the binder. The caller is assumed to have constructed
  // |msg| with placeholder binders.
  const size_t binders_len = 3 + hash_len;
  uint8_t verify_data[EVP_MAX_MD_SIZE];
  size_t verify_data_len;
  if (!tls13_psk_binder(verify_data, &verify_data_len, ssl->session.get(),
                        transcript, msg, binders_len, SSL_is_dtls(hs->ssl)) ||
      verify_data_len != hash_len) {
    OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
    return false;
  }

  auto msg_binder = msg.last(verify_data_len);
  OPENSSL_memcpy(msg_binder.data(), verify_data, verify_data_len);
  if (out_binder_len != nullptr) {
    *out_binder_len = verify_data_len;
  }
  return true;
}

bool tls13_verify_psk_binder(const SSL_HANDSHAKE *hs,
                             const SSL_SESSION *session, const SSLMessage &msg,
                             CBS *binders) {
  uint8_t verify_data[EVP_MAX_MD_SIZE];
  size_t verify_data_len;
  CBS binder;
  // The binders are computed over |msg| with |binders| and its u16 length
  // prefix removed. The caller is assumed to have parsed |msg|, extracted
  // |binders|, and verified the PSK extension is last.
  if (!tls13_psk_binder(verify_data, &verify_data_len, session, hs->transcript,
                        msg.raw, 2 + CBS_len(binders), SSL_is_dtls(hs->ssl)) ||
      // We only consider the first PSK, so compare against the first binder.
      !CBS_get_u8_length_prefixed(binders, &binder)) {
    OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
    return false;
  }

  bool binder_ok =
      CBS_len(&binder) == verify_data_len &&
      CRYPTO_memcmp(CBS_data(&binder), verify_data, verify_data_len) == 0;
#if defined(BORINGSSL_UNSAFE_FUZZER_MODE)
  binder_ok = true;
#endif
  if (!binder_ok) {
    OPENSSL_PUT_ERROR(SSL, SSL_R_DIGEST_CHECK_FAILED);
    return false;
  }

  return true;
}

size_t ssl_ech_confirmation_signal_hello_offset(const SSL *ssl) {
  static_assert(ECH_CONFIRMATION_SIGNAL_LEN < SSL3_RANDOM_SIZE,
                "the confirmation signal is a suffix of the random");
  const size_t header_len =
      SSL_is_dtls(ssl) ? DTLS1_HM_HEADER_LENGTH : SSL3_HM_HEADER_LENGTH;
  return header_len + 2 /* version */ + SSL3_RANDOM_SIZE -
         ECH_CONFIRMATION_SIGNAL_LEN;
}

bool ssl_ech_accept_confirmation(const SSL_HANDSHAKE *hs, Span<uint8_t> out,
                                 Span<const uint8_t> client_random,
                                 const SSLTranscript &transcript, bool is_hrr,
                                 Span<const uint8_t> msg, size_t offset) {
  // See draft-ietf-tls-esni-13, sections 7.2 and 7.2.1.
  static const uint8_t kZeros[EVP_MAX_MD_SIZE] = {0};

  // We hash |msg|, with bytes from |offset| zeroed.
  if (msg.size() < offset + ECH_CONFIRMATION_SIGNAL_LEN) {
    OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
    return false;
  }

  auto before_zeros = msg.subspan(0, offset);
  auto after_zeros = msg.subspan(offset + ECH_CONFIRMATION_SIGNAL_LEN);
  uint8_t context[EVP_MAX_MD_SIZE];
  unsigned context_len;
  ScopedEVP_MD_CTX ctx;
  if (!transcript.CopyToHashContext(ctx.get(), transcript.Digest()) ||
      !EVP_DigestUpdate(ctx.get(), before_zeros.data(), before_zeros.size()) ||
      !EVP_DigestUpdate(ctx.get(), kZeros, ECH_CONFIRMATION_SIGNAL_LEN) ||
      !EVP_DigestUpdate(ctx.get(), after_zeros.data(), after_zeros.size()) ||
      !EVP_DigestFinal_ex(ctx.get(), context, &context_len)) {
    return false;
  }

  uint8_t secret[EVP_MAX_MD_SIZE];
  size_t secret_len;
  if (!HKDF_extract(secret, &secret_len, transcript.Digest(),
                    client_random.data(), client_random.size(), kZeros,
                    transcript.DigestLen())) {
    return false;
  }

  assert(out.size() == ECH_CONFIRMATION_SIGNAL_LEN);
  return hkdf_expand_label(
      out, transcript.Digest(), MakeConstSpan(secret, secret_len),
      is_hrr ? label_to_span("hrr ech accept confirmation")
             : label_to_span("ech accept confirmation"),
      MakeConstSpan(context, context_len), SSL_is_dtls(hs->ssl));
}

BSSL_NAMESPACE_END
