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: Andrey Markovytch <andreym@codeaurora.org>
This commit is contained in:
parent
8928f8683b
commit
f707680de8
3 changed files with 49 additions and 19 deletions
|
@ -39,7 +39,6 @@
|
||||||
/* #define DEBUG 1 */
|
/* #define DEBUG 1 */
|
||||||
#define pr_fmt(fmt) "pfk [%s]: " fmt, __func__
|
#define pr_fmt(fmt) "pfk [%s]: " fmt, __func__
|
||||||
|
|
||||||
|
|
||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
#include <linux/fs.h>
|
#include <linux/fs.h>
|
||||||
#include <linux/errno.h>
|
#include <linux/errno.h>
|
||||||
|
@ -273,7 +272,7 @@ static int pfk_parse_cipher(const unsigned char *cipher,
|
||||||
return -EPERM;
|
return -EPERM;
|
||||||
|
|
||||||
if (!strcmp(cipher, PFK_SUPPORTED_CIPHER) == 0) {
|
if (!strcmp(cipher, PFK_SUPPORTED_CIPHER) == 0) {
|
||||||
pr_err("not supported alghoritm\n");
|
pr_debug("not supported alghoritm %s\n", cipher);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -404,15 +403,17 @@ int pfk_load_key(const struct bio *bio, struct ice_crypto_setting *ice_setting)
|
||||||
}
|
}
|
||||||
|
|
||||||
cipher = ecryptfs_get_cipher(ecryptfs_data);
|
cipher = ecryptfs_get_cipher(ecryptfs_data);
|
||||||
if (!key) {
|
if (!cipher) {
|
||||||
pr_err("could not parse key from ecryptfs\n");
|
pr_err("could not parse key from ecryptfs\n");
|
||||||
ret = -EINVAL;
|
ret = -EINVAL;
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = pfk_parse_cipher(cipher, &algo_mode);
|
ret = pfk_parse_cipher(cipher, &algo_mode);
|
||||||
if (ret != 0)
|
if (ret != 0) {
|
||||||
|
pr_debug("not supported cipher\n");
|
||||||
return ret;
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
ret = pfk_key_size_to_key_type(key_size, &key_size_type);
|
ret = pfk_key_size_to_key_type(key_size, &key_size_type);
|
||||||
if (ret != 0)
|
if (ret != 0)
|
||||||
|
@ -583,8 +584,11 @@ static void pfk_open_cb(struct inode *inode, void *ecryptfs_data)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (0 != pfk_parse_cipher(cipher, NULL))
|
if (0 != pfk_parse_cipher(cipher, NULL)) {
|
||||||
|
pr_debug("open_cb: not supported cipher\n");
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
if (0 != pfk_key_size_to_key_type(key_size, NULL))
|
if (0 != pfk_key_size_to_key_type(key_size, NULL))
|
||||||
return;
|
return;
|
||||||
|
@ -618,7 +622,7 @@ static void pfk_release_cb(struct inode *inode)
|
||||||
|
|
||||||
data = pfk_get_ecryptfs_data(inode);
|
data = pfk_get_ecryptfs_data(inode);
|
||||||
if (!data) {
|
if (!data) {
|
||||||
pr_err("could not get ecryptfs data from inode\n");
|
pr_debug("could not get ecryptfs data from inode\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -22,6 +22,7 @@
|
||||||
#include <soc/qcom/scm.h>
|
#include <soc/qcom/scm.h>
|
||||||
#include <linux/device-mapper.h>
|
#include <linux/device-mapper.h>
|
||||||
#include <soc/qcom/qseecomi.h>
|
#include <soc/qcom/qseecomi.h>
|
||||||
|
#include <crypto/ice.h>
|
||||||
#include "pfk_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);
|
ret = scm_call2_atomic(smc_id, &desc);
|
||||||
pr_debug(" %s , ret = %d\n", __func__, ret);
|
pr_debug(" %s , ret = %d\n", __func__, ret);
|
||||||
if (ret)
|
if (ret) {
|
||||||
pr_err("%s: Error: 0x%x\n", __func__, 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;
|
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.arginfo = TZ_ES_INVALIDATE_ICE_KEY_PARAM_ID;
|
||||||
desc.args[0] = index;
|
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);
|
ret = scm_call2_atomic(smc_id, &desc);
|
||||||
|
|
||||||
|
qcom_ice_setup_ice_hw("ufs", false);
|
||||||
|
|
||||||
pr_debug(" %s , ret = %d\n", __func__, ret);
|
pr_debug(" %s , ret = %d\n", __func__, ret);
|
||||||
if (ret)
|
if (ret)
|
||||||
pr_err("%s: Error: 0x%x\n", __func__, ret);
|
pr_err("%s: Error: 0x%x\n", __func__, ret);
|
||||||
|
|
|
@ -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
|
* kc_clear_entry() - clear the key from entry and remove the key from ICE
|
||||||
*
|
*
|
||||||
* @entry: pointer to entry
|
* @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
|
* Securely wipe and release the key memory, remove the key from ICE
|
||||||
* Should be invoked under lock
|
* 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)
|
if (!entry)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (clear_qscee)
|
|
||||||
qti_pfk_ice_invalidate_key(entry->key_index);
|
|
||||||
|
|
||||||
memset(entry->key, 0, entry->key_size);
|
memset(entry->key, 0, entry->key_size);
|
||||||
memset(entry->salt, 0, entry->salt_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;
|
int ret = 0;
|
||||||
|
|
||||||
kc_clear_entry(entry, false);
|
kc_clear_entry(entry);
|
||||||
|
|
||||||
memcpy(entry->key, key, key_size);
|
memcpy(entry->key, key, key_size);
|
||||||
entry->key_size = 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:
|
err:
|
||||||
|
|
||||||
kc_clear_entry(entry, true);
|
kc_clear_entry(entry);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
|
@ -411,9 +407,11 @@ int pfk_kc_remove_key_with_salt(const unsigned char *key, size_t key_size,
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
kc_clear_entry(entry, true);
|
kc_clear_entry(entry);
|
||||||
spin_unlock(&kc_lock);
|
spin_unlock(&kc_lock);
|
||||||
|
|
||||||
|
qti_pfk_ice_invalidate_key(entry->key_index);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -432,6 +430,8 @@ int pfk_kc_remove_key(const unsigned char *key, size_t key_size)
|
||||||
{
|
{
|
||||||
struct kc_entry *entry = NULL;
|
struct kc_entry *entry = NULL;
|
||||||
int index = 0;
|
int index = 0;
|
||||||
|
int temp_indexes[PFK_KC_TABLE_SIZE] = {0};
|
||||||
|
int i = 0;
|
||||||
|
|
||||||
if (!kc_is_ready())
|
if (!kc_is_ready())
|
||||||
return -ENODEV;
|
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)
|
if (key_size != PFK_KC_KEY_SIZE)
|
||||||
return -EPERM;
|
return -EPERM;
|
||||||
|
|
||||||
|
memset(temp_indexes, -1, sizeof(temp_indexes));
|
||||||
|
|
||||||
spin_lock(&kc_lock);
|
spin_lock(&kc_lock);
|
||||||
|
|
||||||
entry = kc_find_key_at_index(key, key_size, NULL, 0, &index);
|
entry = kc_find_key_at_index(key, key_size, NULL, 0, &index);
|
||||||
if (!entry) {
|
if (!entry) {
|
||||||
pr_err("key does not exist\n");
|
pr_debug("key does not exist\n");
|
||||||
spin_unlock(&kc_lock);
|
spin_unlock(&kc_lock);
|
||||||
return -EINVAL;
|
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 */
|
/* let's clean additional entries with the same key if there are any */
|
||||||
do {
|
do {
|
||||||
|
@ -459,11 +462,17 @@ int pfk_kc_remove_key(const unsigned char *key, size_t key_size)
|
||||||
if (!entry)
|
if (!entry)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
kc_clear_entry(entry, true);
|
temp_indexes[i++] = entry->key_index;
|
||||||
|
|
||||||
|
kc_clear_entry(entry);
|
||||||
|
|
||||||
} while (true);
|
} while (true);
|
||||||
|
|
||||||
spin_unlock(&kc_lock);
|
spin_unlock(&kc_lock);
|
||||||
|
|
||||||
|
for (i--; i >= 0 ; i--)
|
||||||
|
qti_pfk_ice_invalidate_key(temp_indexes[i]);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -482,8 +491,12 @@ void pfk_kc_clear(void)
|
||||||
spin_lock(&kc_lock);
|
spin_lock(&kc_lock);
|
||||||
for (i = 0; i < PFK_KC_TABLE_SIZE; i++) {
|
for (i = 0; i < PFK_KC_TABLE_SIZE; i++) {
|
||||||
entry = &(kc_table[i]);
|
entry = &(kc_table[i]);
|
||||||
kc_clear_entry(entry, true);
|
kc_clear_entry(entry);
|
||||||
}
|
}
|
||||||
spin_unlock(&kc_lock);
|
spin_unlock(&kc_lock);
|
||||||
|
|
||||||
|
for (i = 0; i < PFK_KC_TABLE_SIZE; i++)
|
||||||
|
qti_pfk_ice_invalidate_key(entry->key_index);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue