From f707680de8e70550be74c26e1d5b609143aba9b7 Mon Sep 17 00:00:00 2001 From: Andrey Markovytch Date: Tue, 4 Aug 2015 15:57:48 +0300 Subject: [PATCH] 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 --- security/pfe/pfk.c | 16 ++++++++++------ security/pfe/pfk_ice.c | 15 ++++++++++++++- security/pfe/pfk_kc.c | 37 +++++++++++++++++++++++++------------ 3 files changed, 49 insertions(+), 19 deletions(-) diff --git a/security/pfe/pfk.c b/security/pfe/pfk.c index 3c8e2f8fad41..277b75eb2469 100644 --- a/security/pfe/pfk.c +++ b/security/pfe/pfk.c @@ -39,7 +39,6 @@ /* #define DEBUG 1 */ #define pr_fmt(fmt) "pfk [%s]: " fmt, __func__ - #include #include #include @@ -273,7 +272,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; } @@ -404,15 +403,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) @@ -583,8 +584,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; @@ -618,7 +622,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; } diff --git a/security/pfe/pfk_ice.c b/security/pfe/pfk_ice.c index 1cb350296159..9d4961aa8330 100644 --- a/security/pfe/pfk_ice.c +++ b/security/pfe/pfk_ice.c @@ -22,6 +22,7 @@ #include #include #include +#include #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); diff --git a/security/pfe/pfk_kc.c b/security/pfe/pfk_kc.c index eff49d0315b5..919bde4b1190 100644 --- a/security/pfe/pfk_kc.c +++ b/security/pfe/pfk_kc.c @@ -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); + }