/* QTI Secure Execution Environment Communicator (QSEECOM) driver
 *
 * Copyright (c) 2012, 2015, 2017-2018 The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
 * only version 2 as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 */

/* Refer to Documentation/qseecom.txt for detailed usage instructions.
 */

#include "qseecom.h"

static int qtiapp_test(struct device *dev, void *input,
		void *output, int input_len, int option);
struct qseecom_props {
	const int function;
	bool libraries_inbuilt;
	bool logging_support_enabled;
};

const struct qseecom_props qseecom_props_ipq807x = {
	.function = (MUL | CRYPTO | AES_SEC_KEY | RSA_SEC_KEY),
	.libraries_inbuilt = false,
	.logging_support_enabled = true,
};

const struct qseecom_props qseecom_props_ipq6018 = {
	.function = (MUL | CRYPTO | AES_SEC_KEY | RSA_SEC_KEY),
	.libraries_inbuilt = false,
	.logging_support_enabled = true,
};

const struct qseecom_props qseecom_props_ipq5018 = {
	.function = (MUL | CRYPTO | RSA_QTIAPP | AES_QTIAPP | LOG_BITMASK | FUSE |
			MISC | FUSE_WRITE | TZ_CMD),
	.libraries_inbuilt = false,
	.logging_support_enabled = true,
};

static const struct of_device_id qseecom_of_table[] = {
	{	.compatible = "ipq807x-qseecom",
		.data = (void *) &qseecom_props_ipq807x,
	},
	{	.compatible = "ipq6018-qseecom",
		.data = (void *) &qseecom_props_ipq6018,
	},
	{	.compatible = "ipq5018-qseecom",
		.data = (void *) &qseecom_props_ipq5018,
	},
	{}
};
MODULE_DEVICE_TABLE(of, qseecom_of_table);

static int unload_app_libs(void)
{
	struct qseecom_unload_ireq req;
	struct qseecom_command_scm_resp resp;
	int ret = 0;
	uint32_t cmd_id = 0;
	uint32_t smc_id = 0;

	cmd_id = QSEE_UNLOAD_SERV_IMAGE_COMMAND;

	smc_id = QTI_SYSCALL_CREATE_SMC_ID(QTI_OWNER_QSEE_OS, QTI_SVC_APP_MGR,
					   QTI_CMD_UNLOAD_LIB);

	/* SCM_CALL to unload the app */
	ret = qti_scm_qseecom_unload(smc_id, cmd_id, &req, sizeof(uint32_t),
				     &resp, sizeof(resp));

	if (ret) {
		pr_err("scm_call to unload app libs failed, ret val = %d\n",
		      ret);
		return ret;
	}

	pr_info("App libs unloaded successfully\n");

	return 0;
}

static int qtidbg_register_qsee_log_buf(struct device *dev)
{
	uint64_t len = 0;
	int ret = 0;
	void *buf = NULL;
	struct qsee_reg_log_buf_req req;
	struct qseecom_command_scm_resp resp;
	dma_addr_t dma_log_buf = 0;

	len = QSEE_LOG_BUF_SIZE;
	buf = dma_alloc_coherent(dev, len, &dma_log_buf, GFP_KERNEL);
	if (buf == NULL) {
		pr_err("Failed to alloc memory for size %llu\n", len);
		return -ENOMEM;
	}
	g_qsee_log = (struct qtidbg_log_t *)buf;

	req.phy_addr = dma_log_buf;
	req.len = len;

	ret = qti_scm_register_log_buf(dev, &req, sizeof(req),
					  &resp, sizeof(resp));

	if (ret) {
		pr_err("SCM Call failed..SCM Call return value = %d\n", ret);
		dma_free_coherent(dev, len, (void *)g_qsee_log, dma_log_buf);
		return ret;
	}

	if (resp.result) {
		ret = resp.result;
		pr_err("Response status failure..return value = %d\n", ret);
		dma_free_coherent(dev, len, (void *)g_qsee_log, dma_log_buf);
		return ret;
	}

	return 0;
}

static ssize_t
show_qsee_app_log_buf(struct device *dev, struct device_attribute *attr,
		     char *buf)
{
	ssize_t count = 0;

	if (app_state) {
		if (g_qsee_log->log_pos.wrap != 0) {
			memcpy(buf, g_qsee_log->log_buf +
			      g_qsee_log->log_pos.offset, QSEE_LOG_BUF_SIZE -
			      g_qsee_log->log_pos.offset - 4);
			count = QSEE_LOG_BUF_SIZE -
				g_qsee_log->log_pos.offset - 4;
			memcpy(buf + count, g_qsee_log->log_buf,
			      g_qsee_log->log_pos.offset);
			count = count + g_qsee_log->log_pos.offset;
		} else {
			memcpy(buf, g_qsee_log->log_buf,
			      g_qsee_log->log_pos.offset);
			count = g_qsee_log->log_pos.offset;
		}
	} else {
		pr_err("load app and then view log..\n");
		return -EINVAL;
	}

	return count;
}

static ssize_t
generate_key_blob(struct device *dev, struct device_attribute *attr, char *buf)
{
	int rc = 0;
	struct qti_storage_service_gen_key_cmd_t *req_ptr = NULL;
	struct qti_storage_service_gen_key_resp_t *resp_ptr = NULL;
	size_t req_size = 0;
	size_t resp_size = 0;
	size_t dma_buf_size = 0;
	dma_addr_t dma_req_addr = 0;
	dma_addr_t dma_resp_addr = 0;

	key_blob = memset(key_blob, 0, KEY_BLOB_SIZE);
	key_blob_len = 0;

	dev = qdev;

	req_size = sizeof(struct qti_storage_service_gen_key_cmd_t);
	dma_buf_size = PAGE_SIZE * (1 << get_order(req_size));
	req_ptr = (struct qti_storage_service_gen_key_cmd_t *)
			dma_alloc_coherent(dev, dma_buf_size,
			&dma_req_addr, GFP_KERNEL);
	if (!req_ptr)
		return -ENOMEM;

	resp_size = sizeof(struct qti_storage_service_gen_key_resp_t);
	dma_buf_size = PAGE_SIZE * (1 << get_order(resp_size));
	resp_ptr = (struct qti_storage_service_gen_key_resp_t *)
			dma_alloc_coherent(dev, dma_buf_size,
			&dma_resp_addr, GFP_KERNEL);

	if (!resp_ptr) {
                dma_buf_size = PAGE_SIZE * (1 << get_order(req_size));
                dma_free_coherent(dev, dma_buf_size, req_ptr, dma_req_addr);
		return -ENOMEM;
        }

	req_ptr->key_blob.key_material = (u64)dma_key_blob;
	req_ptr->cmd_id = QTI_STOR_SVC_GENERATE_KEY;
	req_ptr->key_blob.key_material_len = KEY_BLOB_SIZE;

	rc = qti_scm_tls_hardening(dma_req_addr, req_size,
				   dma_resp_addr, resp_size,
				   CLIENT_CMD_CRYPTO_AES_64);
	if (rc) {
		pr_err("SCM Call failed..SCM Call return value = %d\n", rc);
		goto err_end;
	}

	if (resp_ptr->status) {
		rc = resp_ptr->status;
		pr_err("Response status failure..return value = %d\n", rc);
		goto err_end;
	}

	key_blob_len = resp_ptr->key_blob_size;
	memcpy(buf, key_blob, key_blob_len);

	goto end;

err_end:
	dma_buf_size = PAGE_SIZE * (1 << get_order(req_size));
	dma_free_coherent(dev, dma_buf_size, req_ptr, dma_req_addr);

	dma_buf_size = PAGE_SIZE * (1 << get_order(resp_size));
	dma_free_coherent(dev, dma_buf_size, resp_ptr, dma_resp_addr);
	return rc;

end:
	dma_buf_size = PAGE_SIZE * (1 << get_order(req_size));
	dma_free_coherent(dev, dma_buf_size, req_ptr, dma_req_addr);

	dma_buf_size = PAGE_SIZE * (1 << get_order(resp_size));
	dma_free_coherent(dev, dma_buf_size, resp_ptr, dma_resp_addr);

	return key_blob_len;
}

static ssize_t
store_key(struct device *dev, struct device_attribute *attr,
	 const char *buf, size_t count)
{
	key = memset(key, 0, KEY_SIZE);
	key_len = 0;

	if (count != KEY_SIZE) {
		pr_info("Invalid input\n");
		pr_info("Key length is %lu bytes\n", (unsigned long)count);
		pr_info("Key length must be %u bytes\n",(unsigned int)KEY_SIZE);
		return -EINVAL;
	}

	key_len = count;
	memcpy(key, buf, key_len);

	return count;
}

static ssize_t
import_key_blob(struct device *dev, struct device_attribute *attr, char *buf)
{
	int rc = 0;
	struct qti_storage_service_import_key_cmd_t *req_ptr = NULL;
	struct qti_storage_service_gen_key_resp_t *resp_ptr = NULL;
	size_t req_size = 0;
	size_t resp_size = 0;
	size_t dma_buf_size = 0;
	dma_addr_t dma_req_addr = 0;
	dma_addr_t dma_resp_addr = 0;

	key_blob = memset(key_blob, 0, KEY_BLOB_SIZE);
	key_blob_len = 0;

	if (key_len == 0) {
		pr_err("Please provide key to import key blob\n");
		return -EINVAL;
	}

	dev = qdev;

        req_size = sizeof(struct qti_storage_service_import_key_cmd_t);
        dma_buf_size = PAGE_SIZE * (1 << get_order(req_size));
        req_ptr = (struct qti_storage_service_import_key_cmd_t *)
                        dma_alloc_coherent(dev, dma_buf_size,
                        &dma_req_addr, GFP_KERNEL);
        if (!req_ptr)
                return -ENOMEM;

        resp_size = sizeof(struct qti_storage_service_gen_key_resp_t);
        dma_buf_size = PAGE_SIZE * (1 << get_order(resp_size));
        resp_ptr = (struct qti_storage_service_gen_key_resp_t *)
                        dma_alloc_coherent(dev, dma_buf_size,
                        &dma_resp_addr, GFP_KERNEL);

        if (!resp_ptr) {
                dma_buf_size = PAGE_SIZE * (1 << get_order(req_size));
                dma_free_coherent(dev, dma_buf_size, req_ptr, dma_req_addr);
                return -ENOMEM;
        }

	req_ptr->input_key = (u64)dma_key;
	req_ptr->key_blob.key_material = (u64)dma_key_blob;
	req_ptr->cmd_id = QTI_STOR_SVC_IMPORT_KEY;
	req_ptr->input_key_len = KEY_SIZE;
	req_ptr->key_blob.key_material_len = KEY_BLOB_SIZE;

	rc = qti_scm_tls_hardening(dma_req_addr, req_size,
				   dma_resp_addr, resp_size,
				   CLIENT_CMD_CRYPTO_AES_64);
	if (rc) {
		pr_err("SCM Call failed..SCM Call return value = %d\n", rc);
		goto err_end;
	}

	if (resp_ptr->status) {
		rc = resp_ptr->status;
		pr_err("Response status failure..return value = %d\n", rc);
		goto err_end;
	}

	key_blob_len = resp_ptr->key_blob_size;
	memcpy(buf, key_blob, key_blob_len);

	goto end;

err_end:
        dma_buf_size = PAGE_SIZE * (1 << get_order(req_size));
	dma_free_coherent(dev, dma_buf_size, req_ptr, dma_req_addr);

        dma_buf_size = PAGE_SIZE * (1 << get_order(resp_size));
	dma_free_coherent(dev, dma_buf_size, resp_ptr, dma_resp_addr);
	return rc;

end:
        dma_buf_size = PAGE_SIZE * (1 << get_order(req_size));
	dma_free_coherent(dev, dma_buf_size, req_ptr, dma_req_addr);

        dma_buf_size = PAGE_SIZE * (1 << get_order(resp_size));
	dma_free_coherent(dev, dma_buf_size, resp_ptr, dma_resp_addr);

	return key_blob_len;
}

static ssize_t
store_key_blob(struct device *dev, struct device_attribute *attr,
	      const char *buf, size_t count)
{
	key_blob = memset(key_blob, 0, KEY_BLOB_SIZE);
	key_blob_len = 0;

	if (count != KEY_BLOB_SIZE) {
		pr_info("Invalid input\n");
		pr_info("Key blob length is %lu bytes\n", (unsigned long)count);
		pr_info("Key blob length must be %u bytes\n", (unsigned int)KEY_BLOB_SIZE);
		return -EINVAL;
	}

	key_blob_len = count;
	memcpy(key_blob, buf, key_blob_len);

	return count;
}

static ssize_t
store_aes_mode(struct device *dev, struct device_attribute *attr,
               const char *buf, size_t count)
{
	unsigned long long val;

	if (kstrtoull(buf, 10, &val))
		return -EINVAL;

	mode = val;
	if (mode >= QTI_CRYPTO_SERVICE_AES_MODE_MAX) {
		pr_info("Invalid aes 256 mode: %llu\n", mode);
		return -EINVAL;
	}

	return count;
}

static ssize_t
store_aes_type(struct device *dev, struct device_attribute *attr,
               const char *buf, size_t count)
{
	unsigned long long val;

	if (kstrtoull(buf, 10, &val))
		return -EINVAL;

	type = val;
	if (!type || type >= QTI_CRYPTO_SERVICE_AES_TYPE_MAX) {
		pr_info("Invalid aes 256 type: %llu\n", type);
		return -EINVAL;
	}

	return count;
}

static ssize_t
store_decrypted_data(struct device *dev, struct device_attribute *attr,
			const char *buf, size_t count)
{
	unsealed_buf = memset(unsealed_buf, 0, MAX_PLAIN_DATA_SIZE);
	decrypted_len = count;

	if ((decrypted_len % AES_BLOCK_SIZE) ||
			decrypted_len > MAX_PLAIN_DATA_SIZE) {
		pr_info("Invalid input\n");
		pr_info("Plain data length is %lu bytes\n",
		       (unsigned long)decrypted_len);
		pr_info("Plain data length must be multiple of AES block size"
			"of 16 bytes and <= %u bytes\n",
			(unsigned int)MAX_PLAIN_DATA_SIZE);
		return -EINVAL;
	}

	if (!ivdata) {
		pr_info("could not allocate ivdata\n");
		return -EINVAL;
	}
	get_random_bytes((void *)ivdata, AES_BLOCK_SIZE);

	memcpy(unsealed_buf, buf, decrypted_len);
	return count;
}

static ssize_t
store_iv_data(struct device *dev, struct device_attribute *attr,
                        const char *buf, size_t count)
{
	if (!ivdata) {
		pr_info("could not allocate ivdata\n");
		return -EINVAL;
	}

	ivdata = memset(ivdata, 0, AES_BLOCK_SIZE);
	ivdata_len = count;

	if (ivdata_len != AES_BLOCK_SIZE) {
		pr_info("Invalid input\n");
		pr_info("IV data length is %lu bytes\n",
		       (unsigned long)ivdata_len);
		pr_info("IV data length must be equal to AES block size"
		        " (16) bytes\n");
		return -EINVAL;
	}

	memcpy(ivdata, buf, ivdata_len);
	return count;
}

