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 #ifdef HITLS_CRYPTO_GCM
18
19 #include <stdint.h>
20 #include "securec.h"
21 #include "bsl_sal.h"
22 #include "bsl_err_internal.h"
23 #include "crypt_utils.h"
24 #include "crypt_errno.h"
25 #include "crypt_modes_gcm.h"
26 #include "modes_local.h"
27 #include "crypt_modes.h"
28
MODES_GCM_SetKey(MODES_CipherGCMCtx * ctx,const uint8_t * key,uint32_t len)29 int32_t MODES_GCM_SetKey(MODES_CipherGCMCtx *ctx, const uint8_t *key, uint32_t len)
30 {
31 if (ctx == NULL) {
32 BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
33 return CRYPT_NULL_INPUT;
34 }
35 int32_t ret = ctx->ciphMeth->setEncryptKey(ctx->ciphCtx, key, len);
36 if (ret != CRYPT_SUCCESS) {
37 BSL_ERR_PUSH_ERROR(ret);
38 return ret;
39 }
40 return MODES_GCM_InitHashTable(ctx);
41 }
42
MODES_GCM_InitHashTable(MODES_CipherGCMCtx * ctx)43 int32_t MODES_GCM_InitHashTable(MODES_CipherGCMCtx *ctx)
44 {
45 if (ctx == NULL) {
46 BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
47 return CRYPT_NULL_INPUT;
48 }
49 uint8_t gcmKey[GCM_BLOCKSIZE] = { 0 };
50 int32_t ret = ctx->ciphMeth->encryptBlock(ctx->ciphCtx, gcmKey, gcmKey, GCM_BLOCKSIZE);
51 if (ret != CRYPT_SUCCESS) {
52 BSL_ERR_PUSH_ERROR(ret);
53 return ret;
54 }
55 GcmTableGen4bit(gcmKey, ctx->hTable);
56 ctx->tagLen = GCM_BLOCKSIZE;
57 BSL_SAL_CleanseData(gcmKey, sizeof(gcmKey));
58 return CRYPT_SUCCESS;
59 }
60
61 // Update the number of usage times.
CheckUseCnt(const MODES_CipherGCMCtx * ctx)62 static int32_t CheckUseCnt(const MODES_CipherGCMCtx *ctx)
63 {
64 // 128, 120, 112, 104, or 96 that is 12 byte - 16 byte
65 if (ctx->cryptCnt == GCM_MAX_INVOCATIONS_TIMES) {
66 BSL_ERR_PUSH_ERROR(CRYPT_MODES_KEYUSE_TOOMANY_TIME);
67 return CRYPT_MODES_KEYUSE_TOOMANY_TIME;
68 }
69 return CRYPT_SUCCESS;
70 }
71
72 /**
73 * NIST_800-38D-5.2
74 * 1 ≤ len(IV) ≤ 2^64 - 1 (bit)
75 * It is currently restricted to no more than 2^32 - 1 bytes
76 */
MODES_GCM_SetIv(MODES_CipherGCMCtx * ctx,const uint8_t * iv,uint32_t ivLen)77 int32_t MODES_GCM_SetIv(MODES_CipherGCMCtx *ctx, const uint8_t *iv, uint32_t ivLen)
78 {
79 if (iv == NULL || ivLen == 0) {
80 BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
81 return CRYPT_NULL_INPUT;
82 }
83 int32_t ret = CheckUseCnt(ctx); // Check the number of usage times.
84 if (ret != CRYPT_SUCCESS) {
85 BSL_ERR_PUSH_ERROR(ret);
86 return ret;
87 }
88 uint32_t i;
89 uint64_t len = (uint64_t)ivLen;
90 // when ivLen == 0, do reinit, no need to refersh iv
91 if (len == 12) { // len(IV ) = 96bit = 12byte
92 const uint8_t ivPad[4] = {0x00, 0x00, 0x00, 0x01};
93 /* Y0 = IV || 0^31 || 1 if len(IV ) = 96 = 12byte */
94 (void)memcpy_s(ctx->iv, GCM_BLOCKSIZE, iv, 12);
95 (void)memcpy_s(ctx->iv + 12, GCM_BLOCKSIZE - 12, ivPad, sizeof(ivPad)); // pad last 4bit(base = 12)
96 } else {
97 /* Y0 = GHASH(H, {}, IV ) otherwise */
98 (void)memset_s(ctx->iv, GCM_BLOCKSIZE, 0, GCM_BLOCKSIZE);
99 const uint8_t *off = iv;
100 uint32_t blockLen = ivLen & GCM_BLOCK_MASK;
101 uint32_t lastLen = ivLen - blockLen;
102 uint8_t tmp[GCM_BLOCKSIZE] = {0};
103 if (blockLen > 0) {
104 GcmHashMultiBlock(ctx->iv, ctx->hTable, off, blockLen);
105 off += blockLen;
106 }
107 if (lastLen > 0) {
108 for (i = 0; i < lastLen; i++) {
109 tmp[i] = off[i];
110 }
111 GcmHashMultiBlock(ctx->iv, ctx->hTable, tmp, GCM_BLOCKSIZE);
112 }
113 len = (uint64_t)ivLen << 3; // bitLen = byteLen << 3
114 (void)BSL_SAL_CleanseData(tmp, GCM_BLOCKSIZE);
115 Uint64ToBeBytes(len, tmp + 8); // The last 8 bytes store the length of the IV.
116 GcmHashMultiBlock(ctx->iv, ctx->hTable, tmp, GCM_BLOCKSIZE);
117 }
118 /**
119 * NIST_800-38D-7.1
120 * GCTR(J0)
121 */
122 ctx->ciphMeth->encryptBlock(ctx->ciphCtx, ctx->iv, ctx->ek0, GCM_BLOCKSIZE);
123
124 /**
125 * NIST_800-38D-7.1
126 * INC32
127 * the 32-bit incrementing function is applied to the pre-counter block
128 * to produce the initial counter block for an invocation of the GCTR
129 * function on the plaintext
130 */
131 uint32_t ctr = GET_UINT32_BE(ctx->iv, 12); // Offset of 12 bytes. Use the last four bytes.
132 ctr++;
133 PUT_UINT32_BE(ctr, ctx->iv, 12); // Writeback of offset 12 bytes
134
135 // Reset information.
136 (void)memset_s(ctx->ghash, GCM_BLOCKSIZE, 0, GCM_BLOCKSIZE);
137 ctx->aadLen = 0;
138 (void)memset_s(ctx->last, GCM_BLOCKSIZE, 0, GCM_BLOCKSIZE);
139 ctx->lastLen = 0;
140 ctx->plaintextLen = 0;
141 (void)memset_s(ctx->remCt, GCM_BLOCKSIZE, 0, GCM_BLOCKSIZE);
142
143 // Clear sensitive information.
144 BSL_SAL_CleanseData(&ctr, sizeof(uint32_t));
145 return CRYPT_SUCCESS;
146 }
147
148 /**
149 * NIST_800-38D-5.2
150 * len(AAD) ≤ 2^64 - 1 (bit)
151 * Currently, it is restricted to no more than 2^32 - 1 bytes.
152 */
SetAad(MODES_CipherGCMCtx * ctx,const uint8_t * aad,uint32_t aadLen)153 static int32_t SetAad(MODES_CipherGCMCtx *ctx, const uint8_t *aad, uint32_t aadLen)
154 {
155 if (aad == NULL && aadLen != 0) {
156 BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
157 return CRYPT_NULL_INPUT;
158 }
159 const uint8_t *off = aad;
160 uint32_t i;
161 if (ctx->aadLen != 0 || ctx->plaintextLen != 0) { // aad is set
162 BSL_ERR_PUSH_ERROR(CRYPT_MODES_AAD_REPEAT_SET_ERROR);
163 return CRYPT_MODES_AAD_REPEAT_SET_ERROR;
164 }
165 uint32_t blockLen = aadLen & GCM_BLOCK_MASK;
166 uint32_t lastLen = aadLen - blockLen;
167 if (blockLen > 0) {
168 GcmHashMultiBlock(ctx->ghash, ctx->hTable, off, blockLen);
169 off += blockLen;
170 }
171 if (lastLen > 0) {
172 uint8_t temp[GCM_BLOCKSIZE] = {0};
173 for (i = 0; i < lastLen; i++) {
174 temp[i] = off[i];
175 }
176 GcmHashMultiBlock(ctx->ghash, ctx->hTable, temp, GCM_BLOCKSIZE);
177 }
178 ctx->aadLen = aadLen;
179 return CRYPT_SUCCESS;
180 }
181
182 // Overflow occurs when the encryption length is determined and the encrypted length information is updated.
CryptLenCheckAndRefresh(MODES_CipherGCMCtx * ctx,uint32_t len)183 int32_t CryptLenCheckAndRefresh(MODES_CipherGCMCtx *ctx, uint32_t len)
184 {
185 // The length of len is only 32 bits. This calculation does not cause overflow.
186 uint64_t plaintextLen = ctx->plaintextLen + len;
187 if (plaintextLen > GCM_MAX_COMBINED_LENGTH) {
188 BSL_ERR_PUSH_ERROR(CRYPT_MODES_CRYPTLEN_OVERFLOW);
189 return CRYPT_MODES_CRYPTLEN_OVERFLOW;
190 }
191 ctx->plaintextLen = plaintextLen;
192 return CRYPT_SUCCESS;
193 }
194
GcmXorInEncrypt(XorCryptData * data,uint32_t len)195 static void GcmXorInEncrypt(XorCryptData *data, uint32_t len)
196 {
197 uint32_t i;
198 for (i = 0; i < len; i++) {
199 data->out[i] = data->in[i] ^ data->ctr[i];
200 data->tag[i] = data->out[i];
201 }
202 }
203
GcmXorInDecrypt(XorCryptData * data,uint32_t len)204 static void GcmXorInDecrypt(XorCryptData *data, uint32_t len)
205 {
206 uint32_t i;
207 for (i = 0; i < len; i++) {
208 data->tag[i] = data->in[i];
209 data->out[i] = data->in[i] ^ data->ctr[i];
210 }
211 }
212
213 // Process the remaining data in the last update.
MODES_GCM_LastHandle(MODES_CipherGCMCtx * ctx,const uint8_t * in,uint8_t * out,uint32_t len,bool enc)214 uint32_t MODES_GCM_LastHandle(MODES_CipherGCMCtx *ctx, const uint8_t *in, uint8_t *out, uint32_t len, bool enc)
215 {
216 uint32_t lastLen = 0;
217 if (ctx->lastLen > 0) {
218 XorCryptData data;
219 lastLen = (ctx->lastLen < len) ? ctx->lastLen : len;
220 data.in = in;
221 data.out = out;
222 data.ctr = &(ctx->last[GCM_BLOCKSIZE - ctx->lastLen]);
223 data.tag = &(ctx->remCt[GCM_BLOCKSIZE - ctx->lastLen]);
224 if (enc) { // ctx->lastLen must be smaller than the GCM_BLOCKSIZE
225 GcmXorInEncrypt(&data, lastLen);
226 } else {
227 GcmXorInDecrypt(&data, lastLen);
228 }
229 // Refresh the remaining length.
230 ctx->lastLen -= lastLen;
231 if (ctx->lastLen == 0) {
232 GcmHashMultiBlock(ctx->ghash, ctx->hTable, ctx->remCt, GCM_BLOCKSIZE);
233 }
234 }
235 return lastLen;
236 }
237
GcmMultiBlockCrypt(MODES_CipherGCMCtx * ctx,const uint8_t * in,uint8_t * out,uint32_t len,bool enc)238 static void GcmMultiBlockCrypt(MODES_CipherGCMCtx *ctx, const uint8_t *in, uint8_t *out, uint32_t len, bool enc)
239 {
240 uint32_t blockLen = len;
241 const uint8_t *dataIn = in;
242 uint8_t *dataOut = out;
243 // count information, last 32 bits of the IV, with an offset of 12 bytes (16-4 = 12)
244 uint32_t ctr = GET_UINT32_BE(ctx->iv, 12);
245 if (enc == false) {
246 GcmHashMultiBlock(ctx->ghash, ctx->hTable, in, len);
247 }
248 while (blockLen > 0) {
249 ctx->ciphMeth->encryptBlock(ctx->ciphCtx, ctx->iv, ctx->last, GCM_BLOCKSIZE);
250 DATA64_XOR(dataIn, ctx->last, dataOut, GCM_BLOCKSIZE);
251 /**
252 * NIST_800-38D-7.1
253 * INC32
254 */
255 ctr++;
256 PUT_UINT32_BE(ctr, ctx->iv, 12); // Offset of 12 bytes. Use the last four bytes.
257 // Refresh the remaining length.
258 blockLen -= GCM_BLOCKSIZE;
259 // offset
260 dataIn += GCM_BLOCKSIZE;
261 dataOut += GCM_BLOCKSIZE;
262 }
263 if (enc) {
264 GcmHashMultiBlock(ctx->ghash, ctx->hTable, out, len);
265 }
266 // Clear sensitive information.
267 BSL_SAL_CleanseData(&ctr, sizeof(uint32_t));
268 }
269
270 // enc: true: the encryption operation, false: the decryption operation
MODES_GCM_Crypt(MODES_CipherGCMCtx * ctx,const uint8_t * in,uint8_t * out,uint32_t len,bool enc)271 static int32_t MODES_GCM_Crypt(MODES_CipherGCMCtx *ctx, const uint8_t *in, uint8_t *out, uint32_t len, bool enc)
272 {
273 if (ctx == NULL || out == NULL) {
274 BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
275 return CRYPT_NULL_INPUT;
276 }
277 if (len != 0 && in == NULL) {
278 BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
279 return CRYPT_NULL_INPUT;
280 }
281 int32_t ret = CryptLenCheckAndRefresh(ctx, len);
282 if (ret != CRYPT_SUCCESS) {
283 return ret;
284 }
285 uint32_t lastLen = MODES_GCM_LastHandle(ctx, in, out, len, enc);
286 // Data processing is complete. Exit.
287 if (lastLen == len) {
288 return CRYPT_SUCCESS;
289 }
290
291 XorCryptData data;
292 data.in = in + lastLen;
293 data.out = out + lastLen;
294 data.ctr = ctx->last;
295 data.tag = ctx->remCt;
296
297 uint32_t multiBlockLen = (len - lastLen) & GCM_BLOCK_MASK;
298 if (multiBlockLen > 0) {
299 GcmMultiBlockCrypt(ctx, data.in, data.out, multiBlockLen, enc);
300 data.in += multiBlockLen;
301 data.out += multiBlockLen;
302 }
303 uint32_t remLen = len - lastLen - multiBlockLen;
304 if (remLen > 0) {
305 // count information, last 32 bits of the IV, with an offset of 12 bytes (16-4 = 12)
306 uint32_t ctr = GET_UINT32_BE(ctx->iv, 12);
307 (void)ctx->ciphMeth->encryptBlock(ctx->ciphCtx, ctx->iv, ctx->last, GCM_BLOCKSIZE);
308 if (enc) {
309 GcmXorInEncrypt(&data, remLen);
310 } else {
311 GcmXorInDecrypt(&data, remLen);
312 }
313 /**
314 * NIST_800-38D-7.1
315 * INC32
316 */
317 ctr++;
318 PUT_UINT32_BE(ctr, ctx->iv, 12); // Offset of 12 bytes. Use the last four bytes.
319 // Clear sensitive information.
320 BSL_SAL_CleanseData(&ctr, sizeof(uint32_t));
321 }
322 ctx->lastLen = (remLen > 0) ? (GCM_BLOCKSIZE - remLen) : 0;
323
324 return CRYPT_SUCCESS;
325 }
326
GcmPad(MODES_CipherGCMCtx * ctx)327 static void GcmPad(MODES_CipherGCMCtx *ctx)
328 {
329 // S = GHASHH (A || 0v || C || 0u || [len(A)]64 || [len(C)]64).
330 if (ctx->lastLen != 0) {
331 uint32_t offset = GCM_BLOCKSIZE - ctx->lastLen;
332 (void)memset_s(ctx->remCt + offset, GCM_BLOCKSIZE - offset, 0, ctx->lastLen);
333 GcmHashMultiBlock(ctx->ghash, ctx->hTable, ctx->remCt, GCM_BLOCKSIZE);
334 }
335 uint64_t aadLen = (uint64_t)(ctx->aadLen) << 3; // bitLen = byteLen << 3
336 uint64_t plaintextLen = ctx->plaintextLen << 3; // bitLen = byteLen << 3
337 uint8_t padBuf[GCM_BLOCKSIZE];
338 Uint64ToBeBytes(aadLen, padBuf);
339 Uint64ToBeBytes(plaintextLen, padBuf + 8); // The last 64 bits (8 bytes) is the length of the ciphertext.
340
341 GcmHashMultiBlock(ctx->ghash, ctx->hTable, padBuf, GCM_BLOCKSIZE);
342 }
343
SetTagLen(MODES_CipherGCMCtx * ctx,const uint8_t * val,uint32_t len)344 static int32_t SetTagLen(MODES_CipherGCMCtx *ctx, const uint8_t *val, uint32_t len)
345 {
346 if (val == NULL) {
347 BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
348 return CRYPT_NULL_INPUT;
349 }
350 if (len != sizeof(uint32_t)) {
351 BSL_ERR_PUSH_ERROR(CRYPT_MODES_CTRL_TAGLEN_ERROR);
352 return CRYPT_MODES_CTRL_TAGLEN_ERROR;
353 }
354 /**
355 * NIST_800-38D-5.2.1.2
356 * The bit length of the tag, denoted t, is a security parameter, as discussed in Appendix B.
357 * In general, t may be any one of the following five values: 128, 120, 112, 104, or 96. For certain
358 * applications, t may be 64 or 32; guidance for the use of these two tag lengths, including
359 * requirements on the length of the input data and the lifetime of the ciphCtx in these cases,
360 * is given in Appendix C
361 */
362 uint32_t tagLen = *((const uint32_t *)val);
363 // 32bit is 4 bytes, 64bit is 8 bytes, 128, 120, 112, 104, or 96 is 12byte - 16byte
364 if (tagLen == 4 || tagLen == 8 || (tagLen >= 12 && tagLen <= 16)) {
365 ctx->tagLen = (uint8_t)tagLen;
366 return CRYPT_SUCCESS;
367 }
368 BSL_ERR_PUSH_ERROR(CRYPT_MODES_CTRL_TAGLEN_ERROR);
369 return CRYPT_MODES_CTRL_TAGLEN_ERROR;
370 }
371
GetTag(MODES_CipherGCMCtx * ctx,uint8_t * val,uint32_t len)372 static int32_t GetTag(MODES_CipherGCMCtx *ctx, uint8_t *val, uint32_t len)
373 {
374 if (val == NULL) {
375 BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
376 return CRYPT_NULL_INPUT;
377 }
378 if (len != ctx->tagLen) {
379 BSL_ERR_PUSH_ERROR(CRYPT_MODES_TAGLEN_ERROR);
380 return CRYPT_MODES_TAGLEN_ERROR;
381 }
382 ctx->cryptCnt++; // The encryption/decryption process ends. Key usage times + 1
383 GcmPad(ctx);
384 uint32_t i;
385 for (i = 0; i < len; i++) {
386 val[i] = ctx->ghash[i] ^ ctx->ek0[i];
387 }
388 return CRYPT_SUCCESS;
389 }
390
MODES_GCM_Encrypt(MODES_CipherGCMCtx * ctx,const uint8_t * in,uint8_t * out,uint32_t len)391 int32_t MODES_GCM_Encrypt(MODES_CipherGCMCtx *ctx, const uint8_t *in, uint8_t *out, uint32_t len)
392 {
393 return MODES_GCM_Crypt(ctx, in, out, len, true);
394 }
395
MODES_GCM_Decrypt(MODES_CipherGCMCtx * ctx,const uint8_t * in,uint8_t * out,uint32_t len)396 int32_t MODES_GCM_Decrypt(MODES_CipherGCMCtx *ctx, const uint8_t *in, uint8_t *out, uint32_t len)
397 {
398 return MODES_GCM_Crypt(ctx, in, out, len, false);
399 }
400
MODES_GCM_Ctrl(MODES_GCM_Ctx * modeCtx,int32_t opt,void * val,uint32_t len)401 int32_t MODES_GCM_Ctrl(MODES_GCM_Ctx *modeCtx, int32_t opt, void *val, uint32_t len)
402 {
403 if (modeCtx == NULL) {
404 return CRYPT_NULL_INPUT;
405 }
406 switch (opt) {
407 case CRYPT_CTRL_SET_IV:
408 case CRYPT_CTRL_REINIT_STATUS:
409 return MODES_GCM_SetIv(&modeCtx->gcmCtx, val, len);
410 case CRYPT_CTRL_SET_TAGLEN:
411 return SetTagLen(&modeCtx->gcmCtx, val, len);
412 case CRYPT_CTRL_SET_AAD:
413 return SetAad(&modeCtx->gcmCtx, val, len);
414 case CRYPT_CTRL_GET_TAG:
415 return GetTag(&modeCtx->gcmCtx, val, len);
416 case CRYPT_CTRL_GET_BLOCKSIZE:
417 if (val == NULL || len != sizeof(uint32_t)) {
418 return CRYPT_INVALID_ARG;
419 }
420 *(int32_t *)val = 1;
421 return CRYPT_SUCCESS;
422 default:
423 BSL_ERR_PUSH_ERROR(CRYPT_MODES_CTRL_TYPE_ERROR);
424 return CRYPT_MODES_CTRL_TYPE_ERROR;
425 }
426 }
427
MODES_GCM_NewCtx(int32_t algId)428 MODES_GCM_Ctx *MODES_GCM_NewCtx(int32_t algId)
429 {
430 const EAL_SymMethod *method = EAL_GetSymMethod(algId);
431 if (method == NULL) {
432 BSL_ERR_PUSH_ERROR(CRYPT_INVALID_ARG);
433 return NULL;
434 }
435 MODES_GCM_Ctx *ctx = BSL_SAL_Calloc(1, sizeof(MODES_GCM_Ctx));
436 if (ctx == NULL) {
437 BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL);
438 return ctx;
439 }
440 ctx->algId = algId;
441
442 ctx->gcmCtx.ciphCtx = BSL_SAL_Calloc(1, method->ctxSize);
443 if (ctx->gcmCtx.ciphCtx == NULL) {
444 BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL);
445 BSL_SAL_Free(ctx);
446 return NULL;
447 }
448
449 ctx->gcmCtx.ciphMeth = method;
450 return ctx;
451 }
452
MODES_GCM_InitCtx(MODES_GCM_Ctx * modeCtx,const uint8_t * key,uint32_t keyLen,const uint8_t * iv,uint32_t ivLen,bool enc)453 int32_t MODES_GCM_InitCtx(MODES_GCM_Ctx *modeCtx, const uint8_t *key, uint32_t keyLen, const uint8_t *iv,
454 uint32_t ivLen, bool enc)
455 {
456 if (modeCtx == NULL) {
457 BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
458 return CRYPT_NULL_INPUT;
459 }
460 int32_t ret = MODES_GCM_SetKey(&modeCtx->gcmCtx, key, keyLen);
461 if (ret != CRYPT_SUCCESS) {
462 return ret;
463 }
464
465 ret = MODES_GCM_SetIv(&modeCtx->gcmCtx, iv, ivLen);
466 if (ret != CRYPT_SUCCESS) {
467 (void)MODES_GCM_DeInitCtx(modeCtx);
468 return ret;
469 }
470 modeCtx->enc = enc;
471 return ret;
472 }
473
MODES_GCM_Update(MODES_GCM_Ctx * modeCtx,const uint8_t * in,uint32_t inLen,uint8_t * out,uint32_t * outLen)474 int32_t MODES_GCM_Update(MODES_GCM_Ctx *modeCtx, const uint8_t *in, uint32_t inLen, uint8_t *out, uint32_t *outLen)
475 {
476 return MODES_CipherStreamProcess(modeCtx->enc ? MODES_GCM_Encrypt : MODES_GCM_Decrypt, &modeCtx->gcmCtx,
477 in, inLen, out, outLen);
478 }
479
MODES_GCM_Final(MODES_GCM_Ctx * modeCtx,uint8_t * out,uint32_t * outLen)480 int32_t MODES_GCM_Final(MODES_GCM_Ctx *modeCtx, uint8_t *out, uint32_t *outLen)
481 {
482 (void) modeCtx;
483 (void) out;
484 (void) outLen;
485 return CRYPT_EAL_CIPHER_FINAL_WITH_AEAD_ERROR;
486 }
487
MODES_GCM_DeInitCtx(MODES_GCM_Ctx * modeCtx)488 int32_t MODES_GCM_DeInitCtx(MODES_GCM_Ctx *modeCtx)
489 {
490 if (modeCtx == NULL) {
491 BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
492 return CRYPT_NULL_INPUT;
493 }
494 int32_t algId = modeCtx->algId;
495 void *ciphCtx = modeCtx->gcmCtx.ciphCtx;
496 const EAL_SymMethod *ciphMeth = modeCtx->gcmCtx.ciphMeth;
497 modeCtx->gcmCtx.ciphMeth->cipherDeInitCtx(ciphCtx);
498 BSL_SAL_CleanseData((void *)(&(modeCtx->gcmCtx)), sizeof(MODES_CipherGCMCtx));
499 modeCtx->gcmCtx.ciphCtx = ciphCtx;
500 modeCtx->gcmCtx.ciphMeth = ciphMeth;
501 modeCtx->algId = algId;
502 return CRYPT_SUCCESS;
503 }
504
MODES_GCM_FreeCtx(MODES_GCM_Ctx * modeCtx)505 void MODES_GCM_FreeCtx(MODES_GCM_Ctx *modeCtx)
506 {
507 if (modeCtx == NULL) {
508 return;
509 }
510 (void)BSL_SAL_ClearFree(modeCtx->gcmCtx.ciphCtx, modeCtx->gcmCtx.ciphMeth->ctxSize);
511 (void)BSL_SAL_CleanseData(modeCtx, sizeof(MODES_GCM_Ctx));
512 BSL_SAL_Free(modeCtx);
513 }
514
515
MODES_GCM_InitCtxEx(MODES_GCM_Ctx * modeCtx,const uint8_t * key,uint32_t keyLen,const uint8_t * iv,uint32_t ivLen,void * param,bool enc)516 int32_t MODES_GCM_InitCtxEx(MODES_GCM_Ctx *modeCtx, const uint8_t *key, uint32_t keyLen, const uint8_t *iv,
517 uint32_t ivLen, void *param, bool enc)
518 {
519 (void)param;
520 if (modeCtx == NULL) {
521 BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
522 return CRYPT_NULL_INPUT;
523 }
524 switch (modeCtx->algId) {
525 case CRYPT_CIPHER_SM4_GCM:
526 #ifdef HITLS_CRYPTO_SM4
527 return SM4_GCM_InitCtx(modeCtx, key, keyLen, iv, ivLen, enc);
528 #else
529 return CRYPT_EAL_ALG_NOT_SUPPORT;
530 #endif
531 default:
532 return MODES_GCM_InitCtx(modeCtx, key, keyLen, iv, ivLen, enc);
533 }
534 }
535
MODES_GCM_UpdateEx(MODES_GCM_Ctx * modeCtx,const uint8_t * in,uint32_t inLen,uint8_t * out,uint32_t * outLen)536 int32_t MODES_GCM_UpdateEx(MODES_GCM_Ctx *modeCtx, const uint8_t *in, uint32_t inLen, uint8_t *out, uint32_t *outLen)
537 {
538 if (modeCtx == NULL) {
539 BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
540 return CRYPT_NULL_INPUT;
541 }
542 switch (modeCtx->algId) {
543 case CRYPT_CIPHER_AES128_GCM:
544 case CRYPT_CIPHER_AES192_GCM:
545 case CRYPT_CIPHER_AES256_GCM:
546 #ifdef HITLS_CRYPTO_AES
547 return AES_GCM_Update(modeCtx, in, inLen, out, outLen);
548 #else
549 return CRYPT_EAL_ALG_NOT_SUPPORT;
550 #endif
551 case CRYPT_CIPHER_SM4_GCM:
552 #ifdef HITLS_CRYPTO_SM4
553 return SM4_GCM_Update(modeCtx, in, inLen, out, outLen);
554 #else
555 return CRYPT_EAL_ALG_NOT_SUPPORT;
556 #endif
557 default:
558 return MODES_GCM_Update(modeCtx, in, inLen, out, outLen);
559 }
560 }
561
562 #endif