// Copyright 2014 The BoringSSL Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include <openssl/aead.h>

#include <optional>

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

#include <openssl/cipher.h>
#include <openssl/err.h>
#include <openssl/mem.h>
#include <openssl/span.h>

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


using namespace bssl;

size_t EVP_AEAD_key_length(const EVP_AEAD *aead) { return aead->key_len; }

size_t EVP_AEAD_nonce_length(const EVP_AEAD *aead) { return aead->nonce_len; }

size_t EVP_AEAD_max_overhead(const EVP_AEAD *aead) { return aead->overhead; }

size_t EVP_AEAD_max_tag_len(const EVP_AEAD *aead) { return aead->max_tag_len; }

void EVP_AEAD_CTX_zero(EVP_AEAD_CTX *ctx) {
  OPENSSL_memset(ctx, 0, sizeof(EVP_AEAD_CTX));
}

EVP_AEAD_CTX *EVP_AEAD_CTX_new(const EVP_AEAD *aead, const uint8_t *key,
                               size_t key_len, size_t tag_len) {
  EVP_AEAD_CTX *ctx = New<EVP_AEAD_CTX>();
  if (!ctx) {
    return nullptr;
  }
  EVP_AEAD_CTX_zero(ctx);

  if (EVP_AEAD_CTX_init(ctx, aead, key, key_len, tag_len, nullptr)) {
    return ctx;
  }

  EVP_AEAD_CTX_free(ctx);
  return nullptr;
}

void EVP_AEAD_CTX_free(EVP_AEAD_CTX *ctx) {
  if (ctx == nullptr) {
    return;
  }
  EVP_AEAD_CTX_cleanup(ctx);
  Delete(ctx);
}

int EVP_AEAD_CTX_init(EVP_AEAD_CTX *ctx, const EVP_AEAD *aead,
                      const uint8_t *key, size_t key_len, size_t tag_len,
                      ENGINE *impl) {
  if (!aead->init) {
    OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_NO_DIRECTION_SET);
    ctx->aead = nullptr;
    return 0;
  }
  return EVP_AEAD_CTX_init_with_direction(ctx, aead, key, key_len, tag_len,
                                          evp_aead_open);
}

int EVP_AEAD_CTX_init_with_direction(EVP_AEAD_CTX *ctx, const EVP_AEAD *aead,
                                     const uint8_t *key, size_t key_len,
                                     size_t tag_len,
                                     enum evp_aead_direction_t dir) {
  if (key_len != aead->key_len) {
    OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_UNSUPPORTED_KEY_SIZE);
    ctx->aead = nullptr;
    return 0;
  }

  ctx->aead = aead;

  int ok;
  if (aead->init) {
    ok = aead->init(ctx, key, key_len, tag_len);
  } else {
    ok = aead->init_with_direction(ctx, key, key_len, tag_len, dir);
  }

  if (!ok) {
    ctx->aead = nullptr;
  }

  return ok;
}

void EVP_AEAD_CTX_cleanup(EVP_AEAD_CTX *ctx) {
  if (ctx->aead == nullptr) {
    return;
  }
  ctx->aead->cleanup(ctx);
  ctx->aead = nullptr;
}

// check_alias returns 1 if |out| is compatible with |in| and 0 otherwise. If
// |in| and |out| alias, we require that |in| == |out|.
static int check_alias(const uint8_t *in, size_t in_len, const uint8_t *out,
                       size_t out_len) {
  if (!buffers_alias(in, in_len, out, out_len)) {
    return 1;
  }

  return in == out;
}

int EVP_AEAD_CTX_seal(const EVP_AEAD_CTX *ctx, uint8_t *out, size_t *out_len,
                      size_t max_out_len, const uint8_t *nonce,
                      size_t nonce_len, const uint8_t *in, size_t in_len,
                      const uint8_t *ad, size_t ad_len) {
  bool ok = false;
  Cleanup cleanup([&] {
    if (!ok) {
      // In the event of an error, clear the output buffer so that a caller
      // that doesn't check the return value doesn't send raw data.
      OPENSSL_memset(out, 0, max_out_len);
      *out_len = 0;
    }
  });

  if (max_out_len < in_len) {
    OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BUFFER_TOO_SMALL);
    return 0;
  }

  CRYPTO_IOVEC iovec[1];
  iovec[0].in = in;
  iovec[0].out = out;
  iovec[0].len = in_len;
  CRYPTO_IVEC aadvec[1];
  aadvec[0].in = ad;
  aadvec[0].len = ad_len;
  if (!EVP_AEAD_CTX_sealv(ctx, iovec, 1, out + in_len, out_len,
                          max_out_len - in_len, nonce, nonce_len, aadvec, 1)) {
    *out_len = 0;
    return 0;
  }
  *out_len += in_len;
  ok = true;
  return 1;
}

