/*
 *  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 <memory>

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

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

#include <linux/ioctl.h>
#include <linux/msm_ion.h>
#include <sys/mman.h>

#include <stdio.h>
#include <stdlib.h>
#include <stddef.h>
#include <unistd.h>
#include <dirent.h>
#include <fcntl.h>

#include <sys/types.h>
#include <sys/stat.h>
#include <dlfcn.h>

#include "QSEEComAPI.h"
#include "keymaster_qcom.h"

// For debugging
//#define LOG_NDEBUG 0

#define LOG_TAG "QCOMKeyMaster"
#include <cutils/log.h>
struct qcom_km_ion_info_t {
    int32_t ion_fd;
    int32_t ifd_data_fd;
    struct ion_handle_data ion_alloc_handle;
    unsigned char * ion_sbuffer;
    uint32_t sbuf_len;
};

struct qcom_keymaster_handle {
    struct QSEECom_handle *qseecom;
    void *libhandle;
    int (*QSEECom_start_app)(struct QSEECom_handle ** handle, char* path,
                          char* appname, uint32_t size);
    int (*QSEECom_shutdown_app)(struct QSEECom_handle **handle);
    int (*QSEECom_send_cmd)(struct QSEECom_handle* handle, void *cbuf,
                          uint32_t clen, void *rbuf, uint32_t rlen);
    int (*QSEECom_send_modified_cmd)(struct QSEECom_handle* handle, void *cbuf,
                          uint32_t clen, void *rbuf, uint32_t rlen,
                          struct QSEECom_ion_fd_info *ihandle);
    int (*QSEECom_set_bandwidth)(struct QSEECom_handle* handle, bool high);
};
typedef struct qcom_keymaster_handle qcom_keymaster_handle_t;

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

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

typedef std::unique_ptr<keymaster0_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()

static int qcom_km_get_keypair_public(const keymaster0_device_t* dev,
        const uint8_t* keyBlob, const size_t keyBlobLength,
        uint8_t** x509_data, size_t* x509_data_length) {

    struct qcom_km_key_blob * keyblob_ptr = (struct qcom_km_key_blob *)keyBlob;

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

    if (keyBlob == NULL) {
        ALOGE("Supplied key blob was NULL");
        return -1;
    }

    // Should be large enough for keyblob data:
    if (keyBlobLength < (sizeof(qcom_km_key_blob_t))) {
        ALOGE("key blob appears to be truncated");
        return -1;
    }

    if (keyblob_ptr->magic_num != KM_MAGIC_NUM) {
        ALOGE("Cannot read key; it was not made by this keymaster");
        return -1;
    }

    if (keyblob_ptr->public_exponent_size == 0 ) {
        ALOGE("Key blob appears to have incorrect exponent length");
        return -1;
    }
    if (keyblob_ptr->modulus_size == 0 ) {
        ALOGE("Key blob appears to have incorrect modulus length");
        return -1;
    }

    Unique_RSA rsa(RSA_new());
    if (rsa.get() == NULL) {
        ALOGE("Could not allocate RSA structure");
        return -1;
    }

    rsa->n = BN_bin2bn(reinterpret_cast<const unsigned char*>(keyblob_ptr->modulus),
                               keyblob_ptr->modulus_size, NULL);
    if (rsa->n == NULL) {
       ALOGE("Failed to initialize  modulus");
        return -1;
    }

    rsa->e = BN_bin2bn(reinterpret_cast<const unsigned char*>(&keyblob_ptr->public_exponent),
                               keyblob_ptr->public_exponent_size, NULL);
    if (rsa->e == NULL) {
        ALOGE("Failed to initialize public exponent");
        return -1;
    }

    Unique_EVP_PKEY pkey(EVP_PKEY_new());
    if (pkey.get() == NULL) {
        ALOGE("Could not allocate EVP_PKEY structure");
        return -1;
    }
    if (EVP_PKEY_assign_RSA(pkey.get(), rsa.get()) != 1) {
        ALOGE("Failed to assign rsa  parameters \n");
        return -1;
    }
    OWNERSHIP_TRANSFERRED(rsa);

    int len = i2d_PUBKEY(pkey.get(), NULL);
    if (len <= 0) {
        ALOGE("Len returned is < 0 len = %d", len);
        return -1;
    }

    std::unique_ptr<unsigned char[]> key(new unsigned char[len]);
    if (key.get() == NULL) {
        ALOGE("Could not allocate memory for public key data");
        return -1;
    }

    unsigned char* tmp = key.get();
    if (i2d_PUBKEY(pkey.get(), &tmp) != len) {
        ALOGE("Len 2 returned is < 0 len = %d", len);
        return -1;
    }
    *x509_data_length = len;
    *x509_data = key.release();

    return 0;
}

static int32_t qcom_km_ION_memalloc(struct qcom_km_ion_info_t *handle,
                                uint32_t size)
{
    int32_t ret = 0;
    int32_t iret = 0;
    int32_t fd = 0;
    unsigned char *v_addr;
    struct ion_allocation_data ion_alloc_data;
    int32_t ion_fd;
    int32_t rc;
    struct ion_fd_data ifd_data;
    struct ion_handle_data handle_data;

    /* open ION device for memory management
     * O_DSYNC -> uncached memory
    */
    if(handle == NULL){
      ALOGE("Error:: null handle received");
      return -1;
    }
    ion_fd  = open("/dev/ion", O_RDONLY | O_DSYNC);
    if (ion_fd < 0) {
       ALOGE("Error::Cannot open ION device");
       return -1;
    }
    handle->ion_sbuffer = NULL;
    handle->ifd_data_fd = 0;

    /* Size of allocation */
    ion_alloc_data.len = (size + 4095) & (~4095);

    /* 4K aligned */
    ion_alloc_data.align = 4096;

    /* memory is allocated from EBI heap */
   ion_alloc_data.ION_HEAP_MASK = ION_HEAP(ION_QSECOM_HEAP_ID);

    /* Set the memory to be uncached */
    ion_alloc_data.flags = 0;

    /* IOCTL call to ION for memory request */
    rc = ioctl(ion_fd, ION_IOC_ALLOC, &ion_alloc_data);
    if (rc) {
       ret = -1;
       goto alloc_fail;
    }

    if (ion_alloc_data.handle != NULL) {
       ifd_data.handle = ion_alloc_data.handle;
    } else {
       ret = -1;
       goto alloc_fail;
    }
    /* Call MAP ioctl to retrieve the ifd_data.fd file descriptor */
    rc = ioctl(ion_fd, ION_IOC_MAP, &ifd_data);
    if (rc) {
       ret = -1;
       goto ioctl_fail;
    }

    /* Make the ion mmap call */
    v_addr = (unsigned char *)mmap(NULL, ion_alloc_data.len,
                                    PROT_READ | PROT_WRITE,
                                    MAP_SHARED, ifd_data.fd, 0);
    if (v_addr == MAP_FAILED) {
       ALOGE("Error::ION MMAP failed");
       ret = -1;
       goto map_fail;
    }
    handle->ion_fd = ion_fd;
    handle->ifd_data_fd = ifd_data.fd;
    handle->ion_sbuffer = v_addr;
    handle->ion_alloc_handle.handle = ion_alloc_data.handle;
    handle->sbuf_len = size;
    return ret;

