You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

183 lines
4.2 KiB

/*
* 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 <fcntl.h>
#include <sys/ioctl.h>
#include <unistd.h>
#include <pthread.h>
#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;
}
}