/*
 * 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 <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 = 0;

    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: {},
    },
};
