diff options
Diffstat (limited to 'security/pfe')
-rw-r--r-- | security/pfe/pfk_ice.c | 23 | ||||
-rw-r--r-- | security/pfe/pfk_ice.h | 7 | ||||
-rw-r--r-- | security/pfe/pfk_kc.c | 88 | ||||
-rw-r--r-- | security/pfe/pfk_kc.h | 2 |
4 files changed, 91 insertions, 29 deletions
diff --git a/security/pfe/pfk_ice.c b/security/pfe/pfk_ice.c index 2f09d8801a96..facecedc3827 100644 --- a/security/pfe/pfk_ice.c +++ b/security/pfe/pfk_ice.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2015-2016, The Linux Foundation. All rights reserved. +/* Copyright (c) 2015-2017, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -64,7 +64,8 @@ uint8_t ice_key[ICE_KEY_SIZE]; uint8_t ice_salt[ICE_KEY_SIZE]; -int qti_pfk_ice_set_key(uint32_t index, uint8_t *key, uint8_t *salt) +int qti_pfk_ice_set_key(uint32_t index, uint8_t *key, uint8_t *salt, + char *storage_type) { struct scm_desc desc = {0}; int ret; @@ -84,6 +85,9 @@ int qti_pfk_ice_set_key(uint32_t index, uint8_t *key, uint8_t *salt) if (!tzbuf_key || !tzbuf_salt) return -ENOMEM; + if (storage_type == NULL) + return -EINVAL; + memset(tzbuf_key, 0, tzbuflen_key); memset(tzbuf_salt, 0, tzbuflen_salt); @@ -103,7 +107,8 @@ int qti_pfk_ice_set_key(uint32_t index, uint8_t *key, uint8_t *salt) desc.args[3] = virt_to_phys(tzbuf_salt); desc.args[4] = tzbuflen_salt; - ret = qcom_ice_setup_ice_hw("ufs", true); + ret = qcom_ice_setup_ice_hw((const char *)storage_type, true); + if (ret) { pr_err("%s: could not enable clocks: 0x%x\n", __func__, ret); return ret; @@ -111,7 +116,7 @@ int qti_pfk_ice_set_key(uint32_t index, uint8_t *key, uint8_t *salt) ret = scm_call2(smc_id, &desc); - qcom_ice_setup_ice_hw("ufs", false); + ret = qcom_ice_setup_ice_hw((const char *)storage_type, false); pr_debug(" %s , ret = %d\n", __func__, ret); if (ret) { @@ -127,7 +132,7 @@ int qti_pfk_ice_set_key(uint32_t index, uint8_t *key, uint8_t *salt) } -int qti_pfk_ice_invalidate_key(uint32_t index) +int qti_pfk_ice_invalidate_key(uint32_t index, char *storage_type) { struct scm_desc desc = {0}; int ret; @@ -137,13 +142,17 @@ int qti_pfk_ice_invalidate_key(uint32_t index) if (index < MIN_ICE_KEY_INDEX || index > MAX_ICE_KEY_INDEX) return -EINVAL; + if (storage_type == NULL) + return -EINVAL; + smc_id = TZ_ES_INVALIDATE_ICE_KEY_ID; pr_debug(" %s , smc_id = 0x%x\n", __func__, smc_id); desc.arginfo = TZ_ES_INVALIDATE_ICE_KEY_PARAM_ID; desc.args[0] = index; - ret = qcom_ice_setup_ice_hw("ufs", true); + ret = qcom_ice_setup_ice_hw((const char *)storage_type, true); + if (ret) { pr_err("%s: could not enable clocks: 0x%x\n", __func__, ret); return ret; @@ -151,7 +160,7 @@ int qti_pfk_ice_invalidate_key(uint32_t index) ret = scm_call2(smc_id, &desc); - qcom_ice_setup_ice_hw("ufs", false); + ret = qcom_ice_setup_ice_hw((const char *)storage_type, false); pr_debug(" %s , ret = %d\n", __func__, ret); if (ret) diff --git a/security/pfe/pfk_ice.h b/security/pfe/pfk_ice.h index fe3f2ad3950c..fb7c0d142953 100644 --- a/security/pfe/pfk_ice.h +++ b/security/pfe/pfk_ice.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2016, The Linux Foundation. All rights reserved. +/* Copyright (c) 2017, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -25,8 +25,9 @@ int pfk_ice_init(void); int pfk_ice_deinit(void); -int qti_pfk_ice_set_key(uint32_t index, uint8_t *key, uint8_t *salt); -int qti_pfk_ice_invalidate_key(uint32_t index); +int qti_pfk_ice_set_key(uint32_t index, uint8_t *key, uint8_t *salt, + char *storage_type); +int qti_pfk_ice_invalidate_key(uint32_t index, char *storage_type); #endif /* PFK_ICE_H_ */ diff --git a/security/pfe/pfk_kc.c b/security/pfe/pfk_kc.c index 39e67569a1dd..3a12dd172d04 100644 --- a/security/pfe/pfk_kc.c +++ b/security/pfe/pfk_kc.c @@ -23,6 +23,7 @@ * Empty entries always have the oldest timestamp. */ +#include <linux/module.h> #include <linux/mutex.h> #include <linux/spinlock.h> #include <crypto/ice.h> @@ -51,10 +52,12 @@ /** The maximum key and salt size */ #define PFK_MAX_KEY_SIZE PFK_KC_KEY_SIZE #define PFK_MAX_SALT_SIZE PFK_KC_SALT_SIZE +#define PFK_UFS "ufs" static DEFINE_SPINLOCK(kc_lock); static unsigned long flags; static bool kc_ready; +static char *s_type = "sdcc"; /** * enum pfk_kc_entry_state - state of the entry inside kc table @@ -404,7 +407,7 @@ static int kc_update_entry(struct kc_entry *entry, const unsigned char *key, kc_spin_unlock(); ret = qti_pfk_ice_set_key(entry->key_index, entry->key, - entry->salt); + entry->salt, s_type); kc_spin_lock(); return ret; @@ -524,7 +527,8 @@ int pfk_kc_load_key_start(const unsigned char *key, size_t key_size, kc_update_timestamp(entry); entry->state = ACTIVE_ICE_LOADED; - if (async) + if (async && (!strcmp(s_type, + (char *)PFK_UFS))) entry->loaded_ref_cnt++; break; @@ -544,7 +548,8 @@ int pfk_kc_load_key_start(const unsigned char *key, size_t key_size, * sync calls from within work thread do not pass * requests further to HW */ - if (async) + if (async && (!strcmp(s_type, + (char *)PFK_UFS))) entry->loaded_ref_cnt++; } @@ -556,9 +561,9 @@ int pfk_kc_load_key_start(const unsigned char *key, size_t key_size, case (ACTIVE_ICE_LOADED): kc_update_timestamp(entry); - if (async) + if (async && (!strcmp(s_type, + (char *)PFK_UFS))) entry->loaded_ref_cnt++; - break; case(SCM_ERROR): ret = entry->scm_error; @@ -616,24 +621,36 @@ void pfk_kc_load_key_end(const unsigned char *key, size_t key_size, return; } - ref_cnt = --entry->loaded_ref_cnt; + if (!strcmp(s_type, (char *)PFK_UFS)) { + ref_cnt = --entry->loaded_ref_cnt; - if (ref_cnt < 0) - pr_err("internal error, ref count should never be negative\n"); + if (ref_cnt < 0) + pr_err("internal error, ref count should never be negative\n"); - if (!ref_cnt) { + if (!ref_cnt) { + entry->state = INACTIVE; + /* + * wake-up invalidation if it's waiting + * for the entry to be released + */ + if (entry->thread_pending) { + tmp_pending = entry->thread_pending; + entry->thread_pending = NULL; + + kc_spin_unlock(); + wake_up_process(tmp_pending); + return; + } + } + } else { entry->state = INACTIVE; /* * wake-up invalidation if it's waiting * for the entry to be released - */ + */ if (entry->thread_pending) { - tmp_pending = entry->thread_pending; + wake_up_process(entry->thread_pending); entry->thread_pending = NULL; - - kc_spin_unlock(); - wake_up_process(tmp_pending); - return; } } @@ -689,7 +706,7 @@ int pfk_kc_remove_key_with_salt(const unsigned char *key, size_t key_size, kc_spin_unlock(); - qti_pfk_ice_invalidate_key(entry->key_index); + qti_pfk_ice_invalidate_key(entry->key_index, s_type); kc_spin_lock(); kc_entry_finish_invalidating(entry); @@ -771,7 +788,8 @@ int pfk_kc_remove_key(const unsigned char *key, size_t key_size) temp_indexes_size--; for (i = temp_indexes_size; i >= 0 ; i--) qti_pfk_ice_invalidate_key( - kc_entry_at_index(temp_indexes[i])->key_index); + kc_entry_at_index(temp_indexes[i])->key_index, + s_type); /* fall through */ res = 0; @@ -814,7 +832,8 @@ int pfk_kc_clear(void) kc_spin_unlock(); for (i = 0; i < PFK_KC_TABLE_SIZE; i++) - qti_pfk_ice_invalidate_key(kc_entry_at_index(i)->key_index); + qti_pfk_ice_invalidate_key(kc_entry_at_index(i)->key_index, + s_type); /* fall through */ res = 0; @@ -850,3 +869,36 @@ void pfk_kc_clear_on_reset(void) } kc_spin_unlock(); } + +static int pfk_kc_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, PFK_UFS, strlen(boot))) + *device = PFK_UFS; + + return 0; + } + return -EINVAL; +} + +static int __init pfk_kc_pre_init(void) +{ + return pfk_kc_find_storage_type(&s_type); +} + +static void __exit pfk_kc_exit(void) +{ + s_type = NULL; +} + +module_init(pfk_kc_pre_init); +module_exit(pfk_kc_exit); + +MODULE_LICENSE("GPL v2"); +MODULE_DESCRIPTION("Per-File-Key-KC driver"); diff --git a/security/pfe/pfk_kc.h b/security/pfe/pfk_kc.h index 0b0ec8825c15..dc4ad15b359d 100644 --- a/security/pfe/pfk_kc.h +++ b/security/pfe/pfk_kc.h @@ -27,7 +27,7 @@ int pfk_kc_remove_key_with_salt(const unsigned char *key, size_t key_size, int pfk_kc_remove_key(const unsigned char *key, size_t key_size); int pfk_kc_clear(void); void pfk_kc_clear_on_reset(void); - +extern char *saved_command_line; #endif /* PFK_KC_H_ */ |