/*
 * 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.
 */
#pragma once

#include <gtest/gtest.h>
#include <stdint.h>

#include <string>
#include <vector>

namespace android {
namespace kernel {

class Cipher {
 public:
  virtual ~Cipher() {}
  bool Encrypt(const std::vector<uint8_t> &key, const uint8_t *iv,
               const uint8_t *src, uint8_t *dst, int nbytes) const {
    if (key.size() != keysize()) {
      ADD_FAILURE() << "Bad key size";
      return false;
    }
    return DoCrypt(key.data(), iv, src, dst, nbytes, true);
  }
  bool Decrypt(const std::vector<uint8_t> &key, const uint8_t *iv,
               const uint8_t *src, uint8_t *dst, int nbytes) const {
    if (key.size() != keysize()) {
      ADD_FAILURE() << "Bad key size";
      return false;
    }
    return DoCrypt(key.data(), iv, src, dst, nbytes, false);
  }
  virtual int keysize() const = 0;
  virtual int ivsize() const = 0;

 protected:
  virtual bool DoCrypt(const uint8_t *key, const uint8_t *iv,
                       const uint8_t *src, uint8_t *dst, int nbytes,
                       bool encrypt) const = 0;
};

// aes_256_xts.cpp

constexpr int kAesBlockSize = 16;
constexpr int kAes256KeySize = 32;
constexpr int kAes256XtsKeySize = 2 * kAes256KeySize;

class Aes256XtsCipher : public Cipher {
 public:
  int keysize() const { return kAes256XtsKeySize; }
  int ivsize() const { return kAesBlockSize; }

 private:
  bool DoCrypt(const uint8_t *key, const uint8_t *iv, const uint8_t *src,
               uint8_t *dst, int nbytes, bool encrypt) const;
};

// adiantum.cpp

constexpr int kAdiantumKeySize = 32;

// It's variable-length in general, but the Linux kernel always uses 32.
constexpr int kAdiantumIVSize = 32;

class AdiantumCipher : public Cipher {
 public:
  int keysize() const { return kAdiantumKeySize; }
  int ivsize() const { return kAdiantumIVSize; }

 private:
  bool DoCrypt(const uint8_t *key, const uint8_t *iv, const uint8_t *src,
               uint8_t *dst, int nbytes, bool encrypt) const;
};

// utils.cpp

std::string Errno();

void DeleteRecursively(const std::string &path);

void RandomBytesForTesting(std::vector<uint8_t> &bytes);

std::vector<uint8_t> GenerateTestKey(size_t size);

std::string BytesToHex(const std::vector<uint8_t> &bytes);

template <size_t N>
static inline std::string BytesToHex(const uint8_t (&array)[N]) {
  return BytesToHex(std::vector<uint8_t>(&array[0], &array[N]));
}

bool GetFirstApiLevel(int *first_api_level);

constexpr int kFilesystemUuidSize = 16;

struct FilesystemUuid {
  uint8_t bytes[kFilesystemUuidSize];
};

struct FilesystemInfo {
  std::string fs_blk_device;
  std::string type;
  FilesystemUuid uuid;
  std::string raw_blk_device;
};

bool GetFilesystemInfo(const std::string &mountpoint, FilesystemInfo *info);

bool VerifyDataRandomness(const std::vector<uint8_t> &bytes);

bool CreateHwWrappedKey(std::vector<uint8_t> *master_key,
                        std::vector<uint8_t> *exported_key);

bool DeriveHwWrappedEncryptionKey(const std::vector<uint8_t> &master_key,
                                  std::vector<uint8_t> *enc_key);

bool DeriveHwWrappedRawSecret(const std::vector<uint8_t> &master_key,
                              std::vector<uint8_t> *secret);
}  // namespace kernel
}  // namespace android
