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

Commit 5e5e43c1 authored by Victor Zaharchuk's avatar Victor Zaharchuk
Browse files

msm: ice: Add support for ICE-FDE full disk encryption



Porting the FDE functionality from msm-4.14 branch commit
<b8f1b6a6> (Add support for block disk encryption).
Modified to be compatible with the 5.4 Kernel.

Test:
1. Basic_SimpleEncryption.
2. ModifyEnforcedFiles_FileCreationWithinEnforcedFolder.
3. PIN, pattern, password.
4. Verified filename encryption.
5. Generate/set ICE keys.
6. Enable ICE state for userdata partition.
7. Format the userdata partition.
8. Check if partition is encrypted via ICE.

Change-Id: I307d75b7cdf25f7a9ad2b4f948e64d13278e6f03
Signed-off-by: default avatarNeeraj Soni <neersoni@codeaurora.org>
Signed-off-by: default avatarVictor Zaharchuk <vzaharch@codeaurora.org>
parent 607818c6
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -44,6 +44,7 @@ CONFIG_SCSI_UFS_QCOM=m
CONFIG_SCSI_UFS_BSG=y
CONFIG_SCSI_UFS_CRYPTO_QTI=m
CONFIG_QTI_CRYPTO_COMMON=m
CONFIG_QTI_CRYPTO_FDE=m
CONFIG_PCI_MSM=m
CONFIG_MHI_BUS=m
CONFIG_MHI_UCI=m
+9 −7
Original line number Diff line number Diff line
@@ -36,7 +36,7 @@
#include <soc/qcom/qseecomi.h>
#include <asm/cacheflush.h>
#include "qseecom_kernel.h"
#include <crypto/ice.h>
#include <linux/crypto-qti-common.h>
#include <linux/delay.h>
#include <linux/signal.h>
#include <linux/compat.h>
@@ -90,7 +90,9 @@
#define TWO 2
#define QSEECOM_UFS_ICE_CE_NUM 10
#define QSEECOM_SDCC_ICE_CE_NUM 20
#define QSEECOM_ICE_FDE_KEY_INDEX 0

/* Assume the ice device contains 32 slots (0-31) and reserve the last one for the FDE  */
#define QSEECOM_ICE_FDE_KEY_INDEX 31

#define PHY_ADDR_4G	(1ULL<<32)

@@ -6412,9 +6414,9 @@ static int qseecom_enable_ice_setup(int usage)
	int ret = 0;

	if (usage == QSEOS_KM_USAGE_UFS_ICE_DISK_ENCRYPTION)
		ret = qcom_ice_setup_ice_hw("ufs", true);
		ret = crypto_qti_ice_setup_ice_hw("ufs", true);
	else if (usage == QSEOS_KM_USAGE_SDCC_ICE_DISK_ENCRYPTION)
		ret = qcom_ice_setup_ice_hw("sdcc", true);
		ret = crypto_qti_ice_setup_ice_hw("sdcc", true);

	return ret;
}
@@ -6424,9 +6426,9 @@ static int qseecom_disable_ice_setup(int usage)
	int ret = 0;

	if (usage == QSEOS_KM_USAGE_UFS_ICE_DISK_ENCRYPTION)
		ret = qcom_ice_setup_ice_hw("ufs", false);
		ret = crypto_qti_ice_setup_ice_hw("ufs", false);
	else if (usage == QSEOS_KM_USAGE_SDCC_ICE_DISK_ENCRYPTION)
		ret = qcom_ice_setup_ice_hw("sdcc", false);
		ret = crypto_qti_ice_setup_ice_hw("sdcc", false);

	return ret;
}
@@ -8289,7 +8291,7 @@ long qseecom_ioctl(struct file *file,
			pr_err("copy_from_user failed\n");
			return -EFAULT;
		}
		qcom_ice_set_fde_flag(ice_data.flag);
		crypto_qti_ice_set_fde_flag(ice_data.flag);
		break;
	}
	case QSEECOM_IOCTL_FBE_CLEAR_KEY: {
+64 −2
Original line number Diff line number Diff line
@@ -2,7 +2,7 @@
/*
 * UFS Crypto ops QTI implementation.
 *
 * Copyright (c) 2020, Linux Foundation. All rights reserved.
 * Copyright (c) 2020-2021, Linux Foundation. All rights reserved.
 */

#include <crypto/algapi.h>
@@ -22,6 +22,9 @@ static struct ufs_hba_crypto_variant_ops ufshcd_crypto_qti_variant_ops = {
	.disable = ufshcd_crypto_qti_disable,
	.resume = ufshcd_crypto_qti_resume,
	.debug = ufshcd_crypto_qti_debug,
#if IS_ENABLED(CONFIG_QTI_CRYPTO_FDE)
	.prepare_lrbp_crypto = ufshcd_crypto_qti_prep_lrbp_crypto,
#endif
};

static uint8_t get_data_unit_size_mask(unsigned int data_unit_size)
@@ -34,6 +37,59 @@ static uint8_t get_data_unit_size_mask(unsigned int data_unit_size)
	return data_unit_size / MINIMUM_DUN_SIZE;
}

