/* Copyright (c) 2015, 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/err.h>
#include <openssl/rand.h>

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


SSL_AEAD_CTX *SSL_AEAD_CTX_new(enum evp_aead_direction_t direction,
                               uint16_t version, int is_dtls,
                               const SSL_CIPHER *cipher, const uint8_t *enc_key,
                               size_t enc_key_len, const uint8_t *mac_key,
                               size_t mac_key_len, const uint8_t *fixed_iv,
                               size_t fixed_iv_len) {
  const EVP_AEAD *aead;
  size_t expected_mac_key_len, expected_fixed_iv_len;
  if (!ssl_cipher_get_evp_aead(&aead, &expected_mac_key_len,
                               &expected_fixed_iv_len, cipher, version,
                               is_dtls) ||
      /* Ensure the caller returned correct key sizes. */
      expected_fixed_iv_len != fixed_iv_len ||
      expected_mac_key_len != mac_key_len) {
    OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
    return 0;
  }

  uint8_t merged_key[EVP_AEAD_MAX_KEY_LENGTH];
  if (mac_key_len > 0) {
    /* This is a "stateful" AEAD (for compatibility with pre-AEAD cipher
     * suites). */
    if (mac_key_len + enc_key_len + fixed_iv_len > sizeof(merged_key)) {
      OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
      return 0;
    }
    OPENSSL_memcpy(merged_key, mac_key, mac_key_len);
    OPENSSL_memcpy(merged_key + mac_key_len, enc_key, enc_key_len);
    OPENSSL_memcpy(merged_key + mac_key_len + enc_key_len, fixed_iv,
                   fixed_iv_len);
    enc_key = merged_key;
    enc_key_len += mac_key_len;
    enc_key_len += fixed_iv_len;
  }

  SSL_AEAD_CTX *aead_ctx = (SSL_AEAD_CTX *)OPENSSL_malloc(sizeof(SSL_AEAD_CTX));
  if (aead_ctx == NULL) {
    OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
    return NULL;
  }
  OPENSSL_memset(aead_ctx, 0, sizeof(SSL_AEAD_CTX));
  aead_ctx->cipher = cipher;
  aead_ctx->version = version;

  if (!EVP_AEAD_CTX_init_with_direction(
          &aead_ctx->ctx, aead, enc_key, enc_key_len,
          EVP_AEAD_DEFAULT_TAG_LENGTH, direction)) {
    OPENSSL_free(aead_ctx);
    return NULL;
  }

  assert(EVP_AEAD_nonce_length(aead) <= EVP_AEAD_MAX_NONCE_LENGTH);
  static_assert(EVP_AEAD_MAX_NONCE_LENGTH < 256,
                "variable_nonce_len doesn't fit in uint8_t");
  aead_ctx->variable_nonce_len = (uint8_t)EVP_AEAD_nonce_length(aead);
  if (mac_key_len == 0) {
    assert(fixed_iv_len <= sizeof(aead_ctx->fixed_nonce));
    OPENSSL_memcpy(aead_ctx->fixed_nonce, fixed_iv, fixed_iv_len);
    aead_ctx->fixed_nonce_len = fixed_iv_len;

    if (cipher->algorithm_enc & SSL_CHACHA20POLY1305) {
      /* The fixed nonce into the actual nonce (the sequence number). */
      aead_ctx->xor_fixed_nonce = 1;
      aead_ctx->variable_nonce_len = 8;
    } else {
      /* The fixed IV is prepended to the nonce. */
      assert(fixed_iv_len <= aead_ctx->variable_nonce_len);
      aead_ctx->variable_nonce_len -= fixed_iv_len;
    }

    /* AES-GCM uses an explicit nonce. */
    if (cipher->algorithm_enc & (SSL_AES128GCM | SSL_AES256GCM)) {
      aead_ctx->variable_nonce_included_in_record = 1;
    }

    /* The TLS 1.3 construction XORs the fixed nonce into the sequence number
     * and omits the additional data. */
    if (version >= TLS1_3_VERSION) {
      aead_ctx->xor_fixed_nonce = 1;
      aead_ctx->variable_nonce_len = 8;
      aead_ctx->variable_nonce_included_in_record = 0;
      aead_ctx->omit_ad = 1;
      assert(fixed_iv_len >= aead_ctx->variable_nonce_len);
    }
  } else {
    assert(version < TLS1_3_VERSION);
    aead_ctx->variable_nonce_included_in_record = 1;
    aead_ctx->random_variable_nonce = 1;
    aead_ctx->omit_length_in_ad = 1;
    aead_ctx->omit_version_in_ad = (version == SSL3_VERSION);
  }

  return aead_ctx;
}

void SSL_AEAD_CTX_free(SSL_AEAD_CTX *aead) {
  if (aead == NULL) {
    return;
  }
  EVP_AEAD_CTX_cleanup(&aead->ctx);
  OPENSSL_free(aead);
}

