在2.1.2-3 编译TA应用节,使用itrustee-sdk脚本对TA镜像签名打包时,默认使用国际算法AES进行加密。若需使用国密算法,可修改config_cloud.ini配置文件中的secEncryptContentAlg为1,表明对加密时采用国密SM4-CBC。
然后重新执行make即可,则在TA签名打包过程中,对TA的加密将自动采用SM4-CBC国密算法。对应的,在TEEOS加载TA镜像时,会根据配置信息采用SM4-CBC进行解密。
TA调用安全存储接口保存持久化数据时,默认使用国际算法进行加密,若需使用国密算法,可在调用安全存储接口生成持久化对象时,将入参flags与TEE_DATA_FLAG_GM进行或操作,则后续操作此持久化对象时,将使用国密算法进行加密和摘要计算。
1 2 3 4 5 |
// 创建一个新的持久化对象 TEE_Result TEE_CreatePersistentObject(uint32_t storageID, const void *objectID, size_t objectIDLen, uint32_t flags, TEE_ObjectHandle attributes, const void *initialData, size_t initialDataLen, TEE_ObjectHandle *object); // 打开一个新的持久化对象 TEE_Result TEE_OpenPersistentObject(uint32_t storageID, const void *objectID, size_t objectIDLen, uint32_t flags,TEE_ObjectHandle *object); |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
TEE_Result WritePersistentData(const void *buffer, size_t len) { TEE_Result ret; uint32_t storageID = TEE_OBJECT_STORAGE_PRIVATE; TEE_ObjectHandle persistentObj = NULL; void *objectID = "sec_storage_data/store_key_sample.txt"; void *aes_key = NULL; // 创建持久化对象时添加国密标志TEE_DATA_FLAG_GM ret = TEE_CreatePersistentObject(storageID, objectID, strlen(objectID), \ TEE_DATA_FLAG_ACCESS_WRITE | TEE_DATA_FLAG_GM, NULL, NULL, 0, &persistentObj); if (ret != TEE_SUCCESS) { tloge("Failed to create object:ret = 0x%x\n", ret); return ret; } // 写入数据时自动使用国密算法 ret = TEE_WriteObjectData(persistentObj, buffer, len); if (ret != TEE_SUCCESS) { tloge("Failed to write data:ret = 0x%x\n", ret); goto close; } tloge("write persistent data success\n"); close: TEE_CloseObject(persistentObj); return ret; } |
当客户在TEE内调用国密SM4-CBC/ECB算法时,可配置硬件加速,实现性能大幅度提升。使用硬件加速需新调用如下接口函数。
1 2 |
// 为operation句柄设置硬件加速引擎SEC_CRYPTO标志。 TEE_Result TEE_SetCryptoFlag(TEE_OperationHandle operation, uint32_t crypto); |
参数:
1 2 |
// 使能硬件加速,申请dma内存,用于减少内存拷贝。 int32_t tee_enable_crypto_accelerator(TEE_OperationHandle operation, size_t length, struct accel_memref_t *memrefs, int *memref_num); |
参数:
可参考如下简单示例:其使用硬件加速进行SM4-CBC计算。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 |
#define SM4_KEY_SIZE 128 #define DMA_ACCEL_MEM_NUM 2 #define SM4_IV_LEN 16 TEE_Result SEC_AccelerateSM4_CBC(void *inBuf, size_t inLen, void *outBuf, size_t *outLen) { TEE_Result ret; TEE_ObjectHandle key = NULL; TEE_OperationHandle operation = NULL; struct accel_memref_t accel_memrefs[DMA_ACCEL_MEM_NUM]; int memref_num = DMA_ACCEL_MEM_NUM; uint8_t iv[SM4_IV_LEN] = {0}; ret = TEE_AllocateTransientObject(TEE_TYPE_SM4, SM4_KEY_SIZE, &key); if (ret != TEE_SUCCESS) { tloge("alloc key object failed. ret=0x%x\n", ret); return ret; } ret = TEE_GenerateKey(key, SM4_KEY_SIZE, NULL, 0); if (ret != TEE_SUCCESS) { tloge("generate random key failed. ret=0x%x\n", ret); goto free_key; } ret = TEE_AllocateOperation(&operation, TEE_ALG_SM4_CBC_NOPAD, TEE_MODE_ENCRYPT, SM4_KEY_SIZE); if (ret != TEE_SUCCESS) { tloge("alloc operation failed, ret=0x%x\n", ret); goto free_key; } // 设置flag必须在TEE_SetOperationKey和tee_enable_crypto_accelerator之前 ret = TEE_SetCryptoFlag(operation, SEC_CRYPTO); if (ret != TEE_SUCCESS) { tloge("set crypto flag failed. ret=0x%x\n", ret); goto free_opt; } ret = TEE_SetOperationKey(operation, key); if (ret != TEE_SUCCESS) { tloge("operation set key failed. ret=0x%x\n", ret); goto free_opt; } // 申请2个dma内存,分别存放输入数据和输出数据 if (tee_enable_crypto_accelerator(operation, inLen, accel_memrefs, &memref_num) != 0 || memref_num != DMA_ACCEL_MEM_NUM) { tloge("tee_enable_crypto_accelerator failed\n"); goto free_opt; } (void)memcpy_s((void *)(accel_memrefs[0].buffer), inLen, inBuf, inLen); (void)memset_s((void *)(accel_memrefs[1].buffer), inLen, 0, inLen); TEE_CipherInit(operation, iv, SM4_IV_LEN); ret = TEE_CipherDoFinal(operation, NULL, inLen, NULL, outLen); if (ret != TEE_SUCCESS) { tloge("cipher do final failed. ret=0x%x\n", ret); goto free_opt; } (void)memcpy_s(outBuf, *outLen, (void *)(accel_memrefs[1].buffer), *outLen); tlogi("sm4-cbc cipher success. outLen=%d\n", *outLen); free_opt: TEE_FreeOperation(operation); free_key: TEE_FreeTransientObject(key); return ret; } |
1
|
gpd.ta.dma_allocable: true |
至此即完成了硬件加速的代码编写和配置。