static ssize_t
show_encrypted_data(struct device *dev, struct device_attribute *attr,
			char *buf)
{
	int rc = 0;
	struct qti_crypto_service_encrypt_data_cmd_t *req_ptr = NULL;
	uint64_t req_size = 0;
	size_t dma_buf_size = 0;
	uint64_t output_len = 0;
	dma_addr_t dma_req_addr = 0;

	sealed_buf = memset(sealed_buf, 0, MAX_ENCRYPTED_DATA_SIZE);
	output_len = decrypted_len;

	if (decrypted_len <= 0 || decrypted_len % AES_BLOCK_SIZE) {
		pr_err("Invalid input %lld\n", decrypted_len);
		pr_info("Input data length for encryption should be multiple"
			" of AES block size(16)\n");
		return -EINVAL;
	}

	dev = qdev;

	req_size = sizeof(struct qti_crypto_service_encrypt_data_cmd_t);
	dma_buf_size = PAGE_SIZE * (1 << get_order(req_size));
	req_ptr = (struct qti_crypto_service_encrypt_data_cmd_t *)
					dma_alloc_coherent(dev, dma_buf_size,
					&dma_req_addr, GFP_KERNEL);
	if (!req_ptr)
		return -ENOMEM;

	req_ptr->type = type;
	req_ptr->mode = mode;
	req_ptr->iv = (req_ptr->mode == 0 ? 0 : (u64)dma_iv_data);
	req_ptr->iv_len = AES_BLOCK_SIZE;
	req_ptr->plain_data = (u64)dma_unsealed_data;
	req_ptr->output_buffer = (u64)dma_sealed_data;
	req_ptr->plain_data_len = decrypted_len;
	req_ptr->output_len = output_len;

	/* dma_resp_addr and resp_size required are passed in req str itself */
	rc = qti_scm_aes(dma_req_addr, req_size, 0, 0,
			CLIENT_CMD_CRYPTO_AES_ENCRYPT);
	if (rc) {
		pr_err("Response status failure..return value = %d\n", rc);
		goto err_end;
	}

	if (mode == QTI_CRYPTO_SERVICE_AES_MODE_CBC && ivdata)
		print_hex_dump(KERN_INFO, "IV data(CBC): ", DUMP_PREFIX_NONE, 16, 1,
				ivdata, AES_BLOCK_SIZE, false);
	else
		pr_info("IV data(ECB): NULL\n");

	memcpy(buf, sealed_buf, req_ptr->output_len);
	encrypted_len = req_ptr->output_len;

goto end;

err_end:
	dma_free_coherent(dev, dma_buf_size, req_ptr, dma_req_addr);
	return rc;

end:
	dma_free_coherent(dev, dma_buf_size, req_ptr, dma_req_addr);
	return encrypted_len;
}

static ssize_t
store_encrypted_data(struct device *dev, struct device_attribute *attr,
			const char *buf, size_t count)
{
	sealed_buf = memset(sealed_buf, 0, MAX_ENCRYPTED_DATA_SIZE);
	encrypted_len = 0;

	if ((count % AES_BLOCK_SIZE) || count > MAX_PLAIN_DATA_SIZE) {
		pr_info("Invalid input\n");
		pr_info("Encrypted data length is %lu bytes\n",
			(unsigned long)count);
		pr_info("Encrypted data length must be multiple of AES block"
			" size 16  and <= %ubytes\n",
			(unsigned int)MAX_ENCRYPTED_DATA_SIZE);
		return -EINVAL;
	}

	encrypted_len = count;
	memcpy(sealed_buf, buf, count);

	return count;
}

static ssize_t
show_decrypted_data(struct device *dev, struct device_attribute *attr, char *buf)
{
	int rc = 0;
	struct qti_crypto_service_decrypt_data_cmd_t *req_ptr = NULL;
	uint64_t req_size = 0;
	size_t dma_buf_size = 0;
	uint64_t output_len = 0;
	dma_addr_t dma_req_addr = 0;

	unsealed_buf = memset(unsealed_buf, 0, MAX_PLAIN_DATA_SIZE);
	output_len = encrypted_len;

	if (encrypted_len <= 0 || encrypted_len % AES_BLOCK_SIZE) {
		pr_err("Invalid input %lld\n", encrypted_len);
		pr_info("Encrypted data length for decryption should be multiple"
			" of AES block size(16)\n");
		return -EINVAL;
	}

	dev = qdev;

	req_size = sizeof(struct qti_crypto_service_decrypt_data_cmd_t);
	dma_buf_size = PAGE_SIZE * (1 << get_order(req_size));
	req_ptr = (struct qti_crypto_service_decrypt_data_cmd_t *)
			dma_alloc_coherent(dev, dma_buf_size,
			&dma_req_addr, GFP_KERNEL);
	if (!req_ptr)
		return -ENOMEM;

	req_ptr->type = type;
	req_ptr->mode = mode;
	req_ptr->encrypted_data = (u64)dma_sealed_data;
	req_ptr->output_buffer = (u64)dma_unsealed_data;
	req_ptr->iv = (req_ptr->mode == 0 ? 0 : (u64)dma_iv_data);
	req_ptr->iv_len = AES_BLOCK_SIZE;
	req_ptr->encrypted_dlen = encrypted_len;
	req_ptr->output_len = output_len;

	/* dma_resp_addr and resp_size required are passed in req str itself */
	rc = qti_scm_aes(dma_req_addr, req_size, 0, 0,
			CLIENT_CMD_CRYPTO_AES_DECRYPT);
	if (rc) {
		pr_err("Response status failure..return value = %d\n", rc);
		goto err_end;
	}

	decrypted_len = req_ptr->output_len;
	memcpy(buf, unsealed_buf, decrypted_len);

goto end;

err_end:
	dma_free_coherent(dev, dma_buf_size, req_ptr, dma_req_addr);

	return rc;

end:
	dma_free_coherent(dev, dma_buf_size, req_ptr, dma_req_addr);

	return decrypted_len;
}

static ssize_t
store_unsealed_data(struct device *dev, struct device_attribute *attr,
		   const char *buf, size_t count)
{
	unsealed_buf = memset(unsealed_buf, 0, MAX_PLAIN_DATA_SIZE);
	unseal_len = 0;

	if (count == 0 || count > MAX_PLAIN_DATA_SIZE) {
		pr_info("Invalid input\n");
		pr_info("Plain data length is %lu bytes\n",
		       (unsigned long)count);
		pr_info("Plain data length must be > 0 bytes and <= %u bytes\n",
		       (unsigned int)MAX_PLAIN_DATA_SIZE);
		return -EINVAL;
	}

	unseal_len = count;
	memcpy(unsealed_buf, buf, unseal_len);

	return count;
}

static ssize_t
show_sealed_data(struct device *dev, struct device_attribute *attr, char *buf)
{
	int rc = 0;
	struct qti_storage_service_seal_data_cmd_t *req_ptr = NULL;
	struct qti_storage_service_seal_data_resp_t *resp_ptr = NULL;
	size_t req_size = 0;
	size_t resp_size = 0;
	size_t dma_buf_size = 0;
	size_t output_len = 0;
	dma_addr_t dma_req_addr = 0;
	dma_addr_t dma_resp_addr = 0;

	sealed_buf = memset(sealed_buf, 0, MAX_ENCRYPTED_DATA_SIZE);
	output_len = unseal_len + ENCRYPTED_DATA_HEADER;

	if (key_blob_len == 0 || unseal_len == 0) {
		pr_err("Invalid input\n");
		pr_info("Need keyblob and plain data for encryption\n");
		return -EINVAL;
	}

	dev = qdev;

	req_size = sizeof(struct qti_storage_service_seal_data_cmd_t);
	dma_buf_size = PAGE_SIZE * (1 << get_order(req_size));
	req_ptr = (struct qti_storage_service_seal_data_cmd_t *)
					dma_alloc_coherent(dev, dma_buf_size,
					&dma_req_addr, GFP_KERNEL);
	if (!req_ptr)
		return -ENOMEM;

	resp_size = sizeof(struct qti_storage_service_seal_data_resp_t);
	dma_buf_size = PAGE_SIZE * (1 << get_order(resp_size));
	resp_ptr = (struct qti_storage_service_seal_data_resp_t *)
					dma_alloc_coherent(dev, dma_buf_size,
					&dma_resp_addr, GFP_KERNEL);

	if (!resp_ptr) {
                dma_buf_size = PAGE_SIZE * (1 << get_order(req_size));
                dma_free_coherent(dev, dma_buf_size, req_ptr, dma_req_addr);
		return -ENOMEM;
        }

	req_ptr->key_blob.key_material = (u64)dma_key_blob;
	req_ptr->plain_data = (u64)dma_unsealed_data;
	req_ptr->output_buffer = (u64)dma_sealed_data;
	req_ptr->cmd_id = QTI_STOR_SVC_SEAL_DATA;
	req_ptr->key_blob.key_material_len = KEY_BLOB_SIZE;
	req_ptr->plain_data_len = unseal_len;
	req_ptr->output_len = output_len;

	rc = qti_scm_tls_hardening(dma_req_addr, req_size,
				   dma_resp_addr, resp_size,
				   CLIENT_CMD_CRYPTO_AES_64);
	if (rc) {
		pr_err("SCM Call failed..SCM Call return value = %d\n", rc);
		goto err_end;
	}

	if (resp_ptr->status != 0) {
		rc = resp_ptr->status;
		pr_err("Response status failure..return value = %d\n", rc);
		goto err_end;
	}

	seal_len = resp_ptr->sealed_data_len;
	memcpy(buf, sealed_buf, seal_len);

	goto end;

err_end:
	dma_buf_size = PAGE_SIZE * (1 << get_order(req_size));
	dma_free_coherent(dev, dma_buf_size, req_ptr, dma_req_addr);

	dma_buf_size = PAGE_SIZE * (1 << get_order(resp_size));
	dma_free_coherent(dev, dma_buf_size, resp_ptr, dma_resp_addr);
	return rc;

end:
	dma_buf_size = PAGE_SIZE * (1 << get_order(req_size));
	dma_free_coherent(dev, dma_buf_size, req_ptr, dma_req_addr);

	dma_buf_size = PAGE_SIZE * (1 << get_order(resp_size));
	dma_free_coherent(dev, dma_buf_size, resp_ptr, dma_resp_addr);

	return seal_len;
}

static ssize_t
store_sealed_data(struct device *dev, struct device_attribute *attr,
		 const char *buf, size_t count)
{
	sealed_buf = memset(sealed_buf, 0, MAX_ENCRYPTED_DATA_SIZE);
	seal_len = 0;

	if (count == 0 || count > MAX_ENCRYPTED_DATA_SIZE) {
		pr_info("Invalid input\n");
		pr_info("Encrypted data length is %lu bytes\n",
		       (unsigned long)count);
		pr_info("Encrypted data length must be > 0 bytes and <= %u bytes\n",
		       (unsigned int)MAX_ENCRYPTED_DATA_SIZE);
		return -EINVAL;
	}

	seal_len = count;
	memcpy(sealed_buf, buf, seal_len);

	return count;
}

static ssize_t
show_unsealed_data(struct device *dev, struct device_attribute *attr, char *buf)
{
	int rc = 0;
	struct qti_storage_service_unseal_data_cmd_t *req_ptr = NULL;
	struct qti_storage_service_unseal_data_resp_t *resp_ptr = NULL;
	size_t req_size = 0;
	size_t resp_size = 0;
	size_t output_len = 0;
	size_t dma_buf_size = 0;
	dma_addr_t dma_req_addr = 0;
	dma_addr_t dma_resp_addr = 0;

	unsealed_buf = memset(unsealed_buf, 0, MAX_PLAIN_DATA_SIZE);
	output_len = seal_len - ENCRYPTED_DATA_HEADER;

	if (key_blob_len == 0 || seal_len == 0) {
		pr_err("Invalid input\n");
		pr_info("Need key and sealed data for decryption\n");
		return -EINVAL;
	}

	dev = qdev;

	req_size = sizeof(struct qti_storage_service_unseal_data_cmd_t);
	dma_buf_size = PAGE_SIZE * (1 << get_order(req_size));
	req_ptr = (struct qti_storage_service_unseal_data_cmd_t *)
					dma_alloc_coherent(dev, dma_buf_size,
					&dma_req_addr, GFP_KERNEL);
	if (!req_ptr)
		return -ENOMEM;

	resp_size = sizeof(struct qti_storage_service_unseal_data_resp_t);
	dma_buf_size = PAGE_SIZE * (1 << get_order(resp_size));
	resp_ptr = (struct qti_storage_service_unseal_data_resp_t *)
					dma_alloc_coherent(dev, dma_buf_size,
					&dma_resp_addr, GFP_KERNEL);
	if (!resp_ptr) {
                dma_buf_size = PAGE_SIZE * (1 << get_order(req_size));
                dma_free_coherent(dev, dma_buf_size, req_ptr, dma_req_addr);
		return -ENOMEM;
        }

	req_ptr->key_blob.key_material = (u64)dma_key_blob;
	req_ptr->sealed_data = (u64)dma_sealed_data;
	req_ptr->output_buffer = (u64)dma_unsealed_data;
	req_ptr->cmd_id = QTI_STOR_SVC_UNSEAL_DATA;
	req_ptr->key_blob.key_material_len = KEY_BLOB_SIZE;
	req_ptr->sealed_dlen = seal_len;
	req_ptr->output_len = output_len;

	rc = qti_scm_tls_hardening(dma_req_addr, req_size,
				   dma_resp_addr, resp_size,
				   CLIENT_CMD_CRYPTO_AES_64);
	if (rc) {
		pr_err("SCM Call failed..SCM Call return value = %d\n", rc);
		goto err_end;
	}

	if (resp_ptr->status != 0) {
		rc = resp_ptr->status;
		pr_err("Response status failure..return value = %d\n", rc);
		goto err_end;
	}

	unseal_len = resp_ptr->unsealed_data_len;
	memcpy(buf, unsealed_buf, unseal_len);

	goto end;

err_end:
	dma_buf_size = PAGE_SIZE * (1 << get_order(req_size));
	dma_free_coherent(dev, dma_buf_size, req_ptr, dma_req_addr);

	dma_buf_size = PAGE_SIZE * (1 << get_order(resp_size));
	dma_free_coherent(dev, dma_buf_size, resp_ptr, dma_resp_addr);

	return rc;

end:
	dma_buf_size = PAGE_SIZE * (1 << get_order(req_size));
	dma_free_coherent(dev, dma_buf_size, req_ptr, dma_req_addr);

	dma_buf_size = PAGE_SIZE * (1 << get_order(resp_size));
	dma_free_coherent(dev, dma_buf_size, resp_ptr, dma_resp_addr);

	return unseal_len;
}

static ssize_t
generate_rsa_key_blob(struct device *dev, struct device_attribute *attr,
		     char *buf)
{
	int rc = 0;
	struct qti_storage_service_rsa_gen_key_cmd_t *req_ptr = NULL;
	struct qti_storage_service_rsa_gen_key_resp_t *resp_ptr = NULL;
	size_t req_size = 0;
	size_t resp_size = 0;
	size_t dma_buf_size = 0;
	dma_addr_t dma_req_addr = 0;
	dma_addr_t dma_resp_addr = 0;

	rsa_key_blob = memset(rsa_key_blob, 0, RSA_KEY_BLOB_SIZE);
	rsa_key_blob_len = 0;

	dev = qdev;

	req_size = sizeof(struct qti_storage_service_rsa_gen_key_cmd_t);
	dma_buf_size = PAGE_SIZE * (1 << get_order(req_size));
	req_ptr = (struct qti_storage_service_rsa_gen_key_cmd_t *)
					dma_alloc_coherent(dev, dma_buf_size,
					&dma_req_addr, GFP_KERNEL);
	if (!req_ptr)
		return -ENOMEM;

	resp_size = sizeof(struct qti_storage_service_rsa_gen_key_resp_t);
	dma_buf_size = PAGE_SIZE * (1 << get_order(resp_size));
	resp_ptr = (struct qti_storage_service_rsa_gen_key_resp_t *)
					dma_alloc_coherent(dev, dma_buf_size,
					&dma_resp_addr, GFP_KERNEL);
	if (!resp_ptr) {
                dma_buf_size = PAGE_SIZE * (1 << get_order(req_size));
                dma_free_coherent(dev, dma_buf_size, req_ptr, dma_req_addr);
		return -ENOMEM;
        }

	req_ptr->key_blob.key_material = (u64)dma_rsa_key_blob;
	req_ptr->cmd_id = QTI_STOR_SVC_RSA_GENERATE_KEY;
	req_ptr->rsa_params.modulus_size = RSA_MODULUS_LEN;
	req_ptr->rsa_params.public_exponent = RSA_PUBLIC_EXPONENT;
	req_ptr->rsa_params.pad_algo =
			QTI_STOR_SVC_RSA_DIGEST_PAD_PKCS115_SHA2_256;
	req_ptr->key_blob.key_material_len = RSA_KEY_BLOB_SIZE;

	rc = qti_scm_tls_hardening(dma_req_addr, req_size,
				   dma_resp_addr, resp_size,
				   CLIENT_CMD_CRYPTO_RSA_64);
	if (rc) {
		pr_err("SCM call failed..SCM Call return value = %d\n", rc);
		goto err_end;
	}

	if (resp_ptr->status) {
		rc = resp_ptr->status;
		pr_err("Response status failure..return value = %d\n", rc);
		goto err_end;
	}

	rsa_key_blob_len = resp_ptr->key_blob_size;
	memcpy(buf, rsa_key_blob, rsa_key_blob_len);

	goto end;

err_end:
	dma_buf_size = PAGE_SIZE * (1 << get_order(req_size));
	dma_free_coherent(dev, dma_buf_size, req_ptr, dma_req_addr);

	dma_buf_size = PAGE_SIZE * (1 << get_order(resp_size));
	dma_free_coherent(dev, dma_buf_size, resp_ptr, dma_resp_addr);

	return rc;

end:
	dma_buf_size = PAGE_SIZE * (1 << get_order(req_size));
	dma_free_coherent(dev, dma_buf_size, req_ptr, dma_req_addr);

	dma_buf_size = PAGE_SIZE * (1 << get_order(resp_size));
	dma_free_coherent(dev, dma_buf_size, resp_ptr, dma_resp_addr);

	return rsa_key_blob_len;
}

