• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2022 Huawei Technologies Co., Ltd.
3  * Licensed under the Mulan PSL v2.
4  * You can use this software according to the terms and conditions of the Mulan PSL v2.
5  * You may obtain a copy of Mulan PSL v2 at:
6  *     http://license.coscl.org.cn/MulanPSL2
7  * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR
8  * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR
9  * PURPOSE.
10  * See the Mulan PSL v2 for more details.
11  */
12 #include "tee_crypto_api.h"
13 #include "tee_object_api.h"
14 #include "tee_ext_api.h"
15 #include "tee_log.h"
16 #include "securec.h"
17 
18 #define TA_KEY_IV_LEN           16
19 #define TA_AES_KEY_LEN          32
20 #define TA_AES_KEY_LEN_BIT      (32 * 8)
21 #define TA_MAC_BUFFER_SIZE      32
22 #define TA_DATA_BUFFER_SIZE     64
23 
24 static uint8_t g_data_plain_text[TA_DATA_BUFFER_SIZE] = { 0 };
25 
26 enum {
27     CMD_ID_AES_CBC_MAC_DEMO = 1,
28     CMD_ID_AES_CMAC_DEMO = 2,
29 };
30 
31 /*
32  * Demo For AES-CBC-MAC
33  * You can generate a key and use AES-CBC-MAC to get the MAC of TA data
34  */
crypto_api_aes_cbc_mac_test(void)35 static TEE_Result crypto_api_aes_cbc_mac_test(void)
36 {
37     TEE_Result ret;
38 
39     /* operation */
40     TEE_OperationHandle operation_mac = NULL;
41     uint8_t object_id[TA_KEY_IV_LEN];
42 
43     /* key object */
44     TEE_ObjectHandle object = NULL;
45 
46     /* other params */
47     uint8_t *plaintext = NULL;
48     uint8_t mac_result[TA_MAC_BUFFER_SIZE] = { 0 };
49     size_t mac_len = TA_MAC_BUFFER_SIZE;
50 
51     /* 1.Allocate Operation */
52     ret = TEE_AllocateOperation(&operation_mac, TEE_ALG_AES_CBC_MAC_NOPAD, TEE_MODE_MAC, TA_AES_KEY_LEN_BIT);
53     if (ret != TEE_SUCCESS) {
54         tloge("Failed to allocate operation for mac, ret is 0x%x", ret);
55         return ret;
56     }
57 
58     /* 2. Generate key */
59     ret = TEE_AllocateTransientObject(TEE_TYPE_AES, TA_AES_KEY_LEN_BIT, &object);
60     if (ret != TEE_SUCCESS) {
61         tloge("Failed to allocate object for AES key: ret=0x%x", ret);
62         goto cleanup_1;
63     }
64     ret = TEE_GenerateKey(object, TA_AES_KEY_LEN_BIT, NULL, 0);
65     if (ret != TEE_SUCCESS) {
66         tloge("Failed to generate AES key:ret=0x%x", ret);
67         goto cleanup_2;
68     }
69 
70     /* 3.Set operation key */
71     ret = TEE_SetOperationKey(operation_mac, object);
72     if (ret != TEE_SUCCESS) {
73         tloge("failed to set operation key for mac:ret=0x%x", ret);
74         goto cleanup_2;
75     }
76 
77     /* 4.Set object_id and generate random plaintext(In user case maybe the plaintext is the key data of the TA) */
78     TEE_GenerateRandom(object_id, sizeof(object_id));
79     plaintext = g_data_plain_text;
80     TEE_GenerateRandom((void *)plaintext, sizeof(g_data_plain_text));
81 
82     /* 5.Use the Key and object_id to Do AES-CBC-MAC */
83     TEE_MACInit(operation_mac, object_id, sizeof(object_id));
84     TEE_MACUpdate(operation_mac, (void *)plaintext, (size_t)(sizeof(g_data_plain_text) - TA_MAC_BUFFER_SIZE));
85     ret = TEE_MACComputeFinal(operation_mac,
86         (void *)(plaintext + sizeof(g_data_plain_text) - TA_MAC_BUFFER_SIZE),
87         TA_MAC_BUFFER_SIZE,
88         (void *)(mac_result),
89         &mac_len);
90     if (ret != TEE_SUCCESS) {
91         tloge("Failed to mac compute final do final:ret=0x%x", ret);
92         goto cleanup_2;
93     }
94     tlogi("Succeed to do AES-CBC-MAC");
95 
96 cleanup_2:
97     TEE_FreeTransientObject(object);
98 cleanup_1:
99     TEE_FreeOperation(operation_mac);
100     return ret;
101 }
102 
103 /*
104  * Demo For AES-CMAC
105  * You can generate a key and use AES-CMAC to get the MAC of TA data
106  */
crypto_api_aes_cmac_test(void)107 static TEE_Result crypto_api_aes_cmac_test(void)
108 {
109     TEE_Result ret;
110 
111     /* operation */
112     TEE_OperationHandle operation_mac = NULL;
113 
114     /* key object */
115     TEE_ObjectHandle object = NULL;
116 
117     /* other params */
118     uint8_t *plaintext = NULL;
119     uint8_t mac_result[TA_MAC_BUFFER_SIZE] = { 0 };
120     size_t mac_len = TA_MAC_BUFFER_SIZE;
121 
122     /* 1.Allocate Operation */
123     ret = TEE_AllocateOperation(&operation_mac, TEE_ALG_AES_CMAC, TEE_MODE_MAC, TA_AES_KEY_LEN_BIT);
124     if (ret != TEE_SUCCESS) {
125         tloge("Failed to allocate operation for mac, ret is 0x%x", ret);
126         return ret;
127     }
128 
129     /* 2. Generate key */
130     ret = TEE_AllocateTransientObject(TEE_TYPE_AES, TA_AES_KEY_LEN_BIT, &object);
131     if (ret != TEE_SUCCESS) {
132         tloge("Failed to allocate object for AES key: ret=0x%x", ret);
133         goto cleanup_1;
134     }
135     ret = TEE_GenerateKey(object, TA_AES_KEY_LEN_BIT, NULL, 0);
136     if (ret != TEE_SUCCESS) {
137         tloge("Failed to generate AES key:ret=0x%x", ret);
138         goto cleanup_2;
139     }
140 
141     /* 3.Set operation key */
142     ret = TEE_SetOperationKey(operation_mac, object);
143     if (ret != TEE_SUCCESS) {
144         tloge("failed to set operation key for mac:ret=0x%x", ret);
145         goto cleanup_2;
146     }
147 
148     /* 4.Set object_id and generate random plaintext(In user case maybe the plaintext is the key data of the TA) */
149     plaintext = g_data_plain_text;
150     TEE_GenerateRandom((void *)plaintext, sizeof(g_data_plain_text));
151 
152     /* 5.Use the Key and object_id to Do AES-CMAC(CMAC do not use object_id) */
153     TEE_MACInit(operation_mac, NULL, 0);
154     TEE_MACUpdate(operation_mac, (void *)plaintext, (size_t)(sizeof(g_data_plain_text) - TA_MAC_BUFFER_SIZE));
155     ret = TEE_MACComputeFinal(operation_mac,
156         (void *)(plaintext + sizeof(g_data_plain_text) - TA_MAC_BUFFER_SIZE),
157         TA_MAC_BUFFER_SIZE,
158         (void *)(mac_result),
159         &mac_len);
160     if (ret != TEE_SUCCESS) {
161         tloge("Failed to mac compute final do final:ret=0x%x", ret);
162         goto cleanup_2;
163     }
164     tlogi("Succeed to do AES-CMAC\n");
165 cleanup_2:
166     TEE_FreeTransientObject(object);
167 cleanup_1:
168     TEE_FreeOperation(operation_mac);
169     return ret;
170 }
171 
TA_CreateEntryPoint(void)172 TEE_Result TA_CreateEntryPoint(void)
173 {
174     TEE_Result ret;
175 
176     tlogd("----- TA entry point ----- ");
177     /* When you develop your own CA, you need to change the name to your own path and CA name. */
178     ret = AddCaller_CA_exec("/vendor/bin/mac_demo_ca", 0);
179     if (ret == TEE_SUCCESS) {
180         tlogd("TA entry point: add ca whitelist success");
181     } else {
182         tloge("TA entry point: add ca whitelist failed");
183         return TEE_ERROR_GENERIC;
184     }
185 
186     return TEE_SUCCESS;
187 }
188 
TA_OpenSessionEntryPoint(uint32_t param_types,TEE_Param params[4],void ** session_context)189 TEE_Result TA_OpenSessionEntryPoint(uint32_t param_types, TEE_Param params[4], void** session_context)
190 {
191     (void)param_types;
192     (void)params;
193     (void)session_context;
194     tlogd("---- TA MAC Demo OpenSession EntryPoint -----");
195 
196     return TEE_SUCCESS;
197 }
198 
TA_InvokeCommandEntryPoint(void * session_context,uint32_t cmd_id,uint32_t param_types,TEE_Param params[4])199 TEE_Result TA_InvokeCommandEntryPoint(void* session_context, uint32_t cmd_id, uint32_t param_types, TEE_Param params[4])
200 {
201     (void)session_context;
202     (void)params;
203     TEE_Result ret;
204     if (!check_param_type(param_types,
205         TEE_PARAM_TYPE_NONE,
206         TEE_PARAM_TYPE_NONE,
207         TEE_PARAM_TYPE_NONE,
208         TEE_PARAM_TYPE_NONE)) {
209         tloge("Bad expected parameter types");
210         return TEE_ERROR_BAD_PARAMETERS;
211     }
212 
213     tlogd("--- TA MAC Demo InvokeCommand EntryPoint ---");
214     switch (cmd_id) {
215     case CMD_ID_AES_CBC_MAC_DEMO:
216         ret = crypto_api_aes_cbc_mac_test();
217         break;
218     case CMD_ID_AES_CMAC_DEMO:
219         ret = crypto_api_aes_cmac_test();
220         break;
221     default:
222         tloge("invalid cmd:%u", cmd_id);
223         ret = TEE_ERROR_BAD_PARAMETERS;
224         break;
225     }
226     if (ret != TEE_SUCCESS) {
227         tloge("Cmd id %u Test Failed, ret is 0x%x", cmd_id, ret);
228     } else {
229         tlogd("Cmd id %u Test Pass", cmd_id);
230     }
231     return ret;
232 }
233 
TA_CloseSessionEntryPoint(void * session_context)234 void TA_CloseSessionEntryPoint(void* session_context)
235 {
236     (void)session_context;
237     tlogd("---- TA MAC Demo CloseSession EntryPoint -----");
238 }
239 
TA_DestroyEntryPoint(void)240 void TA_DestroyEntryPoint(void)
241 {
242     tlogd("---- TA MAC Demo Destroy EntryPoint ----");
243 }
244