/* 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 <utility>

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

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


BSSL_NAMESPACE_BEGIN

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

  hs->hash_len = hs->transcript.DigestLen();

  // Initialize the secret to the zero key.
  OPENSSL_memset(hs->secret, 0, hs->hash_len);

  return true;
}

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

  hs->transcript.FreeBuffer();
  return HKDF_extract(hs->secret, &hs->hash_len, hs->transcript.Digest(), psk,
                      psk_len, hs->secret, hs->hash_len);
}

bool tls13_init_early_key_schedule(SSL_HANDSHAKE *hs, const uint8_t *psk,
                                   size_t psk_len) {
  SSL *const ssl = hs->ssl;
  return init_key_schedule(hs, ssl_session_protocol_version(ssl->session.get()),
                           ssl->session->cipher) &&
         HKDF_extract(hs->secret, &hs->hash_len, hs->transcript.Digest(), psk,
                      psk_len, hs->secret, hs->hash_len);
}

static bool hkdf_expand_label(uint8_t *out, const EVP_MD *digest,
                              const uint8_t *secret, size_t secret_len,
                              const char *label, size_t label_len,
                              const uint8_t *hash, size_t hash_len,
                              size_t len) {
  static const char kTLS13ProtocolLabel[] = "tls13 ";

  ScopedCBB cbb;
  CBB child;
  Array<uint8_t> hkdf_label;
  if (!CBB_init(cbb.get(), 2 + 1 + strlen(kTLS13ProtocolLabel) + label_len + 1 +
                               hash_len) ||
      !CBB_add_u16(cbb.get(), len) ||
      !CBB_add_u8_length_prefixed(cbb.get(), &child) ||
      !CBB_add_bytes(&child, (const uint8_t *)kTLS13ProtocolLabel,
                     strlen(kTLS13ProtocolLabel)) ||
      !CBB_add_bytes(&child, (const uint8_t *)label, label_len) ||
      !CBB_add_u8_length_prefixed(cbb.get(), &child) ||
      !CBB_add_bytes(&child, hash, hash_len) ||
      !CBBFinishArray(cbb.get(), &hkdf_label)) {
    return false;
  }

  return HKDF_expand(out, len, digest, secret, secret_len, hkdf_label.data(),
                     hkdf_label.size());
}

static const char kTLS13LabelDerived[] = "derived";

bool tls13_advance_key_schedule(SSL_HANDSHAKE *hs, const uint8_t *in,
                                size_t len) {
  uint8_t derive_context[EVP_MAX_MD_SIZE];
  unsigned derive_context_len;
  if (!EVP_Digest(nullptr, 0, derive_context, &derive_context_len,
                  hs->transcript.Digest(), nullptr)) {
    return false;
  }

  if (!hkdf_expand_label(hs->secret, hs->transcript.Digest(), hs->secret,
                         hs->hash_len, kTLS13LabelDerived,
                         strlen(kTLS13LabelDerived), derive_context,
                         derive_context_len, hs->hash_len)) {
    return false;
  }

  return HKDF_extract(hs->secret, &hs->hash_len, hs->transcript.Digest(), in,
                      len, hs->secret, hs->hash_len);
}

// derive_secret derives a secret of length |len| and writes the result in |out|
// with the given label and the current base secret and most recently-saved
// handshake context. It returns true on success and false on error.
static bool derive_secret(SSL_HANDSHAKE *hs, uint8_t *out, size_t len,
                          const char *label, size_t label_len) {
  uint8_t context_hash[EVP_MAX_MD_SIZE];
  size_t context_hash_len;
  if (!hs->transcript.GetHash(context_hash, &context_hash_len)) {
    return false;
  }

  return hkdf_expand_label(out, hs->transcript.Digest(), hs->secret,
                           hs->hash_len, label, label_len, context_hash,
                           context_hash_len, len);
}

bool tls13_set_traffic_key(SSL *ssl, enum ssl_encryption_level_t level,
                           enum evp_aead_direction_t direction,
                           const uint8_t *traffic_secret,
                           size_t traffic_secret_len) {
  const SSL_SESSION *session = SSL_get_session(ssl);
  uint16_t version = ssl_session_protocol_version(session);

  if (traffic_secret_len > 0xff) {
    OPENSSL_PUT_ERROR(SSL, ERR_R_OVERFLOW);
    return false;
  }

  UniquePtr<SSLAEADContext> traffic_aead;
  if (ssl->quic_method == nullptr) {
    // Look up cipher suite properties.
    const EVP_AEAD *aead;
    size_t discard;
    if (!ssl_cipher_get_evp_aead(&aead, &discard, &discard, session->cipher,
                                 version, SSL_is_dtls(ssl))) {
      return false;
    }

    const EVP_MD *digest = ssl_session_get_digest(session);

    // Derive the key.
    size_t key_len = EVP_AEAD_key_length(aead);
    uint8_t key[EVP_AEAD_MAX_KEY_LENGTH];
    if (!hkdf_expand_label(key, digest, traffic_secret, traffic_secret_len,
                           "key", 3, NULL, 0, key_len)) {
      return false;
    }

    // Derive the IV.
    size_t iv_len = EVP_AEAD_nonce_length(aead);
    uint8_t iv[EVP_AEAD_MAX_NONCE_LENGTH];
    if (!hkdf_expand_label(iv, digest, traffic_secret, traffic_secret_len, "iv",
                           2, NULL, 0, iv_len)) {
      return false;
    }


    traffic_aead = SSLAEADContext::Create(
        direction, session->ssl_version, SSL_is_dtls(ssl), session->cipher,
        MakeConstSpan(key, key_len), Span<const uint8_t>(),
        MakeConstSpan(iv, iv_len));
  } else {
    // Install a placeholder SSLAEADContext so that SSL accessors work. The
    // encryption itself will be handled by the SSL_QUIC_METHOD.
    traffic_aead =
        SSLAEADContext::CreatePlaceholderForQUIC(version, session->cipher);
  }

  if (!traffic_aead) {
    return false;
  }

  if (direction == evp_aead_open) {
    if (!ssl->method->set_read_state(ssl, std::move(traffic_aead))) {
      return false;
    }
  } else {
    if (!ssl->method->set_write_state(ssl, std::move(traffic_aead))) {
      return false;
    }
  }

  // Save the traffic secret.
  if (direction == evp_aead_open) {
    OPENSSL_memmove(ssl->s3->read_traffic_secret, traffic_secret,
                    traffic_secret_len);
    ssl->s3->read_traffic_secret_len = traffic_secret_len;
    ssl->s3->read_level = level;
  } else {
    OPENSSL_memmove(ssl->s3->write_traffic_secret, traffic_secret,
                    traffic_secret_len);
    ssl->s3->write_traffic_secret_len = traffic_secret_len;
    ssl->s3->write_level = level;
  }

  return true;
}


static const char kTLS13LabelExporter[] = "exp master";
static const char kTLS13LabelEarlyExporter[] = "e 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_secrets(SSL_HANDSHAKE *hs) {
  SSL *const ssl = hs->ssl;
  if (!derive_secret(hs, hs->early_traffic_secret, hs->hash_len,
                     kTLS13LabelClientEarlyTraffic,
                     strlen(kTLS13LabelClientEarlyTraffic)) ||
      !ssl_log_secret(ssl, "CLIENT_EARLY_TRAFFIC_SECRET",
                      hs->early_traffic_secret, hs->hash_len) ||
      !derive_secret(hs, ssl->s3->early_exporter_secret, hs->hash_len,
                     kTLS13LabelEarlyExporter,
                     strlen(kTLS13LabelEarlyExporter))) {
    return false;
  }
  ssl->s3->early_exporter_secret_len = hs->hash_len;

  if (ssl->quic_method != nullptr) {
    if (ssl->server) {
      if (!ssl->quic_method->set_encryption_secrets(
              ssl, ssl_encryption_early_data, nullptr, hs->early_traffic_secret,
              hs->hash_len)) {
        OPENSSL_PUT_ERROR(SSL, SSL_R_QUIC_INTERNAL_ERROR);
        return false;
      }
    } else {
      if (!ssl->quic_method->set_encryption_secrets(
              ssl, ssl_encryption_early_data, hs->early_traffic_secret, nullptr,
              hs->hash_len)) {
        OPENSSL_PUT_ERROR(SSL, SSL_R_QUIC_INTERNAL_ERROR);
        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, hs->hash_len,
                     kTLS13LabelClientHandshakeTraffic,
                     strlen(kTLS13LabelClientHandshakeTraffic)) ||
      !ssl_log_secret(ssl, "CLIENT_HANDSHAKE_TRAFFIC_SECRET",
                      hs->client_handshake_secret, hs->hash_len) ||
      !derive_secret(hs, hs->server_handshake_secret, hs->hash_len,
                     kTLS13LabelServerHandshakeTraffic,
                     strlen(kTLS13LabelServerHandshakeTraffic)) ||
      !ssl_log_secret(ssl, "SERVER_HANDSHAKE_TRAFFIC_SECRET",
                      hs->server_handshake_secret, hs->hash_len)) {
    return false;
  }

  if (ssl->quic_method != nullptr) {
    if (ssl->server) {
      if (!ssl->quic_method->set_encryption_secrets(
              ssl, ssl_encryption_handshake, hs->client_handshake_secret,
              hs->server_handshake_secret, hs->hash_len)) {
        OPENSSL_PUT_ERROR(SSL, SSL_R_QUIC_INTERNAL_ERROR);
        return false;
      }
    } else {
      if (!ssl->quic_method->set_encryption_secrets(
              ssl, ssl_encryption_handshake, hs->server_handshake_secret,
              hs->client_handshake_secret, hs->hash_len)) {
        OPENSSL_PUT_ERROR(SSL, SSL_R_QUIC_INTERNAL_ERROR);
        return false;
      }
    }
  }

  return true;
}

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

  if (ssl->quic_method != nullptr) {
    if (ssl->server) {
      if (!ssl->quic_method->set_encryption_secrets(
              ssl, ssl_encryption_application, hs->client_traffic_secret_0,
              hs->server_traffic_secret_0, hs->hash_len)) {
        OPENSSL_PUT_ERROR(SSL, SSL_R_QUIC_INTERNAL_ERROR);
        return false;
      }
    } else {
      if (!ssl->quic_method->set_encryption_secrets(
              ssl, ssl_encryption_application, hs->server_traffic_secret_0,
              hs->client_traffic_secret_0, hs->hash_len)) {
        OPENSSL_PUT_ERROR(SSL, SSL_R_QUIC_INTERNAL_ERROR);
        return false;
      }
    }
  }

  return true;
}

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

bool tls13_rotate_traffic_key(SSL *ssl, enum evp_aead_direction_t direction) {
  uint8_t *secret;
  size_t secret_len;
  if (direction == evp_aead_open) {
    secret = ssl->s3->read_traffic_secret;
    secret_len = ssl->s3->read_traffic_secret_len;
  } else {
    secret = ssl->s3->write_traffic_secret;
    secret_len = ssl->s3->write_traffic_secret_len;
  }

  const EVP_MD *digest = ssl_session_get_digest(SSL_get_session(ssl));
  if (!hkdf_expand_label(secret, digest, secret, secret_len,
                         kTLS13LabelApplicationTraffic,
                         strlen(kTLS13LabelApplicationTraffic), NULL, 0,
                         secret_len)) {
    return false;
  }

  return tls13_set_traffic_key(ssl, ssl_encryption_application, direction,
                               secret, secret_len);
}

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

bool tls13_derive_resumption_secret(SSL_HANDSHAKE *hs) {
  if (hs->hash_len > SSL_MAX_MASTER_KEY_LENGTH) {
    OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
    return false;
  }
  hs->new_session->master_key_length = hs->hash_len;
  return derive_secret(hs, hs->new_session->master_key,
                       hs->new_session->master_key_length,
                       kTLS13LabelResumption, strlen(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.
static bool tls13_verify_data(const EVP_MD *digest, uint16_t version,
                              uint8_t *out, size_t *out_len,
                              const uint8_t *secret, size_t hash_len,
                              uint8_t *context, size_t context_len) {
  uint8_t key[EVP_MAX_MD_SIZE];
  unsigned len;
  if (!hkdf_expand_label(key, digest, secret, hash_len, kTLS13LabelFinished,
                         strlen(kTLS13LabelFinished), NULL, 0, hash_len) ||
      HMAC(digest, key, hash_len, context, context_len, out, &len) == NULL) {
    return false;
  }
  *out_len = len;
  return true;
}

bool tls13_finished_mac(SSL_HANDSHAKE *hs, uint8_t *out, size_t *out_len,
                        bool is_server) {
  const uint8_t *traffic_secret;
  if (is_server) {
    traffic_secret = hs->server_handshake_secret;
  } else {
    traffic_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(hs->transcript.Digest(), hs->ssl->version, out,
                         out_len, traffic_secret, hs->hash_len, context_hash,
                         context_hash_len)) {
    return 0;
  }
  return 1;
}

static const char kTLS13LabelResumptionPSK[] = "resumption";

bool tls13_derive_session_psk(SSL_SESSION *session, Span<const uint8_t> nonce) {
  const EVP_MD *digest = ssl_session_get_digest(session);
  return hkdf_expand_label(session->master_key, digest, session->master_key,
                           session->master_key_length, kTLS13LabelResumptionPSK,
                           strlen(kTLS13LabelResumptionPSK), nonce.data(),
                           nonce.size(), session->master_key_length);
}

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[EVP_MAX_MD_SIZE];
  uint8_t export_context[EVP_MAX_MD_SIZE];
  uint8_t derived_secret[EVP_MAX_MD_SIZE];
  unsigned hash_len;
  unsigned export_context_len;
  unsigned derived_secret_len = EVP_MD_size(digest);
  return EVP_Digest(context.data(), context.size(), hash, &hash_len, digest,
                    nullptr) &&
         EVP_Digest(nullptr, 0, export_context, &export_context_len, digest,
                    nullptr) &&
         hkdf_expand_label(derived_secret, digest, secret.data(), secret.size(),
                           label.data(), label.size(), export_context,
                           export_context_len, derived_secret_len) &&
         hkdf_expand_label(out.data(), digest, derived_secret,
                           derived_secret_len, kTLS13LabelExportKeying,
                           strlen(kTLS13LabelExportKeying), hash, hash_len,
                           out.size());
}

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

static bool tls13_psk_binder(uint8_t *out, uint16_t version,
                             const EVP_MD *digest, uint8_t *psk, size_t psk_len,
                             uint8_t *context, size_t context_len,
                             size_t hash_len) {
  uint8_t binder_context[EVP_MAX_MD_SIZE];
  unsigned binder_context_len;
  if (!EVP_Digest(NULL, 0, binder_context, &binder_context_len, digest, NULL)) {
    return false;
  }

  uint8_t early_secret[EVP_MAX_MD_SIZE] = {0};
  size_t early_secret_len;
  if (!HKDF_extract(early_secret, &early_secret_len, digest, psk, hash_len,
                    NULL, 0)) {
    return false;
  }

  uint8_t binder_key[EVP_MAX_MD_SIZE] = {0};
  size_t len;
  if (!hkdf_expand_label(binder_key, digest, early_secret, hash_len,
                         kTLS13LabelPSKBinder, strlen(kTLS13LabelPSKBinder),
                         binder_context, binder_context_len, hash_len) ||
      !tls13_verify_data(digest, version, out, &len, binder_key, hash_len,
                         context, context_len)) {
    return false;
  }

  return true;
}

bool tls13_write_psk_binder(SSL_HANDSHAKE *hs, uint8_t *msg, size_t len) {
  SSL *const ssl = hs->ssl;
  const EVP_MD *digest = ssl_session_get_digest(ssl->session.get());
  size_t hash_len = EVP_MD_size(digest);

  if (len < hash_len + 3) {
    OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
    return false;
  }

  ScopedEVP_MD_CTX ctx;
  uint8_t context[EVP_MAX_MD_SIZE];
  unsigned context_len;

  if (!EVP_DigestInit_ex(ctx.get(), digest, NULL) ||
      !EVP_DigestUpdate(ctx.get(), hs->transcript.buffer().data(),
                        hs->transcript.buffer().size()) ||
      !EVP_DigestUpdate(ctx.get(), msg, len - hash_len - 3) ||
      !EVP_DigestFinal_ex(ctx.get(), context, &context_len)) {
    return false;
  }

  uint8_t verify_data[EVP_MAX_MD_SIZE] = {0};
  if (!tls13_psk_binder(verify_data, ssl->session->ssl_version, digest,
                        ssl->session->master_key,
                        ssl->session->master_key_length, context, context_len,
                        hash_len)) {
    return false;
  }

  OPENSSL_memcpy(msg + len - hash_len, verify_data, hash_len);
  return true;
}

bool tls13_verify_psk_binder(SSL_HANDSHAKE *hs, SSL_SESSION *session,
                             const SSLMessage &msg, CBS *binders) {
  size_t hash_len = hs->transcript.DigestLen();

  // The message must be large enough to exclude the binders.
  if (CBS_len(&msg.raw) < CBS_len(binders) + 2) {
    OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
    return false;
  }

  // Hash a ClientHello prefix up to the binders. This includes the header. For
  // now, this assumes we only ever verify PSK binders on initial
  // ClientHellos.
  uint8_t context[EVP_MAX_MD_SIZE];
  unsigned context_len;
  if (!EVP_Digest(CBS_data(&msg.raw), CBS_len(&msg.raw) - CBS_len(binders) - 2,
                  context, &context_len, hs->transcript.Digest(), NULL)) {
    return false;
  }

  uint8_t verify_data[EVP_MAX_MD_SIZE] = {0};
  CBS binder;
  if (!tls13_psk_binder(verify_data, hs->ssl->version, hs->transcript.Digest(),
                        session->master_key, session->master_key_length,
                        context, context_len, hash_len) ||
      // 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) == hash_len &&
                   CRYPTO_memcmp(CBS_data(&binder), verify_data, hash_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;
}

BSSL_NAMESPACE_END
