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


int tls13_init_key_schedule(SSL_HANDSHAKE *hs) {
  SSL *const ssl = hs->ssl;
  const EVP_MD *digest = ssl_get_handshake_digest(ssl_get_algorithm_prf(ssl));

  hs->hash_len = EVP_MD_size(digest);

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

  /* Initialize the rolling hashes and release the handshake buffer. */
  if (!ssl3_init_handshake_hash(ssl)) {
    return 0;
  }
  ssl3_free_handshake_buffer(ssl);
  return 1;
}

int tls13_advance_key_schedule(SSL_HANDSHAKE *hs, const uint8_t *in,
                               size_t len) {
  const EVP_MD *digest =
      ssl_get_handshake_digest(ssl_get_algorithm_prf(hs->ssl));

  return HKDF_extract(hs->secret, &hs->hash_len, digest, in, len, hs->secret,
                      hs->hash_len);
}

static int hkdf_expand_label(uint8_t *out, const EVP_MD *digest,
                             const uint8_t *secret, size_t secret_len,
                             const uint8_t *label, size_t label_len,
                             const uint8_t *hash, size_t hash_len, size_t len) {
  static const char kTLS13LabelVersion[] = "TLS 1.3, ";

  CBB cbb, child;
  uint8_t *hkdf_label;
  size_t hkdf_label_len;
  if (!CBB_init(&cbb, 2 + 1 + strlen(kTLS13LabelVersion) + label_len + 1 +
                          hash_len) ||
      !CBB_add_u16(&cbb, len) ||
      !CBB_add_u8_length_prefixed(&cbb, &child) ||
      !CBB_add_bytes(&child, (const uint8_t *)kTLS13LabelVersion,
                     strlen(kTLS13LabelVersion)) ||
      !CBB_add_bytes(&child, label, label_len) ||
      !CBB_add_u8_length_prefixed(&cbb, &child) ||
      !CBB_add_bytes(&child, hash, hash_len) ||
      !CBB_finish(&cbb, &hkdf_label, &hkdf_label_len)) {
    CBB_cleanup(&cbb);
    return 0;
  }

  int ret = HKDF_expand(out, len, digest, secret, secret_len, hkdf_label,
                        hkdf_label_len);
  OPENSSL_free(hkdf_label);
  return ret;
}

int tls13_get_context_hash(SSL *ssl, uint8_t *out, size_t *out_len) {
  EVP_MD_CTX ctx;
  EVP_MD_CTX_init(&ctx);
  unsigned handshake_len = 0;
  int ok = EVP_MD_CTX_copy_ex(&ctx, &ssl->s3->handshake_hash) &&
           EVP_DigestFinal_ex(&ctx, out, &handshake_len);
  EVP_MD_CTX_cleanup(&ctx);
  if (ok) {
    *out_len = handshake_len;
  }
  return ok;
}