int EVP_AEAD_CTX_seal_scatter(const EVP_AEAD_CTX *ctx, uint8_t *out,
                              uint8_t *out_tag, size_t *out_tag_len,
                              size_t max_out_tag_len, const uint8_t *nonce,
                              size_t nonce_len, const uint8_t *in,
                              size_t in_len, const uint8_t *extra_in,
                              size_t extra_in_len, const uint8_t *ad,
                              size_t ad_len) {
  bool ok = false;
  Cleanup cleanup([&] {
    if (!ok) {
      // In the event of an error, clear the output buffer so that a caller
      // that doesn't check the return value doesn't send raw data.
      OPENSSL_memset(out, 0, in_len);
      OPENSSL_memset(out_tag, 0, max_out_tag_len);
      *out_tag_len = 0;
    }
  });

  CRYPTO_IOVEC iovec[2];
  iovec[0].in = in;
  iovec[0].out = out;
  iovec[0].len = in_len;
  iovec[1].in = extra_in;
  iovec[1].out = out_tag;
  iovec[1].len = extra_in_len;
  CRYPTO_IVEC aadvec[1];
  aadvec[0].in = ad;
  aadvec[0].len = ad_len;
  if (!EVP_AEAD_CTX_sealv(
          ctx, iovec, extra_in_len ? 2 : 1, out_tag + extra_in_len, out_tag_len,
          max_out_tag_len - extra_in_len, nonce, nonce_len, aadvec, 1)) {
    *out_tag_len = 0;
    return 0;
  }
  *out_tag_len += extra_in_len;
  ok = true;
  return 1;
}

static bool check_iovec_internal_alias(Span<const CRYPTO_IOVEC> iovecs) {
  for (size_t i = 0; i < iovecs.size(); ++i) {
    // Same index check.
    if (!check_alias(iovecs[i].in, iovecs[i].len, iovecs[i].out,
                     iovecs[i].len)) {
      return false;
    }
#if !defined(NDEBUG)
    // Unrealistic cases; they'd be harmful but also extremely unlikely anyone
    // will ever get those wrong. Thus skip them in release builds.
    for (size_t j = i + 1; j < iovecs.size(); ++j) {
      if (buffers_alias(iovecs[i].in, iovecs[i].len,  //
                        iovecs[j].out, iovecs[j].len) ||
          buffers_alias(iovecs[i].out, iovecs[i].len,  //
                        iovecs[j].in, iovecs[j].len) ||
          buffers_alias(iovecs[i].out, iovecs[i].len,  //
                        iovecs[j].out, iovecs[j].len)) {
        return false;
      }
    }
#endif
  }
  return true;
}

#if !defined(NDEBUG)
static bool check_ivec_buf_alias(Span<const CRYPTO_IVEC> ivecs,
                                 const uint8_t *buf, size_t buf_len) {
  for (const CRYPTO_IVEC &ivec : ivecs) {
    if (buffers_alias(ivec.in, ivec.len, buf, buf_len)) {
      return false;
    }
  }
  return true;
}

static bool check_iovec_out_ivec_alias(Span<const CRYPTO_IOVEC> iovecs,
                                       Span<const CRYPTO_IVEC> ivecs) {
  for (const CRYPTO_IOVEC &iovec : iovecs) {
    if (!check_ivec_buf_alias(ivecs, iovec.out, iovec.len)) {
      return false;
    }
  }
  return true;
}

static bool check_iovec_buf_alias(Span<const CRYPTO_IOVEC> iovecs,
                                  const uint8_t *buf, size_t buf_len) {
  for (const CRYPTO_IOVEC &iovec : iovecs) {
    if (buffers_alias(iovec.in, iovec.len, buf, buf_len)) {
      return false;
    }
    if (buffers_alias(iovec.out, iovec.len, buf, buf_len)) {
      return false;
    }
  }
  return true;
}

static bool check_iovec_out_buf_alias(Span<const CRYPTO_IOVEC> iovecs,
                                      const uint8_t *buf, size_t buf_len) {
  for (const CRYPTO_IOVEC &iovec : iovecs) {
    if (buffers_alias(iovec.out, iovec.len, buf, buf_len)) {
      return false;
    }
  }
  return true;
}
#endif

