• 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_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