/*
 * Copyright (C) 2020 The Android Open Source Project
 *
 * 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 <gtest/gtest.h>
#include <openssl/cipher.h>
#include <openssl/evp.h>
#include <string.h>

#include "vts_kernel_encryption.h"

namespace android {
namespace kernel {

static void DoXtsMasking(uint8_t *data, int num_blocks,
                         const uint8_t tweak[kAesBlockSize]) {
  uint8_t mask[kAesBlockSize];

  memcpy(mask, tweak, kAesBlockSize);

  for (int i = 0; i < num_blocks; i++) {
    // XOR the next block with the current mask.
    for (int j = 0; j < kAesBlockSize; j++) {
      data[i * kAesBlockSize + j] ^= mask[j];
    }
    // Multipy the mask by 'x' in GF(2^128).
    int carry = 0;
    for (int j = 0; j < kAesBlockSize; j++) {
      int next_carry = mask[j] >> 7;

      mask[j] = (mask[j] << 1) ^ carry;
      carry = next_carry;
    }
    if (carry != 0) {
      mask[0] ^= 0x87;
    }
  }
}

bool Aes256XtsCipher::DoCrypt(const uint8_t key[kAes256XtsKeySize],
                              const uint8_t iv[kAesBlockSize],
                              const uint8_t *src, uint8_t *dst, int nbytes,
                              bool encrypt) const {
  std::unique_ptr<EVP_CIPHER_CTX, void (*)(EVP_CIPHER_CTX *)> ctx(
      EVP_CIPHER_CTX_new(), EVP_CIPHER_CTX_free);
  const char *op = encrypt ? "encryption" : "decryption";
  int outl;

  if (ctx == nullptr) {
    ADD_FAILURE() << "Failed to allocate BoringSSL cipher context";
    return false;
  }
  if (nbytes % kAesBlockSize != 0) {
    ADD_FAILURE() << "Bad input size";
    return false;
  }

  // For some reason, BoringSSL considers AES-256-XTS to be deprecated, and it's
  // in a directory of deprecated algorithms that's not compiled on Android.
  // AES-256-ECB is still available though, so just implement XTS manually...

  // Encrypt the IV.  This uses the second half of the AES-256-XTS key.
  uint8_t tweak[kAesBlockSize];
  if (EVP_EncryptInit_ex(ctx.get(), EVP_aes_256_ecb(), nullptr,
                         key + kAes256KeySize, nullptr) != 1) {
    ADD_FAILURE() << "Failed to initialize BoringSSL AES context";
    return false;
  }
  if (EVP_EncryptUpdate(ctx.get(), tweak, &outl, iv, kAesBlockSize) != 1 ||
      outl != kAesBlockSize) {
    ADD_FAILURE() << "BoringSSL AES encryption of tweak failed";
    return false;
  }

  // Copy plaintext to output buffer, so that we can just transform it in-place.
  memmove(dst, src, nbytes);

  // Mask the data pre-encryption/decryption.
  DoXtsMasking(dst, nbytes / kAesBlockSize, tweak);

  // Encrypt or decrypt the data.
  if (EVP_CipherInit_ex(ctx.get(), EVP_aes_256_ecb(), nullptr, key, nullptr,
                        encrypt) != 1) {
    ADD_FAILURE() << "Failed to reinitialize BoringSSL AES context";
    return false;
  }
  EVP_CIPHER_CTX_set_padding(ctx.get(), 0);
  if (EVP_CipherUpdate(ctx.get(), dst, &outl, dst, nbytes) != 1 ||
      outl != nbytes) {
    ADD_FAILURE() << "BoringSSL AES " << op << " of data failed";
    return false;
  }
  // Mask the data post-encryption/decryption.
  DoXtsMasking(dst, nbytes / kAesBlockSize, tweak);
  return true;
}

}  // namespace kernel
}  // namespace android
