/*
 * Copyright (C) 2012 Samsung Electronics Co., LTD
 * Copyright (C) 2012 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 <errno.h>
#include <string.h>
#include <stdint.h>

#include <keystore.h>

#include <hardware/hardware.h>
#include <hardware/keymaster.h>

#include <openssl/evp.h>
#include <openssl/bio.h>
#include <openssl/rsa.h>
#include <openssl/err.h>
#include <openssl/x509.h>

#include <utils/UniquePtr.h>

#define LOG_TAG "ExynosKeyMaster"
#include <cutils/log.h>

#include <tlcTeeKeymaster_if.h>

#define RSA_KEY_BUFFER_SIZE   1536
#define RSA_KEY_MAX_SIZE      (2048 >> 3)

struct BIGNUM_Delete {
    void operator()(BIGNUM* p) const {
        BN_free(p);
    }
};
typedef UniquePtr<BIGNUM, BIGNUM_Delete> Unique_BIGNUM;

struct EVP_PKEY_Delete {
    void operator()(EVP_PKEY* p) const {
        EVP_PKEY_free(p);
    }
};
typedef UniquePtr<EVP_PKEY, EVP_PKEY_Delete> Unique_EVP_PKEY;

struct PKCS8_PRIV_KEY_INFO_Delete {
    void operator()(PKCS8_PRIV_KEY_INFO* p) const {
        PKCS8_PRIV_KEY_INFO_free(p);
    }
};
typedef UniquePtr<PKCS8_PRIV_KEY_INFO, PKCS8_PRIV_KEY_INFO_Delete> Unique_PKCS8_PRIV_KEY_INFO;

struct RSA_Delete {
    void operator()(RSA* p) const {
        RSA_free(p);
    }
};
typedef UniquePtr<RSA, RSA_Delete> Unique_RSA;

typedef UniquePtr<keymaster_device_t> Unique_keymaster_device_t;

/**
 * Many OpenSSL APIs take ownership of an argument on success but don't free the argument
 * on failure. This means we need to tell our scoped pointers when we've transferred ownership,
 * without triggering a warning by not using the result of release().
 */
#define OWNERSHIP_TRANSFERRED(obj) \
    typeof (obj.release()) _dummy __attribute__((unused)) = obj.release()

/*
 * Checks this thread's error queue and logs if necessary.
 */
static void logOpenSSLError(const char* location) {
    int error = ERR_get_error();

    if (error != 0) {
        char message[256];
        ERR_error_string_n(error, message, sizeof(message));
        ALOGE("OpenSSL error in %s %d: %s", location, error, message);
    }

    ERR_clear_error();
    ERR_remove_state(0);
}

static int exynos_km_generate_keypair(const keymaster_device_t* dev,
        const keymaster_keypair_t key_type, const void* key_params,
        uint8_t** keyBlob, size_t* keyBlobLength) {
    teeResult_t ret = TEE_ERR_NONE;

    if (key_type != TYPE_RSA) {
        ALOGE("Unsupported key type %d", key_type);
        return -1;
    } else if (key_params == NULL) {
        ALOGE("key_params == null");
        return -1;
    }

    keymaster_rsa_keygen_params_t* rsa_params = (keymaster_rsa_keygen_params_t*) key_params;

    if ((rsa_params->modulus_size != 512) &&
        (rsa_params->modulus_size != 1024) &&
        (rsa_params->modulus_size != 2048)) {
        ALOGE("key size(%d) is not supported\n", rsa_params->modulus_size);
        return -1;
    }

    UniquePtr<uint8_t> keyDataPtr(reinterpret_cast<uint8_t*>(malloc(RSA_KEY_BUFFER_SIZE)));
    if (keyDataPtr.get() == NULL) {
        ALOGE("memory allocation is failed");
        return -1;
    }

    ret = TEE_RSAGenerateKeyPair(TEE_KEYPAIR_RSACRT, keyDataPtr.get(), RSA_KEY_BUFFER_SIZE,
				rsa_params->modulus_size, (uint32_t)rsa_params->public_exponent,
				keyBlobLength);
    if (ret != TEE_ERR_NONE) {
        ALOGE("TEE_RSAGenerateKeyPair() is failed: %d", ret);
        return -1;
    }

   *keyBlob = keyDataPtr.release();

    return 0;
}

