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