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_CTR
18
19 #include "securec.h"
20 #include "bsl_err_internal.h"
21 #include "crypt_utils.h"
22 #include "crypt_errno.h"
23 #include "crypt_modes_ctr.h"
24 #include "modes_local.h"
25
MODES_CTR_LastHandle(MODES_CipherCommonCtx * ctx,const uint8_t * in,uint8_t * out,uint32_t len)26 uint32_t MODES_CTR_LastHandle(MODES_CipherCommonCtx *ctx, const uint8_t *in, uint8_t *out, uint32_t len)
27 {
28 uint32_t left = len;
29 uint32_t blockSize = ctx->blockSize;
30 const uint8_t *tmpIn = in;
31 uint8_t *tmpOut = out;
32 // buf[0, ctx->offset, blockSize)
33 // The data from st to blockSize - 1 is the data obtained after the last encryption and is not used up.
34 while ((ctx->offset != 0) && (left > 0)) {
35 *(tmpOut++) = ((*(tmpIn++)) ^ (ctx->buf[ctx->offset++]));
36 --left;
37 // & (blockSize - 1) is equivalent to mod blockSize.
38 ctx->offset &= (uint8_t)(blockSize - 1);
39 }
40 // Return the calculated length.
41 return (len - left);
42 }
43
MODES_CTR_RemHandle(MODES_CipherCommonCtx * ctx,const uint8_t * in,uint8_t * out,uint32_t len)44 void MODES_CTR_RemHandle(MODES_CipherCommonCtx *ctx, const uint8_t *in, uint8_t *out, uint32_t len)
45 {
46 if (len == 0) {
47 return;
48 }
49 uint32_t left = len;
50 uint32_t blockSize = ctx->blockSize;
51 const uint8_t *tmpIn = in;
52 uint8_t *tmpOut = out;
53 // Ensure that the length of IV is 16 when setting it, which will not cause encryption failures.
54 // To optimize performance, the function does not determine the length of the IV.
55 (void)ctx->ciphMeth->encryptBlock(ctx->ciphCtx, ctx->iv, ctx->buf, blockSize);
56 MODE_IncCounter(ctx->iv, ctx->blockSize);
57 ctx->offset = 0;
58 while ((left) > 0) {
59 tmpOut[ctx->offset] = (tmpIn[ctx->offset]) ^ (ctx->buf[ctx->offset]);
60 --left;
61 ++ctx->offset;
62 }
63 }
64
MODES_CTR_Crypt(MODES_CipherCommonCtx * ctx,const uint8_t * in,uint8_t * out,uint32_t len)65 int32_t MODES_CTR_Crypt(MODES_CipherCommonCtx *ctx, const uint8_t *in, uint8_t *out, uint32_t len)
66 {
67 uint32_t offset = MODES_CTR_LastHandle(ctx, in, out, len);
68 uint32_t left = len - offset;
69 const uint8_t *tmpIn = in + offset;
70 uint8_t *tmpOut = out + offset;
71 uint32_t blockSize = ctx->blockSize;
72
73 while (left >= blockSize) {
74 // Ensure that the length of IV is 16 when setting it, which will not cause encryption failures.
75 // To optimize performance, the function does not determine the length of the IV.
76 (void)ctx->ciphMeth->encryptBlock(ctx->ciphCtx, ctx->iv, ctx->buf, blockSize);
77 MODE_IncCounter(ctx->iv, ctx->blockSize);
78 DATA64_XOR(tmpIn, ctx->buf, tmpOut, blockSize);
79 left -= blockSize;
80 tmpOut += blockSize;
81 tmpIn += blockSize;
82 }
83
84 MODES_CTR_RemHandle(ctx, tmpIn, tmpOut, left);
85
86 return CRYPT_SUCCESS;
87 }
88
MODES_CTR_NewCtx(int32_t algId)89 MODES_CipherCtx *MODES_CTR_NewCtx(int32_t algId)
90 {
91 return MODES_CipherNewCtx(algId);
92 }
93
MODES_CTR_InitCtx(MODES_CipherCtx * modeCtx,const uint8_t * key,uint32_t keyLen,const uint8_t * iv,uint32_t ivLen,bool enc)94 int32_t MODES_CTR_InitCtx(MODES_CipherCtx *modeCtx, const uint8_t *key, uint32_t keyLen, const uint8_t *iv,
95 uint32_t ivLen, bool enc)
96 {
97 return MODES_CipherInitCtx(modeCtx, modeCtx->commonCtx.ciphMeth->setEncryptKey,
98 modeCtx->commonCtx.ciphCtx, key, keyLen, iv, ivLen, enc);
99 }
100
MODES_CTR_Update(MODES_CipherCtx * modeCtx,const uint8_t * in,uint32_t inLen,uint8_t * out,uint32_t * outLen)101 int32_t MODES_CTR_Update(MODES_CipherCtx *modeCtx, const uint8_t *in, uint32_t inLen, uint8_t *out, uint32_t *outLen)
102 {
103 return MODES_CipherStreamProcess(MODES_CTR_Crypt, &modeCtx->commonCtx, in, inLen, out, outLen);
104 }
105
MODES_CTR_Final(MODES_CipherCtx * modeCtx,uint8_t * out,uint32_t * outLen)106 int32_t MODES_CTR_Final(MODES_CipherCtx *modeCtx, uint8_t *out, uint32_t *outLen)
107 {
108 (void) modeCtx;
109 (void) out;
110 *outLen = 0;
111 return CRYPT_SUCCESS;
112 }
113
MODES_CTR_DeInitCtx(MODES_CipherCtx * modeCtx)114 int32_t MODES_CTR_DeInitCtx(MODES_CipherCtx *modeCtx)
115 {
116 return MODES_CipherDeInitCtx(modeCtx);
117 }
118
MODES_CTR_Ctrl(MODES_CipherCtx * modeCtx,int32_t cmd,void * val,uint32_t valLen)119 int32_t MODES_CTR_Ctrl(MODES_CipherCtx *modeCtx, int32_t cmd, void *val, uint32_t valLen)
120 {
121 if (modeCtx == NULL) {
122 BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
123 return CRYPT_NULL_INPUT;
124 }
125 switch (cmd) {
126 case CRYPT_CTRL_GET_BLOCKSIZE:
127 if (val == NULL || valLen != sizeof(uint32_t)) {
128 return CRYPT_INVALID_ARG;
129 }
130 *(int32_t *)val = 1;
131 return CRYPT_SUCCESS;
132 default:
133 return MODES_CipherCtrl(modeCtx, cmd, val, valLen);;
134 }
135 }
136
137
MODES_CTR_FreeCtx(MODES_CipherCtx * modeCtx)138 void MODES_CTR_FreeCtx(MODES_CipherCtx *modeCtx)
139 {
140 MODES_CipherFreeCtx(modeCtx);
141 }
142
MODES_CTR_InitCtxEx(MODES_CipherCtx * modeCtx,const uint8_t * key,uint32_t keyLen,const uint8_t * iv,uint32_t ivLen,void * param,bool enc)143 int32_t MODES_CTR_InitCtxEx(MODES_CipherCtx *modeCtx, const uint8_t *key, uint32_t keyLen, const uint8_t *iv,
144 uint32_t ivLen, void *param, bool enc)
145 {
146 (void)param;
147 if (modeCtx == NULL) {
148 BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
149 return CRYPT_NULL_INPUT;
150 }
151 switch (modeCtx->algId) {
152 case CRYPT_CIPHER_SM4_CTR:
153 #ifdef HITLS_CRYPTO_SM4
154 return SM4_CTR_InitCtx(modeCtx, key, keyLen, iv, ivLen, enc);
155 #else
156 return CRYPT_EAL_ALG_NOT_SUPPORT;
157 #endif
158 default:
159 return MODES_CTR_InitCtx(modeCtx, key, keyLen, iv, ivLen, enc);
160 }
161 }
162
MODES_CTR_UpdateEx(MODES_CipherCtx * modeCtx,const uint8_t * in,uint32_t inLen,uint8_t * out,uint32_t * outLen)163 int32_t MODES_CTR_UpdateEx(MODES_CipherCtx *modeCtx, const uint8_t *in, uint32_t inLen, uint8_t *out, uint32_t *outLen)
164 {
165 if (modeCtx == NULL) {
166 BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
167 return CRYPT_NULL_INPUT;
168 }
169 switch (modeCtx->algId) {
170 case CRYPT_CIPHER_AES128_CTR:
171 case CRYPT_CIPHER_AES192_CTR:
172 case CRYPT_CIPHER_AES256_CTR:
173 #ifdef HITLS_CRYPTO_AES
174 return AES_CTR_Update(modeCtx, in, inLen, out, outLen);
175 #else
176 return CRYPT_EAL_ALG_NOT_SUPPORT;
177 #endif
178 case CRYPT_CIPHER_SM4_CTR:
179 #ifdef HITLS_CRYPTO_SM4
180 return SM4_CTR_Update(modeCtx, in, inLen, out, outLen);
181 #else
182 return CRYPT_EAL_ALG_NOT_SUPPORT;
183 #endif
184 default:
185 return MODES_CTR_Update(modeCtx, in, inLen, out, outLen);
186 }
187 }
188
189 #endif