map_fail:
    if (handle->ion_sbuffer != NULL) {
        iret = munmap(handle->ion_sbuffer, ion_alloc_data.len);
        if (iret)
           ALOGE("Error::Failed to unmap memory for load image. ret = %d", ret);
    }

ioctl_fail:
    handle_data.handle = ion_alloc_data.handle;
    if (handle->ifd_data_fd)
        close(handle->ifd_data_fd);
    iret = ioctl(ion_fd, ION_IOC_FREE, &handle_data);
    if (iret) {
       ALOGE("Error::ION FREE ioctl returned error = %d",iret);
    }

alloc_fail:
    if (ion_fd > 0)
       close(ion_fd);
    return ret;
}

/** @brief: Deallocate ION memory
 *
 *
 */
static int32_t qcom_km_ion_dealloc(struct qcom_km_ion_info_t *handle)
{
    struct ion_handle_data handle_data;
    int32_t ret = 0;

    /* Deallocate the memory for the listener */
    ret = munmap(handle->ion_sbuffer, (handle->sbuf_len + 4095) & (~4095));
    if (ret) {
        ALOGE("Error::Unmapping ION Buffer failed with ret = %d", ret);
    }

    handle_data.handle = handle->ion_alloc_handle.handle;
    close(handle->ifd_data_fd);
    ret = ioctl(handle->ion_fd, ION_IOC_FREE, &handle_data);
    if (ret) {
        ALOGE("Error::ION Memory FREE ioctl failed with ret = %d", ret);
    }
    close(handle->ion_fd);
    return ret;
}

