// Copyright 2025 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 <assert.h>
#include <stddef.h>
#include <stdint.h>
#include <sys/types.h>

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

#include "../fipsmodule/cipher/internal.h"
#include "../internal.h"


using namespace bssl;

// Implementation of AES-EAX defined in
// https://www.iacr.org/archive/fse2004/30170391/30170391.pdf.

#define EVP_AEAD_AES_EAX_TAG_LEN AES_BLOCK_SIZE

struct aead_aes_eax_ctx {
  union {
    double align;
    AES_KEY ks;
  } ks;
  uint8_t b[AES_BLOCK_SIZE];
  uint8_t p[AES_BLOCK_SIZE];
};

static void mult_by_X(uint8_t out[AES_BLOCK_SIZE],
                      const uint8_t in[AES_BLOCK_SIZE]) {
  const crypto_word_t in_hi = CRYPTO_load_word_be(in);
  for (size_t i = 0; i < AES_BLOCK_SIZE - 1; ++i) {
    out[i] = (in[i] << 1) | (in[i + 1] >> 7);
  }
  // Carry over 0x87 if msb is 1, 0x00 if msb is 0.
  out[AES_BLOCK_SIZE - 1] = in[AES_BLOCK_SIZE - 1] << 1;
  const uint8_t p = 0x87;
  constant_time_conditional_memxor(out + AES_BLOCK_SIZE - 1, &p, /*n=*/1,
                                   constant_time_msb_w(in_hi));
}

static int aead_aes_eax_init(EVP_AEAD_CTX *ctx, const uint8_t *key,
                             size_t key_len, size_t tag_len) {
  struct aead_aes_eax_ctx *aes_ctx = (struct aead_aes_eax_ctx *)&ctx->state;

  if (key_len != 16 && key_len != 32) {
    OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_KEY_LENGTH);
    return 0;
  }

  if (tag_len == EVP_AEAD_DEFAULT_TAG_LENGTH) {
    tag_len = EVP_AEAD_AES_EAX_TAG_LEN;
  }

  if (tag_len != EVP_AEAD_AES_EAX_TAG_LEN) {
    OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_UNSUPPORTED_TAG_SIZE);
    return 0;
  }

  if (AES_set_encrypt_key(key, /*bits=*/key_len * 8, &aes_ctx->ks.ks) != 0) {
    OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_AES_KEY_SETUP_FAILED);
    return 0;
  }
  ctx->tag_len = tag_len;

  // L <- Ek(0^n).
  OPENSSL_memset(aes_ctx->b, 0, sizeof(aes_ctx->b));
  AES_encrypt(aes_ctx->b, aes_ctx->b, &aes_ctx->ks.ks);
  // B <- 2L.
  mult_by_X(aes_ctx->b, aes_ctx->b);
  // P <- 4L = 2B.
  mult_by_X(aes_ctx->p, aes_ctx->b);
  return 1;
}

static void aead_aes_eax_cleanup(EVP_AEAD_CTX *ctx) {}

// Implements the CBK function in the paper.
static void cbk_block(const struct aead_aes_eax_ctx *aes_ctx,
                      const uint8_t in[AES_BLOCK_SIZE],
                      uint8_t out[AES_BLOCK_SIZE]) {
  CRYPTO_xor16(out, in, out);
  AES_encrypt(out, out, &aes_ctx->ks.ks);
}

// Precondition: in_len <= AES_BLOCK_SIZE.
static void pad(const struct aead_aes_eax_ctx *aes_ctx,
                uint8_t out[AES_BLOCK_SIZE], const uint8_t *in, size_t in_len) {
  assert(in_len <= AES_BLOCK_SIZE);
  if (in_len == AES_BLOCK_SIZE) {
    CRYPTO_xor16(out, aes_ctx->b, in);
    return;
  }
  OPENSSL_memset(out, 0, AES_BLOCK_SIZE);
  OPENSSL_memcpy(out, in, in_len);
  out[in_len] = 0x80;
  CRYPTO_xor16(out, aes_ctx->p, out);
}

