• 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 <tee_property_inner.h>
16 #include <tee_object_api.h>
17 #include <crypto_inner_defines.h>
18 #include <crypto_hal_hash.h>
19 #include <crypto_driver_adaptor.h>
20 #include "tee_operation.h"
21 #include "tee_crypto_common_hash.h"
22 
23 /* For GP compatible, we add some panic when there is some error, For common use, we need to disable this panic */
24 #ifndef GP_COMPATIBLE
25 #define TEE_Panic(x) \
26     do {             \
27     } while (0)
28 #endif
29 
digest_update_param_check(TEE_OperationHandle operation,const void * chunk,size_t chunk_size)30 static TEE_Result digest_update_param_check(TEE_OperationHandle operation, const void *chunk, size_t chunk_size)
31 {
32     bool check = (operation == NULL || chunk == NULL || chunk_size == 0 ||
33         (check_operation((const TEE_OperationHandle)operation) != TEE_SUCCESS));
34     if (check) {
35         tloge("operation handle or other param is Invalid!");
36         return TEE_ERROR_BAD_PARAMETERS;
37     }
38 
39     if (tee_get_ta_api_level() > API_LEVEL1_0 && chunk_size > MAX_SRC_SIZE) {
40         tloge("The chunk size is invalid!");
41         return TEE_ERROR_BAD_PARAMETERS;
42     }
43     return TEE_SUCCESS;
44 }
45 
tee_digest_update100(TEE_OperationHandle operation,const void * chunk,size_t chunk_size)46 TEE_Result tee_digest_update100(TEE_OperationHandle operation, const void *chunk, size_t chunk_size)
47 {
48     TEE_Result ret = digest_update_param_check(operation, chunk, chunk_size);
49     if (ret != TEE_SUCCESS) {
50         TEE_Panic(ret);
51         return ret;
52     }
53 
54     if (crypto_lock_operation(operation) != TEE_SUCCESS)
55         return TEE_ERROR_GENERIC;
56 
57     ret = digest_operation_state_check((const TEE_OperationHandle)operation);
58     if (ret != TEE_SUCCESS) {
59         crypto_unlock_operation(operation);
60         TEE_Panic(ret);
61         return ret;
62     }
63 
64     ret = proc_hal_digest_update(operation, chunk, chunk_size);
65     crypto_unlock_operation(operation);
66     if (ret != TEE_SUCCESS) {
67         tloge("Do digest update failed, ret=0x%x\n", ret);
68         TEE_Panic(ret);
69         return ret;
70     }
71 
72     return TEE_SUCCESS;
73 }
74 
tee_digest_update111(TEE_OperationHandle operation,const void * chunk,size_t chunk_size)75 void tee_digest_update111(TEE_OperationHandle operation, const void *chunk, size_t chunk_size)
76 {
77     if (tee_digest_update100(operation, chunk, chunk_size) != TEE_SUCCESS)
78         tloge("Tee Digest Update failed!");
79 }
80 
crypto_output_buff_len_check(uint32_t algorithm,size_t output_len)81 static TEE_Result crypto_output_buff_len_check(uint32_t algorithm, size_t output_len)
82 {
83     for (uint32_t i = 0; i < ELEM_NUM(g_output_lower_limit); i++) {
84         if (g_output_lower_limit[i].algorithm == algorithm) {
85             if (output_len < g_output_lower_limit[i].output_lower_limit)
86                 return TEE_ERROR_SHORT_BUFFER;
87             else
88                 return TEE_SUCCESS;
89         }
90     }
91 
92     return TEE_ERROR_NOT_SUPPORTED;
93 }
94 
proc_hal_digest_dofinal(TEE_OperationHandle operation,const void * chunk,size_t chunk_size,void * hash,size_t * hash_len)95 static TEE_Result proc_hal_digest_dofinal(TEE_OperationHandle operation, const void *chunk, size_t chunk_size,
96         void *hash, size_t *hash_len)
97 {
98     struct memref_t data_in = {0};
99     struct memref_t data_out = {0};
100     data_in.buffer = (uint64_t)(uintptr_t)chunk;
101     data_in.size = (uint32_t)chunk_size;
102     data_out.buffer = (uint64_t)(uintptr_t)hash;
103     data_out.size = (uint32_t)(*hash_len);
104 
105     TEE_Result result = proc_hal_digest_init(operation);
106     if (result != TEE_SUCCESS)
107         return result;
108 
109     int32_t ret = tee_crypto_hash_dofinal(operation->crypto_ctxt, &data_in, &data_out);
110     free_operation_ctx(operation);
111 
112     crypto_hal_info *crypto_hal_data = operation->hal_info;
113     crypto_hal_data->digestalloc_flag = DIGEST_NO_ALLOC_CTX;
114     if (ret != TEE_SUCCESS)
115         return change_hal_ret_to_gp(ret);
116 
117     *hash_len = (size_t)data_out.size;
118 
119     return TEE_SUCCESS;
120 }
121 
TEE_DigestDoFinal(TEE_OperationHandle operation,const void * chunk,size_t chunkLen,void * hash,size_t * hashLen)122 TEE_Result TEE_DigestDoFinal(TEE_OperationHandle operation, const void *chunk, size_t chunkLen, void *hash,
123     size_t *hashLen)
124 {
125     bool check = (operation == NULL || hash == NULL || hashLen == NULL || *hashLen == 0 ||
126         (check_operation((const TEE_OperationHandle)operation) != TEE_SUCCESS));
127     if (check) {
128         tloge("bad params");
129         TEE_Panic(TEE_ERROR_BAD_PARAMETERS);
130         return TEE_ERROR_BAD_PARAMETERS;
131     }
132 
133     if (crypto_lock_operation(operation) != TEE_SUCCESS)
134         return TEE_ERROR_GENERIC;
135 
136     TEE_Result ret = digest_operation_state_check((const TEE_OperationHandle)operation);
137     if (ret != TEE_SUCCESS) {
138         crypto_unlock_operation(operation);
139         TEE_Panic(ret);
140         return ret;
141     }
142 
143     if (crypto_output_buff_len_check(operation->algorithm, *hashLen) != TEE_SUCCESS) {
144         tloge("Output buffer is too short\n");
145         crypto_unlock_operation(operation);
146         return TEE_ERROR_SHORT_BUFFER;
147     }
148 
149     ret = proc_hal_digest_dofinal(operation, chunk, chunkLen, hash, hashLen);
150     operation->digestLength = *hashLen;
151     crypto_unlock_operation(operation);
152     if (ret != TEE_SUCCESS) {
153         tloge("tee proc digest failed, ret=0x%x\n", ret);
154         TEE_Panic(ret);
155         return ret;
156     }
157 
158     return TEE_SUCCESS;
159 }
160 
161