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_SM3
18
19 #include <stdlib.h>
20 #include <stdint.h>
21 #include "securec.h"
22 #include "crypt_errno.h"
23 #include "crypt_utils.h"
24 #include "bsl_err_internal.h"
25 #include "crypt_sm3.h"
26 #include "sm3_local.h"
27 #include "bsl_sal.h"
28 #include "crypt_types.h"
29
30 struct CryptSm3Ctx {
31 uint32_t h[CRYPT_SM3_DIGESTSIZE / sizeof(uint32_t)]; /* store the intermediate data of the hash value */
32 uint32_t hNum, lNum; /* input data counter, maximum value 2 ^ 64 bits */
33 uint8_t block[CRYPT_SM3_BLOCKSIZE]; /* store the remaining data which less than one block */
34 /* Number of remaining bytes in 'block' arrary that are stored less than one block */
35 uint32_t num;
36 };
37
CRYPT_SM3_NewCtx(void)38 CRYPT_SM3_Ctx *CRYPT_SM3_NewCtx(void)
39 {
40 return BSL_SAL_Calloc(1, sizeof(CRYPT_SM3_Ctx));
41 }
42
CRYPT_SM3_FreeCtx(CRYPT_SM3_Ctx * ctx)43 void CRYPT_SM3_FreeCtx(CRYPT_SM3_Ctx *ctx)
44 {
45 BSL_SAL_ClearFree(ctx, sizeof(CRYPT_SM3_Ctx));
46 }
47
CRYPT_SM3_Init(CRYPT_SM3_Ctx * ctx,BSL_Param * param)48 int32_t CRYPT_SM3_Init(CRYPT_SM3_Ctx *ctx, BSL_Param *param)
49 {
50 if (ctx == NULL) {
51 BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
52 return CRYPT_NULL_INPUT;
53 }
54 (void) param;
55 (void)memset_s(ctx, sizeof(CRYPT_SM3_Ctx), 0, sizeof(CRYPT_SM3_Ctx));
56 /* GM/T 0004-2012 chapter 4.1 */
57 ctx->h[0] = 0x7380166F;
58 ctx->h[1] = 0x4914B2B9;
59 ctx->h[2] = 0x172442D7;
60 ctx->h[3] = 0xDA8A0600;
61 ctx->h[4] = 0xA96F30BC;
62 ctx->h[5] = 0x163138AA;
63 ctx->h[6] = 0xE38DEE4D;
64 ctx->h[7] = 0xB0FB0E4E;
65 return CRYPT_SUCCESS;
66 }
67
CRYPT_SM3_Deinit(CRYPT_SM3_Ctx * ctx)68 void CRYPT_SM3_Deinit(CRYPT_SM3_Ctx *ctx)
69 {
70 if (ctx == NULL) {
71 BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
72 return;
73 }
74 (void)memset_s(ctx, sizeof(CRYPT_SM3_Ctx), 0, sizeof(CRYPT_SM3_Ctx));
75 }
76
IsInputOverflow(CRYPT_SM3_Ctx * ctx,uint32_t nbytes)77 static uint32_t IsInputOverflow(CRYPT_SM3_Ctx *ctx, uint32_t nbytes)
78 {
79 uint32_t cnt0 = ctx->lNum + (nbytes << SHIFTS_PER_BYTE);
80 if (cnt0 < ctx->lNum) {
81 if (++ctx->hNum == 0) {
82 BSL_ERR_PUSH_ERROR(CRYPT_SM3_INPUT_OVERFLOW);
83 return CRYPT_SM3_INPUT_OVERFLOW;
84 }
85 }
86 uint32_t cnt1 = ctx->hNum + (uint32_t)(nbytes >> (BITSIZE(uint32_t) - SHIFTS_PER_BYTE));
87 if (cnt1 < ctx->hNum) {
88 BSL_ERR_PUSH_ERROR(CRYPT_SM3_INPUT_OVERFLOW);
89 return CRYPT_SM3_INPUT_OVERFLOW;
90 }
91 ctx->hNum = cnt1;
92 ctx->lNum = cnt0;
93 return CRYPT_SUCCESS;
94 }
95
IsUpdateParamValid(CRYPT_SM3_Ctx * ctx,const uint8_t * in,uint32_t len)96 static int32_t IsUpdateParamValid(CRYPT_SM3_Ctx *ctx, const uint8_t *in, uint32_t len)
97 {
98 if ((ctx == NULL) || (in == NULL && len != 0)) {
99 BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
100 return CRYPT_NULL_INPUT;
101 }
102
103 if (IsInputOverflow(ctx, len) != CRYPT_SUCCESS) {
104 BSL_ERR_PUSH_ERROR(CRYPT_SM3_INPUT_OVERFLOW);
105 return CRYPT_SM3_INPUT_OVERFLOW;
106 }
107
108 return CRYPT_SUCCESS;
109 }
110
CRYPT_SM3_Update(CRYPT_SM3_Ctx * ctx,const uint8_t * in,uint32_t len)111 int32_t CRYPT_SM3_Update(CRYPT_SM3_Ctx *ctx, const uint8_t *in, uint32_t len)
112 {
113 int32_t ret = IsUpdateParamValid(ctx, in, len);
114 if (ret != CRYPT_SUCCESS) {
115 return ret;
116 }
117
118 if (len == 0) {
119 return CRYPT_SUCCESS;
120 }
121
122 const uint8_t *data = in;
123 uint32_t dataLen = len;
124 uint32_t left = CRYPT_SM3_BLOCKSIZE - ctx->num;
125
126 if (ctx->num != 0) {
127 if (dataLen < left) {
128 (void)memcpy_s(ctx->block + ctx->num, left, data, dataLen);
129 ctx->num += dataLen;
130 return CRYPT_SUCCESS;
131 }
132 // When the external input data is greater than the remaining space of the block,
133 // copy the data which is the same length as the remaining space.
134 (void)memcpy_s(ctx->block + ctx->num, left, data, left);
135 SM3_Compress(ctx->h, ctx->block, 1);
136 dataLen -= left;
137 data += left;
138 ctx->num = 0;
139 }
140
141 uint32_t blockCnt = dataLen / CRYPT_SM3_BLOCKSIZE;
142 if (blockCnt > 0) {
143 SM3_Compress(ctx->h, data, blockCnt);
144 blockCnt *= CRYPT_SM3_BLOCKSIZE;
145 data += blockCnt;
146 dataLen -= blockCnt;
147 }
148
149 if (dataLen != 0) {
150 // copy the remaining data to the cache array
151 (void)memcpy_s(ctx->block, CRYPT_SM3_BLOCKSIZE, data, dataLen);
152 ctx->num = dataLen;
153 }
154
155 return CRYPT_SUCCESS;
156 }
157
IsFinalParamValid(const CRYPT_SM3_Ctx * ctx,const uint8_t * out,const uint32_t * outLen)158 static int32_t IsFinalParamValid(const CRYPT_SM3_Ctx *ctx, const uint8_t *out, const uint32_t *outLen)
159 {
160 if ((ctx == NULL) || (out == NULL) || (outLen == NULL)) {
161 BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
162 return CRYPT_NULL_INPUT;
163 }
164
165 if (*outLen < CRYPT_SM3_DIGESTSIZE) {
166 BSL_ERR_PUSH_ERROR(CRYPT_SM3_OUT_BUFF_LEN_NOT_ENOUGH);
167 return CRYPT_SM3_OUT_BUFF_LEN_NOT_ENOUGH;
168 }
169
170 return CRYPT_SUCCESS;
171 }
172
CRYPT_SM3_Final(CRYPT_SM3_Ctx * ctx,uint8_t * out,uint32_t * outLen)173 int32_t CRYPT_SM3_Final(CRYPT_SM3_Ctx *ctx, uint8_t *out, uint32_t *outLen)
174 {
175 int32_t ret = IsFinalParamValid(ctx, out, outLen);
176 if (ret != CRYPT_SUCCESS) {
177 return ret;
178 }
179
180 ctx->block[ctx->num++] = 0x80; /* 0x80 means add '1' to the end of the message */
181 uint8_t *block = ctx->block;
182 uint32_t num = ctx->num;
183 uint32_t left = CRYPT_SM3_BLOCKSIZE - num;
184 if (left < 8) { /* less than 8 bytes which insufficient for storing data length data */
185 (void)memset_s(block + num, left, 0, left);
186 SM3_Compress(ctx->h, ctx->block, 1);
187 num = 0;
188 left = CRYPT_SM3_BLOCKSIZE;
189 }
190 (void)memset_s(block + num, left - 8, 0, left - 8);
191 block += CRYPT_SM3_BLOCKSIZE - 8;
192 PUT_UINT32_BE(ctx->hNum, block, 0);
193 block += sizeof(uint32_t);
194 PUT_UINT32_BE(ctx->lNum, block, 0);
195 SM3_Compress(ctx->h, ctx->block, 1);
196 ctx->num = 0;
197
198 PUT_UINT32_BE(ctx->h[0], out, 0);
199 PUT_UINT32_BE(ctx->h[1], out, 4);
200 PUT_UINT32_BE(ctx->h[2], out, 8);
201 PUT_UINT32_BE(ctx->h[3], out, 12);
202 PUT_UINT32_BE(ctx->h[4], out, 16);
203 PUT_UINT32_BE(ctx->h[5], out, 20);
204 PUT_UINT32_BE(ctx->h[6], out, 24);
205 PUT_UINT32_BE(ctx->h[7], out, 28);
206 *outLen = CRYPT_SM3_DIGESTSIZE;
207
208 return CRYPT_SUCCESS;
209 }
210
CRYPT_SM3_CopyCtx(CRYPT_SM3_Ctx * dst,const CRYPT_SM3_Ctx * src)211 int32_t CRYPT_SM3_CopyCtx(CRYPT_SM3_Ctx *dst, const CRYPT_SM3_Ctx *src)
212 {
213 if (dst == NULL || src == NULL) {
214 BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
215 return CRYPT_NULL_INPUT;
216 }
217
218 (void)memcpy_s(dst, sizeof(CRYPT_SM3_Ctx), src, sizeof(CRYPT_SM3_Ctx));
219 return CRYPT_SUCCESS;
220 }
221
CRYPT_SM3_DupCtx(const CRYPT_SM3_Ctx * src)222 CRYPT_SM3_Ctx *CRYPT_SM3_DupCtx(const CRYPT_SM3_Ctx *src)
223 {
224 if (src == NULL) {
225 BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
226 return NULL;
227 }
228 CRYPT_SM3_Ctx *newCtx = CRYPT_SM3_NewCtx();
229 if (newCtx == NULL) {
230 BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL);
231 return NULL;
232 }
233 (void)memcpy_s(newCtx, sizeof(CRYPT_SM3_Ctx), src, sizeof(CRYPT_SM3_Ctx));
234 return newCtx;
235 }
236
237 #endif /* HITLS_CRYPTO_SM3 */
238