size_t SSL_AEAD_CTX_explicit_nonce_len(const SSL_AEAD_CTX *aead) {
#if defined(BORINGSSL_UNSAFE_FUZZER_MODE)
  aead = NULL;
#endif

  if (aead != NULL && aead->variable_nonce_included_in_record) {
    return aead->variable_nonce_len;
  }
  return 0;
}

size_t SSL_AEAD_CTX_max_suffix_len(const SSL_AEAD_CTX *aead,
                                   size_t extra_in_len) {
#if defined(BORINGSSL_UNSAFE_FUZZER_MODE)
  aead = NULL;
#endif

  return extra_in_len +
         (aead == NULL ? 0 : EVP_AEAD_max_overhead(aead->ctx.aead));
}

size_t SSL_AEAD_CTX_max_overhead(const SSL_AEAD_CTX *aead) {
  return SSL_AEAD_CTX_explicit_nonce_len(aead) +
         SSL_AEAD_CTX_max_suffix_len(aead, 0);
}

/* ssl_aead_ctx_get_ad writes the additional data for |aead| into |out| and
 * returns the number of bytes written. */
static size_t ssl_aead_ctx_get_ad(SSL_AEAD_CTX *aead, uint8_t out[13],
                                  uint8_t type, uint16_t wire_version,
                                  const uint8_t seqnum[8],
                                  size_t plaintext_len) {
  if (aead->omit_ad) {
    return 0;
  }

  OPENSSL_memcpy(out, seqnum, 8);
  size_t len = 8;
  out[len++] = type;
  if (!aead->omit_version_in_ad) {
    out[len++] = (uint8_t)(wire_version >> 8);
    out[len++] = (uint8_t)wire_version;
  }
  if (!aead->omit_length_in_ad) {
    out[len++] = (uint8_t)(plaintext_len >> 8);
    out[len++] = (uint8_t)plaintext_len;
  }
  return len;
}

int SSL_AEAD_CTX_open(SSL_AEAD_CTX *aead, CBS *out, uint8_t type,
                      uint16_t wire_version, const uint8_t seqnum[8],
                      uint8_t *in, size_t in_len) {
#if defined(BORINGSSL_UNSAFE_FUZZER_MODE)
  aead = NULL;
#endif

  if (aead == NULL) {
    /* Handle the initial NULL cipher. */
    CBS_init(out, in, in_len);
    return 1;
  }

  /* TLS 1.2 AEADs include the length in the AD and are assumed to have fixed
   * overhead. Otherwise the parameter is unused. */
  size_t plaintext_len = 0;
  if (!aead->omit_length_in_ad) {
    size_t overhead = SSL_AEAD_CTX_max_overhead(aead);
    if (in_len < overhead) {
      /* Publicly invalid. */
      OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_PACKET_LENGTH);
      return 0;
    }
    plaintext_len = in_len - overhead;
  }
  uint8_t ad[13];
  size_t ad_len = ssl_aead_ctx_get_ad(aead, ad, type, wire_version, seqnum,
                                      plaintext_len);

  /* Assemble the nonce. */
  uint8_t nonce[EVP_AEAD_MAX_NONCE_LENGTH];
  size_t nonce_len = 0;

  /* Prepend the fixed nonce, or left-pad with zeros if XORing. */
  if (aead->xor_fixed_nonce) {
    nonce_len = aead->fixed_nonce_len - aead->variable_nonce_len;
    OPENSSL_memset(nonce, 0, nonce_len);
  } else {
    OPENSSL_memcpy(nonce, aead->fixed_nonce, aead->fixed_nonce_len);
    nonce_len += aead->fixed_nonce_len;
  }

  /* Add the variable nonce. */
  if (aead->variable_nonce_included_in_record) {
    if (in_len < aead->variable_nonce_len) {
      /* Publicly invalid. */
      OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_PACKET_LENGTH);
      return 0;
    }
    OPENSSL_memcpy(nonce + nonce_len, in, aead->variable_nonce_len);
    in += aead->variable_nonce_len;
    in_len -= aead->variable_nonce_len;
  } else {
    assert(aead->variable_nonce_len == 8);
    OPENSSL_memcpy(nonce + nonce_len, seqnum, aead->variable_nonce_len);
  }
  nonce_len += aead->variable_nonce_len;

  /* XOR the fixed nonce, if necessary. */
  if (aead->xor_fixed_nonce) {
    assert(nonce_len == aead->fixed_nonce_len);
    for (size_t i = 0; i < aead->fixed_nonce_len; i++) {
      nonce[i] ^= aead->fixed_nonce[i];
    }
  }

  /* Decrypt in-place. */
  size_t len;
  if (!EVP_AEAD_CTX_open(&aead->ctx, in, &len, in_len, nonce, nonce_len,
                         in, in_len, ad, ad_len)) {
    return 0;
  }
  CBS_init(out, in, len);
  return 1;
}

