/* SPDX-License-Identifier: (GPL-2.0+ OR MIT) */ /* * drivers/keymanage/km_efuse_key.c * * Copyright (C) 2020 Amlogic, Inc. All rights reserved. * */ #include "key_manage_i.h" #include #include #include #define SECURE_BOOT_KEY_NAME "secure_boot_set" extern int efuse_usr_api_init_dtb(const char* dt_addr); extern int efuse_usr_api_get_cfg_key_size(const char* keyname, unsigned* pSz); extern int efuse_usr_api_write_key(const char* keyname, const void* keydata, const unsigned dataSz); extern int efuse_usr_api_read_key(const char* keyname, void* databuf, const unsigned bufSz); int keymanage_efuse_init(const char *buf, int len) { char ver; int ret = 0; const char* dtbLoadAddr = (char*) getenv_ulong("dtb_mem_addr", 16, CONFIG_SYS_SDRAM_BASE + (16U<<20)); if (!dtbLoadAddr) { KM_ERR("dtbLoadAddr is NULL\n"); return __LINE__; } ret = efuse_usr_api_init_dtb(dtbLoadAddr); if (ret) { KM_ERR("efuse init failed\n"); return __LINE__; } ver = unifykey_get_efuse_version(); if (ver == 0) { KM_DBG("efuse version not cfg\n"); return 0; } //TODO: program the efuse version return ret; } int keymange_efuse_exit(void) { return 0; } //must be hexdata if stored in efuse int keymanage_efuse_write(const char *keyname, const void* keydata, unsigned int datalen) { int ret = 0; if (!strcmp(SECURE_BOOT_KEY_NAME, keyname)) { char _cmdbuf[96]; sprintf(_cmdbuf, "efuse %s %p", keyname, keydata); ret = run_command(_cmdbuf, 0);; } else { ret = efuse_usr_api_write_key(keyname, keydata, datalen); } return ret; } ssize_t keymanage_efuse_size(const char* keyname) { int ret = 0; unsigned cfgSz = 0; if (!strcmp(SECURE_BOOT_KEY_NAME, keyname)) { KM_ERR("efuse pattern cannot be query[%s]\n", keyname); return 0; } ret = efuse_usr_api_get_cfg_key_size(keyname, &cfgSz); if (ret || !cfgSz) { KM_ERR("Fail at get cfg size for efuse key[%s]\n", keyname); return 0; } return cfgSz; } int keymanage_efuse_exist(const char* keyname) { if (!strcmp(SECURE_BOOT_KEY_NAME, keyname)) { const unsigned long cfg10 = IS_FEAT_BOOT_VERIFY(); KM_MSG("cfg10=0x%lX\n", cfg10); return ( cfg10 ); } else { int ret = 0; const ssize_t cfgSz = keymanage_efuse_size(keyname); char* databuf = NULL; int isEmpty = 1; int i = 0; databuf = (char*)malloc(cfgSz); if (!databuf) { KM_ERR("Fail to alloc bufsz 0x%x for key %s\n", (unsigned)cfgSz, keyname); return 0; } ret = keymanage_efuse_read(keyname, databuf, cfgSz); if (ret) { KM_ERR("Fail at read key[%s]\n", keyname); goto _exit; } for (i = 0; i < cfgSz && isEmpty; ++i) { isEmpty = !databuf[i]; } _exit: free(databuf); return !isEmpty; } return __LINE__; } int keymanage_efuse_query_can_read(const char* keyname) { if (!strcmp(SECURE_BOOT_KEY_NAME, keyname)) { return 0; } else { return 1;//user space always can be read } } //data format is hexdata int keymanage_efuse_read(const char *keyname, void* databuf, const unsigned bufSz) { int ret = 0; unsigned cfgSz = 0; cfgSz = keymanage_efuse_size(keyname); if (cfgSz > bufSz) { KM_ERR("buf sz 0x%x < dts cfg sz 0x%x\n", bufSz, cfgSz); return __LINE__; } ret = efuse_usr_api_read_key(keyname, databuf, cfgSz); return ret; }