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