/*
 * Copyright 2014 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.
 */

#ifndef SYSTEM_KEYMASTER_ANDROID_KEYMASTER_TEST_UTILS_H_
#define SYSTEM_KEYMASTER_ANDROID_KEYMASTER_TEST_UTILS_H_

/*
 * Utilities used to help with testing.  Not used in production code.
 */

#include <stdarg.h>

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

#include <gtest/gtest.h>

#include <hardware/keymaster0.h>
#include <hardware/keymaster1.h>
#include <hardware/keymaster_defs.h>
#include <keymaster/authorization_set.h>
#include <keymaster/logger.h>

std::ostream& operator<<(std::ostream& os, const keymaster_key_param_t& param);
bool operator==(const keymaster_key_param_t& a, const keymaster_key_param_t& b);
std::string hex2str(std::string);

namespace keymaster {

bool operator==(const AuthorizationSet& a, const AuthorizationSet& b);
bool operator!=(const AuthorizationSet& a, const AuthorizationSet& b);

std::ostream& operator<<(std::ostream& os, const AuthorizationSet& set);

namespace test {

template <keymaster_tag_t Tag, typename KeymasterEnum>
bool contains(const AuthorizationSet& set, TypedEnumTag<KM_ENUM, Tag, KeymasterEnum> tag,
              KeymasterEnum val) {
    int pos = set.find(tag);
    return pos != -1 && set[pos].enumerated == val;
}

template <keymaster_tag_t Tag, typename KeymasterEnum>
bool contains(const AuthorizationSet& set, TypedEnumTag<KM_ENUM_REP, Tag, KeymasterEnum> tag,
              KeymasterEnum val) {
    int pos = -1;
    while ((pos = set.find(tag, pos)) != -1)
        if (set[pos].enumerated == val)
            return true;
    return false;
}

template <keymaster_tag_t Tag>
bool contains(const AuthorizationSet& set, TypedTag<KM_INT, Tag> tag, uint32_t val) {
    int pos = set.find(tag);
    return pos != -1 && set[pos].integer == val;
}

template <keymaster_tag_t Tag>
bool contains(const AuthorizationSet& set, TypedTag<KM_INT_REP, Tag> tag, uint32_t val) {
    int pos = -1;
    while ((pos = set.find(tag, pos)) != -1)
        if (set[pos].integer == val)
            return true;
    return false;
}

template <keymaster_tag_t Tag>
bool contains(const AuthorizationSet& set, TypedTag<KM_LONG, Tag> tag, uint64_t val) {
    int pos = set.find(tag);
    return pos != -1 && set[pos].long_integer == val;
}

template <keymaster_tag_t Tag>
bool contains(const AuthorizationSet& set, TypedTag<KM_BYTES, Tag> tag, const std::string& val) {
    int pos = set.find(tag);
    return pos != -1 &&
           std::string(reinterpret_cast<const char*>(set[pos].blob.data),
                       set[pos].blob.data_length) == val;
}

template <keymaster_tag_t Tag>
bool contains(const AuthorizationSet& set, TypedTag<KM_BIGNUM, Tag> tag, const std::string& val) {
    int pos = set.find(tag);
    return pos != -1 &&
           std::string(reinterpret_cast<const char*>(set[pos].blob.data),
                       set[pos].blob.data_length) == val;
}

inline bool contains(const AuthorizationSet& set, keymaster_tag_t tag) {
    return set.find(tag) != -1;
}

class StdoutLogger : public Logger {
  public:
    StdoutLogger() { set_instance(this); }

