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

Commit 2d6fc51f authored by Neeraj Soni's avatar Neeraj Soni Committed by Jiten Patel
Browse files

Fix OTA issue with vts fixes for new fbe framework



Fixes for kernel encryption vts test need multiple encryption
flag support which needs additional changes to ensure IV is
generated and calculated correctly for all file systems and
storage types.

Ported and fixed the merged conflicts in cqhci-crypto-qti.c file
(cherry picked from kernel_msm-4.14 commit: 3309411)

Conflicts:
	drivers/mmc/host/cqhci-crypto-qti.c

Test:
1) Flashed Q meta, create multiple files under /data.
2) Build R (include changes topic: 660_OTA_FIXES) and flash
   APPS images of R except userdata and boot the device.
3) Device booted upto UI.
4) Files created with Q build retained.
5) Created new files under /data and checked retention across
   multiple re-boots.

Change-Id: I78ffe24be53056270caebcb6d37924c7c25c1ece
Signed-off-by: default avatarNeeraj Soni <neersoni@codeaurora.org>
Signed-off-by: default avatarJiten Patel <jitepate@codeaurora.org>
parent bed17f6d
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -50,6 +50,7 @@ struct default_key_c {
	struct blk_crypto_key key;
	bool is_hw_wrapped;
	u64 max_dun;
	bool set_dun;
};

