• 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 <string.h>
14 #include <tee_log.h>
15 #include <ta_framework.h>
16 #include <tee_ext_api.h>
17 #include <tee_property_inner.h>
18 #include <tee_object_api.h>
19 #include <crypto_inner_defines.h>
20 #include <crypto_hal_ae.h>
21 #include <crypto_hal.h>
22 #include <crypto_driver_adaptor.h>
23 #include "tee_operation.h"
24 
25 #define MAX_TAG_NUM   7
26 #define MAX_NONCE_NUM 7
27 
28 /* For GP compatible, we add some panic when there is some error, For common use, we need to disable this panic */
29 #ifndef GP_COMPATIBLE
30 #define TEE_Panic(x) \
31     do {             \
32     } while (0)
33 #endif
34 
35 struct ae_op_config_s {
36     uint32_t expect_class;
37     uint32_t expect_mode[MAX_MODE_NUM];
38     uint32_t algorithm;
39     uint32_t nonce_count;
40     uint32_t expect_nonce[MAX_NONCE_NUM];
41     uint32_t tag_count;
42     uint32_t expect_tag[MAX_TAG_NUM];
43 };
44 
45 #define GCM_NOUNCE_NUM 2
46 #define GCM_TAG_NUM    5
47 #define CCM_NOUNCE_NUM 7
48 #define CCM_TAG_NUM    7
49 static const struct ae_op_config_s g_ae_config[] = {
50     { TEE_OPERATION_AE,
51         { TEE_MODE_ENCRYPT, TEE_MODE_DECRYPT },
52         TEE_ALG_AES_GCM,
53         GCM_NOUNCE_NUM,
54         /* GCM nounce len: can be 7 or 12 bytes */
55         { 7, 12 },
56         GCM_TAG_NUM,
57         /* tagLen: Size in bits of the tag. For AES-GCM, can be 128, 120, 112, 104, or 96. */
58         { 96 / 8, 104 / 8, 112 / 8, 120 / 8, 128 / 8 } },
59     { TEE_OPERATION_AE,
60         { TEE_MODE_ENCRYPT, TEE_MODE_DECRYPT },
61         TEE_ALG_AES_CCM,
62         CCM_NOUNCE_NUM,
63         /* CCM nounce len:can be 7 ~ 13 bytes */
64         { 7, 8, 9, 10, 11, 12, 13 },
65         CCM_TAG_NUM,
66         /* tagLen: Size in bits of the tag. For AES-CCM, can be 128, 112, 96, 80, 64, 48, or 32 */
67         { 32 / 8, 48 / 8, 64 / 8, 80 / 8, 96 / 8, 112 / 8, 128 / 8 } },
68     { TEE_OPERATION_AE,
69         { TEE_MODE_ENCRYPT, TEE_MODE_DECRYPT },
70         TEE_ALG_SM4_GCM,
71         GCM_NOUNCE_NUM,
72         /* GCM nounce len: can be 7 or 12 bytes */
73         { 7, 12 },
74         GCM_TAG_NUM,
75         /* tagLen: Size in bits of the tag. For SM4-GCM, can be 128, 120, 112, 104, or 96. */
76         { 96 / 8, 104 / 8, 112 / 8, 120 / 8, 128 / 8 } },
77 };
78 
check_tag_length_valid(const uint32_t * valid_tag_array,uint32_t array_size,uint32_t tag_length)79 static TEE_Result check_tag_length_valid(const uint32_t *valid_tag_array, uint32_t array_size, uint32_t tag_length)
80 {
81     uint32_t index;
82 
83     for (index = 0; index < array_size; index++) {
84         if (valid_tag_array[index] == tag_length)
85             return TEE_SUCCESS;
86     }
87 
88     return TEE_ERROR_NOT_SUPPORTED;
89 }
90 
check_nonce_length_valid(const uint32_t * valid_nonce_array,uint32_t array_size,uint32_t nonce_length)91 static TEE_Result check_nonce_length_valid(const uint32_t *valid_nonce_array, uint32_t array_size,
92     uint32_t nonce_length)
93 {
94     uint32_t index;
95     for (index = 0; index < array_size; index++) {
96         if (valid_nonce_array[index] == nonce_length)
97             return TEE_SUCCESS;
98     }
99 
100     return TEE_ERROR_BAD_PARAMETERS;
101 }
102 
ae_init_operation_error(const TEE_OperationHandle operation)103 static TEE_Result ae_init_operation_error(const TEE_OperationHandle operation)
104 {
105     if ((operation->handleState & TEE_HANDLE_FLAG_KEY_SET) != TEE_HANDLE_FLAG_KEY_SET) {
106         tloge("Invalid operation key state for this operation\n");
107         return TEE_ERROR_BAD_STATE;
108     }
109 
110     if ((operation->handleState & TEE_HANDLE_FLAG_INITIALIZED) == TEE_HANDLE_FLAG_INITIALIZED) {
111         tloge("Invalid operation state for this operation\n");
112         return TEE_ERROR_BAD_STATE;
113     }
114 
115     if (operation->keyValue == NULL) {
116         tloge("Please initialize operation key first\n");
117         return TEE_ERROR_BAD_PARAMETERS;
118     }
119 
120     return TEE_SUCCESS;
121 }
122 
ae_init_check_config(const TEE_OperationHandle operation,const struct ae_op_config_s * config,uint32_t tag_length,uint32_t nonce_length)123 static TEE_Result ae_init_check_config(const TEE_OperationHandle operation, const struct ae_op_config_s *config,
124     uint32_t tag_length, uint32_t nonce_length)
125 {
126     if (operation->operationClass != config->expect_class) {
127         tloge("This operationClass is invalid\n");
128         return TEE_ERROR_BAD_PARAMETERS;
129     }
130 
131     if (operation->mode != config->expect_mode[0] && operation->mode != config->expect_mode[1]) {
132         tloge("This operation mode is invalid\n");
133         return TEE_ERROR_BAD_PARAMETERS;
134     }
135 
136     TEE_Result ret = check_nonce_length_valid(config->expect_nonce, config->nonce_count, nonce_length);
137     if (ret != TEE_SUCCESS) {
138         tloge("Invalid nonce length for this operation\n");
139         return ret;
140     }
141 
142     ret = check_tag_length_valid(config->expect_tag, config->tag_count, tag_length);
143     if (ret != TEE_SUCCESS)
144         tloge("Invalid tag length for this operation\n");
145 
146     return ret;
147 }
148 
ae_init_operation_state_check(const TEE_OperationHandle operation,uint32_t tag_length,uint32_t nonce_length)149 static TEE_Result ae_init_operation_state_check(const TEE_OperationHandle operation, uint32_t tag_length,
150     uint32_t nonce_length)
151 {
152     const struct ae_op_config_s *config = NULL;
153     uint32_t index;
154     TEE_Result ret;
155 
156     uint32_t api_level = tee_get_ta_api_level();
157     if (api_level > API_LEVEL1_0) {
158         ret = ae_init_operation_error(operation);
159         if (ret != TEE_SUCCESS)
160             return ret;
161     }
162 
163     for (index = 0; index < ELEM_NUM(g_ae_config); index++) {
164         if (operation->algorithm == g_ae_config[index].algorithm) {
165             config = &g_ae_config[index];
166             break;
167         }
168     }
169 
170     if (config == NULL) {
171         tloge("This algorithm is invalid\n");
172         return TEE_ERROR_BAD_PARAMETERS;
173     }
174 
175     return ae_init_check_config(operation, config, tag_length, nonce_length);
176 }
177 
ae_init_hal(TEE_OperationHandle operation,const operation_ae_init * ae_init_param,uint32_t engine)178 static TEE_Result ae_init_hal(TEE_OperationHandle operation, const operation_ae_init *ae_init_param, uint32_t engine)
179 {
180     uint32_t direction = (operation->mode == TEE_MODE_ENCRYPT) ? ENC_MODE : DEC_MODE;
181     free_operation_ctx(operation);
182 
183     struct symmerit_key_t ae_key = {0};
184     ae_key.key_buffer = (uint64_t)(uintptr_t)(operation->keyValue);
185     ae_key.key_size = operation->keySize;
186     ae_key.key_type = CRYPTO_KEYTYPE_USER;
187 
188     struct ae_init_data ae_init_param_hal = {0};
189     ae_init_param_hal.nonce = (uint64_t)(uintptr_t)(ae_init_param->nonce);
190     ae_init_param_hal.nonce_len = (uint32_t)ae_init_param->nonce_len;
191     ae_init_param_hal.tag_len = ae_init_param->tag_len;
192     ae_init_param_hal.aad_len = (uint32_t)ae_init_param->aad_len;
193     ae_init_param_hal.payload_len = (uint32_t)ae_init_param->payload_len;
194     operation->crypto_ctxt = tee_crypto_ae_init(operation->algorithm, direction, &ae_key,
195         &ae_init_param_hal, engine);
196     if (operation->crypto_ctxt == NULL)
197         return TEE_ERROR_NOT_SUPPORTED;
198 
199     return TEE_SUCCESS;
200 }
201 
TEE_AEInit(TEE_OperationHandle operation,void * nonce,size_t nonceLen,uint32_t tagLen,size_t AADLen,size_t payloadLen)202 TEE_Result TEE_AEInit(TEE_OperationHandle operation, void *nonce, size_t nonceLen, uint32_t tagLen, size_t AADLen,
203     size_t payloadLen)
204 {
205     bool check = (operation == NULL || (check_operation((const TEE_OperationHandle)operation) != TEE_SUCCESS) ||
206         nonce == NULL);
207     if (check) {
208         tloge("bad params");
209         TEE_Panic(TEE_ERROR_BAD_PARAMETERS);
210         return TEE_ERROR_BAD_PARAMETERS;
211     }
212 
213     uint32_t api_level = tee_get_ta_api_level();
214     if (api_level >= API_LEVEL1_1_1)
215         tagLen = tagLen / BIT_TO_BYTE;
216 
217     if (crypto_lock_operation(operation) != TEE_SUCCESS)
218         return TEE_ERROR_GENERIC;
219 
220     TEE_Result ret = ae_init_operation_state_check((const TEE_OperationHandle)operation, tagLen, nonceLen);
221     if (ret != TEE_SUCCESS)
222         goto end;
223 
224     operation->digestLength          = tagLen;
225 
226     crypto_hal_info *crypto_hal_data = (crypto_hal_info *)(operation->hal_info);
227     if (crypto_hal_data == NULL) {
228         tloge("Ae init call back is invalid\n");
229         ret = TEE_ERROR_BAD_PARAMETERS;
230         goto end;
231     }
232 
233     operation_ae_init ae_init_param = { 0 };
234     ae_init_param.nonce       = nonce;
235     ae_init_param.nonce_len   = nonceLen;
236     ae_init_param.tag_len     = tagLen;
237     ae_init_param.aad_len     = AADLen;
238     ae_init_param.payload_len = payloadLen;
239 
240     ret = ae_init_hal(operation, &ae_init_param, crypto_hal_data->crypto_flag);
241     if (ret != TEE_SUCCESS)
242         tloge("ae init hal failed, ret = 0x%x", ret);
243 end:
244     crypto_unlock_operation(operation);
245     if (ret != TEE_ERROR_NOT_SUPPORTED && ret != TEE_SUCCESS)
246         TEE_Panic(ret);
247     return ret;
248 }
249 
ae_update_check_config(const TEE_OperationHandle operation,const struct ae_op_config_s * config)250 static TEE_Result ae_update_check_config(const TEE_OperationHandle operation, const struct ae_op_config_s *config)
251 {
252     if (operation->operationClass != config->expect_class) {
253         tloge("This operationClass is invalid!\n");
254         return TEE_ERROR_BAD_PARAMETERS;
255     }
256 
257     if (operation->mode != config->expect_mode[0] && operation->mode != config->expect_mode[1]) {
258         tloge("This operation mode is invalid!\n");
259         return TEE_ERROR_BAD_PARAMETERS;
260     }
261 
262     return TEE_SUCCESS;
263 }
264 
ae_update_operation_check(const TEE_OperationHandle operation)265 static TEE_Result ae_update_operation_check(const TEE_OperationHandle operation)
266 {
267     const struct ae_op_config_s *config = NULL;
268     uint32_t index;
269     for (index = 0; index < ELEM_NUM(g_ae_config); index++) {
270         if (operation->algorithm == g_ae_config[index].algorithm) {
271             config = &g_ae_config[index];
272             break;
273         }
274     }
275 
276     if (config == NULL) {
277         tloge("This algorithm is invalid!\n");
278         return TEE_ERROR_BAD_PARAMETERS;
279     }
280     return ae_update_check_config(operation, config);
281 }
282 
ae_update_aad_check(TEE_OperationHandle operation,uint32_t api_level)283 static TEE_Result ae_update_aad_check(TEE_OperationHandle operation, uint32_t api_level)
284 {
285     if (api_level > API_LEVEL1_1_1) {
286         if ((operation->handleState & TEE_HANDLE_FLAG_INITIALIZED) == TEE_HANDLE_FLAG_INITIALIZED) {
287             tloge("Invalid operation state for this operation\n");
288             return TEE_ERROR_BAD_STATE;
289         }
290     }
291 
292     if ((operation->handleState & TEE_HANDLE_FLAG_KEY_SET) != TEE_HANDLE_FLAG_KEY_SET) {
293         tloge("Invalid operation key state for this operation\n");
294         return TEE_ERROR_BAD_STATE;
295     }
296     return ae_update_operation_check(operation);
297 }
298 
ae_update_check(TEE_OperationHandle operation)299 static TEE_Result ae_update_check(TEE_OperationHandle operation)
300 {
301     if ((operation->handleState & TEE_HANDLE_FLAG_KEY_SET) != TEE_HANDLE_FLAG_KEY_SET) {
302         tloge("Invalid operation key state for this operation\n");
303         return TEE_ERROR_BAD_STATE;
304     }
305     return ae_update_operation_check(operation);
306 }
307 
ae_update_aad_hal(TEE_OperationHandle operation,const void * data,size_t data_len)308 static TEE_Result ae_update_aad_hal(TEE_OperationHandle operation, const void *data, size_t data_len)
309 {
310     struct memref_t aad_data = {0};
311     aad_data.buffer = (uint64_t)(uintptr_t)data;
312     aad_data.size = (uint32_t)data_len;
313     int32_t ret = tee_crypto_ae_update_aad(operation->crypto_ctxt, &aad_data);
314     return change_hal_ret_to_gp(ret);
315 }
316 
TEE_AEUpdateAAD(TEE_OperationHandle operation,const void * AADdata,size_t AADdataLen)317 void TEE_AEUpdateAAD(TEE_OperationHandle operation, const void *AADdata, size_t AADdataLen)
318 {
319     bool check = (operation == NULL || (check_operation((const TEE_OperationHandle)operation) != TEE_SUCCESS));
320     if (check) {
321         tloge("operation is invalid");
322         TEE_Panic(TEE_ERROR_BAD_PARAMETERS);
323         return;
324     }
325 
326     if (pthread_mutex_lock(&(operation->operation_lock)) != TEE_SUCCESS) {
327         tloge("crypto api pthread_mutex_lock failed\n");
328         return;
329     }
330 
331     uint32_t api_level = tee_get_ta_api_level();
332     if ((operation->algorithm == TEE_ALG_AES_GCM || operation->algorithm == TEE_ALG_SM4_GCM)
333         && api_level == API_LEVEL1_0)
334         goto unlock;
335 
336     check = (AADdata == NULL || AADdataLen == 0);
337     if (check) {
338         tloge("Invalid aad data");
339         goto unlock;
340     }
341 
342     TEE_Result ret = ae_update_aad_check(operation, api_level);
343     if (ret != TEE_SUCCESS)
344         goto unlock_with_panic;
345 
346     ret = ae_update_aad_hal(operation, AADdata, AADdataLen);
347     if (ret != TEE_SUCCESS) {
348         tloge("AEUpdateAAD failed\n");
349         goto unlock_with_panic;
350     }
351 
352     if (api_level == API_LEVEL1_1_1)
353         operation->handleState |= TEE_HANDLE_FLAG_INITIALIZED;
354 
355 unlock:
356     if (pthread_mutex_unlock(&(operation->operation_lock)) != TEE_SUCCESS)
357         tloge("crypto api pthread_mutex_unlock failed\n");
358     return;
359 
360 unlock_with_panic:
361     if (pthread_mutex_unlock(&(operation->operation_lock)) != TEE_SUCCESS)
362         tloge("crypto api pthread_mutex_unlock failed\n");
363     TEE_Panic(ret);
364     return;
365 }
366 
fill_src_dest_param(operation_src_dest * src_dest_param,void * src_data_value,size_t src_len_value,void * dest_data_value,size_t * dest_len_value)367 void fill_src_dest_param(operation_src_dest *src_dest_param, void *src_data_value, size_t src_len_value,
368     void *dest_data_value, size_t *dest_len_value)
369 {
370     if (src_dest_param == NULL || dest_len_value == NULL) {
371         tloge("the input is invalid\n");
372         return;
373     }
374     src_dest_param->src_data  = src_data_value;
375     src_dest_param->src_len   = src_len_value;
376     src_dest_param->dest_data = dest_data_value;
377     src_dest_param->dest_len  = dest_len_value;
378 }
379 
ae_update_hal(TEE_OperationHandle operation,const void * src_data,size_t src_len,void * dest_data,size_t * dest_len)380 static TEE_Result ae_update_hal(TEE_OperationHandle operation, const void *src_data, size_t src_len,
381     void *dest_data, size_t *dest_len)
382 {
383     struct memref_t data_in = {0};
384     struct memref_t data_out = {0};
385 
386     data_in.buffer = (uint64_t)(uintptr_t)src_data;
387     data_in.size = (uint32_t)src_len;
388     data_out.buffer = (uint64_t)(uintptr_t)dest_data;
389     data_out.size = (uint32_t)(*dest_len);
390 
391     int32_t ret = tee_crypto_ae_update(operation->crypto_ctxt, &data_in, &data_out);
392     if (ret != TEE_SUCCESS) {
393         tloge("do ae update failed");
394         return change_hal_ret_to_gp(ret);
395     }
396     *dest_len = (size_t)data_out.size;
397     return TEE_SUCCESS;
398 }
399 
TEE_AEUpdate(TEE_OperationHandle operation,void * srcData,size_t srcLen,void * destData,size_t * destLen)400 TEE_Result TEE_AEUpdate(TEE_OperationHandle operation, void *srcData, size_t srcLen, void *destData, size_t *destLen)
401 {
402     bool check = (operation == NULL || (srcData == NULL && srcLen > 0) || destLen == NULL ||
403         (*destLen > 0 && destData == NULL) || (check_operation((const TEE_OperationHandle)operation) != TEE_SUCCESS));
404     if (check) {
405         tloge("bad params");
406         TEE_Panic(TEE_ERROR_BAD_PARAMETERS);
407         return TEE_ERROR_BAD_PARAMETERS;
408     }
409 
410     if (*destLen < srcLen) {
411         tloge("Output buffer is too short to hold the result\n");
412         return TEE_ERROR_SHORT_BUFFER;
413     }
414     uint32_t api_level = tee_get_ta_api_level();
415     if (crypto_lock_operation(operation) != TEE_SUCCESS)
416         return TEE_ERROR_GENERIC;
417 
418     TEE_Result ret = ae_update_check(operation);
419     if (ret != TEE_SUCCESS)
420         goto end;
421 
422     crypto_hal_info *crypto_hal_data = (crypto_hal_info *)(operation->hal_info);
423     if (crypto_hal_data == NULL) {
424         tloge("Ae update call back is invalid\n");
425         ret =  TEE_ERROR_BAD_PARAMETERS;
426         goto end;
427     }
428 
429     check = ((api_level == API_LEVEL1_1_1) || ((api_level > API_LEVEL1_1_1) && (srcLen != 0)));
430     if (check)
431         operation->handleState |= TEE_HANDLE_FLAG_INITIALIZED;
432 
433     ret = ae_update_hal(operation, srcData, srcLen, destData, destLen);
434     if (ret != TEE_SUCCESS)
435         tloge("Ae update failed, ret: 0x%x\n", ret);
436 
437 end:
438     if (ret != TEE_SUCCESS) {
439         operation->handleState &= ~TEE_HANDLE_FLAG_INITIALIZED;
440         crypto_unlock_operation(operation);
441         TEE_Panic(ret);
442         return ret;
443     }
444     crypto_unlock_operation(operation);
445     return ret;
446 }
447 
check_dest_data_old_level(const size_t * dest_len,const void * dest_data,size_t src_len)448 static TEE_Result check_dest_data_old_level(const size_t *dest_len, const void *dest_data, size_t src_len)
449 {
450     bool check = ((dest_len == NULL) || (dest_data == NULL) || (*dest_len == 0));
451     if (check) {
452         tloge("Invalid dest data/length");
453         return TEE_ERROR_BAD_PARAMETERS;
454     }
455 
456     if (*dest_len < src_len) {
457         tloge("Output buffer is too short to hold the result\n");
458         return TEE_ERROR_SHORT_BUFFER;
459     }
460     return TEE_SUCCESS;
461 }
462 
check_dest_data_new_level(size_t * dest_len,const void * dest_data,size_t src_len,bool * flag)463 static TEE_Result check_dest_data_new_level(size_t *dest_len, const void *dest_data, size_t src_len, bool *flag)
464 {
465     bool check_null         = ((dest_data == NULL) && (dest_len == NULL));
466     bool check_short_buffer = (((dest_data == NULL) && (dest_len != NULL) && (*dest_len == 0)) ||
467         ((dest_data != NULL) && (dest_len != NULL) && (*dest_len < src_len)));
468     bool check_success      = ((dest_data != NULL) && (dest_len != NULL) && (*dest_len >= src_len));
469 
470     if (check_null) {
471         *flag = true;
472         return TEE_SUCCESS;
473     } else if (check_short_buffer) {
474         tloge("Output buffer is too short to hold the result\n");
475         if (*dest_len == 0)
476             *dest_len = src_len;
477         return TEE_ERROR_SHORT_BUFFER;
478     } else if (check_success) {
479         return TEE_SUCCESS;
480     } else {
481         tloge("Invalid destdata or destlen");
482         return TEE_ERROR_BAD_PARAMETERS;
483     }
484 }
485 
ae_encrypt_check_dest_data(const void * dest_data,size_t * dest_len,size_t src_len,uint32_t api_level,bool * flag)486 static TEE_Result ae_encrypt_check_dest_data(const void *dest_data, size_t *dest_len, size_t src_len,
487     uint32_t api_level, bool *flag)
488 {
489     if (api_level < API_LEVEL1_1_1)
490         return check_dest_data_old_level(dest_len, dest_data, src_len);
491     else
492         return check_dest_data_new_level(dest_len, dest_data, src_len, flag);
493 }
494 
malloc_dest_data(void ** dest_data,size_t * dest_len,size_t src_len,const TEE_OperationHandle operation)495 static TEE_Result malloc_dest_data(void **dest_data, size_t *dest_len, size_t src_len,
496     const TEE_OperationHandle operation)
497 {
498     uint32_t malloc_size;
499     if (((struct ctx_handle_t *)(operation->crypto_ctxt))->is_support_ae_update) {
500         malloc_size = src_len + CTX_OFF_SET;
501     } else {
502         struct crypto_cache_t *cache =
503             (struct crypto_cache_t *)(uintptr_t)(((struct ctx_handle_t *)(operation->crypto_ctxt))->cache_buffer);
504         malloc_size = cache->effective_len + src_len;
505     }
506 
507     bool check = (malloc_size < src_len || malloc_size > MAX_SRC_SIZE);
508     if (check) {
509         tloge("src len or update len is invalid");
510         return TEE_ERROR_BAD_PARAMETERS;
511     }
512 
513     if (malloc_size != 0) {
514         *dest_data = TEE_Malloc(malloc_size, 0);
515         if (*dest_data == NULL) {
516             tloge("malloc destData failed");
517             return TEE_ERROR_OUT_OF_MEMORY;
518         }
519     }
520     *dest_len = malloc_size;
521     return TEE_SUCCESS;
522 }
523 
free_dest_data(void ** dest_data)524 void free_dest_data(void **dest_data)
525 {
526     if (dest_data == NULL)
527         return;
528     TEE_Free(*dest_data);
529     *dest_data = NULL;
530     return;
531 }
532 
ae_encrypt_hal(TEE_OperationHandle operation,operation_src_dest * src_dest_param,void * tag,size_t * tag_len)533 static TEE_Result ae_encrypt_hal(TEE_OperationHandle operation, operation_src_dest *src_dest_param,
534     void *tag, size_t *tag_len)
535 {
536     struct memref_t data_in = {0};
537     struct memref_t data_out = {0};
538     struct memref_t tag_ref = {0};
539 
540     data_in.size = (uint32_t)(src_dest_param->src_len);
541     if (data_in.size == 0)
542         data_in.buffer = 0;
543     else
544         data_in.buffer = (uint64_t)(uintptr_t)(src_dest_param->src_data);
545 
546     data_out.buffer = (uint64_t)(uintptr_t)(src_dest_param->dest_data);
547     data_out.size = (uint32_t)(*(src_dest_param->dest_len));
548 
549     tag_ref.buffer = (uint64_t)(uintptr_t)tag;
550     tag_ref.size = (uint32_t)(*tag_len);
551 
552     int32_t ret = tee_crypto_ae_enc_final(operation->crypto_ctxt, &data_in, &data_out, &tag_ref);
553     free_operation_ctx(operation);
554     if (ret != TEE_SUCCESS) {
555         tloge("ae encrypt failed");
556         return change_hal_ret_to_gp(ret);
557     }
558 
559     *(src_dest_param->dest_len) = (size_t)data_out.size;
560     *tag_len = (size_t)tag_ref.size;
561     operation->digestLength = tag_ref.size;
562     return TEE_SUCCESS;
563 }
564 
ae_encrypt_final_param_check(TEE_OperationHandle operation,void * src_data,size_t src_len,void * tag,const size_t * tag_len)565 static TEE_Result ae_encrypt_final_param_check(TEE_OperationHandle operation, void *src_data, size_t src_len,
566     void *tag, const size_t *tag_len)
567 {
568     bool check = ((src_len > 0 && src_data == NULL) || tag_len == NULL || (*tag_len > 0 && tag == NULL) ||
569         (check_operation((const TEE_OperationHandle)operation) != TEE_SUCCESS));
570     if (check) {
571         tloge("bad params");
572         return TEE_ERROR_BAD_PARAMETERS;
573     }
574     TEE_Result ret = ae_update_check(operation);
575     if (ret != TEE_SUCCESS) {
576         tloge("ae final check failed");
577         return ret;
578     }
579 
580     operation->handleState &= ~TEE_HANDLE_FLAG_INITIALIZED;
581     return TEE_SUCCESS;
582 }
583 
TEE_AEEncryptFinal(TEE_OperationHandle operation,void * srcData,size_t srcLen,void * destData,size_t * destLen,void * tag,size_t * tagLen)584 TEE_Result TEE_AEEncryptFinal(TEE_OperationHandle operation, void *srcData, size_t srcLen, void *destData,
585     size_t *destLen, void *tag, size_t *tagLen)
586 {
587     bool check = (operation == NULL || crypto_lock_operation(operation) != TEE_SUCCESS);
588     if (check)
589         return TEE_ERROR_BAD_PARAMETERS;
590 
591     TEE_Result ret = ae_encrypt_final_param_check(operation, srcData, srcLen, tag, tagLen);
592     if (ret != TEE_SUCCESS) {
593         crypto_unlock_operation(operation);
594         TEE_Panic(ret);
595         return ret;
596     }
597 
598     bool malloc_flag = false;
599     uint32_t api_level = tee_get_ta_api_level();
600     ret = ae_encrypt_check_dest_data(destData, destLen, srcLen, api_level, &malloc_flag);
601     if (ret != TEE_SUCCESS)
602         goto ae_encrypt_free_dest;
603 
604     size_t temp_dest_len = 0;
605     void *temp_dest_data = NULL;
606     uint32_t templen     = 0;
607     if (malloc_flag) {
608         ret = malloc_dest_data(&temp_dest_data, &temp_dest_len, srcLen, operation);
609         if (ret != TEE_SUCCESS)
610             goto ae_encrypt_free_dest;
611     } else {
612         templen = *destLen;
613     }
614     operation_src_dest src_dest_param = { 0 };
615     if (malloc_flag)
616         fill_src_dest_param(&src_dest_param, srcData, srcLen, temp_dest_data, &temp_dest_len);
617     else
618         fill_src_dest_param(&src_dest_param, srcData, srcLen, destData, destLen);
619 
620     ret = ae_encrypt_hal(operation, &src_dest_param, tag, tagLen);
621     if (ret != TEE_SUCCESS) {
622         tloge("Ae encrypt final failed, ret: 0x%x\n", ret);
623         goto ae_encrypt_free_dest;
624     }
625     if (api_level < API_LEVEL1_1_1)
626         *destLen = templen;
627 ae_encrypt_free_dest:
628     if (malloc_flag)
629         free_dest_data(&temp_dest_data);
630     crypto_unlock_operation(operation);
631     if (ret != TEE_SUCCESS)
632         TEE_Panic(ret);
633     return ret;
634 }
635 
ae_decrypt_hal(TEE_OperationHandle operation,operation_src_dest * src_dest_param,const void * tag,size_t tag_len)636 static TEE_Result ae_decrypt_hal(TEE_OperationHandle operation, operation_src_dest *src_dest_param,
637     const void *tag, size_t tag_len)
638 {
639     struct memref_t data_in = {0};
640     struct memref_t data_out = {0};
641     struct memref_t tag_ref = {0};
642 
643     data_in.size = (uint32_t)src_dest_param->src_len;
644     if (data_in.size == 0)
645         data_in.buffer = 0;
646     else
647         data_in.buffer = (uint64_t)(uintptr_t)(src_dest_param->src_data);
648 
649     data_out.buffer = (uint64_t)(uintptr_t)(src_dest_param->dest_data);
650     data_out.size = (uint32_t)(*(src_dest_param->dest_len));
651 
652     tag_ref.buffer = (uint64_t)(uintptr_t)tag;
653     tag_ref.size = (uint32_t)tag_len;
654 
655     int32_t ret = tee_crypto_ae_dec_final(operation->crypto_ctxt, &data_in, &tag_ref, &data_out);
656     free_operation_ctx(operation);
657     if (ret != TEE_SUCCESS) {
658         tloge("ae decrypt failed");
659         return change_hal_ret_to_gp(ret);
660     }
661 
662     *(src_dest_param->dest_len) = (size_t)data_out.size;
663     return TEE_SUCCESS;
664 }
665 
ae_decrypt_final_param_check(TEE_OperationHandle operation,void * src_data,size_t src_len,void * tag,size_t tag_len)666 static TEE_Result ae_decrypt_final_param_check(TEE_OperationHandle operation, void *src_data, size_t src_len,
667     void *tag, size_t tag_len)
668 {
669     bool check = ((src_len > 0 && src_data == NULL) || (tag_len > 0 && tag == NULL));
670     if (check) {
671         tloge("bad params");
672         return TEE_ERROR_BAD_PARAMETERS;
673     }
674     TEE_Result ret = ae_update_check(operation);
675     if (ret != TEE_SUCCESS) {
676         tloge("ae decrypt final check failed");
677         return ret;
678     }
679 
680     operation->handleState &= ~TEE_HANDLE_FLAG_INITIALIZED;
681     return TEE_SUCCESS;
682 }
683 
TEE_AEDecryptFinal(TEE_OperationHandle operation,void * srcData,size_t srcLen,void * destData,size_t * destLen,void * tag,size_t tagLen)684 TEE_Result TEE_AEDecryptFinal(TEE_OperationHandle operation, void *srcData, size_t srcLen, void *destData,
685     size_t *destLen, void *tag, size_t tagLen)
686 {
687     bool check = (operation == NULL || destLen == NULL || (*destLen > 0 && destData == NULL) ||
688         (*destLen == 0 && destData != NULL) || (check_operation((const TEE_OperationHandle)operation) != TEE_SUCCESS));
689     if (check)
690         return TEE_ERROR_BAD_PARAMETERS;
691 
692     if (crypto_lock_operation(operation) != TEE_SUCCESS)
693         return TEE_ERROR_GENERIC;
694 
695     bool malloc_flag = false;
696     TEE_Result ret = ae_decrypt_final_param_check(operation, srcData, srcLen, tag, tagLen);
697     if (ret != TEE_SUCCESS)
698         goto free_dest;
699 
700     operation_src_dest src_dest_param = { 0 };
701     uint32_t api_level = tee_get_ta_api_level();
702     size_t temp_dest_len = 0;
703     void *temp_dest_data = NULL;
704     uint32_t templen = 0;
705 
706     if (*destLen == 0 && api_level > API_LEVEL1_0) {
707         ret = malloc_dest_data(&temp_dest_data, &temp_dest_len, srcLen, operation);
708         if (ret != TEE_SUCCESS)
709             goto free_dest;
710         malloc_flag = true;
711     } else {
712         templen = *destLen;
713         if (*destLen < srcLen) {
714             tloge("Output buffer is too short to hold the result\n");
715             crypto_unlock_operation(operation);
716             return TEE_ERROR_SHORT_BUFFER;
717         }
718     }
719 
720     if (malloc_flag)
721         fill_src_dest_param(&src_dest_param, srcData, srcLen, temp_dest_data, &temp_dest_len);
722     else
723         fill_src_dest_param(&src_dest_param, srcData, srcLen, destData, destLen);
724 
725     ret = ae_decrypt_hal(operation, &src_dest_param, tag, tagLen);
726     if (ret != TEE_SUCCESS) {
727         tloge("ae decrypt final failed, ret: 0x%x\n", ret);
728         goto free_dest;
729     }
730 
731     if (api_level < API_LEVEL1_1_1)
732         *destLen = templen;
733 free_dest:
734     if (malloc_flag)
735         free_dest_data(&temp_dest_data);
736     crypto_unlock_operation(operation);
737     if (ret != TEE_SUCCESS)
738         TEE_Panic(ret);
739     return ret;
740 }
741