    int log_msg(LogLevel level, const char* fmt, va_list args) const {
        int output_len = 0;
        switch (level) {
        case DEBUG_LVL:
            output_len = printf("DEBUG: ");
            break;
        case INFO_LVL:
            output_len = printf("INFO: ");
            break;
        case WARNING_LVL:
            output_len = printf("WARNING: ");
            break;
        case ERROR_LVL:
            output_len = printf("ERROR: ");
            break;
        case SEVERE_LVL:
            output_len = printf("SEVERE: ");
            break;
        }

        output_len += vprintf(fmt, args);
        output_len += printf("\n");
        return output_len;
    }
};

inline std::string make_string(const uint8_t* data, size_t length) {
    return std::string(reinterpret_cast<const char*>(data), length);
}

template <size_t N> std::string make_string(const uint8_t(&a)[N]) {
    return make_string(a, N);
}

/**
 * Keymaster1TestInstance is used to parameterize Keymaster1Tests.  Its main function is to create a
 * keymaster1_device_t to which test calls can be directed.  It also provides a place to specify
 * various bits of alternative behavior, in cases where different devices are expected to behave
 * differently (any such cases are a potential bug, but sometimes they may make sense).
 */
class Keymaster1TestInstanceCreator {
  public:
    virtual ~Keymaster1TestInstanceCreator(){};
    virtual keymaster1_device_t* CreateDevice() const = 0;

    virtual bool algorithm_in_hardware(keymaster_algorithm_t algorithm) const = 0;
    virtual int keymaster0_calls() const = 0;
};

// Use a shared_ptr because it's copyable.
typedef std::shared_ptr<Keymaster1TestInstanceCreator> InstanceCreatorPtr;

const uint64_t OP_HANDLE_SENTINEL = 0xFFFFFFFFFFFFFFFF;
class Keymaster1Test : public testing::TestWithParam<InstanceCreatorPtr> {
  protected:
    Keymaster1Test();
    ~Keymaster1Test();

    keymaster1_device_t* device();

    keymaster_error_t GenerateKey(const AuthorizationSetBuilder& builder);

    keymaster_error_t ImportKey(const AuthorizationSetBuilder& builder,
                                keymaster_key_format_t format, const std::string& key_material);

    keymaster_error_t ExportKey(keymaster_key_format_t format, std::string* export_data);

    keymaster_error_t GetCharacteristics();

    keymaster_error_t BeginOperation(keymaster_purpose_t purpose);
    keymaster_error_t BeginOperation(keymaster_purpose_t purpose, const AuthorizationSet& input_set,
                                     AuthorizationSet* output_set = NULL);

    keymaster_error_t UpdateOperation(const std::string& message, std::string* output,
                                      size_t* input_consumed);
    keymaster_error_t UpdateOperation(const AuthorizationSet& additional_params,
                                      const std::string& message, std::string* output,
                                      size_t* input_consumed);

    keymaster_error_t FinishOperation(std::string* output);
    keymaster_error_t FinishOperation(const std::string& signature, std::string* output);
    keymaster_error_t FinishOperation(const AuthorizationSet& additional_params,
                                      const std::string& signature, std::string* output);

    keymaster_error_t AbortOperation();

    keymaster_error_t GetVersion(uint8_t* major, uint8_t* minor, uint8_t* subminor);

    std::string ProcessMessage(keymaster_purpose_t purpose, const std::string& message);
    std::string ProcessMessage(keymaster_purpose_t purpose, const std::string& message,
                               const AuthorizationSet& begin_params,
                               const AuthorizationSet& update_params,
                               AuthorizationSet* output_params = NULL);
    std::string ProcessMessage(keymaster_purpose_t purpose, const std::string& message,
                               const std::string& signature, const AuthorizationSet& begin_params,
                               const AuthorizationSet& update_params,
                               AuthorizationSet* output_params = NULL);
    std::string ProcessMessage(keymaster_purpose_t purpose, const std::string& message,
                               const std::string& signature);

    void SignMessage(const std::string& message, std::string* signature, keymaster_digest_t digest);
    void SignMessage(const std::string& message, std::string* signature, keymaster_digest_t digest,
                     keymaster_padding_t padding);
    void MacMessage(const std::string& message, std::string* signature, keymaster_digest_t digest,
                    size_t mac_length);

    void VerifyMessage(const std::string& message, const std::string& signature,
                       keymaster_digest_t digest);
    void VerifyMessage(const std::string& message, const std::string& signature,
                       keymaster_digest_t digest, keymaster_padding_t padding);