static const struct dm_default_key_cipher *
@@ -120,6 +121,8 @@ static int default_key_ctr_optional(struct dm_target *ti,
			iv_large_sectors = true;
		} else if (!strcmp(opt_string, "wrappedkey_v0")) {
			dkc->is_hw_wrapped = true;
		} else if (!strcmp(opt_string, "set_dun")) {
			dkc->set_dun = true;
		} else {
			ti->error = "Invalid feature arguments";
			return -EINVAL;
+12 −1
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@
#include "sdhci-msm.h"
#include "cqhci-crypto-qti.h"
#include <linux/crypto-qti-common.h>
#include <linux/pm_runtime.h>

#define RAW_SECRET_SIZE 32
#define MINIMUM_DUN_SIZE 512
@@ -84,9 +85,12 @@ static int cqhci_crypto_qti_keyslot_program(struct keyslot_manager *ksm,
	crypto_alg_id = cqhci_crypto_cap_find(host, key->crypto_mode,
					       key->data_unit_size);

	pm_runtime_get_sync(&host->mmc->card->dev);

	if (!cqhci_is_crypto_enabled(host) ||
	    !cqhci_keyslot_valid(host, slot) ||
	    !ice_cap_idx_valid(host, crypto_alg_id)) {
		pm_runtime_put_sync(&host->mmc->card->dev);
		return -EINVAL;
	}

@@ -94,6 +98,7 @@ static int cqhci_crypto_qti_keyslot_program(struct keyslot_manager *ksm,

	if (!(data_unit_mask &
	      host->crypto_cap_array[crypto_alg_id].sdus_mask)) {
		pm_runtime_put_sync(&host->mmc->card->dev);
		return -EINVAL;
	}

@@ -102,6 +107,7 @@ static int cqhci_crypto_qti_keyslot_program(struct keyslot_manager *ksm,
	if (err)
		pr_err("%s: failed with error %d\n", __func__, err);

	pm_runtime_put_sync(&host->mmc->card->dev);
	return err;
}

@@ -111,15 +117,20 @@ static int cqhci_crypto_qti_keyslot_evict(struct keyslot_manager *ksm,
{
	int err = 0;
	struct cqhci_host *host = keyslot_manager_private(ksm);
	pm_runtime_get_sync(&host->mmc->card->dev);

	if (!cqhci_is_crypto_enabled(host) ||
	    !cqhci_keyslot_valid(host, slot))
	    !cqhci_keyslot_valid(host, slot)) {
		pm_runtime_put_sync(&host->mmc->card->dev);
		return -EINVAL;
	}

	err = crypto_qti_keyslot_evict(host->crypto_vops->priv, slot);
	if (err)
		pr_err("%s: failed with error %d\n", __func__, err);

	pm_runtime_put_sync(&host->mmc->card->dev);

	return err;
}

+6 −2
Original line number Diff line number Diff line
@@ -398,8 +398,12 @@ int ufshcd_prepare_lrbp_crypto_spec(struct ufs_hba *hba,

	lrbp->crypto_enable = true;
	lrbp->crypto_key_slot = bc->bc_keyslot;
	if (bc->is_ext4) {
		lrbp->data_unit_num = (u64)cmd->request->bio->bi_iter.bi_sector;
		lrbp->data_unit_num >>= 3;
	} else {
		lrbp->data_unit_num = bc->bc_dun[0];

	}
	return 0;
}
EXPORT_SYMBOL_GPL(ufshcd_prepare_lrbp_crypto_spec);
+12 −3
Original line number Diff line number Diff line
@@ -26,6 +26,7 @@
#include <linux/ratelimit.h>
#include <crypto/skcipher.h>
#include "fscrypt_private.h"
#include <linux/genhd.h>

static unsigned int num_prealloc_crypto_pages = 32;

@@ -87,9 +88,7 @@ void fscrypt_generate_iv(union fscrypt_iv *iv, u64 lblk_num,
#endif
	memset(iv, 0, ci->ci_mode->ivsize);

	if (flags & FSCRYPT_POLICY_FLAG_IV_INO_LBLK_64 ||
		((fscrypt_policy_contents_mode(&ci->ci_policy) ==
		  FSCRYPT_MODE_PRIVATE) && inlinecrypt)) {
	if (flags & FSCRYPT_POLICY_FLAG_IV_INO_LBLK_64) {
		WARN_ON_ONCE(lblk_num > U32_MAX);
		WARN_ON_ONCE(ci->ci_inode->i_ino > U32_MAX);
		lblk_num |= (u64)ci->ci_inode->i_ino << 32;
@@ -98,6 +97,16 @@ void fscrypt_generate_iv(union fscrypt_iv *iv, u64 lblk_num,
		lblk_num = (u32)(ci->ci_hashed_ino + lblk_num);
	} else if (flags & FSCRYPT_POLICY_FLAG_DIRECT_KEY) {
		memcpy(iv->nonce, ci->ci_nonce, FS_KEY_DERIVATION_NONCE_SIZE);
	} else if ((fscrypt_policy_contents_mode(&ci->ci_policy) ==
						 FSCRYPT_MODE_PRIVATE)
						 && inlinecrypt) {
		if (ci->ci_inode->i_sb->s_type->name) {
			if (!strcmp(ci->ci_inode->i_sb->s_type->name, "f2fs")) {
				WARN_ON_ONCE(lblk_num > U32_MAX);
				WARN_ON_ONCE(ci->ci_inode->i_ino > U32_MAX);
				lblk_num |= (u64)ci->ci_inode->i_ino << 32;
			}
		}
	}
	iv->lblk_num = cpu_to_le64(lblk_num);
}
+34 −0
Original line number Diff line number Diff line
@@ -42,11 +42,32 @@ static void fscrypt_get_devices(struct super_block *sb, int num_devs,
		sb->s_cop->get_devices(sb, devs);
}

#define SDHCI "sdhci"

static int fscrypt_find_storage_type(char **device)
{
	char boot[20] = {'\0'};
	char *match = (char *)strnstr(saved_command_line,
				      "androidboot.bootdevice=",
				      strlen(saved_command_line));
	if (match) {
		memcpy(boot, (match + strlen("androidboot.bootdevice=")),
			sizeof(boot) - 1);

		if (strnstr(boot, "sdhci", strlen(boot)))
			*device = SDHCI;

		return 0;
	}
	return -EINVAL;
}

static unsigned int fscrypt_get_dun_bytes(const struct fscrypt_info *ci)
{
	struct super_block *sb = ci->ci_inode->i_sb;
	unsigned int flags = fscrypt_policy_flags(&ci->ci_policy);
	int ino_bits = 64, lblk_bits = 64;
	char *s_type = "ufs";

	if (flags & FSCRYPT_POLICY_FLAG_DIRECT_KEY)
		return offsetofend(union fscrypt_iv, nonce);
@@ -57,6 +78,15 @@ static unsigned int fscrypt_get_dun_bytes(const struct fscrypt_info *ci)
	if (flags & FSCRYPT_POLICY_FLAG_IV_INO_LBLK_32)
		return sizeof(__le32);

	if (fscrypt_policy_contents_mode(&ci->ci_policy) ==
	    FSCRYPT_MODE_PRIVATE) {
		fscrypt_find_storage_type(&s_type);
		if (!strcmp(s_type, "sdhci"))
			return sizeof(__le32);
		else
			return sizeof(__le64);
	}

	/* Default case: IVs are just the file logical block number */
	if (sb->s_cop->get_ino_and_lblk_bits)
		sb->s_cop->get_ino_and_lblk_bits(sb, &ino_bits, &lblk_bits);
@@ -310,6 +340,10 @@ void fscrypt_set_bio_crypt_ctx(struct bio *bio, const struct inode *inode,

	fscrypt_generate_dun(ci, first_lblk, dun);
	bio_crypt_set_ctx(bio, &ci->ci_key.blk_key->base, dun, gfp_mask);
	if ((fscrypt_policy_contents_mode(&ci->ci_policy) ==
	    FSCRYPT_MODE_PRIVATE) &&
	    (!strcmp(inode->i_sb->s_type->name, "ext4")))
		bio->bi_crypt_context->is_ext4 = true;
}
EXPORT_SYMBOL_GPL(fscrypt_set_bio_crypt_ctx);

Loading