static bool check_iovec_alias(Span<const CRYPTO_IOVEC> iovecs,
                              Span<const CRYPTO_IVEC> aadvecs,
                              const uint8_t *out, size_t out_len,
                              const uint8_t *in1, size_t in1_len,
                              const uint8_t *in2, size_t in2_len) {
  return
#if !defined(NDEBUG)
      // Unrealistic cases; they'd be harmful but also extremely unlikely anyone
      // will ever get those wrong. Thus skip them in release builds.
      //
      // iovec.out <-> aadvec.
      check_iovec_out_ivec_alias(iovecs, aadvecs) &&
      // iovec <-> out.
      check_iovec_buf_alias(iovecs, out, out_len) &&
      // iovec.out <-> in1.
      check_iovec_out_buf_alias(iovecs, in1, in1_len) &&
      // iovec.out <-> in2.
      check_iovec_out_buf_alias(iovecs, in2, in2_len) &&
      // aadvec <-> out.
      check_ivec_buf_alias(aadvecs, out, out_len) &&
      // out <-> in1.
      !buffers_alias(out, out_len, in1, in1_len) &&
      // out <-> in2.
      !buffers_alias(out, out_len, in2, in2_len) &&
#endif
      // iovec <-> iovec.
      check_iovec_internal_alias(iovecs);
}

static void clear_iovec(Span<const CRYPTO_IOVEC> iovecs) {
  for (const CRYPTO_IOVEC &iovec : iovecs) {
    OPENSSL_memset(iovec.out, 0, iovec.len);
  }
}

int EVP_AEAD_CTX_sealv(const EVP_AEAD_CTX *ctx, const CRYPTO_IOVEC *iovec,
                       size_t num_iovec, uint8_t *out_tag, size_t *out_tag_len,
                       size_t max_out_tag_len, const uint8_t *nonce,
                       size_t nonce_len, const CRYPTO_IVEC *aadvec,
                       size_t num_aadvec) {
  Span<const CRYPTO_IOVEC> iovecs(iovec, num_iovec);
  Span<const CRYPTO_IVEC> aadvecs(aadvec, num_aadvec);

  bool ok = false;
  Cleanup cleanup([&] {
    if (!ok) {
      // In the event of an error, clear the output buffer so that a caller
      // that doesn't check the return value doesn't send raw data.
      clear_iovec(iovecs);
      OPENSSL_memset(out_tag, 0, max_out_tag_len);
      *out_tag_len = 0;
    }
  });

  if (!bssl::iovec::IsValid(iovecs) || !bssl::iovec::IsValid(aadvecs)) {
    OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_TOO_LARGE);
    return 0;
  }

  // Enforce aliasing rules: no output may alias any input, with the one
  // exception that an iovec member's |in| and |out| pointers may be identical
  // for in-place operation.
  if (!check_iovec_alias(iovecs, aadvecs, out_tag, max_out_tag_len, nonce,
                         nonce_len, nullptr, 0)) {
    OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_OUTPUT_ALIASES_INPUT);
    return 0;
  }

  if (!ctx->aead->sealv) {
    OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_CTRL_NOT_IMPLEMENTED);
    return 0;
  }

  if (ctx->aead->sealv(ctx, iovecs, Span(out_tag, max_out_tag_len), out_tag_len,
                       Span(nonce, nonce_len), aadvecs)) {
    ok = true;
    return 1;
  }

  return 0;
}