static ssize_t
store_rsa_key(struct device *dev, struct device_attribute *attr,
	     const char *buf, size_t count)
{
	int idx = 0;
	int ret = 0;
	int i = 0;
	int j = 0;
	char hex_len[RSA_PARAM_LEN];

	memset(rsa_import_modulus, 0, RSA_KEY_SIZE_MAX);
	rsa_import_modulus_len = 0;
	memset(rsa_import_public_exponent, 0, RSA_PUB_EXP_SIZE_MAX);
	rsa_import_public_exponent_len = 0;
	memset(rsa_import_pvt_exponent, 0, RSA_KEY_SIZE_MAX);
	rsa_import_pvt_exponent_len = 0;

	if (count != RSA_KEY_MATERIAL_SIZE) {
		pr_info("Invalid input\n");
		pr_info("Key material length is %lu bytes\n",
		       (unsigned long)count);
		pr_info("Key material length must be %u bytes\n",
		       (unsigned int)RSA_KEY_MATERIAL_SIZE);
		return -EINVAL;
	}

	memcpy(rsa_import_modulus, buf, RSA_KEY_SIZE_MAX);
	idx += RSA_KEY_SIZE_MAX;
	memset(hex_len, 0, RSA_PARAM_LEN);
	for (i = idx, j = 0; i < idx + 2; i++, j++)
		snprintf(hex_len + (j * 2), 3, "%02X", buf[i]);
	ret = kstrtoul(hex_len, 16, (unsigned long *)&rsa_import_modulus_len);
	if (ret) {
		pr_info("Cannot read modulus size from input buffer..\n");
		return -EINVAL;
	}
	idx += 2;

	memcpy(rsa_import_public_exponent, buf + idx, RSA_PUB_EXP_SIZE_MAX);
	idx += RSA_PUB_EXP_SIZE_MAX;
	memset(hex_len, 0, RSA_PARAM_LEN);
	for (i = idx, j = 0; i < idx + 1; i++, j++)
		snprintf(hex_len + (j * 2), 3, "%02X", buf[i]);
	ret = kstrtoul(hex_len, 16,
		      (unsigned long *)&rsa_import_public_exponent_len);
	if (ret) {
		pr_info("Cannot read pub exp size from input buffer..\n");
		return -EINVAL;
	}
	idx += 1;

	memcpy(rsa_import_pvt_exponent, buf + idx, RSA_KEY_SIZE_MAX);
	idx += RSA_KEY_SIZE_MAX;
	memset(hex_len, 0, RSA_PARAM_LEN);
	for (i = idx, j = 0; i < idx + 2; i++, j++)
		snprintf(hex_len + (j * 2), 3, "%02X", buf[i]);
	ret = kstrtoul(hex_len, 16,
		      (unsigned long *)&rsa_import_pvt_exponent_len);
	if (ret) {
		pr_info("Cannot read pvt exp size from input buffer..\n");
		return -EINVAL;
	}
	idx += 2;

	return count;
}

static ssize_t
import_rsa_key_blob(struct device *dev, struct device_attribute *attr,
		   char *buf)
{
	int rc = 0;
	size_t req_size = 0;
	size_t resp_size = 0;
	size_t dma_buf_size = 0;
	dma_addr_t dma_req_addr = 0;
	dma_addr_t dma_resp_addr = 0;

	struct qti_storage_service_rsa_import_key_cmd_t *req_ptr = NULL;
	struct qti_storage_service_rsa_import_key_resp_t *resp_ptr = NULL;

	memset(rsa_key_blob, 0, RSA_KEY_BLOB_SIZE);
	rsa_key_blob_len = 0;

	if (rsa_import_pvt_exponent_len == 0 ||
	   rsa_import_public_exponent_len == 0 || rsa_import_modulus_len == 0) {
		pr_err("Please provide key to import key blob\n");
		return -EINVAL;
	}

	if (rsa_import_pvt_exponent_len > RSA_KEY_SIZE_MAX ||
	   rsa_import_public_exponent_len > RSA_PUB_EXP_SIZE_MAX ||
	   rsa_import_modulus_len > RSA_KEY_SIZE_MAX) {
		pr_info("Invalid key\n");
		pr_info("Both pvt and pub exponent len less than 512 bytes\n");
		pr_info("Modulus len should be less than 4096 bytes\n");
		return -EINVAL;
	}

	dev = qdev;

	req_size = sizeof(struct qti_storage_service_rsa_import_key_cmd_t);
	dma_buf_size = PAGE_SIZE * (1 << get_order(req_size));
	req_ptr = (struct qti_storage_service_rsa_import_key_cmd_t *)
					dma_alloc_coherent(dev, dma_buf_size,
					&dma_req_addr, GFP_KERNEL);
	if (!req_ptr)
		return -ENOMEM;

	resp_size = sizeof(struct qti_storage_service_rsa_import_key_resp_t);
	dma_buf_size = PAGE_SIZE * (1 << get_order(resp_size));
	resp_ptr = (struct qti_storage_service_rsa_import_key_resp_t *)
					dma_alloc_coherent(dev, dma_buf_size,
					&dma_resp_addr, GFP_KERNEL);
	if (!resp_ptr) {
                dma_buf_size = PAGE_SIZE * (1 << get_order(req_size));
                dma_free_coherent(dev, dma_buf_size, req_ptr, dma_req_addr);
		return -ENOMEM;
        }

	req_ptr->key_blob.key_material = (u64)dma_rsa_key_blob;
	req_ptr->cmd_id = QTI_STOR_SVC_RSA_IMPORT_KEY;
	memcpy(req_ptr->modulus, rsa_import_modulus, rsa_import_modulus_len);
	req_ptr->modulus_len = rsa_import_modulus_len;
	memcpy(req_ptr->public_exponent, rsa_import_public_exponent,
	      rsa_import_public_exponent_len);
	req_ptr->public_exponent_len = rsa_import_public_exponent_len;
	req_ptr->digest_pad_type = QTI_STOR_SVC_RSA_DIGEST_PAD_PKCS115_SHA2_256;
	memcpy(req_ptr->pvt_exponent, rsa_import_pvt_exponent,
	      rsa_import_pvt_exponent_len);
	req_ptr->pvt_exponent_len = rsa_import_pvt_exponent_len;
	req_ptr->key_blob.key_material_len = RSA_KEY_BLOB_SIZE;

	rc = qti_scm_tls_hardening(dma_req_addr, req_size,
				   dma_resp_addr, resp_size,
				   CLIENT_CMD_CRYPTO_RSA_64);
	if (rc) {
		pr_err("SCM Call failed..SCM Call return value = %d\n", rc);
		goto err_end;
	}


	if (resp_ptr->status) {
		rc = resp_ptr->status;
		pr_err("Response status failure..return value = %d\n", rc);
		goto err_end;
	}

	rsa_key_blob_len = RSA_KEY_BLOB_SIZE;
	memcpy(buf, rsa_key_blob, rsa_key_blob_len);

	goto end;

err_end:
	dma_buf_size = PAGE_SIZE * (1 << get_order(req_size));
	dma_free_coherent(dev, dma_buf_size, req_ptr, dma_req_addr);

	dma_buf_size = PAGE_SIZE * (1 << get_order(resp_size));
	dma_free_coherent(dev, dma_buf_size, resp_ptr, dma_resp_addr);

	return rc;

end:
	dma_buf_size = PAGE_SIZE * (1 << get_order(req_size));
	dma_free_coherent(dev, dma_buf_size, req_ptr, dma_req_addr);

	dma_buf_size = PAGE_SIZE * (1 << get_order(resp_size));
	dma_free_coherent(dev, dma_buf_size, resp_ptr, dma_resp_addr);

	return rsa_key_blob_len;
}

static ssize_t
store_rsa_key_blob(struct device *dev, struct device_attribute *attr,
		  const char *buf, size_t count)
{
	memset(rsa_key_blob, 0, RSA_KEY_BLOB_SIZE);
	rsa_key_blob_len = 0;

	if (count != RSA_KEY_BLOB_SIZE) {
		pr_info("Invalid input\n");
		pr_info("Key blob length is %lu bytes\n", (unsigned long)count);
		pr_info("Key blob length must be %u bytes\n",
		       (unsigned int)RSA_KEY_BLOB_SIZE);
		return -EINVAL;
	}

	rsa_key_blob_len = count;
	memcpy(rsa_key_blob, buf, rsa_key_blob_len);

	return count;
}

static ssize_t
store_rsa_plain_data(struct device *dev, struct device_attribute *attr,
		       const char *buf, size_t count)
{
	rsa_plain_data_buf = memset(rsa_plain_data_buf, 0,
				   MAX_RSA_PLAIN_DATA_SIZE);
	rsa_plain_data_len = 0;

	if (count == 0 || count > MAX_RSA_PLAIN_DATA_SIZE) {
		pr_info("Invalid input\n");
		pr_info("Plain data length is %lu bytes\n",
		       (unsigned long)count);
		pr_info("Plain data length must be > 0 bytes and <= %u bytes\n",
		       (unsigned int)MAX_RSA_PLAIN_DATA_SIZE);
		return -EINVAL;
	}

	rsa_plain_data_len = count;
	memcpy(rsa_plain_data_buf, buf, rsa_plain_data_len);

	return count;
}

static ssize_t
show_rsa_signed_data(struct device *dev, struct device_attribute *attr,
		    char *buf)
{
	int rc = 0;
	struct qti_storage_service_rsa_sign_data_cmd_t *req_ptr = NULL;
	struct qti_storage_service_rsa_sign_data_resp_t *resp_ptr = NULL;
	size_t req_size = 0;
	size_t resp_size = 0;
	size_t dma_buf_size = 0;
	dma_addr_t dma_req_addr = 0;
	dma_addr_t dma_resp_addr = 0;

	memset(rsa_sign_data_buf, 0, MAX_RSA_SIGN_DATA_SIZE);
	rsa_sign_data_len = 0;

	if (rsa_key_blob_len == 0 || rsa_plain_data_len == 0) {
		pr_err("Invalid input\n");
		pr_info("Need key blob and plain data for RSA Signing\n");
		return -EINVAL;
	}

	dev = qdev;

	req_size = sizeof(struct qti_storage_service_rsa_sign_data_cmd_t);
	dma_buf_size = PAGE_SIZE * (1 << get_order(req_size));
	req_ptr = (struct qti_storage_service_rsa_sign_data_cmd_t *)
					dma_alloc_coherent(dev, dma_buf_size,
					&dma_req_addr, GFP_KERNEL);
	if (!req_ptr)
		return -ENOMEM;

	resp_size = sizeof(struct qti_storage_service_rsa_sign_data_resp_t);
	dma_buf_size = PAGE_SIZE * (1 << get_order(resp_size));
	resp_ptr = (struct qti_storage_service_rsa_sign_data_resp_t *)
					dma_alloc_coherent(dev, dma_buf_size,
					&dma_resp_addr, GFP_KERNEL);
	if (!resp_ptr) {
                dma_buf_size = PAGE_SIZE * (1 << get_order(req_size));
                dma_free_coherent(dev, dma_buf_size, req_ptr, dma_req_addr);
		return -ENOMEM;
        }

	req_ptr->key_blob.key_material = (u64)dma_rsa_key_blob;
	req_ptr->plain_data = (u64)dma_rsa_plain_data_buf;
	req_ptr->output_buffer = (u64)dma_rsa_sign_data_buf;
	req_ptr->cmd_id = QTI_STOR_SVC_RSA_SIGN_DATA;
	req_ptr->key_blob.key_material_len = RSA_KEY_BLOB_SIZE;
	req_ptr->plain_data_len = rsa_plain_data_len;
	req_ptr->output_len = MAX_RSA_SIGN_DATA_SIZE;

	rc = qti_scm_tls_hardening(dma_req_addr, req_size,
				   dma_resp_addr, resp_size,
				   CLIENT_CMD_CRYPTO_RSA_64);
	if (rc) {
		pr_err("SCM Call failed..SCM Call return value = %d\n", rc);
		goto err_end;
	}

	if (resp_ptr->status != 0) {
		rc = resp_ptr->status;
		pr_err("Response status failure..return value = %d\n", rc);
		goto err_end;
	}

	rsa_sign_data_len = resp_ptr->sealed_data_len;
	memcpy(buf, rsa_sign_data_buf, rsa_sign_data_len);

	goto end;

err_end:
	dma_buf_size = PAGE_SIZE * (1 << get_order(req_size));
	dma_free_coherent(dev, dma_buf_size, req_ptr, dma_req_addr);

	dma_buf_size = PAGE_SIZE * (1 << get_order(resp_size));
	dma_free_coherent(dev, dma_buf_size, resp_ptr, dma_resp_addr);

	return rc;

end:
	dma_buf_size = PAGE_SIZE * (1 << get_order(req_size));
	dma_free_coherent(dev, dma_buf_size, req_ptr, dma_req_addr);

	dma_buf_size = PAGE_SIZE * (1 << get_order(resp_size));
	dma_free_coherent(dev, dma_buf_size, resp_ptr, dma_resp_addr);

	return rsa_sign_data_len;
}

static ssize_t
store_rsa_signed_data(struct device *dev, struct device_attribute *attr,
		 const char *buf, size_t count)
{
	rsa_sign_data_buf = memset(rsa_sign_data_buf, 0,
				  MAX_RSA_SIGN_DATA_SIZE);
	rsa_sign_data_len = 0;

	if (count == 0 || count > MAX_RSA_SIGN_DATA_SIZE) {
		pr_info("Invalid input\n");
		pr_info("Signed data length is %lu\n", (unsigned long)count);
		pr_info("Signed data length must be > 0 bytes and <= %u bytes\n",
		       (unsigned int)MAX_RSA_SIGN_DATA_SIZE);
		return -EINVAL;
	}

	rsa_sign_data_len = count;
	memcpy(rsa_sign_data_buf, buf, rsa_sign_data_len);

	return count;
}