static int qcom_km_generate_keypair(const keymaster0_device_t* dev,
        const keymaster_keypair_t key_type, const void* key_params,
        uint8_t** keyBlob, size_t* keyBlobLength) {

    if (dev->context == NULL) {
        ALOGE("qcom_km_generate_keypair: Context == NULL");
        return -1;
    }

    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;
    }
    if (keyBlob == NULL || keyBlobLength == NULL) {
        ALOGE("output key blob or length == NULL");
        return -1;
    }
    keymaster_rsa_keygen_params_t* rsa_params = (keymaster_rsa_keygen_params_t*) key_params;

    keymaster_gen_keypair_cmd_t *send_cmd = NULL;
    keymaster_gen_keypair_resp_t  *resp = NULL;
    struct QSEECom_handle *handle = NULL;
    struct qcom_keymaster_handle *km_handle =(struct qcom_keymaster_handle *)dev->context;
    int ret = 0;

    handle = (struct QSEECom_handle *)(km_handle->qseecom);
    send_cmd = (keymaster_gen_keypair_cmd_t *)handle->ion_sbuffer;
    resp = (keymaster_gen_keypair_resp_t *)(handle->ion_sbuffer +
                               QSEECOM_ALIGN(sizeof(keymaster_gen_keypair_cmd_t)));
    send_cmd->cmd_id = KEYMASTER_GENERATE_KEYPAIR;
    send_cmd->key_type = key_type;
    send_cmd->rsa_params.modulus_size = rsa_params->modulus_size;
    send_cmd->rsa_params.public_exponent = rsa_params->public_exponent;
    resp->status = KEYMASTER_FAILURE;
    resp->key_blob_len =  sizeof(qcom_km_key_blob_t);

    ret = (*km_handle->QSEECom_set_bandwidth)(handle, true);
    if (ret < 0) {
        ALOGE("Generate key command failed (unable to enable clks) ret =%d", ret);
        return -1;
    }

    ret = (*km_handle->QSEECom_send_cmd)(handle, send_cmd,
                               QSEECOM_ALIGN(sizeof(keymaster_gen_keypair_cmd_t)), resp,
                               QSEECOM_ALIGN(sizeof(keymaster_gen_keypair_resp_t)));

    if((*km_handle->QSEECom_set_bandwidth)(handle, false))
        ALOGE("Import key command: (unable to disable clks)");

    if ( (ret < 0)  ||  (resp->status  < 0)) {
        ALOGE("Generate key command failed resp->status = %d ret =%d", resp->status, ret);
        return -1;
    } else {
        std::unique_ptr<unsigned char[]> keydata(new unsigned char[resp->key_blob_len]);
        if (keydata.get() == NULL) {
            ALOGE("could not allocate memory for key blob");
            return -1;
        }
        unsigned char* p = keydata.get();
        memcpy(p, (unsigned char *)(&resp->key_blob), resp->key_blob_len);
        *keyBlob = keydata.release();
        *keyBlobLength = resp->key_blob_len;
    }
    return 0;
}