int EVP_AEAD_CTX_open(const EVP_AEAD_CTX *ctx, uint8_t *out, size_t *out_len,
                      size_t max_out_len, const uint8_t *nonce,
                      size_t nonce_len, const uint8_t *in, size_t in_len,
                      const uint8_t *ad, size_t ad_len) {
  bool ok = false;
  Cleanup cleanup([&] {
    if (!ok) {
      // In the event of an error, clear the output buffer so that a caller
      // that doesn't check the return value doesn't try and process bad
      // data.
      OPENSSL_memset(out, 0, max_out_len);
      *out_len = 0;
    }
  });

  if (ctx->tag_len) {
    // If the tag length is known, the caller only needs to provide enough
    // space for in_len - tag_len.
    if (in_len < ctx->tag_len) {
      OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_DECRYPT);
      return 0;
    }
    size_t plaintext_len = in_len - ctx->tag_len;
    if (max_out_len < plaintext_len) {
      OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BUFFER_TOO_SMALL);
      return 0;
    }

    CRYPTO_IOVEC iovec[1];
    iovec[0].in = in;
    iovec[0].out = out;
    iovec[0].len = plaintext_len;
    CRYPTO_IVEC aadvec[1];
    aadvec[0].in = ad;
    aadvec[0].len = ad_len;
    if (!EVP_AEAD_CTX_openv_detached(ctx, iovec, 1, nonce, nonce_len,
                                     in + plaintext_len, ctx->tag_len, aadvec,
                                     1)) {
      return 0;
    }
    *out_len = plaintext_len;
    ok = true;
    return 1;
  }

  if (max_out_len < in_len) {
    // Variable tag length AEADs need to be able to decrypt the entire
    // plaintext before they can split it up. So the caller has to provide
    // sufficient max_out_len for temporary data.
    OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BUFFER_TOO_SMALL);
    return 0;
  }
  CRYPTO_IOVEC iovec[1];
  iovec[0].in = in;
  iovec[0].out = out;
  iovec[0].len = in_len;
  CRYPTO_IVEC aadvec[1];
  aadvec[0].in = ad;
  aadvec[0].len = ad_len;
  if (!EVP_AEAD_CTX_openv(ctx, iovec, 1, out_len, nonce, nonce_len, aadvec,
                          1)) {
    return 0;
  }
  ok = true;
  return 1;
}

int EVP_AEAD_CTX_open_gather(const EVP_AEAD_CTX *ctx, uint8_t *out,
                             const uint8_t *nonce, size_t nonce_len,
                             const uint8_t *in, size_t in_len,
                             const uint8_t *in_tag, size_t in_tag_len,
                             const uint8_t *ad, size_t ad_len) {
  bool ok = false;
  Cleanup cleanup([&] {
    if (!ok) {
      // In the event of an error, clear the output buffer so that a caller
      // that doesn't check the return value doesn't try and process bad
      // data.
      OPENSSL_memset(out, 0, in_len);
    }
  });

  CRYPTO_IOVEC iovec[1];
  iovec[0].in = in;
  iovec[0].out = out;
  iovec[0].len = in_len;
  CRYPTO_IVEC aadvec[1];
  aadvec[0].in = ad;
  aadvec[0].len = ad_len;
  if (!EVP_AEAD_CTX_openv_detached(ctx, iovec, 1, nonce, nonce_len, in_tag,
                                   in_tag_len, aadvec, 1)) {
    return 0;
  }
  ok = true;
  return 1;
}

int EVP_AEAD_CTX_openv(const EVP_AEAD_CTX *ctx, const CRYPTO_IOVEC *iovec,
                       size_t num_iovec, size_t *out_total_bytes,
                       const uint8_t *nonce, size_t nonce_len,
                       const CRYPTO_IVEC *aadvec, size_t num_aadvec) {
  Span<const CRYPTO_IOVEC> iovecs(iovec, num_iovec);
  Span<const CRYPTO_IVEC> aadvecs(aadvec, num_aadvec);

  bool ok = false;
  Cleanup cleanup([&] {
    if (!ok) {
      // In the event of an error, clear the output buffer so that a caller
      // that doesn't check the return value doesn't try and process bad
      // data.
      clear_iovec(iovecs);
      *out_total_bytes = 0;
    }
  });

  if (!bssl::iovec::IsValid(iovecs) || !bssl::iovec::IsValid(aadvecs)) {
    OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_TOO_LARGE);
    return 0;
  }

  // Enforce aliasing rules: no output may alias any input, with the one
  // exception that an iovec member's |in| and |out| pointers may be identical
  // for in-place operation.
  if (!check_iovec_alias(iovecs, aadvecs, nullptr, 0, nonce, nonce_len, nullptr,
                         0)) {
    OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_OUTPUT_ALIASES_INPUT);
    return 0;
  }

  if (!ctx->aead->openv) {
    if (ctx->tag_len && ctx->aead->openv_detached) {
      // Try with a detached tag.
      InplaceVector<CRYPTO_IOVEC, CRYPTO_IOVEC_MAX> detached_iovecs;
      detached_iovecs.CopyFrom(iovecs);

      uint8_t tagbuf[EVP_AEAD_MAX_OVERHEAD];
      std::optional<Span<const uint8_t>> tag = bssl::iovec::GetAndRemoveSuffix(
          Span(tagbuf).first(ctx->tag_len), Span(detached_iovecs));

      if (!tag.has_value()) {  // I.e. no |ctx->tag_len| bytes available.
        OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_DECRYPT);
        return 0;
      }

      if (ctx->aead->openv_detached(ctx, detached_iovecs,
                                    Span(nonce, nonce_len), *tag, aadvecs)) {
        ok = true;
        *out_total_bytes = bssl::iovec::TotalLength(Span(detached_iovecs));
        return 1;
      }
      return 0;
    }

    OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_CTRL_NOT_IMPLEMENTED);
    return 0;
  }

  if (ctx->aead->openv(ctx, iovecs, out_total_bytes, Span(nonce, nonce_len),
                       aadvecs)) {
    ok = true;
    return 1;
  }

  return 0;
}

