| #include <dlfcn.h> |
| #include <stdbool.h> |
| #include <stdio.h> |
| #include <stdlib.h> |
| #include <string.h> |
| #include <stdint.h> |
| #include "gsw_secrypt_ss_interface.h" |
| #include "gsw_hal_errcode.h" |
| #include "gsw_log_interface.h" |
| |
| #define GSW_TEE "[HAL][GSW_TEE]" |
| |
| /** |
| * struct TEEC_Context - Represents a connection between a client application |
| * and a TEE. |
| */ |
| typedef struct { |
| /* Implementation defined */ |
| struct { |
| int fd; |
| bool reg_mem; |
| bool memref_null; |
| } imp; |
| } TEEC_Context; |
| |
| /** |
| * struct TEEC_Session - Represents a connection between a client application |
| * and a trusted application. |
| */ |
| typedef struct { |
| /* Implementation defined */ |
| struct { |
| TEEC_Context *ctx; |
| uint32_t session_id; |
| } imp; |
| } TEEC_Session; |
| |
| struct test_ctx { |
| TEEC_Context ctx; |
| TEEC_Session sess; |
| }; |
| |
| #define TEEC_SUCCESS 0x00000000 |
| #define TEEC_ERROR_STORAGE_NOT_AVAILABLE 0xF0100003 |
| #define TEEC_ERROR_GENERIC 0xFFFF0000 |
| #define TEEC_ERROR_ACCESS_DENIED 0xFFFF0001 |
| #define TEEC_ERROR_CANCEL 0xFFFF0002 |
| #define TEEC_ERROR_ACCESS_CONFLICT 0xFFFF0003 |
| #define TEEC_ERROR_EXCESS_DATA 0xFFFF0004 |
| #define TEEC_ERROR_BAD_FORMAT 0xFFFF0005 |
| #define TEEC_ERROR_BAD_PARAMETERS 0xFFFF0006 |
| #define TEEC_ERROR_BAD_STATE 0xFFFF0007 |
| #define TEEC_ERROR_ITEM_NOT_FOUND 0xFFFF0008 |
| #define TEEC_ERROR_NOT_IMPLEMENTED 0xFFFF0009 |
| #define TEEC_ERROR_NOT_SUPPORTED 0xFFFF000A |
| #define TEEC_ERROR_NO_DATA 0xFFFF000B |
| #define TEEC_ERROR_OUT_OF_MEMORY 0xFFFF000C |
| #define TEEC_ERROR_BUSY 0xFFFF000D |
| #define TEEC_ERROR_COMMUNICATION 0xFFFF000E |
| #define TEEC_ERROR_SECURITY 0xFFFF000F |
| #define TEEC_ERROR_SHORT_BUFFER 0xFFFF0010 |
| #define TEEC_ERROR_EXTERNAL_CANCEL 0xFFFF0011 |
| #define TEEC_ERROR_TARGET_DEAD 0xFFFF3024 |
| |
| struct test_ctx ctx; |
| |
| #define lib_secure_path "/lib/libsecure_storage.so" |
| static void *dlHandle_secure; |
| |
| #define lib_mbtk_path "/lib/libmbtk_lib.so" |
| static void *dlHandle_mbtk; |
| #define PUBLIC_KEY_SEC_NAME "public_key_obj" |
| #define SEC_LEVEL1_SEC_NAME "sec_levell_obj" |
| typedef struct |
| { |
| size_t length; |
| int is_update; |
| //int is_read; |
| unsigned char *content; |
| } tmp_sec; |
| tmp_sec public_key_sec = {0}; |
| tmp_sec sec_level1_sec = {0}; |
| |
| typedef uint32_t TEEC_Result; |
| // static void (*mbtk_log)(int level, const char *format, ...); |
| // static void (*mbtk_log_init)(char *path, char *tag); |
| |
| int (*prepare_tee_session)(struct test_ctx *ctx); |
| void (*terminate_tee_session)(struct test_ctx *ctx); |
| TEEC_Result (*read_secure_object)(struct test_ctx *ctx, const char *id,char *data, size_t *data_len); |
| TEEC_Result (*write_secure_object)(struct test_ctx *ctx, const char *id,char *data, size_t data_len); |
| TEEC_Result (*delete_secure_object)(struct test_ctx *ctx, const char *id); |
| |
| static int tee_api_import(void) |
| { |
| |
| dlHandle_mbtk = dlopen(lib_mbtk_path, RTLD_NOW); |
| if (dlHandle_mbtk == NULL) |
| { |
| return GSW_HAL_NORMAL_FAIL; |
| } |
| |
| dlHandle_secure = dlopen(lib_secure_path, RTLD_NOW); |
| if (dlHandle_secure == NULL) |
| { |
| return GSW_HAL_NORMAL_FAIL; |
| } |
| |
| // mbtk_log_init = (void (*)(char *path, char *tag))dlsym(dlHandle_mbtk, "mbtk_log_init"); |
| // if (mbtk_log_init == NULL) |
| // { |
| // return GSW_HAL_NORMAL_FAIL; |
| // } |
| |
| // mbtk_log = (void (*)(int level, const char *format, ...))dlsym(dlHandle_mbtk, "mbtk_log"); |
| // if (mbtk_log == NULL) |
| // { |
| // return GSW_HAL_NORMAL_FAIL; |
| // } |
| |
| prepare_tee_session = (int (*)(struct test_ctx *ctx))dlsym(dlHandle_secure, "prepare_tee_session"); |
| if (prepare_tee_session == NULL) |
| { |
| LOGE(GSW_TEE,"prepare_tee_session dlsym fail\n"); |
| return GSW_HAL_NORMAL_FAIL; |
| } |
| |
| terminate_tee_session = (void (*)(struct test_ctx *ctx))dlsym(dlHandle_secure, "terminate_tee_session"); |
| if (terminate_tee_session == NULL) |
| { |
| LOGE(GSW_TEE,"terminate_tee_session dlsym fail\n"); |
| return GSW_HAL_NORMAL_FAIL; |
| } |
| |
| read_secure_object = (TEEC_Result (*)(struct test_ctx *ctx, const char *id,char *data, size_t *data_len))dlsym(dlHandle_secure, "read_secure_object"); |
| if (read_secure_object == NULL) |
| { |
| LOGE(GSW_TEE,"read_secure_object dlsym fail\n"); |
| return GSW_HAL_NORMAL_FAIL; |
| } |
| |
| write_secure_object = (TEEC_Result (*)(struct test_ctx *ctx, const char *id,char *data, size_t data_len))dlsym(dlHandle_secure, "write_secure_object"); |
| if (write_secure_object == NULL) |
| { |
| LOGE(GSW_TEE,"write_secure_object dlsym fail\n"); |
| return GSW_HAL_NORMAL_FAIL; |
| } |
| |
| delete_secure_object = (TEEC_Result (*)(struct test_ctx *ctx, const char *id))dlsym(dlHandle_secure, "delete_secure_object"); |
| if (delete_secure_object == NULL) |
| { |
| LOGE(GSW_TEE,"delete_secure_object dlsym fail\n"); |
| return GSW_HAL_NORMAL_FAIL; |
| } |
| |
| return GSW_HAL_SUCCESS; |
| } |
| |
| /** |
| * @brief init tee sdk |
| * @param [in] None |
| * @param [out] None |
| * @retval GSW_HAL_SUCCESS is success\other is fail |
| */ |
| int32_t gsw_tee_sdk_init(void) |
| { |
| LOGE(GSW_TEE,"init start\n"); |
| int32_t ret = 0; |
| ret = tee_api_import(); |
| if(ret) |
| { |
| LOGE(GSW_TEE,"tee_api_import fail\n"); |
| return ret; |
| } |
| ret = prepare_tee_session(&ctx); |
| LOGE(GSW_TEE,"init end\n"); |
| if (public_key_sec.content == NULL) { |
| public_key_sec.content = malloc(7000); |
| public_key_sec.length = 0; |
| public_key_sec.is_update = 0; |
| } |
| |
| if (sec_level1_sec.content == NULL) { |
| sec_level1_sec.content = malloc(7000); |
| sec_level1_sec.length = 0; |
| sec_level1_sec.is_update = 0; |
| } |
| return ret; |
| } |
| |
| /** |
| * @brief read sensitive data from tee |
| * @param [in] char* in_obj_name :Sensitive data name |
| * @param [in] unsigned int* p_out_buf_len:The size of sensitive data output cache |
| * @param [out] char* out_buf:Cache of sensitive data output |
| * @param [out] unsigned int* p_out_buf_len:Sensitive data length |
| * @retval GSW_HAL_SUCCESS is success\other is fail |
| */ |
| #define basic_buf_len 7000 |
| int32_t gsw_tee_read_secure_data(const char* in_obj_name, char* out_buf, unsigned int* p_out_buf_len) |
| { |
| //LOGE(GSW_TEE,"start read\n"); |
| if (in_obj_name == NULL || out_buf == NULL) |
| { |
| return GSW_HAL_NORMAL_FAIL; |
| } |
| |
| int32_t ret = 0; |
| size_t size = basic_buf_len; |
| char *tmp_buf = (char*)malloc(basic_buf_len); |
| if (NULL == tmp_buf) |
| { |
| LOGE(GSW_TEE,"Failed malloc fail"); |
| return GSW_HAL_NO_MEMORY; |
| } |
| |
| bool is_pubkey = !strncmp(in_obj_name, PUBLIC_KEY_SEC_NAME, strlen(PUBLIC_KEY_SEC_NAME)); |
| bool is_level1 = !strncmp(in_obj_name, SEC_LEVEL1_SEC_NAME, strlen(SEC_LEVEL1_SEC_NAME)); |
| |
| if (is_pubkey || is_level1) |
| { |
| tmp_sec *target = is_pubkey ? &public_key_sec : &sec_level1_sec; |
| if (target->is_update) |
| { |
| if (target->length == 0 || target->content[0] == '\0') |
| ret = GSW_HAL_ERROR_TEE_SFS_FILE_NOEXIST; |
| else |
| { |
| memcpy(out_buf, target->content, target->length); |
| *p_out_buf_len = target->length; |
| ret = GSW_HAL_SUCCESS; |
| } |
| free(tmp_buf); |
| return ret; |
| } |
| |
| |
| TEEC_Result res = read_secure_object(&ctx, in_obj_name, tmp_buf, &size); |
| |
| if (res == TEEC_ERROR_ITEM_NOT_FOUND) |
| { |
| LOGE(GSW_TEE, "the obj no found\n"); |
| ret = GSW_HAL_ERROR_TEE_SFS_FILE_NOEXIST; |
| |
| target->is_update = 1; |
| target->length = 0; |
| target->content[0] = '\0'; |
| } |
| else if (res == TEEC_SUCCESS) |
| { |
| LOGE(GSW_TEE, "the obj is exist\n"); |
| memcpy(target->content, tmp_buf, size); |
| |
| target->length = size; |
| target->is_update = 1; |
| |
| memcpy(out_buf, tmp_buf, size); |
| *p_out_buf_len = size; |
| |
| ret = GSW_HAL_SUCCESS; |
| } |
| else |
| { |
| LOGE(GSW_TEE,"Failed to read an object from the secure storage"); |
| ret = GSW_HAL_NORMAL_FAIL; |
| } |
| |
| free(tmp_buf); |
| return ret; |
| } |
| |
| TEEC_Result res = read_secure_object(&ctx, in_obj_name, tmp_buf, &size); |
| if (res == TEEC_ERROR_ITEM_NOT_FOUND) |
| { |
| LOGE(GSW_TEE,"the obj no found\n"); |
| ret = GSW_HAL_ERROR_TEE_SFS_FILE_NOEXIST; |
| } |
| else if (res == TEEC_SUCCESS) |
| { |
| LOGE(GSW_TEE,"the obj is exist\n"); |
| memcpy(out_buf, tmp_buf, size); |
| *p_out_buf_len = size; |
| ret = GSW_HAL_SUCCESS; |
| } |
| else |
| { |
| LOGE(GSW_TEE,"Failed to read an object from the secure storage"); |
| ret = GSW_HAL_NORMAL_FAIL; |
| } |
| |
| free(tmp_buf); |
| return ret; |
| } |
| |
| /** |
| * @brief write sensitive data to tee |
| * @param [in] char* in_obj_name :Sensitive data name |
| * @param [in] char* in_buf:A cache for writing sensitive data |
| * @param [out] unsigned int in_buf_len:Sensitive data length |
| * @retval GSW_HAL_SUCCESS is success\other is fail |
| */ |
| int32_t gsw_tee_write_secure_data(const char* in_obj_name, char* in_buf, unsigned int in_buf_len) |
| { |
| LOGE(GSW_TEE,"write start\n"); |
| if (in_obj_name == NULL || in_buf == NULL) |
| return GSW_HAL_NORMAL_FAIL; |
| int32_t ret = 0; |
| |
| TEEC_Result res = write_secure_object(&ctx, in_obj_name,in_buf, in_buf_len); |
| if (res != TEEC_SUCCESS) |
| { |
| LOGE(GSW_TEE,"Failed to write an object from the secure storage"); |
| ret = GSW_HAL_NORMAL_FAIL; |
| } |
| bool is_pubkey = !strncmp(in_obj_name, PUBLIC_KEY_SEC_NAME, strlen(PUBLIC_KEY_SEC_NAME)); |
| bool is_level1 = !strncmp(in_obj_name, SEC_LEVEL1_SEC_NAME, strlen(SEC_LEVEL1_SEC_NAME)); |
| if (is_pubkey || is_level1) |
| { |
| tmp_sec *target = is_pubkey ? &public_key_sec : &sec_level1_sec; |
| target->is_update = 0; |
| } |
| LOGE(GSW_TEE,"write really end\n"); |
| return ret; |
| } |
| |
| |
| /** |
| * @brief delete sensitive data from tee |
| * @param [in] char* in_obj_name :Sensitive data name |
| * @retval GSW_HAL_SUCCESS is success\other is fail |
| */ |
| int32_t gsw_tee_delete_secure_data(const char* in_obj_name) |
| { |
| LOGE(GSW_TEE,"delete start\n"); |
| if (in_obj_name == NULL) |
| return GSW_HAL_NORMAL_FAIL; |
| int32_t ret = 0; |
| |
| TEEC_Result res = delete_secure_object(&ctx, in_obj_name); |
| if (res != TEEC_SUCCESS) |
| { |
| LOGE(GSW_TEE,"Failed to delete the object: 0x%x", res); |
| ret = GSW_HAL_NORMAL_FAIL; |
| } |
| bool is_pubkey = !strncmp(in_obj_name, PUBLIC_KEY_SEC_NAME, strlen(PUBLIC_KEY_SEC_NAME)); |
| bool is_level1 = !strncmp(in_obj_name, SEC_LEVEL1_SEC_NAME, strlen(SEC_LEVEL1_SEC_NAME)); |
| if (is_pubkey || is_level1) |
| { |
| tmp_sec *target = is_pubkey ? &public_key_sec : &sec_level1_sec; |
| target->length = 0; |
| } |
| LOGE(GSW_TEE,"delete really end\n"); |
| return ret; |
| } |
| |
| /** |
| * @brief check sensitive data from tee |
| * @param [in] char* in_obj_name :Sensitive data name |
| * @retval GSW_HAL_SUCCESS is exist\ other is not exist or fail |
| */ |
| int32_t gsw_tee_check_secure_data(const char* in_obj_name) |
| { |
| if (in_obj_name == NULL) |
| return GSW_HAL_NORMAL_FAIL; |
| int32_t ret = 1; |
| size_t size = basic_buf_len; |
| char *tmp_buf = (char*)malloc(basic_buf_len); |
| if (NULL == tmp_buf) |
| { |
| LOGE(GSW_TEE,"Failed malloc fail"); |
| return GSW_HAL_NO_MEMORY; |
| } |
| TEEC_Result res = read_secure_object(&ctx, in_obj_name, tmp_buf, &size); |
| if (res == TEEC_ERROR_ITEM_NOT_FOUND) |
| { |
| LOGE(GSW_TEE,"the obj no found\n"); |
| ret = GSW_HAL_ERROR_TEE_SFS_FILE_NOEXIST; |
| } |
| else if (res == TEEC_SUCCESS) |
| { |
| LOGE(GSW_TEE,"the obj is exist\n"); |
| ret = GSW_HAL_SUCCESS; |
| } |
| else |
| { |
| LOGE(GSW_TEE,"Failed to read an object from the secure storage"); |
| ret = GSW_HAL_NORMAL_FAIL; |
| } |
| free(tmp_buf); |
| return ret; |
| } |
| |
| /** |
| * @brief deinit tee sdk |
| * @param [in] None |
| * @param [out] None |
| * @retval GSW_HAL_SUCCESS is success\other is fail |
| */ |
| int32_t gsw_tee_sdk_deinit(void) |
| { |
| LOGE(GSW_TEE,"deinit start\n"); |
| if (terminate_tee_session) { |
| terminate_tee_session(&ctx); // 终止TEE会话 |
| terminate_tee_session = NULL; |
| } |
| |
| if (dlHandle_secure) { |
| dlclose(dlHandle_secure); // 卸载安全库 |
| dlHandle_secure = NULL; |
| } |
| |
| if (dlHandle_mbtk) { |
| dlclose(dlHandle_mbtk); // 卸载日志库 |
| dlHandle_mbtk = NULL; |
| } |
| LOGE(GSW_TEE,"deinit end\n"); |
| return GSW_HAL_SUCCESS; |
| } |
| |
| int32_t gsw_secure_init(void) |
| { |
| static int s_init_flag = 0; |
| if (0xAA55 == s_init_flag) |
| { |
| return GSW_HAL_SUCCESS; |
| } |
| if (GSW_HAL_SUCCESS == gsw_tee_sdk_init()) |
| { |
| s_init_flag = 0xAA55; |
| return GSW_HAL_SUCCESS; |
| } |
| LOGE(GSW_TEE,"secure sdk init fail!!!"); |
| return GSW_HAL_NORMAL_FAIL; |
| } |
| |
| int32_t gsw_secure_storage_query(const char *objname, int32_t *exist_state) |
| { |
| #if 0 |
| if (NULL == objname || NULL == exist_state) |
| { |
| LOGE(GSW_TEE,"storage query input param error objname %p, exist_state %p",objname, exist_state); |
| return GSW_HAL_ARG_INVALID; |
| } |
| int32_t ret = gsw_secure_init(); |
| if (GSW_HAL_SUCCESS != ret) |
| { |
| return ret; |
| } |
| ret = gsw_tee_check_secure_data(objname); |
| if (GSW_HAL_SUCCESS == ret) |
| { |
| *exist_state = 1; //表明数据存在 |
| } |
| else |
| { |
| *exist_state = 0; |
| } |
| return ret; |
| #else |
| return GSW_HAL_NO_SUPPROT; |
| #endif |
| } |
| |
| int32_t gsw_secure_storage_read(const char *objname, uint8_t *outbuf, uint32_t buflen, uint32_t *outlen) |
| { |
| #if 0 |
| if (NULL == objname || NULL == outbuf || NULL == outlen) |
| { |
| LOGE(GSW_TEE,"storage read input param error objname %p, outbuf %p, outlen %p",objname, outbuf, outlen); |
| return GSW_HAL_ARG_INVALID; |
| } |
| int32_t ret = gsw_secure_init(); |
| if (GSW_HAL_SUCCESS != ret) |
| { |
| return ret; |
| } |
| *outlen = buflen; |
| return gsw_tee_read_secure_data(objname, (char*)outbuf, outlen); |
| #else |
| return GSW_HAL_NO_SUPPROT; |
| #endif |
| |
| } |
| |
| int32_t gsw_secure_storage_write(const char *objname, const uint8_t *inbuf, uint32_t inlen) |
| { |
| #if 0 |
| if (NULL == objname || NULL == inbuf || 0 == inlen) |
| { |
| LOGE(GSW_TEE,"storage write input param error objname %p, outbuf %p, inlen %u",objname, inbuf, inlen); |
| return GSW_HAL_ARG_INVALID; |
| } |
| int32_t ret = gsw_secure_init(); |
| if (GSW_HAL_SUCCESS != ret) |
| { |
| return ret; |
| } |
| return gsw_tee_write_secure_data(objname, (char*)inbuf, inlen); |
| #else |
| return GSW_HAL_NO_SUPPROT; |
| #endif |
| } |
| |
| int32_t gsw_secure_storage_delete(const char *objname) |
| { |
| #if 0 |
| if (NULL == objname) |
| { |
| LOGE(GSW_TEE,"storage delete input param error objname %p",objname); |
| return GSW_HAL_ARG_INVALID; |
| } |
| int32_t ret = gsw_secure_init(); |
| if (GSW_HAL_SUCCESS != ret) |
| { |
| return ret; |
| } |
| return gsw_tee_delete_secure_data(objname); |
| #else |
| return GSW_HAL_NO_SUPPROT; |
| #endif |
| } |