    std::string EncryptMessage(const std::string& message, keymaster_padding_t padding,
                               std::string* generated_nonce = NULL);
    std::string EncryptMessage(const std::string& message, keymaster_block_mode_t block_mode,
                               keymaster_padding_t padding, std::string* generated_nonce = NULL);
    std::string EncryptMessage(const AuthorizationSet& update_params, const std::string& message,
                               keymaster_padding_t padding, std::string* generated_nonce = NULL);
    std::string EncryptMessage(const AuthorizationSet& update_params, const std::string& message,
                               keymaster_block_mode_t block_mode, keymaster_padding_t padding,
                               std::string* generated_nonce = NULL);
    std::string EncryptMessageWithParams(const std::string& message,
                                         const AuthorizationSet& begin_params,
                                         const AuthorizationSet& update_params,
                                         AuthorizationSet* output_params);

    std::string DecryptMessage(const std::string& ciphertext, keymaster_padding_t padding);
    std::string DecryptMessage(const std::string& ciphertext, keymaster_block_mode_t block_mode,
                               keymaster_padding_t padding);
    std::string DecryptMessage(const std::string& ciphertext, keymaster_padding_t padding,
                               const std::string& nonce);
    std::string DecryptMessage(const std::string& ciphertext, keymaster_block_mode_t block_mode,
                               keymaster_padding_t padding, const std::string& nonce);
    std::string DecryptMessage(const AuthorizationSet& update_params, const std::string& ciphertext,
                               keymaster_padding_t padding, const std::string& nonce);
    std::string DecryptMessage(const AuthorizationSet& update_params, const std::string& ciphertext,
                               keymaster_block_mode_t block_mode, keymaster_padding_t padding,
                               const std::string& nonce);

    void CheckHmacTestVector(std::string key, std::string message, keymaster_digest_t digest,
                             std::string expected_mac);
    void CheckAesOcbTestVector(const std::string& key, const std::string& nonce,
                               const std::string& associated_data, const std::string& message,
                               const std::string& expected_ciphertext);
    void CheckAesCtrTestVector(const std::string& key, const std::string& nonce,
                               const std::string& message, const std::string& expected_ciphertext);
    AuthorizationSet UserAuthParams();
    AuthorizationSet ClientParams();

    template <typename T>
    bool ResponseContains(const std::vector<T>& expected, const T* values, size_t len) {
        return expected.size() == len &&
               std::is_permutation(values, values + len, expected.begin());
    }

    template <typename T> bool ResponseContains(T expected, const T* values, size_t len) {
        return (len == 1 && *values == expected);
    }

    AuthorizationSet hw_enforced();
    AuthorizationSet sw_enforced();

    void FreeCharacteristics();
    void FreeKeyBlob();

    void corrupt_key_blob();

    void set_key_blob(const uint8_t* key, size_t key_length) {
        FreeKeyBlob();
        blob_.key_material = key;
        blob_.key_material_size = key_length;
    }

    AuthorizationSet client_params() {
        return AuthorizationSet(client_params_, sizeof(client_params_) / sizeof(client_params_[0]));
    }

  private:
    keymaster1_device_t* device_;
    keymaster_blob_t client_id_ = {.data = reinterpret_cast<const uint8_t*>("app_id"),
                                   .data_length = 6};
    keymaster_key_param_t client_params_[1] = {
        Authorization(TAG_APPLICATION_ID, client_id_.data, client_id_.data_length)};

    uint64_t op_handle_;

    keymaster_key_blob_t blob_;
    keymaster_key_characteristics_t* characteristics_;
};

struct Keymaster0CountingWrapper : public keymaster0_device_t {
    Keymaster0CountingWrapper(keymaster0_device_t* device) : device_(device), counter_(0) {
        common = device_->common;
        common.close = counting_close_device;
        client_version = device_->client_version;
        flags = device_->flags;
        context = this;

        generate_keypair = counting_generate_keypair;
        import_keypair = counting_import_keypair;
        get_keypair_public = counting_get_keypair_public;
        delete_keypair = counting_delete_keypair;
        delete_all = counting_delete_all;
        sign_data = counting_sign_data;
        verify_data = counting_verify_data;
    }