static int qcom_km_import_keypair(const keymaster0_device_t* dev,
        const uint8_t* key, const size_t key_length,
        uint8_t** keyBlob, size_t* keyBlobLength)
{
    if (dev->context == NULL) {
        ALOGE("qcom_km_import_keypair: Context  == NULL");
        return -1;
    }

    if (key == NULL) {
        ALOGE("Input key == NULL");
        return -1;
    } else if (keyBlob == NULL || keyBlobLength == NULL) {
        ALOGE("Output key blob or length == NULL");
        return -1;
    }

    struct QSEECom_ion_fd_info  ion_fd_info;
    struct qcom_km_ion_info_t ihandle;
    int ret = 0;

    ihandle.ion_fd = 0;
    ihandle.ion_alloc_handle.handle = NULL;
    if (qcom_km_ION_memalloc(&ihandle, QSEECOM_ALIGN(key_length)) < 0) {
        ALOGE("ION allocation  failed");
        return -1;
    }
    memset(&ion_fd_info, 0, sizeof(struct QSEECom_ion_fd_info));

    /* Populate the send data structure */
    ion_fd_info.data[0].fd = ihandle.ifd_data_fd;
    ion_fd_info.data[0].cmd_buf_offset = sizeof(enum keymaster_cmd_t);


    struct QSEECom_handle *handle = NULL;
    keymaster_import_keypair_cmd_t *send_cmd = NULL;
    keymaster_import_keypair_resp_t  *resp = NULL;
    struct qcom_keymaster_handle *km_handle =(struct qcom_keymaster_handle *)dev->context;

    handle = (struct QSEECom_handle *)(km_handle->qseecom);
    send_cmd = (keymaster_import_keypair_cmd_t *)handle->ion_sbuffer;
    resp = (keymaster_import_keypair_resp_t *)(handle->ion_sbuffer +
                                        QSEECOM_ALIGN(sizeof(keymaster_import_keypair_cmd_t)));
    send_cmd->cmd_id = KEYMASTER_IMPORT_KEYPAIR;
    send_cmd->pkcs8_key = (uint32_t)ihandle.ion_sbuffer;

    memcpy((unsigned char *)ihandle.ion_sbuffer, key, key_length);

    send_cmd->pkcs8_key_len = key_length;
    resp->status = KEYMASTER_FAILURE;
    resp->key_blob_len =  sizeof(qcom_km_key_blob_t);

    ret = (*km_handle->QSEECom_set_bandwidth)(handle, true);
    if (ret < 0) {
        ALOGE("Import key command failed (unable to enable clks) ret =%d", ret);
        qcom_km_ion_dealloc(&ihandle);
        return -1;
    }
    ret = (*km_handle->QSEECom_send_modified_cmd)(handle, send_cmd,
                               QSEECOM_ALIGN(sizeof(*send_cmd)), resp,
                               QSEECOM_ALIGN(sizeof(*resp)), &ion_fd_info);

    if((*km_handle->QSEECom_set_bandwidth)(handle, false))
        ALOGE("Import key command: (unable to disable clks)");

    if ( (ret < 0)  ||  (resp->status  < 0)) {
        ALOGE("Import key command failed resp->status = %d ret =%d", resp->status, ret);
        qcom_km_ion_dealloc(&ihandle);
        return -1;
    } else {
        std::unique_ptr<unsigned char[]> keydata(new unsigned char[resp->key_blob_len]);
        if (keydata.get() == NULL) {
            ALOGE("could not allocate memory for key blob");
            return -1;
        }
        unsigned char* p = keydata.get();
        memcpy(p, (unsigned char *)(&resp->key_blob), resp->key_blob_len);
        *keyBlob = keydata.release();
        *keyBlobLength = resp->key_blob_len;

    }
    qcom_km_ion_dealloc(&ihandle);
    return 0;
}

