/*
 * Copyright (C) 2019 The LineageOS 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.
 */

#define LOG_TAG "vendor.qti.hardware.cryptfshw@1.0-impl-qti.qsee"

#include "QSEEComController.h"

#include <CryptfsHwUtils.h>
#include <Types.h>
#include <android-base/logging.h>
#include <android-base/properties.h>
#include <dlfcn.h>

#include <thread>

namespace {
constexpr char kFilename[] = "libQSEEComAPI.so";

#ifdef WAIT_FOR_QSEE
bool IsQseecomUp() {
    using namespace std::chrono_literals;
    for (size_t i = 0; i < CRYPTFS_HW_UP_CHECK_COUNT; i++) {
        if (::android::base::GetBoolProperty("sys.keymaster.loaded", false)) {
            return true;
        }
        std::this_thread::sleep_for(100ms);
    }

    LOG(ERROR) << "Timed out waiting for QSEECom";
    return false;
}
#endif
}  // anonymous namespace

namespace vendor {
namespace qti {
namespace hardware {
namespace cryptfshw {
namespace V1_0 {
namespace implementation {
namespace qsee {

Controller::Controller() {
    std::shared_ptr<void> handle(dlopen(kFilename, RTLD_LAZY | RTLD_LOCAL), [this](void* p) {
        mFn_create_key = nullptr;
        mFn_update_key_user_info = nullptr;
        mFn_wipe_key = nullptr;

        if (p != nullptr) {
            int err = dlclose(p);
            p = nullptr;
            if (err != 0) {
                LOG(ERROR) << "FAILED TO CLOSE LIBRARY " << kFilename;
            }
        }
    });
    if (handle == nullptr) {
        LOG(ERROR) << "FAILED TO LOAD LIBRARY " << kFilename << ": " << dlerror();
        return;
    }

#ifdef WAIT_FOR_QSEE
    if (!IsQseecomUp()) {
        LOG_TO(SYSTEM, ERROR)
                << "Timed out waiting for QSEECom listeners. Aborting FDE key operation";
        return;
    }
#endif

    handle_ = handle;
    mFn_create_key = loadFunction<int (*)(int, void*)>("QSEECom_create_key");
    mFn_update_key_user_info =
            loadFunction<int (*)(int, void*, void*)>("QSEECom_update_key_user_info");
    mFn_wipe_key = loadFunction<int (*)(int)>("QSEECom_wipe_key");
}

template <typename Function>
Function Controller::loadFunction(const char* name) {
    void* fn = dlsym(handle_.get(), name);
    if (fn == nullptr) {
        LOG(ERROR) << "loadFunction -- failed to load function " << name;
    }
    return reinterpret_cast<Function>(fn);
}

int Controller::createKey(int usage, const char* passwd) {
    int32_t ret;
    unsigned char hash32[MAX_PASSWORD_LEN];

    if (mFn_create_key == nullptr) return CRYPTFS_HW_UPDATE_KEY_FAILED;

    GetTmpPasswd(passwd, hash32, MAX_PASSWORD_LEN);

    ret = mFn_create_key(usage, hash32);
    if (ret) {
        LOG_TO(SYSTEM, ERROR) << "Error::Qseecom call to create encryption key for usage " << usage
                              << " failed with ret = " << ret << ", errno = " << errno;
        if (errno == ERANGE) {
            ret = CRYPTFS_HW_KMS_MAX_FAILURE;
        } else {
            ret = CRYPTFS_HW_CREATE_KEY_FAILED;
        }
    } else {
        LOG_TO(SYSTEM, ERROR) << "SUCESS::Qseecom call to create encryption key for usage " << usage
                              << " success with ret = " << ret;
    }

    secure_memset(hash32, 0, MAX_PASSWORD_LEN);

    return ret;
}

int Controller::updateKey(int usage, const char* oldpw, const char* newpw) {
    int32_t ret;
    unsigned char current_hash32[MAX_PASSWORD_LEN], new_hash32[MAX_PASSWORD_LEN];

    if (mFn_update_key_user_info == nullptr) return CRYPTFS_HW_UPDATE_KEY_FAILED;

    GetTmpPasswd(oldpw, current_hash32, MAX_PASSWORD_LEN);
    GetTmpPasswd(newpw, new_hash32, MAX_PASSWORD_LEN);

    ret = mFn_update_key_user_info(usage, current_hash32, new_hash32);
    if (ret) {
        LOG_TO(SYSTEM, ERROR) << "Error::Qseecom call to update the encryption key for usage "
                              << usage << " failed with ret = " << ret << ", errno = " << errno;
        if (errno == ERANGE) {
            ret = CRYPTFS_HW_KMS_MAX_FAILURE;
        } else {
            ret = CRYPTFS_HW_UPDATE_KEY_FAILED;
        }
    } else {
        LOG_TO(SYSTEM, ERROR) << "SUCCESS::Qseecom call to update the encryption key for usage "
                              << usage << " success with ret = " << ret;
    }

    secure_memset(current_hash32, 0, MAX_PASSWORD_LEN);
    secure_memset(new_hash32, 0, MAX_PASSWORD_LEN);

    return ret;
}

int Controller::wipeKey(int usage) {
    int32_t ret;

    if (mFn_wipe_key == nullptr) return CRYPTFS_HW_UPDATE_KEY_FAILED;

    ret = mFn_wipe_key(usage);
    if (ret) {
        LOG_TO(SYSTEM, ERROR) << "Error::Qseecom call to wipe the encryption key for usage "
                              << usage << " failed with ret = " << ret << ", errno = " << errno;
        ret = CRYPTFS_HW_WIPE_KEY_FAILED;
    } else {
        LOG_TO(SYSTEM, ERROR) << "SUCCESS::Qseecom call to wipe the encryption key for usage "
                              << usage << " success with ret = " << ret;
    }
    return ret;
}

}  // namespace qsee
}  // namespace implementation
}  // namespace V1_0
}  // namespace cryptfshw
}  // namespace hardware
}  // namespace qti
}  // namespace vendor