static ssize_t
verify_rsa_signed_data(struct device *dev, struct device_attribute *attr,
		      char *buf)
{
	int rc = 0;
	struct qti_storage_service_rsa_verify_data_cmd_t *req_ptr = NULL;
	struct qti_storage_service_rsa_verify_data_resp_t *resp_ptr = NULL;
	size_t req_size = 0;
	size_t resp_size = 0;
	size_t dma_buf_size = 0;
	dma_addr_t dma_req_addr = 0;
	dma_addr_t dma_resp_addr = 0;
	const char *message = NULL;
	int message_len = 0;

	if (rsa_key_blob_len == 0 || rsa_sign_data_len == 0
	   || rsa_plain_data_len == 0) {
		pr_err("Invalid input\n");
		pr_info("Need key blob, signed data and plain data for RSA Verification\n");
		return -EINVAL;
	}

	dev = qdev;

	req_size = sizeof(struct qti_storage_service_rsa_verify_data_cmd_t);
	dma_buf_size = PAGE_SIZE * (1 << get_order(req_size));
	req_ptr = (struct qti_storage_service_rsa_verify_data_cmd_t *)
					dma_alloc_coherent(dev, dma_buf_size,
					&dma_req_addr, GFP_KERNEL);
	if (!req_ptr)
		return -ENOMEM;

	resp_size = sizeof(struct qti_storage_service_rsa_verify_data_resp_t);
	dma_buf_size = PAGE_SIZE * (1 << get_order(resp_size));
	resp_ptr = (struct qti_storage_service_rsa_verify_data_resp_t *)
					dma_alloc_coherent(dev, dma_buf_size,
					&dma_resp_addr, GFP_KERNEL);
	if (!resp_ptr) {
                dma_buf_size = PAGE_SIZE * (1 << get_order(req_size));
                dma_free_coherent(dev, dma_buf_size, req_ptr, dma_req_addr);
		return -ENOMEM;
        }

	req_ptr->key_blob.key_material = (u64)dma_rsa_key_blob;
	req_ptr->signed_data = (u64)dma_rsa_sign_data_buf;
	req_ptr->data = (u64)dma_rsa_plain_data_buf;
	req_ptr->cmd_id = QTI_STOR_SVC_RSA_VERIFY_SIGNATURE;
	req_ptr->key_blob.key_material_len = rsa_key_blob_len;
	req_ptr->signed_dlen = rsa_sign_data_len;
	req_ptr->data_len = rsa_plain_data_len;

	rc = qti_scm_tls_hardening(dma_req_addr, req_size,
				   dma_resp_addr, resp_size,
				   CLIENT_CMD_CRYPTO_RSA_64);
	if (rc) {
		pr_err("SCM Call failed..SCM Call return value = %d\n", rc);
		goto err_end;
	}

	if (resp_ptr->status != 0) {
		rc = resp_ptr->status;
		pr_err("Response status failure..return value = %d\n", rc);
		message = "RSA Verification Failed\0\n";
		message_len = strlen(message) + 1;
		memcpy(buf, message, message_len);
		goto err_end;
	} else {
		message = "RSA Verification Successful\0\n";
		message_len = strlen(message) + 1;
		memcpy(buf, message, message_len);
	}

	goto end;

err_end:
	dma_buf_size = PAGE_SIZE * (1 << get_order(req_size));
	dma_free_coherent(dev, dma_buf_size, req_ptr, dma_req_addr);

	dma_buf_size = PAGE_SIZE * (1 << get_order(resp_size));
	dma_free_coherent(dev, dma_buf_size, resp_ptr, dma_resp_addr);

	return rc;

end:
	dma_buf_size = PAGE_SIZE * (1 << get_order(req_size));
	dma_free_coherent(dev, dma_buf_size, req_ptr, dma_req_addr);

	dma_buf_size = PAGE_SIZE * (1 << get_order(resp_size));
	dma_free_coherent(dev, dma_buf_size, resp_ptr, dma_resp_addr);

	return message_len;
}

static ssize_t
show_aes_encrypted_data_qtiapp(struct device *dev,
		struct device_attribute *attr, char *buf)
{
	int rc = 0;
	struct qti_crypto_service_encrypt_data_cmd_t *req_ptr = NULL;
	uint64_t req_size = 0;
	size_t dma_buf_size = 0;
	uint64_t output_len = 0;
	dma_addr_t dma_req_addr = 0;

	aes_sealed_buf = memset(aes_sealed_buf, 0, MAX_ENCRYPTED_DATA_SIZE);
	output_len = aes_decrypted_len;

	if (aes_decrypted_len <= 0 || aes_decrypted_len % AES_BLOCK_SIZE) {
		pr_err("Invalid input %lld\n", aes_decrypted_len);
		pr_info("Input data length for encryption should be multiple"
			"of AES block size(16)\n");
		return -EINVAL;
	}
	if (!aes_type || aes_type >= QTI_CRYPTO_SERVICE_AES_TYPE_MAX) {
		pr_info(" aes type needed for encryption\n");
		return -EINVAL;
	}

	dev = qdev;

	req_size = sizeof(struct qti_crypto_service_encrypt_data_cmd_t);
	dma_buf_size = PAGE_SIZE * (1 << get_order(req_size));
	req_ptr = (struct qti_crypto_service_encrypt_data_cmd_t *)
					dma_alloc_coherent(dev, dma_buf_size,
					&dma_req_addr, GFP_KERNEL);
	if (!req_ptr)
		return -ENOMEM;

	req_ptr->type = aes_type;
	req_ptr->mode = aes_mode;
	req_ptr->iv = (req_ptr->mode == 0 ? 0 : (u64)dma_aes_ivdata);
	req_ptr->iv_len = AES_BLOCK_SIZE;
	req_ptr->plain_data = (u64)dma_aes_unsealed_buf;
	req_ptr->output_buffer = (u64)dma_aes_sealed_buf;
	req_ptr->plain_data_len = aes_decrypted_len;
	req_ptr->output_len = output_len;

	rc = qtiapp_test(dev, (uint8_t *)dma_req_addr, NULL, req_size,
						QTI_APP_AES_ENCRYPT_ID);
	if (rc) {
		pr_err("Response status failure..return value = %d\n", rc);
		goto err_end;
	}

	if (aes_mode == QTI_CRYPTO_SERVICE_AES_MODE_CBC && aes_ivdata)
		print_hex_dump(KERN_INFO, "IV data(CBC): ", DUMP_PREFIX_NONE, 16, 1,
				aes_ivdata, AES_BLOCK_SIZE, false);
	else
		pr_info("IV data(ECB): NULL\n");

	memcpy(buf, aes_sealed_buf, req_ptr->output_len);
	aes_encrypted_len = req_ptr->output_len;

goto end;

err_end:
	dma_buf_size = PAGE_SIZE * (1 << get_order(req_size));
	dma_free_coherent(dev, dma_buf_size, req_ptr, dma_req_addr);

	return rc;

end:
	dma_buf_size = PAGE_SIZE * (1 << get_order(req_size));
	dma_free_coherent(dev, dma_buf_size, req_ptr, dma_req_addr);

	return aes_encrypted_len;
}

static ssize_t
store_aes_decrypted_data_qtiapp(struct device *dev,
		struct device_attribute *attr, const char *buf, size_t count)
{

	if ((count % AES_BLOCK_SIZE) ||
			count > MAX_PLAIN_DATA_SIZE) {
		pr_info("\nInvalid input\n");
		pr_info("Plain data length is %lu bytes\n",
				(unsigned long)count);
		pr_info("Plain data length must be multiple of AES block size"
				"of 16 bytes and <= %u bytes\n",
				(unsigned int)MAX_PLAIN_DATA_SIZE);
		return -EINVAL;
	}

	if (!aes_ivdata) {
		pr_info("could not allocate ivdata\n");
		return -EINVAL;
	}
	get_random_bytes((void *)aes_ivdata, AES_BLOCK_SIZE);

	aes_unsealed_buf = memset(aes_unsealed_buf, 0, MAX_PLAIN_DATA_SIZE);
	aes_decrypted_len = count;
	memcpy(aes_unsealed_buf, buf, aes_decrypted_len);
	return count;
}

static ssize_t
show_aes_decrypted_data_qtiapp(struct device *dev,
		struct device_attribute *attr, char *buf)
{
	int rc = 0;
	struct qti_crypto_service_decrypt_data_cmd_t *req_ptr = NULL;
	uint64_t req_size = 0;
	size_t dma_buf_size = 0;
	uint64_t output_len = 0;
	dma_addr_t dma_req_addr = 0;

	aes_unsealed_buf = memset(aes_unsealed_buf, 0, MAX_PLAIN_DATA_SIZE);
	output_len = aes_encrypted_len;

	if (aes_encrypted_len <= 0 || aes_encrypted_len % AES_BLOCK_SIZE) {
		pr_err("Invalid input %lld\n", aes_encrypted_len);
		pr_info("Encrypted data length for decryption should be multiple "
			"of AES block size(16)\n");
		return -EINVAL;
	}
	if (!aes_type || aes_type >= QTI_CRYPTO_SERVICE_AES_TYPE_MAX) {
		pr_info(" aes type needed for decryption\n");
		return -EINVAL;
	}

	dev = qdev;

	req_size = sizeof(struct qti_crypto_service_decrypt_data_cmd_t);
	dma_buf_size = PAGE_SIZE * (1 << get_order(req_size));
	req_ptr = (struct qti_crypto_service_decrypt_data_cmd_t *)
					dma_alloc_coherent(dev, dma_buf_size,
					&dma_req_addr, GFP_KERNEL);
	if (!req_ptr)
		return -ENOMEM;

	req_ptr->type = aes_type;
	req_ptr->mode = aes_mode;
	req_ptr->encrypted_data = (u64)dma_aes_sealed_buf;
	req_ptr->output_buffer = (u64)dma_aes_unsealed_buf;
	req_ptr->iv = (req_ptr->mode == 0 ? 0 : (u64)dma_aes_ivdata);
	req_ptr->iv_len = AES_BLOCK_SIZE;
	req_ptr->encrypted_dlen = aes_encrypted_len;
	req_ptr->output_len = output_len;

	rc = qtiapp_test(dev, (uint8_t *)dma_req_addr, NULL, req_size,
						QTI_APP_AES_DECRYPT_ID);
	if (rc) {
		pr_err("Response status failure..return value = %d\n", rc);
		goto err_end;
	}

	aes_decrypted_len = req_ptr->output_len;
	memcpy(buf, aes_unsealed_buf, aes_decrypted_len);

goto end;

err_end:
	dma_buf_size = PAGE_SIZE * (1 << get_order(req_size));
	dma_free_coherent(dev, dma_buf_size, req_ptr, dma_req_addr);

	return rc;

end:
	dma_buf_size = PAGE_SIZE * (1 << get_order(req_size));
	dma_free_coherent(dev, dma_buf_size, req_ptr, dma_req_addr);

	return aes_decrypted_len;
}

static ssize_t
store_aes_encrypted_data_qtiapp(struct device *dev,
		struct device_attribute *attr, const char *buf, size_t count)
{
	if ((count % AES_BLOCK_SIZE) || count > MAX_PLAIN_DATA_SIZE) {
		pr_info("\nInvalid input\n");
		pr_info("Encrypted data length is %lu bytes\n",
				(unsigned long)count);
		pr_info("Encrypted data length must be multiple of AES block"
				"size 16  and <= %ubytes\n",
				(unsigned int)MAX_ENCRYPTED_DATA_SIZE);
		return -EINVAL;
	}

	aes_sealed_buf = memset(aes_sealed_buf, 0, MAX_ENCRYPTED_DATA_SIZE);
	aes_encrypted_len = count;
	memcpy(aes_sealed_buf, buf, count);

	return count;
}



static ssize_t
store_decrypted_rsa_data_qtiapp(struct device *dev,
		struct device_attribute *attr, const char *buf, size_t count)
{
	if (!count || (count > MAX_RSA_PLAIN_DATA_SIZE)) {
		pr_err("\nInvalid length\n");
		pr_err("Given length: %lu, Max Plain msg length: %u\n",
		(unsigned long)count, (unsigned int)MAX_RSA_PLAIN_DATA_SIZE);
		return -EINVAL;
	}

	memset(rsa_unsealed_buf, 0, MAX_RSA_PLAIN_DATA_SIZE);
	rsa_decrypted_len = count;
	memcpy(rsa_unsealed_buf, buf, rsa_decrypted_len);
	return count;
}

static ssize_t
show_encrypted_rsa_data_qtiapp(struct device *dev,
		struct device_attribute *attr, char *buf)
{
	uint32_t ret = 0;
	struct qti_storage_service_rsa_message_type *msg_vector_ptr = NULL;
	struct qti_storage_service_rsa_key_type *key = NULL;
	struct qti_storage_service_rsa_message_req *req_ptr = NULL;
	uint64_t msg_vector_size = 0, key_size = 0, req_size = 0;
	size_t dma_buf_size = 0;
	dma_addr_t dma_encrypted_msg_len = 0;
	dma_addr_t dma_msg_vector = 0;
	dma_addr_t dma_key = 0;
	dma_addr_t dma_req = 0;
	uint64_t *output_len = NULL;

	dev = qdev;

	if (rsa_decrypted_len <= 0) {
		pr_err("\nInvalid msg size %lld\n", rsa_decrypted_len);
		return ret;
	} else if (rsa_d_key_len <= 0) {
		pr_err("\nInvalid private exponent, size %lld\n",
				rsa_d_key_len);
		return ret;
	} else if (rsa_e_key_len <= 0) {
		pr_err("\nInvalid public exponent, size %lld\n", rsa_e_key_len);
		return ret;
	} else if (rsa_n_key_len <= 0) {
		pr_err("\nInvalid modulus key, size %lld\n", rsa_n_key_len);
		return ret;
	} else if (rsa_hashidx <= 0) {
		pr_err("\nInvalid rsa hashidx, size %lld\n", rsa_hashidx);
		return ret;
	} else if (rsa_nbits_key <= 0) {
		pr_err("\nInvalid key nbits, size %lld\n", rsa_nbits_key);
		return ret;
	}

	memset(rsa_sealed_buf, 0, MAX_RSA_SIGN_DATA_SIZE);
	rsa_encrypted_len = 0;
	output_len = (uint64_t*)dma_alloc_coherent(dev, sizeof(uint64_t),
				&dma_encrypted_msg_len, GFP_KERNEL);

	if (!output_len) {
		pr_err("Error: alloc failed\n");
		return -ENOMEM;
	}

	msg_vector_size = sizeof(struct qti_storage_service_rsa_message_type);
	dma_buf_size = PAGE_SIZE * (1 << get_order(msg_vector_size));
	msg_vector_ptr = (struct qti_storage_service_rsa_message_type *)
		dma_alloc_coherent(dev, dma_buf_size,
				&dma_msg_vector, GFP_KERNEL|GFP_DMA);

	if (!msg_vector_ptr) {
		pr_err("Mem allocation failed for msg vector\n");
		goto err_mem_msg_vector;
	}

	msg_vector_ptr->input = (u64)dma_rsa_unsealed_buf;

	msg_vector_ptr->input_len = rsa_decrypted_len;
	msg_vector_ptr->label = (u64)dma_rsa_label;
	msg_vector_ptr->label_len = rsa_label_len;
	msg_vector_ptr->output = (u64)dma_rsa_sealed_buf;
	msg_vector_ptr->output_len = (u64)dma_encrypted_msg_len;
	msg_vector_ptr->padding_type = rsa_padding_type;
	msg_vector_ptr->hashidx = rsa_hashidx;

        key_size = sizeof(struct qti_storage_service_rsa_key_type);
        dma_buf_size = PAGE_SIZE * (1 << get_order(key_size));
        key = (struct qti_storage_service_rsa_key_type *)
                dma_alloc_coherent(dev, dma_buf_size, &dma_key,
                                        GFP_KERNEL|GFP_DMA);
        if(!key) {
                pr_err("Mem allocation failed for key vector\n");
                goto err_mem_key;
        }

        key->n = (u64)dma_rsa_n_key;
        key->e = (u64)dma_rsa_e_key;
        key->d = (u64)dma_rsa_d_key;
        key->nbits = rsa_nbits_key;

        req_size = sizeof(struct qti_storage_service_rsa_message_req);
        dma_buf_size = PAGE_SIZE * (1 << get_order(req_size));
        req_ptr = (struct qti_storage_service_rsa_message_req *)
                        dma_alloc_coherent(dev, dma_buf_size, &dma_req,
                                                GFP_KERNEL|GFP_DMA);
        if (!req_ptr) {
                pr_err("Mem allocation failed for request buffer\n");
                goto err_mem_req;
        }

        req_ptr->msg_req = (u64)dma_msg_vector;
        req_ptr->key_req = (u64)dma_key;
        req_ptr->operation = QTI_APP_RSA_ENCRYPTION_ID;

        ret = qtiapp_test(dev, (void *)dma_req, NULL, req_size,
                                                QTI_APP_RSA_ENC_DEC_ID);

        if (ret) {
                pr_err("RSA encryption failed from QTI app with error code %d\n",ret);
                rsa_encrypted_len = 0;
        } else {
                rsa_encrypted_len = *output_len;
                memcpy(buf, rsa_sealed_buf, rsa_encrypted_len);
        }

        dma_buf_size = PAGE_SIZE * (1 << get_order(req_size));
        dma_free_coherent(dev, dma_buf_size, req_ptr, dma_req);

err_mem_req:
        dma_buf_size = PAGE_SIZE * (1 << get_order(key_size));
        dma_free_coherent(dev, dma_buf_size, key, dma_key);
err_mem_key:
        dma_buf_size = PAGE_SIZE * (1 << get_order(msg_vector_size));
        dma_free_coherent(dev, dma_buf_size, msg_vector_ptr, dma_msg_vector);
err_mem_msg_vector:
        dma_free_coherent(dev, sizeof(uint64_t), output_len, dma_encrypted_msg_len);

        return rsa_encrypted_len;

}

