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.

468 lines
13 KiB

/*
* Copyright (c) Hisilicon Technologies Co., Ltd. 2019-2021. All rights reserved.
* Description: keyladder tsr2rcipher sample.
* Author: Hisilicon
* Create: 2019-09-19
*/
#include "securec.h"
#include "uapi_system.h"
#include "uapi_memory.h"
#include "uapi_tsr2rcipher.h"
#include "uapi_keyslot.h"
#include "uapi_klad.h"
#include "parse_config_file.h"
#define sample_get_inputcmd(input_cmd) fgets((char *)(input_cmd), (sizeof(input_cmd) - 1), stdin)
#define klad_err_print_hex(val) printf("[%-32s][line:%04d]%s = 0x%08x\n", __FUNCTION__, __LINE__, #val, val)
#define klad_err_print_info(val) printf("[%-32s][line:%04d]%s\n", __FUNCTION__, __LINE__, val)
#define klad_err_print_val(val) printf("[%-32s][line:%04d]%s = %d\n", __FUNCTION__, __LINE__, #val, val)
#define klad_err_print_point(val) printf("[%-32s][line:%04d]%s = %p\n", __FUNCTION__, __LINE__, #val, val)
#define klad_print_error_code(err_code) \
printf("[%-32s][line:%04d]return [0x%08x]\n", __FUNCTION__, __LINE__, err_code)
#define klad_print_error_func(func, err_code) \
printf("[%-32s][line:%04d]call [%s] return [0x%08x]\n", __FUNCTION__, __LINE__, #func, err_code)
#define KEY_LEN 16
#define DATA_LEN 188
#define CMD_MAX_NUM 32
static td_u8 g_input_pkt[DATA_LEN] = {0};
static td_u8 g_session_key[KEY_LEN] = {0};
static td_u8 g_tsc_iv[KEY_LEN] = {0};
static td_u8 g_content_key[KEY_LEN] = {0};
td_void dump_data(const td_char *name, const td_u8 *data, td_u32 len)
{
td_u32 index;
if (name == NULL || data == NULL) {
return;
}
printf("begin dump %s\n", name);
printf("data len = %d\n", len);
printf("data:\n");
for (index = 0; index < len; index++) {
printf("%02X ", data[index]);
if ((index + 1) % KEY_LEN == 0) {
printf("\n");
}
}
printf("\ndump end\n");
}
td_s32 set_key(td_handle klad)
{
td_s32 ret;
errno_t errno;
uapi_klad_session_key session_key = {0};
uapi_klad_content_key content_key = {0};
session_key.level = UAPI_KLAD_LEVEL1;
session_key.alg = UAPI_KLAD_ALG_TYPE_AES;
session_key.key_size = KEY_LEN;
errno = memcpy_s(session_key.key, UAPI_KLAD_MAX_KEY_LEN, g_session_key, KEY_LEN);
if (errno != EOK) {
klad_print_error_func(memcpy_s, errno);
return TD_FAILURE;
}
ret = uapi_klad_set_session_key(klad, &session_key);
if (ret != TD_SUCCESS) {
klad_print_error_func(uapi_klad_set_session_key, ret);
return ret;
}
content_key.odd = 0;
content_key.key_size = KEY_LEN;
content_key.alg = UAPI_KLAD_ALG_TYPE_AES;
errno = memcpy_s(content_key.key, UAPI_KLAD_MAX_KEY_LEN, g_content_key, KEY_LEN);
if (errno != EOK) {
klad_print_error_func(memcpy_s, errno);
return TD_FAILURE;
}
ret = uapi_klad_set_content_key(klad, &content_key);
if (ret != TD_SUCCESS) {
klad_print_error_func(uapi_klad_set_content_key, ret);
return ret;
}
return TD_SUCCESS;
}
static td_s32 priv_key_init(td_void)
{
td_s32 ret;
ret = uapi_sys_init();
if (ret != TD_SUCCESS) {
klad_print_error_func(uapi_sys_init, ret);
goto out;;
}
ret = uapi_tsr2rcipher_init();
if (ret != TD_SUCCESS) {
klad_print_error_func(uapi_tsr2rcipher_init, ret);
goto sys_deinit;
}
ret = uapi_keyslot_init();
if (ret != TD_SUCCESS) {
klad_print_error_func(uapi_keyslot_init, ret);
goto tsc_deinit;
}
ret = uapi_klad_init();
if (ret != TD_SUCCESS) {
klad_print_error_func(uapi_klad_init, ret);
goto ks_deinit;
}
goto out;
ks_deinit:
uapi_keyslot_deinit();
tsc_deinit:
uapi_tsr2rcipher_deinit();
sys_deinit:
uapi_sys_deinit();
out:
return ret;
}
static td_s32 priv_klad_create(uapi_tsr2rcipher_attr *tsc_attr, td_handle *handle_tsc,
td_handle *handle_ks, td_handle *handle_klad)
{
td_s32 ret;
uapi_keyslot_attr keyslot_attr;
ret = uapi_tsr2rcipher_get_default_attr(tsc_attr);
if (ret != TD_SUCCESS) {
klad_print_error_func(uapi_tsr2rcipher_get_default_attr, ret);
goto out;
}
tsc_attr->alg = UAPI_TSR2RCIPHER_ALG_AES_CBC;
tsc_attr->is_create_keyslot = TD_FALSE;
ret = uapi_tsr2rcipher_create(tsc_attr, handle_tsc);
if (ret != TD_SUCCESS) {
klad_print_error_func(uapi_tsr2rcipher_create, ret);
goto out;
}
keyslot_attr.secure_mode = UAPI_KEYSLOT_SECURE_MODE_NONE;
keyslot_attr.type = UAPI_KEYSLOT_TYPE_TSCIPHER;
ret = uapi_keyslot_create(&keyslot_attr, handle_ks);
if (ret != TD_SUCCESS) {
klad_print_error_func(uapi_keyslot_create, ret);
goto tsc_destroy;
}
ret = uapi_klad_create(handle_klad);
if (ret != TD_SUCCESS) {
klad_print_error_func(uapi_klad_create, ret);
goto ks_destroy;
}
goto out;
ks_destroy:
uapi_keyslot_destroy(*handle_ks);
tsc_destroy:
uapi_tsr2rcipher_destroy(*handle_tsc);
out:
return ret;
}
static td_s32 priv_klad_attach(td_handle handle_klad, td_handle handle_ks,
td_handle handle_tsc, uapi_tsr2rcipher_attr *tsc_attr)
{
td_s32 ret;
uapi_klad_attr attr_klad = {0};
attr_klad.klad_cfg.owner_id = 0;
attr_klad.klad_cfg.klad_type = UAPI_KLAD_TYPE_R2R;
attr_klad.key_cfg.encrypt_support = 1;
attr_klad.key_cfg.decrypt_support = 1;
attr_klad.key_cfg.engine = UAPI_CRYPTO_ALG_AES_CISSA;
ret = uapi_klad_set_attr(handle_klad, &attr_klad);
if (ret != TD_SUCCESS) {
klad_print_error_func(uapi_klad_set_attr, ret);
goto out;
}
ret = uapi_klad_attach(handle_klad, handle_ks);
if (ret != TD_SUCCESS) {
klad_print_error_func(uapi_klad_attach, ret);
goto out;
}
ret = uapi_tsr2rcipher_attach_keyslot(handle_tsc, handle_ks);
if (ret != TD_SUCCESS) {
klad_print_error_func(uapi_tsr2rcipher_attach_keyslot, ret);
goto klad_detach;
}
ret = set_key(handle_klad);
if (ret != TD_SUCCESS) {
klad_print_error_func(set_key, ret);
goto tsc_detach;
}
ret = uapi_tsr2rcipher_get_attr(handle_tsc, tsc_attr);
if (ret != TD_SUCCESS) {
klad_print_error_func(uapi_tsr2rcipher_get_default_attr, ret);
goto tsc_detach;
}
tsc_attr->is_odd_key = TD_FALSE;
ret = uapi_tsr2rcipher_set_attr(handle_tsc, tsc_attr);
if (ret != TD_SUCCESS) {
klad_print_error_func(uapi_tsr2rcipher_set_attr, ret);
goto tsc_detach;
}
goto out;
tsc_detach:
uapi_tsr2rcipher_detach_keyslot(handle_tsc, handle_ks);
klad_detach:
uapi_klad_detach(handle_klad, handle_ks);
out:
return ret;
}
static td_s32 priv_klad_mem_map(td_handle handle_tsc, uapi_tsr2rcipher_mem_handle *src_mem_handle,
td_u8 **src_virt, uapi_tsr2rcipher_mem_handle *dst_mem_handle, td_u8 **dst_virt)
{
td_s32 ret;
const td_u32 data_len = DATA_LEN;
ret = uapi_tsr2rcipher_set_iv(handle_tsc, UAPI_TSR2RCIPHER_IV_EVEN, g_tsc_iv, KEY_LEN);
if (ret != TD_SUCCESS) {
klad_print_error_func(uapi_tsr2rcipher_set_iv, ret);
goto out;
}
src_mem_handle->mem_handle = uapi_mem_new("src_buf", strlen("src_buf") + 1, data_len, TD_FALSE);
if (src_mem_handle->mem_handle < 0) {
klad_print_error_func(uapi_mem_new, TD_FAILURE);
goto out;
}
src_mem_handle->addr_offset = 0;
printf("src_phy: 0x%llx!\n", src_mem_handle->mem_handle);
*src_virt = uapi_mem_map(src_mem_handle->mem_handle, data_len);
if (*src_virt == TD_NULL) {
klad_print_error_func(uapi_mem_map, TD_FAILURE);
goto src_del;
}
dst_mem_handle->mem_handle = uapi_mem_new("dst_buf", strlen("dst_buf") + 1, data_len, TD_FALSE);
if (dst_mem_handle->mem_handle < 0) {
klad_print_error_func(uapi_mem_new, TD_FAILURE);
goto src_unmap;
}
dst_mem_handle->addr_offset = 0;
printf("dst_phy: 0x%llx!\n", dst_mem_handle->mem_handle);
*dst_virt = uapi_mem_map(dst_mem_handle->mem_handle, data_len);
if (*dst_virt == TD_NULL) {
klad_print_error_func(uapi_mem_map, TD_FAILURE);
goto dst_del;
}
goto out;
dst_del:
uapi_mem_delete(dst_mem_handle->mem_handle);
src_unmap:
uapi_mem_unmap(*src_virt, DATA_LEN);
src_del:
uapi_mem_delete(src_mem_handle->mem_handle);
out:
return ret;
}
static td_s32 priv_klad_encrypt(td_handle handle_tsc, const uapi_tsr2rcipher_mem_handle *src_mem_handle,
td_u8 *src_virt, td_u8 *dst_virt, const uapi_tsr2rcipher_mem_handle *dst_mem_handle)
{
td_s32 ret = TD_FAILURE;
errno_t errno;
const td_u32 data_len = DATA_LEN;
td_char input_cmd[CMD_MAX_NUM] = {0};
errno = memset_s(src_virt, data_len, 0x0, data_len * sizeof(td_u8));
if (errno != EOK) {
klad_print_error_func(memset_s, errno);
goto out;
}
errno = memset_s(dst_virt, data_len, 0x0, data_len * sizeof(td_u8));
if (errno != EOK) {
klad_print_error_func(memset_s, errno);
goto out;
}
errno = memcpy_s(src_virt, data_len, g_input_pkt, data_len * sizeof(td_u8));
if (errno != EOK) {
klad_print_error_func(memcpy_s, errno);
goto out;
}
ret = uapi_tsr2rcipher_encrypt(handle_tsc, *src_mem_handle, *dst_mem_handle, data_len);
if (ret != TD_SUCCESS) {
klad_print_error_func(uapi_tsr2rcipher_encrypt, ret);
dump_data("dst_buf", dst_virt, data_len);
goto out;
}
dump_data("src_buf", src_virt, data_len);
dump_data("dst_buf", dst_virt, data_len);
printf("please input 'q' to quit!\n");
while (1) {
sample_get_inputcmd(input_cmd);
if (input_cmd[0] == 'q') {
printf("prepare to quit!\n");
break;
}
}
out:
return ret;
}
static td_void priv_klad_umem_map(td_u8 *src_virt, const uapi_tsr2rcipher_mem_handle *src_mem_handle,
td_u8 *dst_virt, const uapi_tsr2rcipher_mem_handle *dst_mem_handle)
{
uapi_mem_unmap(dst_virt, DATA_LEN);
uapi_mem_delete(dst_mem_handle->mem_handle);
uapi_mem_unmap(src_virt, DATA_LEN);
uapi_mem_delete(src_mem_handle->mem_handle);
return;
}
static td_void priv_klad_detach(td_handle handle_klad, td_handle handle_ks, td_handle handle_tsc)
{
td_s32 ret;
ret = uapi_tsr2rcipher_detach_keyslot(handle_tsc, handle_ks);
if (ret != TD_SUCCESS) {
klad_print_error_func(uapi_tsr2rcipher_detach_keyslot, ret);
}
ret = uapi_klad_detach(handle_klad, handle_ks);
if (ret != TD_SUCCESS) {
klad_print_error_func(uapi_klad_detach, ret);
}
return;
}
static td_void priv_klad_destroy(td_handle handle_klad, td_handle handle_ks, td_handle handle_tsc)
{
uapi_klad_destroy(handle_klad);
uapi_keyslot_destroy(handle_ks);
uapi_tsr2rcipher_destroy(handle_tsc);
return;
}
static td_void priv_klad_deinit(td_void)
{
uapi_klad_deinit();
uapi_keyslot_deinit();
uapi_tsr2rcipher_deinit();
uapi_sys_deinit();
return;
}
static td_s32 priv_data_init(const td_char *cfg_path)
{
td_s32 ret;
td_s32 value_num = 0;
ret = parse_config_file(cfg_path, &value_num);
if (ret != TD_SUCCESS || value_num == 0 || value_num > MAX_VAR_NUM) {
klad_print_error_func(parse_config_file, ret);
goto out;
}
ret = get_key_value(SESSIONKEY_TAG, g_session_key, KEY_LEN);
if (ret != TD_SUCCESS) {
klad_print_error_func(get_key_value, ret);
goto out;
}
ret = get_key_value(CONTENTKEY_TAG, g_content_key, KEY_LEN);
if (ret != TD_SUCCESS) {
klad_print_error_func(get_key_value, ret);
goto out;
}
ret = get_key_value(IV_TAG, g_tsc_iv, KEY_LEN);
if (ret != TD_SUCCESS) {
klad_print_error_func(get_key_value, ret);
goto out;
}
ret = get_key_value(PKT_INPUT_DATA, g_input_pkt, DATA_LEN);
if (ret != TD_SUCCESS) {
klad_print_error_func(get_key_value, ret);
goto out;
}
out:
return ret;
}
td_s32 main(td_s32 argc, td_char *argv[])
{
td_handle handle_ks = 0;
td_handle handle_klad = 0;
td_handle handle_tsc = 0;
uapi_tsr2rcipher_attr tsc_attr = {0};
td_u8 *src_virt = TD_NULL;
td_u8 *dst_virt = TD_NULL;
uapi_tsr2rcipher_mem_handle src_mem_handle = {0};
uapi_tsr2rcipher_mem_handle dst_mem_handle = {0};
if (argv == TD_NULL || argv[1] == TD_NULL) {
printf("Please enter the path of the klad_data_cfg.ini file.!!!\n");
goto out;
}
if (priv_data_init(argv[1]) != TD_SUCCESS) {
goto out;
}
if (priv_key_init() != TD_SUCCESS) {
goto out;
}
if (priv_klad_create(&tsc_attr, &handle_tsc, &handle_ks, &handle_klad) != TD_SUCCESS) {
goto klad_deinit;
}
if (priv_klad_attach(handle_klad, handle_ks, handle_tsc, &tsc_attr) != TD_SUCCESS) {
goto klad_destroy;
}
if (priv_klad_mem_map(handle_tsc, &src_mem_handle, &src_virt, &dst_mem_handle, &dst_virt) != TD_SUCCESS) {
goto tsc_detach;
}
if (priv_klad_encrypt(handle_tsc, &src_mem_handle, src_virt, dst_virt, &dst_mem_handle) != TD_SUCCESS) {
goto dst_unmap;
}
dst_unmap:
priv_klad_umem_map(src_virt, &src_mem_handle, dst_virt, &dst_mem_handle);
tsc_detach:
priv_klad_detach(handle_klad, handle_ks, handle_tsc);
klad_destroy:
priv_klad_destroy(handle_klad, handle_ks, handle_tsc);
klad_deinit:
priv_klad_deinit();
out:
return 0;
}