Merge "security: pfe: Adapt ICE engine setup call for eMMC"
This commit is contained in:
commit
c3bae3e0a6
4 changed files with 91 additions and 29 deletions
|
@ -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)
|
||||||
|
|
|
@ -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_ */
|
||||||
|
|
|
@ -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");
|
||||||
|
|
|
@ -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_ */
|
||||||
|
|
Loading…
Add table
Reference in a new issue