Update source to Armbian-dev-202610.A311Y3
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0+ OR MIT)
|
||||
|
||||
config AMLOGIC_EFUSE_UNIFYKEY
|
||||
tristate "Amlogic EUSE and UNIFYKEY support"
|
||||
tristate "Amlogic EFUSE and UNIFYKEY support"
|
||||
default n
|
||||
help
|
||||
amlogic EFUSE and UNIFYKEY glue driver
|
||||
@@ -22,7 +22,7 @@ config AMLOGIC_UNIFYKEY
|
||||
not choose by default
|
||||
|
||||
config AMLOGIC_EFUSE_BURN
|
||||
bool "Amlogic efuse pattern burn suppot"
|
||||
bool "Amlogic efuse pattern burn support"
|
||||
default n
|
||||
help
|
||||
en, if project need burn efuse pattern file, then
|
||||
@@ -34,5 +34,5 @@ config AMLOGIC_DEFENDKEY
|
||||
tristate "Amlogic defendkey driver support"
|
||||
default n
|
||||
help
|
||||
amlogic defendkey device driver
|
||||
not choose by default
|
||||
amlogic defendkey device driver
|
||||
not choose by default
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0+ OR MIT)
|
||||
|
||||
MODULE_NAME = amlogic-efuse-unifykey
|
||||
obj-$(CONFIG_AMLOGIC_EFUSE_UNIFYKEY) = $(MODULE_NAME).o
|
||||
obj-$(CONFIG_AMLOGIC_EFUSE_UNIFYKEY) += $(MODULE_NAME).o
|
||||
$(MODULE_NAME)-y += efuse_unifykey.o
|
||||
$(MODULE_NAME)-$(CONFIG_AMLOGIC_EFUSE) += efuse.o efuse_api.o
|
||||
$(MODULE_NAME)-$(CONFIG_AMLOGIC_EFUSE_BURN) += efuse_burn.o
|
||||
|
||||
@@ -20,41 +20,55 @@
|
||||
#include "efuse_burn.h"
|
||||
#include "defendkey.h"
|
||||
|
||||
#define EFUSE_BIT BIT(0)
|
||||
#define UNIFYKEY_BIT BIT(1)
|
||||
#define BURN_BIT BIT(2)
|
||||
#define DEFENDKEY_BIT BIT(3)
|
||||
|
||||
static unsigned int efuse_unifykey_init_mask;
|
||||
|
||||
static int __init efuse_unifykey_init(void)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = aml_efuse_init();
|
||||
if (ret)
|
||||
return ret;
|
||||
if (!ret)
|
||||
efuse_unifykey_init_mask |= EFUSE_BIT;
|
||||
|
||||
ret = aml_unifykeys_init();
|
||||
if (ret) {
|
||||
aml_efuse_exit();
|
||||
return ret;
|
||||
}
|
||||
if (!ret)
|
||||
efuse_unifykey_init_mask |= UNIFYKEY_BIT;
|
||||
|
||||
ret = aml_efuse_burn_init();
|
||||
if (ret) {
|
||||
aml_efuse_burn_exit();
|
||||
return ret;
|
||||
}
|
||||
if (!ret)
|
||||
efuse_unifykey_init_mask |= BURN_BIT;
|
||||
|
||||
ret = aml_defendkey_init();
|
||||
if (ret) {
|
||||
aml_efuse_burn_exit();
|
||||
return ret;
|
||||
}
|
||||
if (!ret)
|
||||
efuse_unifykey_init_mask |= DEFENDKEY_BIT;
|
||||
|
||||
if (efuse_unifykey_init_mask != (EFUSE_BIT | UNIFYKEY_BIT | BURN_BIT |
|
||||
DEFENDKEY_BIT))
|
||||
pr_err("efuse_unifykey: init incomplete, mask=0x%x, failed:%s%s%s%s\n",
|
||||
efuse_unifykey_init_mask,
|
||||
(efuse_unifykey_init_mask & EFUSE_BIT) ? "" : " efuse",
|
||||
(efuse_unifykey_init_mask & UNIFYKEY_BIT) ? "" : " unifykey",
|
||||
(efuse_unifykey_init_mask & BURN_BIT) ? "" : " burn",
|
||||
(efuse_unifykey_init_mask & DEFENDKEY_BIT) ? "" : " defendkey");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void __exit efuse_unifykey_exit(void)
|
||||
{
|
||||
aml_efuse_exit();
|
||||
aml_unifykeys_exit();
|
||||
aml_efuse_burn_exit();
|
||||
aml_defendkey_exit();
|
||||
if (efuse_unifykey_init_mask & DEFENDKEY_BIT)
|
||||
aml_defendkey_exit();
|
||||
if (efuse_unifykey_init_mask & BURN_BIT)
|
||||
aml_efuse_burn_exit();
|
||||
if (efuse_unifykey_init_mask & UNIFYKEY_BIT)
|
||||
aml_unifykeys_exit();
|
||||
if (efuse_unifykey_init_mask & EFUSE_BIT)
|
||||
aml_efuse_exit();
|
||||
}
|
||||
|
||||
module_init(efuse_unifykey_init);
|
||||
|
||||
@@ -246,8 +246,13 @@ static u32 Tlv_ReadObject(u8 *input, int32_t len,
|
||||
switch (tag) {
|
||||
case EMTLVOBJNAMESIZE:
|
||||
pcontent->namesize = *((u32 *)(input + idx));
|
||||
if (pcontent->namesize > MAX_OBJ_NAME_LEN - 1)
|
||||
goto tlv_readkeycontent_err;
|
||||
break;
|
||||
case EMTLVOBJNAME:
|
||||
if (pcontent->namesize == 0 ||
|
||||
pcontent->namesize > length)
|
||||
goto tlv_readkeycontent_err;
|
||||
memset(pcontent->name, 0, MAX_OBJ_NAME_LEN);
|
||||
memcpy(pcontent->name, input + idx, pcontent->namesize);
|
||||
break;
|
||||
@@ -266,6 +271,9 @@ static u32 Tlv_ReadObject(u8 *input, int32_t len,
|
||||
memcpy(pcontent->hashptr, input + idx, length);
|
||||
break;
|
||||
case EMTLVOBJDATABUF:
|
||||
if (pcontent->datasize == 0 ||
|
||||
pcontent->datasize > length)
|
||||
goto tlv_readkeycontent_err;
|
||||
pcontent->dataptr = kmalloc(pcontent->datasize,
|
||||
GFP_KERNEL);
|
||||
if (!pcontent->dataptr)
|
||||
@@ -278,10 +286,13 @@ static u32 Tlv_ReadObject(u8 *input, int32_t len,
|
||||
}
|
||||
idx += length;
|
||||
}
|
||||
if (pcontent->datasize && !pcontent->dataptr)
|
||||
goto tlv_readkeycontent_err;
|
||||
return sum;
|
||||
|
||||
tlv_readkeycontent_err:
|
||||
kfree(pcontent->dataptr);
|
||||
pcontent->dataptr = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -371,7 +382,7 @@ static int normalkey_hash(u8 *data, u32 len, u8 *hash)
|
||||
{
|
||||
struct crypto_shash *tfm;
|
||||
struct shash_desc *desc;
|
||||
int ret = -1;
|
||||
int ret;
|
||||
|
||||
memset(hash, 0, SHA256_DIGEST_SIZE);
|
||||
tfm = crypto_alloc_shash("sha256", 0, 0);
|
||||
@@ -461,7 +472,7 @@ int normalkey_add(const u8 *name, u8 *buffer, u32 len, u32 attr)
|
||||
return -1;
|
||||
|
||||
namelen = strlen(name);
|
||||
if (namelen > MAX_OBJ_NAME_LEN)
|
||||
if (namelen >= MAX_OBJ_NAME_LEN)
|
||||
return -1;
|
||||
|
||||
obj = normalkey_get(name);
|
||||
@@ -624,6 +635,8 @@ int normalkey_readfromblock(void *block, unsigned long size)
|
||||
break;
|
||||
}
|
||||
idx += ret;
|
||||
if (!obj->dataptr)
|
||||
continue;
|
||||
normalkey_hash(obj->dataptr, obj->datasize, hash);
|
||||
if (memcmp(hash, obj->hashptr, 32)) {
|
||||
kfree(obj->dataptr);
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
// #define DEBUG
|
||||
#include <linux/module.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/spinlock.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/amlogic/arm-smccc.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/mm.h>
|
||||
@@ -22,13 +22,14 @@ static struct device_node *ofdts_node;
|
||||
static int pfn_valid_flag;
|
||||
#endif
|
||||
|
||||
static DEFINE_SPINLOCK(storage_lock);
|
||||
static DEFINE_MUTEX(storage_lock);
|
||||
static int storage_init_status;
|
||||
static struct bl31_storage_share_mem *share_mem;
|
||||
static int share_mem_ioremapped;
|
||||
|
||||
static unsigned long storage_smc_ops(u64 func)
|
||||
{
|
||||
struct arm_smccc_res res;
|
||||
struct arm_smccc_res res = {0};
|
||||
|
||||
arm_smccc_smc((unsigned long)func, 0, 0, 0, 0, 0, 0, 0, &res);
|
||||
return res.a0;
|
||||
@@ -53,16 +54,20 @@ unsigned long secure_storage_write(u8 *keyname, u8 *keybuf,
|
||||
u8 *keydata;
|
||||
u8 *name;
|
||||
unsigned long ret;
|
||||
unsigned long lockflags;
|
||||
|
||||
if (storage_init_status != 1)
|
||||
mutex_lock(&storage_lock);
|
||||
if (!share_mem || !share_mem->in || storage_init_status != 1) {
|
||||
mutex_unlock(&storage_lock);
|
||||
return RET_EUND;
|
||||
}
|
||||
|
||||
namelen = strlen(keyname);
|
||||
if (namelen + keylen + 12 > share_mem->size)
|
||||
if (keylen > share_mem->size ||
|
||||
namelen + 12 > share_mem->size - keylen) {
|
||||
mutex_unlock(&storage_lock);
|
||||
return RET_EMEM;
|
||||
}
|
||||
|
||||
spin_lock_irqsave(&storage_lock, lockflags);
|
||||
input = (u32 *)(share_mem->in);
|
||||
*input++ = namelen;
|
||||
*input++ = keylen;
|
||||
@@ -72,7 +77,7 @@ unsigned long secure_storage_write(u8 *keyname, u8 *keybuf,
|
||||
keydata = name + namelen;
|
||||
memcpy(keydata, keybuf, keylen);
|
||||
ret = storage_smc_ops(BL31_STORAGE_WRITE);
|
||||
spin_unlock_irqrestore(&storage_lock, lockflags);
|
||||
mutex_unlock(&storage_lock);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -86,16 +91,19 @@ unsigned long secure_storage_read(u8 *keyname, u8 *keybuf,
|
||||
u8 *name;
|
||||
u8 *buf;
|
||||
unsigned long ret;
|
||||
unsigned long lockflags;
|
||||
|
||||
if (storage_init_status != 1)
|
||||
mutex_lock(&storage_lock);
|
||||
if (!share_mem || !share_mem->in || !share_mem->out || storage_init_status != 1) {
|
||||
mutex_unlock(&storage_lock);
|
||||
return RET_EUND;
|
||||
}
|
||||
|
||||
namelen = strlen(keyname);
|
||||
if (namelen + 8 > share_mem->size)
|
||||
if (namelen + 8 > share_mem->size) {
|
||||
mutex_unlock(&storage_lock);
|
||||
return RET_EMEM;
|
||||
}
|
||||
|
||||
spin_lock_irqsave(&storage_lock, lockflags);
|
||||
input = (u32 *)(share_mem->in);
|
||||
output = (u32 *)(share_mem->out);
|
||||
*input++ = namelen;
|
||||
@@ -110,7 +118,7 @@ unsigned long secure_storage_read(u8 *keyname, u8 *keybuf,
|
||||
buf = (u8 *)(output + 1);
|
||||
memcpy(keybuf, buf, *readlen);
|
||||
}
|
||||
spin_unlock_irqrestore(&storage_lock, lockflags);
|
||||
mutex_unlock(&storage_lock);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -122,16 +130,19 @@ unsigned long secure_storage_verify(u8 *keyname, u8 *hashbuf)
|
||||
u32 namelen;
|
||||
u8 *name;
|
||||
unsigned long ret;
|
||||
unsigned long lockflags;
|
||||
|
||||
if (storage_init_status != 1)
|
||||
mutex_lock(&storage_lock);
|
||||
if (!share_mem || !share_mem->in || !share_mem->out || storage_init_status != 1) {
|
||||
mutex_unlock(&storage_lock);
|
||||
return RET_EUND;
|
||||
}
|
||||
|
||||
namelen = strlen(keyname);
|
||||
if (namelen + 4 > share_mem->size)
|
||||
if (namelen + 4 > share_mem->size) {
|
||||
mutex_unlock(&storage_lock);
|
||||
return RET_EMEM;
|
||||
}
|
||||
|
||||
spin_lock_irqsave(&storage_lock, lockflags);
|
||||
input = (u32 *)(share_mem->in);
|
||||
output = (u32 *)(share_mem->out);
|
||||
*input++ = namelen;
|
||||
@@ -140,7 +151,7 @@ unsigned long secure_storage_verify(u8 *keyname, u8 *hashbuf)
|
||||
ret = storage_smc_ops(BL31_STORAGE_VERIFY);
|
||||
if (ret == RET_OK)
|
||||
memcpy(hashbuf, (u8 *)output, 32);
|
||||
spin_unlock_irqrestore(&storage_lock, lockflags);
|
||||
mutex_unlock(&storage_lock);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -152,16 +163,19 @@ unsigned long secure_storage_query(u8 *key_name, u32 *retval)
|
||||
u32 namelen;
|
||||
u8 *name;
|
||||
unsigned long ret;
|
||||
unsigned long lockflags;
|
||||
|
||||
if (storage_init_status != 1)
|
||||
mutex_lock(&storage_lock);
|
||||
if (!share_mem || !share_mem->in || !share_mem->out || storage_init_status != 1) {
|
||||
mutex_unlock(&storage_lock);
|
||||
return RET_EUND;
|
||||
}
|
||||
|
||||
namelen = strlen(key_name);
|
||||
if (namelen + 4 > share_mem->size)
|
||||
if (namelen + 4 > share_mem->size) {
|
||||
mutex_unlock(&storage_lock);
|
||||
return RET_EMEM;
|
||||
}
|
||||
|
||||
spin_lock_irqsave(&storage_lock, lockflags);
|
||||
input = (u32 *)(share_mem->in);
|
||||
output = (u32 *)(share_mem->out);
|
||||
*input++ = namelen;
|
||||
@@ -170,7 +184,7 @@ unsigned long secure_storage_query(u8 *key_name, u32 *retval)
|
||||
ret = storage_smc_ops(BL31_STORAGE_QUERY);
|
||||
if (ret == RET_OK)
|
||||
*retval = *output;
|
||||
spin_unlock_irqrestore(&storage_lock, lockflags);
|
||||
mutex_unlock(&storage_lock);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -182,16 +196,19 @@ unsigned long secure_storage_tell(u8 *keyname, u32 *retval)
|
||||
u32 namelen;
|
||||
u8 *name;
|
||||
unsigned long ret;
|
||||
unsigned long lockflags;
|
||||
|
||||
if (storage_init_status != 1)
|
||||
mutex_lock(&storage_lock);
|
||||
if (!share_mem || !share_mem->in || !share_mem->out || storage_init_status != 1) {
|
||||
mutex_unlock(&storage_lock);
|
||||
return RET_EUND;
|
||||
}
|
||||
|
||||
namelen = strlen(keyname);
|
||||
if (namelen + 4 > share_mem->size)
|
||||
if (namelen + 4 > share_mem->size) {
|
||||
mutex_unlock(&storage_lock);
|
||||
return RET_EMEM;
|
||||
}
|
||||
|
||||
spin_lock_irqsave(&storage_lock, lockflags);
|
||||
input = (u32 *)(share_mem->in);
|
||||
output = (u32 *)(share_mem->out);
|
||||
*input++ = namelen;
|
||||
@@ -200,7 +217,7 @@ unsigned long secure_storage_tell(u8 *keyname, u32 *retval)
|
||||
ret = storage_smc_ops(BL31_STORAGE_TELL);
|
||||
if (ret == RET_OK)
|
||||
*retval = *output;
|
||||
spin_unlock_irqrestore(&storage_lock, lockflags);
|
||||
mutex_unlock(&storage_lock);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -212,16 +229,19 @@ unsigned long secure_storage_status(u8 *keyname, u32 *retval)
|
||||
u32 namelen;
|
||||
u8 *name;
|
||||
u64 ret;
|
||||
unsigned long lockflags;
|
||||
|
||||
if (storage_init_status != 1)
|
||||
mutex_lock(&storage_lock);
|
||||
if (!share_mem || !share_mem->in || !share_mem->out || storage_init_status != 1) {
|
||||
mutex_unlock(&storage_lock);
|
||||
return RET_EUND;
|
||||
}
|
||||
|
||||
namelen = strlen(keyname);
|
||||
if (namelen + 4 > share_mem->size)
|
||||
if (namelen + 4 > share_mem->size) {
|
||||
mutex_unlock(&storage_lock);
|
||||
return RET_EMEM;
|
||||
}
|
||||
|
||||
spin_lock_irqsave(&storage_lock, lockflags);
|
||||
input = (u32 *)(share_mem->in);
|
||||
output = (u32 *)(share_mem->out);
|
||||
*input++ = namelen;
|
||||
@@ -230,7 +250,7 @@ unsigned long secure_storage_status(u8 *keyname, u32 *retval)
|
||||
ret = storage_smc_ops(BL31_STORAGE_STATUS);
|
||||
if (ret == RET_OK)
|
||||
*retval = *output;
|
||||
spin_unlock_irqrestore(&storage_lock, lockflags);
|
||||
mutex_unlock(&storage_lock);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -241,7 +261,7 @@ int __init security_key_init(struct platform_device *pdev)
|
||||
unsigned long phy_out;
|
||||
unsigned long phy_block;
|
||||
|
||||
storage_init_status = -1;
|
||||
storage_init_status = 0;
|
||||
|
||||
share_mem = devm_kzalloc(&pdev->dev, sizeof(*share_mem), GFP_KERNEL);
|
||||
if (IS_ERR_OR_NULL(share_mem)) {
|
||||
@@ -295,6 +315,7 @@ int __init security_key_init(struct platform_device *pdev)
|
||||
share_mem->in = ioremap_cache(phy_in, share_mem->size);
|
||||
share_mem->out = ioremap_cache(phy_out, share_mem->size);
|
||||
share_mem->block = ioremap_cache(phy_block, share_mem->size);
|
||||
share_mem_ioremapped = 1;
|
||||
}
|
||||
|
||||
pr_info("storage in: 0x%lx, out: 0x%lx, block: 0x%lx\n",
|
||||
@@ -310,3 +331,25 @@ int __init security_key_init(struct platform_device *pdev)
|
||||
pr_info("security_key init done!\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
void security_key_deinit(void)
|
||||
{
|
||||
if (!share_mem)
|
||||
return;
|
||||
|
||||
mutex_lock(&storage_lock);
|
||||
storage_init_status = 0;
|
||||
if (share_mem_ioremapped) {
|
||||
if (share_mem->in)
|
||||
iounmap(share_mem->in);
|
||||
if (share_mem->out)
|
||||
iounmap(share_mem->out);
|
||||
if (share_mem->block)
|
||||
iounmap(share_mem->block);
|
||||
share_mem_ioremapped = 0;
|
||||
}
|
||||
share_mem->in = NULL;
|
||||
share_mem->out = NULL;
|
||||
share_mem->block = NULL;
|
||||
mutex_unlock(&storage_lock);
|
||||
}
|
||||
|
||||
@@ -47,4 +47,5 @@ unsigned long secure_storage_tell(u8 *name, u32 *retval);
|
||||
unsigned long secure_storage_status(u8 *name, u32 *retval);
|
||||
void *secure_storage_getbuf(u32 *size);
|
||||
int __init security_key_init(struct platform_device *pdev);
|
||||
void security_key_deinit(void);
|
||||
#endif
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
#define SECUREKEY_SIZE SECURESTORAGE_WHOLE_SIZE
|
||||
|
||||
static DEFINE_MUTEX(securekey_lock);
|
||||
u8 *securekey_prebuf;
|
||||
static u8 *securekey_prebuf;
|
||||
|
||||
struct storagekey_info_t {
|
||||
u8 *buffer;
|
||||
@@ -53,7 +53,7 @@ int is_valid_unifykey_storage_type(u32 storage_type)
|
||||
return 0;
|
||||
}
|
||||
|
||||
return -EINVAL;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int register_unifykey_types(struct unifykey_type *uk_type)
|
||||
@@ -73,13 +73,18 @@ int register_unifykey_types(struct unifykey_type *uk_type)
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (!uk_type->ops || !unifykey_types.ops) {
|
||||
ret = -EINVAL;
|
||||
goto error;
|
||||
}
|
||||
|
||||
unifykey_types.storage_type = uk_type->storage_type;
|
||||
unifykey_types.ops->read = uk_type->ops->read;
|
||||
unifykey_types.ops->write = uk_type->ops->write;
|
||||
|
||||
error:
|
||||
if (ret)
|
||||
pr_err("register unifykey types failed: %d", ret);
|
||||
pr_err("register unifykey types failed: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL(register_unifykey_types);
|
||||
@@ -112,7 +117,7 @@ static s32 _amlkey_init(u8 *seed, u32 len, int encrypt_type)
|
||||
}
|
||||
|
||||
uk_type = &unifykey_types;
|
||||
if (unlikely(!uk_type->ops->read)) {
|
||||
if (!uk_type->ops || unlikely(!uk_type->ops->read)) {
|
||||
ret = -3;
|
||||
goto error;
|
||||
}
|
||||
@@ -129,12 +134,14 @@ static s32 _amlkey_init(u8 *seed, u32 len, int encrypt_type)
|
||||
&actual_size);
|
||||
if (ret) {
|
||||
memset(storagekey_info.buffer, 0, SECURESTORAGE_HEAD_SIZE);
|
||||
storagekey_info.buffer = NULL;
|
||||
ret = -5;
|
||||
goto _out;
|
||||
}
|
||||
|
||||
if (actual_size >= (1U << 20)) {
|
||||
memset(storagekey_info.buffer, 0, SECURESTORAGE_HEAD_SIZE);
|
||||
storagekey_info.buffer = NULL;
|
||||
ret = -6;
|
||||
goto _out;
|
||||
}
|
||||
@@ -150,7 +157,7 @@ _out:
|
||||
|
||||
error:
|
||||
if (ret)
|
||||
pr_err("amlkey init failed: %d", ret);
|
||||
pr_err("amlkey init failed: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -166,6 +173,7 @@ int securekey_prebuf_init(void)
|
||||
void securekey_prebuf_deinit(void)
|
||||
{
|
||||
kfree(securekey_prebuf);
|
||||
securekey_prebuf = NULL;
|
||||
}
|
||||
|
||||
static u32 _amlkey_exist(const u8 *name)
|
||||
@@ -291,7 +299,7 @@ static ssize_t _amlkey_write(const u8 *name, u8 *buffer,
|
||||
buf = securekey_prebuf;
|
||||
|
||||
memcpy(buf, storagekey_info.buffer, storagekey_info.size);
|
||||
if (!uk_type->ops->write) {
|
||||
if (!uk_type->ops || !uk_type->ops->write) {
|
||||
err = -7;
|
||||
retval = 0;
|
||||
mutex_unlock(&securekey_lock);
|
||||
@@ -306,7 +314,7 @@ static ssize_t _amlkey_write(const u8 *name, u8 *buffer,
|
||||
|
||||
_out:
|
||||
if (err)
|
||||
pr_err("amlkey write failed: %d", err);
|
||||
pr_err("amlkey write failed: %d\n", err);
|
||||
return retval;
|
||||
}
|
||||
|
||||
@@ -330,8 +338,7 @@ static s32 _amlkey_init_normal(u8 *seed, u32 len, int encrypt_type)
|
||||
err = -1;
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (!unifykey_types.ops->read) {
|
||||
if (!unifykey_types.ops || !unifykey_types.ops->read) {
|
||||
err = -2;
|
||||
goto error;
|
||||
}
|
||||
@@ -342,6 +349,7 @@ static s32 _amlkey_init_normal(u8 *seed, u32 len, int encrypt_type)
|
||||
}
|
||||
|
||||
mutex_lock(&normalkey_lock);
|
||||
memset(normal_block, 0, normal_blksz);
|
||||
ret = unifykey_types.ops->read(normal_block,
|
||||
normal_blksz,
|
||||
&normal_flashsize);
|
||||
@@ -364,7 +372,7 @@ finish:
|
||||
|
||||
error:
|
||||
if (err)
|
||||
pr_err("amlkey init normal failed: %d", err);
|
||||
pr_err("amlkey init normal failed: %d\n", err);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -414,7 +422,7 @@ static unsigned int _amlkey_read_normal(const u8 *name, u8 *buffer, u32 len)
|
||||
|
||||
mutex_lock(&normalkey_lock);
|
||||
obj = normalkey_get(name);
|
||||
if (obj && len >= obj->datasize) {
|
||||
if (obj && obj->dataptr && len >= obj->datasize) {
|
||||
size = obj->datasize;
|
||||
memcpy(buffer, obj->dataptr, size);
|
||||
}
|
||||
@@ -434,8 +442,7 @@ static ssize_t _amlkey_write_normal(const u8 *name, u8 *buffer,
|
||||
err = -1;
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (!unifykey_types.ops->write) {
|
||||
if (!unifykey_types.ops || !unifykey_types.ops->write) {
|
||||
err = -2;
|
||||
goto error;
|
||||
}
|
||||
@@ -469,7 +476,7 @@ unlock:
|
||||
|
||||
error:
|
||||
if (err)
|
||||
pr_err("amlkey write normal failed: %d", err);
|
||||
pr_err("amlkey write normal failed: %d\n", err);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -491,7 +498,7 @@ static s32 _amlkey_hash_normal(const u8 *name, u8 *hash)
|
||||
|
||||
int normal_key_init(struct platform_device *pdev)
|
||||
{
|
||||
u32 blksz;
|
||||
u32 blksz = 0;
|
||||
int ret;
|
||||
|
||||
ret = device_property_read_u32(&pdev->dev, "blocksize", &blksz);
|
||||
@@ -510,6 +517,7 @@ int normal_key_init(struct platform_device *pdev)
|
||||
void normal_key_deinit(void)
|
||||
{
|
||||
kfree(normal_block);
|
||||
normal_block = NULL;
|
||||
}
|
||||
|
||||
enum amlkey_if_type {
|
||||
@@ -518,7 +526,7 @@ enum amlkey_if_type {
|
||||
IFTYPE_MAX
|
||||
};
|
||||
|
||||
struct amlkey_if amlkey_ifs[] = {
|
||||
static struct amlkey_if amlkey_ifs[] = {
|
||||
[IFTYPE_SECURE_STORAGE] = {
|
||||
.init = _amlkey_init,
|
||||
.exist = _amlkey_exist,
|
||||
@@ -546,23 +554,27 @@ int __init amlkey_if_init(struct platform_device *pdev)
|
||||
int ret;
|
||||
|
||||
ret = security_key_init(pdev);
|
||||
if (ret != -EOPNOTSUPP) {
|
||||
if (ret == 0) {
|
||||
pr_info("secure key used!\n");
|
||||
amlkey_if = &amlkey_ifs[IFTYPE_SECURE_STORAGE];
|
||||
ret = securekey_prebuf_init();
|
||||
return ret;
|
||||
return securekey_prebuf_init();
|
||||
}
|
||||
if (ret == -EOPNOTSUPP) {
|
||||
pr_info("normal key used!\n");
|
||||
ret = normal_key_init(pdev);
|
||||
amlkey_if = &amlkey_ifs[IFTYPE_NORMAL_STORAGE];
|
||||
}
|
||||
|
||||
pr_info("normal key used!\n");
|
||||
ret = normal_key_init(pdev);
|
||||
amlkey_if = &amlkey_ifs[IFTYPE_NORMAL_STORAGE];
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void amlkey_if_deinit(void)
|
||||
{
|
||||
security_key_deinit();
|
||||
|
||||
securekey_prebuf_deinit();
|
||||
|
||||
normal_key_deinit();
|
||||
|
||||
amlkey_if = NULL;
|
||||
}
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
#include <linux/of.h>
|
||||
#include <linux/ctype.h>
|
||||
#include <linux/compat.h>
|
||||
#include <linux/atomic.h>
|
||||
#if defined(CONFIG_AMLOGIC_EFUSE)
|
||||
#include <linux/amlogic/efuse.h>
|
||||
#endif
|
||||
@@ -35,7 +36,7 @@ typedef int (*key_unify_dev_init)(struct key_info_t *uk_info,
|
||||
char *buf, unsigned int len);
|
||||
|
||||
static struct aml_uk_dev *ukdev_global;
|
||||
static int lock;
|
||||
static atomic_t lock = ATOMIC_INIT(0);
|
||||
static DEFINE_MUTEX(attach_mutex);
|
||||
struct unifykey_type *storage_device[] = {
|
||||
#if IS_ENABLED(CONFIG_AMLOGIC_MMC_MESON_GX)
|
||||
@@ -62,11 +63,17 @@ static struct key_item_t *uk_find_item_by_name(struct list_head *list,
|
||||
{
|
||||
struct key_item_t *item;
|
||||
|
||||
list_for_each_entry(item, list, node)
|
||||
/*
|
||||
* list_for_each_entry can guarantee item is not null.
|
||||
*/
|
||||
/* coverity[NULL_FIELD:SUPPRESS] */
|
||||
list_for_each_entry(item, list, node) {
|
||||
/* coverity[NULL_FIELD:SUPPRESS] */
|
||||
if (!strncmp(item->name, name,
|
||||
((strlen(item->name) > strlen(name)) ?
|
||||
strlen(item->name) : strlen(name))))
|
||||
return item;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
@@ -75,9 +82,15 @@ static struct key_item_t *uk_find_item_by_id(struct list_head *list, int id)
|
||||
{
|
||||
struct key_item_t *item;
|
||||
|
||||
list_for_each_entry(item, list, node)
|
||||
/*
|
||||
* list_for_each_entry can guarantee item is not null.
|
||||
*/
|
||||
/* coverity[NULL_FIELD:SUPPRESS] */
|
||||
list_for_each_entry(item, list, node) {
|
||||
/* coverity[NULL_FIELD:SUPPRESS] */
|
||||
if (item->id == id)
|
||||
return item;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
@@ -87,7 +100,12 @@ static int uk_count_key(struct list_head *list)
|
||||
int count = 0;
|
||||
struct list_head *node;
|
||||
|
||||
/*
|
||||
* list_for_each can guarantee node is not null.
|
||||
*/
|
||||
/* coverity[NULL_FIELD:SUPPRESS] */
|
||||
list_for_each(node, list)
|
||||
/* coverity[NULL_FIELD:SUPPRESS] */
|
||||
count++;
|
||||
|
||||
return count;
|
||||
@@ -108,7 +126,7 @@ static int key_storage_read(char *name, unsigned char *data,
|
||||
}
|
||||
|
||||
/* make sure attr in storage & dts are the same! */
|
||||
encrypt = amlkey_get_attr((u8 *)name) & KEY_ATTR_ENCRYPT;
|
||||
encrypt = (amlkey_get_attr((u8 *)name) & KEY_ATTR_ENCRYPT) ? 1 : 0;
|
||||
|
||||
encrypt_dts = (u32)(flag & KEY_ATTR_ENCRYPT) ? 1 : 0;
|
||||
if (encrypt != encrypt_dts) {
|
||||
@@ -241,7 +259,7 @@ static int key_unify_init(struct aml_uk_dev *ukdev, char *buf,
|
||||
int auto_attach(struct unifykey_type *uk_type)
|
||||
{
|
||||
static int init;
|
||||
int ret = -1;
|
||||
int ret;
|
||||
struct aml_uk_dev *ukdev = get_ukdev();
|
||||
|
||||
mutex_lock(&attach_mutex);
|
||||
@@ -332,7 +350,7 @@ int key_unify_write(struct aml_uk_dev *ukdev, char *name,
|
||||
case KEY_UNKNOWN_DEV:
|
||||
default:
|
||||
pr_err("unknown device for key %s\n", name);
|
||||
break;
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return ret;
|
||||
@@ -378,7 +396,7 @@ int key_unify_read(struct aml_uk_dev *ukdev, char *name,
|
||||
case KEY_UNKNOWN_DEV:
|
||||
default:
|
||||
pr_err("unknown device for key %s\n", name);
|
||||
break;
|
||||
return -EINVAL;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
@@ -421,7 +439,7 @@ int key_unify_size(struct aml_uk_dev *ukdev, char *name, unsigned int *real)
|
||||
case KEY_UNKNOWN_DEV:
|
||||
default:
|
||||
pr_err("unknown device for key %s\n", name);
|
||||
break;
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return ret;
|
||||
@@ -462,7 +480,7 @@ int key_unify_query(struct aml_uk_dev *ukdev, char *name,
|
||||
case KEY_UNKNOWN_DEV:
|
||||
default:
|
||||
pr_err("unknown device for key %s\n", name);
|
||||
break;
|
||||
return -EINVAL;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
@@ -542,11 +560,11 @@ static int unifykey_open(struct inode *inode, struct file *file)
|
||||
{
|
||||
struct aml_uk_dev *ukdev;
|
||||
|
||||
if (lock == 1) {
|
||||
/* only one open at a time */
|
||||
if (atomic_xchg(&lock, 1)) {
|
||||
pr_err("%s: can not operate other key\n", __func__);
|
||||
return -EPERM;
|
||||
}
|
||||
lock = 1;
|
||||
ukdev = container_of(inode->i_cdev, struct aml_uk_dev, cdev);
|
||||
file->private_data = ukdev;
|
||||
|
||||
@@ -555,7 +573,7 @@ static int unifykey_open(struct inode *inode, struct file *file)
|
||||
|
||||
static int unifykey_release(struct inode *inode, struct file *file)
|
||||
{
|
||||
lock = 0;
|
||||
atomic_set(&lock, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -563,8 +581,9 @@ static loff_t unifykey_llseek(struct file *filp, loff_t off, int whence)
|
||||
{
|
||||
struct aml_uk_dev *ukdev;
|
||||
loff_t newpos;
|
||||
|
||||
ukdev = filp->private_data;
|
||||
if (!ukdev)
|
||||
return -EINVAL;
|
||||
|
||||
switch (whence) {
|
||||
case 0: /* SEEK_SET (start postion)*/
|
||||
@@ -577,7 +596,7 @@ static loff_t unifykey_llseek(struct file *filp, loff_t off, int whence)
|
||||
|
||||
case 2: /* SEEK_END */
|
||||
newpos = (loff_t)uk_count_key(&ukdev->uk_hdr) - 1;
|
||||
newpos = newpos - off;
|
||||
newpos = newpos + off;
|
||||
break;
|
||||
|
||||
default: /* can't happen */
|
||||
@@ -605,6 +624,8 @@ static long unifykey_unlocked_ioctl(struct file *file,
|
||||
int ret;
|
||||
|
||||
ukdev = file->private_data;
|
||||
if (!ukdev)
|
||||
return -EINVAL;
|
||||
|
||||
switch (cmd) {
|
||||
case KEYUNIFY_ATTACH:
|
||||
@@ -654,8 +675,7 @@ static long unifykey_unlocked_ioctl(struct file *file,
|
||||
item->perm = perm;
|
||||
item->flag = state;
|
||||
item->id = key->id;
|
||||
strncpy(item->name, key->name, (KEY_UNIFY_NAME_LEN - 1));
|
||||
item->name[KEY_UNIFY_NAME_LEN - 1] = '\0';
|
||||
strscpy(item->name, key->name, KEY_UNIFY_NAME_LEN);
|
||||
ret = key_unify_size(ukdev, key->name, &item->size);
|
||||
if (ret != 0) {
|
||||
pr_err("fail to obtain key size of %s\n", key->name);
|
||||
@@ -695,24 +715,32 @@ static ssize_t unifykey_read(struct file *file,
|
||||
loff_t *ppos)
|
||||
{
|
||||
struct aml_uk_dev *ukdev;
|
||||
int ret;
|
||||
int id;
|
||||
unsigned int reallen;
|
||||
struct key_item_t *item;
|
||||
char *local_buf = NULL;
|
||||
int ret;
|
||||
int id;
|
||||
unsigned int reallen, copy_len;
|
||||
struct key_item_t *item;
|
||||
char *local_buf = NULL;
|
||||
|
||||
ukdev = file->private_data;
|
||||
if (!ukdev)
|
||||
return -EINVAL;
|
||||
|
||||
id = (int)(*ppos);
|
||||
item = uk_find_item_by_id(&ukdev->uk_hdr, id);
|
||||
if (!item) {
|
||||
ret = -EINVAL;
|
||||
goto exit;
|
||||
if (!item)
|
||||
return -EINVAL;
|
||||
|
||||
if (count == 0)
|
||||
return -EINVAL;
|
||||
|
||||
if (item->dev == KEY_SECURE) {
|
||||
if (count < SHA256_SUM_LEN)
|
||||
pr_err("Securekey reads 32-byte hash,but count=%d\n", (int)count);
|
||||
local_buf = kzalloc(SHA256_SUM_LEN, GFP_KERNEL);
|
||||
} else {
|
||||
local_buf = kzalloc(count, GFP_KERNEL);
|
||||
}
|
||||
|
||||
if (item->dev == KEY_SECURE)
|
||||
count = SHA256_SUM_LEN;
|
||||
local_buf = kzalloc(count, GFP_KERNEL);
|
||||
if (!local_buf) {
|
||||
pr_err("memory not enough,%s:%d\n",
|
||||
__func__, __LINE__);
|
||||
@@ -722,14 +750,14 @@ static ssize_t unifykey_read(struct file *file,
|
||||
ret = key_unify_read(ukdev, item->name, local_buf, count, &reallen);
|
||||
if (ret < 0)
|
||||
goto exit;
|
||||
if (count > reallen)
|
||||
count = reallen;
|
||||
if (copy_to_user((void *)buf, (void *)local_buf, count)) {
|
||||
|
||||
copy_len = min(count, reallen);
|
||||
if (copy_to_user((void *)buf, (void *)local_buf, copy_len)) {
|
||||
ret = -EFAULT;
|
||||
goto exit;
|
||||
}
|
||||
pr_info("%s: name: %s, size %d\n", __func__, item->name, (int)count);
|
||||
ret = count;
|
||||
pr_info("%s: name: %s, size %d\n", __func__, item->name, copy_len);
|
||||
ret = copy_len;
|
||||
exit:
|
||||
kfree(local_buf);
|
||||
return ret;
|
||||
@@ -746,17 +774,21 @@ static ssize_t unifykey_write(struct file *file,
|
||||
char *local_buf;
|
||||
|
||||
ukdev = file->private_data;
|
||||
if (!ukdev)
|
||||
return -EINVAL;
|
||||
|
||||
if (count == 0)
|
||||
return -EINVAL;
|
||||
|
||||
id = (int)(*ppos);
|
||||
item = uk_find_item_by_id(&ukdev->uk_hdr, id);
|
||||
if (!item)
|
||||
return -EINVAL;
|
||||
|
||||
local_buf = kzalloc(count, GFP_KERNEL);
|
||||
if (!local_buf)
|
||||
return -ENOMEM;
|
||||
|
||||
id = (int)(*ppos);
|
||||
item = uk_find_item_by_id(&ukdev->uk_hdr, id);
|
||||
if (!item) {
|
||||
ret = -EINVAL;
|
||||
goto exit;
|
||||
}
|
||||
if (copy_from_user(local_buf, buf, count)) {
|
||||
ret = -EFAULT;
|
||||
goto exit;
|
||||
@@ -799,14 +831,18 @@ static ssize_t list_show(const struct class *cla,
|
||||
ukdev = container_of(cla, struct aml_uk_dev, cls);
|
||||
|
||||
key_cnt = uk_count_key(&ukdev->uk_hdr);
|
||||
n = sprintf(&buf[0], "%d keys installed\n", key_cnt);
|
||||
n = scnprintf(&buf[0], PAGE_SIZE, "%d keys installed\n", key_cnt);
|
||||
|
||||
for (index = 0; index < key_cnt; index++) {
|
||||
unifykey = uk_find_item_by_id(&ukdev->uk_hdr, index);
|
||||
if (unifykey)
|
||||
n += sprintf(&buf[n], "%02d: %s, %s, %x\n",
|
||||
index, unifykey->name,
|
||||
keydev[unifykey->dev], unifykey->perm);
|
||||
if (!unifykey)
|
||||
continue;
|
||||
/* one line worst case: index + name + dev + perm <= 73 */
|
||||
if (n >= PAGE_SIZE - LIST_LINE_MAX)
|
||||
break;
|
||||
n += scnprintf(&buf[n], PAGE_SIZE - n, "%02d: %s, %s, %x\n",
|
||||
index, unifykey->name,
|
||||
keydev[unifykey->dev], unifykey->perm);
|
||||
}
|
||||
buf[n] = 0;
|
||||
|
||||
@@ -844,7 +880,7 @@ static ssize_t exist_show(const struct class *cla,
|
||||
if (keystate > 2)
|
||||
keystate = 2;
|
||||
|
||||
n = sprintf(buf, "%s\n", state[keystate]);
|
||||
n = scnprintf(buf, PAGE_SIZE, "%s\n", state[keystate]);
|
||||
buf[n] = 0;
|
||||
|
||||
return n;
|
||||
@@ -881,7 +917,7 @@ static ssize_t secure_show(const struct class *cla,
|
||||
if (secure > 1)
|
||||
secure = 1;
|
||||
_out:
|
||||
n = sprintf(buf, "%s\n", state[secure]);
|
||||
n = scnprintf(buf, PAGE_SIZE, "%s\n", state[secure]);
|
||||
buf[n] = 0;
|
||||
|
||||
return n;
|
||||
@@ -918,7 +954,7 @@ static ssize_t encrypt_show(const struct class *cla,
|
||||
if (encrypt > 1)
|
||||
encrypt = 1;
|
||||
_out:
|
||||
n = sprintf(buf, "%s\n", state[encrypt]);
|
||||
n = scnprintf(buf, PAGE_SIZE, "%s\n", state[encrypt]);
|
||||
buf[n] = 0;
|
||||
|
||||
return n;
|
||||
@@ -970,7 +1006,7 @@ static ssize_t name_show(const struct class *cla,
|
||||
return 0;
|
||||
}
|
||||
|
||||
n = sprintf(buf, "%s\n", curkey->name);
|
||||
n = scnprintf(buf, PAGE_SIZE, "%s\n", curkey->name);
|
||||
buf[n] = 0;
|
||||
|
||||
return n;
|
||||
@@ -990,12 +1026,11 @@ static ssize_t name_store(const struct class *cla,
|
||||
size_t reval;
|
||||
|
||||
ukdev = container_of(cla, struct aml_uk_dev, cls);
|
||||
curkey = ukdev->curkey;
|
||||
|
||||
if (count >= KEY_UNIFY_NAME_LEN)
|
||||
count = KEY_UNIFY_NAME_LEN - 1;
|
||||
if (count > KEY_UNIFY_NAME_LEN)
|
||||
return -EINVAL;
|
||||
|
||||
if (count <= 0) {
|
||||
if (count <= 1) {
|
||||
pr_err(" count=%zd is invalid in %s\n", count, __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
@@ -1072,6 +1107,8 @@ static ssize_t read_show(const struct class *cla,
|
||||
}
|
||||
if (curkey->dev == KEY_SECURE)
|
||||
keysize = SHA256_SUM_LEN;
|
||||
if (keysize > PAGE_SIZE - 1)
|
||||
keysize = PAGE_SIZE - 1;
|
||||
pr_err("name: %s, size %d\n", curkey->name, keysize);
|
||||
keydata = kzalloc(keysize, GFP_KERNEL);
|
||||
if (!keydata) {
|
||||
@@ -1104,7 +1141,7 @@ static ssize_t write_store(const struct class *cla,
|
||||
{
|
||||
struct aml_uk_dev *ukdev;
|
||||
struct key_item_t *curkey;
|
||||
int ret;
|
||||
int ret = -EINVAL;
|
||||
unsigned char *keydata = NULL;
|
||||
size_t key_len = 0;
|
||||
|
||||
@@ -1119,8 +1156,10 @@ static ssize_t write_store(const struct class *cla,
|
||||
if (curkey) {
|
||||
keydata = kzalloc(count, GFP_KERNEL);
|
||||
|
||||
if (!keydata)
|
||||
goto _out;
|
||||
if (!keydata) {
|
||||
ret = -ENOMEM;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* check string */
|
||||
for (key_len = 0; key_len < count; key_len++)
|
||||
@@ -1142,12 +1181,11 @@ static ssize_t write_store(const struct class *cla,
|
||||
__func__, __LINE__);
|
||||
goto _out;
|
||||
}
|
||||
ret = count;
|
||||
}
|
||||
_out:
|
||||
kfree(keydata);
|
||||
keydata = NULL;
|
||||
|
||||
return count;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static ssize_t attach_show(const struct class *cla,
|
||||
@@ -1159,7 +1197,8 @@ static ssize_t attach_show(const struct class *cla,
|
||||
|
||||
/* show attach status. */
|
||||
ukdev = container_of(cla, struct aml_uk_dev, cls);
|
||||
n = sprintf(buf, "%s\n", (ukdev->init_flag == 0 ? "no" : "yes"));
|
||||
n = scnprintf(buf, PAGE_SIZE, "%s\n",
|
||||
(ukdev->init_flag == 0 ? "no" : "yes"));
|
||||
buf[n] = 0;
|
||||
|
||||
return n;
|
||||
@@ -1170,9 +1209,12 @@ static ssize_t attach_store(const struct class *cla,
|
||||
const char *buf, size_t count)
|
||||
{
|
||||
struct aml_uk_dev *ukdev;
|
||||
int ret;
|
||||
|
||||
ukdev = container_of(cla, struct aml_uk_dev, cls);
|
||||
key_unify_init(ukdev, NULL, KEY_UNIFY_NAME_LEN);
|
||||
ret = key_unify_init(ukdev, NULL, KEY_UNIFY_NAME_LEN);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
return count;
|
||||
}
|
||||
@@ -1271,7 +1313,7 @@ static ssize_t help_show(const struct class *class,
|
||||
{
|
||||
ssize_t n = 0;
|
||||
|
||||
n = sprintf(buf, "%s", unifykeys_help_str);
|
||||
n = scnprintf(buf, PAGE_SIZE, "%s", unifykeys_help_str);
|
||||
buf[n] = 0;
|
||||
|
||||
return n;
|
||||
@@ -1427,6 +1469,8 @@ error3:
|
||||
error2:
|
||||
unregister_chrdev_region(ukdev->uk_devno, 1);
|
||||
error1:
|
||||
uk_dt_release(pdev);
|
||||
ukdev_global = NULL;
|
||||
devm_kfree(&pdev->dev, ukdev);
|
||||
out:
|
||||
amlkey_if_deinit();
|
||||
@@ -1446,6 +1490,7 @@ static void aml_unifykeys_remove(struct platform_device *pdev)
|
||||
cdev_del(&ukdev->cdev);
|
||||
class_unregister(&ukdev->cls);
|
||||
platform_set_drvdata(pdev, NULL);
|
||||
ukdev_global = NULL;
|
||||
amlkey_if_deinit();
|
||||
while (storage_device[i]) {
|
||||
if (storage_device[i]->unifykey_notifier_list.head)
|
||||
|
||||
@@ -14,6 +14,9 @@
|
||||
|
||||
#define KEY_UNIFY_NAME_LEN 48
|
||||
|
||||
/* one list_show line worst case: "%02d: name, dev, perm\n" + '\0' */
|
||||
#define LIST_LINE_MAX (KEY_UNIFY_NAME_LEN + 32)
|
||||
|
||||
#define aml_unify_debug 0
|
||||
#define pr_dbg(fmt...)\
|
||||
do {\
|
||||
@@ -82,7 +85,7 @@ void *get_ukdev(void);
|
||||
|
||||
#ifdef CONFIG_AMLOGIC_UNIFYKEY
|
||||
int __init aml_unifykeys_init(void);
|
||||
void __exit aml_unifykeys_exit(void);
|
||||
void aml_unifykeys_exit(void);
|
||||
#else
|
||||
static int __init aml_unifykeys_init(void)
|
||||
{
|
||||
|
||||
@@ -45,14 +45,17 @@ static int uk_item_parse_dt(struct aml_uk_dev *ukdev, struct device_node *node,
|
||||
goto exit;
|
||||
}
|
||||
if (propname) {
|
||||
if (strcmp(propname, "efuse") == 0)
|
||||
if (strcmp(propname, "efuse") == 0) {
|
||||
tmp_item->dev = KEY_EFUSE;
|
||||
else if (strcmp(propname, "normal") == 0)
|
||||
} else if (strcmp(propname, "normal") == 0) {
|
||||
tmp_item->dev = KEY_NORMAL;
|
||||
else if (strcmp(propname, "secure") == 0)
|
||||
} else if (strcmp(propname, "secure") == 0) {
|
||||
tmp_item->dev = KEY_SECURE;
|
||||
else
|
||||
} else {
|
||||
tmp_item->dev = KEY_UNKNOWN_DEV;
|
||||
ret = -EINVAL;
|
||||
goto exit;
|
||||
}
|
||||
}
|
||||
|
||||
tmp_item->perm = 0;
|
||||
@@ -75,7 +78,7 @@ exit:
|
||||
|
||||
static int uk_item_create(struct platform_device *pdev, int *num)
|
||||
{
|
||||
int ret = -1;
|
||||
int ret;
|
||||
int index;
|
||||
struct device_node *child;
|
||||
struct device_node *np = pdev->dev.of_node;
|
||||
@@ -121,10 +124,18 @@ int uk_dt_release(struct platform_device *pdev)
|
||||
struct key_item_t *item;
|
||||
struct key_item_t *tmp;
|
||||
|
||||
if (!ukdev)
|
||||
return 0;
|
||||
|
||||
if (pdev->dev.of_node)
|
||||
of_node_put(pdev->dev.of_node);
|
||||
|
||||
/*
|
||||
* list_for_each_entry_safe can guarantee item is not null.
|
||||
*/
|
||||
/* coverity[NULL_FIELD:SUPPRESS] */
|
||||
list_for_each_entry_safe(item, tmp, &ukdev->uk_hdr, node) {
|
||||
/* coverity[NULL_FIELD:SUPPRESS] */
|
||||
list_del(&item->node);
|
||||
kfree(item);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user