• 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_SHA512
18 #include "crypt_sha2.h"
19 #include <stdlib.h>
20 #include "securec.h"
21 #include "crypt_utils.h"
22 #include "crypt_errno.h"
23 #include "bsl_err_internal.h"
24 #include "sha2_core.h"
25 #include "bsl_sal.h"
26 #include "crypt_types.h"
27 
28 #define SHA2_512_PADSIZE    112
29 
30 // function : num1 += num2(num1 and num2 are 128bit int32_t)
Add128Bit(uint64_t * num1h,uint64_t * num1l,uint64_t num2h,uint64_t num2l)31 static int32_t Add128Bit(uint64_t *num1h, uint64_t *num1l, uint64_t num2h, uint64_t num2l)
32 {
33     uint64_t num1hTemp = *num1h;
34     uint64_t num1lTemp = *num1l;
35     uint64_t sumh = num1hTemp;
36     uint64_t suml = num1lTemp + num2l;
37     uint64_t carry = 0;
38     if (suml < num1lTemp) {
39         carry = 1;
40         sumh += carry;
41     }
42     sumh += num2h;
43     // num2h + carry >= 1, thus sumh shoud > num1hTemp; otherwise overflow
44     if ((carry > 0 || num2h > 0) && sumh <= num1hTemp) {
45         BSL_ERR_PUSH_ERROR(CRYPT_SHA2_INPUT_OVERFLOW);
46         return CRYPT_SHA2_INPUT_OVERFLOW;
47     }
48     *num1h = sumh;
49     *num1l = suml;
50     return 0;
51 }
52 
53 struct CryptSha2512Ctx {
54     uint64_t h[CRYPT_SHA2_512_DIGESTSIZE / sizeof(uint64_t)];
55     uint8_t block[CRYPT_SHA2_512_BLOCKSIZE];
56     uint64_t lNum, hNum;
57     uint32_t num, mdlen;
58     uint32_t errorCode; /* error Code */
59 };
60 
CheckIsCorrupted(CRYPT_SHA2_512_Ctx * ctx,uint32_t nbytes)61 static int32_t CheckIsCorrupted(CRYPT_SHA2_512_Ctx *ctx, uint32_t nbytes)
62 {
63     // bit len of data = len << 3, which may be 2^67, thus need to 2 uint64 to represent
64     uint64_t bitLenl = (uint64_t)nbytes << 3; // low 64 bit
65     // high 64 bit, right shift 61 to get higest 3 bit
66     uint64_t bitLenh = sizeof(nbytes) >= sizeof(uint64_t) ? (uint64_t)nbytes >> 61 : 0;
67     if (Add128Bit(&ctx->hNum, &ctx->lNum, bitLenh, bitLenl) != 0) {
68         // overflow, the len of msg over 2 ^ 128;
69         ctx->errorCode = CRYPT_SHA2_INPUT_OVERFLOW;
70         BSL_ERR_PUSH_ERROR(CRYPT_SHA2_INPUT_OVERFLOW);
71         return CRYPT_SHA2_INPUT_OVERFLOW;
72     }
73     return CRYPT_SUCCESS;
74 }
75 
CRYPT_SHA2_512_NewCtx(void)76 CRYPT_SHA2_512_Ctx *CRYPT_SHA2_512_NewCtx(void)
77 {
78     return BSL_SAL_Calloc(1, sizeof(CRYPT_SHA2_512_Ctx));
79 }
80 
CRYPT_SHA2_512_FreeCtx(CRYPT_SHA2_512_Ctx * ctx)81 void CRYPT_SHA2_512_FreeCtx(CRYPT_SHA2_512_Ctx *ctx)
82 {
83     CRYPT_SHA2_512_Ctx *mdCtx = ctx;
84     if (mdCtx == NULL) {
85         return;
86     }
87     BSL_SAL_ClearFree(ctx, sizeof(CRYPT_SHA2_512_Ctx));
88 }
89 
CRYPT_SHA2_512_Init(CRYPT_SHA2_512_Ctx * ctx,BSL_Param * param)90 int32_t CRYPT_SHA2_512_Init(CRYPT_SHA2_512_Ctx *ctx, BSL_Param *param)
91 {
92     if (ctx == NULL) {
93         BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
94         return CRYPT_NULL_INPUT;
95     }
96     (void) param;
97 
98     (void)memset_s(ctx, sizeof(CRYPT_SHA2_512_Ctx), 0, sizeof(CRYPT_SHA2_512_Ctx));
99 
100     // see RFC6234 chapter 6.3
101     ctx->h[0] = U64(0x6a09e667f3bcc908);
102     ctx->h[1] = U64(0xbb67ae8584caa73b);
103     ctx->h[2] = U64(0x3c6ef372fe94f82b);
104     ctx->h[3] = U64(0xa54ff53a5f1d36f1);
105     ctx->h[4] = U64(0x510e527fade682d1);
106     ctx->h[5] = U64(0x9b05688c2b3e6c1f);
107     ctx->h[6] = U64(0x1f83d9abfb41bd6b);
108     ctx->h[7] = U64(0x5be0cd19137e2179);
109     ctx->mdlen = CRYPT_SHA2_512_DIGESTSIZE;
110 
111     return CRYPT_SUCCESS;
112 }
113 
CRYPT_SHA2_512_Deinit(CRYPT_SHA2_512_Ctx * ctx)114 void CRYPT_SHA2_512_Deinit(CRYPT_SHA2_512_Ctx *ctx)
115 {
116     if (ctx == NULL) {
117         return;
118     }
119     BSL_SAL_CleanseData((void *)(ctx), sizeof(CRYPT_SHA2_512_Ctx));
120 }
121 
CRYPT_SHA2_512_CopyCtx(CRYPT_SHA2_512_Ctx * dst,const CRYPT_SHA2_512_Ctx * src)122 int32_t CRYPT_SHA2_512_CopyCtx(CRYPT_SHA2_512_Ctx *dst, const CRYPT_SHA2_512_Ctx *src)
123 {
124     if (dst == NULL || src == NULL) {
125         BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
126         return CRYPT_NULL_INPUT;
127     }
128 
129     (void)memcpy_s(dst, sizeof(CRYPT_SHA2_512_Ctx), src, sizeof(CRYPT_SHA2_512_Ctx));
130     return CRYPT_SUCCESS;
131 }
132 
CRYPT_SHA2_512_DupCtx(const CRYPT_SHA2_512_Ctx * src)133 CRYPT_SHA2_512_Ctx *CRYPT_SHA2_512_DupCtx(const CRYPT_SHA2_512_Ctx *src)
134 {
135     if (src == NULL) {
136         BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
137         return NULL;
138     }
139     CRYPT_SHA2_512_Ctx *newCtx = CRYPT_SHA2_512_NewCtx();
140     if (newCtx == NULL) {
141         BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL);
142         return NULL;
143     }
144     (void)memcpy_s(newCtx, sizeof(CRYPT_SHA2_512_Ctx), src, sizeof(CRYPT_SHA2_512_Ctx));
145     return newCtx;
146 }
147 
UpdateParamIsValid(CRYPT_SHA2_512_Ctx * ctx,const uint8_t * data,uint32_t nbytes)148 static int32_t UpdateParamIsValid(CRYPT_SHA2_512_Ctx *ctx, const uint8_t *data, uint32_t nbytes)
149 {
150     if ((ctx == NULL) || (data == NULL && nbytes != 0)) {
151         BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
152         return CRYPT_NULL_INPUT;
153     }
154 
155     if (ctx->errorCode == CRYPT_SHA2_INPUT_OVERFLOW) {
156         BSL_ERR_PUSH_ERROR(CRYPT_SHA2_INPUT_OVERFLOW);
157         return CRYPT_SHA2_INPUT_OVERFLOW;
158     }
159 
160     return CheckIsCorrupted(ctx, nbytes);
161 }
162 
CRYPT_SHA2_512_Update(CRYPT_SHA2_512_Ctx * ctx,const uint8_t * data,uint32_t nbytes)163 int32_t CRYPT_SHA2_512_Update(CRYPT_SHA2_512_Ctx *ctx, const uint8_t *data, uint32_t nbytes)
164 {
165     int32_t ret = UpdateParamIsValid(ctx, data, nbytes);
166     if (ret != CRYPT_SUCCESS) {
167         return ret;
168     }
169 
170     if (nbytes == 0) {
171         return CRYPT_SUCCESS;
172     }
173 
174     const uint32_t n = CRYPT_SHA2_512_BLOCKSIZE - ctx->num;
175     if (nbytes < n) {
176         // if the data can't fill block, just copy data to block
177         (void)memcpy_s(ctx->block + ctx->num, n, data, nbytes);
178         ctx->num += (uint32_t)nbytes;
179         return CRYPT_SUCCESS;
180     }
181 
182     const uint8_t *d = data;
183     uint32_t dataLen = nbytes;
184     if (ctx->num != 0) {
185         // fill the block first and compute
186         (void)memcpy_s(ctx->block + ctx->num, n, data, n);
187         ctx->num = 0;
188         dataLen -= n;
189         d += n;
190         SHA512CompressMultiBlocks(ctx->h, ctx->block, 1);
191     }
192 
193     SHA512CompressMultiBlocks(ctx->h, d, dataLen / CRYPT_SHA2_512_BLOCKSIZE);
194     d += dataLen;
195     dataLen &= (CRYPT_SHA2_512_BLOCKSIZE - 1);
196     d -= dataLen;
197 
198     if (dataLen != 0) {
199         // copy rest data to blcok
200         if (memcpy_s(ctx->block, CRYPT_SHA2_512_BLOCKSIZE, d, dataLen) != EOK) {
201             BSL_ERR_PUSH_ERROR(CRYPT_SECUREC_FAIL);
202             return CRYPT_SECUREC_FAIL;
203         }
204         ctx->num = (uint32_t)dataLen;
205     }
206 
207     return CRYPT_SUCCESS;
208 }
209 
FinalParamIsValid(const CRYPT_SHA2_512_Ctx * ctx,const uint8_t * out,const uint32_t * outLen)210 static int32_t FinalParamIsValid(const CRYPT_SHA2_512_Ctx *ctx, const uint8_t *out, const uint32_t *outLen)
211 {
212     if ((ctx == NULL) || (out == NULL) || (outLen == NULL)) {
213         BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
214         return CRYPT_NULL_INPUT;
215     }
216 
217     if (*outLen < ctx->mdlen) {
218         BSL_ERR_PUSH_ERROR(CRYPT_SHA2_OUT_BUFF_LEN_NOT_ENOUGH);
219         return CRYPT_SHA2_OUT_BUFF_LEN_NOT_ENOUGH;
220     }
221 
222     if (ctx->errorCode == CRYPT_SHA2_INPUT_OVERFLOW) {
223         BSL_ERR_PUSH_ERROR(CRYPT_SHA2_INPUT_OVERFLOW);
224         return CRYPT_SHA2_INPUT_OVERFLOW;
225     }
226 
227     return CRYPT_SUCCESS;
228 }
229 
CRYPT_SHA2_512_Final(CRYPT_SHA2_512_Ctx * ctx,uint8_t * digest,uint32_t * len)230 int32_t CRYPT_SHA2_512_Final(CRYPT_SHA2_512_Ctx *ctx, uint8_t *digest, uint32_t *len)
231 {
232     int32_t ret = FinalParamIsValid(ctx, digest, len);
233     if (ret != CRYPT_SUCCESS) {
234         return ret;
235     }
236 
237     uint32_t pad;
238     uint32_t n = ctx->num;
239     uint8_t *block = ctx->block;
240 
241     block[n++] = 0x80;
242 
243     if (n > SHA2_512_PADSIZE) {
244         pad = CRYPT_SHA2_512_BLOCKSIZE - n;
245         (void)memset_s(block + n, pad, 0, pad);
246         SHA512CompressMultiBlocks(ctx->h, block, 1);
247         n = 0;
248         pad = SHA2_512_PADSIZE;
249     } else {
250         pad = SHA2_512_PADSIZE - n;
251     }
252 
253     (void)memset_s(block + n, pad, 0, pad);
254     Uint64ToBeBytes(ctx->hNum, block + SHA2_512_PADSIZE);
255     Uint64ToBeBytes(ctx->lNum, block + SHA2_512_PADSIZE + sizeof(uint64_t));
256     SHA512CompressMultiBlocks(ctx->h, block, 1);
257 
258     uint8_t *out = digest;
259     uint32_t ncnt = ctx->mdlen >> 3; // MDSize / 8, calculate the number of times that values need to be assigned to out
260     for (n = 0; n < ncnt; n++) {
261         Uint64ToBeBytes(ctx->h[n], out);
262         out += sizeof(uint64_t);
263     }
264     *len = ctx->mdlen;
265 
266     return CRYPT_SUCCESS;
267 }
268 
269 #ifdef HITLS_CRYPTO_SHA384
270 
271 typedef CRYPT_SHA2_512_Ctx CRYPT_SHA2_384_Ctx;
272 
CRYPT_SHA2_384_NewCtx(void)273 CRYPT_SHA2_384_Ctx *CRYPT_SHA2_384_NewCtx(void)
274 {
275     return BSL_SAL_Calloc(1, sizeof(CRYPT_SHA2_384_Ctx));
276 }
277 
CRYPT_SHA2_384_FreeCtx(CRYPT_SHA2_384_Ctx * ctx)278 void CRYPT_SHA2_384_FreeCtx(CRYPT_SHA2_384_Ctx *ctx)
279 {
280     CRYPT_SHA2_384_Ctx *mdCtx = ctx;
281     if (mdCtx == NULL) {
282         return;
283     }
284     BSL_SAL_ClearFree(ctx, sizeof(CRYPT_SHA2_384_Ctx));
285 }
286 
CRYPT_SHA2_384_Init(CRYPT_SHA2_384_Ctx * ctx,BSL_Param * param)287 int32_t CRYPT_SHA2_384_Init(CRYPT_SHA2_384_Ctx *ctx, BSL_Param *param)
288 {
289     if (ctx == NULL) {
290         BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
291         return CRYPT_NULL_INPUT;
292     }
293     (void) param;
294     (void)memset_s(ctx, sizeof(CRYPT_SHA2_384_Ctx), 0, sizeof(CRYPT_SHA2_384_Ctx));
295     ctx->h[0] = U64(0xcbbb9d5dc1059ed8);
296     ctx->h[1] = U64(0x629a292a367cd507);
297     ctx->h[2] = U64(0x9159015a3070dd17);
298     ctx->h[3] = U64(0x152fecd8f70e5939);
299     ctx->h[4] = U64(0x67332667ffc00b31);
300     ctx->h[5] = U64(0x8eb44a8768581511);
301     ctx->h[6] = U64(0xdb0c2e0d64f98fa7);
302     ctx->h[7] = U64(0x47b5481dbefa4fa4);
303     ctx->mdlen = CRYPT_SHA2_384_DIGESTSIZE;
304     return CRYPT_SUCCESS;
305 }
306 
CRYPT_SHA2_384_Deinit(CRYPT_SHA2_384_Ctx * ctx)307 void CRYPT_SHA2_384_Deinit(CRYPT_SHA2_384_Ctx *ctx)
308 {
309     if (ctx == NULL) {
310         return;
311     }
312     BSL_SAL_CleanseData((void *)(ctx), sizeof(CRYPT_SHA2_384_Ctx));
313 }
314 
CRYPT_SHA2_384_CopyCtx(CRYPT_SHA2_384_Ctx * dst,const CRYPT_SHA2_384_Ctx * src)315 int32_t CRYPT_SHA2_384_CopyCtx(CRYPT_SHA2_384_Ctx *dst, const CRYPT_SHA2_384_Ctx *src)
316 {
317     if (dst == NULL || src == NULL) {
318         BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
319         return CRYPT_NULL_INPUT;
320     }
321 
322     (void)memcpy_s(dst, sizeof(CRYPT_SHA2_384_Ctx), src, sizeof(CRYPT_SHA2_384_Ctx));
323     return CRYPT_SUCCESS;
324 }
325 
CRYPT_SHA2_384_DupCtx(const CRYPT_SHA2_384_Ctx * src)326 CRYPT_SHA2_384_Ctx *CRYPT_SHA2_384_DupCtx(const CRYPT_SHA2_384_Ctx *src)
327 {
328     if (src == NULL) {
329         BSL_ERR_PUSH_ERROR(CRYPT_NULL_INPUT);
330         return NULL;
331     }
332     CRYPT_SHA2_384_Ctx *newCtx = CRYPT_SHA2_384_NewCtx();
333     if (newCtx == NULL) {
334         BSL_ERR_PUSH_ERROR(CRYPT_MEM_ALLOC_FAIL);
335         return NULL;
336     }
337     (void)memcpy_s(newCtx, sizeof(CRYPT_SHA2_384_Ctx), src, sizeof(CRYPT_SHA2_384_Ctx));
338     return newCtx;
339 }
340 
CRYPT_SHA2_384_Update(CRYPT_SHA2_384_Ctx * ctx,const uint8_t * data,uint32_t nbytes)341 int32_t CRYPT_SHA2_384_Update(CRYPT_SHA2_384_Ctx *ctx, const uint8_t *data, uint32_t nbytes)
342 {
343     return CRYPT_SHA2_512_Update((CRYPT_SHA2_512_Ctx *)ctx, data, nbytes);
344 }
345 
CRYPT_SHA2_384_Final(CRYPT_SHA2_384_Ctx * ctx,uint8_t * digest,uint32_t * len)346 int32_t CRYPT_SHA2_384_Final(CRYPT_SHA2_384_Ctx *ctx, uint8_t *digest, uint32_t *len)
347 {
348     return CRYPT_SHA2_512_Final((CRYPT_SHA2_512_Ctx *)ctx, digest, len);
349 }
350 
351 #endif // HITLS_CRYPTO_SHA384
352 
353 #endif // HITLS_CRYPTO_SHA512
354