static int exynos_km_import_keypair(const keymaster_device_t* dev,
        const uint8_t* key, const size_t key_length,
        uint8_t** key_blob, size_t* key_blob_length) {
    uint8_t kbuf[RSA_KEY_BUFFER_SIZE];
    teeRsaKeyMeta_t metadata;
    uint32_t key_len = 0;
    teeResult_t ret = TEE_ERR_NONE;

    if (key == NULL) {
        ALOGE("input key == NULL");
        return -1;
    } else if (key_blob == NULL || key_blob_length == NULL) {
        ALOGE("output key blob or length == NULL");
        return -1;
    }

    /* decoding */
    Unique_PKCS8_PRIV_KEY_INFO pkcs8(d2i_PKCS8_PRIV_KEY_INFO(NULL, &key, key_length));
    if (pkcs8.get() == NULL) {
        logOpenSSLError("pkcs4.get");
        return -1;
    }

    /* assign to EVP */
    Unique_EVP_PKEY pkey(EVP_PKCS82PKEY(pkcs8.get()));
    if (pkey.get() == NULL) {
        logOpenSSLError("pkey.get");
        return -1;
    }
    OWNERSHIP_TRANSFERRED(pkcs8);

    /* change key format */
    RSA* rsa = pkey.get()->pkey.rsa;
    if (rsa == NULL) {
        logOpenSSLError("get rsa key format");
	return -1;
    }

    key_len += sizeof(metadata);

    metadata.lenpubmod = BN_bn2bin(rsa->n, kbuf + key_len);
    key_len += metadata.lenpubmod;
    if (metadata.lenpubmod == (512 >> 3))
        metadata.keysize = TEE_RSA_KEY_SIZE_512;
    else if (metadata.lenpubmod == (1024 >> 3))
        metadata.keysize = TEE_RSA_KEY_SIZE_1024;
    else if (metadata.lenpubmod == (2048 >> 3))
        metadata.keysize = TEE_RSA_KEY_SIZE_2048;
    else {
        ALOGE("key size(%d) is not supported\n", metadata.lenpubmod << 3);
        return -1;
    }

    metadata.lenpubexp = BN_bn2bin(rsa->e, kbuf + key_len);
    key_len += metadata.lenpubexp;

    if ((rsa->p != NULL) && (rsa->q != NULL) && (rsa->dmp1 != NULL) &&
	(rsa->dmq1 != NULL) && (rsa->iqmp != NULL))
    {
           metadata.keytype = TEE_KEYPAIR_RSACRT;
	   metadata.rsacrtpriv.lenp = BN_bn2bin(rsa->p, kbuf + key_len);
	   key_len += metadata.rsacrtpriv.lenp;
	   metadata.rsacrtpriv.lenq = BN_bn2bin(rsa->q, kbuf + key_len);
	   key_len += metadata.rsacrtpriv.lenq;
	   metadata.rsacrtpriv.lendp = BN_bn2bin(rsa->dmp1, kbuf + key_len);
	   key_len += metadata.rsacrtpriv.lendp;
	   metadata.rsacrtpriv.lendq = BN_bn2bin(rsa->dmq1, kbuf + key_len);
	   key_len += metadata.rsacrtpriv.lendq;
	   metadata.rsacrtpriv.lenqinv = BN_bn2bin(rsa->iqmp, kbuf + key_len);
	   key_len += metadata.rsacrtpriv.lenqinv;
    } else {
           metadata.keytype = TEE_KEYPAIR_RSA;
	   metadata.rsapriv.lenpriexp = BN_bn2bin(rsa->p, kbuf + key_len);
	   key_len += metadata.rsapriv.lenprimod;
    }
    memcpy(kbuf, &metadata, sizeof(metadata));

    UniquePtr<uint8_t> outPtr(reinterpret_cast<uint8_t*>(malloc(RSA_KEY_BUFFER_SIZE)));
    if (outPtr.get() == NULL) {
        ALOGE("memory allocation is failed");
        return -1;
    }

    *key_blob_length = RSA_KEY_BUFFER_SIZE;

    ret = TEE_KeyImport(kbuf, key_len, outPtr.get(), key_blob_length);
    if (ret != TEE_ERR_NONE) {
        ALOGE("TEE_KeyImport() is failed: %d", ret);
        return -1;
    }

    *key_blob = outPtr.release();

    return 0;
}

static int exynos_km_get_keypair_public(const struct keymaster_device* dev,
        const uint8_t* key_blob, const size_t key_blob_length,
        uint8_t** x509_data, size_t* x509_data_length) {
    uint32_t bin_mod_len;
    uint32_t bin_exp_len;
    teeResult_t ret = TEE_ERR_NONE;

    if (x509_data == NULL || x509_data_length == NULL) {
        ALOGE("output public key buffer == NULL");
        return -1;
    }

    UniquePtr<uint8_t> binModPtr(reinterpret_cast<uint8_t*>(malloc(RSA_KEY_MAX_SIZE)));
    if (binModPtr.get() == NULL) {
        ALOGE("memory allocation is failed");
        return -1;
    }

    UniquePtr<uint8_t> binExpPtr(reinterpret_cast<uint8_t*>(malloc(sizeof(uint32_t))));
    if (binExpPtr.get() == NULL) {
        ALOGE("memory allocation is failed");
        return -1;
    }

    bin_mod_len = RSA_KEY_MAX_SIZE;
    bin_exp_len = sizeof(uint32_t);

    ret = TEE_GetPubKey(key_blob, key_blob_length, binModPtr.get(), &bin_mod_len, binExpPtr.get(),
			&bin_exp_len);
    if (ret != TEE_ERR_NONE) {
        ALOGE("TEE_GetPubKey() is failed: %d", ret);
        return -1;
    }

    Unique_BIGNUM bn_mod(BN_new());
    if (bn_mod.get() == NULL) {
        ALOGE("memory allocation is failed");
        return -1;
    }

    Unique_BIGNUM bn_exp(BN_new());
    if (bn_exp.get() == NULL) {
        ALOGE("memory allocation is failed");
        return -1;
    }

    BN_bin2bn(binModPtr.get(), bin_mod_len, bn_mod.get());
    BN_bin2bn(binExpPtr.get(), bin_exp_len, bn_exp.get());

    /* assign to RSA */
    Unique_RSA rsa(RSA_new());
    if (rsa.get() == NULL) {
        logOpenSSLError("rsa.get");
        return -1;
    }

    RSA* rsa_tmp = rsa.get();

    rsa_tmp->n = bn_mod.release();
    rsa_tmp->e = bn_exp.release();

    /* assign to EVP */
    Unique_EVP_PKEY pkey(EVP_PKEY_new());
    if (pkey.get() == NULL) {
        logOpenSSLError("allocate EVP_PKEY");
        return -1;
    }

    if (EVP_PKEY_assign_RSA(pkey.get(), rsa.get()) == 0) {
        logOpenSSLError("assing RSA to EVP_PKEY");
        return -1;
    }
    OWNERSHIP_TRANSFERRED(rsa);

    /* change to x.509 format */
    int len = i2d_PUBKEY(pkey.get(), NULL);
    if (len <= 0) {
        logOpenSSLError("i2d_PUBKEY");
        return -1;
    }

    UniquePtr<uint8_t> key(static_cast<uint8_t*>(malloc(len)));
    if (key.get() == NULL) {
        ALOGE("Could not allocate memory for public key data");
        return -1;
    }

    unsigned char* tmp = reinterpret_cast<unsigned char*>(key.get());
    if (i2d_PUBKEY(pkey.get(), &tmp) != len) {
        logOpenSSLError("Compare results");
        return -1;
    }

    *x509_data_length = len;
    *x509_data = key.release();

    return 0;
}

