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_SM4
18
19 #include "crypt_sm4_armv8.h"
20 #include "crypt_sm4.h"
21 #include "bsl_err_internal.h"
22 #include "crypt_errno.h"
23
24 #ifdef HITLS_CRYPTO_XTS
25 // key[0..16]: data key
26 // key[16..32]: tweak key
CRYPT_SM4_XTS_SetEncryptKey(CRYPT_SM4_Ctx * ctx,const uint8_t * key,uint32_t len)27 int32_t CRYPT_SM4_XTS_SetEncryptKey(CRYPT_SM4_Ctx *ctx, const uint8_t *key, uint32_t len)
28 {
29 if (ctx == NULL || key == NULL) {
30 BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
31 return CRYPT_NULL_INPUT;
32 }
33
34 if (len != XTS_KEY_LEN) {
35 BSL_ERR_PUSH_ERROR(CRYPT_SM4_ERR_KEY_LEN);
36 return CRYPT_SM4_ERR_KEY_LEN;
37 }
38
39 if (memcmp(key, key + CRYPT_SM4_BLOCKSIZE, CRYPT_SM4_BLOCKSIZE) == 0) {
40 BSL_ERR_PUSH_ERROR(CRYPT_SM4_UNSAFE_KEY);
41 return CRYPT_SM4_UNSAFE_KEY;
42 }
43 CRYPT_SM4_Ctx *tmk = (CRYPT_SM4_Ctx *)&ctx[1];
44 Vpsm4SetEncryptKey(key, (SM4_KEY *)ctx->rk);
45 Vpsm4SetEncryptKey(key + CRYPT_SM4_BLOCKSIZE, (SM4_KEY *)tmk->rk);
46
47 return CRYPT_SUCCESS;
48 }
49
50 // key[0..16]: data key
51 // key[16..32]: tweak key
CRYPT_SM4_XTS_SetDecryptKey(CRYPT_SM4_Ctx * ctx,const uint8_t * key,uint32_t len)52 int32_t CRYPT_SM4_XTS_SetDecryptKey(CRYPT_SM4_Ctx *ctx, const uint8_t *key, uint32_t len)
53 {
54 if (ctx == NULL || key == NULL) {
55 BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
56 return CRYPT_NULL_INPUT;
57 }
58
59 if (len != XTS_KEY_LEN) {
60 BSL_ERR_PUSH_ERROR(CRYPT_SM4_ERR_KEY_LEN);
61 return CRYPT_SM4_ERR_KEY_LEN;
62 }
63
64 if (memcmp(key, key + CRYPT_SM4_BLOCKSIZE, CRYPT_SM4_BLOCKSIZE) == 0) {
65 BSL_ERR_PUSH_ERROR(CRYPT_SM4_UNSAFE_KEY);
66 return CRYPT_SM4_UNSAFE_KEY;
67 }
68 CRYPT_SM4_Ctx *tmk = (CRYPT_SM4_Ctx *)&ctx[1];
69 Vpsm4SetDecryptKey(key, (SM4_KEY *)ctx->rk);
70 Vpsm4SetEncryptKey(key + CRYPT_SM4_BLOCKSIZE, (SM4_KEY *)tmk->rk);
71
72 return CRYPT_SUCCESS;
73 }
74
CRYPT_SM4_XTS_Encrypt(CRYPT_SM4_Ctx * ctx,const uint8_t * in,uint8_t * out,uint32_t len,uint8_t * iv)75 int32_t CRYPT_SM4_XTS_Encrypt(CRYPT_SM4_Ctx *ctx, const uint8_t *in, uint8_t *out, uint32_t len, uint8_t *iv)
76 {
77 CRYPT_SM4_Ctx *tmk = NULL;
78 if (ctx == NULL || iv == NULL) {
79 BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
80 return CRYPT_NULL_INPUT;
81 }
82
83 if (len < CRYPT_SM4_BLOCKSIZE) {
84 BSL_ERR_PUSH_ERROR(CRYPT_SM4_ERR_MSG_LEN);
85 return CRYPT_SM4_ERR_MSG_LEN;
86 }
87 tmk = (CRYPT_SM4_Ctx *)&ctx[1];
88 Vpsm4XtsCipher(in, out, len, (const SM4_KEY *)ctx->rk, (const SM4_KEY *)tmk->rk, iv, 1);
89
90 return CRYPT_SUCCESS;
91 }
92
CRYPT_SM4_XTS_Decrypt(CRYPT_SM4_Ctx * ctx,const uint8_t * in,uint8_t * out,uint32_t len,uint8_t * iv)93 int32_t CRYPT_SM4_XTS_Decrypt(CRYPT_SM4_Ctx *ctx, const uint8_t *in, uint8_t *out, uint32_t len, uint8_t *iv)
94 {
95 CRYPT_SM4_Ctx *tmk = NULL;
96 if (ctx == NULL || iv == NULL) {
97 BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
98 return CRYPT_NULL_INPUT;
99 }
100
101 if (len < CRYPT_SM4_BLOCKSIZE) {
102 BSL_ERR_PUSH_ERROR(CRYPT_SM4_ERR_MSG_LEN);
103 return CRYPT_SM4_ERR_MSG_LEN;
104 }
105 tmk = (CRYPT_SM4_Ctx *)&ctx[1];
106 Vpsm4XtsCipher(in, out, len, (const SM4_KEY *)ctx->rk, (const SM4_KEY *)tmk->rk, iv, 0);
107
108 return CRYPT_SUCCESS;
109 }
110 #endif
111
CRYPT_SM4_SetEncryptKey(CRYPT_SM4_Ctx * ctx,const uint8_t * key,uint32_t len)112 int32_t CRYPT_SM4_SetEncryptKey(CRYPT_SM4_Ctx *ctx, const uint8_t *key, uint32_t len)
113 {
114 if (ctx == NULL || key == NULL) {
115 BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
116 return CRYPT_NULL_INPUT;
117 }
118
119 if (len != SM4_KEY_LEN) {
120 BSL_ERR_PUSH_ERROR(CRYPT_SM4_ERR_KEY_LEN);
121 return CRYPT_SM4_ERR_KEY_LEN;
122 }
123 Vpsm4SetEncryptKey(key, (SM4_KEY *)ctx->rk);
124
125 return CRYPT_SUCCESS;
126 }
127
CRYPT_SM4_SetDecryptKey(CRYPT_SM4_Ctx * ctx,const uint8_t * key,uint32_t len)128 int32_t CRYPT_SM4_SetDecryptKey(CRYPT_SM4_Ctx *ctx, const uint8_t *key, uint32_t len)
129 {
130 if (ctx == NULL || key == NULL) {
131 BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
132 return CRYPT_NULL_INPUT;
133 }
134
135 if (len != SM4_KEY_LEN) {
136 BSL_ERR_PUSH_ERROR(CRYPT_SM4_ERR_KEY_LEN);
137 return CRYPT_SM4_ERR_KEY_LEN;
138 }
139
140 Vpsm4SetDecryptKey(key, (SM4_KEY *)ctx->rk);
141 return CRYPT_SUCCESS;
142 }
143
144 #ifdef HITLS_CRYPTO_ECB
CRYPT_SM4_ECB_Encrypt(CRYPT_SM4_Ctx * ctx,const uint8_t * in,uint8_t * out,uint32_t len)145 int32_t CRYPT_SM4_ECB_Encrypt(CRYPT_SM4_Ctx *ctx, const uint8_t *in, uint8_t *out, uint32_t len)
146 {
147 if (ctx == NULL) {
148 BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
149 return CRYPT_NULL_INPUT;
150 }
151 if (len < CRYPT_SM4_BLOCKSIZE) {
152 BSL_ERR_PUSH_ERROR(CRYPT_SM4_ERR_MSG_LEN);
153 return CRYPT_SM4_ERR_MSG_LEN;
154 }
155 Vpsm4EcbEncrypt(in, out, len, ctx->rk);
156 return CRYPT_SUCCESS;
157 }
158
CRYPT_SM4_ECB_Decrypt(CRYPT_SM4_Ctx * ctx,const uint8_t * in,uint8_t * out,uint32_t len)159 int32_t CRYPT_SM4_ECB_Decrypt(CRYPT_SM4_Ctx *ctx, const uint8_t *in, uint8_t *out, uint32_t len)
160 {
161 if (ctx == NULL) {
162 BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
163 return CRYPT_NULL_INPUT;
164 }
165 if (len < CRYPT_SM4_BLOCKSIZE) {
166 BSL_ERR_PUSH_ERROR(CRYPT_SM4_ERR_MSG_LEN);
167 return CRYPT_SM4_ERR_MSG_LEN;
168 }
169 Vpsm4EcbEncrypt(in, out, len, ctx->rk);
170 return CRYPT_SUCCESS;
171 }
172 #endif
173
174 #ifdef HITLS_CRYPTO_CBC
CRYPT_SM4_CBC_Encrypt(CRYPT_SM4_Ctx * ctx,const uint8_t * in,uint8_t * out,uint32_t len,uint8_t * iv)175 int32_t CRYPT_SM4_CBC_Encrypt(CRYPT_SM4_Ctx *ctx, const uint8_t *in, uint8_t *out, uint32_t len, uint8_t *iv)
176 {
177 if (ctx == NULL) {
178 BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
179 return CRYPT_NULL_INPUT;
180 }
181 if (len % CRYPT_SM4_BLOCKSIZE != 0) {
182 BSL_ERR_PUSH_ERROR(CRYPT_SM4_ERR_MSG_LEN);
183 return CRYPT_SM4_ERR_MSG_LEN;
184 }
185 Vpsm4CbcEncrypt(in, out, len, ctx->rk, iv, 1);
186 return CRYPT_SUCCESS;
187 }
188
CRYPT_SM4_CBC_Decrypt(CRYPT_SM4_Ctx * ctx,const uint8_t * in,uint8_t * out,uint32_t len,uint8_t * iv)189 int32_t CRYPT_SM4_CBC_Decrypt(CRYPT_SM4_Ctx *ctx, const uint8_t *in, uint8_t *out, uint32_t len, uint8_t *iv)
190 {
191 if (ctx == NULL) {
192 BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
193 return CRYPT_NULL_INPUT;
194 }
195 if (len % CRYPT_SM4_BLOCKSIZE != 0) {
196 BSL_ERR_PUSH_ERROR(CRYPT_SM4_ERR_MSG_LEN);
197 return CRYPT_SM4_ERR_MSG_LEN;
198 }
199 Vpsm4CbcEncrypt(in, out, len, ctx->rk, iv, 0);
200 return CRYPT_SUCCESS;
201 }
202 #endif // HITLS_CRYPTO_CBC
203
204 #ifdef HITLS_CRYPTO_CFB
CRYPT_SM4_CFB_Encrypt(CRYPT_SM4_Ctx * ctx,const uint8_t * in,uint8_t * out,uint32_t len,uint8_t * iv,uint8_t * offset)205 int32_t CRYPT_SM4_CFB_Encrypt(CRYPT_SM4_Ctx *ctx, const uint8_t *in, uint8_t *out, uint32_t len,
206 uint8_t *iv, uint8_t *offset)
207 {
208 if (ctx == NULL) {
209 BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
210 return CRYPT_NULL_INPUT;
211 }
212 int tmp = *offset;
213 Vpsm4Cfb128Encrypt(in, out, len, ctx->rk, iv, &tmp);
214 *offset = (uint8_t)tmp;
215 return CRYPT_SUCCESS;
216 }
217
CRYPT_SM4_CFB_Decrypt(CRYPT_SM4_Ctx * ctx,const uint8_t * in,uint8_t * out,uint32_t len,uint8_t * iv,uint8_t * offset)218 int32_t CRYPT_SM4_CFB_Decrypt(CRYPT_SM4_Ctx *ctx, const uint8_t *in, uint8_t *out, uint32_t len,
219 uint8_t *iv, uint8_t *offset)
220 {
221 if (ctx == NULL) {
222 BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
223 return CRYPT_NULL_INPUT;
224 }
225 int tmp = *offset;
226 Vpsm4Cfb128Decrypt(in, out, len, ctx->rk, iv, &tmp);
227 *offset = (uint8_t)tmp;
228 return CRYPT_SUCCESS;
229 }
230 #endif
231
232 #if defined(HITLS_CRYPTO_CTR) || defined(HITLS_CRYPTO_GCM)
CRYPT_SM4_CTR_Encrypt(CRYPT_SM4_Ctx * ctx,const uint8_t * in,uint8_t * out,uint32_t len,uint8_t * iv)233 int32_t CRYPT_SM4_CTR_Encrypt(CRYPT_SM4_Ctx *ctx, const uint8_t *in, uint8_t *out, uint32_t len, uint8_t *iv)
234 {
235 if (ctx == NULL) {
236 BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
237 return CRYPT_NULL_INPUT;
238 }
239 Vpsm4Ctr32EncryptBlocks(in, out, len, ctx->rk, iv);
240 return CRYPT_SUCCESS;
241 }
242
CRYPT_SM4_CTR_Decrypt(CRYPT_SM4_Ctx * ctx,const uint8_t * in,uint8_t * out,uint32_t len,uint8_t * iv)243 int32_t CRYPT_SM4_CTR_Decrypt(CRYPT_SM4_Ctx *ctx, const uint8_t *in, uint8_t *out, uint32_t len, uint8_t *iv)
244 {
245 if (ctx == NULL) {
246 BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
247 return CRYPT_NULL_INPUT;
248 }
249 Vpsm4Ctr32EncryptBlocks(in, out, len, ctx->rk, iv);
250 return CRYPT_SUCCESS;
251 }
252 #endif
253
254 #endif // HITLS_CRYPTO_SM4
255