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