// 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_siv_boringssl.h"

#include <string>
#include <vector>

#include "tink/deterministic_aead.h"
#include "tink/util/errors.h"
#include "tink/util/status.h"
#include "tink/util/statusor.h"
#include "openssl/err.h"
#include "openssl/aes.h"

namespace crypto {
namespace tink {
namespace subtle {

static void XorBlock(
    const uint8_t x[16],
    const uint8_t y[16],
    uint8_t res[16]) {
  for (int i = 0; i < 16; i++) {
    res[i] = x[i] ^ y[i];
  }
}

// static
crypto::tink::util::StatusOr<std::unique_ptr<DeterministicAead>>
AesSivBoringSsl::New(absl::string_view key_value) {
  std::unique_ptr<AesSivBoringSsl> aes_siv(new AesSivBoringSsl());
  if (aes_siv->SetKey(key_value)) {
    return std::unique_ptr<DeterministicAead>(aes_siv.release());
  } else {
    return util::Status(util::error::INTERNAL, "invalid key size");
  }
}

bool AesSivBoringSsl::SetKey(absl::string_view key) {
  size_t key_size = key.size();
  if (!IsValidKeySizeInBytes(key_size)) {
    return false;
  }
  if (0 != AES_set_encrypt_key(
              reinterpret_cast<const uint8_t*>(key.data()),
              4 * key_size, &k1_)) {
    return false;
  }
  if (0 != AES_set_encrypt_key(
              reinterpret_cast<const uint8_t*>(key.data() + key_size / 2),
              4 * key_size, &k2_)) {
    return false;
  }
  uint8_t block[BLOCK_SIZE];
  memset(block, 0, BLOCK_SIZE);
  EncryptBlock(block, block);
  MultiplyByX(block);
  memcpy(cmac_k1_, block, BLOCK_SIZE);
  MultiplyByX(block);
  memcpy(cmac_k2_, block, BLOCK_SIZE);
  return true;
}

void AesSivBoringSsl::CtrCrypt(const uint8_t siv[BLOCK_SIZE],
                               const uint8_t *in, uint8_t *out,
                               size_t size) const {
  uint8_t iv[BLOCK_SIZE];
  memcpy(iv, siv, BLOCK_SIZE);
  iv[8] &= 0x7f;
  iv[12] &= 0x7f;
  unsigned int num = 0;
  uint8_t ecount_buf[BLOCK_SIZE];
  memset(ecount_buf, 0, BLOCK_SIZE);
  AES_ctr128_encrypt(in, out, size, &k2_, iv, ecount_buf, &num);
}

void AesSivBoringSsl::EncryptBlock(const uint8_t in[BLOCK_SIZE],
                                   uint8_t out[BLOCK_SIZE]) const {
  AES_encrypt(in, out, &k1_);
}

// static
void AesSivBoringSsl::MultiplyByX(uint8_t block[BLOCK_SIZE]) {
  uint8_t carry = block[0] >> 7;
  for (size_t i = 0; i < BLOCK_SIZE - 1; i++) {
    block[i] = (block[i] << 1) | (block[i+1] >> 7);
  }
  block[BLOCK_SIZE - 1 ] = (block[BLOCK_SIZE - 1] << 1) ^ (carry ? 0x87 : 0);
}

void AesSivBoringSsl::Cmac(const uint8_t* data, size_t size,
                           uint8_t mac[BLOCK_SIZE]) const {
  size_t blocks = (size + BLOCK_SIZE - 1) / BLOCK_SIZE;
  if (blocks == 0) {
    blocks = 1;
  }
  size_t last_block_size = size - BLOCK_SIZE * (blocks - 1);
  uint8_t block[BLOCK_SIZE];
  memset(block, 0, BLOCK_SIZE);
  size_t idx = 0;
  for (size_t i = 0; i < blocks - 1; i++) {
    XorBlock(block, &data[idx], block);
    EncryptBlock(block, block);
    idx += BLOCK_SIZE;
  }
  for (size_t j = 0; j < last_block_size; j++) {
    block[j] ^= data[idx + j];
  }
  if (last_block_size == BLOCK_SIZE) {
    XorBlock(block, cmac_k1_, block);
  } else {
    block[last_block_size] ^= 0x80;
    XorBlock(block, cmac_k2_, block);
  }
  EncryptBlock(block, mac);
}

// Computes Cmac(XorEnd(data, last))
void AesSivBoringSsl::CmacLong(
    const uint8_t* data, size_t size, const uint8_t last[BLOCK_SIZE],
    uint8_t mac[BLOCK_SIZE]) const {
  uint8_t block[BLOCK_SIZE];
  memcpy(block, data, BLOCK_SIZE);
  size_t idx = BLOCK_SIZE;
  while (BLOCK_SIZE <= size - idx) {
    EncryptBlock(block, block);
    XorBlock(block, &data[idx], block);
    idx += BLOCK_SIZE;
  }
  size_t remaining = size - idx;
  for (int j = 0; j < BLOCK_SIZE - remaining; ++j) {
    block[remaining + j] ^= last[j];
  }
  if (remaining == 0) {
    XorBlock(block, cmac_k1_, block);
  } else {
    EncryptBlock(block, block);
    for (int j = 0; j < remaining; ++j) {
      block[j] ^= last[BLOCK_SIZE - remaining + j];
      block[j] ^= data[idx + j];
    }
    block[remaining] ^= 0x80;
    XorBlock(block, cmac_k2_, block);
  }
  EncryptBlock(block, mac);
}

void AesSivBoringSsl::S2v(const uint8_t* aad, size_t aad_size,
                          const uint8_t* msg, size_t msg_size,
                          uint8_t siv[BLOCK_SIZE]) const {
  // This stuff could be precomputed.
  uint8_t block[BLOCK_SIZE];
  memset(block, 0, BLOCK_SIZE);
  Cmac(block, BLOCK_SIZE, block);
  MultiplyByX(block);

  uint8_t aad_mac[BLOCK_SIZE];
  Cmac(aad, aad_size, aad_mac);
  XorBlock(block, aad_mac, block);

  if (msg_size >= BLOCK_SIZE) {
    CmacLong(msg, msg_size, block, siv);
  } else {
    MultiplyByX(block);
    for (size_t i = 0; i < msg_size; i++) {
      block[i] ^= msg[i];
    }
    block[msg_size] ^= 0x80;
    Cmac(block, BLOCK_SIZE, siv);
  }
}

util::StatusOr<std::string> AesSivBoringSsl::EncryptDeterministically(
    absl::string_view plaintext, absl::string_view additional_data) const {
  uint8_t siv[BLOCK_SIZE];
  S2v(reinterpret_cast<const uint8_t*>(additional_data.data()),
      additional_data.size(),
      reinterpret_cast<const uint8_t*>(plaintext.data()),
      plaintext.size(),
      siv);
  size_t ciphertext_size = plaintext.size() + BLOCK_SIZE;
  std::vector<uint8_t> ct(ciphertext_size);
  memcpy(ct.data(), siv, BLOCK_SIZE);
  CtrCrypt(siv, reinterpret_cast<const uint8_t*>(plaintext.data()),
           ct.data() + BLOCK_SIZE, plaintext.size());
  return std::string(reinterpret_cast<const char*>(ct.data()), ciphertext_size);
}

util::StatusOr<std::string> AesSivBoringSsl::DecryptDeterministically(
    absl::string_view ciphertext, absl::string_view additional_data) const {
  if (ciphertext.size() < BLOCK_SIZE) {
    return util::Status(util::error::INVALID_ARGUMENT, "ciphertext too short");
  }
  size_t plaintext_size = ciphertext.size() - BLOCK_SIZE;
  std::vector<uint8_t> pt(plaintext_size);
  const uint8_t *siv = reinterpret_cast<const uint8_t*>(&ciphertext[0]);
  const uint8_t *ct = reinterpret_cast<const uint8_t*>(&ciphertext[BLOCK_SIZE]);
  CtrCrypt(siv, ct, pt.data(), plaintext_size);

  uint8_t s2v[BLOCK_SIZE];
  S2v(reinterpret_cast<const uint8_t*>(additional_data.data()),
      additional_data.size(), pt.data(), plaintext_size, s2v);
  // Compare the siv from the ciphertext with the recomputed siv
  uint8_t diff = 0;
  for (int i = 0; i < BLOCK_SIZE; ++i) {
    diff |= siv[i] ^ s2v[i];
  }
  if (diff != 0) {
    return util::Status(util::error::INVALID_ARGUMENT, "invalid ciphertext");
  }
  return std::string(reinterpret_cast<const char*>(pt.data()), plaintext_size);
}

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