• 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 <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