Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b30ac1ff authored by Neeraj Soni's avatar Neeraj Soni
Browse files

crypto: Remove crypto block device from encryption path



Crypto block device created using request based device
mapper layer is not required for ICE based HW FDE since
data is encrypted inline.

Change-Id: I4ed0baf7191a1775f5c7971c5e9d2ccd630febf9
Signed-off-by: default avatarNeeraj Soni <neersoni@codeaurora.org>
parent e959c1ce
Loading
Loading
Loading
Loading
+55 −25
Original line number Diff line number Diff line
/* Copyright (c) 2014-2017, The Linux Foundation. All rights reserved.
/* Copyright (c) 2014-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
@@ -56,6 +56,9 @@
#define QCOM_ICE_MAX_BIST_CHECK_COUNT 100
#define QCOM_ICE_UFS		10
#define QCOM_ICE_SDCC		20
#define QCOM_ICE_ENCRYPT	0x1
#define QCOM_ICE_DECRYPT	0x2
#define QCOM_SECT_LEN_IN_BYTE	512

struct ice_clk_info {
	struct list_head list;
@@ -105,6 +108,11 @@ struct ice_device {
	ktime_t			ice_reset_complete_time;
};

static int ice_fde_flag;
static unsigned long userdata_start;
static unsigned long userdata_end;
static struct ice_crypto_setting ice_data;

static int qti_ice_setting_config(struct request *req,
		struct platform_device *pdev,
		struct ice_crypto_setting *crypto_data,
@@ -134,19 +142,49 @@ static int qti_ice_setting_config(struct request *req,
		memcpy(&setting->crypto_data, crypto_data,
				sizeof(setting->crypto_data));

		if (rq_data_dir(req) == WRITE)
		if (rq_data_dir(req) == WRITE &&
				(ice_fde_flag & QCOM_ICE_ENCRYPT))
			setting->encr_bypass = false;
		else if (rq_data_dir(req) == READ)
		else if (rq_data_dir(req) == READ &&
				(ice_fde_flag & QCOM_ICE_DECRYPT))
			setting->decr_bypass = false;
		else {
			/* Should I say BUG_ON */
			setting->encr_bypass = true;
			setting->decr_bypass = true;
			pr_debug("%s direction unknown", __func__);
		}
	}

	return 0;
}

void qcom_ice_set_fde_flag(int flag)
{
	ice_fde_flag = flag;
	pr_debug("%s read_write setting %d\n", __func__, ice_fde_flag);
}
EXPORT_SYMBOL(qcom_ice_set_fde_flag);

int qcom_ice_set_fde_conf(sector_t s_sector, sector_t size,
					int index, int mode)
{
	userdata_start = s_sector;
	userdata_end = s_sector + size;
	if (INT_MAX - s_sector < size) {
		WARN_ON(1);
		return -EINVAL;
	}
	ice_data.key_index = index;
	ice_data.algo_mode = mode;
	ice_data.key_size = ICE_CRYPTO_KEY_SIZE_256;
	ice_data.key_mode = ICE_CRYPTO_USE_LUT_SW_KEY;

	pr_debug("%s sector info set start %lu end %lu\n", __func__,
		userdata_start, userdata_end);
	return 0;
}
EXPORT_SYMBOL(qcom_ice_set_fde_conf);

static int qcom_ice_enable_clocks(struct ice_device *, bool);

@@ -1430,11 +1468,10 @@ static int qcom_ice_config_start(struct platform_device *pdev,
		struct request *req,
		struct ice_data_setting *setting, bool async)
{
	struct ice_crypto_setting *crypto_data;
	struct ice_crypto_setting pfk_crypto_data = {0};
	union map_info *info;
	int ret = 0;
	bool is_pfe = false;
	sector_t data_size;

