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
13 #include "crypto_hal_ae.h"
14 #include <securec.h>
15 #include <tee_log.h>
16 #include <tee_crypto_hal.h>
17 #include "crypto_manager.h"
18 #include "soft_ae.h"
19 #include "crypto_hal.h"
20
alloc_crypto_cache(uint32_t alg_type,const struct ae_init_data * ae_init_param)21 static struct crypto_cache_t *alloc_crypto_cache(uint32_t alg_type, const struct ae_init_data *ae_init_param)
22 {
23 uint32_t total_buff_len = 0;
24
25 if (alg_type == CRYPTO_TYPE_AES_CCM)
26 total_buff_len = ae_init_param->payload_len;
27 else if (alg_type == CRYPTO_TYPE_AES_GCM || alg_type == CRYPTO_TYPE_SM4_GCM)
28 total_buff_len = ((ae_init_param->payload_len > 0) && (ae_init_param->payload_len < MAX_CRYPTO_DATA_LEN)) ?
29 ae_init_param->payload_len : MAX_CRYPTO_DATA_LEN;
30 else
31 return NULL;
32
33 if (total_buff_len > MAX_CRYPTO_DATA_LEN) {
34 tloge("Payload len is too large, total_buff_len=0x%x\n", total_buff_len);
35 return NULL;
36 }
37 struct crypto_cache_t *crypto_cache = TEE_Malloc(sizeof(*crypto_cache), 0);
38 if (crypto_cache == NULL) {
39 tloge("Malloc cache buffer failed\n");
40 return NULL;
41 }
42 crypto_cache->total_len = total_buff_len;
43 crypto_cache->effective_len = 0;
44 crypto_cache->buffer = TEE_Malloc(total_buff_len, 0);
45 if (crypto_cache->buffer == NULL) {
46 tloge("Malloc cache buffer failed\n");
47 TEE_Free(crypto_cache);
48 return NULL;
49 }
50
51 return crypto_cache;
52 }
53
tee_crypto_ae_init(uint32_t alg_type,uint32_t direction,const struct symmerit_key_t * key,const struct ae_init_data * ae_init_param,uint32_t engine)54 struct ctx_handle_t *tee_crypto_ae_init(uint32_t alg_type, uint32_t direction, const struct symmerit_key_t *key,
55 const struct ae_init_data *ae_init_param, uint32_t engine)
56 {
57 bool check = (key == NULL || ae_init_param == NULL);
58 if (check) {
59 tloge("Invalid params\n");
60 return NULL;
61 }
62
63 check = ((alg_type == CRYPTO_TYPE_AES_CCM) &&
64 ((ae_init_param->payload_len == 0) || (ae_init_param->payload_len > MAX_CRYPTO_DATA_LEN)));
65 if (check) {
66 tloge("Invalid payload len, payload_len=0x%x\n", ae_init_param->payload_len);
67 return NULL;
68 }
69
70 struct ctx_handle_t *ctx = alloc_ctx_handle(alg_type, engine);
71 if (ctx == NULL) {
72 tloge("Malloc ctx handle failed\n");
73 return NULL;
74 }
75 ctx->direction = direction;
76 if (alg_type == CRYPTO_TYPE_AES_CCM)
77 ctx->aad_size = ae_init_param->aad_len;
78
79 int32_t ret;
80
81 if (engine == SOFT_CRYPTO)
82 ret = soft_crypto_ae_init(ctx, key, ae_init_param);
83 else
84 ret = crypto_driver_ae_init(ctx, key, ae_init_param);
85 if (ret != CRYPTO_SUCCESS) {
86 tloge("Ae init failed, ret=%d\n", ret);
87 tee_crypto_ctx_free(ctx);
88 return NULL;
89 }
90
91 ctx->is_support_ae_update = true;
92 struct crypto_cache_t *ctx_cache_buffer = alloc_crypto_cache(alg_type, ae_init_param);
93 if (ctx_cache_buffer == NULL) {
94 tloge("Alloc crypto cache failed\n");
95 tee_crypto_ctx_free(ctx);
96 return NULL;
97 }
98 ctx->cache_buffer = (uint64_t)(uintptr_t)ctx_cache_buffer;
99
100 return ctx;
101 }
102
tee_crypto_ae_update_aad(struct ctx_handle_t * ctx,const struct memref_t * aad_data)103 int32_t tee_crypto_ae_update_aad(struct ctx_handle_t *ctx, const struct memref_t *aad_data)
104 {
105 bool check = ((ctx == NULL) || (aad_data == NULL));
106 if (check) {
107 tloge("Invalid params\n");
108 return CRYPTO_BAD_PARAMETERS;
109 }
110 if ((ctx->alg_type == CRYPTO_TYPE_AES_CCM) && (ctx->aad_size < aad_data->size)) {
111 tloge("The AADLen size is bigger than AEInit\n");
112 return CRYPTO_BAD_PARAMETERS;
113 }
114
115 if (ctx->engine == SOFT_CRYPTO)
116 return soft_crypto_ae_update_aad(ctx, aad_data);
117 return crypto_driver_ae_update_aad(ctx, aad_data);
118 }
119
check_ae_in_size(struct ctx_handle_t * ctx,const struct memref_t * data_in)120 static int32_t check_ae_in_size(struct ctx_handle_t *ctx, const struct memref_t *data_in)
121 {
122 struct crypto_cache_t *cache = (struct crypto_cache_t *)(uintptr_t)(ctx->cache_buffer);
123 bool check = ((cache == NULL) || (data_in->size > cache->total_len));
124 if (check) {
125 tloge("Invalid params\n");
126 return CRYPTO_BAD_PARAMETERS;
127 }
128
129 check = ((cache->effective_len > UINT32_MAX - data_in->size) ||
130 (cache->effective_len + data_in->size > cache->total_len));
131 if (check) {
132 tloge("The src len is invalid, effective_len=0x%x, src_len=0x%x\n",
133 cache->effective_len, data_in->size);
134 return CRYPTO_BAD_PARAMETERS;
135 }
136 return TEE_SUCCESS;
137 }
138
do_crypto_cache(struct ctx_handle_t * ctx,const struct memref_t * data_in,struct memref_t * data_out)139 static int32_t do_crypto_cache(struct ctx_handle_t *ctx, const struct memref_t *data_in, struct memref_t *data_out)
140 {
141 int32_t ret = check_ae_in_size(ctx, data_in);
142 if (ret != CRYPTO_SUCCESS)
143 return ret;
144
145 if (data_in->size == 0)
146 return TEE_SUCCESS;
147
148 struct crypto_cache_t *cache = (struct crypto_cache_t *)(uintptr_t)(ctx->cache_buffer);
149
150 uint32_t avaliable_cache_len = cache->total_len - cache->effective_len;
151 errno_t rc = memcpy_s((void *)((uintptr_t)cache->buffer + cache->effective_len), avaliable_cache_len,
152 (uint8_t *)(uintptr_t)(data_in->buffer), data_in->size);
153 if (rc != EOK) {
154 tloge("Copy ae data to cache failed");
155 return TEE_ERROR_SECURITY;
156 }
157
158 cache->effective_len += data_in->size;
159 data_out->size = 0;
160 return CRYPTO_SUCCESS;
161 }
162
tee_crypto_ae_update(struct ctx_handle_t * ctx,const struct memref_t * data_in,struct memref_t * data_out)163 int32_t tee_crypto_ae_update(struct ctx_handle_t *ctx, const struct memref_t *data_in, struct memref_t *data_out)
164 {
165 bool check = ((ctx == NULL) || (ctx->cache_buffer == 0) || (data_in == NULL) || (data_out == NULL));
166 if (check) {
167 tloge("Invalid params\n");
168 return CRYPTO_BAD_PARAMETERS;
169 }
170
171 if (data_in->size == 0)
172 return CRYPTO_SUCCESS;
173
174 int32_t ret;
175 if (ctx->engine == SOFT_CRYPTO)
176 ret = soft_crypto_ae_update(ctx, data_in, data_out);
177 else
178 ret = crypto_driver_ae_update(ctx, data_in, data_out);
179
180 if (ret == CRYPTO_NOT_SUPPORTED) {
181 ctx->is_support_ae_update = false;
182 tlogd("this algorithm not support update!");
183 ret = do_crypto_cache(ctx, data_in, data_out);
184 }
185 if (ret != CRYPTO_SUCCESS) {
186 tloge("do ae update failed, ret = %d", ret);
187 return ret;
188 }
189 return ret;
190 }
191
do_ae_final_not_support_update(struct ctx_handle_t * ctx,const struct memref_t * data_in,struct memref_t * data_out,const struct memref_t * tag_in,struct memref_t * tag_out)192 static int32_t do_ae_final_not_support_update(struct ctx_handle_t *ctx,
193 const struct memref_t *data_in, struct memref_t *data_out,
194 const struct memref_t *tag_in, struct memref_t *tag_out)
195 {
196 uint32_t dest_size = data_out->size;
197 int32_t ret = do_crypto_cache(ctx, data_in, data_out);
198 if (ret != CRYPTO_SUCCESS) {
199 tloge("Do crypto cache failed, ret=%d\n", ret);
200 return ret;
201 }
202 data_out->size = dest_size;
203 struct crypto_cache_t *cache = (struct crypto_cache_t *)(uintptr_t)(ctx->cache_buffer);
204 if (cache == NULL) {
205 tloge("Invalid params\n");
206 return CRYPTO_BAD_PARAMETERS;
207 }
208 struct memref_t new_data_in = {0};
209 new_data_in.buffer = (uint64_t)(uintptr_t)(cache->buffer);
210 new_data_in.size = cache->effective_len;
211
212 if (ctx->engine == SOFT_CRYPTO) {
213 if (ctx->direction == ENC_MODE)
214 return soft_crypto_ae_enc_final(ctx, (const struct memref_t *)&new_data_in, data_out, tag_out);
215 else
216 return soft_crypto_ae_dec_final(ctx, (const struct memref_t *)&new_data_in, tag_in, data_out);
217 } else {
218 if (ctx->direction == ENC_MODE)
219 return crypto_driver_ae_enc_final(ctx, (const struct memref_t *)&new_data_in, data_out, tag_out);
220 else
221 return crypto_driver_ae_dec_final(ctx, (const struct memref_t *)&new_data_in, tag_in, data_out);
222 }
223 }
224
tee_crypto_ae_enc_final(struct ctx_handle_t * ctx,const struct memref_t * data_in,struct memref_t * data_out,struct memref_t * tag_out)225 int32_t tee_crypto_ae_enc_final(struct ctx_handle_t *ctx, const struct memref_t *data_in,
226 struct memref_t *data_out, struct memref_t *tag_out)
227 {
228 bool check = ((ctx == NULL) || (data_in == NULL) || (data_out == NULL) || (tag_out == NULL));
229 if (check) {
230 tloge("Invalid params\n");
231 return CRYPTO_BAD_PARAMETERS;
232 }
233
234 if (ctx->is_support_ae_update) {
235 if (ctx->engine == SOFT_CRYPTO)
236 return soft_crypto_ae_enc_final(ctx, data_in, data_out, tag_out);
237 else
238 return crypto_driver_ae_enc_final(ctx, data_in, data_out, tag_out);
239 } else {
240 return do_ae_final_not_support_update(ctx, data_in, data_out, NULL, tag_out);
241 }
242 }
243
tee_crypto_ae_dec_final(struct ctx_handle_t * ctx,const struct memref_t * data_in,const struct memref_t * tag_in,struct memref_t * data_out)244 int32_t tee_crypto_ae_dec_final(struct ctx_handle_t *ctx, const struct memref_t *data_in,
245 const struct memref_t *tag_in, struct memref_t *data_out)
246 {
247 bool check = ((ctx == NULL) || (data_in == NULL) || (tag_in == NULL) || (data_out == NULL));
248 if (check) {
249 tloge("Invalid params\n");
250 return CRYPTO_BAD_PARAMETERS;
251 }
252
253 if (ctx->is_support_ae_update) {
254 if (ctx->engine == SOFT_CRYPTO)
255 return soft_crypto_ae_dec_final(ctx, data_in, tag_in, data_out);
256 else
257 return crypto_driver_ae_dec_final(ctx, data_in, tag_in, data_out);
258 } else {
259 return do_ae_final_not_support_update(ctx, data_in, data_out, tag_in, NULL);
260 }
261 }
262