static ssize_t
store_encrypted_rsa_data_qtiapp(struct device *dev,
		struct device_attribute *attr, const char *buf, size_t count)
{
	if (!count || (count > MAX_RSA_SIGN_DATA_SIZE)) {
		pr_err("\nInvalid length\n");
		pr_err("Given length: %lu, Max Encrypted Msg length: %u\n",
		(unsigned long)count, (unsigned int)MAX_RSA_SIGN_DATA_SIZE);
		return -EINVAL;
	}

	memset(rsa_sealed_buf, 0, MAX_RSA_SIGN_DATA_SIZE);
	rsa_encrypted_len = count;
	memcpy(rsa_sealed_buf, buf, rsa_encrypted_len);
	return count;
}

static ssize_t
show_decrypted_rsa_data_qtiapp(struct device *dev, struct device_attribute *attr,
                                                 char *buf)
{
        uint32_t ret = 0;
        struct qti_storage_service_rsa_message_type *msg_vector_ptr = NULL;
        struct qti_storage_service_rsa_key_type *key = NULL;
        struct qti_storage_service_rsa_message_req *req_ptr = NULL;
        uint64_t msg_vector_size = 0, key_size = 0, req_size = 0;
        size_t dma_buf_size = 0;
        dma_addr_t dma_decrypted_msg_len = 0;
        dma_addr_t dma_msg_vector = 0;
        dma_addr_t dma_key = 0;
        dma_addr_t dma_req = 0;
        uint64_t *output_len = NULL;

        dev = qdev;
        if (rsa_encrypted_len <= 0) {
                pr_err("Invalid encrypted msg size %lld\n", rsa_encrypted_len);
                return ret;
        } else if (rsa_d_key_len <=0) {
                pr_err("Invalid private exponent, size %lld\n", rsa_d_key_len);
                return ret;
        } else if (rsa_e_key_len <=0) {
                pr_err("Invalid public exponent, size %lld\n", rsa_e_key_len);
                return ret;
        } else if (rsa_n_key_len <=0) {
                pr_err("Invalid modulus key, size %lld\n", rsa_n_key_len);
                return ret;
        } else if (rsa_hashidx <=0) {
                pr_err("Invalid rsa hashidx, size %lld\n", rsa_hashidx);
                return ret;
        } else if (rsa_nbits_key <=0) {
                pr_err("Invalid key nbits, size %lld\n", rsa_nbits_key);
                return ret;
        }

        output_len = (uint64_t*)dma_alloc_coherent(dev, sizeof(uint64_t),
                                &dma_decrypted_msg_len, GFP_KERNEL);
        if (!output_len) {
                pr_err("Error: alloc failed\n");
                return -ENOMEM;
        }

        memset(rsa_unsealed_buf, 0, MAX_RSA_PLAIN_DATA_SIZE);
        rsa_decrypted_len = 0;

        msg_vector_size = sizeof(struct qti_storage_service_rsa_message_type);
        dma_buf_size = PAGE_SIZE * (1 << get_order(msg_vector_size));
        msg_vector_ptr = (struct qti_storage_service_rsa_message_type *)
                                        dma_alloc_coherent(dev, dma_buf_size,
                                        &dma_msg_vector, GFP_KERNEL);
        if (!msg_vector_ptr) {
                pr_err("Mem allocation failed for msg vector\n");
                goto err_mem_msg_vector;
        }

        msg_vector_ptr->input = (u64)dma_rsa_sealed_buf;
        msg_vector_ptr->input_len = rsa_encrypted_len;
        msg_vector_ptr->label = (u64)dma_rsa_label;
        msg_vector_ptr->label_len = rsa_label_len;
        msg_vector_ptr->output = (u64)dma_rsa_unsealed_buf;
        msg_vector_ptr->output_len = (u64)dma_decrypted_msg_len;
        msg_vector_ptr->padding_type = rsa_padding_type;
        msg_vector_ptr->hashidx = rsa_hashidx;

        key_size = sizeof(struct qti_storage_service_rsa_key_type);
        dma_buf_size = PAGE_SIZE * (1 << get_order(key_size));
        key = (struct qti_storage_service_rsa_key_type *)
                dma_alloc_coherent(dev, dma_buf_size, &dma_key,
                                        GFP_KERNEL);
        if(!key) {
                pr_err("Mem allocation failed for key vector\n");
                goto err_mem_key;
        }

        key->n = (u64)dma_rsa_n_key;
        key->e = (u64)dma_rsa_e_key;
        key->d = (u64)dma_rsa_d_key;
        key->nbits = rsa_nbits_key;

        req_size = sizeof(struct qti_storage_service_rsa_message_req);
        dma_buf_size = PAGE_SIZE * (1 << get_order(req_size));
        req_ptr = (struct qti_storage_service_rsa_message_req *)
                        dma_alloc_coherent(dev, dma_buf_size, &dma_req,
                                                GFP_KERNEL);
        if (!req_ptr) {
                pr_err("Mem allocation failed for request buffer\n");
                goto err_mem_req;
        }

        req_ptr->msg_req = (u64)dma_msg_vector;
        req_ptr->key_req = (u64)dma_key;
        req_ptr->operation = QTI_APP_RSA_DECRYPTION_ID;

        ret = qtiapp_test(dev, (void *)dma_req, NULL, req_size,
                                                QTI_APP_RSA_ENC_DEC_ID);

        if (ret) {
                pr_err("RSA decryption failed with %d from QTI app\n",ret);
                rsa_decrypted_len = 0;
        } else {
                rsa_decrypted_len = *output_len;
                memcpy(buf, rsa_unsealed_buf, rsa_decrypted_len);
        }

        dma_buf_size = PAGE_SIZE * (1 << get_order(req_size));
        dma_free_coherent(dev, dma_buf_size, req_ptr, dma_req);

err_mem_req:
        dma_buf_size = PAGE_SIZE * (1 << get_order(key_size));
        dma_free_coherent(dev, dma_buf_size, key, dma_key);
err_mem_key:
        dma_buf_size = PAGE_SIZE * (1 << get_order(msg_vector_size));
        dma_free_coherent(dev, dma_buf_size, msg_vector_ptr, dma_msg_vector);
err_mem_msg_vector:
        dma_free_coherent(dev, sizeof(uint64_t), output_len,
                                                        dma_decrypted_msg_len);

        return rsa_decrypted_len;
}

static ssize_t
store_label_rsa_data_qtiapp(struct device *dev, struct device_attribute *attr,
		const char *buf, size_t count)
{
	if (!count || (count > MAX_RSA_PLAIN_DATA_SIZE)) {
		pr_err("\nInvalid length\n");
		pr_err("Given length: %lu, Max Lebel length: %u\n",
		(unsigned long)count, (unsigned int)MAX_RSA_PLAIN_DATA_SIZE);
		return -EINVAL;
	}

	memset(rsa_label, 0, MAX_RSA_PLAIN_DATA_SIZE);
	rsa_label_len = count;
	memcpy(rsa_label, buf, rsa_label_len);
	return count;
}

static ssize_t
store_n_key_rsa_data_qtiapp(struct device *dev, struct device_attribute *attr,
		const char *buf, size_t count)
{
	if (!count || (count > RSA_KEY_SIZE_MAX)) {
		pr_err("\nInvalid length\n");
		pr_err("Given length: %lu, Max Key Modulus length: %u\n",
			(unsigned long)count, (unsigned int)RSA_KEY_SIZE_MAX);
		return -EINVAL;
	}

	memset(rsa_n_key, 0, RSA_KEY_SIZE_MAX);
	rsa_n_key_len = count;
	memcpy(rsa_n_key, buf, rsa_n_key_len);
	if (rsa_n_key[count-1] == 0x0a)
		rsa_n_key[count-1] = 0x00;
	return count;
}

static ssize_t
store_e_key_rsa_data_qtiapp(struct device *dev, struct device_attribute *attr,
		const char *buf, size_t count)
{
	if (!count || (count > RSA_KEY_SIZE_MAX)) {
		pr_err("\nInvalid length\n");
		pr_err("Given length: %lu, Max Public exponent length: %u\n",
		(unsigned long)count, (unsigned int)RSA_KEY_SIZE_MAX);
		return -EINVAL;
	}

	memset(rsa_e_key, 0, RSA_KEY_SIZE_MAX);
	rsa_e_key_len = count;
	memcpy(rsa_e_key, buf, rsa_e_key_len);
	if (rsa_e_key[count-1] == 0x0a)
		rsa_e_key[count-1] = 0x00;
	return count;
}
static ssize_t
store_d_key_rsa_data_qtiapp(struct device *dev, struct device_attribute *attr,
		const char *buf, size_t count)
{
	if (!count || (count > RSA_KEY_SIZE_MAX)) {
		pr_err("\nInvalid length\n");
		pr_err("Given length: %lu, Max Private exponent length: %u\n",
			(unsigned long)count, (unsigned int)RSA_KEY_SIZE_MAX);
		return -EINVAL;
	}

	memset(rsa_d_key, 0, RSA_KEY_SIZE_MAX);
	rsa_d_key_len = count;
	memcpy(rsa_d_key, buf, rsa_d_key_len);
	if (rsa_d_key[count-1] == 0x0a)
		rsa_d_key[count-1] = 0x00;
	return count;
}
static ssize_t
store_nbits_key_rsa_data_qtiapp(struct device *dev,
		struct device_attribute *attr, const char *buf, size_t count)
{
	unsigned long long val;

	if (kstrtoull(buf, 10, &val))
		return -EINVAL;

	if (val <= 0 || val % RSA_KEY_ALIGN) {
		pr_err("\nInvalid key nbits: %llu\n", val);
		pr_err("No of bits in key should be RSA_KEY_ALIGN %d aligned\n",
				RSA_KEY_ALIGN);
		return -EINVAL;
	}
	rsa_nbits_key = val;

	return count;
}
static ssize_t
store_hashidx_rsa_data_qtiapp(struct device *dev, struct device_attribute *attr,
		const char *buf, size_t count)
{
	unsigned long long val;

	if (kstrtoull(buf, 10, &val))
		return -EINVAL;

	if (val <= 0 || val >= QSEE_HASH_IDX_MAX) {
		pr_err("\nInvalid rsa hashidx: %llu\n", val);
		return -EINVAL;
	}
	rsa_hashidx = val;

	return count;
}

static ssize_t
store_padding_type_rsa_data_qtiapp(struct device *dev,
		struct device_attribute *attr, const char *buf, size_t count)
{
	unsigned long long val;

	if (kstrtoull(buf, 10, &val))
		return -EINVAL;

	if (val < 0 || val >= QSEE_RSA_PADDING_TYPE_MAX) {
		pr_err("\nInvalid padding type: %llu\n", val);
		return -EINVAL;
	}
	rsa_padding_type = val;

	return count;
}

static ssize_t
store_aes_mode_qtiapp(struct device *dev, struct device_attribute *attr,
		const char *buf, size_t count)
{
	unsigned long long val;

	if (kstrtoull(buf, 10, &val))
		return -EINVAL;

	if (val >= QTI_CRYPTO_SERVICE_AES_MODE_MAX) {
		pr_info("\nInvalid aes 256 mode: %llu\n", val);
		return -EINVAL;
	}
	aes_mode = val;

	return count;
}

static ssize_t
store_aes_type_qtiapp(struct device *dev, struct device_attribute *attr,
		const char *buf, size_t count)
{
	unsigned long long val;

	if (kstrtoull(buf, 10, &val))
		return -EINVAL;

	if (!val || val >= QTI_CRYPTO_SERVICE_AES_TYPE_MAX) {
		pr_info("\nInvalid aes 256 type: %llu\n", val);
		return -EINVAL;
	}
	aes_type = val;

	return count;
}

static ssize_t
store_iv_data_qtiapp(struct device *dev, struct device_attribute *attr,
		const char *buf, size_t count)
{
	if (!aes_ivdata) {
		pr_info("could not allocate ivdata\n");
		return -EINVAL;
	}

	if (count != AES_BLOCK_SIZE) {
		pr_info("\nInvalid input\n");
		pr_info("IV data length is %lu bytes\n",
				(unsigned long)count);
		pr_info("IV data length must be equal to AES block size"
				"(16) bytes");
		return -EINVAL;
	}

	aes_ivdata = memset(aes_ivdata, 0, AES_BLOCK_SIZE);
	aes_ivdata_len = count;
	memcpy(aes_ivdata, buf, aes_ivdata_len);
	return count;
}

static int __init rsa_sec_key_init(struct device *dev)
{
	int err = 0;
	size_t dma_buf_size = 0;

	rsa_sec_kobj = kobject_create_and_add("rsa_sec_key", rsa_sec_kobj);

	if (!rsa_sec_kobj) {
		pr_info("Failed to register rsa_sec_key sysfs\n");
		return -ENOMEM;
	}

	err = sysfs_create_group(rsa_sec_kobj, &rsa_sec_key_attr_grp);

	if (err) {
		kobject_put(rsa_sec_kobj);
		rsa_sec_kobj = NULL;
		return err;
	}

	dma_buf_size = PAGE_SIZE * (1 << get_order(RSA_KEY_BLOB_SIZE));
	buf_rsa_key_blob = dma_alloc_coherent(dev, dma_buf_size,
					&dma_rsa_key_blob, GFP_KERNEL);

	dma_buf_size = PAGE_SIZE * (1 << get_order(RSA_KEY_SIZE_MAX));
	buf_rsa_import_modulus = dma_alloc_coherent(dev, dma_buf_size,
				&dma_rsa_import_modulus, GFP_KERNEL);

	dma_buf_size = PAGE_SIZE * (1 << get_order(RSA_PUB_EXP_SIZE_MAX));
	buf_rsa_import_public_exponent = dma_alloc_coherent(dev, dma_buf_size,
				&dma_rsa_import_public_exponent, GFP_KERNEL);

	dma_buf_size = PAGE_SIZE * (1 << get_order(RSA_KEY_SIZE_MAX));
	buf_rsa_import_pvt_exponent = dma_alloc_coherent(dev, dma_buf_size,
				&dma_rsa_import_pvt_exponent, GFP_KERNEL);

	dma_buf_size = PAGE_SIZE * (1 << get_order(MAX_RSA_SIGN_DATA_SIZE));
	buf_rsa_sign_data_buf = dma_alloc_coherent(dev, dma_buf_size,
					&dma_rsa_sign_data_buf, GFP_KERNEL);

	dma_buf_size = PAGE_SIZE * (1 << get_order(MAX_RSA_PLAIN_DATA_SIZE));
	buf_rsa_plain_data_buf = dma_alloc_coherent(dev, dma_buf_size,
					&dma_rsa_plain_data_buf, GFP_KERNEL);

	if (!buf_rsa_key_blob || !buf_rsa_import_modulus ||
	   !buf_rsa_import_public_exponent || !buf_rsa_import_pvt_exponent ||
	   !buf_rsa_sign_data_buf || !buf_rsa_plain_data_buf) {
		pr_err("Cannot allocate memory for RSA secure-key ops\n");

		if (buf_rsa_key_blob) {
			dma_buf_size = PAGE_SIZE *
					(1 << get_order(RSA_KEY_BLOB_SIZE));
			dma_free_coherent(dev, dma_buf_size, buf_rsa_key_blob,
							dma_rsa_key_blob);
		}

		if (buf_rsa_import_modulus) {
			dma_buf_size = PAGE_SIZE *
					(1 << get_order(RSA_KEY_SIZE_MAX));
			dma_free_coherent(dev, dma_buf_size,
					buf_rsa_import_modulus,
					dma_rsa_import_modulus);
		}

		if (buf_rsa_import_public_exponent) {
			dma_buf_size = PAGE_SIZE *
					(1 << get_order(RSA_PUB_EXP_SIZE_MAX));
			dma_free_coherent(dev, dma_buf_size,
						buf_rsa_import_public_exponent,
						dma_rsa_import_public_exponent);
		}

		if (buf_rsa_import_pvt_exponent) {
			dma_buf_size = PAGE_SIZE *
					(1 << get_order(RSA_KEY_SIZE_MAX));
			dma_free_coherent(dev, dma_buf_size,
						buf_rsa_import_pvt_exponent,
						dma_rsa_import_pvt_exponent);
		}

		if (buf_rsa_sign_data_buf) {
			dma_buf_size = PAGE_SIZE *
				(1 << get_order(MAX_RSA_SIGN_DATA_SIZE));
			dma_free_coherent(dev, dma_buf_size,
						buf_rsa_sign_data_buf,
						dma_rsa_sign_data_buf);
		}

		if(buf_rsa_plain_data_buf) {
			dma_buf_size = PAGE_SIZE *
				(1 << get_order(MAX_RSA_PLAIN_DATA_SIZE));
			dma_free_coherent(dev, dma_buf_size,
						buf_rsa_plain_data_buf,
						dma_rsa_plain_data_buf);
		}

		sysfs_remove_group(rsa_sec_kobj, &rsa_sec_key_attr_grp);
		kobject_put(rsa_sec_kobj);
		rsa_sec_kobj = NULL;

		return -ENOMEM;
	}

	rsa_key_blob = (uint8_t*) buf_rsa_key_blob;
	rsa_import_modulus = (uint8_t*) buf_rsa_import_modulus;
	rsa_import_public_exponent = (uint8_t*) buf_rsa_import_public_exponent;
	rsa_import_pvt_exponent = (uint8_t*) buf_rsa_import_pvt_exponent;
	rsa_sign_data_buf = (uint8_t*) buf_rsa_sign_data_buf;
	rsa_plain_data_buf = (uint8_t*) buf_rsa_plain_data_buf;

	return 0;
}