static int qcom_km_sign_data(const keymaster0_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)
{
    if (dev->context == NULL) {
        ALOGE("qcom_km_sign_data: Context  == NULL");
        return -1;
    }
    if (dataLength > KM_KEY_SIZE_MAX) {
        ALOGE("Input data to be signed is too long %d bytes", dataLength);
        return -1;
    }
    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;
    }

    struct QSEECom_handle *handle = NULL;
    keymaster_sign_data_cmd_t *send_cmd = NULL;
    keymaster_sign_data_resp_t  *resp = NULL;
    struct QSEECom_ion_fd_info  ion_fd_info;
    struct qcom_km_ion_info_t ihandle;
    struct qcom_keymaster_handle *km_handle =(struct qcom_keymaster_handle *)dev->context;
    int ret = 0;

    handle = (struct QSEECom_handle *)(km_handle->qseecom);
    ihandle.ion_fd = 0;
    ihandle.ion_alloc_handle.handle = NULL;
    if (qcom_km_ION_memalloc(&ihandle, dataLength) < 0) {
        ALOGE("ION allocation  failed");
        return -1;
    }
    memset(&ion_fd_info, 0, sizeof(struct QSEECom_ion_fd_info));

    /* Populate the send data structure */
    ion_fd_info.data[0].fd = ihandle.ifd_data_fd;
    ion_fd_info.data[0].cmd_buf_offset = sizeof(enum keymaster_cmd_t) +
         sizeof(qcom_km_key_blob_t) + sizeof(keymaster_rsa_sign_params_t);

    send_cmd = (keymaster_sign_data_cmd_t *)handle->ion_sbuffer;
    resp = (keymaster_sign_data_resp_t *)(handle->ion_sbuffer +
                            QSEECOM_ALIGN(sizeof(keymaster_sign_data_cmd_t)));
    send_cmd->cmd_id = KEYMASTER_SIGN_DATA ;
    send_cmd->sign_param.digest_type = sign_params->digest_type;
    send_cmd->sign_param.padding_type = sign_params->padding_type;
    memcpy((unsigned char *)(&send_cmd->key_blob), keyBlob, keyBlobLength);
    memcpy((unsigned char *)ihandle.ion_sbuffer, data, dataLength);

    send_cmd->data = (uint32_t)ihandle.ion_sbuffer;
    send_cmd->dlen = dataLength;
    resp->sig_len = KM_KEY_SIZE_MAX;
    resp->status = KEYMASTER_FAILURE;

    ret = (*km_handle->QSEECom_set_bandwidth)(handle, true);
    if (ret < 0) {
        ALOGE("Sign data command failed (unable to enable clks) ret =%d", ret);
        qcom_km_ion_dealloc(&ihandle);
        return -1;
    }

    ret = (*km_handle->QSEECom_send_modified_cmd)(handle, send_cmd,
                               QSEECOM_ALIGN(sizeof(*send_cmd)), resp,
                               QSEECOM_ALIGN(sizeof(*resp)), &ion_fd_info);

    if((*km_handle->QSEECom_set_bandwidth)(handle, false))
        ALOGE("Sign data command: (unable to disable clks)");

    if ( (ret < 0)  ||  (resp->status  < 0)) {
        ALOGE("Sign data command failed resp->status = %d ret =%d", resp->status, ret);
        qcom_km_ion_dealloc(&ihandle);
        return -1;
    } else {
        std::unique_ptr<uint8_t> signedDataPtr(reinterpret_cast<uint8_t*>(malloc(resp->sig_len)));
        if (signedDataPtr.get() == NULL) {
            ALOGE("Sign data memory allocation failed");
            qcom_km_ion_dealloc(&ihandle);
            return -1;
        }
        unsigned char* p = signedDataPtr.get();
        memcpy(p, (unsigned char *)(&resp->signed_data), resp->sig_len);

        *signedDataLength = resp->sig_len;
        *signedData = signedDataPtr.release();
    }
    qcom_km_ion_dealloc(&ihandle);
    return 0;
}