/* 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 one on success and zero on error. */
static int derive_secret(SSL_HANDSHAKE *hs, uint8_t *out, size_t len,
                         const uint8_t *label, size_t label_len) {
  SSL *const ssl = hs->ssl;
  const EVP_MD *digest = ssl_get_handshake_digest(ssl_get_algorithm_prf(ssl));

  uint8_t context_hash[EVP_MAX_MD_SIZE];
  size_t context_hash_len;
  if (!tls13_get_context_hash(ssl, context_hash, &context_hash_len)) {
    return 0;
  }

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

int tls13_set_traffic_key(SSL *ssl, enum evp_aead_direction_t direction,
                          const uint8_t *traffic_secret,
                          size_t traffic_secret_len) {
  if (traffic_secret_len > 0xff) {
    OPENSSL_PUT_ERROR(SSL, ERR_R_OVERFLOW);
    return 0;
  }

  /* Look up cipher suite properties. */
  const EVP_AEAD *aead;
  const EVP_MD *digest = ssl_get_handshake_digest(ssl_get_algorithm_prf(ssl));
  size_t discard;
  if (!ssl_cipher_get_evp_aead(&aead, &discard, &discard,
                               SSL_get_session(ssl)->cipher,
                               ssl3_protocol_version(ssl))) {
    return 0;
  }

  /* 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,
                         (const uint8_t *)"key", 3, NULL, 0, key_len)) {
    return 0;
  }

  /* 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,
                         (const uint8_t *)"iv", 2, NULL, 0, iv_len)) {
    return 0;
  }

  SSL_AEAD_CTX *traffic_aead = SSL_AEAD_CTX_new(
      direction, ssl3_protocol_version(ssl), SSL_get_session(ssl)->cipher, key,
      key_len, NULL, 0, iv, iv_len);
  if (traffic_aead == NULL) {
    return 0;
  }

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

  /* 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;
  } else {
    OPENSSL_memmove(ssl->s3->write_traffic_secret, traffic_secret,
                    traffic_secret_len);
    ssl->s3->write_traffic_secret_len = traffic_secret_len;
  }

  return 1;
}

static const char kTLS13LabelClientHandshakeTraffic[] =
    "client handshake traffic secret";
static const char kTLS13LabelServerHandshakeTraffic[] =
    "server handshake traffic secret";
static const char kTLS13LabelClientApplicationTraffic[] =
    "client application traffic secret";
static const char kTLS13LabelServerApplicationTraffic[] =
    "server application traffic secret";

int tls13_derive_handshake_secrets(SSL_HANDSHAKE *hs) {
  SSL *const ssl = hs->ssl;
  return derive_secret(hs, hs->client_handshake_secret, hs->hash_len,
                       (const uint8_t *)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,
                       (const uint8_t *)kTLS13LabelServerHandshakeTraffic,
                       strlen(kTLS13LabelServerHandshakeTraffic)) &&
         ssl_log_secret(ssl, "SERVER_HANDSHAKE_TRAFFIC_SECRET",
                        hs->server_handshake_secret, hs->hash_len);
}

static const char kTLS13LabelExporter[] = "exporter master secret";

int tls13_derive_application_secrets(SSL_HANDSHAKE *hs) {
  SSL *const ssl = hs->ssl;
  ssl->s3->exporter_secret_len = hs->hash_len;
  return derive_secret(hs, hs->client_traffic_secret_0, hs->hash_len,
                       (const uint8_t *)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,
                       (const uint8_t *)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,
                       (const uint8_t *)kTLS13LabelExporter,
                       strlen(kTLS13LabelExporter));
}

static const char kTLS13LabelApplicationTraffic[] =
    "application traffic secret";

int tls13_rotate_traffic_key(SSL *ssl, enum evp_aead_direction_t direction) {
  const EVP_MD *digest = ssl_get_handshake_digest(ssl_get_algorithm_prf(ssl));

  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;
  }

  if (!hkdf_expand_label(secret, digest, secret, secret_len,
                         (const uint8_t *)kTLS13LabelApplicationTraffic,
                         strlen(kTLS13LabelApplicationTraffic), NULL, 0,
                         secret_len)) {
    return 0;
  }

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

static const char kTLS13LabelResumption[] = "resumption master secret";

int tls13_derive_resumption_secret(SSL_HANDSHAKE *hs) {
  SSL *const ssl = hs->ssl;
  if (ssl->s3->hs->hash_len > SSL_MAX_MASTER_KEY_LENGTH) {
    OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
    return 0;
  }

  ssl->s3->new_session->master_key_length = hs->hash_len;
  return derive_secret(hs, ssl->s3->new_session->master_key,
                       ssl->s3->new_session->master_key_length,
                       (const uint8_t *)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 int tls13_verify_data(const EVP_MD *digest, 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,
                         (const uint8_t *)kTLS13LabelFinished,
                         strlen(kTLS13LabelFinished), NULL, 0, hash_len) ||
      HMAC(digest, key, hash_len, context, context_len, out, &len) == NULL) {
    return 0;
  }
  *out_len = len;
  return 1;
}

int tls13_finished_mac(SSL_HANDSHAKE *hs, uint8_t *out, size_t *out_len,
                       int is_server) {
  SSL *const ssl = hs->ssl;
  const EVP_MD *digest = ssl_get_handshake_digest(ssl_get_algorithm_prf(ssl));

  const uint8_t *traffic_secret;
  if (is_server == ssl->server) {
    traffic_secret = ssl->s3->write_traffic_secret;
  } else {
    traffic_secret = ssl->s3->read_traffic_secret;
  }

  uint8_t context_hash[EVP_MAX_MD_SIZE];
  size_t context_hash_len;
  if (!tls13_get_context_hash(ssl, context_hash, &context_hash_len) ||
      !tls13_verify_data(digest, out, out_len, traffic_secret, hs->hash_len,
                         context_hash, context_hash_len)) {
    return 0;
  }
  return 1;
}

int tls13_export_keying_material(SSL *ssl, uint8_t *out, size_t out_len,
                                 const char *label, size_t label_len,
                                 const uint8_t *context, size_t context_len,
                                 int use_context) {
  const EVP_MD *digest = ssl_get_handshake_digest(ssl_get_algorithm_prf(ssl));

  const uint8_t *hash = NULL;
  size_t hash_len = 0;
  if (use_context) {
    hash = context;
    hash_len = context_len;
  }
  return hkdf_expand_label(out, digest, ssl->s3->exporter_secret,
                           ssl->s3->exporter_secret_len, (const uint8_t *)label,
                           label_len, hash, hash_len, out_len);
}

static const char kTLS13LabelPSKBinder[] = "resumption psk binder key";

static int tls13_psk_binder(SSL *ssl, uint8_t *out, 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 0;
  }

  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 0;
  }

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

  return 1;
}

int tls13_write_psk_binder(SSL *ssl, uint8_t *msg, size_t len) {
  const EVP_MD *digest =
      ssl_get_handshake_digest(ssl->session->cipher->algorithm_prf);
  size_t hash_len = EVP_MD_size(digest);

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

  EVP_MD_CTX ctx;
  EVP_MD_CTX_init(&ctx);
  uint8_t context[EVP_MAX_MD_SIZE];
  unsigned context_len;
  if (!EVP_DigestInit_ex(&ctx, digest, NULL) ||
      !EVP_DigestUpdate(&ctx, ssl->s3->handshake_buffer->data,
                        ssl->s3->handshake_buffer->length) ||
      !EVP_DigestUpdate(&ctx, msg, len - hash_len - 3) ||
      !EVP_DigestFinal_ex(&ctx, context, &context_len)) {
    EVP_MD_CTX_cleanup(&ctx);
    return 0;
  }

  EVP_MD_CTX_cleanup(&ctx);

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

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

int tls13_verify_psk_binder(SSL *ssl, SSL_SESSION *session,
                            CBS *binders) {
  const EVP_MD *digest =
      ssl_get_handshake_digest(session->cipher->algorithm_prf);
  size_t hash_len = EVP_MD_size(digest);

  /* Get the full ClientHello, including message header. It must be large enough
   * to exclude the binders. */
  CBS message;
  ssl->method->get_current_message(ssl, &message);
  if (CBS_len(&message) < CBS_len(binders) + 2) {
    OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
    return 0;
  }

  /* Hash a ClientHello prefix up to the binders. 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(&message), CBS_len(&message) - CBS_len(binders) - 2,
                  context, &context_len, digest, NULL)) {
    return 0;
  }

  uint8_t verify_data[EVP_MAX_MD_SIZE] = {0};
  CBS binder;
  if (!tls13_psk_binder(ssl, verify_data, 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 0;
  }

  int 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 = 1;
#endif
  if (!binder_ok) {
    OPENSSL_PUT_ERROR(SSL, SSL_R_DIGEST_CHECK_FAILED);
    return 0;
  }

  return 1;
}