template <typename IVEC>
static void omac_with_tag(const struct aead_aes_eax_ctx *aes_ctx,
                          uint8_t out[AES_BLOCK_SIZE], Span<const IVEC> ivecs,
                          uint8_t tag) {
  OPENSSL_memset(out, 0, AES_BLOCK_SIZE);
  out[AES_BLOCK_SIZE - 1] = tag;
  size_t in_len = bssl::iovec::TotalLength(ivecs);
  if (in_len == 0) {
    // CBK(pad(M;B,P)) = CBK(B). Avoiding padding to skip a copy.
    cbk_block(aes_ctx, aes_ctx->b, out);
    return;
  }
  // CBK(M1) = Ek(M1 ^ 0^n)
  AES_encrypt(out, out, &aes_ctx->ks.ks);
  bssl::iovec::ForEachBlockRange<AES_BLOCK_SIZE>(
      ivecs,
      [&](const uint8_t *in, size_t len) {
        while (len >= AES_BLOCK_SIZE) {
          // Full blocks, no padding needed.
          cbk_block(aes_ctx, in, out);
          in += AES_BLOCK_SIZE;
          len -= AES_BLOCK_SIZE;
        }
        BSSL_CHECK(len == 0);
        return true;
      },
      [&](const uint8_t *in, size_t len) {
        // Remaining blocks.
        while (len > AES_BLOCK_SIZE) {
          // Full blocks, no padding needed.
          cbk_block(aes_ctx, in, out);
          in += AES_BLOCK_SIZE;
          len -= AES_BLOCK_SIZE;
        }
        // Last partial block.
        uint8_t padded_block[AES_BLOCK_SIZE];
        pad(aes_ctx, padded_block, in, len);
        cbk_block(aes_ctx, padded_block, out);
        return true;
      });
}

static void omac_with_tag_iovec_out(const struct aead_aes_eax_ctx *aes_ctx,
                                    uint8_t out[AES_BLOCK_SIZE],
                                    Span<const CRYPTO_IOVEC> iovecs,
                                    uint8_t tag) {
  OPENSSL_memset(out, 0, AES_BLOCK_SIZE);
  out[AES_BLOCK_SIZE - 1] = tag;
  size_t in_len = bssl::iovec::TotalLength(iovecs);
  if (in_len == 0) {
    // CBK(pad(M;B,P)) = CBK(B). Avoiding padding to skip a copy.
    cbk_block(aes_ctx, aes_ctx->b, out);
    return;
  }
  // CBK(M1) = Ek(M1 ^ 0^n)
  AES_encrypt(out, out, &aes_ctx->ks.ks);
  bssl::iovec::ForEachOutBlockRange<AES_BLOCK_SIZE>(
      iovecs,
      [&](const uint8_t *in, size_t len) {
        while (len >= AES_BLOCK_SIZE) {
          // Full blocks, no padding needed.
          cbk_block(aes_ctx, in, out);
          in += AES_BLOCK_SIZE;
          len -= AES_BLOCK_SIZE;
        }
        BSSL_CHECK(len == 0);
        return true;
      },
      [&](const uint8_t *in, size_t len) {
        while (len > AES_BLOCK_SIZE) {
          // Full blocks, no padding needed.
          cbk_block(aes_ctx, in, out);
          in += AES_BLOCK_SIZE;
          len -= AES_BLOCK_SIZE;
        }
        // Last partial block.
        uint8_t padded_block[AES_BLOCK_SIZE];
        pad(aes_ctx, padded_block, in, len);
        cbk_block(aes_ctx, padded_block, out);
        return true;
      });
}

// Encrypts/decrypts `in_len` bytes from `in` to `out` using AES-CTR with `n` as
// the IV.
static void aes_ctr(const struct aead_aes_eax_ctx *aes_ctx,
                    Span<const CRYPTO_IOVEC> iovecs,
                    const uint8_t n[AES_BLOCK_SIZE]) {
  uint8_t ivec[AES_BLOCK_SIZE];
  OPENSSL_memcpy(ivec, n, AES_BLOCK_SIZE);

  uint8_t ecount_buf[AES_BLOCK_SIZE];
  unsigned int num = 0;

  for (const CRYPTO_IOVEC &iovec : iovecs) {
    AES_ctr128_encrypt(iovec.in, iovec.out, iovec.len, &aes_ctx->ks.ks, ivec,
                       ecount_buf, &num);
  }
}