static int qcom_km_verify_data(const keymaster0_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)
{
    if (dev->context == NULL) {
        ALOGE("qcom_km_verify_data: Context  == NULL");
        return -1;
    }

    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;
    }

    struct QSEECom_handle *handle = NULL;
    keymaster_verify_data_cmd_t *send_cmd = NULL;
    keymaster_verify_data_resp_t  *resp = NULL;

    struct QSEECom_ion_fd_info  ion_fd_info;
    struct qcom_km_ion_info_t ihandle;
    struct qcom_keymaster_handle *km_handle =(struct qcom_keymaster_handle *)dev->context;
    int ret = 0;

    handle = (struct QSEECom_handle *)(km_handle->qseecom);
    ihandle.ion_fd = 0;
    ihandle.ion_alloc_handle.handle = NULL;
    if (qcom_km_ION_memalloc(&ihandle, signedDataLength + signatureLength) <0) {
        ALOGE("ION allocation  failed");
        return -1;
    }
    memset(&ion_fd_info, 0, sizeof(struct QSEECom_ion_fd_info));

    /* Populate the send data structure */
    ion_fd_info.data[0].fd = ihandle.ifd_data_fd;
    ion_fd_info.data[0].cmd_buf_offset = sizeof(enum keymaster_cmd_t) +
        sizeof(qcom_km_key_blob_t ) + sizeof(keymaster_rsa_sign_params_t);

    send_cmd = (keymaster_verify_data_cmd_t *)handle->ion_sbuffer;
    resp = (keymaster_verify_data_resp_t *)((char *)handle->ion_sbuffer +
                               sizeof(keymaster_verify_data_cmd_t));
    send_cmd->cmd_id = KEYMASTER_VERIFY_DATA ;
    send_cmd->sign_param.digest_type = sign_params->digest_type;
    send_cmd->sign_param.padding_type = sign_params->padding_type;
    memcpy((unsigned char *)(&send_cmd->key_blob), keyBlob, keyBlobLength);

    send_cmd->signed_data = (uint32_t)ihandle.ion_sbuffer;
    send_cmd->signed_dlen = signedDataLength;
    memcpy((unsigned char *)ihandle.ion_sbuffer, signedData, signedDataLength);

    send_cmd->signature = signedDataLength;
    send_cmd->slen = signatureLength;
    memcpy(((unsigned char *)ihandle.ion_sbuffer + signedDataLength),
                                  signature, signatureLength);
    resp->status = KEYMASTER_FAILURE;

    ret = (*km_handle->QSEECom_set_bandwidth)(handle, true);
    if (ret < 0) {
        ALOGE("Verify data  command failed (unable to enable clks) ret =%d", ret);
        qcom_km_ion_dealloc(&ihandle);
        return -1;
    }

    ret = (*km_handle->QSEECom_send_modified_cmd)(handle, send_cmd,
                               QSEECOM_ALIGN(sizeof(*send_cmd)), resp,
                               QSEECOM_ALIGN(sizeof(*resp)), &ion_fd_info);

    if((*km_handle->QSEECom_set_bandwidth)(handle, false))
        ALOGE("Verify data  command: (unable to disable clks)");

    if ( (ret < 0)  ||  (resp->status  < 0)) {
        ALOGE("Verify data command failed resp->status = %d ret =%d", resp->status, ret);
        qcom_km_ion_dealloc(&ihandle);
        return -1;
    }
    qcom_km_ion_dealloc(&ihandle);
    return 0;
}

/* Close an opened OpenSSL instance */
static int qcom_km_close(hw_device_t *dev)
{
    keymaster0_device_t* km_dev = (keymaster0_device_t *)dev;
    struct qcom_keymaster_handle *km_handle =(struct qcom_keymaster_handle *)km_dev->context;

    if (km_handle->qseecom == NULL) {
        ALOGE("Context  == NULL");
        return -1;
    }
    (*km_handle->QSEECom_shutdown_app)((struct QSEECom_handle **)&km_handle->qseecom);
    free(km_dev->context);
    free(dev);
    return 0;
}

