• 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 "soft_ae.h"
14 #include <securec.h>
15 #include <tee_log.h>
16 #include "soft_common_api.h"
17 #include "ae_common.h"
18 #include "soft_err.h"
19 
check_param_is_invalid(uint32_t alg_type,const struct symmerit_key_t * key,const struct ae_init_data * ae_init_param)20 static bool check_param_is_invalid(uint32_t alg_type, const struct symmerit_key_t *key,
21     const struct ae_init_data *ae_init_param)
22 {
23     bool check = (key == NULL || key->key_buffer == 0 || key->key_size == 0 ||
24         (ae_init_param == NULL) || (ae_init_param->nonce == 0));
25     if (check) {
26         tloge("The input has null point");
27         return true;
28     }
29 
30     check = ((alg_type != CRYPTO_TYPE_AES_CCM) && (alg_type != CRYPTO_TYPE_AES_GCM) &&
31              (alg_type != CRYPTO_TYPE_SM4_GCM));
32     if (check) {
33         tloge("Invalid AE algorithm, algorithm=0x%x", alg_type);
34         return true;
35     }
36 
37     return false;
38 }
39 
set_expected_tag(struct ctx_handle_t * ctx,void * tag,uint32_t tag_len)40 static int32_t set_expected_tag(struct ctx_handle_t *ctx, void *tag, uint32_t tag_len)
41 {
42     if (tag_len != ctx->tag_len) {
43         tloge("The input tag length is not equal actual tag length, tag_len = 0x%x, crypto_hal_data->tag_len = 0x%x\n",
44             tag_len, ctx->tag_len);
45         return CRYPTO_BAD_PARAMETERS;
46     }
47     uint32_t tag_flag = ((ctx->alg_type == CRYPTO_TYPE_AES_CCM) ? EVP_CTRL_CCM_SET_TAG : EVP_CTRL_GCM_SET_TAG);
48     int32_t rc = EVP_CIPHER_CTX_ctrl((EVP_CIPHER_CTX *)(uintptr_t)(ctx->ctx_buffer), tag_flag, tag_len, tag);
49     if (rc != BORINGSSL_OK) {
50         tloge("Evp aes cipher update aad data failed\n");
51         return get_soft_crypto_error(CRYPTO_BAD_PARAMETERS);
52     }
53 
54     return CRYPTO_SUCCESS;
55 }
56 
set_ae_ccm_tag(struct ctx_handle_t * ae_ctx,EVP_CIPHER_CTX * ctx,const struct ae_init_data * ae_init_param)57 static int32_t set_ae_ccm_tag(struct ctx_handle_t *ae_ctx, EVP_CIPHER_CTX *ctx,
58     const struct ae_init_data *ae_init_param)
59 {
60     if (ae_ctx->alg_type != CRYPTO_TYPE_AES_CCM)
61         return BORINGSSL_OK;
62 
63     if (ae_ctx->direction == ENC_MODE) {
64         return EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_CCM_SET_TAG, ae_init_param->tag_len, NULL);
65     } else {
66         uint8_t tag[AES_CCM_MAX_TAG_LEN] = { 0 };
67         return EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_CCM_SET_TAG, ae_init_param->tag_len, tag);
68     }
69 }
70 
init_ae_info(struct ctx_handle_t * ae_ctx,EVP_CIPHER_CTX * ctx,const struct symmerit_key_t * key,const struct ae_init_data * ae_init_param,const EVP_CIPHER * cipher)71 static int32_t init_ae_info(struct ctx_handle_t *ae_ctx, EVP_CIPHER_CTX *ctx, const struct symmerit_key_t *key,
72     const struct ae_init_data *ae_init_param, const EVP_CIPHER *cipher)
73 {
74     int32_t ret;
75     uint8_t aes_key[AES_MAX_KEY_SIZE] = { 0 };
76 
77     uint8_t *key_buffer = (uint8_t *)(uintptr_t)key->key_buffer;
78     errno_t rc = memcpy_s(aes_key, AES_MAX_KEY_SIZE, key_buffer, key->key_size);
79     if (rc != EOK) {
80         tloge("Copy key failed");
81         return CRYPTO_ERROR_SECURITY;
82     }
83     uint32_t enc_mode = ((ae_ctx->direction == TEE_MODE_ENCRYPT) ? AES_MODE_ENCRYPT : AES_MODE_DECRYPT);
84     ret = EVP_CipherInit_ex(ctx, cipher, NULL, NULL, NULL, enc_mode);
85     if (ret != BORINGSSL_OK) {
86         (void)memset_s(aes_key, AES_MAX_KEY_SIZE, 0x0, AES_MAX_KEY_SIZE);
87         tloge("Evp ae cipher init failed\n");
88         return get_soft_crypto_error(CRYPTO_BAD_PARAMETERS);
89     }
90 
91     uint32_t iv_flag = ((ae_ctx->alg_type == CRYPTO_TYPE_AES_CCM) ? EVP_CTRL_CCM_SET_IVLEN : EVP_CTRL_GCM_SET_IVLEN);
92     ret = EVP_CIPHER_CTX_ctrl(ctx, iv_flag, ae_init_param->nonce_len, NULL);
93     if (ret != BORINGSSL_OK) {
94         tloge("ae set nounce failed\n");
95         (void)memset_s(aes_key, AES_MAX_KEY_SIZE, 0x0, AES_MAX_KEY_SIZE);
96         return get_soft_crypto_error(CRYPTO_BAD_PARAMETERS);
97     }
98 
99     /* Only the ccm algorithm should been set tag len */
100     ret = set_ae_ccm_tag(ae_ctx, ctx, ae_init_param);
101     if (ret != BORINGSSL_OK) {
102         tloge("ae set tag failed\n");
103         (void)memset_s(aes_key, AES_MAX_KEY_SIZE, 0x0, AES_MAX_KEY_SIZE);
104         return get_soft_crypto_error(CRYPTO_BAD_PARAMETERS);
105     }
106 
107     ret = EVP_CipherInit_ex(ctx, NULL, NULL, aes_key, (uint8_t *)(uintptr_t)(ae_init_param->nonce), -1);
108     (void)memset_s(aes_key, AES_MAX_KEY_SIZE, 0x0, AES_MAX_KEY_SIZE);
109     if (ret != BORINGSSL_OK) {
110         tloge("ae init failed\n");
111         return get_soft_crypto_error(CRYPTO_BAD_PARAMETERS);
112     }
113     int32_t out_len = 0;
114     if (ae_ctx->alg_type == CRYPTO_TYPE_AES_CCM) {
115         ret = EVP_CipherUpdate(ctx, NULL, &out_len, NULL, ae_init_param->payload_len);
116         if (ret != BORINGSSL_OK) {
117             tloge("Evp ae cipher update failed\n");
118             return get_soft_crypto_error(CRYPTO_BAD_PARAMETERS);
119         }
120     }
121 
122     return CRYPTO_SUCCESS;
123 }
124 
soft_ae_crypto_final(struct ctx_handle_t * ctx,const struct memref_t * data_in,struct memref_t * data_out)125 static int32_t soft_ae_crypto_final(struct ctx_handle_t *ctx, const struct memref_t *data_in,
126     struct memref_t *data_out)
127 {
128     bool check = (data_in->size > INT32_MAX || data_out->size > INT32_MAX);
129     if (check) {
130         tloge("data size is too long\n");
131         return CRYPTO_BAD_PARAMETERS;
132     }
133 
134     int32_t dest_len_temp = 0;
135     int32_t final_len = 0;
136 
137     uint8_t *in_buffer = (uint8_t *)(uintptr_t)data_in->buffer;
138     uint8_t *out_buffer = (uint8_t *)(uintptr_t)data_out->buffer;
139 
140     EVP_CIPHER_CTX *ae_ctx = (EVP_CIPHER_CTX *)(uintptr_t)(ctx->ctx_buffer);
141     int32_t rc;
142     check = (in_buffer != NULL && data_in->size != 0);
143     if (check) {
144         dest_len_temp = (int32_t)(data_out->size);
145         rc = EVP_CipherUpdate(ae_ctx, out_buffer, &dest_len_temp,
146             in_buffer, (int32_t)(data_in->size));
147         if (rc != BORINGSSL_OK) {
148             tloge("Evp ae cipher update data failed\n");
149             return get_soft_crypto_error(CRYPTO_BAD_PARAMETERS);
150         }
151     }
152     if (ctx->alg_type == CRYPTO_TYPE_AES_GCM || ctx->alg_type == CRYPTO_TYPE_SM4_GCM) {
153         final_len = (int32_t)(data_out->size) - dest_len_temp;
154         rc = EVP_CipherFinal_ex(ae_ctx, out_buffer + dest_len_temp, &final_len);
155         if (rc != BORINGSSL_OK) {
156             tloge("Evp ae cipher final data failed\n");
157             return get_soft_crypto_error(CRYPTO_BAD_PARAMETERS);
158         }
159     }
160     if (dest_len_temp + final_len < 0) {
161         tloge("Evp ae cipher final data failed\n");
162         return CRYPTO_BAD_PARAMETERS;
163     }
164     data_out->size = (uint32_t)(dest_len_temp + final_len);
165     return CRYPTO_SUCCESS;
166 }
167 
ae_final_chek_param(struct ctx_handle_t * ctx,const struct memref_t * data_in,const struct memref_t * tag,struct memref_t * data_out)168 static int32_t ae_final_chek_param(struct ctx_handle_t *ctx, const struct memref_t *data_in,
169     const struct memref_t *tag, struct memref_t *data_out)
170 {
171     bool check = (ctx == NULL || ctx->ctx_buffer == 0);
172     if (check)
173         return CRYPTO_BAD_PARAMETERS;
174 
175     check = (data_in == NULL || data_out == NULL || data_out->buffer == 0 || tag == NULL || tag->buffer == 0);
176     if (check) {
177         tloge("bad params");
178         free_cipher_context(&(ctx->ctx_buffer));
179         return CRYPTO_BAD_PARAMETERS;
180     }
181     return CRYPTO_SUCCESS;
182 }
183 
soft_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)184 int32_t soft_crypto_ae_dec_final(struct ctx_handle_t *ctx, const struct memref_t *data_in,
185     const struct memref_t *tag_in, struct memref_t *data_out)
186 {
187     if (ae_final_chek_param(ctx, data_in, tag_in, data_out) != CRYPTO_SUCCESS)
188         return CRYPTO_BAD_PARAMETERS;
189 
190     int32_t ret = set_expected_tag(ctx, (uint8_t *)(uintptr_t)(tag_in->buffer), tag_in->size);
191     if (ret != CRYPTO_SUCCESS) {
192         tloge("Evp ae set expected tag data failed");
193         free_cipher_context(&(ctx->ctx_buffer));
194         return ret;
195     }
196 
197     ret = soft_ae_crypto_final(ctx, data_in, data_out);
198     free_cipher_context(&(ctx->ctx_buffer));
199     if (ret != CRYPTO_SUCCESS)
200         tloge("Evp ae crypto final data failed\n");
201     return ret;
202 }
203 
soft_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)204 int32_t soft_crypto_ae_enc_final(struct ctx_handle_t *ctx, const struct memref_t *data_in,
205     struct memref_t *data_out, struct memref_t *tag_out)
206 {
207     if (ae_final_chek_param(ctx, data_in, tag_out, data_out) != CRYPTO_SUCCESS)
208         return CRYPTO_BAD_PARAMETERS;
209 
210     uint32_t actual_tag_len = ctx->tag_len;
211     if (tag_out->size < actual_tag_len) {
212         tloge("The input tag buffer length is too small\n");
213         free_cipher_context(&(ctx->ctx_buffer));
214         return CRYPTO_BAD_PARAMETERS;
215     }
216 
217     int32_t rc = soft_ae_crypto_final(ctx, data_in, data_out);
218     if (rc != CRYPTO_SUCCESS) {
219         tloge("do ae enc final failed, ret = %d", rc);
220         free_cipher_context(&(ctx->ctx_buffer));
221         return rc;
222     }
223 
224     uint32_t tag_flag = ((ctx->alg_type == CRYPTO_TYPE_AES_CCM) ? EVP_CTRL_CCM_GET_TAG : EVP_CTRL_GCM_GET_TAG);
225     rc = EVP_CIPHER_CTX_ctrl((EVP_CIPHER_CTX *)(uintptr_t)(ctx->ctx_buffer), tag_flag,
226         actual_tag_len, (uint8_t *)(uintptr_t)(tag_out->buffer));
227     free_cipher_context(&(ctx->ctx_buffer));
228     if (rc != BORINGSSL_OK) {
229         tloge("Evp ae get tag data failed\n");
230         return get_soft_crypto_error(CRYPTO_BAD_PARAMETERS);
231     }
232     tag_out->size = actual_tag_len;
233 
234     return TEE_SUCCESS;
235 }
236 
get_ae_cipher(uint32_t alg_type,uint32_t key_size)237 static evp_cipher_func get_ae_cipher(uint32_t alg_type, uint32_t key_size)
238 {
239     for (uint32_t i = 0; i < ARRAY_NUM(g_aes_des_init_oeration); i++) {
240         if (g_aes_des_init_oeration[i].algorithm == alg_type &&
241             g_aes_des_init_oeration[i].key_size == key_size)
242             return g_aes_des_init_oeration[i].aes_cipher;
243     }
244     return NULL;
245 }
246 
soft_crypto_ae_init(struct ctx_handle_t * ctx,const struct symmerit_key_t * key,const struct ae_init_data * ae_init_param)247 int32_t soft_crypto_ae_init(struct ctx_handle_t *ctx, const struct symmerit_key_t *key,
248     const struct ae_init_data *ae_init_param)
249 {
250     if (ctx == NULL)
251         return CRYPTO_BAD_PARAMETERS;
252 
253     if (check_param_is_invalid(ctx->alg_type, key, ae_init_param)) {
254         tloge("The input param is invalid");
255         return CRYPTO_BAD_PARAMETERS;
256     }
257     evp_cipher_func aes_cipher = get_ae_cipher(ctx->alg_type, key->key_size);
258     if (aes_cipher == NULL) {
259         tloge("Get ae cipher func failed");
260         return CRYPTO_BAD_PARAMETERS;
261     }
262 
263     EVP_CIPHER_CTX *ae_ctx = EVP_CIPHER_CTX_new();
264     if (ae_ctx == NULL) {
265         tloge("New ae ctx failed");
266         return CRYPTO_BAD_PARAMETERS;
267     }
268 
269     int32_t ret = init_ae_info(ctx, ae_ctx, key, ae_init_param, aes_cipher());
270     if (ret != CRYPTO_SUCCESS) {
271         tloge("Evp ae init failed\n");
272         EVP_CIPHER_CTX_free(ae_ctx);
273         return ret;
274     }
275 
276     ctx->ctx_buffer = (uint64_t)(uintptr_t)ae_ctx;
277     ctx->tag_len = ae_init_param->tag_len;
278     ctx->free_context = free_cipher_context;
279 
280     return CRYPTO_SUCCESS;
281 }
282 
soft_crypto_ae_update_aad(struct ctx_handle_t * ctx,const struct memref_t * aad_data)283 int32_t soft_crypto_ae_update_aad(struct ctx_handle_t *ctx, const struct memref_t *aad_data)
284 {
285     bool check = (ctx == NULL || aad_data == NULL || ctx->ctx_buffer == 0 ||
286         aad_data->buffer == 0 || aad_data->size == 0 || aad_data->size > INT32_MAX);
287     if (check)
288         return CRYPTO_BAD_PARAMETERS;
289 
290     int32_t out_len = 0;
291     EVP_CIPHER_CTX *ae_ctx = (EVP_CIPHER_CTX *)(uintptr_t)(ctx->ctx_buffer);
292     int32_t rc = EVP_CipherUpdate(ae_ctx, NULL, &out_len, (uint8_t *)(uintptr_t)(aad_data->buffer),
293         (int32_t)(aad_data->size));
294     if (rc != BORINGSSL_OK) {
295         tloge("Evp aes cipher update aad data failed\n");
296         return get_soft_crypto_error(CRYPTO_BAD_PARAMETERS);
297     }
298     return CRYPTO_SUCCESS;
299 }
300 
soft_crypto_ae_update(struct ctx_handle_t * ctx,const struct memref_t * data_in,struct memref_t * data_out)301 int32_t soft_crypto_ae_update(struct ctx_handle_t *ctx, const struct memref_t *data_in, struct memref_t *data_out)
302 {
303     bool check = (ctx != NULL && ctx->alg_type == CRYPTO_TYPE_AES_CCM);
304     if (check)
305         return CRYPTO_NOT_SUPPORTED;
306     check = (ctx == NULL || ctx->ctx_buffer == 0 || data_in == NULL || data_out == NULL ||
307         data_in->buffer == 0 || data_out->buffer == 0);
308     if (check) {
309         tloge("bad params");
310         return CRYPTO_BAD_PARAMETERS;
311     }
312 
313     uint8_t *in_buffer = (uint8_t *)(uintptr_t)data_in->buffer;
314     uint8_t *out_buffer = (uint8_t *)(uintptr_t)data_out->buffer;
315 
316     if (data_out->size > INT32_MAX)
317         return CRYPTO_BAD_PARAMETERS;
318 
319     int32_t dest_len_temp = (int32_t)(data_out->size);
320 
321     int32_t rc = EVP_CipherUpdate((EVP_CIPHER_CTX *)(uintptr_t)(ctx->ctx_buffer), out_buffer, &dest_len_temp,
322         in_buffer, (int32_t)data_in->size);
323     check = (rc != BORINGSSL_OK || dest_len_temp < 0);
324     if (check) {
325         tloge("Evp aes cipher update aad data failed\n");
326         return get_soft_crypto_error(CRYPTO_BAD_PARAMETERS);
327     }
328     data_out->size = (uint32_t)dest_len_temp;
329     return CRYPTO_SUCCESS;
330 }
331