static int __init sec_key_init(struct device *dev)
{
	int err = 0;
	size_t dma_buf_size = 0;

	dev = qdev;

	sec_kobj = kobject_create_and_add("sec_key", NULL);

	if (!sec_kobj) {
		pr_info("Failed to register sec_key sysfs\n");
		return -ENOMEM;
	}

	err = sysfs_create_group(sec_kobj, &sec_key_attr_grp);

	if (err) {
		kobject_put(sec_kobj);
		sec_kobj = NULL;
		return err;
	}

	dma_buf_size = PAGE_SIZE * (1 << get_order(KEY_SIZE));
	buf_key = dma_alloc_coherent(dev, dma_buf_size,
					&dma_key, GFP_KERNEL);

	dma_buf_size = PAGE_SIZE * (1 << get_order(KEY_BLOB_SIZE));
	buf_key_blob = dma_alloc_coherent(dev, dma_buf_size,
					&dma_key_blob, GFP_KERNEL);

	dma_buf_size = PAGE_SIZE * (1 << get_order(MAX_ENCRYPTED_DATA_SIZE));
	buf_sealed_buf = dma_alloc_coherent(dev, dma_buf_size,
					&dma_sealed_data, GFP_KERNEL);

	dma_buf_size = PAGE_SIZE * (1 << get_order(MAX_PLAIN_DATA_SIZE));
	buf_unsealed_buf = dma_alloc_coherent(dev, dma_buf_size,
					&dma_unsealed_data, GFP_KERNEL);

	dma_buf_size = PAGE_SIZE * (1 << get_order(AES_BLOCK_SIZE));
	buf_iv = dma_alloc_coherent(dev, dma_buf_size,
					&dma_iv_data, GFP_KERNEL);

	dma_buf_size = PAGE_SIZE * (1 << get_order(MAX_KEY_HANDLE_SIZE));
	key_handle = dma_alloc_coherent(dev, dma_buf_size,
					&dma_key_handle, GFP_KERNEL);
	dma_buf_size = PAGE_SIZE * (1 << get_order(MAX_KEY_HANDLE_SIZE));
	aes_key_handle = dma_alloc_coherent(dev, dma_buf_size,
					&dma_aes_key_handle, GFP_KERNEL);

	if (!buf_key || !buf_key_blob || !buf_sealed_buf ||
	    !buf_unsealed_buf || !buf_iv || !key_handle || !aes_key_handle) {
		pr_err("Cannot allocate memory for secure-key ops\n");

		if (buf_key) {
			dma_buf_size = PAGE_SIZE *
					(1 << get_order(KEY_SIZE));
			dma_free_coherent(dev, dma_buf_size, buf_key,
							dma_key);
		}

		if (buf_key_blob) {
			dma_buf_size = PAGE_SIZE *
					(1 << get_order(KEY_BLOB_SIZE));
			dma_free_coherent(dev, dma_buf_size, buf_key_blob,
							dma_key_blob);
		}

		if (buf_sealed_buf) {
			dma_buf_size = PAGE_SIZE *
				(1 << get_order(MAX_ENCRYPTED_DATA_SIZE));
			dma_free_coherent(dev, dma_buf_size,
							buf_sealed_buf,
							dma_sealed_data);
		}

		if (buf_unsealed_buf) {
			dma_buf_size = PAGE_SIZE *
					(1 << get_order(MAX_PLAIN_DATA_SIZE));
			dma_free_coherent(dev, dma_buf_size,
							buf_unsealed_buf,
							dma_unsealed_data);
		}

		if (buf_iv) {
			dma_buf_size = PAGE_SIZE *
					(1 << get_order(AES_BLOCK_SIZE));
			dma_free_coherent(dev, dma_buf_size,
							buf_iv,
							dma_iv_data);
		}

		if (key_handle) {
			dma_buf_size = PAGE_SIZE *
					(1 << get_order(MAX_KEY_HANDLE_SIZE));
			dma_free_coherent(dev, dma_buf_size,
					key_handle, dma_key_handle);
		}

		if (aes_key_handle) {
			dma_buf_size = PAGE_SIZE *
					(1 << get_order(MAX_KEY_HANDLE_SIZE));
			dma_free_coherent(dev, dma_buf_size, aes_key_handle,
					 dma_aes_key_handle);
		}

		sysfs_remove_group(sec_kobj, &sec_key_attr_grp);
		kobject_put(sec_kobj);
		sec_kobj = NULL;

		return -ENOMEM;
	}

	key = (uint8_t*) buf_key;
	key_blob = (uint8_t*) buf_key_blob;
	sealed_buf = (uint8_t*) buf_sealed_buf;
	unsealed_buf = (uint8_t*) buf_unsealed_buf;
	ivdata = (uint8_t*) buf_iv;

	return 0;
}

static ssize_t mdt_write(struct file *filp, struct kobject *kobj,
	struct bin_attribute *bin_attr,
	char *buf, loff_t pos, size_t count)
{
	uint8_t *tmp;
	/*
	 * Position '0' means new file being written,
	 * Hence allocate new memory after freeing already allocated mem if any
	 */
	if (pos == 0) {
		kfree(mdt_file);
		mdt_file = kzalloc((count) * sizeof(uint8_t), GFP_KERNEL);
	} else {
		tmp = mdt_file;
		mdt_file = krealloc(tmp,
			(pos + count) * sizeof(uint8_t), GFP_KERNEL);
	}

	if (!mdt_file)
		return -ENOMEM;

	memcpy((mdt_file + pos), buf, count);
	mdt_size = pos + count;
	return count;
}

static ssize_t seg_write(struct file *filp, struct kobject *kobj,
	struct bin_attribute *bin_attr,
	char *buf, loff_t pos, size_t count)
{
	uint8_t *tmp;
	if (pos == 0) {
		kfree(seg_file);
		seg_file = kzalloc((count) * sizeof(uint8_t), GFP_KERNEL);
	} else {
		tmp = seg_file;
		seg_file = krealloc(tmp, (pos + count) * sizeof(uint8_t),
					GFP_KERNEL);
	}

	if (!seg_file)
		return -ENOMEM;

	memcpy((seg_file + pos), buf, count);
	seg_size = pos + count;
	return count;
}

static int qseecom_unload_app(void)
{
	struct qseecom_unload_ireq req;
	struct qseecom_command_scm_resp resp;
	int ret = 0;
	uint32_t cmd_id = 0;
	uint32_t smc_id = 0;

	cmd_id = QSEOS_APP_SHUTDOWN_COMMAND;

	smc_id = QTI_SYSCALL_CREATE_SMC_ID(QTI_OWNER_QSEE_OS, QTI_SVC_APP_MGR,
					   QTI_CMD_UNLOAD_APP_ID);

	req.app_id = qsee_app_id;

	/* SCM_CALL to unload the app */
	ret = qti_scm_qseecom_unload(smc_id, cmd_id, &req,
				     sizeof(struct qseecom_unload_ireq),
				     &resp, sizeof(resp));
	if (ret) {
		pr_err("scm_call to unload app (id = %d) failed\n", req.app_id);
		pr_info("scm call ret value = %d\n", ret);
		return ret;
	}

	pr_info("App id %d now unloaded\n", req.app_id);

	return 0;
}

static int qtiapp_test(struct device *dev, void *input,
		      void *output, int input_len, int option)
{
	int ret = 0;

	union qseecom_client_send_data_ireq send_data_req;
	struct qseecom_command_scm_resp resp;
	struct qsee_send_cmd_rsp *msgrsp; /* response data sent from QSEE */
	struct qsee_64_send_cmd *msgreq;
	void *buf = NULL;
	dma_addr_t dma_buf = 0;
	dma_addr_t dma_msgreq;
	dma_addr_t dma_msgresp;

	dev = qdev;

	/*
	 * Using dma_alloc_coherent to avoid colliding with input pointer's
	 * allocated page, since qsee_register_shared_buffer() in sampleapp
	 * checks if input ptr is in secure area. Page where msgreq/msgrsp
	 * is allocated is added to blacklisted area by sampleapp and added
	 * as secure memory region, hence input data (shared buffer)
	 * cannot be in that secure memory region
	 */
	buf = dma_alloc_coherent(dev, PAGE_SIZE, &dma_buf, GFP_KERNEL);
	if (!buf) {
		pr_err("Failed to allocate page\n");
		return -ENOMEM;
	} else {
               printk("\n memory allocated at physical address 0x%x\n",dma_buf);
	}

	/*
	 * Getting virtual page address. pg_tmp will be pointing to
	 * first page structure
	 */
	msgreq = (struct qsee_64_send_cmd *)buf;

	msgrsp = (struct qsee_send_cmd_rsp *)((uint8_t *) msgreq +
				sizeof(struct qsee_64_send_cmd));

	dma_msgreq = dma_buf;
	dma_msgresp = (dma_addr_t)((uint8_t *)dma_msgreq +
				sizeof(struct qsee_64_send_cmd));
	/*
	 * option = 1 -> Basic Multiplication,
	 * option = 4 -> Crypto Function
	 */

	switch (option) {
	case 1:
		msgreq->cmd_id = CLIENT_CMD1_BASIC_DATA;
		msgreq->data = *((dma_addr_t *)input);
		break;
	case 4:
		msgreq->cmd_id = CLIENT_CMD8_RUN_CRYPTO_TEST;
		break;
	case QTI_APP_LOG_BITMASK_TEST_ID:
		msgreq->cmd_id = CLIENT_CMD53_RUN_LOG_BITMASK_TEST;
		break;
	case QTI_APP_FUSE_TEST_ID:
		msgreq->cmd_id = CLIENT_CMD18_RUN_FUSE_TEST;
		break;
	case QTI_APP_MISC_TEST_ID:
		msgreq->cmd_id = CLIENT_CMD13_RUN_MISC_TEST;
		break;
	case QTI_APP_FUSE_BLOW_ID:
		msgreq->cmd_id = CLIENT_CMD43_RUN_FUSE_BLOW;
		msgreq->data = (dma_addr_t)input;
		msgreq->len = input_len;
		break;
	case QTI_APP_AES_ENCRYPT_ID:
		msgreq->cmd_id = CLIENT_CMD40_RUN_AES_ENCRYPT;
		msgreq->data = (dma_addr_t)input;
		msgreq->len = input_len;
		break;
	case QTI_APP_AES_DECRYPT_ID:
		msgreq->cmd_id = CLIENT_CMD41_RUN_AES_DECRYPT;
		msgreq->data = (dma_addr_t)input;
		msgreq->len = input_len;
		break;
	case QTI_APP_RSA_ENC_DEC_ID:
		msgreq->cmd_id = CLIENT_CMD42_RUN_RSA_CRYPT;
		msgreq->data = (dma_addr_t)input;
		msgreq->len = input_len;
		break;
	default:
		pr_err("Invalid Option\n");
		goto fn_exit;
	}

	send_data_req.v1.app_id = qsee_app_id;

	send_data_req.v1.req_ptr = dma_msgreq;
	send_data_req.v1.rsp_ptr = dma_msgresp;

	send_data_req.v1.req_len = sizeof(struct qsee_64_send_cmd);
	send_data_req.v1.rsp_len = sizeof(struct qsee_send_cmd_rsp);
	ret = qti_scm_qseecom_send_data(&send_data_req,
			sizeof(send_data_req.v1), &resp, sizeof(resp));
	if (ret) {
		pr_err("qseecom_scm_call failed with err: %d\n", ret);
		goto fn_exit;
	}

	if (resp.result == QSEOS_RESULT_INCOMPLETE) {
		pr_err("Result incomplete\n");
		ret = -EINVAL;
		goto fn_exit;
	} else {
		if (resp.result != QSEOS_RESULT_SUCCESS) {
			pr_err("Response result %lu not supported\n",
							resp.result);
			ret = -EINVAL;
			goto fn_exit;
		} else {
			if (option == 4) {
				if (!msgrsp->status) {
					pr_info("Crypto operation success\n");
				} else {
					pr_info("Crypto operation failed\n");
					goto fn_exit;
				}
			}
		}
	}

	if (option == 1) {
		if (msgrsp->status) {
			pr_err("Input size exceeded supported range\n");
			ret = -EINVAL;
		}
		basic_output = msgrsp->data;
	} else if (option == QTI_APP_LOG_BITMASK_TEST_ID) {
		if (!msgrsp->status) {
			pr_info("Log Bitmask test Success\n");
		} else {
			pr_info("Log Bitmask test failed\n");
			goto fn_exit;
		}
	} else if (option == QTI_APP_FUSE_TEST_ID) {
		if (!msgrsp->status) {
			pr_info("Fuse test success\n");
		} else {
			pr_info("Fuse test failed\n");
			goto fn_exit;
		}
	} else if (option == QTI_APP_MISC_TEST_ID) {
		if (!msgrsp->status) {
			pr_info("Misc test success\n");
		} else {
			pr_info("Misc test failed\n");
			goto fn_exit;
		}
	} else if (option == QTI_APP_RSA_ENC_DEC_ID ||
			option == QTI_APP_FUSE_BLOW_ID) {
		if (msgrsp->status)
			ret = -EINVAL;
	} else if (option == QTI_APP_AES_ENCRYPT_ID ||
			option == QTI_APP_AES_DECRYPT_ID) {
		if (msgrsp->status)
			ret = -EOPNOTSUPP;
	}

fn_exit:
	dma_free_coherent(dev, PAGE_SIZE, buf, dma_buf);

	return ret;
}

static int32_t copy_files(int *img_size)
{
	uint8_t *buf;

	if (mdt_file && seg_file) {
		*img_size = mdt_size + seg_size;

		qsee_sbuffer = kzalloc(*img_size, GFP_KERNEL);
		if (!qsee_sbuffer) {
			pr_err("Error: qsee_sbuffer alloc failed\n");
			return -ENOMEM;
		}
		buf = qsee_sbuffer;

		memcpy(buf, mdt_file, mdt_size);
		buf += mdt_size;
		memcpy(buf, seg_file, seg_size);
		buf += seg_size;
	} else {
		pr_err("Sampleapp file Inputs not provided\n");
		return -EINVAL;
	}
	return 0;
}

static int load_request(struct device *dev, uint32_t smc_id,
		       uint32_t cmd_id, size_t req_size)
{
	union qseecom_load_ireq load_req;
	struct qseecom_command_scm_resp resp;
	int ret, ret1;
	int img_size;

	kfree(qsee_sbuffer);
	ret = copy_files(&img_size);
	if (ret) {
		pr_err("Copying Files failed\n");
		return ret;
	}

	dev = qdev;

	load_req.load_lib_req.mdt_len = mdt_size;
	load_req.load_lib_req.img_len = img_size;
	load_req.load_lib_req.phy_addr = dma_map_single(dev, qsee_sbuffer,
						       img_size, DMA_TO_DEVICE);
	ret1 = dma_mapping_error(dev, load_req.load_lib_req.phy_addr);
	if (ret1 == 0) {
		ret = qti_scm_qseecom_load(smc_id, cmd_id, &load_req,
					   req_size, &resp, sizeof(resp));
		dma_unmap_single(dev, load_req.load_lib_req.phy_addr,
				img_size, DMA_TO_DEVICE);
	}
	if (ret1) {
		pr_err("DMA Mapping error (qsee_sbuffer)\n");
		return ret1;
	}
	if (ret) {
		pr_err("SCM_CALL to load app and services failed\n");
		return ret;
	}

	if (resp.result == QSEOS_RESULT_FAILURE) {
		pr_err("SCM_CALL rsp.result is QSEOS_RESULT_FAILURE\n");
		return -EFAULT;
	}

	if (resp.result == QSEOS_RESULT_INCOMPLETE)
		pr_err("Process_incomplete_cmd ocurred\n");

	if (resp.result != QSEOS_RESULT_SUCCESS) {
		pr_err("scm_call failed resp.result unknown, %lu\n",
				resp.result);
		return -EFAULT;
	}

	pr_info("Successfully loaded app and services!!!!!\n");

	qsee_app_id = resp.data;
	return 0;
}

