// 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 <inttypes.h>
#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/bytes.h>
#include <crypto/cipher.h>
#include <explicit-memory/bytes.h>
#include <fbl/algorithm.h>
#include <fbl/alloc_checker.h>
#include <fbl/auto_call.h>
#include <fbl/macros.h>

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

#include "error.h"

#define ZXDEBUG 0

namespace crypto {

// The previously opaque crypto implementation context.  Guaranteed to clean up on destruction.
struct Cipher::Context {
  Context() { EVP_CIPHER_CTX_init(&impl); }

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

  EVP_CIPHER_CTX impl;
};

namespace {

// Get the cipher for the given |version|.
zx_status_t GetCipher(Cipher::Algorithm cipher, const EVP_CIPHER** out) {
  switch (cipher) {
    case Cipher::kUninitialized:
      xprintf("not initialized\n");
      return ZX_ERR_INVALID_ARGS;

    case Cipher::kAES256_XTS:
      *out = EVP_aes_256_xts();
      return ZX_OK;

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

}  // namespace

// Public methods

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

  if (!out) {
    xprintf("missing output pointer\n");
    return ZX_ERR_INVALID_ARGS;
  }
  const EVP_CIPHER* cipher;
  if ((rc = GetCipher(algo, &cipher)) != ZX_OK) {
    return rc;
  }
  *out = cipher->key_len;

  return ZX_OK;
}

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

  if (!out) {
    xprintf("missing output pointer\n");
    return ZX_ERR_INVALID_ARGS;
  }
  const EVP_CIPHER* cipher;
  if ((rc = GetCipher(algo, &cipher)) != ZX_OK) {
    return rc;
  }
  *out = cipher->iv_len;

  return ZX_OK;
}

zx_status_t Cipher::GetBlockSize(Algorithm algo, size_t* out) {
  zx_status_t rc;

  if (!out) {
    xprintf("missing output pointer\n");
    return ZX_ERR_INVALID_ARGS;
  }
  const EVP_CIPHER* cipher;
  if ((rc = GetCipher(algo, &cipher)) != ZX_OK) {
    return rc;
  }
  *out = cipher->block_size;

  return ZX_OK;
}

Cipher::Cipher() : cipher_(kUninitialized), direction_(kUnset), block_size_(0), alignment_(0) {}

Cipher::~Cipher() {}

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

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

  const EVP_CIPHER* cipher;
  if ((rc = GetCipher(algo, &cipher)) != ZX_OK) {
    return rc;
  }
  if (key.len() != cipher->key_len || iv.len() != cipher->iv_len) {
    xprintf("bad parameter(s): key_len=%zu, iv_len=%zu\n", key.len(), iv.len());
    return ZX_ERR_INVALID_ARGS;
  }
  cipher_ = algo;

  // Set the IV.
  fbl::AllocChecker ac;
  size_t n = fbl::round_up(cipher->iv_len, sizeof(zx_off_t)) / sizeof(zx_off_t);
  iv_.reset(new (&ac) zx_off_t[n]{0});
  if (!ac.check()) {
    xprintf("failed to allocate %zu bytes\n", n * sizeof(zx_off_t));
    return ZX_ERR_NO_MEMORY;
  }
  memcpy(iv_.get(), iv.get(), iv.len());
  iv0_ = iv_[0];

  // Handle alignment for random access ciphers
  if (alignment != 0) {
    if ((alignment & (alignment - 1)) != 0) {
      xprintf("alignment must be a power of 2: %" PRIu64 "\n", alignment);
      return ZX_ERR_INVALID_ARGS;
    }
    // White-list tweaked codebook ciphers
    switch (algo) {
      case kAES256_XTS:
        break;
      default:
        xprintf("Selected cipher cannot be used in random access mode\n");
        return ZX_ERR_INVALID_ARGS;
    }
  }
  alignment_ = alignment;

  // Initialize cipher context
  ctx_.reset(new (&ac) Context());
  if (!ac.check()) {
    xprintf("allocation failed: %zu bytes\n", sizeof(Context));
    return ZX_ERR_NO_MEMORY;
  }
  uint8_t* iv8 = reinterpret_cast<uint8_t*>(iv_.get());
  if (EVP_CipherInit_ex(&ctx_->impl, cipher, nullptr, key.get(), iv8, direction == kEncrypt) < 0) {
    xprintf_crypto_errors(&rc);
    return rc;
  }
  direction_ = direction;
  block_size_ = cipher->block_size;

  cleanup.cancel();
  return ZX_OK;
}

zx_status_t Cipher::Transform(const uint8_t* in, zx_off_t offset, size_t length, uint8_t* out,
                              Direction direction) {
  zx_status_t rc;

  if (!ctx_ || direction != direction_) {
    xprintf("not initialized/wrong direction\n");
    return ZX_ERR_BAD_STATE;
  }
  if (length == 0) {
    return ZX_OK;
  }
  if (!in || !out || length % block_size_ != 0) {
    xprintf("bad args: in=%p, length=%zu, out=%p, direction=%d\n", in, length, out, direction);
    return ZX_ERR_INVALID_ARGS;
  }
  if (alignment_ == 0) {
    // Stream cipher; just transform without modifying the IV.
    if (EVP_Cipher(&ctx_->impl, out, in, length) <= 0) {
      xprintf_crypto_errors(&rc);
      return rc;
    }

  } else {
    if (offset % alignment_ != 0) {
      xprintf("unaligned offset\n");
      return ZX_ERR_INVALID_ARGS;
    }
    iv_[0] = iv0_ + static_cast<uint64_t>(offset / alignment_);
    uint8_t* iv8 = reinterpret_cast<uint8_t*>(iv_.get());
    while (length > 0) {
      size_t chunk_len = length < alignment_ ? length : alignment_;
      if (EVP_CipherInit_ex(&ctx_->impl, nullptr, nullptr, nullptr, iv8, -1) < 0 ||
          EVP_Cipher(&ctx_->impl, out, in, chunk_len) <= 0) {
        xprintf_crypto_errors(&rc);
        return rc;
      }
      out += chunk_len;
      in += chunk_len;
      length -= chunk_len;
      iv_[0] += 1;
    }
  }

  return ZX_OK;
}

void Cipher::Reset() {
  ctx_.reset();
  block_size_ = 0;
  cipher_ = kUninitialized;
  direction_ = kUnset;
  alignment_ = 0;
}

}  // namespace crypto
