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

Commit 1cb80a2c authored by Andrey Markovytch's avatar Andrey Markovytch
Browse files

PFK: fixed bug where key was cleared without turning on clocks first



ICE clocks need to be turned on to clear the key, fixed

Change-Id: I1cd5a10899c2f128b138fe380beb34a5a310fa05
Signed-off-by: default avatarAndrey Markovytch <andreym@codeaurora.org>
parent 1a45a811
Loading
Loading
Loading
Loading
+10 −6
Original line number Diff line number Diff line
@@ -39,7 +39,6 @@
/* #define DEBUG 1 */
#define pr_fmt(fmt)	"pfk [%s]: " fmt, __func__


#include <linux/module.h>
#include <linux/fs.h>
#include <linux/errno.h>
@@ -283,7 +282,7 @@ static int pfk_parse_cipher(const unsigned char *cipher,
		return -EPERM;

	if (!strcmp(cipher, PFK_SUPPORTED_CIPHER) == 0) {
		pr_err("not supported alghoritm\n");
		pr_debug("not supported alghoritm %s\n", cipher);
		return -EINVAL;
	}

@@ -414,15 +413,17 @@ int pfk_load_key(const struct bio *bio, struct ice_crypto_setting *ice_setting)
	}

	cipher = ecryptfs_get_cipher(ecryptfs_data);
	if (!key) {
	if (!cipher) {
		pr_err("could not parse key from ecryptfs\n");
		ret = -EINVAL;
		goto end;
	}

	ret = pfk_parse_cipher(cipher, &algo_mode);
	if (ret != 0)
	if (ret != 0) {
		pr_debug("not supported cipher\n");
		return ret;
	}

	ret = pfk_key_size_to_key_type(key_size, &key_size_type);
	if (ret != 0)
@@ -593,8 +594,11 @@ static void pfk_open_cb(struct inode *inode, void *ecryptfs_data)
		return;
	}

	if (0 != pfk_parse_cipher(cipher, NULL))
	if (0 != pfk_parse_cipher(cipher, NULL)) {
		pr_debug("open_cb: not supported cipher\n");
		return;
	}


	if (0 != pfk_key_size_to_key_type(key_size, NULL))
		return;
@@ -628,7 +632,7 @@ static void pfk_release_cb(struct inode *inode)

	data = pfk_get_ecryptfs_data(inode);
	if (!data) {
		pr_err("could not get ecryptfs data from inode\n");
		pr_debug("could not get ecryptfs data from inode\n");
		return;
	}

+14 −1
Original line number Diff line number Diff line
@@ -22,6 +22,7 @@
#include <soc/qcom/scm.h>
#include <linux/device-mapper.h>
#include <soc/qcom/qseecomi.h>
#include <crypto/ice.h>
#include "pfk_ice.h"


@@ -105,9 +106,15 @@ int qti_pfk_ice_set_key(uint32_t index, uint8_t *key, uint8_t *salt)

	ret = scm_call2_atomic(smc_id, &desc);
	pr_debug(" %s , ret = %d\n", __func__, ret);
	if (ret)
	if (ret) {
		pr_err("%s: Error: 0x%x\n", __func__, ret);

		smc_id = TZ_ES_INVALIDATE_ICE_KEY_ID;
		desc.arginfo = TZ_ES_INVALIDATE_ICE_KEY_PARAM_ID;
		desc.args[0] = index;
		scm_call2_atomic(smc_id, &desc);
	}

	return ret;
}

@@ -128,8 +135,14 @@ int qti_pfk_ice_invalidate_key(uint32_t index)
	desc.arginfo = TZ_ES_INVALIDATE_ICE_KEY_PARAM_ID;
	desc.args[0] = index;

	ret = qcom_ice_setup_ice_hw("ufs", true);
	if (ret)
		pr_err("%s: could not enable clocks: 0x%x\n", __func__, ret);

	ret = scm_call2_atomic(smc_id, &desc);

	qcom_ice_setup_ice_hw("ufs", false);

	pr_debug(" %s , ret = %d\n", __func__, ret);
	if (ret)
		pr_err("%s: Error: 0x%x\n", __func__, ret);