/* To show basic multiplication output */
static ssize_t
show_basic_output(struct device *dev, struct device_attribute *attr,
					char *buf)
{
	return snprintf(buf, (basic_data_len + 1), "%lu\n", basic_output);
}

/* Basic multiplication App*/
static ssize_t
store_basic_input(struct device *dev, struct device_attribute *attr,
					const char *buf, size_t count)
{
	dma_addr_t __aligned(sizeof(dma_addr_t) * 8) basic_input = 0;
	uint32_t ret = 0;
	basic_data_len = count;
	if ((count - 1) == 0) {
		pr_err("Input cannot be NULL!\n");
		return -EINVAL;
	}
	if (kstrtouint(buf, 10, (unsigned int *)&basic_input) || basic_input > (U32_MAX / 10))
		pr_err("Please enter a valid unsigned integer less than %u\n",
			(U32_MAX / 10));
	else
		ret = qtiapp_test(dev, &basic_input, NULL, 0, 1);

	return ret ? ret : count;
}

static ssize_t
store_load_start(struct device *dev, struct device_attribute *attr,
		const char *buf, size_t count)
{
	int load_cmd;
	uint32_t smc_id = 0;
	uint32_t cmd_id = 0;
	size_t req_size = 0;

	dev = qdev;

	if (kstrtouint(buf, 10, &load_cmd)) {
		pr_err("Provide valid integer input!\n");
		pr_err("Echo 0 to load app libs\n");
		pr_err("Echo 1 to load app\n");
		pr_err("Echo 2 to unload app\n");
		return -EINVAL;
	}
	if (load_cmd == 0) {
		if (!(props->libraries_inbuilt || app_libs_state)) {
			smc_id = QTI_SYSCALL_CREATE_SMC_ID(QTI_OWNER_QSEE_OS,
					QTI_SVC_APP_MGR, QTI_CMD_LOAD_LIB);
			cmd_id = QSEE_LOAD_SERV_IMAGE_COMMAND;
			req_size = sizeof(struct qseecom_load_lib_ireq);
			if (load_request(dev, smc_id, cmd_id, req_size))
				pr_info("Loading app libs failed\n");
			else
				app_libs_state = 1;
			if (props->logging_support_enabled) {
				if (qtidbg_register_qsee_log_buf(dev))
					pr_info("Registering log buf failed\n");
			}
		} else {
			pr_info("Libraries are either already loaded or are inbuilt in this platform\n");
		}
	} else if (load_cmd == 1) {
		if (props->libraries_inbuilt || app_libs_state) {
			if (!app_state) {
				smc_id = QTI_SYSCALL_CREATE_SMC_ID(
						QTI_OWNER_QSEE_OS, QTI_SVC_APP_MGR,
						QTI_CMD_LOAD_APP_ID);
				cmd_id = QSEOS_APP_START_COMMAND;
				req_size = sizeof(struct qseecom_load_app_ireq);
				if (load_request(dev, smc_id, cmd_id, req_size))
					pr_info("Loading app failed\n");
				else
					app_state = 1;
			} else {
				pr_info("App already loaded...\n");
			}
		} else {
			if (!app_libs_state)
				pr_info("App libs must be loaded first\n");
			if (!props->libraries_inbuilt)
				pr_info("App libs are not inbuilt in this platform\n");
		}
	} else if (load_cmd == 2) {
		if (app_state) {
			if (qseecom_unload_app())
				pr_info("App unload failed\n");
			else
				app_state = 0;
		} else {
			pr_info("App already unloaded...\n");
		}
	} else {
		pr_info("Echo 0 to load app libs if its not inbuilt\n");
		pr_info("Echo 1 to load app if its not already loaded\n");
		pr_info("Echo 2 to unload app if its already loaded\n");
	}

	return count;
}

static ssize_t
store_crypto_input(struct device *dev, struct device_attribute *attr,
		const char *buf, size_t count)
{
	qtiapp_test(dev, NULL, NULL, 0, 4);
	return count;
}

static ssize_t
store_log_bitmask_input(struct device *dev, struct device_attribute *attr,
		const char *buf, size_t count)
{
	qtiapp_test(dev, NULL, NULL, 0, QTI_APP_LOG_BITMASK_TEST_ID);
	return count;
}

static ssize_t
store_fuse_input(struct device *dev, struct device_attribute *attr,
		const char *buf, size_t count)
{
	qtiapp_test(dev, NULL, NULL, 0, QTI_APP_FUSE_TEST_ID);
	return count;
}

static ssize_t
store_misc_input(struct device *dev, struct device_attribute *attr,
		const char *buf, size_t count)
{
	qtiapp_test(dev, NULL, NULL, 0, QTI_APP_MISC_TEST_ID);
	return count;
}

static ssize_t
store_addr_fuse_write_qtiapp(struct device *dev, struct device_attribute *attr,
			const char *buf, size_t count)
{
	unsigned long long val;

	if (kstrtoull(buf, 0, &val))
		return -EINVAL;

	fuse_addr = val;

	return count;
}
static ssize_t
store_value_fuse_write_qtiapp(struct device *dev, struct device_attribute *attr,
			const char *buf, size_t count)
{
	unsigned long long val;

	if (kstrtoull(buf, 0, &val))
		return -EINVAL;

	if(val > MAX_FUSE_WRITE_VALUE) {
		pr_err("\nInvalid input: %llu\n", val);
		return -EINVAL;
	}
	fuse_value = val;

	return count;
}
static ssize_t
store_fec_enable_fuse_write_qtiapp(struct device *dev, struct device_attribute *attr,
			const char *buf, size_t count)
{
	unsigned long long val;

	if (kstrtoull(buf, 10, &val))
		return -EINVAL;

	if(val != 0 && val !=1) {
		pr_err("\nInvalid input: %llu\n", val);
		pr_err("fec enable should be either 0 or 1\n");
		return -EINVAL;
	}
	is_fec_enable = val;

	return count;
}

static ssize_t
store_blow_fuse_write_qtiapp(struct device *dev, struct device_attribute *attr,
			const char *buf, size_t count)
{
	uint32_t ret = 0;
	struct qti_storage_service_fuse_blow_req *req_ptr = NULL;
	uint64_t req_size = 0;
	size_t dma_buf_size = 0;
	dma_addr_t dma_req_addr = 0;

	unsigned long long val;

	if (kstrtoull(buf, 10, &val))
		return -EINVAL;

	if(val !=1) {
		pr_err("\nInvalid input: %llu\n", val);
		pr_err("echo 1 to blow the fuse\n");
		return -EINVAL;
	}

	dev = qdev;

	req_size = sizeof(struct qti_storage_service_fuse_blow_req);
	dma_buf_size = PAGE_SIZE * (1 << get_order(req_size));
	req_ptr = (struct qti_storage_service_fuse_blow_req *)
					dma_alloc_coherent(dev, dma_buf_size,
					&dma_req_addr, GFP_KERNEL);
	if (!req_ptr)
		return -ENOMEM;

	req_ptr->addr = fuse_addr;
	req_ptr->value = fuse_value;
	req_ptr->is_fec_enable = is_fec_enable;

	ret = qtiapp_test(dev, (void *)dma_req_addr, NULL, req_size,
					QTI_APP_FUSE_BLOW_ID);
	if (ret) {
		pr_err("Fuse Blow failed from QTI app with error code %d\n",ret);
	}
	else
		ret = count;

	dma_buf_size = PAGE_SIZE * (1 << get_order(req_size));
	dma_free_coherent(dev, dma_buf_size, req_ptr, dma_req_addr);

	return ret;
}


ssize_t store_tz_cmd(struct device *dev, struct device_attribute *attr,
			const char *buf, size_t count)
{
	int ret = 0;
	union qseecom_client_send_data_ireq send_data_req;
	struct qseecom_command_scm_resp scm_rsp;
	struct tz_cmd *tz_cmd;
	struct tz_cmd_req_hdr *req_hdr;
	struct tz_cmd_rsp_hdr *rsp_hdr;
	void *cmd_buf = NULL;
	void *req;
	void *rsp;
	uint32_t req_len;
	uint32_t rsp_len;
	dma_addr_t dma_buf = 0;
	dma_addr_t dma_req;
	dma_addr_t dma_rsp;
	long int temp_val = 0;

	if (count != sizeof(struct tz_cmd)) {
		pr_err("Invalid input length : %d", count);
		return -EINVAL;
	}

	dev = qdev;
	tz_cmd = (struct tz_cmd *)buf;
	req_len = sizeof(struct tz_cmd_req_hdr) + tz_cmd->req_len;
	rsp_len = sizeof(struct tz_cmd_rsp_hdr) + tz_cmd->rsp_len;

	if (req_len + rsp_len > MAX_TZ_CMD_BUFFER_SIZE) {
		pr_err("TZ command buffer too large\n");
		return -EINVAL;
	}

	cmd_buf = dma_alloc_coherent(dev, req_len + rsp_len, &dma_buf,
				     GFP_KERNEL);
	if (!cmd_buf) {
		pr_err("Failed to allocate page\n");
		return -ENOMEM;
	}

	req = cmd_buf;
	rsp = (void *)((uint8_t *)req + req_len);
	dma_req = dma_buf;
	dma_rsp = (dma_addr_t)((uint8_t *)dma_req + req_len);

	req_hdr = (struct tz_cmd_req_hdr *)req;
	req_hdr->cmd_id = tz_cmd->cmd_id;
	temp_val = tz_cmd->req_ptr;
	if ((ret = copy_from_user((uint8_t *)req + sizeof(struct tz_cmd_req_hdr),
				(void *)temp_val, tz_cmd->req_len)) != 0) {
		pr_err("Error copying TZ req, copy_from_user returned: %d\n",
		       ret);
		ret = -EFAULT;
		goto free_dma_buf;
	}
	send_data_req.v1.app_id = qsee_app_id;
	send_data_req.v1.req_ptr = dma_req;
	send_data_req.v1.rsp_ptr = dma_rsp;
	send_data_req.v1.req_len = req_len;
	send_data_req.v1.rsp_len = rsp_len;
	if ((ret = qti_scm_qseecom_send_data(&send_data_req,
				sizeof(send_data_req.v1), &scm_rsp,
				sizeof(scm_rsp))) != 0) {
		pr_err("qseecom_scm_call failed with err: %d\n", ret);
		ret = ret > 0 ? -EIO : ret;
		goto free_dma_buf;
	}
	if (scm_rsp.result == QSEOS_RESULT_INCOMPLETE) {
		pr_err("qseecom_scm_call incomplete\n");
		ret = -EIO;
		goto free_dma_buf;
	} else if (scm_rsp.result != QSEOS_RESULT_SUCCESS) {
		pr_err("qseecom_scm_call result %lu not supported\n",
				scm_rsp.result);
		ret = -EIO;
		goto free_dma_buf;
	}

	rsp_hdr = (struct tz_cmd_rsp_hdr *)rsp;

	temp_val = tz_cmd->out_status_ptr;
	if ((ret = copy_to_user((void *)temp_val, &rsp_hdr->status,
				sizeof(rsp_hdr->status))) != 0) {
		pr_err("Error copying TZ status, copy_to_user returned: %d\n", ret);
		ret = -EFAULT;
		goto free_dma_buf;
	}

	temp_val = tz_cmd->out_rsp_len_ptr;
	if ((ret = copy_to_user((void *)temp_val, &rsp_hdr->rsp_len,
				sizeof(rsp_hdr->rsp_len))) != 0) {
		pr_err("Error copying TZ rsp_len, copy_to_user returned: %d\n", ret);
		ret = -EFAULT;
		goto free_dma_buf;
	}

	temp_val = tz_cmd->rsp_ptr;
	if ((ret = copy_to_user((void *)temp_val,
				(uint8_t *)rsp + sizeof(struct tz_cmd_rsp_hdr),
				tz_cmd->rsp_len)) != 0) {
		pr_err("Error copying TZ rsp, copy_to_user returned: %d\n", ret);
		ret = -EFAULT;
		goto free_dma_buf;
	}

free_dma_buf:
	dma_free_coherent(dev, req_len + rsp_len, cmd_buf, dma_buf);

	return ret == 0 ? count : ret;
}


