/* * 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; }