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