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_SHA256
18 #include "crypt_sha2.h"
19 #include <stdlib.h>
20 #include "securec.h"
21 #include "crypt_errno.h"
22 #include "crypt_utils.h"
23 #include "bsl_err_internal.h"
24 #include "sha2_core.h"
25 #include "bsl_sal.h"
26 #include "crypt_types.h"
27
28 struct CryptSha256Ctx {
29 uint32_t h[CRYPT_SHA2_256_DIGESTSIZE / sizeof(uint32_t)]; /* 256 bits for SHA256 state */
30 uint32_t block[CRYPT_SHA2_256_BLOCKSIZE / sizeof(uint32_t)]; /* 512 bits block cache */
31 uint32_t lNum, hNum; /* input bits counter, max 2^64 bits */
32 uint32_t blocklen; /* block length */
33 uint32_t outlen; /* digest output length */
34 uint32_t errorCode; /* error Code */
35 };
36
CRYPT_SHA2_256_NewCtx(void)37 CRYPT_SHA2_256_Ctx *CRYPT_SHA2_256_NewCtx(void)
38 {
39 return BSL_SAL_Calloc(1, sizeof(CRYPT_SHA2_256_Ctx));
40 }
41
CRYPT_SHA2_256_FreeCtx(CRYPT_SHA2_256_Ctx * ctx)42 void CRYPT_SHA2_256_FreeCtx(CRYPT_SHA2_256_Ctx *ctx)
43 {
44 CRYPT_SHA2_256_Ctx *mdCtx = ctx;
45 if (mdCtx == NULL) {
46 return;
47 }
48 BSL_SAL_ClearFree(ctx, sizeof(CRYPT_SHA2_256_Ctx));
49 }
50
CRYPT_SHA2_256_Init(CRYPT_SHA2_256_Ctx * ctx,BSL_Param * param)51 int32_t CRYPT_SHA2_256_Init(CRYPT_SHA2_256_Ctx *ctx, BSL_Param *param)
52 {
53 if (ctx == NULL) {
54 BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
55 return CRYPT_NULL_INPUT;
56 }
57 (void) param;
58 (void)memset_s(ctx, sizeof(CRYPT_SHA2_256_Ctx), 0, sizeof(CRYPT_SHA2_256_Ctx));
59 /**
60 * @RFC 4634 6.1 SHA-224 and SHA-256 Initialization
61 * SHA-256, the initial hash value, H(0):
62 * H(0)0 = 6a09e667
63 * H(0)1 = bb67ae85
64 * H(0)2 = 3c6ef372
65 * H(0)3 = a54ff53a
66 * H(0)4 = 510e527f
67 * H(0)5 = 9b05688c
68 * H(0)6 = 1f83d9ab
69 * H(0)7 = 5be0cd19
70 */
71 ctx->h[0] = 0x6a09e667UL;
72 ctx->h[1] = 0xbb67ae85UL;
73 ctx->h[2] = 0x3c6ef372UL;
74 ctx->h[3] = 0xa54ff53aUL;
75 ctx->h[4] = 0x510e527fUL;
76 ctx->h[5] = 0x9b05688cUL;
77 ctx->h[6] = 0x1f83d9abUL;
78 ctx->h[7] = 0x5be0cd19UL;
79 ctx->outlen = CRYPT_SHA2_256_DIGESTSIZE;
80 return CRYPT_SUCCESS;
81 }
82
CRYPT_SHA2_256_Deinit(CRYPT_SHA2_256_Ctx * ctx)83 void CRYPT_SHA2_256_Deinit(CRYPT_SHA2_256_Ctx *ctx)
84 {
85 if (ctx == NULL) {
86 return;
87 }
88 BSL_SAL_CleanseData((void *)(ctx), sizeof(CRYPT_SHA2_256_Ctx));
89 }
90
CRYPT_SHA2_256_CopyCtx(CRYPT_SHA2_256_Ctx * dst,const CRYPT_SHA2_256_Ctx * src)91 int32_t CRYPT_SHA2_256_CopyCtx(CRYPT_SHA2_256_Ctx *dst, const CRYPT_SHA2_256_Ctx *src)
92 {
93 if (dst == NULL || src == NULL) {
94 BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
95 return CRYPT_NULL_INPUT;
96 }
97
98 (void)memcpy_s(dst, sizeof(CRYPT_SHA2_256_Ctx), src, sizeof(CRYPT_SHA2_256_Ctx));
99 return CRYPT_SUCCESS;
100 }
101
CRYPT_SHA2_256_DupCtx(const CRYPT_SHA2_256_Ctx * src)102 CRYPT_SHA2_256_Ctx *CRYPT_SHA2_256_DupCtx(const CRYPT_SHA2_256_Ctx *src)
103 {
104 if (src == NULL) {
105 BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
106 return NULL;
107 }
108 CRYPT_SHA2_256_Ctx *newCtx = CRYPT_SHA2_256_NewCtx();
109 if (newCtx == NULL) {
110 BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL);
111 return NULL;
112 }
113 (void)memcpy_s(newCtx, sizeof(CRYPT_SHA2_256_Ctx), src, sizeof(CRYPT_SHA2_256_Ctx));
114 return newCtx;
115 }
116
117 static int32_t CheckIsCorrupted(CRYPT_SHA2_256_Ctx *ctx, uint32_t nbytes);
UpdateParamIsValid(CRYPT_SHA2_256_Ctx * ctx,const uint8_t * data,uint32_t nbytes)118 static int32_t UpdateParamIsValid(CRYPT_SHA2_256_Ctx *ctx, const uint8_t *data, uint32_t nbytes)
119 {
120 if ((ctx == NULL) || (data == NULL && nbytes != 0)) {
121 BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
122 return CRYPT_NULL_INPUT;
123 }
124
125 if (ctx->errorCode != CRYPT_SUCCESS) {
126 BSL_ERR_PUSH_ERROR(CRYPT_SHA2_INPUT_OVERFLOW);
127 return CRYPT_SHA2_INPUT_OVERFLOW;
128 }
129
130 if (CheckIsCorrupted(ctx, nbytes) != CRYPT_SUCCESS) {
131 BSL_ERR_PUSH_ERROR(CRYPT_SHA2_INPUT_OVERFLOW);
132 return CRYPT_SHA2_INPUT_OVERFLOW;
133 }
134
135 return CRYPT_SUCCESS;
136 }
137
CheckIsCorrupted(CRYPT_SHA2_256_Ctx * ctx,uint32_t nbytes)138 static int32_t CheckIsCorrupted(CRYPT_SHA2_256_Ctx *ctx, uint32_t nbytes)
139 {
140 uint32_t cnt0 = (ctx->lNum + (nbytes << SHIFTS_PER_BYTE)) & 0xffffffffUL;
141 if (cnt0 < ctx->lNum) { /* overflow */
142 if (++ctx->hNum == 0) {
143 ctx->errorCode = CRYPT_SHA2_INPUT_OVERFLOW;
144 BSL_ERR_PUSH_ERROR(CRYPT_SHA2_INPUT_OVERFLOW);
145 return CRYPT_SHA2_INPUT_OVERFLOW;
146 }
147 }
148 uint32_t cnt1 = ctx->hNum + (uint32_t)(nbytes >> (BITSIZE(uint32_t) - SHIFTS_PER_BYTE));
149 if (cnt1 < ctx->hNum) { /* overflow */
150 ctx->errorCode = CRYPT_SHA2_INPUT_OVERFLOW;
151 BSL_ERR_PUSH_ERROR(CRYPT_SHA2_INPUT_OVERFLOW);
152 return CRYPT_SHA2_INPUT_OVERFLOW;
153 }
154 ctx->hNum = cnt1;
155 ctx->lNum = cnt0;
156 return CRYPT_SUCCESS;
157 }
158
CRYPT_SHA2_256_Update(CRYPT_SHA2_256_Ctx * ctx,const uint8_t * data,uint32_t nbytes)159 int32_t CRYPT_SHA2_256_Update(CRYPT_SHA2_256_Ctx *ctx, const uint8_t *data, uint32_t nbytes)
160 {
161 int32_t ret = UpdateParamIsValid(ctx, data, nbytes);
162 if (ret != CRYPT_SUCCESS) {
163 return ret;
164 }
165
166 if (nbytes == 0) {
167 return CRYPT_SUCCESS;
168 }
169
170 const uint8_t *d = data;
171 uint32_t left = nbytes;
172 uint32_t n = ctx->blocklen;
173 uint8_t *p = (uint8_t *)ctx->block;
174
175 if (left < CRYPT_SHA2_256_BLOCKSIZE - n) {
176 if (memcpy_s(p + n, CRYPT_SHA2_256_BLOCKSIZE - n, d, left) != EOK) {
177 BSL_ERR_PUSH_ERROR(CRYPT_SECUREC_FAIL);
178 return CRYPT_SECUREC_FAIL;
179 }
180 ctx->blocklen += (uint32_t)left;
181 return CRYPT_SUCCESS;
182 }
183 if ((n != 0) && (left >= CRYPT_SHA2_256_BLOCKSIZE - n)) {
184 if (memcpy_s(p + n, CRYPT_SHA2_256_BLOCKSIZE - n, d, CRYPT_SHA2_256_BLOCKSIZE - n) != EOK) {
185 BSL_ERR_PUSH_ERROR(CRYPT_SECUREC_FAIL);
186 return CRYPT_SECUREC_FAIL;
187 }
188 SHA256CompressMultiBlocks(ctx->h, p, 1);
189 n = CRYPT_SHA2_256_BLOCKSIZE - n;
190 d += n;
191 left -= n;
192 ctx->blocklen = 0;
193 (void)memset_s(p, CRYPT_SHA2_256_BLOCKSIZE, 0, CRYPT_SHA2_256_BLOCKSIZE);
194 }
195
196 n = (uint32_t)(left / CRYPT_SHA2_256_BLOCKSIZE);
197 if (n > 0) {
198 SHA256CompressMultiBlocks(ctx->h, d, n);
199 n *= CRYPT_SHA2_256_BLOCKSIZE;
200 d += n;
201 left -= n;
202 }
203
204 if (left != 0) {
205 ctx->blocklen = (uint32_t)left;
206 if (memcpy_s((uint8_t *)ctx->block, CRYPT_SHA2_256_BLOCKSIZE, d, left) != EOK) {
207 BSL_ERR_PUSH_ERROR(CRYPT_SECUREC_FAIL);
208 return CRYPT_SECUREC_FAIL;
209 }
210 }
211
212 return CRYPT_SUCCESS;
213 }
214
FinalParamIsValid(const CRYPT_SHA2_256_Ctx * ctx,const uint8_t * out,const uint32_t * outLen)215 static int32_t FinalParamIsValid(const CRYPT_SHA2_256_Ctx *ctx, const uint8_t *out, const uint32_t *outLen)
216 {
217 if ((ctx == NULL) || (out == NULL) || (outLen == NULL)) {
218 BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
219 return CRYPT_NULL_INPUT;
220 }
221
222 if (*outLen < ctx->outlen) {
223 BSL_ERR_PUSH_ERROR(CRYPT_SHA2_OUT_BUFF_LEN_NOT_ENOUGH);
224 return CRYPT_SHA2_OUT_BUFF_LEN_NOT_ENOUGH;
225 }
226
227 if (ctx->errorCode == CRYPT_SHA2_INPUT_OVERFLOW) {
228 BSL_ERR_PUSH_ERROR(CRYPT_SHA2_INPUT_OVERFLOW);
229 return CRYPT_SHA2_INPUT_OVERFLOW;
230 }
231
232 return CRYPT_SUCCESS;
233 }
CRYPT_SHA2_256_Final(CRYPT_SHA2_256_Ctx * ctx,uint8_t * digest,uint32_t * outlen)234 int32_t CRYPT_SHA2_256_Final(CRYPT_SHA2_256_Ctx *ctx, uint8_t *digest, uint32_t *outlen)
235 {
236 int32_t ret = FinalParamIsValid(ctx, digest, outlen);
237 if (ret != CRYPT_SUCCESS) {
238 return ret;
239 }
240
241 uint8_t *p = (uint8_t *)ctx->block;
242 uint32_t n = ctx->blocklen;
243
244 p[n++] = 0x80;
245 if (n > (CRYPT_SHA2_256_BLOCKSIZE - 8)) { /* 8 bytes to save bits of input */
246 (void)memset_s(p + n, CRYPT_SHA2_256_BLOCKSIZE - n, 0, CRYPT_SHA2_256_BLOCKSIZE - n);
247 n = 0;
248 SHA256CompressMultiBlocks(ctx->h, p, 1);
249 }
250 (void)memset_s(p + n, CRYPT_SHA2_256_BLOCKSIZE - n, 0,
251 CRYPT_SHA2_256_BLOCKSIZE - 8 - n); /* 8 bytes to save bits of input */
252
253 p += CRYPT_SHA2_256_BLOCKSIZE - 8; /* 8 bytes to save bits of input */
254 PUT_UINT32_BE(ctx->hNum, p, 0);
255 p += sizeof(uint32_t);
256 PUT_UINT32_BE(ctx->lNum, p, 0);
257 p += sizeof(uint32_t);
258 p -= CRYPT_SHA2_256_BLOCKSIZE;
259 SHA256CompressMultiBlocks(ctx->h, p, 1);
260 ctx->blocklen = 0;
261 (void)memset_s(p, CRYPT_SHA2_256_BLOCKSIZE, 0, CRYPT_SHA2_256_BLOCKSIZE);
262
263 n = ctx->outlen / sizeof(uint32_t);
264 for (uint32_t nn = 0; nn < n; nn++) {
265 PUT_UINT32_BE(ctx->h[nn], digest, sizeof(uint32_t) * nn);
266 }
267 *outlen = ctx->outlen;
268
269 return CRYPT_SUCCESS;
270 }
271
272 #ifdef HITLS_CRYPTO_SHA224
273
274
CRYPT_SHA2_224_NewCtx(void)275 CRYPT_SHA2_224_Ctx *CRYPT_SHA2_224_NewCtx(void)
276 {
277 return BSL_SAL_Calloc(1, sizeof(CRYPT_SHA2_224_Ctx));
278 }
279
CRYPT_SHA2_224_FreeCtx(CRYPT_SHA2_224_Ctx * ctx)280 void CRYPT_SHA2_224_FreeCtx(CRYPT_SHA2_224_Ctx *ctx)
281 {
282 CRYPT_SHA2_224_Ctx *mdCtx = ctx;
283 if (mdCtx == NULL) {
284 return;
285 }
286 BSL_SAL_ClearFree(ctx, sizeof(CRYPT_SHA2_224_Ctx));
287 }
288
CRYPT_SHA2_224_Init(CRYPT_SHA2_224_Ctx * ctx,BSL_Param * param)289 int32_t CRYPT_SHA2_224_Init(CRYPT_SHA2_224_Ctx *ctx, BSL_Param *param)
290 {
291 if (ctx == NULL) {
292 BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
293 return CRYPT_NULL_INPUT;
294 }
295 (void) param;
296 (void)memset_s(ctx, sizeof(CRYPT_SHA2_224_Ctx), 0, sizeof(CRYPT_SHA2_224_Ctx));
297 /**
298 * @RFC 4634 6.1 SHA-224 and SHA-256 Initialization
299 * SHA-224, the initial hash value, H(0):
300 * H(0)0 = c1059ed8
301 * H(0)1 = 367cd507
302 * H(0)2 = 3070dd17
303 * H(0)3 = f70e5939
304 * H(0)4 = ffc00b31
305 * H(0)5 = 68581511
306 * H(0)6 = 64f98fa7
307 * H(0)7 = befa4fa4
308 */
309 ctx->h[0] = 0xc1059ed8UL;
310 ctx->h[1] = 0x367cd507UL;
311 ctx->h[2] = 0x3070dd17UL;
312 ctx->h[3] = 0xf70e5939UL;
313 ctx->h[4] = 0xffc00b31UL;
314 ctx->h[5] = 0x68581511UL;
315 ctx->h[6] = 0x64f98fa7UL;
316 ctx->h[7] = 0xbefa4fa4UL;
317 ctx->outlen = CRYPT_SHA2_224_DIGESTSIZE;
318 return CRYPT_SUCCESS;
319 }
320
CRYPT_SHA2_224_Deinit(CRYPT_SHA2_224_Ctx * ctx)321 void CRYPT_SHA2_224_Deinit(CRYPT_SHA2_224_Ctx *ctx)
322 {
323 if (ctx == NULL) {
324 return;
325 }
326 BSL_SAL_CleanseData((void *)(ctx), sizeof(CRYPT_SHA2_224_Ctx));
327 }
328
CRYPT_SHA2_224_CopyCtx(CRYPT_SHA2_224_Ctx * dst,const CRYPT_SHA2_224_Ctx * src)329 int32_t CRYPT_SHA2_224_CopyCtx(CRYPT_SHA2_224_Ctx *dst, const CRYPT_SHA2_224_Ctx *src)
330 {
331 if (dst == NULL || src == NULL) {
332 BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
333 return CRYPT_NULL_INPUT;
334 }
335
336 (void)memcpy_s(dst, sizeof(CRYPT_SHA2_224_Ctx), src, sizeof(CRYPT_SHA2_224_Ctx));
337 return CRYPT_SUCCESS;
338 }
339
CRYPT_SHA2_224_DupCtx(const CRYPT_SHA2_224_Ctx * src)340 CRYPT_SHA2_224_Ctx *CRYPT_SHA2_224_DupCtx(const CRYPT_SHA2_224_Ctx *src)
341 {
342 if (src == NULL) {
343 BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
344 return NULL;
345 }
346 CRYPT_SHA2_224_Ctx *newCtx = CRYPT_SHA2_224_NewCtx();
347 if (newCtx == NULL) {
348 BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL);
349 return NULL;
350 }
351 (void)memcpy_s(newCtx, sizeof(CRYPT_SHA2_224_Ctx), src, sizeof(CRYPT_SHA2_224_Ctx));
352 return newCtx;
353 }
354
CRYPT_SHA2_224_Update(CRYPT_SHA2_224_Ctx * ctx,const uint8_t * data,uint32_t nbytes)355 int32_t CRYPT_SHA2_224_Update(CRYPT_SHA2_224_Ctx *ctx, const uint8_t *data, uint32_t nbytes)
356 {
357 return CRYPT_SHA2_256_Update((CRYPT_SHA2_256_Ctx *)ctx, data, nbytes);
358 }
359
CRYPT_SHA2_224_Final(CRYPT_SHA2_224_Ctx * ctx,uint8_t * digest,uint32_t * len)360 int32_t CRYPT_SHA2_224_Final(CRYPT_SHA2_224_Ctx *ctx, uint8_t *digest, uint32_t *len)
361 {
362 return CRYPT_SHA2_256_Final((CRYPT_SHA2_256_Ctx *)ctx, digest, len);
363 }
364 #endif // HITLS_CRYPTO_SHA224
365
366 #endif // HITLS_CRYPTO_SHA256
367