static int exynos_km_sign_data(const keymaster_device_t* dev,
        const void* params,
        const uint8_t* keyBlob, const size_t keyBlobLength,
        const uint8_t* data, const size_t dataLength,
        uint8_t** signedData, size_t* signedDataLength) {
    teeResult_t ret = TEE_ERR_NONE;

    if (data == NULL) {
        ALOGE("input data to sign == NULL");
        return -1;
    } else if (signedData == NULL || signedDataLength == NULL) {
        ALOGE("output signature buffer == NULL");
        return -1;
    }

    keymaster_rsa_sign_params_t* sign_params = (keymaster_rsa_sign_params_t*) params;
    if (sign_params->digest_type != DIGEST_NONE) {
        ALOGE("Cannot handle digest type %d", sign_params->digest_type);
        return -1;
    } else if (sign_params->padding_type != PADDING_NONE) {
        ALOGE("Cannot handle padding type %d", sign_params->padding_type);
        return -1;
    }

    UniquePtr<uint8_t> signedDataPtr(reinterpret_cast<uint8_t*>(malloc(RSA_KEY_MAX_SIZE)));
    if (signedDataPtr.get() == NULL) {
        ALOGE("memory allocation is failed");
        return -1;
    }

    *signedDataLength = RSA_KEY_MAX_SIZE;

    ret = TEE_RSASign(keyBlob, keyBlobLength, data, dataLength, signedDataPtr.get(),
			signedDataLength, TEE_RSA_NODIGEST_NOPADDING);
    if (ret != TEE_ERR_NONE) {
        ALOGE("TEE_RSASign() is failed: %d", ret);
        return -1;
    }

    *signedData = signedDataPtr.release();

    return 0;
}

static int exynos_km_verify_data(const keymaster_device_t* dev,
        const void* params,
        const uint8_t* keyBlob, const size_t keyBlobLength,
        const uint8_t* signedData, const size_t signedDataLength,
        const uint8_t* signature, const size_t signatureLength) {
    bool result;
    teeResult_t ret = TEE_ERR_NONE;

    if (signedData == NULL || signature == NULL) {
        ALOGE("data or signature buffers == NULL");
        return -1;
    }

    keymaster_rsa_sign_params_t* sign_params = (keymaster_rsa_sign_params_t*) params;
    if (sign_params->digest_type != DIGEST_NONE) {
        ALOGE("Cannot handle digest type %d", sign_params->digest_type);
        return -1;
    } else if (sign_params->padding_type != PADDING_NONE) {
        ALOGE("Cannot handle padding type %d", sign_params->padding_type);
        return -1;
    } else if (signatureLength != signedDataLength) {
        ALOGE("signed data length must be signature length");
        return -1;
    }

    ret = TEE_RSAVerify(keyBlob, keyBlobLength, signedData, signedDataLength, signature,
			signatureLength, TEE_RSA_NODIGEST_NOPADDING, &result);
    if (ret != TEE_ERR_NONE) {
        ALOGE("TEE_RSAVerify() is failed: %d", ret);
        return -1;
    }

    return (result == true) ? 0 : -1;
}

/* Close an opened Exynos KM instance */
static int exynos_km_close(hw_device_t *dev) {
    free(dev);
    return 0;
}

/*
 * Generic device handling
 */
static int exynos_km_open(const hw_module_t* module, const char* name,
        hw_device_t** device) {
    if (strcmp(name, KEYSTORE_KEYMASTER) != 0)
        return -EINVAL;

    Unique_keymaster_device_t dev(new keymaster_device_t);
    if (dev.get() == NULL)
        return -ENOMEM;

    dev->common.tag = HARDWARE_DEVICE_TAG;
    dev->common.version = 1;
    dev->common.module = (struct hw_module_t*) module;
    dev->common.close = exynos_km_close;

    dev->flags = KEYMASTER_SOFTWARE_ONLY;

    dev->generate_keypair = exynos_km_generate_keypair;
    dev->import_keypair = exynos_km_import_keypair;
    dev->get_keypair_public = exynos_km_get_keypair_public;
    dev->delete_keypair = NULL;
    dev->delete_all = NULL;
    dev->sign_data = exynos_km_sign_data;
    dev->verify_data = exynos_km_verify_data;

    ERR_load_crypto_strings();
    ERR_load_BIO_strings();

    *device = reinterpret_cast<hw_device_t*>(dev.release());

    return 0;
}

static struct hw_module_methods_t keystore_module_methods = {
    open: exynos_km_open,
};

struct keystore_module HAL_MODULE_INFO_SYM
__attribute__ ((visibility ("default"))) = {
    common: {
        tag: HARDWARE_MODULE_TAG,
        version_major: 1,
        version_minor: 0,
        id: KEYSTORE_HARDWARE_MODULE_ID,
        name: "Keymaster Exynos HAL",
        author: "Samsung S.LSI",
        methods: &keystore_module_methods,
        dso: 0,
        reserved: {},
    },
};