static int aead_aes_eax_sealv(const EVP_AEAD_CTX *ctx,
                              Span<const CRYPTO_IOVEC> iovecs,
                              Span<uint8_t> out_tag, size_t *out_tag_len,
                              Span<const uint8_t> nonce,
                              Span<const CRYPTO_IVEC> aadvecs) {
  // We use the full 128 bits of the nonce as counter, so no need to check the
  // plaintext size.

  if (out_tag.size() < ctx->tag_len) {
    OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BUFFER_TOO_SMALL);
    return 0;
  }

  if (nonce.size() != 12 && nonce.size() != 16) {
    OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_UNSUPPORTED_NONCE_SIZE);
    return 0;
  }

  const struct aead_aes_eax_ctx *aes_ctx =
      (struct aead_aes_eax_ctx *)&ctx->state;

  // N <- OMAC(0 || nonce)
  uint8_t n[AES_BLOCK_SIZE];
  CRYPTO_IVEC noncevec[1];
  noncevec[0].in = nonce.data();
  noncevec[0].len = nonce.size();
  omac_with_tag(aes_ctx, n, Span<const CRYPTO_IVEC>(noncevec), /*tag=*/0);
  // H <- OMAC(1 || ad)
  uint8_t h[AES_BLOCK_SIZE];
  omac_with_tag(aes_ctx, h, aadvecs, /*tag=*/1);

  // C <- CTR^{N}_{K}(M)
  aes_ctr(aes_ctx, iovecs, n);

  // MAC <- OMAC(2 || C)
  omac_with_tag_iovec_out(aes_ctx, out_tag.data(), iovecs, /*tag=*/2);
  // MAC <- N ^ C ^ H
  CRYPTO_xor16(out_tag.data(), n, out_tag.data());
  CRYPTO_xor16(out_tag.data(), h, out_tag.data());

  *out_tag_len = ctx->tag_len;
  return 1;
}

static int aead_aes_eax_openv_detached(const EVP_AEAD_CTX *ctx,
                                       Span<const CRYPTO_IOVEC> iovecs,
                                       Span<const uint8_t> nonce,
                                       Span<const uint8_t> in_tag,
                                       Span<const CRYPTO_IVEC> aadvecs) {
  const uint64_t ad_len_64 = bssl::iovec::TotalLength(aadvecs);
  if (ad_len_64 >= (UINT64_C(1) << 61)) {
    OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_TOO_LARGE);
    return 0;
  }

  if (in_tag.size() != EVP_AEAD_AES_EAX_TAG_LEN) {
    OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_DECRYPT);
    return 0;
  }

  if (nonce.size() != 12 && nonce.size() != 16) {
    OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_UNSUPPORTED_NONCE_SIZE);
    return 0;
  }

  const struct aead_aes_eax_ctx *aes_ctx =
      (struct aead_aes_eax_ctx *)&ctx->state;

  // N <- OMAC(0 || nonce)
  uint8_t n[AES_BLOCK_SIZE];
  CRYPTO_IVEC noncevec[1];
  noncevec[0].in = nonce.data();
  noncevec[0].len = nonce.size();
  omac_with_tag(aes_ctx, n, Span<const CRYPTO_IVEC>(noncevec),
                /*tag=*/0);
  // H <- OMAC(1 || ad)
  uint8_t h[AES_BLOCK_SIZE];
  omac_with_tag(aes_ctx, h, aadvecs, /*tag=*/1);

  // MAC <- OMAC(2 || C)
  uint8_t mac[AES_BLOCK_SIZE];
  omac_with_tag(aes_ctx, mac, iovecs, /*tag=*/2);
  // MAC <- N ^ C ^ H
  CRYPTO_xor16(mac, n, mac);
  CRYPTO_xor16(mac, h, mac);

  if (CRYPTO_memcmp(mac, in_tag.data(), in_tag.size()) != 0) {
    OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_DECRYPT);
    return 0;
  }

  // M <- CTR^{N}_{K}(C)
  aes_ctr(aes_ctx, iovecs, n);
  return 1;
}

static const EVP_AEAD aead_aes_128_eax = {
    16,                        // AES key size
    16,                        // nonce length
    EVP_AEAD_AES_EAX_TAG_LEN,  // overhead
    EVP_AEAD_AES_EAX_TAG_LEN,  // max tag length

    aead_aes_eax_init,
    nullptr,  // init_with_direction
    aead_aes_eax_cleanup,
    nullptr,  // openv
    aead_aes_eax_sealv,
    aead_aes_eax_openv_detached,
    nullptr,  // get_iv
    nullptr,  // tag_len
};

static const EVP_AEAD aead_aes_256_eax = {
    32,                        // AES key size
    16,                        // nonce length
    EVP_AEAD_AES_EAX_TAG_LEN,  // overhead
    EVP_AEAD_AES_EAX_TAG_LEN,  // max tag length

    aead_aes_eax_init,
    nullptr,  // init_with_direction
    aead_aes_eax_cleanup,
    nullptr,  // openv
    aead_aes_eax_sealv,
    aead_aes_eax_openv_detached,
    nullptr,  // get_iv
    nullptr,  // tag_len
};

const EVP_AEAD *EVP_aead_aes_128_eax() { return &aead_aes_128_eax; }

const EVP_AEAD *EVP_aead_aes_256_eax() { return &aead_aes_256_eax; }
