From 8287467a4b977567f2d572b8687b834d07efe00d Mon Sep 17 00:00:00 2001 From: Jiamin Ma Date: Sat, 29 Jul 2017 21:20:06 +0800 Subject: [PATCH] unifykey: add secure storage and nand key support PD#148390: this commit fix two problems 1. the previews way to detect storage type is invalid 2. the previews define of max key size for nand and emmc is wrong Change-Id: Ie7c05f3e0d85c2386177e196187f52786e0955f4 Signed-off-by: Jiamin Ma --- arch/arm/boot/dts/amlogic/meson8b.dtsi | 1 + drivers/amlogic/unifykey/storagekey.c | 13 +++++-- .../unifykey/v7/key_storage/key_service_routine.c | 3 ++ drivers/amlogic/unifykey/v7/key_storage/storage.c | 40 +++++++++------------- drivers/amlogic/unifykey/v7/key_storage/storage.h | 3 +- .../amlogic/unifykey/v7/key_storage/storage_apis.c | 10 ++++-- .../amlogic/unifykey/v7/key_storage/storage_data.h | 1 - .../amlogic/unifykey/v7/key_storage/storage_def.h | 4 +++ drivers/amlogic/unifykey/v7/securitykey.c | 25 ++++++++++++-- drivers/amlogic/unifykey/v8/securitykey.c | 4 +++ include/linux/amlogic/unifykey/security_key.h | 1 + .../amlogic/unifykey/v7/key_service_routine.h | 2 ++ 12 files changed, 75 insertions(+), 32 deletions(-) diff --git a/arch/arm/boot/dts/amlogic/meson8b.dtsi b/arch/arm/boot/dts/amlogic/meson8b.dtsi index 5cdaf1f..6a09eb2 100644 --- a/arch/arm/boot/dts/amlogic/meson8b.dtsi +++ b/arch/arm/boot/dts/amlogic/meson8b.dtsi @@ -219,6 +219,7 @@ storage_set_enctype = <0x8200006A>; storage_get_enctype = <0x8200006B>; storage_version = <0x8200006C>; + storage_set_type = <0x8200006D>; }; cpu_iomap { diff --git a/drivers/amlogic/unifykey/storagekey.c b/drivers/amlogic/unifykey/storagekey.c index e24bf9e..bb3bfe6 100644 --- a/drivers/amlogic/unifykey/storagekey.c +++ b/drivers/amlogic/unifykey/storagekey.c @@ -114,7 +114,7 @@ EXPORT_SYMBOL(storage_ops_write); int32_t amlkey_init(uint8_t *seed, uint32_t len, int encrypt_type) { int32_t ret = 0; - uint32_t buffer_size, actual_size; + uint32_t actual_size; #ifndef OTHER_METHOD_CALL ret = store_operation_init(); @@ -131,8 +131,17 @@ int32_t amlkey_init(uint8_t *seed, uint32_t len, int encrypt_type) goto _out; } + if (is_meson_m8b_cpu()) { + if ((void *)kallsyms_lookup_name("nand_key_read") + == (void *)store_key_read) + secure_storage_type(0); + else + secure_storage_type(1); + } + /* get buffer from bl31 */ - storagekey_info.buffer = secure_storage_getbuffer(&buffer_size); + storagekey_info.buffer = + secure_storage_getbuffer(&storagekey_info.size); if (storagekey_info.buffer == NULL) { pr_err("%s() %d: can't get buffer from bl31!\n", __func__, __LINE__); diff --git a/drivers/amlogic/unifykey/v7/key_storage/key_service_routine.c b/drivers/amlogic/unifykey/v7/key_storage/key_service_routine.c index 477aad9..aa7c591 100644 --- a/drivers/amlogic/unifykey/v7/key_storage/key_service_routine.c +++ b/drivers/amlogic/unifykey/v7/key_storage/key_service_routine.c @@ -42,6 +42,9 @@ uint64_t storage_service_routine(uint32_t fid, case SECURITY_KEY_NOTIFY_EX: storage_api_notify_ex(x1); break; + case SECURITY_KEY_STORAGE_TYPE: + storage_api_storage_type(x1); + break; case SECURITY_KEY_QUERY: ret = storage_api_query(in, out); break; diff --git a/drivers/amlogic/unifykey/v7/key_storage/storage.c b/drivers/amlogic/unifykey/v7/key_storage/storage.c index ce6114e..817e8b3 100644 --- a/drivers/amlogic/unifykey/v7/key_storage/storage.c +++ b/drivers/amlogic/unifykey/v7/key_storage/storage.c @@ -27,7 +27,8 @@ static int emmc_key_transfer(u8 *buf, u32 *value, u32 len, u32 direct); static uint32_t emmckey_checksum(uint8_t *buf, uint32_t length); - +/* static var is initialized to be 0 by default */ +static uint32_t storage_is_emmc; static void storage_hash(uint8_t *input, uint32_t insize, uint8_t *output) { @@ -64,7 +65,7 @@ int32_t storage_writeToFlash(void) /* the below check is ugly, someone should move the * related code to emmc key */ - if (kallsyms_lookup_name("emmc_key_read")) { + if (storage_is_emmc) { pemmc_key_head = (struct emmc_key_head *)pblock; pstorage_key_head = (struct key_storage_head *) (pblock + sizeof(struct emmc_key_head)); @@ -529,7 +530,10 @@ static int emmc_key_transfer(u8 *buf, u32 *value, u32 len, u32 direct) return 0; } - +void storage_set_type(uint32_t is_emmc) +{ + storage_is_emmc = is_emmc; +} /* initialize nodelist from internal storage block*/ void storage_init(uint32_t flashsize) @@ -548,7 +552,7 @@ void storage_init(uint32_t flashsize) int key_hex_len; /* we should handle an extra header for emmc key */ - if (kallsyms_lookup_name("emmc_key_read")) { + if (storage_is_emmc) { pemmc_key_head = (struct emmc_key_head *)pblock; pstorage_key_head = (struct key_storage_head *) (pblock + sizeof(struct emmc_key_head)); @@ -561,20 +565,14 @@ void storage_init(uint32_t flashsize) if (!emmc_key_transfer(pemmc_key_head->mark, &pemmc_key_head->mark_checksum, 8, 0)) { if (memcmp(pemmc_key_head->mark, - "emmckeys", 8) != 0) { - flash_storage_size = flashsize; + "emmckeys", 8) != 0) goto storage_init_err; - } - } else { - flash_storage_size = flashsize; + } else goto storage_init_err; - } } - if (memcmp(pstorage_key_head->mark, "keyexist", 8) != 0) { - flash_storage_size = flashsize; + if (memcmp(pstorage_key_head->mark, "keyexist", 8) != 0) goto storage_init_err; - } /* parse each key */ tmp_content = (char *)&pstorage_key_head[1]; // skip storage key header @@ -653,19 +651,12 @@ storage_init_exit: uint32_t get_share_storage_block_base(void) { if (storage_share_block == NULL) - storage_share_block = storage_malloc(STORAGE_BLOCK_SIZE); + storage_share_block = storage_malloc( + (int32_t)get_share_storage_block_size()); return (uint32_t)storage_share_block; } -uint32_t get_internal_storage_base(void) -{ - if (internal_storage_block == NULL) - internal_storage_block = storage_malloc(STORAGE_BLOCK_SIZE/4); - - return (uint32_t)internal_storage_block; -} - void free_share_storage(void) { if (!storage_shar_in_block) @@ -684,7 +675,10 @@ void free_internal_storage(void) uint64_t get_share_storage_block_size(void) { - return flash_storage_size; + if (storage_is_emmc) + return STORAGE_BLOCK_SIZE; + else + return STORAGE_BLOCK_SIZE_2; } int64_t storage_get_enctype(void) diff --git a/drivers/amlogic/unifykey/v7/key_storage/storage.h b/drivers/amlogic/unifykey/v7/key_storage/storage.h index 6f802c95..6b7f041b 100644 --- a/drivers/amlogic/unifykey/v7/key_storage/storage.h +++ b/drivers/amlogic/unifykey/v7/key_storage/storage.h @@ -159,7 +159,6 @@ struct storage_ns_message { /* internal apis*/ uint32_t get_share_storage_block_base(void); void free_share_storage(void); -uint32_t get_internal_storage_base(void); void free_internal_storage(void); uint64_t get_share_storage_block_size(void); @@ -182,6 +181,7 @@ int64_t storage_version(void); /*exported APIs*/ void storage_init(uint32_t flashsize); +void storage_set_type(uint32_t is_emmc); uint64_t storage_api_write(void *in); uint64_t storage_api_read(void *in, void **out); uint64_t storage_api_tell(void *in, void **out); @@ -190,6 +190,7 @@ uint64_t storage_api_verify(void *in, void **out); uint64_t storage_api_status(void *in, void **out); void storage_api_notify(void); void storage_api_notify_ex(uint32_t flashsize); +void storage_api_storage_type(uint32_t is_emmc); uint64_t storage_api_list(void); uint64_t storage_api_remove(void); int64_t storage_api_get_enctype(void); diff --git a/drivers/amlogic/unifykey/v7/key_storage/storage_apis.c b/drivers/amlogic/unifykey/v7/key_storage/storage_apis.c index 4dbb8bb..3624804 100644 --- a/drivers/amlogic/unifykey/v7/key_storage/storage_apis.c +++ b/drivers/amlogic/unifykey/v7/key_storage/storage_apis.c @@ -138,10 +138,16 @@ uint64_t storage_api_status(void *in, void **out) void storage_api_notify_ex(uint32_t flashsize) { - if (flashsize > STORAGE_BLOCK_SIZE) { - //ERROR("flash size is too large!\n"); + if (flashsize > get_share_storage_block_size()) { + pr_err("flash size is too large!\n"); return; } storage_init(flashsize); } +void storage_api_storage_type(uint32_t is_emmc) +{ + storage_set_type(is_emmc); +} + + diff --git a/drivers/amlogic/unifykey/v7/key_storage/storage_data.h b/drivers/amlogic/unifykey/v7/key_storage/storage_data.h index 2a42875..3d8ee22 100644 --- a/drivers/amlogic/unifykey/v7/key_storage/storage_data.h +++ b/drivers/amlogic/unifykey/v7/key_storage/storage_data.h @@ -30,6 +30,5 @@ static uint8_t *storage_shar_in_block; static uint8_t *storage_shar_out_block; static uint8_t *storage_share_block; static uint8_t *internal_storage_block; -static uint32_t flash_storage_size = STORAGE_BLOCK_SIZE; #endif diff --git a/drivers/amlogic/unifykey/v7/key_storage/storage_def.h b/drivers/amlogic/unifykey/v7/key_storage/storage_def.h index 4db65cf..f7d5cd9 100644 --- a/drivers/amlogic/unifykey/v7/key_storage/storage_def.h +++ b/drivers/amlogic/unifykey/v7/key_storage/storage_def.h @@ -18,6 +18,10 @@ #ifndef __STORAGE_DEF_H_ #define __STORAGE_DEF_H_ +/* for emmc */ +//#define STORAGE_BLOCK_SIZE (128*1024 - 28) #define STORAGE_BLOCK_SIZE (256*1024) +/* for nand */ +#define STORAGE_BLOCK_SIZE_2 (60620) #endif diff --git a/drivers/amlogic/unifykey/v7/securitykey.c b/drivers/amlogic/unifykey/v7/securitykey.c index 0c5c43b..c6b0165 100644 --- a/drivers/amlogic/unifykey/v7/securitykey.c +++ b/drivers/amlogic/unifykey/v7/securitykey.c @@ -47,10 +47,14 @@ static unsigned long storage_verify_func; static unsigned long storage_list_func; static unsigned long storage_remove_func; static unsigned long storage_notify_ex_func; +static unsigned long storage_type_func; static unsigned long storage_set_enctype_func; static unsigned long storage_get_enctype_func; static unsigned long storage_version_func; +static unsigned int block_base_func_id; +static unsigned int block_size_func_id; + static DEFINE_MUTEX(storage_lock); #if 0 @@ -108,6 +112,11 @@ static inline int32_t smc_to_linux_errno(uint64_t errno) void *secure_storage_getbuffer(uint32_t *size) { + storage_block_size = storage_service_routine( + block_size_func_id, 0, NULL, NULL); + storage_block_base = (void *)(uint32_t)storage_service_routine( + block_base_func_id, 0, NULL, NULL); + *size = storage_block_size; return (void *)storage_block_base; } @@ -120,6 +129,15 @@ void secure_storage_notifier_ex(uint32_t storagesize) mutex_unlock(&storage_lock); } +void secure_storage_type(uint32_t is_emmc) +{ + mutex_lock(&storage_lock); + storage_service_routine(storage_type_func, + is_emmc, NULL, NULL); + mutex_unlock(&storage_lock); +} + + int32_t secure_storage_write(uint8_t *keyname, uint8_t *keybuf, uint32_t keylen, uint32_t keyattr) { @@ -415,10 +433,9 @@ static int storage_probe(struct platform_device *pdev) storage_block_size = 0; if (!of_property_read_u32(np, "storage_block_func", &id)) - storage_block_base = (void *)(uint32_t)storage_service_routine( - id, 0, NULL, NULL); + block_base_func_id = id; if (!of_property_read_u32(np, "storage_size_func", &id)) - storage_block_size = storage_service_routine(id, 0, NULL, NULL); + block_size_func_id = id; if (!of_property_read_u32(np, "storage_free", &id)) storage_free_func = id; @@ -440,6 +457,8 @@ static int storage_probe(struct platform_device *pdev) storage_remove_func = id; if (!of_property_read_u32(np, "storage_notify_ex", &id)) storage_notify_ex_func = id; + if (!of_property_read_u32(np, "storage_set_type", &id)) + storage_type_func = id; if (!of_property_read_u32(np, "storage_set_enctype", &id)) storage_set_enctype_func = id; if (!of_property_read_u32(np, "storage_get_enctype", &id)) diff --git a/drivers/amlogic/unifykey/v8/securitykey.c b/drivers/amlogic/unifykey/v8/securitykey.c index f608c90..5b6b23f 100644 --- a/drivers/amlogic/unifykey/v8/securitykey.c +++ b/drivers/amlogic/unifykey/v8/securitykey.c @@ -98,6 +98,10 @@ void secure_storage_notifier_ex(uint32_t storagesize) { } +void secure_storage_type(uint32_t is_emmc) +{ +} + int32_t secure_storage_write(uint8_t *keyname, uint8_t *keybuf, uint32_t keylen, uint32_t keyattr) { diff --git a/include/linux/amlogic/unifykey/security_key.h b/include/linux/amlogic/unifykey/security_key.h index 8cf7ca3..04e57d0 100644 --- a/include/linux/amlogic/unifykey/security_key.h +++ b/include/linux/amlogic/unifykey/security_key.h @@ -35,6 +35,7 @@ int32_t secure_storage_tell(uint8_t *keyname, uint32_t *retval); int32_t secure_storage_status(uint8_t *keyname, uint32_t *retval); void *secure_storage_getbuffer(uint32_t *size); void secure_storage_notifier_ex(uint32_t storagesize); +void secure_storage_type(uint32_t is_emmc); int32_t secure_storage_set_enctype(uint32_t type); int32_t secure_storage_get_enctype(void); int32_t secure_storage_version(void); diff --git a/include/linux/amlogic/unifykey/v7/key_service_routine.h b/include/linux/amlogic/unifykey/v7/key_service_routine.h index a6636d8..50d2abd 100644 --- a/include/linux/amlogic/unifykey/v7/key_service_routine.h +++ b/include/linux/amlogic/unifykey/v7/key_service_routine.h @@ -112,6 +112,8 @@ #define SECURITY_KEY_SET_ENCTYPE 0x8200006A #define SECURITY_KEY_GET_ENCTYPE 0x8200006B #define SECURITY_KEY_VERSION 0x8200006C +#define SECURITY_KEY_STORAGE_TYPE 0x8200006D + #define AES_GCM_SCP 0x82000070 -- 2.7.4