+25 −12
Original line number Diff line number Diff line
@@ -210,19 +210,15 @@ static void kc_update_timestamp(struct kc_entry *entry)
 * kc_clear_entry() - clear the key from entry and remove the key from ICE
 *
 * @entry: pointer to entry
 * @clear_qscee: if true, also clear the key from qscee
 *
 * Securely wipe and release the key memory, remove the key from ICE
 * Should be invoked under lock
 */
static void kc_clear_entry(struct kc_entry *entry, bool clear_qscee)
static void kc_clear_entry(struct kc_entry *entry)
{
	if (!entry)
		return;

	if (clear_qscee)
		qti_pfk_ice_invalidate_key(entry->key_index);

	memset(entry->key, 0, entry->key_size);
	memset(entry->salt, 0, entry->salt_size);

@@ -248,7 +244,7 @@ static int kc_replace_entry(struct kc_entry *entry, const unsigned char *key,
{
	int ret = 0;

	kc_clear_entry(entry, false);
	kc_clear_entry(entry);

	memcpy(entry->key, key, key_size);
	entry->key_size = key_size;
@@ -269,7 +265,7 @@ static int kc_replace_entry(struct kc_entry *entry, const unsigned char *key,

err:

	kc_clear_entry(entry, true);
	kc_clear_entry(entry);

	return ret;

@@ -411,9 +407,11 @@ int pfk_kc_remove_key_with_salt(const unsigned char *key, size_t key_size,
		return -EINVAL;
	}

	kc_clear_entry(entry, true);
	kc_clear_entry(entry);
	spin_unlock(&kc_lock);

	qti_pfk_ice_invalidate_key(entry->key_index);

	return 0;
}

@@ -432,6 +430,8 @@ int pfk_kc_remove_key(const unsigned char *key, size_t key_size)
{
	struct kc_entry *entry = NULL;
	int index = 0;
	int temp_indexes[PFK_KC_TABLE_SIZE] = {0};
	int i = 0;

	if (!kc_is_ready())
		return -ENODEV;
@@ -442,16 +442,19 @@ int pfk_kc_remove_key(const unsigned char *key, size_t key_size)
	if (key_size != PFK_KC_KEY_SIZE)
		return -EPERM;

	memset(temp_indexes, -1, sizeof(temp_indexes));

	spin_lock(&kc_lock);

	entry = kc_find_key_at_index(key, key_size, NULL, 0, &index);
	if (!entry) {
		pr_err("key does not exist\n");
		pr_debug("key does not exist\n");
		spin_unlock(&kc_lock);
		return -EINVAL;
	}

	kc_clear_entry(entry, true);
	temp_indexes[i++] = entry->key_index;
	kc_clear_entry(entry);

	/* let's clean additional entries with the same key if there are any */
	do {
@@ -459,11 +462,17 @@ int pfk_kc_remove_key(const unsigned char *key, size_t key_size)
		if (!entry)
			break;

		kc_clear_entry(entry, true);
		temp_indexes[i++] = entry->key_index;

		kc_clear_entry(entry);

	} while (true);

	spin_unlock(&kc_lock);

	for (i--; i >= 0 ; i--)
		qti_pfk_ice_invalidate_key(temp_indexes[i]);

	return 0;
}

@@ -482,8 +491,12 @@ void pfk_kc_clear(void)
	spin_lock(&kc_lock);
	for (i = 0; i < PFK_KC_TABLE_SIZE; i++) {
		entry = &(kc_table[i]);
		kc_clear_entry(entry, true);
		kc_clear_entry(entry);
	}
	spin_unlock(&kc_lock);

	for (i = 0; i < PFK_KC_TABLE_SIZE; i++)
		qti_pfk_ice_invalidate_key(entry->key_index);

}