// Copyright 2017 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <lib/zircon-internal/debug.h>
#include <stddef.h>
#include <stdint.h>
#include <string.h>
#include <zircon/errors.h>
#include <zircon/types.h>

#include <crypto/aead.h>
#include <crypto/bytes.h>
#include <fbl/algorithm.h>
#include <fbl/alloc_checker.h>
#include <fbl/auto_call.h>

// See note in //zircon/third_party/ulib/boringssl/BUILD.gn
#define BORINGSSL_NO_CXX
#include <openssl/aead.h>

#include "error.h"

#define ZXDEBUG 0

namespace crypto {

// The previously opaque crypto implementation context.  Guaranteed to clean up on destruction.
struct AEAD::Context {
  Context() {}

  ~Context() { EVP_AEAD_CTX_cleanup(&impl); }

  EVP_AEAD_CTX impl;
};

namespace {

// Get the aead for the given |version|.
zx_status_t GetAEAD(AEAD::Algorithm aead, const EVP_AEAD** out) {
  switch (aead) {
    case AEAD::kUninitialized:
      xprintf("not initialized\n");
      return ZX_ERR_INVALID_ARGS;

    case AEAD::kAES128_GCM:
      *out = EVP_aead_aes_128_gcm();
      return ZX_OK;

    case AEAD::kAES128_GCM_SIV:
      *out = EVP_aead_aes_128_gcm_siv();
      return ZX_OK;

    default:
      xprintf("invalid aead = %u\n", aead);
      return ZX_ERR_NOT_SUPPORTED;
  }
}

}  // namespace

// Public methods

zx_status_t AEAD::GetKeyLen(Algorithm algo, size_t* out) {
  zx_status_t rc;

  if (!out) {
    xprintf("missing output pointer\n");
    return ZX_ERR_INVALID_ARGS;
  }
  const EVP_AEAD* aead;
  if ((rc = GetAEAD(algo, &aead)) != ZX_OK) {
    return rc;
  }
  *out = EVP_AEAD_key_length(aead);

  return ZX_OK;
}

zx_status_t AEAD::GetIVLen(Algorithm algo, size_t* out) {
  zx_status_t rc;

  if (!out) {
    xprintf("missing output pointer\n");
    return ZX_ERR_INVALID_ARGS;
  }
  const EVP_AEAD* aead;
  if ((rc = GetAEAD(algo, &aead)) != ZX_OK) {
    return rc;
  }
  *out = EVP_AEAD_nonce_length(aead);

  return ZX_OK;
}

zx_status_t AEAD::GetTagLen(Algorithm algo, size_t* out) {
  zx_status_t rc;

  if (!out) {
    xprintf("missing output pointer\n");
    return ZX_ERR_INVALID_ARGS;
  }
  const EVP_AEAD* aead;
  if ((rc = GetAEAD(algo, &aead)) != ZX_OK) {
    return rc;
  }
  *out = EVP_AEAD_max_tag_len(aead);

  return ZX_OK;
}

AEAD::AEAD() : ctx_(nullptr), direction_(Cipher::kUnset), tag_len_(0) {}

AEAD::~AEAD() {}

zx_status_t AEAD::Seal(const Bytes& ptext, const uint8_t* aad, size_t aad_len, uint64_t* out_nonce,
                       Bytes* out_ctext) {
  zx_status_t rc;

  if (direction_ != Cipher::kEncrypt) {
    xprintf("not configured to encrypt\n");
    return ZX_ERR_BAD_STATE;
  }

  size_t ptext_len = ptext.len();
  if (!out_nonce || !out_ctext) {
    xprintf("bad parameter(s): out_nonce=%p, ctext=%p\n", out_nonce, out_ctext);
    return ZX_ERR_INVALID_ARGS;
  }

  // If the caller recycles the |Bytes| used for|ctext|, this becomes a no-op.
  size_t ctext_len = ptext_len + tag_len_;
  if ((rc = out_ctext->Resize(ctext_len)) != ZX_OK) {
    return rc;
  }

  uint8_t* iv8 = reinterpret_cast<uint8_t*>(iv_.get());
  size_t out_len;
  if (EVP_AEAD_CTX_seal(&ctx_->impl, out_ctext->get(), &out_len, ctext_len, iv8, iv_len_,
                        ptext.get(), ptext_len, aad, aad_len) != 1) {
    xprintf_crypto_errors(&rc);
    return rc;
  }
  if (out_len != ctext_len) {
    xprintf("length mismatch: expected %zu, got %zu\n", ptext_len, out_len);
    return ZX_ERR_INTERNAL;
  }

  // Increment nonce
  uint64_t nonce = iv_[0];
  iv_[0] += 1;
  if (iv_[0] == iv0_) {
    xprintf("exceeded maximum operations with this key\n");
    return ZX_ERR_BAD_STATE;
  }

  *out_nonce = nonce;
  return ZX_OK;
}

zx_status_t AEAD::Open(uint64_t nonce, const Bytes& ctext, const uint8_t* aad, size_t aad_len,
                       Bytes* out_ptext) {
  zx_status_t rc;

  if (direction_ != Cipher::kDecrypt) {
    xprintf("not configured to decrypt\n");
    return ZX_ERR_BAD_STATE;
  }

  size_t ctext_len = ctext.len();
  if (ctext_len < tag_len_ || !out_ptext) {
    xprintf("bad parameter(s): ctext.len=%zu, ptext=%p\n", ctext_len, out_ptext);
    return ZX_ERR_INVALID_ARGS;
  }

  size_t ptext_len = ctext_len - tag_len_;
  if ((rc = out_ptext->Resize(ptext_len)) != ZX_OK) {
    return rc;
  }

  // Inject nonce
  iv_[0] = nonce;
  uint8_t* iv8 = reinterpret_cast<uint8_t*>(iv_.get());
  size_t out_len;
  if (EVP_AEAD_CTX_open(&ctx_->impl, out_ptext->get(), &out_len, ptext_len, iv8, iv_len_,
                        ctext.get(), ctext_len, aad, aad_len) != 1) {
    xprintf_crypto_errors(&rc);
    return rc;
  }
  if (out_len != ptext_len) {
    xprintf("length mismatch: expected %zu, got %zu\n", ptext_len, out_len);
    return ZX_ERR_INTERNAL;
  }

  return ZX_OK;
}

void AEAD::Reset() {
  ctx_.reset();
  direction_ = Cipher::kUnset;
  iv_len_ = 0;
  tag_len_ = 0;
}

// Private methods

zx_status_t AEAD::Init(Algorithm algo, const Secret& key, const Bytes& iv,
                       Cipher::Direction direction) {
  zx_status_t rc;

  Reset();
  auto cleanup = fbl::MakeAutoCall([&] { Reset(); });

  // Look up specific algorithm
  const EVP_AEAD* aead;
  if ((rc = GetAEAD(algo, &aead)) != ZX_OK) {
    return rc;
  }
  size_t key_len = EVP_AEAD_key_length(aead);
  iv_len_ = EVP_AEAD_nonce_length(aead);
  tag_len_ = EVP_AEAD_max_tag_len(aead);

  // Check parameters
  if (key.len() != key_len) {
    xprintf("wrong key length; have %zu, need %zu\n", key.len(), key_len);
    return ZX_ERR_INVALID_ARGS;
  }
  if (iv.len() != iv_len_) {
    xprintf("wrong IV length; have %zu, need %zu\n", iv.len(), iv_len_);
    return ZX_ERR_INVALID_ARGS;
  }

  // Allocate context
  fbl::AllocChecker ac;
  ctx_.reset(new (&ac) Context());
  if (!ac.check()) {
    xprintf("allocation failed: %zu bytes\n", sizeof(Context));
    return ZX_ERR_NO_MEMORY;
  }

  // Initialize context
  if (EVP_AEAD_CTX_init(&ctx_->impl, aead, key.get(), key.len(), EVP_AEAD_DEFAULT_TAG_LENGTH,
                        nullptr) != 1) {
    xprintf_crypto_errors(&rc);
    return rc;
  }
  direction_ = direction;

  // Reserve space for IV
  size_t n = fbl::round_up(iv_len_, sizeof(uint64_t)) / sizeof(uint64_t);
  iv_.reset(new (&ac) uint64_t[n]{0});
  if (!ac.check()) {
    xprintf("failed to allocate %zu bytes\n", n * sizeof(uint64_t));
    return ZX_ERR_NO_MEMORY;
  }
  memcpy(iv_.get(), iv.get(), iv_len_);

  cleanup.cancel();
  return ZX_OK;
}

}  // namespace crypto
