• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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