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

Commit 421f436f authored by Dinesh K Garg's avatar Dinesh K Garg
Browse files

crypto: ice: Add support for new FDE design



ICE driver provides storage driver info whether IO request requires
crypto operation. ICE driver tags all requests with BIO_INLINECRYPT
flag as needing crypto operation. Per new design all requests of
userdata partition would be tagged as needing crypto operation if
userspace has informed ICE driver about enabling FDE.

Change-Id: I97b18ae76601592900e6f9118ac7b1851e74b6ed
Signed-off-by: default avatarDinesh K Garg <dineshg@codeaurora.org>
parent 0df677ec
Loading
Loading
Loading
Loading
+51 −3
Original line number Diff line number Diff line
@@ -57,6 +57,14 @@
#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
#define QCOM_UD_FOOTER_SIZE	0x4000
#define QCOM_UD_FOOTER_SECS	(QCOM_UD_FOOTER_SIZE / QCOM_SECT_LEN_IN_BYTE)

static int ice_fde_flag;

struct ice_clk_info {
	struct list_head list;
	struct clk *clk;
@@ -130,13 +138,14 @@ static int qti_ice_setting_config(struct request *req,
		return -EINVAL;

	if ((short)(crypto_data->key_index) >= 0) {

		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 */
@@ -147,6 +156,12 @@ static int qti_ice_setting_config(struct request *req,

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

static int qcom_ice_enable_clocks(struct ice_device *, bool);

@@ -1431,8 +1446,11 @@ static int qcom_ice_config_start(struct platform_device *pdev,
		struct ice_data_setting *setting, bool async)
{
	struct ice_crypto_setting pfk_crypto_data = {0};
	struct ice_crypto_setting ice_data = {0};
	int ret = 0;
	bool is_pfe = false;
	unsigned long sec_end = 0;
	sector_t data_size;

	if (!pdev || !req) {
		pr_err("%s: Invalid params passed\n", __func__);
@@ -1467,6 +1485,36 @@ static int qcom_ice_config_start(struct platform_device *pdev,
				&pfk_crypto_data, setting);
	}

	if (ice_fde_flag && req->part && req->part->info
				&& req->part->info->volname[0]) {
		if (!strcmp(req->part->info->volname, "userdata")) {
			sec_end = req->part->start_sect + req->part->nr_sects -
					QCOM_UD_FOOTER_SECS;
			if ((req->__sector >= req->part->start_sect) &&
				(req->__sector < sec_end)) {
				/*
				 * Ugly hack to address non-block-size aligned
				 * userdata end address in eMMC based devices.
				 * for eMMC based devices, since sector and
				 * block sizes are not same i.e. 4K, it is
				 * possible that partition is not a multiple of
				 * block size. For UFS based devices sector
				 * size and block size are same. Hence ensure
				 * that data is within userdata partition using
				 * sector based calculation
				 */
				data_size = req->__data_len /
						QCOM_SECT_LEN_IN_BYTE;

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

	/*
	 * It is not an error. If target is not req-crypt based, all request
	 * from storage driver would come here to check if there is any ICE
+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
@@ -56,11 +56,13 @@ struct platform_device *qcom_ice_get_pdevice(struct device_node *node);

#ifdef CONFIG_CRYPTO_DEV_QCOM_ICE
int qcom_ice_setup_ice_hw(const char *storage_type, int enable);
void qcom_ice_set_fde_flag(int flag);
#else
static inline int qcom_ice_setup_ice_hw(const char *storage_type, int enable)
{
	return 0;
}
static inline void qcom_ice_set_fde_flag(int flag) {}
#endif

struct qcom_ice_variant_ops {