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.

1089 lines
38 KiB

/*
* Copyright (c) Hisilicon Technologies Co., Ltd. 2019-2021. All rights reserved.
* Description: TEE keyladder test sample.
* Author: Hisilicon
* Create: 2019-07-25
*/
#include <unistd.h>
#include "td_type.h"
#include "tee_client_api.h"
#include "securec.h"
#include "parse_config_file.h"
#define ext_err_dft(format, arg...) printf("%s,%d: " format, __FUNCTION__, __LINE__, ## arg)
#define ext_info_dft(format, arg...) printf("%s,%d: " format, __FUNCTION__, __LINE__, ## arg)
#define sample_get_inputcmd(input_cmd) fgets((char *)(input_cmd), (sizeof(input_cmd) - 1), stdin)
#define ext_get_inputcmd(input_cmd) fgets((char *)(input_cmd), (sizeof(input_cmd) - 1), stdin)
#define klad_mark() printf("[%-32s][line:%04d]mark\n", __FUNCTION__, __LINE__)
#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
/*
* *********************************KLAD****************************************
*/
typedef enum {
EXT_TEE_ROOTKEY_NULL = 0x0,
EXT_TEE_ROOTKEY_CSA2 = 0x1,
EXT_TEE_ROOTKEY_CSA3 = 0x2,
EXT_TEE_ROOTKEY_AES = 0x3,
EXT_TEE_ROOTKEY_TDES = 0x4,
EXT_TEE_ROOTKEY_SM4 = 0x5,
EXT_TEE_ROOTKEY_MISC = 0x6,
EXT_TEE_ROOTKEY_R2R = 0x7,
EXT_TEE_ROOTKEY_HDCP = 0x8,
EXT_TEE_ROOTKEY_DCAS = 0x9,
EXT_TEE_ROOTKEY_DYM = 0xFF,
} ext_tee_rootkey_type;
/*
* Keyladder type list
*/
typedef enum {
EXT_TEE_KLAD_COM = 0x10,
EXT_TEE_KLAD_TA = 0x11,
EXT_TEE_KLAD_FP = 0x12,
EXT_TEE_KLAD_NONCE = 0x13,
EXT_TEE_KLAD_CLR = 0x14,
} ext_tee_klad_type;
#define ext_tee_klad_instance(ca, rk, klad, id) \
((((ca) << 24) & 0xFF000000) + (((rk) << 16) & 0xFF0000) + (((klad) << 8) & 0xFF00)+ (id))
#define EXT_CA_ID_BASIC 0x80
/*
* Clear route keyladder
*/
#define EXT_TEE_KLAD_TYPE_CLEARCW \
ext_tee_klad_instance(EXT_CA_ID_BASIC, EXT_TEE_ROOTKEY_NULL, EXT_TEE_KLAD_CLR, 0x01)
/*
* Dynamic keyladder, it can be customized
*/
#define EXT_TEE_KLAD_TYPE_DYNAMIC \
ext_tee_klad_instance(EXT_CA_ID_BASIC, EXT_TEE_ROOTKEY_DYM, EXT_TEE_KLAD_COM, 0x01)
/*
* STBM TA keyladder
* 1 stage keyladder
* Keyladder algorithm use AES, target engine is MCipher and target engine algorithm is AES.
*/
#define EXT_TEE_KLAD_TYPE_OEM_TA ext_tee_klad_instance(EXT_CA_ID_BASIC, EXT_TEE_ROOTKEY_R2R, EXT_TEE_KLAD_COM, 0x01)
/*
* CSA2 keyladder
* 2 stage keyladder
* Keyladder algorithm use AES/TDES/SM4, target engine is TSCIPHER and target engine algorithm is CSA2.
*/
#define EXT_TEE_KLAD_TYPE_CSA2 ext_tee_klad_instance(EXT_CA_ID_BASIC, EXT_TEE_ROOTKEY_CSA2, EXT_TEE_KLAD_COM, 0x01)
/*
* CSA3 keyladder
* 2 stage keyladder
* Keyladder algorithm use AES/TDES/SM4, target engine is TSCIPHER and target engine algorithm is CSA3.
*/
#define EXT_TEE_KLAD_TYPE_CSA3 ext_tee_klad_instance(EXT_CA_ID_BASIC, EXT_TEE_ROOTKEY_CSA3, EXT_TEE_KLAD_COM, 0x01)
/*
* R2R keyladder
* 2 stage keyladder
* Keyladder algorithm use AES/TDES/SM4, target engine is MCipher and target engine algorithm is AES/TDES/SM4.
*/
#define EXT_TEE_KLAD_TYPE_R2R ext_tee_klad_instance(EXT_CA_ID_BASIC, EXT_TEE_ROOTKEY_R2R, EXT_TEE_KLAD_COM, 0x01)
/*
* SP keyladder
* 2 stage keyladder
* Keyladder algorithm use AES/TDES/SM4, target engine is TSCIPHER and target engine algorithm is AES.
*/
#define EXT_TEE_KLAD_TYPE_SP ext_tee_klad_instance(EXT_CA_ID_BASIC, EXT_TEE_ROOTKEY_AES, EXT_TEE_KLAD_COM, 0x01)
/*
* MISC keyladder
* 2 stage keyladder
* Keyladder algorithm use AES/TDES/SM4, target engine is TSCIPHER and target engine algorithm is CSA2/CSA3/AES/TDES.
*/
#define EXT_TEE_KLAD_TYPE_MISC ext_tee_klad_instance(EXT_CA_ID_BASIC, EXT_TEE_ROOTKEY_MISC, EXT_TEE_KLAD_COM, 0x01)
/* Define the maximum session key level */
#define EXT_TEE_SESSION_KEY_MAX_LEVEL 0x04
/* Define the maximum key length. */
#define EXT_TEE_KLAD_MAX_KEY_LEN 32
/* Define the algorithm of crypto engine. */
typedef enum {
EXT_TEE_CRYPTO_ALG_CSA2 = 0, /* CSA2.0 */
EXT_TEE_CRYPTO_ALG_CSA3, /* CSA3.0 */
EXT_TEE_CRYPTO_ALG_ASA, /* ASA 64/128 Algorithm */
EXT_TEE_CRYPTO_ALG_ASA_LIGHT, /* ASA light Algorithm */
EXT_TEE_CRYPTO_ALG_AES_CBC_T = 0x12, /* AES CBC, the clear stream left in the tail */
EXT_TEE_CRYPTO_ALG_AES_CISSA, /* Common IPTV Software-oriented Scrambling Algorithm(CISSA), golbal IV */
EXT_TEE_CRYPTO_ALG_AES_CBC_L, /* AES_CBC_L the clear stream left in the leading */
EXT_TEE_CRYPTO_ALG_AES_CBC_IDSA, /* AES128 CBC Payload, ATIS IIF Default Scrambling Algorithm (IDSA),
the difference between IDSA and AES_IPTV is IDSA only support 0 IV */
EXT_TEE_CRYPTO_ALG_AES_IPTV, /* AES IPTV of SPE */
EXT_TEE_CRYPTO_ALG_AES_CTR, /* AES CTR */
EXT_TEE_CRYPTO_ALG_DES_CI = 0x20, /* DES CBC */
EXT_TEE_CRYPTO_ALG_DES_CBC, /* DES CBC */
EXT_TEE_CRYPTO_ALG_DES_CBC_IDSA, /* DES CBC Payload, ATIS IIF Default Scrambling Algorithm(IDSA),
Not support set IV */
EXT_TEE_CRYPTO_ALG_SMS4_CBC = 0x31, /* SMS4 CBC */
EXT_TEE_CRYPTO_ALG_SMS4_CBC_IDSA, /* SMS4 CBC Payload, ATIS IIF Default Scrambling Algorithm(IDSA),
Not support set IV */
EXT_TEE_CRYPTO_ALG_TDES_CBC = 0x41, /* TDES CBC */
EXT_TEE_CRYPTO_ALG_TDES_CBC_IDSA, /* TDES CBC Payload, ATIS IIF Default Scrambling Algorithm(IDSA),
Not support set IV */
EXT_TEE_CRYPTO_ALG_MULTI2_CBC = 0x51, /* MULTI2 CBC */
EXT_TEE_CRYPTO_ALG_MULTI2_CBC_IDSA, /* MULTI2 CBC Payload, ATIS IIF Default Scrambling Algorithm(IDSA),
Not support set IV */
EXT_TEE_CRYPTO_ALG_RAW_AES = 0x4000,
EXT_TEE_CRYPTO_ALG_RAW_DES,
EXT_TEE_CRYPTO_ALG_RAW_SM4,
EXT_TEE_CRYPTO_ALG_RAW_TDES,
EXT_TEE_CRYPTO_ALG_RAW_HMAC_SHA1,
EXT_TEE_CRYPTO_ALG_RAW_HMAC_SHA2,
EXT_TEE_CRYPTO_ALG_RAW_HMAC_SM3,
EXT_TEE_CRYPTO_ALG_RAW_HDCP,
EXT_TEE_CRYPTO_ALG_MAX
} ext_tee_crypto_alg;
/* Define the key security attribute. */
typedef enum {
EXT_TEE_KLAD_SEC_ENABLE = 0,
EXT_TEE_KLAD_SEC_DISABLE,
EXT_TEE_KLAD_SEC_MAX
} ext_tee_klad_sec;
/* Define the keyladder algorithm. */
typedef enum {
EXT_TEE_KLAD_ALG_TYPE_DEFAULT = 0, /* Default value */
EXT_TEE_KLAD_ALG_TYPE_TDES = 1,
EXT_TEE_KLAD_ALG_TYPE_AES,
EXT_TEE_KLAD_ALG_TYPE_SM4,
EXT_TEE_KLAD_ALG_TYPE_MAX
} ext_tee_klad_alg_type;
/* Define the keyladder level. */
typedef enum {
EXT_TEE_KLAD_LEVEL1 = 0,
EXT_TEE_KLAD_LEVEL2,
EXT_TEE_KLAD_LEVEL3,
EXT_TEE_KLAD_LEVEL4,
EXT_TEE_KLAD_LEVEL5,
EXT_TEE_KLAD_LEVEL6,
EXT_TEE_KLAD_LEVEL_MAX
} ext_tee_klad_level;
/* Define the structure of keyladder configuration. */
typedef struct {
td_u32 owner_id; /* Keyladder owner ID. Different keyladder have different ID. */
td_u32 klad_type; /* Keyladder type. */
} ext_tee_klad_config;
/* Define the structure of content key configurations. */
typedef struct {
td_bool decrypt_support; /* The content key can be used for decrypting. */
td_bool encrypt_support; /* The content key can be used for encrypting. */
ext_tee_crypto_alg engine; /* The content key can be used for which algorithm of the crypto engine. */
} ext_tee_klad_key_config;
/* Define the structure of content key security configurations. */
typedef struct {
ext_tee_klad_sec key_sec;
td_bool dest_buf_sec_support; /* The destination buffer of target engine can be secure. */
td_bool dest_buf_non_sec_support; /* The destination buffer of target engine can be non-secure. */
td_bool src_buf_sec_support; /* The source buffer of target engine can be secure. */
td_bool src_buf_non_sec_support; /* The source buffer of target engine can be non-secure. */
} ext_tee_klad_key_secure_config;
/* Structure of keyladder extend attributes. */
typedef struct {
ext_tee_klad_config klad_cfg; /* The keyladder configuration. */
ext_tee_klad_key_config key_cfg; /* The content key configuration. */
ext_tee_klad_key_secure_config key_sec_cfg; /* The content key security configuration. */
} ext_tee_klad_attr;
/* Structure of setting session key. */
typedef struct {
ext_tee_klad_level level; /* The level of session key. */
ext_tee_klad_alg_type alg; /* The algorithm used to decrypt session key. */
td_u32 key_size; /* The size of session key. */
td_u8 key[EXT_TEE_KLAD_MAX_KEY_LEN]; /* The session key. */
} ext_tee_klad_session_key;
/* Structure of setting content key. */
typedef struct {
td_bool odd; /* Odd or Even key flag. */
ext_tee_klad_alg_type alg; /* The algorithm of the content key. */
td_u32 key_size; /* The size of content key. */
td_u8 key[EXT_TEE_KLAD_MAX_KEY_LEN]; /* The content key. */
} ext_tee_klad_content_key;
/* Structure of sending clear key. */
typedef struct {
td_bool odd; /* Odd or Even key flag. */
td_u32 key_size; /* The size of content key. */
td_u8 key[EXT_TEE_KLAD_MAX_KEY_LEN]; /* The content key. */
} ext_tee_klad_clear_key;
/* Structure of generating keyladder key. */
typedef struct {
ext_tee_klad_alg_type alg; /* The algorithm of the content key. */
td_u32 key_size; /* The size of content key. */
td_u8 key[EXT_TEE_KLAD_MAX_KEY_LEN];
td_u32 gen_key_size; /* The size of generated key. */
td_u8 gen_key[EXT_TEE_KLAD_MAX_KEY_LEN];
} ext_tee_klad_gen_key;
/* Structure of setting Nonce keyladder key. */
typedef struct {
ext_tee_klad_alg_type alg; /* The algorithm of the content key. */
td_u32 key_size; /* The size of content key. */
td_u8 key[EXT_TEE_KLAD_MAX_KEY_LEN];
td_u32 nonce_size; /* The size of nonce key. */
td_u8 nonce[EXT_TEE_KLAD_MAX_KEY_LEN]; /* The size of nonce key. */
} ext_tee_klad_nonce_key;
/* Rootkey slot. */
typedef enum {
EXT_TEE_BOOT_ROOTKEY_SLOT = 0x0,
EXT_TEE_IC_ROOTKEY_SLOT = 0x1,
EXT_TEE_OEM_ROOTKEY_SLOT = 0x2,
EXT_TEE_CAS_ROOTKEY_SLOT0 = 0x10,
EXT_TEE_CAS_ROOTKEY_SLOT1 = 0x11,
EXT_TEE_CAS_ROOTKEY_SLOT2 = 0x12,
EXT_TEE_CAS_ROOTKEY_SLOT3 = 0x13,
EXT_TEE_CAS_ROOTKEY_SLOT4 = 0x14,
EXT_TEE_CAS_ROOTKEY_SLOT5 = 0x15,
EXT_TEE_CAS_ROOTKEY_SLOT6 = 0x16,
EXT_TEE_CAS_ROOTKEY_SLOT7 = 0x17,
EXT_TEE_ROOTKEY_SLOT_MAX
} ext_tee_rootkey_select;
/* Configure crypto engine type. */
typedef struct {
td_bool mcipher_support; /* Support send key to Mcipher or not. */
td_bool tscipher_support; /* Support send key to TScipher(TSR2RCipher and Demux) or not. */
} ext_tee_rootkey_target;
/* Configure crypto engine algorithm. */
typedef struct {
td_bool sm4_support; /* Target engine support SM4 algorithm or not. */
td_bool tdes_support; /* Target engine support TDES algorithm or not. */
td_bool aes_support; /* Target engine support AES algorithm or not. */
td_bool csa2_support; /* Target engine support CSA2 algorithm or not. */
td_bool csa3_support; /* Target engine support CSA3 algorithm or not. */
td_bool hmac_sha_support; /* Target engine support HMAC SHA or not. */
td_bool hmac_sm3_support; /* Target engine support HMAC SM3 or not. */
} ext_tee_rootkey_target_alg;
/* Configure target engine features. */
typedef struct {
td_bool encrypt_support; /* Target engine support encrypt or not. */
td_bool decrypt_support; /* Target engine support decrypt or not. */
} ext_tee_rootkey_target_feature;
/* Configure keyladder algorithm. */
typedef struct {
td_bool sm4_support; /* Keyladder support SM4 algorithm or not. */
td_bool tdes_support; /* Keyladder support TDES algorithm or not. */
td_bool aes_support; /* Keyladder support AES algorithm or not. */
} ext_tee_rootkey_alg;
/* Configure keyladder stage. */
typedef enum {
EXT_TEE_ROOTKEY_LEVEL1 = 0, /* Keyladder support 1 stage. */
EXT_TEE_ROOTKEY_LEVEL2, /* Keyladder support 2 stage. */
EXT_TEE_ROOTKEY_LEVEL3, /* Keyladder support 3 stage. */
EXT_TEE_ROOTKEY_LEVEL4, /* Keyladder support 4 stage. */
EXT_TEE_ROOTKEY_LEVEL5, /* Keyladder support 5 stage. */
EXT_TEE_ROOTKEY_LEVEL_MAX
} ext_tee_rootkey_level;
/* Structure of Rootkey attributes. */
typedef struct {
ext_tee_rootkey_select rootkey_sel; /* Rootkey slot select. */
ext_tee_rootkey_target target_support; /* Crypto engine select. */
ext_tee_rootkey_target_alg target_alg_support; /* Crypto engine algorithm. */
ext_tee_rootkey_target_feature target_feature_support;
ext_tee_rootkey_level level; /* Keyladder stage. */
ext_tee_rootkey_alg alg_support; /* Keyladder algorithm. */
} ext_tee_rootkey_attr;
/*
\brief Declare keyladder callback function interface
\param[in] err_code Return error code.
\param[in] args Receive buffer.
\param[in] size The length of cArgs.
\param[in] user_data User private data.
\param[in] user_data_len User private data length.
*/
typedef td_s32(*ext_tee_klad_func)(td_s32 err_code, td_char *args, td_u32 size,
td_void *user_data, td_u32 user_data_len);
/* Define cb descriptor */
typedef struct {
ext_tee_klad_func done_callback; /* Keyladder callback function interface */
td_void *user_data; /* user private data */
td_u32 user_data_len; /* user private data length */
} ext_tee_klad_done_callback;
#define CMD_KLAD_INIT 0x10
#define CMD_KLAD_DEINIT 0x11
#define CMD_KLAD_CREATE 0x1
#define CMD_KLAD_DESTROY 0x2
#define CMD_KLAD_ATTACH 0x3
#define CMD_KLAD_DETACH 0x4
#define CMD_KLAD_GET_ATTR 0x5
#define CMD_KLAD_SET_ATTR 0x6
#define CMD_RK_GET_ATTR 0x25
#define CMD_RK_SET_ATTR 0x26
#define CMD_KLAD_SET_SESSION_KEY 0x7
#define CMD_KLAD_SET_CONTENT_KEY 0x9
#define CMD_KLAD_ASYNC_SET_CONTENT_KEY 0x19
#define CMD_KLAD_SET_CLEAR_KEY 0xa
#define CMD_KLAD_GET_NONCE_KEY 0xb
#define CMD_KLAD_FP_KEY 0xc
#define CMD_KLAD_GENERATE_KEY 0xd
#define CMD_API_LOG_LEVEL 0xFe
#define CMD_KLAD_LOG_LEVEL 0xFF
static int g_session_open = -1;
static TEEC_Context g_teec_context = {0};
static TEEC_Session g_teec_session = {0};
static TEEC_UUID g_teec_uuid = { 0xc9cf6b2a, 0x4b60, 0x11e7, { 0xa9, 0x19, 0x92, 0xeb, 0xcb, 0x67, 0xfe, 0x33 } };
static int tee_klad_ta_init()
{
TEEC_Result teec_rst;
TEEC_Operation sess_op = {0};
uint32_t origin = 0;
if (g_session_open > 0) {
g_session_open++;
return 0;
}
ext_err_dft("===================init=======================\n");
teec_rst = TEEC_InitializeContext(NULL, &g_teec_context);
if (teec_rst != TEEC_SUCCESS) {
ext_err_dft("Teec Initialize context failed!\n");
return teec_rst;
}
sess_op.started = 1;
sess_op.paramTypes = TEEC_PARAM_TYPES(TEEC_NONE, TEEC_NONE,
TEEC_MEMREF_TEMP_INPUT,
TEEC_MEMREF_TEMP_INPUT);
teec_rst = TEEC_OpenSession(&g_teec_context,
&g_teec_session,
&g_teec_uuid,
TEEC_LOGIN_IDENTIFY,
NULL,
&sess_op,
&origin);
if (teec_rst != TEEC_SUCCESS) {
ext_err_dft("Teec open session failed!\n");
(void)TEEC_FinalizeContext(&g_teec_context);
return (int)teec_rst;
}
g_session_open = 1;
return 0;
}
static int tee_klad_ta_deinit()
{
if (g_session_open > 0) {
g_session_open--;
}
if (g_session_open != 0) {
return 0;
}
(void)TEEC_CloseSession(&g_teec_session);
(void)TEEC_FinalizeContext(&g_teec_context);
g_session_open = -1;
return 0;
}
static int tee_klad_init()
{
TEEC_Result teec_result;
TEEC_Operation teec_operation = {0};
uint32_t origin = 0;
teec_operation.started = 1;
teec_operation.paramTypes = TEEC_PARAM_TYPES(TEEC_NONE, TEEC_NONE, TEEC_NONE, TEEC_NONE);
teec_result = TEEC_InvokeCommand(&g_teec_session, CMD_KLAD_INIT, &teec_operation, &origin);
if (teec_result != 0) {
ext_err_dft("teec invoke command failed, cmd = 0x%08x\n", teec_result);
return (int)teec_result;
}
return 0;
}
static int tee_klad_create(td_handle *klad)
{
TEEC_Result teec_result;
TEEC_Operation teec_operation = {0};
teec_operation.started = 1;
teec_operation.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_TEMP_OUTPUT,
TEEC_NONE, TEEC_NONE, TEEC_NONE);
teec_operation.params[0].tmpref.buffer = (unsigned int *)klad;
teec_operation.params[0].tmpref.size = 0x04;
teec_result = TEEC_InvokeCommand(&g_teec_session, CMD_KLAD_CREATE, &teec_operation, NULL);
if (teec_result != 0) {
ext_err_dft("teec invoke command failed, cmd = 0x%08x\n", teec_result);
return (int)teec_result;
}
return 0;
}
static int tee_klad_attach(td_handle klad, td_handle target)
{
TEEC_Result teec_result;
TEEC_Operation teec_operation = {0};
teec_operation.started = 1;
teec_operation.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT, TEEC_NONE, TEEC_NONE, TEEC_NONE);
teec_operation.params[0].value.a = (unsigned int)klad;
teec_operation.params[0].value.b = (unsigned int)target;
teec_result = TEEC_InvokeCommand(&g_teec_session, CMD_KLAD_ATTACH, &teec_operation, NULL);
if (teec_result != 0) {
ext_err_dft("teec invoke command failed, cmd = 0x%08x\n", teec_result);
return (int)teec_result;
}
return 0;
}
static int tee_klad_detach(td_handle klad, td_handle target)
{
TEEC_Result teec_result;
TEEC_Operation teec_operation = {0};
teec_operation.started = 1;
teec_operation.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT, TEEC_NONE, TEEC_NONE, TEEC_NONE);
teec_operation.params[0].value.a = (unsigned int)klad;
teec_operation.params[0].value.b = (unsigned int)target;
teec_result = TEEC_InvokeCommand(&g_teec_session, CMD_KLAD_DETACH, &teec_operation, NULL);
if (teec_result != 0) {
ext_err_dft("teec invoke command failed, cmd = 0x%08x\n", teec_result);
return (int)teec_result;
}
return 0;
}
int tee_klad_set_rootkey_attr(td_handle klad, const ext_tee_rootkey_attr *attr)
{
errno_t ret;
TEEC_Result teec_result;
TEEC_Operation teec_operation = {0};
ext_tee_rootkey_attr tee_rk_attr;
ret = memcpy_s(&tee_rk_attr, sizeof(tee_rk_attr), attr, sizeof(ext_tee_rootkey_attr));
if (ret != EOK) {
ext_err_dft("Call memcpy_s failed.\n");
return TD_FAILURE;
}
teec_operation.started = 1;
teec_operation.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT,
TEEC_MEMREF_TEMP_INPUT,
TEEC_NONE, TEEC_NONE);
teec_operation.params[0].value.a = (unsigned int)klad;
teec_operation.params[1].tmpref.buffer = (void *)(&tee_rk_attr);
teec_operation.params[1].tmpref.size = sizeof(ext_tee_rootkey_attr);
teec_result = TEEC_InvokeCommand(&g_teec_session, CMD_RK_SET_ATTR, &teec_operation, NULL);
if (teec_result != 0) {
ext_err_dft("teec invoke command failed, cmd = 0x%08x\n", teec_result);
return (int)teec_result;
}
return 0;
}
static int tee_klad_set_attr(td_handle klad, const ext_tee_klad_attr *attr)
{
errno_t ret;
TEEC_Result teec_result;
TEEC_Operation teec_operation = {0};
ext_tee_klad_attr tee_attr;
ret = memcpy_s(&tee_attr, sizeof(tee_attr), attr, sizeof(ext_tee_klad_attr));
if (ret != EOK) {
ext_err_dft("Call memcpy_s failed.\n");
return TD_FAILURE;
}
teec_operation.started = 1;
teec_operation.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT,
TEEC_MEMREF_TEMP_INPUT,
TEEC_NONE, TEEC_NONE);
teec_operation.params[0].value.a = (unsigned int)klad;
teec_operation.params[1].tmpref.buffer = (void *)(&tee_attr);
teec_operation.params[1].tmpref.size = sizeof(ext_tee_klad_attr);
teec_result = TEEC_InvokeCommand(&g_teec_session, CMD_KLAD_SET_ATTR, &teec_operation, NULL);
if (teec_result != 0) {
ext_err_dft("teec invoke command failed, cmd = 0x%08x\n", teec_result);
return (int)teec_result;
}
return 0;
}
int tee_klad_get_attr(td_handle klad, ext_tee_klad_attr *attr)
{
errno_t ret;
TEEC_Result teec_result;
TEEC_Operation teec_operation = {0};
ext_tee_klad_attr tee_attr = {0};
teec_operation.started = 1;
teec_operation.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT,
TEEC_MEMREF_TEMP_OUTPUT,
TEEC_NONE, TEEC_NONE);
teec_operation.params[0].value.a = (unsigned int)klad;
teec_operation.params[1].tmpref.buffer = (void *)&tee_attr;
teec_operation.params[1].tmpref.size = sizeof(ext_tee_klad_attr);
teec_result = TEEC_InvokeCommand(&g_teec_session, CMD_KLAD_GET_ATTR, &teec_operation, NULL);
if (teec_result != 0) {
ext_err_dft("teec invoke command failed, cmd = 0x%08x\n", teec_result);
return (int)teec_result;
}
ret = memcpy_s(attr, sizeof(ext_tee_klad_attr), &tee_attr, sizeof(tee_attr));
if (ret != EOK) {
ext_err_dft("Call memcpy_s failed.\n");
return TD_FAILURE;
}
return 0;
}
int tee_klad_set_session_key(td_handle klad, const ext_tee_klad_session_key *key)
{
TEEC_Result teec_result;
TEEC_Operation teec_operation = {0};
teec_operation.started = 1;
teec_operation.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT,
TEEC_MEMREF_TEMP_INPUT,
TEEC_NONE,
TEEC_NONE);
teec_operation.params[0].value.a = (unsigned int)klad;
teec_operation.params[1].tmpref.buffer = (void *)key;
teec_operation.params[1].tmpref.size = sizeof(ext_tee_klad_session_key);
teec_result = TEEC_InvokeCommand(&g_teec_session, CMD_KLAD_SET_SESSION_KEY, &teec_operation, NULL);
if (teec_result != 0) {
ext_err_dft("teec invoke command failed, cmd = 0x%08x\n", teec_result);
return (int)teec_result;
}
return 0;
}
int tee_klad_set_content_key(td_handle klad, const ext_tee_klad_content_key *key)
{
TEEC_Result teec_result;
TEEC_Operation teec_operation = {0};
teec_operation.started = 1;
teec_operation.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT,
TEEC_MEMREF_TEMP_INPUT,
TEEC_NONE,
TEEC_NONE);
teec_operation.params[0].value.a = (unsigned int)klad;
teec_operation.params[1].tmpref.buffer = (void *)key;
teec_operation.params[1].tmpref.size = sizeof(ext_tee_klad_content_key);
teec_result = TEEC_InvokeCommand(&g_teec_session, CMD_KLAD_SET_CONTENT_KEY, &teec_operation, NULL);
if (teec_result != 0) {
ext_err_dft("teec invoke command failed, cmd = 0x%08x\n", teec_result);
return (int)teec_result;
}
return 0;
}
int tee_klad_set_async_content_key(td_handle klad, const ext_tee_klad_content_key *key)
{
TEEC_Result teec_result;
TEEC_Operation teec_operation = {0};
teec_operation.started = 1;
teec_operation.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT,
TEEC_MEMREF_TEMP_INPUT,
TEEC_NONE,
TEEC_NONE);
teec_operation.params[0].value.a = (unsigned int)klad;
teec_operation.params[1].tmpref.buffer = (void *)key;
teec_operation.params[1].tmpref.size = sizeof(ext_tee_klad_content_key);
teec_result = TEEC_InvokeCommand(&g_teec_session, CMD_KLAD_ASYNC_SET_CONTENT_KEY, &teec_operation, NULL);
if (teec_result != 0) {
ext_err_dft("teec invoke command failed, cmd = 0x%08x\n", teec_result);
return (int)teec_result;
}
return 0;
}
static int tee_klad_set_clear_key(td_handle klad, const ext_tee_klad_clear_key *key)
{
TEEC_Result teec_result;
TEEC_Operation teec_operation = {0};
teec_operation.started = 1;
teec_operation.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT,
TEEC_MEMREF_TEMP_INPUT,
TEEC_NONE,
TEEC_NONE);
teec_operation.params[0].value.a = (unsigned int)klad;
teec_operation.params[1].tmpref.buffer = (void *)key;
teec_operation.params[1].tmpref.size = sizeof(ext_tee_klad_clear_key);
teec_result = TEEC_InvokeCommand(&g_teec_session, CMD_KLAD_SET_CLEAR_KEY, &teec_operation, NULL);
if (teec_result != 0) {
ext_err_dft("teec invoke command failed, cmd = 0x%08x\n", teec_result);
return (int)teec_result;
}
return 0;
}
static int tee_klad_destroy(td_handle klad)
{
TEEC_Result teec_result;
TEEC_Operation teec_operation = {0};
teec_operation.started = 1;
teec_operation.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT,
TEEC_NONE,
TEEC_NONE,
TEEC_NONE);
teec_operation.params[0].value.a = (unsigned int)klad;
teec_result = TEEC_InvokeCommand(&g_teec_session, CMD_KLAD_DESTROY, &teec_operation, NULL);
if (teec_result != 0) {
ext_err_dft("teec invoke command failed, cmd = 0x%08x\n", teec_result);
return (int)teec_result;
}
return 0;
}
static int tee_klad_log_level(td_u32 level)
{
TEEC_Result teec_result;
TEEC_Operation teec_operation = {0};
teec_operation.started = 1;
teec_operation.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT,
TEEC_NONE,
TEEC_NONE,
TEEC_NONE);
teec_operation.params[0].value.a = (unsigned int)level;
teec_result = TEEC_InvokeCommand(&g_teec_session, CMD_KLAD_LOG_LEVEL, &teec_operation, NULL);
if (teec_result != 0) {
ext_err_dft("teec invoke command failed, cmd = 0x%08x\n", teec_result);
return (int)teec_result;
}
return 0;
}
static int tee_api_log_level(td_u32 level)
{
TEEC_Result teec_result;
TEEC_Operation teec_operation = {0};
teec_operation.started = 1;
teec_operation.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT,
TEEC_NONE, TEEC_NONE, TEEC_NONE);
teec_operation.params[0].value.a = (unsigned int)level;
teec_result = TEEC_InvokeCommand(&g_teec_session, CMD_API_LOG_LEVEL, &teec_operation, NULL);
if (teec_result != 0) {
ext_err_dft("teec invoke command failed, cmd = 0x%08x\n", teec_result);
return (int)teec_result;
}
return 0;
}
static int tee_klad_deinit()
{
TEEC_Result teec_result;
TEEC_Operation teec_operation = {0};
teec_operation.started = 1;
teec_operation.paramTypes = TEEC_PARAM_TYPES(TEEC_NONE, TEEC_NONE,
TEEC_NONE, TEEC_NONE);
teec_result = TEEC_InvokeCommand(&g_teec_session, CMD_KLAD_DEINIT, &teec_operation, NULL);
if (teec_result != 0) {
ext_err_dft("teec invoke command failed, cmd = 0x%08x\n", teec_result);
return (int)teec_result;
}
return 0;
}
/*
* *********************************KEYSLOT****************************************
*/
typedef enum {
EXT_KEYSLOT_TYPE_TSCIPHER = 0x00,
EXT_KEYSLOT_TYPE_MCIPHER,
EXT_KEYSLOT_TYPE_HMAC,
EXT_KEYSLOT_TYPE_MAX
} ext_keyslot_type;
#define KEYSLOT_CMD_CREATE 0
#define KEYSLOT_CMD_DESTROY 1
#define KEYSLOT_CMD_LOG_LEVEL 0xff
static int g_session_ks_open = -1;
static TEEC_Context g_teec_ks_context = {0};
static TEEC_Session g_teec_ks_session = {0};
static TEEC_UUID g_teec_ks_uuid = { 0x59e80d08, 0xad42, 0x11e9, { 0xa2, 0xa3, 0x2a, 0x2a, 0xe2, 0xdb, 0xcc, 0xe4 } };
static int tee_ks_ta_init()
{
TEEC_Result teec_rst;
TEEC_Operation sess_op = {0};
uint32_t origin = 0;
if (g_session_ks_open > 0) {
g_session_ks_open++;
return 0;
}
ext_err_dft("===================init=======================\n");
teec_rst = TEEC_InitializeContext(NULL, &g_teec_ks_context);
if (teec_rst != TEEC_SUCCESS) {
ext_err_dft("Teec Initialize context failed!\n");
return teec_rst;
}
sess_op.started = 1;
sess_op.paramTypes = TEEC_PARAM_TYPES(TEEC_NONE, TEEC_NONE,
TEEC_MEMREF_TEMP_INPUT,
TEEC_MEMREF_TEMP_INPUT);
teec_rst = TEEC_OpenSession(&g_teec_ks_context,
&g_teec_ks_session,
&g_teec_ks_uuid,
TEEC_LOGIN_IDENTIFY,
NULL,
&sess_op,
&origin);
if (teec_rst != TEEC_SUCCESS) {
ext_err_dft("Teec open session failed!\n");
(void)TEEC_FinalizeContext(&g_teec_ks_context);
return (int)teec_rst;
}
g_session_ks_open = 1;
return 0;
}
static int tee_ks_ta_deinit()
{
if (g_session_ks_open > 0) {
g_session_ks_open--;
}
if (g_session_ks_open != 0) {
return 0;
}
(void)TEEC_CloseSession(&g_teec_ks_session);
(void)TEEC_FinalizeContext(&g_teec_ks_context);
g_session_ks_open = -1;
return 0;
}
static int tee_sec_key_slot_create(ext_keyslot_type keyslot_type, unsigned int *handle)
{
TEEC_Result teec_result;
TEEC_Operation teec_operation = {0};
if (handle == NULL) {
ext_err_dft("handle is NULL \n");
return -1;
}
teec_operation.started = 1;
teec_operation.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INOUT,
TEEC_NONE,
TEEC_NONE,
TEEC_NONE);
teec_operation.params[0].value.a = (unsigned int)keyslot_type;
teec_result = TEEC_InvokeCommand(&g_teec_ks_session, KEYSLOT_CMD_CREATE, &teec_operation, NULL);
if (teec_result != TEEC_SUCCESS) {
ext_err_dft("Teec invoke command failed, cmd = 0x%08x\n", KEYSLOT_CMD_CREATE);
}
*handle = teec_operation.params[0].value.b;
return (int)teec_result;
}
static int tee_sec_key_slot_destroy(unsigned int handle)
{
TEEC_Result teec_result;
TEEC_Operation teec_operation = {0};
teec_operation.started = 1;
teec_operation.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT,
TEEC_NONE,
TEEC_NONE,
TEEC_NONE);
teec_operation.params[0].value.a = handle;
teec_result = TEEC_InvokeCommand(&g_teec_ks_session, KEYSLOT_CMD_DESTROY, &teec_operation, NULL);
if (teec_result != TEEC_SUCCESS) {
ext_err_dft("Teec invoke command failed, cmd = 0x%08x\n", KEYSLOT_CMD_DESTROY);
}
return (int)teec_result;
}
static int tee_sec_key_slot_log_level(unsigned int level)
{
TEEC_Result teec_result;
TEEC_Operation teec_operation = {0};
teec_operation.started = 1;
teec_operation.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT,
TEEC_NONE,
TEEC_NONE,
TEEC_NONE);
teec_operation.params[0].value.a = level;
teec_result = TEEC_InvokeCommand(&g_teec_ks_session, KEYSLOT_CMD_LOG_LEVEL, &teec_operation, NULL);
if (teec_result != TEEC_SUCCESS) {
ext_err_dft("Teec invoke command failed, cmd = 0x%08x\n", KEYSLOT_CMD_LOG_LEVEL);
}
return (int)teec_result;
}
/*
* *********************************TEST****************************************
*/
static td_u8 g_test_key[KEY_LEN] = {0};
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);
return ret;
}
ret = get_key_value(SESSIONKEY_TAG, g_test_key, KEY_LEN);
if (ret != TD_SUCCESS) {
klad_print_error_func(get_key_value, ret);
return ret;
}
return TD_SUCCESS;
}
static td_s32 priv_klad_init(td_handle *handle_ks, td_handle *handle_klad, td_char *cfg_path)
{
td_s32 ret;
ret = priv_data_init(cfg_path);
if (ret != TD_SUCCESS) {
klad_print_error_func(priv_data_init, ret);
return ret;
}
ret = tee_klad_ta_init();
if (ret != 0) {
klad_print_error_func(tee_klad_ta_init, ret);
return ret;
}
ret = tee_ks_ta_init();
if (ret != 0) {
klad_print_error_func(tee_ks_ta_init, ret);
goto out0;
}
sleep(1);
tee_sec_key_slot_log_level(1);
tee_klad_log_level(3); /* Set klad log to information level(3) */
tee_api_log_level(3); /* Set api log to information level(3) */
ret = tee_klad_init();
if (ret != 0) {
klad_print_error_func(tee_klad_init, ret);
goto out1;
}
ret = tee_sec_key_slot_create(EXT_KEYSLOT_TYPE_MCIPHER, handle_ks);
if (ret != 0) {
klad_print_error_func(tee_sec_key_slot_create, ret);
goto out2;
}
ret = tee_klad_create(handle_klad);
if (ret != 0) {
klad_print_error_func(tee_klad_create, ret);
goto out3;
}
return TD_SUCCESS;
out3:
tee_sec_key_slot_destroy(*handle_ks);
out2:
tee_klad_deinit();
out1:
sleep(1);
tee_ks_ta_deinit();
out0:
tee_klad_ta_deinit();
return ret;
}
static td_s32 priv_klad_attach(td_handle handle_klad, td_handle handle_ks)
{
td_s32 ret;
ext_tee_klad_attr attr_klad = {0};
attr_klad.klad_cfg.owner_id = 0;
attr_klad.klad_cfg.klad_type = EXT_TEE_KLAD_TYPE_CLEARCW;
attr_klad.key_cfg.decrypt_support = 1;
attr_klad.key_cfg.encrypt_support = 1;
attr_klad.key_cfg.engine = EXT_TEE_CRYPTO_ALG_RAW_AES;
attr_klad.key_sec_cfg.key_sec = EXT_TEE_KLAD_SEC_DISABLE;
attr_klad.key_sec_cfg.dest_buf_non_sec_support = 1;
attr_klad.key_sec_cfg.dest_buf_sec_support = 1;
attr_klad.key_sec_cfg.src_buf_non_sec_support = 1;
attr_klad.key_sec_cfg.src_buf_sec_support = 1;
ret = tee_klad_set_attr(handle_klad, &attr_klad);
if (ret != 0) {
klad_print_error_func(tee_klad_set_attr, ret);
goto out;
}
ret = tee_klad_attach(handle_klad, handle_ks);
if (ret != 0) {
klad_print_error_func(tee_klad_attach, ret);
}
out:
return ret;
}
static td_void priv_klad_detach(td_handle handle_klad, td_handle handle_ks)
{
td_s32 ret;
ret = tee_klad_detach(handle_klad, handle_ks);
if (ret != TD_SUCCESS) {
klad_print_error_func(tee_klad_detach, ret);
}
return;
}
static td_void priv_klad_deinit(td_handle handle_ks, td_handle handle_klad)
{
tee_klad_destroy(handle_klad);
tee_sec_key_slot_destroy(handle_ks);
tee_klad_deinit();
sleep(1);
tee_ks_ta_deinit();
tee_klad_ta_deinit();
return;
}
int main(int argc, char *argv[])
{
td_s32 ret;
errno_t errno;
td_handle handle_ks = 0;
td_handle handle_klad = 0;
ext_tee_klad_clear_key key_clear = {0};
td_char input_cmd[0x20] = {0};
(void)argc;
if (argv == TD_NULL || argv[0x1] == TD_NULL) {
printf("Please enter the path of the config file.!!!\n");
return TD_FAILURE;
}
ret = priv_klad_init(&handle_ks, &handle_klad, argv[0x1]);
if (ret != 0) {
klad_print_error_func(priv_klad_init, ret);
goto out0;
}
ret = priv_klad_attach(handle_klad, handle_ks);
if (ret != 0) {
klad_print_error_func(priv_klad_attach, ret);
goto out1;
}
key_clear.odd = 0;
key_clear.key_size = KEY_LEN;
errno = memcpy_s(key_clear.key, EXT_TEE_KLAD_MAX_KEY_LEN, g_test_key, KEY_LEN);
if (errno != EOK) {
klad_print_error_func(memcpy_s, errno);
ret = TD_FAILURE;
goto out2;
}
ret = tee_klad_set_clear_key(handle_klad, &key_clear);
if (ret != 0) {
klad_print_error_func(tee_klad_set_clear_key, ret);
goto out2;
}
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;
}
}
out2:
priv_klad_detach(handle_klad, handle_ks);
out1:
priv_klad_deinit(handle_ks, handle_klad);
out0:
return ret;
}