#if IS_ENABLED(CONFIG_QTI_CRYPTO_FDE)
int ufshcd_crypto_qti_prep_lrbp_crypto(struct ufs_hba *hba,
				       struct scsi_cmnd *cmd,
				       struct ufshcd_lrb *lrbp)
{
	struct bio_crypt_ctx *bc;
	int ret = 0;
	struct ice_data_setting setting;
	bool bypass = true;
	short key_index = 0;
	struct request *req;

	lrbp->crypto_enable = false;
	req = cmd->request;
	if (!req || !req->bio)
		return ret;

	if (!bio_crypt_should_process(req)) {
		ret = crypto_qti_ice_config_start(req, &setting);
		if (!ret) {
			key_index = setting.crypto_data.key_index;
			bypass = (rq_data_dir(req) == WRITE) ?
				 setting.encr_bypass : setting.decr_bypass;
			lrbp->crypto_enable = !bypass;
			lrbp->crypto_key_slot = key_index;
			lrbp->data_unit_num = req->bio->bi_iter.bi_sector >>
					      ICE_CRYPTO_DATA_UNIT_4_KB;
		} else {
			pr_err("%s crypto config failed err = %d\n", __func__,
			       ret);
		}
		return ret;
	}
	bc = req->bio->bi_crypt_context;

	if (WARN_ON(!ufshcd_is_crypto_enabled(hba))) {
		/*
		 * Upper layer asked us to do inline encryption
		 * but that isn't enabled, so we fail this request.
		 */
		return -EINVAL;
	}
	if (!ufshcd_keyslot_valid(hba, bc->bc_keyslot))
		return -EINVAL;

	lrbp->crypto_enable = true;
	lrbp->crypto_key_slot = bc->bc_keyslot;
	lrbp->data_unit_num = bc->bc_dun[0];

	return 0;
}
#endif	//IS_ENABLED(CONFIG_QTI_CRYPTO_FDE)

static bool ice_cap_idx_valid(struct ufs_hba *hba,
			      unsigned int cap_idx)
{
@@ -194,6 +250,7 @@ static int ufshcd_hba_init_crypto_qti_spec(struct ufs_hba *hba,
	int err = 0;
	unsigned int crypto_modes_supported[BLK_ENCRYPTION_MODE_MAX];
	enum blk_crypto_mode_num blk_mode_num;
	unsigned int num_slots = 0;

	/* Default to disabling crypto */
	hba->caps &= ~UFSHCD_CAP_CRYPTO;
@@ -242,7 +299,12 @@ static int ufshcd_hba_init_crypto_qti_spec(struct ufs_hba *hba,
			hba->crypto_cap_array[cap_idx].sdus_mask * 512;
	}

	hba->ksm = keyslot_manager_create(hba->dev, ufshcd_num_keyslots(hba),
	num_slots = ufshcd_num_keyslots(hba);
#if IS_ENABLED(CONFIG_QTI_CRYPTO_FDE)
	if (num_slots > 0)
		--num_slots;
#endif
	hba->ksm = keyslot_manager_create(hba->dev, num_slots,
				ksm_ops, BLK_CRYPTO_FEATURE_WRAPPED_KEYS,
				crypto_modes_supported, hba);

+7 −1
Original line number Diff line number Diff line
/* SPDX-License-Identifier: GPL-2.0-only */
/*
 * Copyright (c) 2020, The Linux Foundation. All rights reserved.
 * Copyright (c) 2020-2021, The Linux Foundation. All rights reserved.
 */

#ifndef _UFSHCD_CRYPTO_QTI_H
@@ -34,6 +34,12 @@ int ufshcd_crypto_qti_suspend(struct ufs_hba *hba, enum ufs_pm_op pm_op);

int ufshcd_crypto_qti_resume(struct ufs_hba *hba, enum ufs_pm_op pm_op);

#if IS_ENABLED(CONFIG_QTI_CRYPTO_FDE)
int ufshcd_crypto_qti_prep_lrbp_crypto(struct ufs_hba *hba,
				       struct scsi_cmnd *cmd,
				       struct ufshcd_lrb *lrbp);
#endif

#if IS_ENABLED(CONFIG_SCSI_UFS_CRYPTO_QTI)
void ufshcd_crypto_qti_set_vops(struct ufs_hba *hba);
#else
+9 −0
Original line number Diff line number Diff line
@@ -1178,6 +1178,15 @@ config QTI_CRYPTO_TZ
	 programmed and managed through SCM calls to TZ where ICE driver
	 will configure keys.

config QTI_CRYPTO_FDE
	tristate "Enable common crypto functionality used for FDE"
	depends on QTI_CRYPTO_COMMON
	help
	 Say 'Y' to enable hardware Full Disk Encryption implementation to be used by
	 different storage layers such as UFS. Enabling the FDE will reserve one slot
	 of KSM(Key Slot Manager) for the FDE. Making one less slot available for FBE
	 (File based encryption) in case both encryption mechanism are enabled on device.

config QTI_HW_KEY_MANAGER
	tristate "Enable QTI Hardware Key Manager for storage encryption"
	default n
Loading