Merge "security: pfe: Adapt ICE engine setup call for eMMC"

This commit is contained in:
Linux Build Service Account 2017-03-21 21:30:08 -07:00 committed by Gerrit - the friendly Code Review server
commit c3bae3e0a6
4 changed files with 91 additions and 29 deletions

View file

@ -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 * 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 * 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_key[ICE_KEY_SIZE];
uint8_t ice_salt[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}; struct scm_desc desc = {0};
int ret; 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) if (!tzbuf_key || !tzbuf_salt)
return -ENOMEM; return -ENOMEM;
if (storage_type == NULL)
return -EINVAL;
memset(tzbuf_key, 0, tzbuflen_key); memset(tzbuf_key, 0, tzbuflen_key);
memset(tzbuf_salt, 0, tzbuflen_salt); 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[3] = virt_to_phys(tzbuf_salt);
desc.args[4] = tzbuflen_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) { if (ret) {
pr_err("%s: could not enable clocks: 0x%x\n", __func__, ret); pr_err("%s: could not enable clocks: 0x%x\n", __func__, ret);
return 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); 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); pr_debug(" %s , ret = %d\n", __func__, ret);
if (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}; struct scm_desc desc = {0};
int ret; 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) if (index < MIN_ICE_KEY_INDEX || index > MAX_ICE_KEY_INDEX)
return -EINVAL; return -EINVAL;
if (storage_type == NULL)
return -EINVAL;
smc_id = TZ_ES_INVALIDATE_ICE_KEY_ID; smc_id = TZ_ES_INVALIDATE_ICE_KEY_ID;
pr_debug(" %s , smc_id = 0x%x\n", __func__, smc_id); pr_debug(" %s , smc_id = 0x%x\n", __func__, smc_id);
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); ret = qcom_ice_setup_ice_hw((const char *)storage_type, true);
if (ret) { if (ret) {
pr_err("%s: could not enable clocks: 0x%x\n", __func__, ret); pr_err("%s: could not enable clocks: 0x%x\n", __func__, ret);
return ret; return ret;
@ -151,7 +160,7 @@ int qti_pfk_ice_invalidate_key(uint32_t index)
ret = scm_call2(smc_id, &desc); 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); pr_debug(" %s , ret = %d\n", __func__, ret);
if (ret) if (ret)

View file

@ -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 * 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 * 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_init(void);
int pfk_ice_deinit(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_set_key(uint32_t index, uint8_t *key, uint8_t *salt,
int qti_pfk_ice_invalidate_key(uint32_t index); char *storage_type);
int qti_pfk_ice_invalidate_key(uint32_t index, char *storage_type);
#endif /* PFK_ICE_H_ */ #endif /* PFK_ICE_H_ */

View file

@ -23,6 +23,7 @@
* Empty entries always have the oldest timestamp. * Empty entries always have the oldest timestamp.
*/ */
#include <linux/module.h>
#include <linux/mutex.h> #include <linux/mutex.h>
#include <linux/spinlock.h> #include <linux/spinlock.h>
#include <crypto/ice.h> #include <crypto/ice.h>
@ -51,10 +52,12 @@
/** The maximum key and salt size */ /** The maximum key and salt size */
#define PFK_MAX_KEY_SIZE PFK_KC_KEY_SIZE #define PFK_MAX_KEY_SIZE PFK_KC_KEY_SIZE
#define PFK_MAX_SALT_SIZE PFK_KC_SALT_SIZE #define PFK_MAX_SALT_SIZE PFK_KC_SALT_SIZE
#define PFK_UFS "ufs"
static DEFINE_SPINLOCK(kc_lock); static DEFINE_SPINLOCK(kc_lock);
static unsigned long flags; static unsigned long flags;
static bool kc_ready; static bool kc_ready;
static char *s_type = "sdcc";
/** /**
* enum pfk_kc_entry_state - state of the entry inside kc table * 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(); kc_spin_unlock();
ret = qti_pfk_ice_set_key(entry->key_index, entry->key, ret = qti_pfk_ice_set_key(entry->key_index, entry->key,
entry->salt); entry->salt, s_type);
kc_spin_lock(); kc_spin_lock();
return ret; return ret;
@ -524,7 +527,8 @@ int pfk_kc_load_key_start(const unsigned char *key, size_t key_size,
kc_update_timestamp(entry); kc_update_timestamp(entry);
entry->state = ACTIVE_ICE_LOADED; entry->state = ACTIVE_ICE_LOADED;
if (async) if (async && (!strcmp(s_type,
(char *)PFK_UFS)))
entry->loaded_ref_cnt++; entry->loaded_ref_cnt++;
break; 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 * sync calls from within work thread do not pass
* requests further to HW * requests further to HW
*/ */
if (async) if (async && (!strcmp(s_type,
(char *)PFK_UFS)))
entry->loaded_ref_cnt++; 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): case (ACTIVE_ICE_LOADED):
kc_update_timestamp(entry); kc_update_timestamp(entry);
if (async) if (async && (!strcmp(s_type,
(char *)PFK_UFS)))
entry->loaded_ref_cnt++; entry->loaded_ref_cnt++;
break; break;
case(SCM_ERROR): case(SCM_ERROR):
ret = entry->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; return;
} }
ref_cnt = --entry->loaded_ref_cnt; if (!strcmp(s_type, (char *)PFK_UFS)) {
ref_cnt = --entry->loaded_ref_cnt;
if (ref_cnt < 0) if (ref_cnt < 0)
pr_err("internal error, ref count should never be negative\n"); 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; entry->state = INACTIVE;
/* /*
* wake-up invalidation if it's waiting * wake-up invalidation if it's waiting
* for the entry to be released * for the entry to be released
*/ */
if (entry->thread_pending) { if (entry->thread_pending) {
tmp_pending = entry->thread_pending; wake_up_process(entry->thread_pending);
entry->thread_pending = NULL; 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(); 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_spin_lock();
kc_entry_finish_invalidating(entry); 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--; temp_indexes_size--;
for (i = temp_indexes_size; i >= 0 ; i--) for (i = temp_indexes_size; i >= 0 ; i--)
qti_pfk_ice_invalidate_key( 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 */ /* fall through */
res = 0; res = 0;
@ -814,7 +832,8 @@ int pfk_kc_clear(void)
kc_spin_unlock(); kc_spin_unlock();
for (i = 0; i < PFK_KC_TABLE_SIZE; i++) 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 */ /* fall through */
res = 0; res = 0;
@ -850,3 +869,36 @@ void pfk_kc_clear_on_reset(void)
} }
kc_spin_unlock(); 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");

View file

@ -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_remove_key(const unsigned char *key, size_t key_size);
int pfk_kc_clear(void); int pfk_kc_clear(void);
void pfk_kc_clear_on_reset(void); void pfk_kc_clear_on_reset(void);
extern char *saved_command_line;
#endif /* PFK_KC_H_ */ #endif /* PFK_KC_H_ */