	if (!pdev || !req) {
		pr_err("%s: Invalid params passed\n", __func__);
@@ -1455,7 +1492,6 @@ static int qcom_ice_config_start(struct platform_device *pdev,
		/* It is not an error to have a request with no  bio */
		return 0;
	}
    //pr_err("%s bio is %pK\n", __func__, req->bio);

	ret = pfk_load_key_start(req->bio, &pfk_crypto_data, &is_pfe, async);
	if (is_pfe) {
@@ -1470,28 +1506,22 @@ static int qcom_ice_config_start(struct platform_device *pdev,
				&pfk_crypto_data, setting);
	}

	/*
	 * info field in req->end_io_data could be used by mulitple dm or
	 * non-dm entities. To ensure that we are running operation on dm
	 * based request, check BIO_DONT_FREE flag
	 */
	if (bio_flagged(req->bio, BIO_INLINECRYPT)) {
		info = dm_get_rq_mapinfo(req);
		if (!info) {
			pr_debug("%s info not available in request\n",
				 __func__);
	if (ice_fde_flag == 0)
		return 0;
		}

		crypto_data = (struct ice_crypto_setting *)info->ptr;
		if (!crypto_data) {
			pr_err("%s crypto_data not available in request\n",
				 __func__);
			return -EINVAL;
		}
	if ((req->__sector >= userdata_start) &&
			(req->__sector < userdata_end)) {
	/*
	 * Ugly hack to address non-block-size aligned userdata end address in
	 * eMMC based devices.
	 */
		data_size = req->__data_len/QCOM_SECT_LEN_IN_BYTE;

		if ((req->__sector + data_size) > userdata_end)
			return 0;
		else
			return qti_ice_setting_config(req, pdev,
				crypto_data, setting);
				&ice_data, setting);
	}

	/*
+26 −1
Original line number Diff line number Diff line
/*
 * QTI Secure Execution Environment Communicator (QSEECOM) driver
 *
 * Copyright (c) 2012-2017, The Linux Foundation. All rights reserved.
 * Copyright (c) 2012-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
@@ -7012,6 +7012,31 @@ static inline long qseecom_ioctl(struct file *file,
			pr_err("failed qseecom_register_listener: %d\n", ret);
		break;
	}
	case QSEECOM_IOCTL_SET_ICE_INFO: {
		struct qseecom_ice_data_t ice_data;

		ret = copy_from_user(&ice_data, argp, sizeof(ice_data));
		if (ret) {
			pr_err("copy_from_user failed\n");
			return -EFAULT;
		}
		qcom_ice_set_fde_flag(ice_data.flag);
		break;
	}

	case QSEECOM_IOCTL_SET_ENCDEC_INFO: {
		struct qseecom_encdec_conf_t conf;

		ret = copy_from_user(&conf, argp, sizeof(conf));
		if (ret) {
			pr_err("copy_from_user failed\n");
			return -EFAULT;
		}
		ret = qcom_ice_set_fde_conf(conf.start_sector, conf.fs_size,
					conf.index, conf.mode);
		break;
	}

	case QSEECOM_IOCTL_UNREGISTER_LISTENER_REQ: {
		if ((data->listener.id == 0) ||
			(data->type != QSEECOM_LISTENER_SERVICE)) {
+3 −1
Original line number Diff line number Diff line
/* Copyright (c) 2014-2017, The Linux Foundation. All rights reserved.
/* Copyright (c) 2014-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
@@ -53,6 +53,8 @@ typedef void (*ice_error_cb)(void *, u32 error);

struct qcom_ice_variant_ops *qcom_ice_get_variant_ops(struct device_node *node);
struct platform_device *qcom_ice_get_pdevice(struct device_node *node);
void qcom_ice_set_fde_flag(int flag);
int qcom_ice_set_fde_conf(sector_t strt, sector_t size, int idx, int mode);

#ifdef CONFIG_CRYPTO_DEV_QCOM_ICE
int qcom_ice_setup_ice_hw(const char *storage_type, int enable);
+16 −0
Original line number Diff line number Diff line
@@ -277,6 +277,17 @@ struct qseecom_ce_info_req {
	struct qseecom_ce_pipe_entry ce_pipe_entry[MAX_CE_PIPE_PAIR_PER_UNIT];
};

struct qseecom_ice_data_t {
	int flag;
};

struct qseecom_encdec_conf_t {
	__le64 start_sector;
	size_t fs_size;
	int index;
	int mode;
};

#define SG_ENTRY_SZ		sizeof(struct qseecom_sg_entry)
#define SG_ENTRY_SZ_64BIT	sizeof(struct qseecom_sg_entry_64bit)

@@ -385,5 +396,10 @@ struct file;
#define QSEECOM_IOCTL_QUERY_CE_PIPE_INFO \
	_IOWR(QSEECOM_IOC_MAGIC, 42, struct qseecom_ce_info_req)

#define QSEECOM_IOCTL_SET_ICE_INFO \
	_IOWR(QSEECOM_IOC_MAGIC, 43, struct qseecom_ice_data_t)

#define QSEECOM_IOCTL_SET_ENCDEC_INFO \
	_IOWR(QSEECOM_IOC_MAGIC, 44, struct qseecom_encdec_conf_t)

#endif /* _UAPI_QSEECOM_H_ */