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 <string.h>
14 #include <tee_log.h>
15 #include <crypto_driver_adaptor.h>
16 #include <crypto_inner_defines.h>
17 #include <crypto_hal_hmac.h>
18 #include <tee_property_inner.h>
19 #include <tee_object_api.h>
20 #include "tee_operation.h"
21
22 #ifndef GP_COMPATIBLE
23 #define TEE_Panic(x) \
24 do { \
25 } while (0)
26 #endif
27
28 struct mac_op_config_s {
29 uint32_t expect_class;
30 uint32_t expect_mode;
31 uint32_t algorithm;
32 uint32_t expect_iv_length;
33 };
34
35 static const struct mac_op_config_s g_mac_config[] = {
36 { TEE_OPERATION_MAC, TEE_MODE_MAC, TEE_ALG_HMAC_MD5, 0 },
37 { TEE_OPERATION_MAC, TEE_MODE_MAC, TEE_ALG_HMAC_SHA1, 0 },
38 { TEE_OPERATION_MAC, TEE_MODE_MAC, TEE_ALG_HMAC_SHA224, 0 },
39 { TEE_OPERATION_MAC, TEE_MODE_MAC, TEE_ALG_HMAC_SHA256, 0 },
40 { TEE_OPERATION_MAC, TEE_MODE_MAC, TEE_ALG_HMAC_SHA384, 0 },
41 { TEE_OPERATION_MAC, TEE_MODE_MAC, TEE_ALG_HMAC_SHA512, 0 },
42 { TEE_OPERATION_MAC, TEE_MODE_MAC, TEE_ALG_AES_CBC_MAC_NOPAD, 16 },
43 { TEE_OPERATION_MAC, TEE_MODE_MAC, TEE_ALG_AES_CMAC, 0 },
44 { TEE_OPERATION_MAC, TEE_MODE_MAC, TEE_ALG_DES_CBC_MAC_NOPAD, 8 },
45 { TEE_OPERATION_MAC, TEE_MODE_MAC, TEE_ALG_DES3_CBC_MAC_NOPAD, 8 },
46 { TEE_OPERATION_MAC, TEE_MODE_MAC, TEE_ALG_HMAC_SM3, 0 },
47 { TEE_OPERATION_MAC, TEE_MODE_MAC, TEE_ALG_SIP_HASH, 0 },
48 };
mac_init_check_config(TEE_OperationHandle operation,const void * iv,size_t iv_len)49 static TEE_Result mac_init_check_config(TEE_OperationHandle operation, const void *iv, size_t iv_len)
50 {
51 const struct mac_op_config_s *config = NULL;
52 uint32_t index;
53
54 for (index = 0; index < ELEM_NUM(g_mac_config); index++) {
55 if (operation->algorithm == g_mac_config[index].algorithm) {
56 config = &g_mac_config[index];
57 break;
58 }
59 }
60
61 bool check = (config == NULL || operation->operationClass != config->expect_class ||
62 operation->mode != config->expect_mode ||
63 (config->expect_iv_length != 0 && (config->expect_iv_length != iv_len || iv == NULL)));
64 if (check) {
65 tloge("This Operation is invalid\n");
66 return TEE_ERROR_BAD_PARAMETERS;
67 }
68
69 return TEE_SUCCESS;
70 }
71
mac_init_operation_state_check(TEE_OperationHandle operation,const void * iv,size_t iv_len)72 static TEE_Result mac_init_operation_state_check(TEE_OperationHandle operation, const void *iv, size_t iv_len)
73 {
74 uint32_t api_level = tee_get_ta_api_level();
75 if (api_level >= API_LEVEL1_1_1) {
76 if ((operation->handleState & TEE_HANDLE_FLAG_KEY_SET) != TEE_HANDLE_FLAG_KEY_SET) {
77 tloge("Invalid operation key state for this operation\n");
78 return TEE_ERROR_BAD_STATE;
79 }
80
81 operation->handleState &= ~TEE_HANDLE_FLAG_INITIALIZED;
82
83 if (operation->keyValue == NULL) {
84 tloge("Operation key is uninitialized\n");
85 return TEE_ERROR_BAD_PARAMETERS;
86 }
87 }
88
89 return mac_init_check_config(operation, iv, iv_len);
90 }
91
mac_init_set_key(uint64_t * key_ptr,uint32_t * key_size,TEE_OperationHandle operation,const void * iv,size_t iv_len)92 static TEE_Result mac_init_set_key(uint64_t *key_ptr, uint32_t *key_size, TEE_OperationHandle operation,
93 const void *iv, size_t iv_len)
94 {
95 bool check = (key_ptr == NULL || key_size == NULL || operation == NULL);
96 if (check) {
97 tloge("input is invalid!");
98 return TEE_ERROR_BAD_PARAMETERS;
99 }
100
101 if (operation->keyValue != NULL && operation->keySize != 0) {
102 *key_ptr = (uint64_t)(uintptr_t)(operation->keyValue);
103 *key_size = operation->keySize;
104 } else if ((iv != NULL) && iv_len <= (TEE_MAX_KEY_SIZE_IN_BITS / BIT_TO_BYTE) &&
105 tee_get_ta_api_level() == API_LEVEL1_0) {
106 *key_ptr = (uint64_t)(uintptr_t)iv;
107 *key_size = iv_len;
108 } else {
109 tloge("Key is not set up yet, please set up the key before initialization, iv_len = 0x%x\n", iv_len);
110 return TEE_ERROR_BAD_PARAMETERS;
111 }
112 return TEE_SUCCESS;
113 }
114
hmac_init_hal(TEE_OperationHandle operation,const void * iv,size_t iv_len,uint32_t engine)115 static TEE_Result hmac_init_hal(TEE_OperationHandle operation, const void *iv, size_t iv_len, uint32_t engine)
116 {
117 struct symmerit_key_t hmac_key = {0};
118 uint32_t temp_key_size = 0;
119 TEE_Result ret = mac_init_set_key(&(hmac_key.key_buffer), &temp_key_size, operation, iv, iv_len);
120 if (ret != TEE_SUCCESS)
121 return ret;
122
123 hmac_key.key_size = temp_key_size;
124 hmac_key.key_type = CRYPTO_KEYTYPE_USER;
125
126 free_operation_ctx(operation);
127 operation->crypto_ctxt = tee_crypto_hmac_init(operation->algorithm, &hmac_key, engine);
128 if (operation->crypto_ctxt == NULL)
129 return TEE_ERROR_GENERIC;
130
131 return TEE_SUCCESS;
132 }
133
is_cipher_algorithm(uint32_t algorithm)134 static bool is_cipher_algorithm(uint32_t algorithm)
135 {
136 bool check = (algorithm == TEE_ALG_AES_CBC_MAC_NOPAD || algorithm == TEE_ALG_AES_CMAC ||
137 algorithm == TEE_ALG_DES_CBC_MAC_NOPAD || algorithm == TEE_ALG_DES3_CBC_MAC_NOPAD);
138 if (check)
139 return true;
140
141 return false;
142 }
143
TEE_MACInit(TEE_OperationHandle operation,void * IV,size_t IVLen)144 void TEE_MACInit(TEE_OperationHandle operation, void *IV, size_t IVLen)
145 {
146 TEE_Result ret;
147
148 bool check = (operation == NULL || (check_operation((const TEE_OperationHandle)operation) != TEE_SUCCESS));
149 if (check) {
150 tloge("bad params");
151 TEE_Panic(TEE_ERROR_BAD_PARAMETERS);
152 return;
153 }
154 if (crypto_lock_operation(operation) != TEE_SUCCESS)
155 return;
156
157 ret = mac_init_operation_state_check(operation, IV, IVLen);
158 if (ret != TEE_SUCCESS) {
159 crypto_unlock_operation(operation);
160 TEE_Panic(ret);
161 return;
162 }
163 crypto_hal_info *crypto_hal_data = (crypto_hal_info *)(operation->hal_info);
164 if (crypto_hal_data == NULL) {
165 tloge("Crypto hal data is NULL\n");
166 crypto_unlock_operation(operation);
167 TEE_Panic(ret);
168 return;
169 }
170
171 if (is_cipher_algorithm(operation->algorithm)) {
172 crypto_unlock_operation(operation);
173 TEE_CipherInit(operation, IV, IVLen);
174 tlogd("TEE_AES_MACInit success\n");
175 return;
176 }
177
178 ret = hmac_init_hal(operation, IV, IVLen, crypto_hal_data->crypto_flag);
179 operation->handleState |= TEE_HANDLE_FLAG_INITIALIZED;
180 crypto_unlock_operation(operation);
181 if (ret != TEE_SUCCESS)
182 TEE_Panic(ret);
183
184 return;
185 }
186
mac_update_check_config(const TEE_OperationHandle operation)187 static TEE_Result mac_update_check_config(const TEE_OperationHandle operation)
188 {
189 const struct mac_op_config_s *config = NULL;
190
191 for (uint32_t index = 0; index < ELEM_NUM(g_mac_config); index++) {
192 if (operation->algorithm == g_mac_config[index].algorithm) {
193 config = &g_mac_config[index];
194 break;
195 }
196 }
197
198 if (config == NULL || operation->operationClass != config->expect_class ||
199 operation->mode != config->expect_mode) {
200 tloge("Invalid param for this operation!\n");
201 return TEE_ERROR_BAD_PARAMETERS;
202 }
203
204 return TEE_SUCCESS;
205 }
206
mac_update_final_operation_state_check(const TEE_OperationHandle operation)207 static TEE_Result mac_update_final_operation_state_check(const TEE_OperationHandle operation)
208 {
209 uint32_t api_level = tee_get_ta_api_level();
210 if (api_level >= API_LEVEL1_1_1) {
211 if ((operation->handleState & TEE_HANDLE_FLAG_KEY_SET) != TEE_HANDLE_FLAG_KEY_SET) {
212 tloge("Invalid operation key state for this operation\n");
213 return TEE_ERROR_BAD_STATE;
214 }
215 if (operation->keyValue == NULL) {
216 tloge("Operation key is uninitialized\n");
217 return TEE_ERROR_BAD_PARAMETERS;
218 }
219 if ((operation->handleState & TEE_HANDLE_FLAG_INITIALIZED) != TEE_HANDLE_FLAG_INITIALIZED) {
220 tloge("Invalid operation state: 0x%x\n", operation->handleState);
221 return TEE_ERROR_BAD_STATE;
222 }
223 }
224
225 return mac_update_check_config(operation);
226 }
227
hmac_update_hal(TEE_OperationHandle operation,const void * chunk,size_t chunk_size)228 static TEE_Result hmac_update_hal(TEE_OperationHandle operation, const void *chunk, size_t chunk_size)
229 {
230 struct memref_t data_in = {0};
231 data_in.buffer = (uint64_t)(uintptr_t)chunk;
232 data_in.size = (uint32_t)chunk_size;
233
234 int32_t ret = tee_crypto_hmac_update(operation->crypto_ctxt, &data_in);
235 return change_hal_ret_to_gp(ret);
236 }
237
TEE_MACUpdate(TEE_OperationHandle operation,const void * chunk,size_t chunkSize)238 void TEE_MACUpdate(TEE_OperationHandle operation, const void *chunk, size_t chunkSize)
239 {
240 TEE_Result ret;
241
242 bool check = (operation == NULL || chunk == NULL || chunkSize == 0 ||
243 (check_operation((const TEE_OperationHandle)operation) != TEE_SUCCESS));
244 if (check) {
245 tloge("bad params");
246 TEE_Panic(TEE_ERROR_BAD_PARAMETERS);
247 return;
248 }
249
250 if (crypto_lock_operation(operation) != TEE_SUCCESS)
251 return;
252
253 ret = mac_update_final_operation_state_check((const TEE_OperationHandle)operation);
254 if (ret != TEE_SUCCESS) {
255 crypto_unlock_operation(operation);
256 TEE_Panic(ret);
257 return;
258 }
259
260 if (is_cipher_algorithm(operation->algorithm)) {
261 crypto_unlock_operation(operation);
262 ret = TEE_CipherUpdate(operation, chunk, chunkSize, NULL, NULL);
263 if (ret != TEE_SUCCESS) {
264 tloge("cipher update failed\n");
265 TEE_Panic(ret);
266 }
267 return;
268 }
269
270 ret = hmac_update_hal(operation, chunk, chunkSize);
271 if (ret != TEE_SUCCESS) {
272 tloge("MACUpdate failed, ret is 0x%x\n", ret);
273 operation->handleState &= ~TEE_HANDLE_FLAG_INITIALIZED;
274 crypto_unlock_operation(operation);
275 TEE_Panic(ret);
276 return;
277 }
278 crypto_unlock_operation(operation);
279 }
280
hmac_dofinal_hal(TEE_OperationHandle operation,const void * message,size_t message_len,void * mac,size_t * mac_len)281 static TEE_Result hmac_dofinal_hal(TEE_OperationHandle operation, const void *message, size_t message_len,
282 void *mac, size_t *mac_len)
283 {
284 struct memref_t data_in = {0};
285 data_in.buffer = (uint64_t)(uintptr_t)message;
286 data_in.size = (uint32_t)message_len;
287
288 struct memref_t data_out = {0};
289 data_out.buffer = (uint64_t)(uintptr_t)mac;
290 data_out.size = (uint32_t)(*mac_len);
291
292 int32_t ret = tee_crypto_hmac_dofinal(operation->crypto_ctxt, &data_in, &data_out);
293 free_operation_ctx(operation);
294 if (ret != TEE_SUCCESS) {
295 tloge("hmac dofinal failed");
296 return change_hal_ret_to_gp(ret);
297 }
298 *mac_len = (size_t)data_out.size;
299 operation->digestLength = data_out.size;
300
301 return TEE_SUCCESS;
302 }
303
crypto_output_buff_len_check(uint32_t algorithm,size_t output_len)304 static TEE_Result crypto_output_buff_len_check(uint32_t algorithm, size_t output_len)
305 {
306 for (uint32_t i = 0; i < ELEM_NUM(g_output_lower_limit); i++) {
307 if (g_output_lower_limit[i].algorithm == algorithm) {
308 if (output_len < g_output_lower_limit[i].output_lower_limit)
309 return TEE_ERROR_SHORT_BUFFER;
310 else
311 return TEE_SUCCESS;
312 }
313 }
314
315 return TEE_ERROR_NOT_SUPPORTED;
316 }
317
TEE_MACComputeFinal(TEE_OperationHandle operation,const void * message,size_t messageLen,void * mac,size_t * macLen)318 TEE_Result TEE_MACComputeFinal(TEE_OperationHandle operation, const void *message, size_t messageLen, void *mac,
319 size_t *macLen)
320 {
321 bool check = (operation == NULL || mac == NULL || macLen == NULL || *macLen == 0 ||
322 (check_operation((const TEE_OperationHandle)operation) != TEE_SUCCESS));
323 if (check) {
324 tloge("bad params");
325 TEE_Panic(TEE_ERROR_BAD_PARAMETERS);
326 return TEE_ERROR_BAD_PARAMETERS;
327 }
328
329 if (crypto_lock_operation(operation) != TEE_SUCCESS)
330 return TEE_ERROR_GENERIC;
331
332 TEE_Result ret = mac_update_final_operation_state_check((const TEE_OperationHandle)operation);
333 if (ret != TEE_SUCCESS) {
334 crypto_unlock_operation(operation);
335 TEE_Panic(ret);
336 return ret;
337 }
338 if (is_cipher_algorithm(operation->algorithm)) {
339 crypto_unlock_operation(operation);
340 return TEE_CipherDoFinal(operation, message, messageLen, mac, macLen);
341 }
342
343 if (crypto_output_buff_len_check(operation->algorithm, *macLen) != TEE_SUCCESS) {
344 tloge("Output buffer is too short\n");
345 crypto_unlock_operation(operation);
346 return TEE_ERROR_SHORT_BUFFER;
347 }
348 ret = hmac_dofinal_hal(operation, message, messageLen, mac, macLen);
349 operation->handleState &= ~TEE_HANDLE_FLAG_INITIALIZED;
350 crypto_unlock_operation(operation);
351 if (ret != TEE_SUCCESS) {
352 if (ret != TEE_ERROR_SHORT_BUFFER)
353 TEE_Panic(ret);
354 }
355 return ret;
356 }
357
tee_mac_commare_final100(TEE_OperationHandle operation,const void * message,size_t message_len,const void * mac,const size_t * mac_len)358 TEE_Result tee_mac_commare_final100(TEE_OperationHandle operation, const void *message, size_t message_len,
359 const void *mac, const size_t *mac_len)
360 {
361 if (mac_len == NULL)
362 return TEE_ERROR_BAD_PARAMETERS;
363 uint8_t hmac_result_buff_temp[MAX_HMAC_LEN] = { 0 };
364 size_t size = *mac_len;
365
366 TEE_Result ret = TEE_MACComputeFinal(operation, message, message_len, hmac_result_buff_temp, &size);
367 if (ret != TEE_SUCCESS) {
368 tloge("TEE_MACComputeFinal failed\n");
369 return ret;
370 }
371
372 bool check = (size != *mac_len || TEE_MemCompare((void *)hmac_result_buff_temp, mac, (uint32_t)size) != 0);
373 if (check) {
374 tloge("size 0x%x != *mac_len 0x%x or compare failed!\n", size, *mac_len);
375 return TEE_ERROR_MAC_INVALID;
376 }
377
378 return ret;
379 }
380
tee_mac_commare_final111(TEE_OperationHandle operation,const void * message,size_t message_len,const void * mac,const size_t mac_len)381 TEE_Result tee_mac_commare_final111(TEE_OperationHandle operation, const void *message, size_t message_len,
382 const void *mac, const size_t mac_len)
383 {
384 size_t len = mac_len;
385
386 return tee_mac_commare_final100(operation, message, message_len, mac, &len);
387 }
388