Files

281 lines
6.4 KiB
C

// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
/*
* Copyright (c) 2019 Amlogic, Inc. All rights reserved.
*/
#include "key_manage_i.h"
#include "key_config.h"
static struct key_info_t unify_key_info={.key_num =0, .key_flag = 0};
static struct key_item_t *unifykey_item=NULL;
static int unifykey_item_verify_check(struct key_item_t *key_item)
{
if (!key_item) {
KM_ERR("unify key item is invalid\n");
return -1;
}
if (key_item->dev == KEY_M_UNKNOWN_DEV || key_item->datFmt == KEY_M_MAX_DF) {
KM_ERR("unify key item is invalid\n");
return -1;
}
return 0;
}
static struct key_item_t *unifykey_find_item_by_name(const char *name)
{
struct key_item_t *pre_item;
int i = 0;
const unsigned cnt = unify_key_info.key_num;
for (pre_item = unifykey_item; i < cnt; ++pre_item, ++i) {
if (!strcmp(pre_item->name, name))
return pre_item;
}
KM_ERR("cannot find dev for keyname %s\n", name);
return NULL;
}
enum key_manager_df_e keymanage_dts_get_key_fmt(const char *keyname)
{
struct key_item_t *key_manage;
enum key_manager_df_e keyValFmt = KEY_M_MAX_DF;
if (!unify_key_info.key_flag) {
KM_ERR("/unify not parsed yet!\n");
return KEY_M_MAX_DF;
}
key_manage = unifykey_find_item_by_name(keyname);
if (key_manage == NULL) {
KM_ERR ("%s key name is not exist\n", keyname) ;
return keyValFmt;
}
if (unifykey_item_verify_check(key_manage)) {
KM_ERR ("%s key name is invalid\n", keyname) ;
return keyValFmt;
}
keyValFmt = key_manage->datFmt;
return keyValFmt;
}
//which device does the key stored in
enum key_manager_dev_e keymanage_dts_get_key_device(const char *keyname)
{
struct key_item_t *key_manage;
if (!unify_key_info.key_flag) {
KM_ERR("/unify not parsed yet!\n");
return KEY_M_MAX_DEV;
}
key_manage = unifykey_find_item_by_name(keyname);
if (key_manage == NULL) {
KM_ERR("%s key name is not exist\n",keyname);
return KEY_M_MAX_DEV;
}
if (unifykey_item_verify_check(key_manage)) {
KM_ERR("%s key name is invalid\n",keyname);
return KEY_M_MAX_DEV;
}
return key_manage->dev;
}
int keymanage_get_permit_type(const char* keyname)
{
struct key_item_t *key_manage;
if (!unify_key_info.key_flag) {
KM_ERR("/unify not parsed yet!\n");
return -1;
}
key_manage = unifykey_find_item_by_name(keyname);
if (key_manage == NULL) {
KM_ERR("%s key name is not exist\n", keyname);
return -1;
}
return key_manage->permit;
}
const char* keymanage_dts_get_key_type(const char* keyname)
{
struct key_item_t *key_manage;
if (!unify_key_info.key_flag) {
KM_ERR("/unify not parsed yet!\n");
return NULL;
}
key_manage = unifykey_find_item_by_name(keyname);
if (key_manage == NULL) {
KM_ERR("%s key name is not exist\n",keyname);
return NULL;
}
return key_manage->keyType;
}
char unifykey_get_efuse_version(void)
{
char ver=0;
if (!unify_key_info.key_flag) {
KM_ERR("/unify not parsed yet!\n");
return 0;
}
if (unify_key_info.efuse_version != -1) {
ver = (char)unify_key_info.efuse_version;
}
return ver;
}
const char* keymanage_dts_get_enc_type(const char* keyname)
{
struct key_item_t *key_manage;
if (!unify_key_info.key_flag) {
KM_ERR("/unify not parsed yet!\n");
return NULL;
}
key_manage = unifykey_find_item_by_name(keyname);
if (key_manage == NULL) {
KM_ERR("%s key name is not exist\n",keyname);
return NULL;
}
return key_manage->encType;
}
#if CONFIG_TEE_CRYPTO_API
int keymanage_get_func_type(const char* keyname)
{
struct key_item_t *key_manage;
if (!unify_key_info.key_flag) {
KM_ERR("/unify not parsed yet!\n");
return -1;
}
key_manage = unifykey_find_item_by_name(keyname);
if (key_manage == NULL) {
KM_ERR("%s key name is not exist\n",keyname);
return -1;
}
return key_manage->func;
}
#endif
int unifykey_get_encrypt_type(void)
{
return unify_key_info.encrypt_type;
}
static int unifykey_item_parse(struct key_item_t *item, int id,char *item_path)
{
struct key_item_t *temp_item=NULL;
int count;
temp_item = unifykey_item + id;
if (item->encType[0] != '\0') {
count = strlen(item->encType);
if ( count > KEY_UNIFY_TYPE_LEN_MAX ) {
KM_ERR("key-encrypt [%s] too long\n", item->encType);
return __LINE__;
}
memcpy(temp_item->encType, (char*)item->encType, count);
}
if (item->name[0] != '\0') {
count = strlen(item->name);
if (count >= KEY_UNIFY_NAME_LEN) {
KM_ERR("key-name strlen (%d) > max(%d) at key_%d\n", count, KEY_UNIFY_NAME_LEN - 1, id);
return __LINE__;
}
memcpy(temp_item->name, item->name, count);
temp_item->name[count] = 0;
}
temp_item->dev = item->dev;
temp_item->permit = item->permit;
temp_item->id = id;
if (item->keyType[0] == '\0') //prop 'key-type' not configured, default to raw except special names
strcpy(temp_item->keyType, "raw");
else {
const int keyTypeLen = strlen(item->keyType);
if (keyTypeLen > KEY_UNIFY_TYPE_LEN_MAX) {
KM_ERR("key[%s]cfg key-type[%s] sz %d > max %d\n", temp_item->name, item->keyType, keyTypeLen, KEY_UNIFY_TYPE_LEN_MAX);
return __LINE__;
}
strcpy(temp_item->keyType, item->keyType);
}
#if CONFIG_TEE_CRYPTO_API
if (!item->func)
temp_item->func = 0;
else
temp_item->func = item->func;
#endif
KM_DBG("key[%02d] keyname %s, %d\n", id, temp_item->name, temp_item->dev);
return 0;
}
static int unifykey_item_create(int num)
{
int ret = 0;
int i;
char item_path[100];
for (i=0;i<num;i++) {
sprintf(item_path, "/unifykey/key_%d", i);
struct key_item_t *item = &amlkeys[i];
ret = unifykey_item_parse(item, i, item_path);
if (ret) {
KM_ERR("Fail at parse %s\n", item_path);
return __LINE__;
}
}
// printf("unifykey-num fact is %x\n",count);
return 0;
}
//parse and cache the dts cfg
//TODO: check keys names has no duplicated
int keymanage_dts_parse(const void* dt_addr)
{
int ret = 0;
unify_key_info.key_num = KEYNUM;
KM_MSG("key_num: %d\n", unify_key_info.key_num);
if (unify_key_info.key_num <= 0) {
KM_ERR("unifykey-num is not configured\n");
return __LINE__;
}
if (unify_key_info.key_num > 256) {
KM_ERR("Cfg key_num is %d > 32,pls check!\n", unify_key_info.key_num);
return __LINE__;
}
unify_key_info.encrypt_type = -1;
if (unifykey_item) {
free(unifykey_item);
}
const unsigned keyInfBufLen = unify_key_info.key_num * sizeof(struct key_item_t);
unifykey_item = (struct key_item_t*)malloc(keyInfBufLen);
memset(unifykey_item, 0 , keyInfBufLen);
ret = unifykey_item_create(unify_key_info.key_num);
unify_key_info.key_flag = ret ? 0 : 1;
return ret;
}