/* * Copyright (c) Hisilicon Technologies Co., Ltd. 2019-2021. All rights reserved. * Description: TEE keyladder test sample. * Author: Hisilicon * Create: 2019-07-25 */ #include #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; }