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