int EVP_AEAD_CTX_openv_detached(const EVP_AEAD_CTX *ctx,
                                const CRYPTO_IOVEC *iovec, size_t num_iovec,
                                const uint8_t *nonce, size_t nonce_len,
                                const uint8_t *in_tag, size_t in_tag_len,
                                const CRYPTO_IVEC *aadvec, size_t num_aadvec) {
  Span<const CRYPTO_IOVEC> iovecs(iovec, num_iovec);
  Span<const CRYPTO_IVEC> aadvecs(aadvec, num_aadvec);

  bool ok = false;
  Cleanup cleanup([&] {
    if (!ok) {
      // In the event of an error, clear the output buffer so that a caller
      // that doesn't check the return value doesn't try and process bad
      // data.
      clear_iovec(iovecs);
    }
  });

  if (!bssl::iovec::IsValid(iovecs) || !bssl::iovec::IsValid(aadvecs)) {
    OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_TOO_LARGE);
    return 0;
  }
  if (in_tag_len > EVP_AEAD_MAX_OPEN_OVERHEAD) {
    OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_UNSUPPORTED_TAG_SIZE);
    return 0;
  }

  // Enforce aliasing rules: no output may alias any input, with the one
  // exception that an iovec member's |in| and |out| pointers may be identical
  // for in-place operation.
  if (!check_iovec_alias(iovecs, aadvecs, nullptr, 0, nonce, nonce_len, in_tag,
                         in_tag_len)) {
    OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_OUTPUT_ALIASES_INPUT);
    return 0;
  }

  if (!ctx->aead->openv_detached) {
    // AEADs with variable overhead may provide openv instead of openv_detached.
    // While one might call openv and then, on success, discard the result if
    // the length was wrong, this requires callers to predict the plaintext
    // length first. We do not expect callers to do this, especially in the TLS
    // CBC construction, where this length is sensitive to the Lucky 13 attack.
    OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_CTRL_NOT_IMPLEMENTED);
    return 0;
  }

  if (ctx->aead->openv_detached(ctx, iovecs, Span(nonce, nonce_len),
                                Span(in_tag, in_tag_len), aadvecs)) {
    ok = true;
    return 1;
  }

  return 0;
}

const EVP_AEAD *EVP_AEAD_CTX_aead(const EVP_AEAD_CTX *ctx) { return ctx->aead; }

int EVP_AEAD_CTX_get_iv(const EVP_AEAD_CTX *ctx, const uint8_t **out_iv,
                        size_t *out_len) {
  if (ctx->aead->get_iv == nullptr) {
    OPENSSL_PUT_ERROR(CIPHER, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
    return 0;
  }

  return ctx->aead->get_iv(ctx, out_iv, out_len);
}

int EVP_AEAD_CTX_tag_len(const EVP_AEAD_CTX *ctx, size_t *out_tag_len,
                         const size_t in_len, const size_t extra_in_len) {
  size_t tag_len;
  if (ctx->aead->tag_len) {
    if (in_len + extra_in_len < in_len) {
      OPENSSL_PUT_ERROR(CIPHER, ERR_R_OVERFLOW);
      *out_tag_len = 0;
      return 0;
    }
    tag_len = ctx->aead->tag_len(ctx, in_len + extra_in_len);
  } else {
    tag_len = ctx->tag_len;
  }

  if (extra_in_len + tag_len < extra_in_len) {
    OPENSSL_PUT_ERROR(CIPHER, ERR_R_OVERFLOW);
    *out_tag_len = 0;
    return 0;
  }
  *out_tag_len = extra_in_len + tag_len;
  return 1;
}