    int count() { return counter_; }

    static keymaster0_device_t* device(const keymaster0_device_t* dev) {
        Keymaster0CountingWrapper* wrapper =
            reinterpret_cast<Keymaster0CountingWrapper*>(dev->context);
        return wrapper->device_;
    }

    static void increment(const keymaster0_device_t* dev) {
        Keymaster0CountingWrapper* wrapper =
            reinterpret_cast<Keymaster0CountingWrapper*>(dev->context);
        wrapper->counter_++;
    }

    static int counting_close_device(hw_device_t* dev) {
        keymaster0_device_t* k0_dev = reinterpret_cast<keymaster0_device_t*>(dev);
        increment(k0_dev);
        Keymaster0CountingWrapper* wrapper =
            reinterpret_cast<Keymaster0CountingWrapper*>(k0_dev->context);
        int retval =
            wrapper->device_->common.close(reinterpret_cast<hw_device_t*>(wrapper->device_));
        delete wrapper;
        return retval;
    }

    static int counting_generate_keypair(const struct keymaster0_device* dev,
                                         const keymaster_keypair_t key_type, const void* key_params,
                                         uint8_t** key_blob, size_t* key_blob_length) {
        increment(dev);
        return device(dev)
            ->generate_keypair(device(dev), key_type, key_params, key_blob, key_blob_length);
    }

    static int counting_import_keypair(const struct keymaster0_device* dev, const uint8_t* key,
                                       const size_t key_length, uint8_t** key_blob,
                                       size_t* key_blob_length) {
        increment(dev);
        return device(dev)->import_keypair(device(dev), key, key_length, key_blob, key_blob_length);
    }

    static int counting_get_keypair_public(const struct keymaster0_device* dev,
                                           const uint8_t* key_blob, const size_t key_blob_length,
                                           uint8_t** x509_data, size_t* x509_data_length) {
        increment(dev);
        return device(dev)->get_keypair_public(device(dev), key_blob, key_blob_length, x509_data,
                                               x509_data_length);
    }

    static int counting_delete_keypair(const struct keymaster0_device* dev, const uint8_t* key_blob,
                                       const size_t key_blob_length) {
        increment(dev);
        if (device(dev)->delete_keypair)
            return device(dev)->delete_keypair(device(dev), key_blob, key_blob_length);
        return 0;
    }

    static int counting_delete_all(const struct keymaster0_device* dev) {
        increment(dev);
        if (device(dev)->delete_all)
            return device(dev)->delete_all(device(dev));
        return 0;
    }

    static int counting_sign_data(const struct keymaster0_device* dev, const void* signing_params,
                                  const uint8_t* key_blob, const size_t key_blob_length,
                                  const uint8_t* data, const size_t data_length,
                                  uint8_t** signed_data, size_t* signed_data_length) {
        increment(dev);
        return device(dev)->sign_data(device(dev), signing_params, key_blob, key_blob_length, data,
                                      data_length, signed_data, signed_data_length);
    }

    static int counting_verify_data(const struct keymaster0_device* dev, const void* signing_params,
                                    const uint8_t* key_blob, const size_t key_blob_length,
                                    const uint8_t* signed_data, const size_t signed_data_length,
                                    const uint8_t* signature, const size_t signature_length) {
        increment(dev);
        return device(dev)->verify_data(device(dev), signing_params, key_blob, key_blob_length,
                                        signed_data, signed_data_length, signature,
                                        signature_length);
    }

  private:
    keymaster0_device_t* device_;
    int counter_;
};

}  // namespace test
}  // namespace keymaster

#endif  // SYSTEM_KEYMASTER_ANDROID_KEYMASTER_TEST_UTILS_H_
