/* * Copyright (c) Hisilicon Technologies Co., Ltd. 2019-2021. All rights reserved. * Description: Defines the interfaces used by the keyslot module. * Author: Hisilicon * Create: 2019-06-26 */ #include "mpi_keyslot_ext.h" #include #include #include #include #include "soc_module.h" #include "mpi_keyslot_define.h" #include "mpi_keyslot_teec.h" #include "mpi_keyslot_ree.h" #define SOC_DEV_KEYSLOT_NAME "soc_keyslot" struct keyslot_initial { pthread_mutex_t lock; atomic_t ref_count; td_s32 keyslot_fd; }; static struct keyslot_initial g_keyslot_initial = { .lock = PTHREAD_MUTEX_INITIALIZER, .ref_count = 0, .keyslot_fd = -1, }; static struct keyslot_initial *priv_get_keyslot_initial(td_void) { return &g_keyslot_initial; } static td_s32 keyslot_fd(td_void) { struct keyslot_initial *initial = priv_get_keyslot_initial(); return initial->keyslot_fd; } td_s32 ext_mpi_keyslot_init(td_void) { td_s32 dev_fd = 0; td_s32 ret; struct keyslot_initial *initial = priv_get_keyslot_initial(); ks_func_enter(); mutex_lock(&initial->lock); if (atomic_read(&initial->ref_count) > 0) { atomic_inc(&initial->ref_count); ret = TD_SUCCESS; goto out; } dev_fd = open("/dev/" SOC_DEV_KEYSLOT_NAME, O_RDWR, 0); if (dev_fd < 0) { ret = SOC_ERR_KS_OPEN_ERR; ext_err_ks("dev_fd=%d\n", dev_fd); goto out; } ret = tee_sec_init(); if (ret != TD_SUCCESS) { print_err_func(tee_sec_init, ret); goto tee_exit; } atomic_set(&initial->ref_count, 1); initial->keyslot_fd = dev_fd; mutex_unlock(&initial->lock); return TD_SUCCESS; tee_exit: close(dev_fd); out: mutex_unlock(&initial->lock); ks_func_exit(); return ret; } td_s32 ext_mpi_keyslot_deinit(td_void) { struct keyslot_initial *initial = priv_get_keyslot_initial(); ks_func_enter(); mutex_lock(&initial->lock); if (atomic_read(&initial->ref_count) > 0) { atomic_dec(&initial->ref_count); } if (atomic_read(&initial->ref_count) != 0) { goto out; } (td_void)tee_sec_deinit(); close(initial->keyslot_fd); initial->keyslot_fd = -1; atomic_set(&initial->ref_count, -1); out: mutex_unlock(&initial->lock); ks_func_exit(); return TD_SUCCESS; } static td_s32 priv_mpi_keyslot_create(const ext_keyslot_attr *attr, td_handle *handle) { td_s32 ret; ks_entry entry = {0}; ks_func_enter(); entry.ks_type = attr->type; ret = ioctl(keyslot_fd(), CMD_KS_CREATE, &entry); if (ret != TD_SUCCESS) { print_err_hex4(keyslot_fd(), CMD_KS_CREATE, attr->type, ret); return ret; } *handle = entry.ks_handle; ks_func_exit(); return TD_SUCCESS; } td_s32 ext_mpi_keyslot_create(const ext_keyslot_attr *attr, td_handle *handle) { if (handle == TD_NULL || attr == TD_NULL) { print_err_code(SOC_ERR_KS_PTR_NULL); return SOC_ERR_KS_PTR_NULL; }; if (attr->secure_mode == EXT_KEYSLOT_SECURE_MODE_NONE) { return priv_mpi_keyslot_create(attr, handle); } else if (attr->secure_mode == EXT_KEYSLOT_SECURE_MODE_TEE) { return tee_sec_key_slot_create(attr->type, handle); } else { print_err_hex3(attr->type, attr->secure_mode, SOC_ERR_KS_INVALID_PARAM); return SOC_ERR_KS_INVALID_PARAM; } } static td_s32 priv_mpi_keyslot_destroy(td_handle handle) { td_s32 ret; ks_func_enter(); ret = ioctl(keyslot_fd(), CMD_KS_DESTORY, &handle); if (ret != TD_SUCCESS) { print_err_hex4(keyslot_fd(), CMD_KS_DESTORY, handle, ret); return ret; } ks_func_exit(); return TD_SUCCESS; } td_s32 ext_mpi_keyslot_destroy(td_handle handle) { ext_keyslot_priv_attr attr; attr.u8 = TD_HANDLE_GET_PRIVATE_DATA(handle); if (attr.bits.secure == 0x0) { return priv_mpi_keyslot_destroy(handle); } else if (attr.bits.secure == 0x1) { return tee_sec_key_slot_destory(handle); } else { print_err_hex2(handle, SOC_ERR_KS_INVALID_PARAM); return SOC_ERR_KS_INVALID_PARAM; } }