summaryrefslogtreecommitdiff
path: root/security/pfe
diff options
context:
space:
mode:
authorNeeraj Soni <neersoni@codeaurora.org>2017-03-20 17:01:21 +0530
committerNeeraj Soni <neersoni@codeaurora.org>2017-03-20 17:01:21 +0530
commit77eeced18f44fc3f24e9fe9d0fd1e9c5313bc06b (patch)
tree68a1ceb8118866bb022b804e392f6c8da12b0a9b /security/pfe
parent541fe938d28fd1d61c22f25c031ebf600af2c61d (diff)
security: pfe: Adapt ICE engine setup call for eMMC
Ice setup operation will work indpendent of storage type. Command line parameters will be read to find out storage type before doing ICE HW Configuration. Change-Id: I90a520f6d80e92505464fcde04980d858b34b455 Signed-off-by: Neeraj Soni <neersoni@codeaurora.org>
Diffstat (limited to 'security/pfe')
-rw-r--r--security/pfe/pfk_ice.c23
-rw-r--r--security/pfe/pfk_ice.h7
-rw-r--r--security/pfe/pfk_kc.c88
-rw-r--r--security/pfe/pfk_kc.h2
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_ */