在线时间4069 小时
UID3441752
注册时间2017-11-21
NXP金币753018
TA的每日心情 | 开心 2024-3-26 15:16 |
---|
签到天数: 266 天 [LV.8]以坛为家I
管理员
- 积分
- 32035
- 最后登录
- 2024-4-26
|
本系列文章对构建在LPC55SXX芯片上的安全可信计算环境ISEE-M产品所涉及的诸多方面进行介绍,共由以下五部分组成:
《终端平台基础设计》,对ISEE-M的整体设计架构进行介绍(点击查看)
《终端平台开发套件》,对ISEE-M的开发工具环境进行简介以及开发示例演示(本文)
《系统整体方案介绍》,对基于ISEE-M产品上构建的系统整体解决方案进行介绍(待续)
《生产线配套工具》,对基于ISEE-M产品上生产产线安全问题的思考和解决办法进行介绍(待续)
《生命周期管理》,对基于ISEE-M产品上研发的终端产品的维护、升级安全问题的思考和解决办法的介绍(待续)
上一期我们对ISEE-M的整体设计架构,核心模块以及系统优势进行了介绍,尤其系统的安全能力,是为物联设备终端提供强大的安全保障的关键。而今天我们要介绍ISEE-M的开发工具环境以及开发示例。上一期还没看过的同学,欢迎进入点击链接了解详情~
提到SDK,相信大家最关心的就是部署是否简单快速?是否便于开发?文档是否通俗易懂?嗯,当然Yes~
ISEE-M SDK基于MCUXpressoSDK设计开发,支持GP TEE Client API,可扩展支持第三方RTOS。ISEE-M内部支持GPTEE Internal API,非常方便用户开发。部署简单,可一键合入MCUXpresso SDK。同时提供开发指南,帮助开发者快速着手开发。
ISEE-M SDK使用说明
█ 开发环境
基于MCUXpresso SDK开发环境即可,无需额外环境准备
支持MCUXpresso SDK 2.6.2及以上
支持Toolchain/IDE: KEIL 5.28
█ 目录结构
ISEE-MSDK基于MCUXpresso SDK设计开发,与MCUXpresso SDK低耦合,目录结构参考下图所示:
SDK工程结构分为示例工程和ISEE-M组件库两部分:
示例工程分为两个子工程,demo_project_ns是非安全工程(REE侧),对应开发业务中安全不敏感的逻辑,demo_project_s是安全工程(TEE侧),对应开发业务中安全敏感的操作(敏感数据或关键算法)。
ISEE-M组件库的路径为middleware/iseem/sdk,doc存放ISEE-M相关文档,在include和library中,分别有teec和tee目录,teec由非安全工程使用,tee由安全工程使用。
█ 支持API & Module概述
GP TEEClient API v1.0及以上
GP TEEInternal API v1.0及以上
支持PUF/HashCrypt/Casper/RNG等关键硬件模块
GPTEE Client API(部分API例举):
TEEC_InitializeContext
TEEC_FinalizeContext
TEEC_RegisterSharedMemory
TEEC_AllocateSharedMemory
TEEC_ReleaseSharedMemory
TEEC_OpenSession
TEEC_CloseSession
TEEC_InvokeCommand
GPTEE Internal API(部分API例举)
Cryptographic Operations API
TEE_CipherInit
TEE_CipherUpdate
TEE_CipherDoFinal
TEE_AsymmetricEncrypt
TEE_AsymmetricDecrypt
TEE_AsymmetricSignDigest
TEE_AsymmetricVerifyDigest
TEE_GenerateRandom
TEE_MACInit
TEE_MACUpdate
TEE_MACComputeFinal
TEE_MACCompareFinal
TEE_DigestUpdate
TEE_DigestDoFinal
Trusted Storage API
TEE_OpenPersistentObject
TEE_CreatePersistentObject
TEE_CloseAndDeletePersistentObject
TEE_RenamePersistentObject
注:GlobalPlatform(GP)是跨行业的国际标准组织,致力于开发、制定并发布安全芯片的技术标准,以促进多应用产业环境的管理及其安全、可互操作的业务部署。
GlobalPlatform组织发布的GP相关规范可以在官方网站上获取:
http://globalplatform.org/specs-library/?filter-committee=tee
《TEE Client API Specification v1.0_GPD_SPE_00》
《TEE_Internal_Core_API_Specification_v1.2.1》
█ 开发CA/TA
CA(Client Application)泛指非安全侧(REE侧)的工程,可参考SDK目录中demo_project_ns。
TA(TrustedApplication)泛指安全侧(TEE侧)的工程,可参考SDK目录中demo_project_s。
开发者可以基于提供的示例代码和开发指南,开发实现相应功能。
在本示例中,CA将敏感数据存储到TA的安全存储中,并在CA需要时从TA安全存储中读出敏感数据。CA和TA通过GP TEE Client API通信,TA将CA请求的敏感数据加密后存储到非易失存储中,加密及存储通过TEE Internal API实现。密钥存储在TEE侧,REE侧程序无法获得,从而保证了敏感数据的安全。
CA代码片段如下:
1. int cmd_type = CMD_ENCRYPT_AND_STORAGE_WRITE;
2. const TEEC_UUID demo_ta_uuid = DEMO_TA_UUID;
3. TEEC_Context context;
4. TEEC_Session session;
5.
6. TEEC_InitializeContext(NULL,&context);
7. TEEC_OpenSession(&context,&session,&demo_ta_uuid,0,NULL,NULL,NULL);
8. TEEC_Operation operation;
9.
10. cmd_type = getchar();
11. cmd_type -= 0x30;
12. if (cmd_type == CMD_ENCRYPT_AND_STORAGE_WRITE)
13. {
14. operation.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_TEMP_INPUT,TEEC_NONE,
15. TEEC_NONE,TEEC_NONE);
16. operation.params[0].tmpref.buffer = send_data;
17. operation.params[0].tmpref.size = sizeof(send_data);
18. printf("CA: send write command\n",cmd_type);
19. TEEC_InvokeCommand(&session,CMD_ENCRYPT_AND_STORAGE_WRITE,&operation,NULL);
20. }
21. else if (cmd_type == CMD_STORAGE_READ_AND_DECRYPT)
22. {
23. hexdump8("CA: prepare data buffer:",receive_data,128);
24. operation.paramTypes = TEEC_PARAM_TYPES(TEEC_MEMREF_TEMP_OUTPUT,TEEC_NONE,
25. TEEC_NONE,TEEC_NONE);
26. operation.params[0].tmpref.buffer = receive_data;
27. operation.params[0].tmpref.size = sizeof(receive_data);
28. printf("CA: send read command\n",cmd_type);
29. TEEC_InvokeCommand(&session,CMD_STORAGE_READ_AND_DECRYPT,&operation,NULL);
30.
31. hexdump8("CA: receive data:",receive_data,128);
32. } else {
33. printf("cmd type %d not support\n",cmd_type);
34. }
35.
36. TEEC_CloseSession(&session);
37. TEEC_FinalizeContext(&context);
(提示:左右滑动查看完整代码行)
TA代码片段如下:
1. TEE_OperationHandle operation = NULL;
2. TEE_ObjectHandle keyObj = NULL;
3. TEE_ObjectHandle dataObj = NULL;
4. TEE_Attribute attr[1] = {0};
5. TEE_Result res = TEE_ERROR_GENERIC;
6.
7. size_t output_len = 0;
8. uint8_t *tmp_data_buf = NULL;
9.
10. if ((data == NULL) || (len != 128))
11. {
12. return TEE_ERROR_BAD_PARAMETERS;
13. }
14.
15. output_len = len;
16.
17. tmp_data_buf = TEE_Malloc(len, 0);
18. if (!tmp_data_buf)
19. {
20. LOG_ERR("TEE Malloc buffer failed");
21. return TEE_ERROR_OUT_OF_MEMORY;
22. }
23.
24. LOG_INFO("read data from persistent object.");
25.
26. res = TEE_OpenPersistentObject(TEE_STORAGE_PRIVATE, (void*)obj_name,
27. sizeof(obj_name), flags | TEE_DATA_FLAG_SHARE_READ |
28. TEE_DATA_FLAG_ACCESS_WRITE_META, &dataObj);
29. if (res != TEE_SUCCESS)
30. {
31. LOG_ERR("TEE_OpenPersistentObject failed");
32. goto out;
33. }
34.
35. res = TEE_ReadObjectData(dataObj, tmp_data_buf, len, &output_len);
36. if (res != TEE_SUCCESS)
37. {
38. LOG_ERR("read object failed");
39. goto out;
40. }
41. hexdump8("TA: data from storage with encrpyt",tmp_data_buf,output_len);
42. LOG_INFO("read data success.");
43.
44. LOG_INFO("decrypt data to ree buffer.");
45. res = TEE_AllocateOperation(&operation, TEE_ALG_AES_CBC_NOPAD,
46. TEE_MODE_DECRYPT, 256);
47. if (res != TEE_SUCCESS)
48. {
49. LOG_ERR("allocate operation failed, res %x", res);
50. goto out;
51. }
52.
53. res = TEE_AllocateTransientObject(TEE_TYPE_AES, 256, &keyObj);
54. if (res != TEE_SUCCESS)
55. {
56. LOG_ERR("allocate key failed, res %x", res);
57. goto out;
58. }
59.
60. TEE_InitRefAttribute(attr, TEE_ATTR_SECRET_VALUE, key, sizeof(key));
61. res = TEE_PopulateTransientObject(keyObj, attr, 1);
62. if (res != TEE_SUCCESS)
63. {
64. LOG_ERR("populate key failed, res %x", res);
65. goto out;
66. }
67.
68. res = TEE_SetOperationKey(operation, keyObj);
69. if (res != TEE_SUCCESS)
70. {
71. LOG_ERR("set key failed, res %x", res);
72. goto out;
73. }
74.
75. TEE_CipherInit(operation, iv, sizeof(iv));
76. res = TEE_CipherUpdate(operation, tmp_data_buf, output_len, data,
77. (size_t *)&len);
78. if (res != TEE_SUCCESS)
79. {
80. LOG_ERR("cipher update failed, res %x", res);
81. goto out;
82. }
83.
84. res = TEE_CipherDoFinal(operation, NULL, 0, data, (size_t *)&len);
85. if (res != TEE_SUCCESS)
86. {
87. LOG_ERR("cipher dofinal failed, res %x", res);
88. goto out;
89. }
90. LOG_INFO("decrypt data success.");
█ 工程编译
工程编译操作超简单,打开工程->编译->烧写 三步走即可。
演示工程环境说明:
开发板型号:LPC55S69-EVK
MCUXpresso SDK版本:2.6.2
编译步骤:
Keil打开示例程序工程
/boards/lpcxpresso55s69/iseem_examples/demo/cm33_core0/demo_project_s/mdk/demo_project.uvmpw,
该操作会打开demo_project_s,demo_project_ns两个子工程。
依次编译demo_project_s和demo_project_ns工程。
设置demo_project_s为活动工程,连接device,烧写。
Demo程序演示
█ 主要功能
在本示例中,CA将敏感信息存储到TA的安全存储中,并在CA需要时从TA安全存储中读出敏感信息。
CA和TA通过GP TEE ClientAPI通信,TA将CA请求的敏感信息加密后存储到非易失存储中,加密及存储通过TEE Internal API实现。密钥存储在TEE侧,REE侧程序无法获得,保证了密钥的安全。
程序可根据终端传入的参数来执行对应的功能。输入参数1,将信息存储到安全存储中;输入参数2,将信息从安全存储中读出。
█ API使用代码示例&编译
这部分已经在前面介绍,这里不再赘述。
█ 运行演示
运行前,先准备串口环境,用于查看运行结果。串口工具有很多,例如putty。
在串口工具中,设置好芯片设备的COM号以及波特率115200运行即可。
示例程序在串口中运行结果演示如下:
关于上述演示代码下载,请联系豆荚科技。
作者:豆荚科技 文章出处:恩智浦MCU加油站
|
|