static int qcom_km_get_lib_sym(qcom_keymaster_handle_t* km_handle)
{
    km_handle->libhandle = dlopen("libQSEEComAPI.so", RTLD_NOW);
    if (  km_handle->libhandle  ) {
        *(void **)(&km_handle->QSEECom_start_app) =
                               dlsym(km_handle->libhandle,"QSEECom_start_app");
        if (km_handle->QSEECom_start_app == NULL) {
               ALOGE("dlsym: Error Loading QSEECom_start_app");
                   dlclose(km_handle->libhandle );
                   km_handle->libhandle  = NULL;
                   return -1;
            }
            *(void **)(&km_handle->QSEECom_shutdown_app) =
                               dlsym(km_handle->libhandle,"QSEECom_shutdown_app");
            if (km_handle->QSEECom_shutdown_app == NULL) {
                   ALOGE("dlsym: Error Loading QSEECom_shutdown_app");
                   dlclose(km_handle->libhandle );
                   km_handle->libhandle  = NULL;
                   return -1;
             }
            *(void **)(&km_handle->QSEECom_send_cmd) =
                               dlsym(km_handle->libhandle,"QSEECom_send_cmd");
            if (km_handle->QSEECom_send_cmd == NULL) {
                   ALOGE("dlsym: Error Loading QSEECom_send_cmd");
                   dlclose(km_handle->libhandle );
                   km_handle->libhandle  = NULL;
                   return -1;
             }
            *(void **)(&km_handle->QSEECom_send_modified_cmd) =
                               dlsym(km_handle->libhandle,"QSEECom_send_modified_cmd");
            if (km_handle->QSEECom_send_modified_cmd == NULL) {
                   ALOGE("dlsym: Error Loading QSEECom_send_modified_cmd");
                   dlclose(km_handle->libhandle );
                   km_handle->libhandle  = NULL;
                   return -1;
             }
            *(void **)(&km_handle->QSEECom_set_bandwidth) =
                               dlsym(km_handle->libhandle,"QSEECom_set_bandwidth");
            if (km_handle->QSEECom_set_bandwidth == NULL) {
                   ALOGE("dlsym: Error Loading QSEECom_set_bandwidth");
                   dlclose(km_handle->libhandle );
                   km_handle->libhandle  = NULL;
                   return -1;
             }

    } else {
        ALOGE("failed to load qseecom library");
        return -1;
    }
    return 0;
}

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

    km_handle = (qcom_keymaster_handle_t *)malloc(sizeof(qcom_keymaster_handle_t));
    if (km_handle == NULL) {
        ALOGE("Memalloc for keymaster handle failed");
        return -1;
    }
    km_handle->qseecom = NULL;
    km_handle->libhandle = NULL;
    ret = qcom_km_get_lib_sym(km_handle);
    if (ret) {
        free(km_handle);
        return -1;
    }
    Unique_keymaster_device_t dev(new keymaster0_device_t);
    if (dev.get() == NULL){
        free(km_handle);
        return -ENOMEM;
    }
    dev->context = (void *)km_handle;
    ret = (*km_handle->QSEECom_start_app)((struct QSEECom_handle **)&km_handle->qseecom,
                         "/vendor/firmware/keymaster", "keymaster", 4096*2);
    if (ret) {
        ALOGE("Loading keymaster app failed");
        free(km_handle);
        return -1;
    }
    dev->common.tag = HARDWARE_DEVICE_TAG;
    dev->common.version = 1;
    dev->common.module = (struct hw_module_t*) module;
    dev->common.close = qcom_km_close;
    dev->flags = KEYMASTER_BLOBS_ARE_STANDALONE;

    dev->generate_keypair = qcom_km_generate_keypair;
    dev->import_keypair = qcom_km_import_keypair;
    dev->get_keypair_public = qcom_km_get_keypair_public;
    dev->delete_keypair = NULL;
    dev->delete_all = NULL;
    dev->sign_data = qcom_km_sign_data;
    dev->verify_data = qcom_km_verify_data;

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

    return 0;
}

static struct hw_module_methods_t keystore_module_methods = {
    .open = qcom_km_open,
};

struct keystore_module HAL_MODULE_INFO_SYM
__attribute__ ((visibility ("default"))) = {
    .common = {
        .tag = HARDWARE_MODULE_TAG,
        .module_api_version = QCOM_KEYMASTER_API_VERSION,
        .hal_api_version = HARDWARE_HAL_API_VERSION,
        .id = KEYSTORE_HARDWARE_MODULE_ID,
        .name = "Keymaster QCOM HAL",
        .author = "The Android Open Source Project",
        .methods = &keystore_module_methods,
        .dso = 0,
        .reserved = {},
    },
};
