// Copyright 2017 Google Inc.
//
// 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
//
//     http://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 "tink/subtle/aes_eax_boringssl.h"

#include <algorithm>
#include <cstring>
#include <memory>
#include <string>
#include <vector>

#include "absl/algorithm/container.h"
#include "absl/base/config.h"
#include "absl/memory/memory.h"
#include "openssl/err.h"
#include "openssl/evp.h"
#include "tink/aead.h"
#include "tink/config/tink_fips.h"
#include "tink/subtle/random.h"
#include "tink/subtle/subtle_util.h"
#include "tink/subtle/subtle_util_boringssl.h"
#include "tink/util/errors.h"
#include "tink/util/status.h"
#include "tink/util/statusor.h"

namespace crypto {
namespace tink {
namespace subtle {

namespace {

// Loads and stores 8 bytes. The endianness of the two routines
// does not matter, as long as the two routines use the same order.
uint64_t Load64(const uint8_t src[8]) {
  uint64_t res;
  std::memcpy(&res, src, 8);
  return res;
}

void Store64(uint64_t val, uint8_t dst[8]) { std::memcpy(dst, &val, 8); }

uint64_t ByteSwap(uint64_t val) {
  val = ((val & 0xffffffff00000000) >> 32) | ((val & 0x00000000ffffffff) << 32);
  val = ((val & 0xffff0000ffff0000) >> 16) | ((val & 0x0000ffff0000ffff) << 16);
  val = ((val & 0xff00ff00ff00ff00) >> 8) | ((val & 0x00ff00ff00ff00ff) << 8);
  return val;
}

uint64_t BigEndianLoad64(const uint8_t src[8]) {
#if defined(ABSL_IS_LITTLE_ENDIAN)
  return ByteSwap(Load64(src));
#elif defined(ABSL_IS_BIG_ENDIAN)
  return val;
#else
#error Unknown endianness
#endif
}

void BigEndianStore64(uint64_t val, uint8_t dst[8]) {
#if defined(ABSL_IS_LITTLE_ENDIAN)
  return Store64(ByteSwap(val), dst);
#elif defined(ABSL_IS_BIG_ENDIAN)
  return Store64(val, dst);
#else
#error Unknown endianness
#endif
}

crypto::tink::util::StatusOr<util::SecretUniquePtr<AES_KEY>> InitAesKey(
    const util::SecretData& key) {
  auto aeskey = util::MakeSecretUniquePtr<AES_KEY>();
  int status = AES_set_encrypt_key(key.data(), key.size() * 8, aeskey.get());
  // status != 0 happens if key_value is invalid.
  if (status != 0) {
    return util::Status(util::error::INVALID_ARGUMENT, "Invalid key value");
  }
  return aeskey;
}

}  // namespace

void AesEaxBoringSsl::XorBlock(const uint8_t x[kBlockSize], Block* y) {
  uint64_t r0 = Load64(x) ^ Load64(y->data());
  uint64_t r1 = Load64(x + 8) ^ Load64(y->data() + 8);
  Store64(r0, y->data());
  Store64(r1, y->data() + 8);
}

void AesEaxBoringSsl::MultiplyByX(const uint8_t in[kBlockSize],
                                  uint8_t out[kBlockSize]) {
  uint64_t in_high = BigEndianLoad64(in);
  uint64_t in_low = BigEndianLoad64(in + 8);
  uint64_t out_high = (in_high << 1) ^ (in_low >> 63);
  // If the most significant bit is set then the result has to
  // be reduced by x^128 + x^7 + x^2 + x + 1.
  // The representation of x^7 + x^2 + x + 1 is 0x87.
  uint64_t out_low = (in_low << 1) ^ (0x87 & -(in_high >> 63));
  BigEndianStore64(out_high, out);
  BigEndianStore64(out_low, out + 8);
}

bool AesEaxBoringSsl::EqualBlocks(const uint8_t x[kBlockSize],
                                  const uint8_t y[kBlockSize]) {
  uint64_t res = Load64(x) ^ Load64(y);
  res |= Load64(x + 8) ^ Load64(y + 8);
  return res == 0;
}

bool AesEaxBoringSsl::IsValidKeySize(size_t key_size_in_bytes) {
  return key_size_in_bytes == 16 ||
         key_size_in_bytes == 32;
}

bool AesEaxBoringSsl::IsValidNonceSize(size_t nonce_size_in_bytes) {
  return nonce_size_in_bytes == 12 ||
         nonce_size_in_bytes == 16;
}

util::SecretData AesEaxBoringSsl::ComputeB() const {
  util::SecretData block(kBlockSize, 0);
  EncryptBlock(&block);
  MultiplyByX(block.data(), block.data());
  return block;
}

util::SecretData AesEaxBoringSsl::ComputeP() const {
  util::SecretData rv(kBlockSize, 0);
  MultiplyByX(B_.data(), rv.data());
  return rv;
}

crypto::tink::util::StatusOr<std::unique_ptr<Aead>> AesEaxBoringSsl::New(
    const util::SecretData& key, size_t nonce_size_in_bytes) {
  auto status = CheckFipsCompatibility<AesEaxBoringSsl>();
  if (!status.ok()) return status;

  if (!IsValidKeySize(key.size())) {
    return util::Status(util::error::INVALID_ARGUMENT, "Invalid key size");
  }
  if (!IsValidNonceSize(nonce_size_in_bytes)) {
    return util::Status(util::error::INVALID_ARGUMENT, "Invalid nonce size");
  }
  auto aeskey_or = InitAesKey(key);
  if (!aeskey_or.ok()) {
    return aeskey_or.status();
  }
  return {absl::WrapUnique(new AesEaxBoringSsl(
      std::move(aeskey_or).ValueOrDie(), nonce_size_in_bytes))};
}

AesEaxBoringSsl::Block AesEaxBoringSsl::Pad(
    absl::Span<const uint8_t> data) const {
  // TODO(bleichen): What are we using in tink to encode assertions?
  // The caller must ensure that data is no longer than a block.
  // CHECK(0 <= len && len <= kBlockSize) << "Invalid data size";
  Block padded_block;
  padded_block.fill(0);
  absl::c_copy(data, padded_block.begin());
  if (data.size() == kBlockSize) {
    XorBlock(B_.data(), &padded_block);
  } else {
    padded_block[data.size()] = 0x80;
    XorBlock(P_.data(), &padded_block);
  }
  return padded_block;
}

void AesEaxBoringSsl::EncryptBlock(util::SecretData* block) const {
  AES_encrypt(block->data(), block->data(), aeskey_.get());
}

void AesEaxBoringSsl::EncryptBlock(Block* block) const {
  AES_encrypt(block->data(), block->data(), aeskey_.get());
}

AesEaxBoringSsl::Block AesEaxBoringSsl::Omac(absl::string_view blob,
                                             int tag) const {
  return Omac(absl::MakeSpan(reinterpret_cast<const uint8_t*>(blob.data()),
                             blob.size()),
              tag);
}

AesEaxBoringSsl::Block AesEaxBoringSsl::Omac(absl::Span<const uint8_t> data,
                                             int tag) const {
  Block mac;
  mac.fill(0);
  mac[15] = tag;
  if (data.empty()) {
    XorBlock(B_.data(), &mac);
    EncryptBlock(&mac);
    return mac;
  }
  EncryptBlock(&mac);
  int idx = 0;
  while (data.size() - idx > kBlockSize) {
    XorBlock(&data[idx], &mac);
    EncryptBlock(&mac);
    idx += kBlockSize;
  }
  const Block padded_block = Pad(absl::MakeSpan(data).subspan(idx));
  XorBlock(padded_block.data(), &mac);
  EncryptBlock(&mac);
  return mac;
}

void AesEaxBoringSsl::CtrCrypt(const Block& N, absl::Span<const uint8_t> in,
                               uint8_t* out) const {
  // in.data() MUST NOT be null
  // Make a copy of N, since BoringSsl changes ctr.
  uint8_t ctr[kBlockSize];
  std::copy_n(N.begin(), kBlockSize, ctr);
  unsigned int num = 0;
  Block ecount_buf;
  ecount_buf.fill(0);
  AES_ctr128_encrypt(in.data(), out, in.size(), aeskey_.get(), ctr,
                     ecount_buf.data(), &num);
}

crypto::tink::util::StatusOr<std::string> AesEaxBoringSsl::Encrypt(
    absl::string_view plaintext, absl::string_view additional_data) const {
  // BoringSSL expects a non-null pointer for plaintext and additional_data,
  // regardless of whether the size is 0.
  plaintext = SubtleUtilBoringSSL::EnsureNonNull(plaintext);
  additional_data = SubtleUtilBoringSSL::EnsureNonNull(additional_data);

  size_t ciphertext_size = plaintext.size() + nonce_size_ + kTagSize;
  std::string ciphertext;
  ResizeStringUninitialized(&ciphertext, ciphertext_size);
  const std::string nonce = Random::GetRandomBytes(nonce_size_);
  const Block N = Omac(nonce, 0);
  const Block H = Omac(additional_data, 1);
  uint8_t* ct_start = reinterpret_cast<uint8_t*>(&ciphertext[nonce_size_]);
  CtrCrypt(N,
           absl::MakeSpan(reinterpret_cast<const uint8_t*>(plaintext.data()),
                          plaintext.size()),
           ct_start);
  Block mac = Omac(absl::MakeSpan(ct_start, plaintext.size()), 2);
  XorBlock(N.data(), &mac);
  XorBlock(H.data(), &mac);
  absl::c_copy(nonce, ciphertext.begin());
  std::copy_n(mac.begin(), kTagSize, &ciphertext[ciphertext_size - kTagSize]);
  return ciphertext;
}

crypto::tink::util::StatusOr<std::string> AesEaxBoringSsl::Decrypt(
    absl::string_view ciphertext, absl::string_view additional_data) const {
  // BoringSSL expects a non-null pointer for additional_data,
  // regardless of whether the size is 0.
  additional_data = SubtleUtilBoringSSL::EnsureNonNull(additional_data);

  size_t ct_size = ciphertext.size();
  if (ct_size < nonce_size_ + kTagSize) {
    return util::Status(util::error::INVALID_ARGUMENT, "Ciphertext too short");
  }
  size_t out_size = ct_size - kTagSize - nonce_size_;
  absl::string_view nonce = ciphertext.substr(0, nonce_size_);
  absl::string_view encrypted = ciphertext.substr(nonce_size_, out_size);
  absl::string_view tag = ciphertext.substr(ct_size - kTagSize, kTagSize);
  const Block N = Omac(nonce, 0);
  const Block H = Omac(additional_data, 1);
  Block mac = Omac(encrypted, 2);
  XorBlock(N.data(), &mac);
  XorBlock(H.data(), &mac);
  const uint8_t *sig = reinterpret_cast<const uint8_t*>(tag.data());
  if (!EqualBlocks(mac.data(), sig)) {
    return util::Status(util::error::INVALID_ARGUMENT, "Tag mismatch");
  }
  std::string res;
  ResizeStringUninitialized(&res, out_size);
  CtrCrypt(N,
           absl::MakeSpan(reinterpret_cast<const uint8_t*>(encrypted.data()),
                          encrypted.size()),
           reinterpret_cast<uint8_t*>(&res[0]));
  return res;
}

}  // namespace subtle
}  // namespace tink
}  // namespace crypto


