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_defines.h"
13 #include "sfs.h"
14 #include "tee_mem_mgmt_api.h"
15 #include "tee_log.h"
16 #include "ta_framework.h"
17 #include "tee_ext_api.h"
18 #include "sfs_internal.h"
19 #include "securec.h"
20 #include "string.h"
21 #include "tee_crypto_hal.h"
22 #include "ssa_fs.h"
23
24
aes_xts_crypto_check(const struct sfd_t * sfd,const struct memref_t * tweak,const struct memref_t * data_in,struct memref_t * data_out)25 static TEE_Result aes_xts_crypto_check(const struct sfd_t *sfd, const struct memref_t *tweak,
26 const struct memref_t *data_in, struct memref_t *data_out)
27 {
28 if (sfd == NULL || tweak == NULL || data_in == NULL || data_out == NULL)
29 return TEE_ERROR_BAD_PARAMETERS;
30
31 if (sfd->meta_data == NULL)
32 return TEE_ERROR_BAD_PARAMETERS;
33
34 if ((void *)(uintptr_t)tweak->buffer == NULL || (void *)(uintptr_t)data_in->buffer == NULL
35 || (void *)(uintptr_t)data_out->buffer == NULL)
36 return TEE_ERROR_BAD_PARAMETERS;
37
38 if (data_in->size % AES_XTS_SINGLE_UNIT != 0) {
39 tloge("data size not supported, size=%u\n", data_in->size);
40 return TEE_ERROR_BAD_PARAMETERS;
41 }
42
43 return TEE_SUCCESS;
44 }
45
aes_xts_crypto_init(TEE_ObjectHandleVar * key_obj1,TEE_ObjectHandleVar * key_obj2,const struct sfd_t * sfd)46 static TEE_Result aes_xts_crypto_init(TEE_ObjectHandleVar *key_obj1, TEE_ObjectHandleVar *key_obj2,
47 const struct sfd_t *sfd)
48 {
49 /* set key */
50 (void)memset_s((void *)key_obj1, sizeof(*key_obj1), 0, sizeof(*key_obj1));
51 (void)memset_s((void *)key_obj2, sizeof(*key_obj2), 0, sizeof(*key_obj2));
52
53 key_obj1->Attribute = (TEE_Attribute *)TEE_Malloc(sizeof(TEE_Attribute), 0);
54 key_obj2->Attribute = (TEE_Attribute *)TEE_Malloc(sizeof(TEE_Attribute), 0);
55 if (key_obj1->Attribute == NULL || key_obj2->Attribute == NULL) {
56 tloge("cipher alloc key attr failed\n");
57 return TEE_ERROR_OUT_OF_MEMORY;
58 }
59 key_obj1->Attribute->content.ref.length = sizeof(sfd->meta_data->xts_key1);
60 key_obj1->Attribute->content.ref.buffer = sfd->meta_data->xts_key1;
61 key_obj2->Attribute->content.ref.length = sizeof(sfd->meta_data->xts_key2);
62 key_obj2->Attribute->content.ref.buffer = sfd->meta_data->xts_key2;
63
64 return TEE_SUCCESS;
65 }
66
aes_xts_crypto_clean(TEE_OperationHandle handle,TEE_ObjectHandleVar * key_obj1,TEE_ObjectHandleVar * key_obj2)67 static void aes_xts_crypto_clean(TEE_OperationHandle handle,
68 TEE_ObjectHandleVar *key_obj1, TEE_ObjectHandleVar *key_obj2)
69 {
70 if (handle != NULL) {
71 TEE_FreeOperation(handle);
72 handle = NULL;
73 }
74
75 if (key_obj1->Attribute != NULL) {
76 TEE_Free(key_obj1->Attribute);
77 key_obj1->Attribute = NULL;
78 }
79 if (key_obj2->Attribute != NULL) {
80 TEE_Free(key_obj2->Attribute);
81 key_obj2->Attribute = NULL;
82 }
83 }
84
aes_xts_crypto(uint32_t mode,const struct sfd_t * sfd,const struct memref_t * tweak,const struct memref_t * data_in,struct memref_t * data_out)85 TEE_Result aes_xts_crypto(uint32_t mode, const struct sfd_t *sfd, const struct memref_t *tweak,
86 const struct memref_t *data_in, struct memref_t *data_out)
87 {
88 TEE_Result ret;
89 TEE_OperationHandle handle = NULL;
90 TEE_ObjectHandleVar key_obj1, key_obj2;
91 uint32_t i;
92 uint32_t data_offset;
93
94 ret = aes_xts_crypto_check(sfd, tweak, data_in, data_out);
95 if (ret != TEE_SUCCESS) {
96 tloge("aes xts crypto check failed, ret 0x%x\n", ret);
97 return ret;
98 }
99
100 ret = aes_xts_crypto_init(&key_obj1, &key_obj2, sfd);
101 if (ret != TEE_SUCCESS) {
102 tloge("aes xts crypto init failed, ret 0x%x\n", ret);
103 goto clean;
104 }
105
106 uint32_t cipher_times = data_in->size / AES_XTS_SINGLE_UNIT;
107 for (i = 0; i < cipher_times; i++) {
108 ret = TEE_AllocateOperation(&handle, TEE_ALG_AES_XTS, mode, TEE_MAX_KEY_SIZE_IN_BITS);
109 if (ret != TEE_SUCCESS) {
110 tloge("alloc crypto operation failed, ret=0x%x\n", ret);
111 goto clean;
112 }
113
114 ret = TEE_SetCryptoFlag(handle, SOFT_CRYPTO);
115 if (ret != TEE_SUCCESS)
116 goto clean;
117
118 ret = TEE_SetOperationKey2(handle, &key_obj1, &key_obj2);
119 if (ret != TEE_SUCCESS) {
120 tloge("cipher setkey2 failed, ret=0x%x\n", ret);
121 goto clean;
122 }
123
124 /* cipher init */
125 TEE_CipherInit(handle, (void *)(uintptr_t)tweak->buffer, tweak->size);
126
127 data_out->size = AES_XTS_SINGLE_UNIT;
128 data_offset = i * AES_XTS_SINGLE_UNIT;
129 ret = TEE_CipherDoFinal(handle, (void *)(uintptr_t)(data_in->buffer + data_offset), AES_XTS_SINGLE_UNIT,
130 (void *)(uintptr_t)(data_out->buffer + data_offset), (size_t *)&data_out->size);
131 if (ret != TEE_SUCCESS) {
132 tloge("cipher dofinal failed, ret=0x%x\n", ret);
133 goto clean;
134 }
135
136 TEE_FreeOperation(handle);
137 handle = NULL;
138 }
139
140 clean:
141 aes_xts_crypto_clean(handle, &key_obj1, &key_obj2);
142 return ret;
143 }
144
calc_hmac256(struct key_info_t * key_info,const uint8_t * src,int32_t length,uint8_t * dest,uint32_t * dest_len)145 TEE_Result calc_hmac256(struct key_info_t *key_info, const uint8_t *src, int32_t length,
146 uint8_t *dest, uint32_t *dest_len)
147 {
148 TEE_OperationHandle mac_ops = NULL;
149 TEE_Result ret;
150 size_t out_len;
151
152 if (key_info == NULL || src == NULL || dest == NULL || dest_len == NULL || length < 0)
153 return TEE_ERROR_BAD_PARAMETERS;
154
155 ret = TEE_AllocateOperation(&mac_ops, TEE_ALG_HMAC_SHA256, TEE_MODE_MAC, key_info->key_len);
156 if (ret != TEE_SUCCESS)
157 return ret;
158
159 ret = TEE_SetCryptoFlag(mac_ops, SOFT_CRYPTO);
160 if (ret != TEE_SUCCESS)
161 goto clean;
162
163 TEE_ObjectHandleVar key_obj;
164 (void)memset_s((void *)&key_obj, sizeof(key_obj), 0, sizeof(key_obj));
165 key_obj.Attribute = TEE_Malloc(sizeof(TEE_Attribute), 0);
166 if (key_obj.Attribute == NULL) {
167 tloge("alloc key attr failed\n");
168 ret = TEE_ERROR_OUT_OF_MEMORY;
169 goto clean;
170 }
171
172 key_obj.Attribute->content.ref.length = key_info->key_len;
173 key_obj.Attribute->content.ref.buffer = key_info->key;
174 ret = TEE_SetOperationKey(mac_ops, &key_obj);
175 if (ret != TEE_SUCCESS) {
176 tloge("set operation key fail, ret:0x%x", ret);
177 goto clean;
178 }
179
180 TEE_MACInit(mac_ops, NULL, 0);
181 out_len = *dest_len;
182 ret = TEE_MACComputeFinal(mac_ops, src, (size_t)length, dest, &out_len);
183 if (ret != 0) {
184 tloge("TEE MAC error! %x\n", ret);
185 goto clean;
186 }
187 *dest_len = out_len;
188 ret = TEE_SUCCESS;
189
190 clean:
191 TEE_FreeOperation(mac_ops);
192 TEE_Free(key_obj.Attribute);
193 return ret;
194 }
195
196 #define BLOCK_SIZE_MAX 0x7D000 /* 500K */
197
cmd_hash(const uint8_t * src_data,uint32_t src_len,uint8_t * dest_data,size_t dest_len)198 TEE_Result cmd_hash(const uint8_t *src_data, uint32_t src_len, uint8_t *dest_data, size_t dest_len)
199 {
200 TEE_OperationHandle crypto_ops = NULL;
201 uint32_t i, block_count;
202 TEE_Result ret;
203
204 if ((src_data == NULL) || (dest_data == NULL)) {
205 tloge("src data or dest data is null");
206 return TEE_ERROR_BAD_PARAMETERS;
207 }
208
209 ret = TEE_AllocateOperation(&crypto_ops, TEE_ALG_SHA256, TEE_MODE_DIGEST, 0);
210 if (ret != TEE_SUCCESS) {
211 tloge("TEE_AllocateOperation, fail %x\n", ret);
212 return ret;
213 }
214
215 block_count = src_len / BLOCK_SIZE_MAX;
216 for (i = 0; i < block_count; i++) {
217 ret = TEE_DigestUpdate(crypto_ops, (void *)(src_data + (uint32_t)(i * BLOCK_SIZE_MAX)), BLOCK_SIZE_MAX);
218 if (ret != TEE_SUCCESS) {
219 tloge("TEE_DigestUpdate, fail ret=%x\n", ret);
220 TEE_FreeOperation(crypto_ops);
221 return ret;
222 }
223 }
224
225 ret = TEE_DigestDoFinal(crypto_ops, (void *)(src_data + (uint32_t)(block_count * BLOCK_SIZE_MAX)),
226 (src_len % BLOCK_SIZE_MAX), dest_data, &dest_len);
227 if (ret != TEE_SUCCESS) {
228 tloge("TEE_DigestDoFinal, fail ret=%x, srclen=%x, dst_len=%x\n", ret, (src_len % BLOCK_SIZE_MAX), dest_len);
229 TEE_FreeOperation(crypto_ops);
230 return ret;
231 }
232
233 TEE_FreeOperation(crypto_ops);
234
235 return TEE_SUCCESS;
236 }
237
238 #define AES_IV_LEN 16
aes_cbc_crypto(uint32_t mode,uint8_t * key_value,uint32_t key_size,const uint8_t * iv,uint32_t iv_size,const uint8_t * data_in,uint32_t data_in_size,uint8_t * data_out)239 TEE_Result aes_cbc_crypto(uint32_t mode, uint8_t *key_value, uint32_t key_size, const uint8_t *iv,
240 uint32_t iv_size, const uint8_t *data_in, uint32_t data_in_size, uint8_t *data_out)
241 {
242 (void)iv_size;
243 if (key_value == NULL || iv == NULL || data_in == NULL || data_out == NULL)
244 return -1;
245
246 TEE_ObjectHandleVar object = { 0 };
247 TEE_OperationHandle operation = NULL;
248
249 object.Attribute = TEE_Malloc(sizeof(TEE_Attribute), 0);
250 if (object.Attribute == NULL) {
251 tloge("allocate key failed!");
252 return TEE_ERROR_OUT_OF_MEMORY;
253 }
254
255 object.Attribute->content.ref.length = key_size;
256 object.Attribute->content.ref.buffer = key_value;
257
258 TEE_Result ret = TEE_AllocateOperation(&operation, TEE_ALG_AES_CBC_NOPAD, mode, key_size);
259 if (ret != TEE_SUCCESS) {
260 tloge("allocate operation failed, ret = 0x%x", ret);
261 TEE_Free(object.Attribute);
262 return ret;
263 }
264
265 ret = TEE_SetOperationKey(operation, &object);
266 if (ret != TEE_SUCCESS) {
267 tloge("set operation key failed, ret = 0x%x", ret);
268 TEE_Free(object.Attribute);
269 TEE_FreeOperation(operation);
270 return ret;
271 }
272
273 TEE_CipherInit(operation, iv, AES_IV_LEN);
274
275 size_t data_out_size = data_in_size;
276 ret = TEE_CipherDoFinal(operation, data_in, data_in_size, data_out, &data_out_size);
277 TEE_Free(object.Attribute);
278 object.Attribute = NULL;
279 TEE_FreeOperation(operation);
280 if (ret != TEE_SUCCESS)
281 tloge("aes do final failed, ret = 0x%x", ret);
282 return ret;
283 }
284