static int __init qtiapp_init(struct device *dev)
{
	int err;
	int i = 0;
	size_t dma_buf_size = 0;
	struct attribute **qtiapp_attrs = kzalloc((hweight_long(props->function)
				+ 1) * sizeof(*qtiapp_attrs), GFP_KERNEL);

	if (!qtiapp_attrs) {
		pr_err("Cannot allocate memory..tzapp\n");
		return -ENOMEM;
	}

	qtiapp_attrs[i++] = &dev_attr_load_start.attr;

	if (props->function & MUL)
		qtiapp_attrs[i++] = &dev_attr_basic_data.attr;

	if (props->function & CRYPTO)
		qtiapp_attrs[i++] = &dev_attr_crypto.attr;

	if (props->logging_support_enabled)
		qtiapp_attrs[i++] = &dev_attr_log_buf.attr;

	if (props->function & LOG_BITMASK)
		qtiapp_attrs[i++] = &dev_attr_log_bitmask.attr;

	if (props->function & FUSE)
		qtiapp_attrs[i++] = &dev_attr_fuse.attr;

	if (props->function & MISC)
		qtiapp_attrs[i++] = &dev_attr_misc.attr;

	if (props->function & TZ_CMD)
		qtiapp_attrs[i++] = &dev_attr_tz_cmd.attr;

	qtiapp_attrs[i] = NULL;

	qtiapp_attr_grp.attrs = qtiapp_attrs;

	qtiapp_kobj = kobject_create_and_add("tzapp", firmware_kobj);

	err = sysfs_create_group(qtiapp_kobj, &qtiapp_attr_grp);

	if (err) {
		kobject_put(qtiapp_kobj);
		return err;
	}

	if (props->function & AES_QTIAPP) {
                dma_buf_size = PAGE_SIZE *
                                (1 << get_order(MAX_ENCRYPTED_DATA_SIZE));
                buf_aes_sealed_buf = dma_alloc_coherent(dev, dma_buf_size,
                                        &dma_aes_sealed_buf, GFP_KERNEL);

                dma_buf_size = PAGE_SIZE *
                                (1 << get_order(MAX_PLAIN_DATA_SIZE));
                buf_aes_unsealed_buf = dma_alloc_coherent(dev, dma_buf_size,
                                        &dma_aes_unsealed_buf, GFP_KERNEL);

                dma_buf_size = PAGE_SIZE *
                                (1 << get_order(AES_BLOCK_SIZE));
                buf_aes_iv = dma_alloc_coherent(dev, dma_buf_size,
                                        &dma_aes_ivdata, GFP_KERNEL);

                if (!buf_aes_sealed_buf || !buf_aes_unsealed_buf || !buf_aes_iv) {
                        pr_err("Cannot allocate memory for aes crypt ops\n");

                        if (buf_aes_sealed_buf) {
                                dma_buf_size = PAGE_SIZE *
                                (1 << get_order(MAX_ENCRYPTED_DATA_SIZE));
                                dma_free_coherent(dev, dma_buf_size,
                                        buf_aes_sealed_buf,
                                        dma_aes_sealed_buf);
                        }

                        if (buf_aes_unsealed_buf) {
                                dma_buf_size = PAGE_SIZE *
                                (1 << get_order(MAX_PLAIN_DATA_SIZE));
                                dma_free_coherent(dev, dma_buf_size,
                                        buf_aes_unsealed_buf,
                                        dma_aes_unsealed_buf);
                        }

                        if (buf_aes_iv) {
                                dma_buf_size = PAGE_SIZE *
                                (1 << get_order(AES_BLOCK_SIZE));
                                dma_free_coherent(dev, dma_buf_size,
                                        buf_aes_iv,
                                        dma_aes_ivdata);
                        }

                } else {

                        aes_sealed_buf = (uint8_t*)buf_aes_sealed_buf;
                        aes_unsealed_buf = (uint8_t*)buf_aes_unsealed_buf;
                        aes_ivdata = (uint8_t*)buf_aes_iv;

                        qtiapp_aes_kobj = kobject_create_and_add("aes", qtiapp_kobj);

                        err = sysfs_create_group(qtiapp_aes_kobj, &qtiapp_aes_attr_grp);

                        if (err) {
                                kobject_put(qtiapp_aes_kobj);
                        }
                }
	}

	if (props->function & RSA_QTIAPP) {
                dma_buf_size = PAGE_SIZE *
                                (1 << get_order(MAX_RSA_PLAIN_DATA_SIZE));
                buf_rsa_unsealed_buf = dma_alloc_coherent(dev, dma_buf_size,
                                        &dma_rsa_unsealed_buf, GFP_KERNEL);
                buf_rsa_label = dma_alloc_coherent(dev, dma_buf_size,
                                        &dma_rsa_label, GFP_KERNEL);

                dma_buf_size = PAGE_SIZE *
                                (1 << get_order(MAX_RSA_SIGN_DATA_SIZE));
                buf_rsa_sealed_buf = dma_alloc_coherent(dev, dma_buf_size,
                                        &dma_rsa_sealed_buf, GFP_KERNEL);

                dma_buf_size = PAGE_SIZE *
                                (1 << get_order(RSA_KEY_SIZE_MAX));
                buf_rsa_n_key = dma_alloc_coherent(dev, dma_buf_size,
                                        &dma_rsa_n_key, GFP_KERNEL);
                buf_rsa_e_key = dma_alloc_coherent(dev, dma_buf_size,
                                        &dma_rsa_e_key, GFP_KERNEL);
                buf_rsa_d_key = dma_alloc_coherent(dev, dma_buf_size,
                                        &dma_rsa_d_key, GFP_KERNEL);

                if (!buf_rsa_unsealed_buf || !buf_rsa_sealed_buf
                        || !buf_rsa_label || !buf_rsa_n_key
                        || !buf_rsa_e_key || !buf_rsa_d_key) {

                        pr_err("Cannot allocate memory for rsa crypt ops\n");

                        if (buf_rsa_unsealed_buf) {
                                dma_buf_size = PAGE_SIZE *
                                (1 << get_order(MAX_RSA_PLAIN_DATA_SIZE));
                                dma_free_coherent(dev, dma_buf_size,
                                                        buf_rsa_unsealed_buf,
                                                        dma_rsa_unsealed_buf);
                        }

                        if (buf_rsa_sealed_buf) {
                                dma_buf_size = PAGE_SIZE *
                                (1 << get_order(MAX_RSA_SIGN_DATA_SIZE));
                                dma_free_coherent(dev, dma_buf_size,
                                                        buf_rsa_sealed_buf,
                                                        dma_rsa_sealed_buf);
                        }

                        if (buf_rsa_label) {
                                dma_buf_size = PAGE_SIZE *
                                (1 << get_order(MAX_RSA_PLAIN_DATA_SIZE));
                                dma_free_coherent(dev, dma_buf_size,
                                                        buf_rsa_label,
                                                        dma_rsa_label);
                        }

                        if (buf_rsa_n_key) {
                                dma_buf_size = PAGE_SIZE *
                                        (1 << get_order(RSA_KEY_SIZE_MAX));
                                dma_free_coherent(dev, dma_buf_size,
                                                        buf_rsa_n_key,
                                                        dma_rsa_n_key);
                        }

                        if (buf_rsa_e_key) {
                                dma_buf_size = PAGE_SIZE *
                                        (1 << get_order(RSA_KEY_SIZE_MAX));
                                dma_free_coherent(dev, dma_buf_size,
                                                        buf_rsa_e_key,
                                                        dma_rsa_e_key);
                        }

                        if (buf_rsa_d_key) {
                                dma_buf_size = PAGE_SIZE *
                                        (1 << get_order(RSA_KEY_SIZE_MAX));
                                dma_free_coherent(dev, dma_buf_size,
                                                        buf_rsa_d_key,
                                                        dma_rsa_d_key);
                        }

                } else {

                        rsa_unsealed_buf = (uint8_t*) buf_rsa_unsealed_buf;
                        rsa_sealed_buf = (uint8_t*) buf_rsa_sealed_buf;
                        rsa_label = (uint8_t*) buf_rsa_label;
                        rsa_n_key = (uint8_t*) buf_rsa_n_key;
                        rsa_e_key = (uint8_t*) buf_rsa_e_key;
                        rsa_d_key = (uint8_t*) buf_rsa_d_key;

                        qtiapp_rsa_kobj = kobject_create_and_add("rsa", qtiapp_kobj);

                        err = sysfs_create_group(qtiapp_rsa_kobj, &qtiapp_rsa_attr_grp);

                        if (err) {
                                kobject_put(qtiapp_rsa_kobj);
                        }
                }

	}

	if(props->function & FUSE_WRITE) {

		qtiapp_fuse_write_kobj = kobject_create_and_add("fuse_write", qtiapp_kobj);

		err = sysfs_create_group(qtiapp_fuse_write_kobj, &qtiapp_fuse_write_attr_grp);

		if (err) {
			kobject_put(qtiapp_fuse_write_kobj);
		}
	}

	return 0;
}

static int __init qseecom_probe(struct platform_device *pdev)
{
	struct device_node *of_node = pdev->dev.of_node;
        struct device_node *node;
        phys_addr_t node_addr;
        size_t node_size;
	struct resource qseecom_res;

	const struct of_device_id *id;
	unsigned int start = 0, size = 0;
	struct qsee_notify_app notify_app;
	struct qseecom_command_scm_resp resp;
	int ret = 0, ret1 = 0;

	if (!of_node)
		return -ENODEV;

	qdev = &pdev->dev;
	id = of_match_device(qseecom_of_table, &pdev->dev);

	if (!id)
		return -ENODEV;

	ret = of_property_read_u32(of_node, "mem-start", &start);
	ret1 = of_property_read_u32(of_node, "mem-size", &size);
	if (ret || ret1) {
		pr_err("No mem-region specified, using default\n");
		goto load;
	}
	/* 4KB adjustment is to ensure QTIApp does not overlap
	 * the region alloted for SMMU WAR
	 */
	if (of_property_read_bool(of_node, "notify-align")) {
		start += PAGE_SIZE;
		size -= PAGE_SIZE;
	}
	notify_app.applications_region_addr = start;
	notify_app.applications_region_size = size;
        node = of_parse_phandle(of_node, "memory-region", 0);

        if (node && !of_address_to_resource(node, 0, &qseecom_res)) {
                node_addr = qseecom_res.start;
                node_size = resource_size(&qseecom_res);

                ret = dma_declare_coherent_memory(qdev, node_addr,
                                                  node_addr, node_size);
                if (ret)
                        printk("\n Failed to declare dma coherent memory");
               else
                       printk("\n Successfully  declared dma coherent memory");
        } else {
               printk("\n mhi coherent pool is not reserved");
        }

	ret = qti_scm_qseecom_notify(&notify_app,
				     sizeof(struct qsee_notify_app),
				     &resp, sizeof(resp));
	if (ret) {
		pr_err("Notify App failed\n");
		return -1;
	}

load:
	props = ((struct qseecom_props *)id->data);

	sysfs_create_bin_file(firmware_kobj, &mdt_attr);
	sysfs_create_bin_file(firmware_kobj, &seg_attr);

	if (!qtiapp_init(qdev))
		pr_info("Loaded tzapp successfully!\n");
	else
		pr_info("Failed to load tzapp module\n");

	if (props->function & AES_SEC_KEY) {
		if (!sec_key_init(qdev))
			pr_info("Init. AES sec key feature successful!\n");
		else
			pr_info("Failed to load AES Sec Key feature\n");
	}

	if (props->function & RSA_SEC_KEY) {
		if (!rsa_sec_key_init(qdev))
			pr_info("Init. RSA sec key feature successful!\n");
		else
			pr_info("Failed to load RSA Sec Key feature\n");
	}

	return 0;
}

static int __exit qseecom_remove(struct platform_device *pdev)
{
        size_t dma_buf_size = 0;
        struct device *dev = &pdev->dev;


	if (app_state) {
		if (qseecom_unload_app())
			pr_err("App unload failed\n");
		else
			app_state = 0;
	}

	sysfs_remove_bin_file(firmware_kobj, &mdt_attr);
	sysfs_remove_bin_file(firmware_kobj, &seg_attr);

	sysfs_remove_group(qtiapp_kobj, &qtiapp_attr_grp);
	kobject_put(qtiapp_kobj);

	if (props->function & AES_SEC_KEY) {
		if (buf_key) {
			dma_buf_size = PAGE_SIZE *
					(1 << get_order(KEY_SIZE));
			dma_free_coherent(dev, dma_buf_size, buf_key,
							dma_key);
		}

		if (buf_key_blob) {
			dma_buf_size = PAGE_SIZE *
					(1 << get_order(KEY_BLOB_SIZE));
			dma_free_coherent(dev, dma_buf_size, buf_key_blob,
							dma_key_blob);
		}

		if (buf_sealed_buf) {
			dma_buf_size = PAGE_SIZE *
				(1 << get_order(MAX_ENCRYPTED_DATA_SIZE));
			dma_free_coherent(dev, dma_buf_size,
							buf_sealed_buf,
							dma_sealed_data);
		}

		if (buf_unsealed_buf) {
			dma_buf_size = PAGE_SIZE *
					(1 << get_order(MAX_PLAIN_DATA_SIZE));
			dma_free_coherent(dev, dma_buf_size,
							buf_unsealed_buf,
							dma_unsealed_data);
		}

		if (buf_iv) {
			dma_buf_size = PAGE_SIZE *
					(1 << get_order(AES_BLOCK_SIZE));
			dma_free_coherent(dev, dma_buf_size,
							buf_iv,
							dma_iv_data);
		}

		sysfs_remove_group(sec_kobj, &sec_key_attr_grp);
		kobject_put(sec_kobj);
	}

	if (props->function & RSA_SEC_KEY) {
		if (buf_rsa_key_blob) {
			dma_buf_size = PAGE_SIZE *
					(1 << get_order(RSA_KEY_BLOB_SIZE));
			dma_free_coherent(dev, dma_buf_size, buf_rsa_key_blob,
							dma_rsa_key_blob);
		}

		if (buf_rsa_import_modulus) {
			dma_buf_size = PAGE_SIZE *
					(1 << get_order(RSA_KEY_SIZE_MAX));
			dma_free_coherent(dev, dma_buf_size,
					buf_rsa_import_modulus,
					dma_rsa_import_modulus);
		}

		if (buf_rsa_import_public_exponent) {
			dma_buf_size = PAGE_SIZE *
					(1 << get_order(RSA_PUB_EXP_SIZE_MAX));
			dma_free_coherent(dev, dma_buf_size,
						buf_rsa_import_public_exponent,
						dma_rsa_import_public_exponent);
		}

		if (buf_rsa_import_pvt_exponent) {
			dma_buf_size = PAGE_SIZE *
					(1 << get_order(RSA_KEY_SIZE_MAX));
			dma_free_coherent(dev, dma_buf_size,
						buf_rsa_import_pvt_exponent,
						dma_rsa_import_pvt_exponent);
		}

		if (buf_rsa_sign_data_buf) {
			dma_buf_size = PAGE_SIZE *
				(1 << get_order(MAX_RSA_SIGN_DATA_SIZE));
			dma_free_coherent(dev, dma_buf_size,
						buf_rsa_sign_data_buf,
						dma_rsa_sign_data_buf);
		}

		if(buf_rsa_plain_data_buf) {
			dma_buf_size = PAGE_SIZE *
				(1 << get_order(MAX_RSA_PLAIN_DATA_SIZE));
			dma_free_coherent(dev, dma_buf_size,
						buf_rsa_plain_data_buf,
						dma_rsa_plain_data_buf);
		}

		sysfs_remove_group(rsa_sec_kobj, &rsa_sec_key_attr_grp);
		kobject_put(rsa_sec_kobj);
	}

	if (props->function & AES_QTIAPP) {
		if (buf_aes_sealed_buf) {
			dma_buf_size = PAGE_SIZE *
			(1 << get_order(MAX_ENCRYPTED_DATA_SIZE));
			dma_free_coherent(dev, dma_buf_size,
				buf_aes_sealed_buf,
				dma_aes_sealed_buf);
		}

		if (buf_aes_unsealed_buf) {
			dma_buf_size = PAGE_SIZE *
			(1 << get_order(MAX_PLAIN_DATA_SIZE));
			dma_free_coherent(dev, dma_buf_size,
				buf_aes_unsealed_buf,
				dma_aes_unsealed_buf);
		}

		if (buf_aes_iv) {
			dma_buf_size = PAGE_SIZE *
			(1 << get_order(AES_BLOCK_SIZE));
			dma_free_coherent(dev, dma_buf_size,
				buf_aes_iv,
				dma_aes_ivdata);
		}

		sysfs_remove_group(qtiapp_aes_kobj, &qtiapp_aes_attr_grp);
		kobject_put(qtiapp_aes_kobj);
	}

	if (props->function & RSA_QTIAPP) {
                if (buf_rsa_unsealed_buf) {
                        dma_buf_size = PAGE_SIZE *
                        (1 << get_order(MAX_RSA_PLAIN_DATA_SIZE));
                        dma_free_coherent(dev, dma_buf_size,
                                                buf_rsa_unsealed_buf,
                                                dma_rsa_unsealed_buf);
                }

                if (buf_rsa_sealed_buf) {
                        dma_buf_size = PAGE_SIZE *
                        (1 << get_order(MAX_RSA_SIGN_DATA_SIZE));
                        dma_free_coherent(dev, dma_buf_size,
                                                buf_rsa_sealed_buf,
                                                dma_rsa_sealed_buf);
                }

                if (buf_rsa_label) {
                        dma_buf_size = PAGE_SIZE *
                        (1 << get_order(MAX_RSA_PLAIN_DATA_SIZE));
                        dma_free_coherent(dev, dma_buf_size,
                                                buf_rsa_label,
                                                dma_rsa_label);
                }

                if (buf_rsa_n_key) {
                        dma_buf_size = PAGE_SIZE *
                                (1 << get_order(RSA_KEY_SIZE_MAX));
                        dma_free_coherent(dev, dma_buf_size,
                                                buf_rsa_n_key,
                                                dma_rsa_n_key);
                }

                if (buf_rsa_e_key) {
                       dma_buf_size = PAGE_SIZE *
                                (1 << get_order(RSA_KEY_SIZE_MAX));
                                dma_free_coherent(dev, dma_buf_size,
                                                buf_rsa_e_key,
                                                dma_rsa_e_key);
                }

                if (buf_rsa_d_key) {
                        dma_buf_size = PAGE_SIZE *
                                (1 << get_order(RSA_KEY_SIZE_MAX));
                        dma_free_coherent(dev, dma_buf_size,
                                                buf_rsa_d_key,
                                                dma_rsa_d_key);
                }

		sysfs_remove_group(qtiapp_rsa_kobj, &qtiapp_rsa_attr_grp);
		kobject_put(qtiapp_rsa_kobj);
	}

	if (props->function & FUSE_WRITE) {
		sysfs_remove_group(qtiapp_fuse_write_kobj,
						&qtiapp_fuse_write_attr_grp);
		kobject_put(qtiapp_fuse_write_kobj);
	}

	kfree(mdt_file);
	kfree(seg_file);

	kfree(qsee_sbuffer);

	if (app_libs_state) {
		if (unload_app_libs())
			pr_err("App libs unload failed\n");
		else
			app_libs_state = 0;
	}

	return 0;
}

static struct platform_driver qseecom_driver = {
	.remove = qseecom_remove,
	.driver = {
		.name = KBUILD_MODNAME,
		.of_match_table = qseecom_of_table,
	},
};
module_platform_driver_probe(qseecom_driver, qseecom_probe);

MODULE_DESCRIPTION("QSEECOM Driver");
MODULE_LICENSE("GPL v2");
