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


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 =
      reinterpret_cast<EVP_AEAD_CTX *>(OPENSSL_malloc(sizeof(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);
  OPENSSL_free(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;
  bssl::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;
  bssl::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(bssl::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(bssl::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(bssl::Span<const CRYPTO_IOVEC> iovecs,
                                       bssl::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(bssl::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(bssl::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(bssl::Span<const CRYPTO_IOVEC> iovecs,
                              bssl::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(bssl::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) {
  bssl::Span<const CRYPTO_IOVEC> iovecs(iovec, num_iovec);
  bssl::Span<const CRYPTO_IVEC> aadvecs(aadvec, num_aadvec);

  bool ok = false;
  bssl::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, bssl::Span(out_tag, max_out_tag_len),
                       out_tag_len, bssl::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;
  bssl::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;
  bssl::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) {
  bssl::Span<const CRYPTO_IOVEC> iovecs(iovec, num_iovec);
  bssl::Span<const CRYPTO_IVEC> aadvecs(aadvec, num_aadvec);

  bool ok = false;
  bssl::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.
      bssl::InplaceVector<CRYPTO_IOVEC, CRYPTO_IOVEC_MAX> detached_iovecs;
      detached_iovecs.CopyFrom(iovecs);

      uint8_t tagbuf[EVP_AEAD_MAX_OVERHEAD];
      std::optional<bssl::Span<const uint8_t>> tag =
          bssl::iovec::GetAndRemoveSuffix(
              bssl::Span(tagbuf).first(ctx->tag_len),
              bssl::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,
                                    bssl::Span(nonce, nonce_len), *tag,
                                    aadvecs)) {
        ok = true;
        *out_total_bytes =
            bssl::iovec::TotalLength(bssl::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,
                       bssl::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) {
  bssl::Span<const CRYPTO_IOVEC> iovecs(iovec, num_iovec);
  bssl::Span<const CRYPTO_IVEC> aadvecs(aadvec, num_aadvec);

  bool ok = false;
  bssl::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, bssl::Span(nonce, nonce_len),
                                bssl::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;
}