int SSL_AEAD_CTX_seal_scatter(SSL_AEAD_CTX *aead, uint8_t *out_prefix,
                              uint8_t *out, uint8_t *out_suffix,
                              size_t *out_suffix_len, size_t max_out_suffix_len,
                              uint8_t type, uint16_t wire_version,
                              const uint8_t seqnum[8], const uint8_t *in,
                              size_t in_len, const uint8_t *extra_in,
                              size_t extra_in_len) {
#if defined(BORINGSSL_UNSAFE_FUZZER_MODE)
  aead = NULL;
#endif

  if ((in != out && buffers_alias(in, in_len, out, in_len)) ||
      buffers_alias(in, in_len, out_suffix, max_out_suffix_len)) {
    OPENSSL_PUT_ERROR(SSL, SSL_R_OUTPUT_ALIASES_INPUT);
    return 0;
  }
  if (extra_in_len > max_out_suffix_len) {
    OPENSSL_PUT_ERROR(SSL, SSL_R_BUFFER_TOO_SMALL);
    return 0;
  }

  if (aead == NULL) {
    /* Handle the initial NULL cipher. */
    OPENSSL_memmove(out, in, in_len);
    OPENSSL_memmove(out_suffix, extra_in, extra_in_len);
    *out_suffix_len = extra_in_len;
    return 1;
  }

  uint8_t ad[13];
  size_t ad_len = ssl_aead_ctx_get_ad(aead, ad, type, wire_version, seqnum,
                                      in_len);

  /* Assemble the nonce. */
  uint8_t nonce[EVP_AEAD_MAX_NONCE_LENGTH];
  size_t nonce_len = 0;

  /* Prepend the fixed nonce, or left-pad with zeros if XORing. */
  if (aead->xor_fixed_nonce) {
    nonce_len = aead->fixed_nonce_len - aead->variable_nonce_len;
    OPENSSL_memset(nonce, 0, nonce_len);
  } else {
    OPENSSL_memcpy(nonce, aead->fixed_nonce, aead->fixed_nonce_len);
    nonce_len += aead->fixed_nonce_len;
  }

  /* Select the variable nonce. */
  if (aead->random_variable_nonce) {
    assert(aead->variable_nonce_included_in_record);
    if (!RAND_bytes(nonce + nonce_len, aead->variable_nonce_len)) {
      return 0;
    }
  } else {
    /* When sending we use the sequence number as the variable part of the
     * nonce. */
    assert(aead->variable_nonce_len == 8);
    OPENSSL_memcpy(nonce + nonce_len, seqnum, aead->variable_nonce_len);
  }
  nonce_len += aead->variable_nonce_len;

  /* Emit the variable nonce if included in the record. */
  if (aead->variable_nonce_included_in_record) {
    assert(!aead->xor_fixed_nonce);
    if (buffers_alias(in, in_len, out_prefix, aead->variable_nonce_len)) {
      OPENSSL_PUT_ERROR(SSL, SSL_R_OUTPUT_ALIASES_INPUT);
      return 0;
    }
    OPENSSL_memcpy(out_prefix, nonce + aead->fixed_nonce_len,
                   aead->variable_nonce_len);
  }

  /* XOR the fixed nonce, if necessary. */
  if (aead->xor_fixed_nonce) {
    assert(nonce_len == aead->fixed_nonce_len);
    for (size_t i = 0; i < aead->fixed_nonce_len; i++) {
      nonce[i] ^= aead->fixed_nonce[i];
    }
  }

  return EVP_AEAD_CTX_seal_scatter(&aead->ctx, out, out_suffix, out_suffix_len,
                                   max_out_suffix_len, nonce, nonce_len, in,
                                   in_len, extra_in, extra_in_len, ad, ad_len);
}

int SSL_AEAD_CTX_seal(SSL_AEAD_CTX *aead, uint8_t *out, size_t *out_len,
                      size_t max_out_len, uint8_t type, uint16_t wire_version,
                      const uint8_t seqnum[8], const uint8_t *in,
                      size_t in_len) {
  size_t prefix_len = SSL_AEAD_CTX_explicit_nonce_len(aead);
  if (in_len + prefix_len < in_len) {
    OPENSSL_PUT_ERROR(CIPHER, SSL_R_RECORD_TOO_LARGE);
    return 0;
  }
  if (in_len + prefix_len > max_out_len) {
    OPENSSL_PUT_ERROR(SSL, SSL_R_BUFFER_TOO_SMALL);
    return 0;
  }

  size_t suffix_len;
  if (!SSL_AEAD_CTX_seal_scatter(aead, out, out + prefix_len,
                                 out + prefix_len + in_len, &suffix_len,
                                 max_out_len - prefix_len - in_len, type,
                                 wire_version, seqnum, in, in_len, 0, 0)) {
    return 0;
  }
  assert(suffix_len <= SSL_AEAD_CTX_max_suffix_len(aead, 0));
  *out_len = prefix_len + in_len + suffix_len;
  return 1;
}
