1 /*
2 * This file is part of the openHiTLS project.
3 *
4 * openHiTLS is licensed under the Mulan PSL v2.
5 * You can use this software according to the terms and conditions of the Mulan PSL v2.
6 * You may obtain a copy of Mulan PSL v2 at:
7 *
8 * http://license.coscl.org.cn/MulanPSL2
9 *
10 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
11 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
12 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
13 * See the Mulan PSL v2 for more details.
14 */
15
16 #include "hitls_build.h"
17 #if defined(HITLS_CRYPTO_EAL) && defined(HITLS_CRYPTO_CIPHER)
18
19 #include "securec.h"
20 #include "crypt_algid.h"
21 #include "crypt_eal_cipher.h"
22 #include "bsl_err_internal.h"
23 #include "bsl_sal.h"
24 #include "crypt_errno.h"
25 #include "eal_cipher_local.h"
26 #include "eal_common.h"
27 #include "crypt_utils.h"
28 #include "crypt_ealinit.h"
29 #include "crypt_types.h"
30 #ifdef HITLS_CRYPTO_PROVIDER
31 #include "crypt_provider.h"
32 #endif
33
CipherCopyMethod(const EAL_CipherMethod * modeMethod,EAL_CipherUnitaryMethod * method)34 static void CipherCopyMethod(const EAL_CipherMethod *modeMethod, EAL_CipherUnitaryMethod *method)
35 {
36 method->newCtx = modeMethod->newCtx;
37 method->initCtx = modeMethod->initCtx;
38 method->deinitCtx = modeMethod->deinitCtx;
39 method->update = modeMethod->update;
40 method->final = modeMethod->final;
41 method->ctrl = modeMethod->ctrl;
42 method->freeCtx = modeMethod->freeCtx;
43 }
44
CipherNewDefaultCtx(CRYPT_CIPHER_AlgId id)45 static CRYPT_EAL_CipherCtx *CipherNewDefaultCtx(CRYPT_CIPHER_AlgId id)
46 {
47 int32_t ret;
48 const EAL_CipherMethod *modeMethod = NULL;
49 ret = EAL_FindCipher(id, &modeMethod);
50 if (ret != CRYPT_SUCCESS) {
51 EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_CIPHER, id, ret);
52 return NULL;
53 }
54
55 CRYPT_EAL_CipherCtx *ctx = (CRYPT_EAL_CipherCtx *)BSL_SAL_Calloc(1u, sizeof(struct CryptEalCipherCtx));
56 if (ctx == NULL) {
57 EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_CIPHER, id, CRYPT_MEM_ALLOC_FAIL);
58 return NULL;
59 }
60
61 EAL_CipherUnitaryMethod *method = (EAL_CipherUnitaryMethod *)BSL_SAL_Calloc(1u, sizeof(EAL_CipherUnitaryMethod));
62 if (method == NULL) {
63 BSL_SAL_Free(ctx);
64 EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_CIPHER, id, CRYPT_MEM_ALLOC_FAIL);
65 return NULL;
66 }
67
68 void *modeCtx = modeMethod->newCtx(id);
69 if (modeCtx == NULL) {
70 EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_CIPHER, id, CRYPT_EAL_CIPHER_ERR_NEWCTX);
71 BSL_SAL_Free(ctx);
72 BSL_SAL_Free(method);
73 return NULL;
74 }
75
76 CipherCopyMethod(modeMethod, method);
77 ctx->id = id;
78 ctx->method = method;
79 ctx->ctx = modeCtx;
80 ctx->states = EAL_CIPHER_STATE_NEW;
81
82 return ctx;
83 }
84
85 #ifdef HITLS_CRYPTO_PROVIDER
CRYPT_EAL_SetCipherMethod(CRYPT_EAL_CipherCtx * ctx,const CRYPT_EAL_Func * funcs)86 static int32_t CRYPT_EAL_SetCipherMethod(CRYPT_EAL_CipherCtx *ctx, const CRYPT_EAL_Func *funcs)
87 {
88 int32_t index = 0;
89 EAL_CipherUnitaryMethod *method = BSL_SAL_Calloc(1, sizeof(EAL_CipherUnitaryMethod));
90 if (method == NULL) {
91 BSL_ERR_PUSH_ERROR(BSL_MALLOC_FAIL);
92 return BSL_MALLOC_FAIL;
93 }
94
95 while (funcs[index].id != 0) {
96 switch (funcs[index].id) {
97 case CRYPT_EAL_IMPLCIPHER_NEWCTX:
98 method->provNewCtx = funcs[index].func;
99 break;
100 case CRYPT_EAL_IMPLCIPHER_INITCTX:
101 method->initCtx = funcs[index].func;
102 break;
103 case CRYPT_EAL_IMPLCIPHER_UPDATE:
104 method->update = funcs[index].func;
105 break;
106 case CRYPT_EAL_IMPLCIPHER_FINAL:
107 method->final = funcs[index].func;
108 break;
109 case CRYPT_EAL_IMPLCIPHER_DEINITCTX:
110 method->deinitCtx = funcs[index].func;
111 break;
112 case CRYPT_EAL_IMPLCIPHER_FREECTX:
113 method->freeCtx = funcs[index].func;
114 break;
115 case CRYPT_EAL_IMPLCIPHER_CTRL:
116 method->ctrl = funcs[index].func;
117 break;
118 default:
119 BSL_SAL_FREE(method);
120 BSL_ERR_PUSH_ERROR(CRYPT_PROVIDER_ERR_UNEXPECTED_IMPL);
121 return CRYPT_PROVIDER_ERR_UNEXPECTED_IMPL;
122 }
123 index++;
124 }
125 ctx->method = method;
126 return CRYPT_SUCCESS;
127 }
128
CRYPT_EAL_ProviderCipherNewCtxInner(CRYPT_EAL_LibCtx * libCtx,int32_t algId,const char * attrName)129 CRYPT_EAL_CipherCtx *CRYPT_EAL_ProviderCipherNewCtxInner(CRYPT_EAL_LibCtx *libCtx, int32_t algId, const char *attrName)
130 {
131 const CRYPT_EAL_Func *funcs = NULL;
132 void *provCtx = NULL;
133 int32_t ret = CRYPT_EAL_ProviderGetFuncs(libCtx, CRYPT_EAL_OPERAID_SYMMCIPHER, algId, attrName,
134 (const CRYPT_EAL_Func **)&funcs, &provCtx);
135 if (ret != CRYPT_SUCCESS) {
136 EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_CIPHER, algId, ret);
137 return NULL;
138 }
139 CRYPT_EAL_CipherCtx *ctx = BSL_SAL_Calloc(1u, sizeof(CRYPT_EAL_CipherCtx));
140 if (ctx == NULL) {
141 EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_CIPHER, algId, CRYPT_MEM_ALLOC_FAIL);
142 return NULL;
143 }
144
145 ret = CRYPT_EAL_SetCipherMethod(ctx, funcs);
146 if (ret != BSL_SUCCESS) {
147 EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_CIPHER, algId, ret);
148 BSL_SAL_FREE(ctx);
149 return NULL;
150 }
151 if (ctx->method->provNewCtx == NULL) {
152 EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_CIPHER, algId, CRYPT_PROVIDER_ERR_IMPL_NULL);
153 BSL_SAL_FREE(ctx->method);
154 BSL_SAL_FREE(ctx);
155 return NULL;
156 }
157 ctx->ctx = ctx->method->provNewCtx(provCtx, algId);
158 if (ctx->ctx == NULL) {
159 EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_CIPHER, algId, CRYPT_MEM_ALLOC_FAIL);
160 BSL_SAL_FREE(ctx->method);
161 BSL_SAL_FREE(ctx);
162 return NULL;
163 }
164 ctx->id = algId;
165 ctx->states = EAL_CIPHER_STATE_NEW;
166 ctx->isProvider = true;
167 return ctx;
168 }
169 #endif
170
CRYPT_EAL_ProviderCipherNewCtx(CRYPT_EAL_LibCtx * libCtx,int32_t algId,const char * attrName)171 CRYPT_EAL_CipherCtx *CRYPT_EAL_ProviderCipherNewCtx(CRYPT_EAL_LibCtx *libCtx, int32_t algId, const char *attrName)
172 {
173 #ifdef HITLS_CRYPTO_PROVIDER
174 return CRYPT_EAL_ProviderCipherNewCtxInner(libCtx, algId, attrName);
175 #else
176 (void)libCtx;
177 (void)attrName;
178 return CRYPT_EAL_CipherNewCtx(algId);
179 #endif
180 }
181
CRYPT_EAL_CipherNewCtx(CRYPT_CIPHER_AlgId id)182 CRYPT_EAL_CipherCtx *CRYPT_EAL_CipherNewCtx(CRYPT_CIPHER_AlgId id)
183 {
184 #ifdef HITLS_CRYPTO_ASM_CHECK
185 if (CRYPT_ASMCAP_Cipher(id) != CRYPT_SUCCESS) {
186 BSL_ERR_PUSH_ERROR(CRYPT_EAL_ALG_ASM_NOT_SUPPORT);
187 return NULL;
188 }
189 #endif
190 return CipherNewDefaultCtx(id);
191 }
192
CRYPT_EAL_CipherFreeCtx(CRYPT_EAL_CipherCtx * ctx)193 void CRYPT_EAL_CipherFreeCtx(CRYPT_EAL_CipherCtx *ctx)
194 {
195 if (ctx == NULL) {
196 // If the input parameter is NULL, it is not considered as an error.
197 return;
198 }
199 if (ctx->method == NULL || ctx->method->freeCtx == NULL) {
200 EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_CIPHER, ctx->id, CRYPT_EAL_ALG_NOT_SUPPORT);
201 BSL_SAL_FREE(ctx->method);
202 BSL_SAL_FREE(ctx);
203 return;
204 }
205
206 (void)ctx->method->freeCtx(ctx->ctx);
207 BSL_SAL_FREE(ctx->method);
208 // Free the memory eal ctx and mode ctx at the EAL layer.
209 BSL_SAL_FREE(ctx);
210 }
211
CRYPT_EAL_CipherInit(CRYPT_EAL_CipherCtx * ctx,const uint8_t * key,uint32_t keyLen,const uint8_t * iv,uint32_t ivLen,bool enc)212 int32_t CRYPT_EAL_CipherInit(CRYPT_EAL_CipherCtx *ctx, const uint8_t *key, uint32_t keyLen, const uint8_t *iv,
213 uint32_t ivLen, bool enc)
214 {
215 int32_t ret;
216 if (ctx == NULL) {
217 EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_CIPHER, CRYPT_CIPHER_MAX, CRYPT_NULL_INPUT);
218 return CRYPT_NULL_INPUT;
219 }
220 if (ctx->method == NULL || ctx->method->initCtx == NULL) {
221 EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_CIPHER, ctx->id, CRYPT_EAL_ALG_NOT_SUPPORT);
222 return CRYPT_EAL_ALG_NOT_SUPPORT;
223 }
224
225 CRYPT_EAL_CipherDeinit(ctx);
226 if (ctx->states != EAL_CIPHER_STATE_NEW) {
227 EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_CIPHER, ctx->id, CRYPT_EAL_ERR_STATE);
228 return CRYPT_EAL_ERR_STATE;
229 }
230
231 ret = ctx->method->initCtx(ctx->ctx, key, keyLen, iv, ivLen, NULL, enc);
232 if (ret != CRYPT_SUCCESS) {
233 EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_CIPHER, ctx->id, ret);
234 return ret;
235 }
236
237 EAL_EventReport(CRYPT_EVENT_SETSSP, CRYPT_ALGO_CIPHER, ctx->id, CRYPT_SUCCESS);
238 ctx->states = EAL_CIPHER_STATE_INIT;
239 return CRYPT_SUCCESS;
240 }
241
CRYPT_EAL_CipherDeinit(CRYPT_EAL_CipherCtx * ctx)242 void CRYPT_EAL_CipherDeinit(CRYPT_EAL_CipherCtx *ctx)
243 {
244 if (ctx == NULL) {
245 // If the ctx is NULL during deinit, it is not considered as an error.
246 return;
247 }
248 if (ctx->method == NULL || ctx->method->deinitCtx == NULL) {
249 EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_CIPHER, ctx->id, CRYPT_EAL_ALG_NOT_SUPPORT);
250 return;
251 }
252
253 int32_t ret = ctx->method->deinitCtx(ctx->ctx);
254 if (ret != CRYPT_SUCCESS) {
255 EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_CIPHER, ctx->id, ret);
256 }
257
258 // Restore the state to the state after the new is successful.
259 ctx->states = EAL_CIPHER_STATE_NEW;
260 EAL_EventReport(CRYPT_EVENT_ZERO, CRYPT_ALGO_CIPHER, ctx->id, CRYPT_SUCCESS);
261 }
262
263 // no need for IV, the value can be set to NULL
CRYPT_EAL_CipherReinit(CRYPT_EAL_CipherCtx * ctx,uint8_t * iv,uint32_t ivLen)264 int32_t CRYPT_EAL_CipherReinit(CRYPT_EAL_CipherCtx *ctx, uint8_t *iv, uint32_t ivLen)
265 {
266 int32_t ret;
267 if (ctx == NULL) {
268 EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_CIPHER, CRYPT_CIPHER_MAX, CRYPT_NULL_INPUT);
269 return CRYPT_NULL_INPUT;
270 }
271
272 // Without init, reinit cannot be invoked directly.
273 if (ctx->states == EAL_CIPHER_STATE_NEW) {
274 EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_CIPHER, ctx->id, CRYPT_EAL_ERR_STATE);
275 return CRYPT_EAL_ERR_STATE;
276 }
277
278 // Reset the IV. In this case, reset the IV is not restricted by the states.
279 if (ctx->method == NULL || ctx->method->ctrl == NULL) {
280 EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_CIPHER, ctx->id, CRYPT_EAL_ALG_NOT_SUPPORT);
281 return CRYPT_EAL_ALG_NOT_SUPPORT;
282 }
283 ret = ctx->method->ctrl(ctx->ctx, CRYPT_CTRL_REINIT_STATUS, iv, ivLen);
284 if (ret != CRYPT_SUCCESS) {
285 EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_CIPHER, ctx->id, ret);
286 return ret;
287 }
288
289 // Reset the states.
290 ctx->states = EAL_CIPHER_STATE_INIT;
291 EAL_EventReport(CRYPT_EVENT_SETSSP, CRYPT_ALGO_CIPHER, ctx->id, CRYPT_SUCCESS);
292 return CRYPT_SUCCESS;
293 }
294
IsPartialOverLap(const void * out,const void * in,uint32_t len)295 static bool IsPartialOverLap(const void *out, const void *in, uint32_t len)
296 {
297 uintptr_t diff;
298 if ((uintptr_t)out > (uintptr_t)in) {
299 diff = (uintptr_t)out - (uintptr_t)in;
300 return diff < (uintptr_t)len;
301 }
302 // If in >= out, this case is valid.
303 return false;
304 }
305
CheckUpdateParam(const CRYPT_EAL_CipherCtx * ctx,const uint8_t * in,uint32_t inLen,const uint8_t * out,const uint32_t * outLen)306 static int32_t CheckUpdateParam(const CRYPT_EAL_CipherCtx *ctx, const uint8_t *in, uint32_t inLen, const uint8_t *out,
307 const uint32_t *outLen)
308 {
309 if (ctx == NULL || out == NULL || outLen == NULL || (in == NULL && inLen != 0)) {
310 BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
311 return CRYPT_NULL_INPUT;
312 }
313 if ((in != NULL && inLen != 0) && IsPartialOverLap(out, in, inLen)) {
314 BSL_ERR_PUSH_ERROR(CRYPT_EAL_ERR_PART_OVERLAP);
315 return CRYPT_EAL_ERR_PART_OVERLAP;
316 }
317 // If the state is not init or update, the state is regarded as an error.
318 // If the state is final or new, update cannot be directly invoked.
319 if (!(ctx->states == EAL_CIPHER_STATE_INIT || ctx->states == EAL_CIPHER_STATE_UPDATE)) {
320 BSL_ERR_PUSH_ERROR(CRYPT_EAL_ERR_STATE);
321 return CRYPT_EAL_ERR_STATE;
322 }
323 if (ctx->method == NULL || ctx->method->update == NULL) {
324 EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_CIPHER, ctx->id, CRYPT_EAL_ALG_NOT_SUPPORT);
325 return CRYPT_EAL_ALG_NOT_SUPPORT;
326 }
327 return CRYPT_SUCCESS;
328 }
329
CRYPT_EAL_CipherUpdate(CRYPT_EAL_CipherCtx * ctx,const uint8_t * in,uint32_t inLen,uint8_t * out,uint32_t * outLen)330 int32_t CRYPT_EAL_CipherUpdate(CRYPT_EAL_CipherCtx *ctx, const uint8_t *in, uint32_t inLen, uint8_t *out,
331 uint32_t *outLen)
332 {
333 int32_t ret = CheckUpdateParam(ctx, in, inLen, out, outLen);
334 if (ret != CRYPT_SUCCESS) {
335 // The push error in CheckUpdateParam can be locate the only error location. No need to add the push error here.
336 EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_CIPHER, (ctx == NULL) ? CRYPT_CIPHER_MAX : ctx->id, ret);
337 return ret;
338 }
339
340 ret = ctx->method->update(ctx->ctx, in, inLen, out, outLen);
341 if (ret != CRYPT_SUCCESS) {
342 EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_CIPHER, ctx->id, ret);
343 return ret;
344 }
345 ctx->states = EAL_CIPHER_STATE_UPDATE;
346 return CRYPT_SUCCESS;
347 }
348
CheckFinalParam(const CRYPT_EAL_CipherCtx * ctx,const uint8_t * out,const uint32_t * outLen)349 int32_t CheckFinalParam(const CRYPT_EAL_CipherCtx *ctx, const uint8_t *out, const uint32_t *outLen)
350 {
351 if (ctx == NULL || out == NULL || outLen == NULL) {
352 BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
353 return CRYPT_NULL_INPUT;
354 }
355 // If the state is not init or update, the state is regarded as an error.
356 // If the state is final or new, update cannot be directly invoked.
357 if (!(ctx->states == EAL_CIPHER_STATE_UPDATE || ctx->states == EAL_CIPHER_STATE_INIT)) {
358 BSL_ERR_PUSH_ERROR(CRYPT_EAL_ERR_STATE);
359 return CRYPT_EAL_ERR_STATE;
360 }
361
362 if (ctx->method == NULL || ctx->method->final == NULL) {
363 BSL_ERR_PUSH_ERROR(CRYPT_EAL_ALG_NOT_SUPPORT);
364 return CRYPT_EAL_ALG_NOT_SUPPORT;
365 }
366 return CRYPT_SUCCESS;
367 }
368
CRYPT_EAL_CipherFinal(CRYPT_EAL_CipherCtx * ctx,uint8_t * out,uint32_t * outLen)369 int32_t CRYPT_EAL_CipherFinal(CRYPT_EAL_CipherCtx *ctx, uint8_t *out, uint32_t *outLen)
370 {
371 int32_t ret;
372 ret = CheckFinalParam(ctx, out, outLen);
373 if (ret != CRYPT_SUCCESS) {
374 EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_CIPHER, (ctx == NULL) ? CRYPT_CIPHER_MAX : ctx->id, ret);
375 return ret;
376 }
377
378 ret = ctx->method->final(ctx->ctx, out, outLen);
379 if (ret != CRYPT_SUCCESS) {
380 EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_CIPHER, ctx->id, ret);
381 return ret;
382 }
383
384 ctx->states = EAL_CIPHER_STATE_FINAL;
385 return CRYPT_SUCCESS;
386 }
387
CipherCtrlIsCanSet(const CRYPT_EAL_CipherCtx * ctx,int32_t type)388 static bool CipherCtrlIsCanSet(const CRYPT_EAL_CipherCtx *ctx, int32_t type)
389 {
390 if (ctx->states == EAL_CIPHER_STATE_NEW) {
391 return false;
392 }
393 if (ctx->states == EAL_CIPHER_STATE_FINAL) {
394 return false;
395 }
396 if ((ctx->states == EAL_CIPHER_STATE_UPDATE) &&
397 (type == CRYPT_CTRL_SET_COUNT || type == CRYPT_CTRL_SET_TAGLEN ||
398 type == CRYPT_CTRL_SET_MSGLEN || type == CRYPT_CTRL_SET_AAD)) {
399 return false;
400 }
401 return true;
402 }
403
CRYPT_EAL_CipherCtrl(CRYPT_EAL_CipherCtx * ctx,int32_t type,void * data,uint32_t len)404 int32_t CRYPT_EAL_CipherCtrl(CRYPT_EAL_CipherCtx *ctx, int32_t type, void *data, uint32_t len)
405 {
406 if (ctx == NULL) {
407 EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_CIPHER, CRYPT_CIPHER_MAX, CRYPT_NULL_INPUT);
408 return CRYPT_NULL_INPUT;
409 }
410 // The IV cannot be set through the Ctrl. You need to set the IV through the init and reinit.
411 if (type == CRYPT_CTRL_SET_IV || type == CRYPT_CTRL_REINIT_STATUS) {
412 EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_CIPHER, ctx->id, CRYPT_EAL_CIPHER_CTRL_ERROR);
413 return CRYPT_EAL_CIPHER_CTRL_ERROR;
414 }
415
416 // If the algorithm is running in the intermediate state, write operations are not allowed.
417 if (!CipherCtrlIsCanSet(ctx, type)) {
418 EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_CIPHER, ctx->id, CRYPT_EAL_ERR_STATE);
419 return CRYPT_EAL_ERR_STATE;
420 }
421 // Setting AAD indicates that the encryption operation has started and no more write operations are allowed.
422 if (type == CRYPT_CTRL_SET_AAD) {
423 ctx->states = EAL_CIPHER_STATE_UPDATE;
424 } else if (type == CRYPT_CTRL_GET_TAG) {
425 // After getTag the system enters the final state.
426 ctx->states = EAL_CIPHER_STATE_FINAL;
427 }
428 if (ctx->method == NULL || ctx->method->ctrl == NULL) {
429 EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_CIPHER, ctx->id, CRYPT_EAL_ALG_NOT_SUPPORT);
430 return CRYPT_EAL_ALG_NOT_SUPPORT;
431 }
432 int32_t ret = ctx->method->ctrl(ctx->ctx, type, data, len);
433 if (ret != CRYPT_SUCCESS) {
434 EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_CIPHER, ctx->id, ret);
435 return ret;
436 }
437 return ret;
438 }
439
CRYPT_EAL_CipherSetPadding(CRYPT_EAL_CipherCtx * ctx,CRYPT_PaddingType type)440 int32_t CRYPT_EAL_CipherSetPadding(CRYPT_EAL_CipherCtx *ctx, CRYPT_PaddingType type)
441 {
442 if (ctx == NULL) {
443 EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_CIPHER, CRYPT_CIPHER_MAX, CRYPT_NULL_INPUT);
444 return CRYPT_NULL_INPUT;
445 }
446
447 if (ctx->method == NULL || ctx->method->ctrl == NULL) {
448 EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_CIPHER, ctx->id, CRYPT_EAL_ALG_NOT_SUPPORT);
449 return CRYPT_EAL_ALG_NOT_SUPPORT;
450 }
451 int32_t ret = ctx->method->ctrl(ctx->ctx, CRYPT_CTRL_SET_PADDING, (void *)&type, sizeof(type));
452 if (ret != CRYPT_SUCCESS) {
453 EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_CIPHER, ctx->id, ret);
454 }
455 return ret;
456 }
457
CRYPT_EAL_CipherGetPadding(CRYPT_EAL_CipherCtx * ctx)458 int32_t CRYPT_EAL_CipherGetPadding(CRYPT_EAL_CipherCtx *ctx)
459 {
460 if (ctx == NULL) {
461 EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_CIPHER, CRYPT_CIPHER_MAX, CRYPT_NULL_INPUT);
462 return CRYPT_NULL_INPUT;
463 }
464
465 if (ctx->method == NULL || ctx->method->ctrl == NULL) {
466 EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_CIPHER, ctx->id, CRYPT_EAL_ALG_NOT_SUPPORT);
467 return CRYPT_EAL_ALG_NOT_SUPPORT;
468 }
469 int32_t type;
470 int32_t ret = ctx->method->ctrl(ctx->ctx, CRYPT_CTRL_GET_PADDING, (void *)&type, sizeof(type));
471 if (ret != CRYPT_SUCCESS) {
472 EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_CIPHER, ctx->id, ret);
473 return CRYPT_PADDING_MAX_COUNT;
474 }
475 return type;
476 }
477
CRYPT_EAL_CipherIsValidAlgId(CRYPT_CIPHER_AlgId id)478 bool CRYPT_EAL_CipherIsValidAlgId(CRYPT_CIPHER_AlgId id)
479 {
480 const EAL_CipherMethod *m = NULL;
481 return EAL_FindCipher(id, &m) == CRYPT_SUCCESS;
482 }
483
484
485 static const uint32_t CIPHER_IS_AEAD[] = {
486 CRYPT_CIPHER_AES128_CCM,
487 CRYPT_CIPHER_AES192_CCM,
488 CRYPT_CIPHER_AES256_CCM,
489 CRYPT_CIPHER_AES128_GCM,
490 CRYPT_CIPHER_AES192_GCM,
491 CRYPT_CIPHER_AES256_GCM,
492 CRYPT_CIPHER_CHACHA20_POLY1305,
493 CRYPT_CIPHER_SM4_GCM,
494 };
495
496 // Check whether the algorithm is the AEAD algorithm. If yes, true is returned. Otherwise, false is returned.
IsAeadAlg(CRYPT_CIPHER_AlgId id)497 static bool IsAeadAlg(CRYPT_CIPHER_AlgId id)
498 {
499 if (ParamIdIsValid(id, CIPHER_IS_AEAD, sizeof(CIPHER_IS_AEAD) / sizeof(CIPHER_IS_AEAD[0]))) {
500 return true;
501 }
502 return false;
503 }
504
CRYPT_EAL_CipherGetInfo(CRYPT_CIPHER_AlgId id,int32_t type,uint32_t * infoValue)505 int32_t CRYPT_EAL_CipherGetInfo(CRYPT_CIPHER_AlgId id, int32_t type, uint32_t *infoValue)
506 {
507 if (infoValue == NULL) {
508 EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_CIPHER, id, CRYPT_INVALID_ARG);
509 return CRYPT_INVALID_ARG;
510 }
511
512 CRYPT_CipherInfo info = {0};
513 if (EAL_GetCipherInfo(id, &info) != CRYPT_SUCCESS) {
514 EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_CIPHER, id, CRYPT_ERR_ALGID);
515 return CRYPT_ERR_ALGID;
516 }
517
518 switch (type) {
519 case CRYPT_INFO_IS_AEAD:
520 (*infoValue) = IsAeadAlg(id) ? 1 : 0;
521 break;
522 case CRYPT_INFO_IS_STREAM:
523 (*infoValue) = (uint32_t)!((info.blockSize) != 1);
524 break;
525 case CRYPT_INFO_IV_LEN:
526 (*infoValue) = info.ivLen;
527 break;
528 case CRYPT_INFO_KEY_LEN:
529 (*infoValue) = info.keyLen;
530 break;
531 case CRYPT_INFO_BLOCK_LEN:
532 (*infoValue) = (uint32_t)info.blockSize;
533 break;
534 default:
535 EAL_ERR_REPORT(CRYPT_EVENT_ERR, CRYPT_ALGO_CIPHER, id, CRYPT_EAL_INTO_TYPE_NOT_SUPPORT);
536 return CRYPT_EAL_INTO_TYPE_NOT_SUPPORT;
537 }
538
539 return CRYPT_SUCCESS;
540 }
541
542 #endif
543